Repository navigation
Add csv_write() to fix issue #45 - #52
Conversation
|
@G0rocks I can see the use of this if it is made general. By that, I mean it should write the result of the VPP to the CSV format, which is normally used in routing software. The current version is too specific for your use case, but it is a special case of the more general polar csv format. I also don't understand why you average the boat speed. You get multiple boat speeds, but there is only one that is the best; you should just use the max boat speed at that TWA/TWS point. |
|
The reason for averaging the boat speed is that I did not know which one was the correct one so I thought to myself that if I averaged them I'd probably get something close to the realistic one. Regarding the generalization, can you tell me explicitly what needs to change so that this function fulfills your requirement of writing the result of the VPP to the CSV format? I don't know how you want this done even though I am probably up for fixing it as long as it still fulfills my requirement of being compatible with OpenCPN. Note that currently OpenCPN polars only work in 5° increments (or multiples of 5°) and when it comes to the wind speed they work in increments of 2 (or multiples of 2) regardless of if it is in knots or meters/sec or another unit but the OpenCPN plugin always writes "knots". |
|
Okay, I can guide you on how to select the best boat speed later. Ideally, we want the function to do something like this (pseudo-code) def write_CSV(VPP, save, fname="SailChart.png"):
tws = VPP.tws_range
twa = VPP.twa_range
# generate header for csv file
writer = csv.writer(file, delimiter=";")
# Write header with TWS in knots
writer.writerow((hcat(["TWA\TWS", [str(ws) for ws in tws]]))
# Loop through every degree
for angle in twa:
row = make_row_from_store(VPP.store)
writer.writerow(row)And then in your VPP setup, you need to set the correct analysis vpp.set_analysis(
tws_range=np.arange(2.0, 40.0, 2.0), twa_range=np.arrange(0.0, 181.0, 5.0)
)which will result in the TWS and TWA you want. But if a user decides he wants to write a CSV file with only |
|
@G0rocks I've written the function quickly. If you don't specify the def csv_write(VPP, tws_range=None, twa_range=None, fname="polar.csv"):
if not hasattr(VPP, "store"):
raise ValueError("VPP object must have a 'store' attribute to use to export to csv.")
import csv
# if we specify tws_range and twa_range, we use them, otherwise we use the ones from VPP
tws = VPP.tws_range if tws_range is None else tws_range
twa = VPP.twa_range if twa_range is None else twa_range
store = np.max(VPP.store[:, :, :, 0], axis=2)/KNOTS_TO_MPS
# if we specify a custom TWA or TWS range, we make a custom structure and we interpolate the results in it
if tws_range is not None or twa_range is not None:
func = RectBivariateSpline(VPP.tws_range, VPP.twa_range, store)
store = func(tws, twa)
with open(fname, mode="w", newline="") as file:
# generate header for csv file
writer = csv.writer(file, delimiter=";")
# Write header with TWS in knots
writer.writerow(["TWA\TWS"] + [str(round(ws/KNOTS_TO_MPS, 2)) for ws in tws])
# Loop through every degree
for j, angle in enumerate(twa):
row = [str(angle)] + [str(round(store[i, j], 2)) for i in range(len(tws))]
writer.writerow(row)If it roughly tests and it works. # standard write of the results
csv_write(vpp, fname="polar.csv")
# custom twa range
csv_write(vpp, twa_range=np.linspace(30.0, 180.0, 16), fname="polar.csv")
# custom tws and tws range
csv_write(vpp, twa_range=np.linspace(30.0, 180.0, 10),
tws_range=np.linspace(4.0, 22.0, 10), fname="polar.csv")I'll let you test it and update the PR if that works for you. I cannot checkout your PR and implement it myself |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JN4y2NWa8kFMBZ5FV92jkj
Implements the review on marinlauber#52: - csv_write(VPP, tws_range=None, twa_range=None, fname="polar.csv") writes the best boat speed over the sail sets (no averaging) with the analysis TWS/TWA as header and rows by default - a custom tws_range (knots) and/or twa_range (degrees) linearly interpolates the results onto that grid, e.g. the 5 deg / 2 kn steps OpenCPN expects; points outside the analysis or not sailable are 0 - speeds are already in knots in the store, so no second unit conversion - VPP.write_csv() convenience method; runVPP.py writes polar.csv - .gitignore only ignores csv files at the repo root (dat/ holds csv data) - tests for the default grid, the interpolation and VPP.write_csv Fixes marinlauber#45 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JN4y2NWa8kFMBZ5FV92jkj
Resolve the import conflicts in src/python_vpp/VPPMod.py and tests/test_utils.py to the package imports, and document write_csv in the README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JN4y2NWa8kFMBZ5FV92jkj
Fixes #45