Skip to content

Conversation

@j-atkins
Copy link
Collaborator

This PR is an updated version of #185 (now closed), originally relating to #155. Rather than simply removing duplicate messages in the log, all Parcels messages are now suppressed to decouple from Parcels, as suggested by @VeckoTheGecko in #185.

I have made further updates to what's printed for the user as they run VirtualShip. This includes adding spinning dials to most instruments to provide a visual cue that the measurement simulation is running (point 2 in #186). For the instruments which take longer to simulate (drifters and argo floats) I have left the call to use Parcels verbose_progress = True to get a progress bar. I would have liked to have decoupled from Parcels again here but it proved tricky to propagate our own progress bar given the iteration occurs within the .execute() and it is difficult to access this or replicate the iteration outside of the Parcels internals.

Finally, I've reorganised some of the print statements in do_expedition.py to provide a bit more structure to what's printed for the user. It's subjective but hopefully it improves readability and tracking the simulation progress a bit? See an example screenshot below for a completed expedition (the spinning dials are replaced with "[COMPLETED]" when the execution is finished).

Screenshot 2025-05-20 at 16 55 02

The Parcels progress bar doesn't fit in so nicely but maybe something for a future PR...

@ammedd
Copy link
Collaborator

ammedd commented May 21, 2025

Nice! I think the water statements are a bit too much too. Perhaps reformulating them to something more general about the route?
Verifying all waypoints are on water... ... Good, all waypoints are on water.
E.g. Verifying route...
... All good to go!

Copy link
Collaborator

@VeckoTheGecko VeckoTheGecko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered using https://github.com/pavdmyt/yaspin ? Looks like a good package with options for this. It has minimal dependencies and is quite well maintained.

Comment on lines +71 to +96
# try/finally to ensure filter is always removed even if .execute fails (to avoid filter being appled universally)
# also suits starting and ending the rotator for custom log message
try:
rotator.start()

for point in sample_points:
particleset.lon_nextloop[:] = point.location.lon
particleset.lat_nextloop[:] = point.location.lat
particleset.time_nextloop[:] = fieldset.time_origin.reltime(
np.datetime64(point.time)
)

# perform one step using the particleset
# dt and runtime are set so exactly one step is made.
particleset.execute(
[_sample_velocity],
dt=1,
runtime=1,
verbose_progress=False,
output_file=out_file,
)

finally:
rotator.stop()
for handler in external_logger.handlers:
handler.removeFilter(handler.filters[0])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Python, this try finally pattern is normally done via context managers. This means that if something fails in the block of code, the code is torn down after.

This will simplify both the code for the spinner, as well as the code for the filtering, boiling down to something like

with spinner("Deploying drifters..."):
    with discard_parcels_warnings():
        # code to process measurement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants