From e0b925238993238effe3c2abd307a68b6d94b18a Mon Sep 17 00:00:00 2001 From: Aart Stuurman Date: Tue, 28 May 2024 17:24:06 +0200 Subject: [PATCH] Remove old drifter file and fix errors --- tests/sailship_config.json | 2 +- tests/test_sailship.py | 7 +- virtual_ship/drifter_deployments.py | 109 ---------------------------- virtual_ship/sailship.py | 33 ++++++--- 4 files changed, 29 insertions(+), 122 deletions(-) delete mode 100644 virtual_ship/drifter_deployments.py diff --git a/tests/sailship_config.json b/tests/sailship_config.json index 23cf4c1a..d7b90b05 100644 --- a/tests/sailship_config.json +++ b/tests/sailship_config.json @@ -25,7 +25,7 @@ "max_depth": "max" }, "drifter_deploylocations": [ - + [-23.081289, 63.743631] ], "argo_deploylocations": [ [-23.081289, 63.743631] diff --git a/tests/test_sailship.py b/tests/test_sailship.py index afd8a95f..33f1e290 100644 --- a/tests/test_sailship.py +++ b/tests/test_sailship.py @@ -17,11 +17,12 @@ def test_sailship() -> None: ctd_fieldset.add_constant("max_depth", -ctd_fieldset.U.depth[-1]) drifter_fieldset = FieldSet.from_data( + {"U": 0, "V": 0, "T": 0}, { - "U": 0, - "V": 0, + "lon": 0, + "lat": 0, + "time": [np.datetime64("1950-01-01") + np.timedelta64(632160, "h")], }, - {"lon": 0, "lat": 0}, ) argo_float_fieldset = FieldSet.from_data( diff --git a/virtual_ship/drifter_deployments.py b/virtual_ship/drifter_deployments.py deleted file mode 100644 index 69836bc3..00000000 --- a/virtual_ship/drifter_deployments.py +++ /dev/null @@ -1,109 +0,0 @@ -"""drifter_deployments function.""" - -import datetime -import os -from datetime import timedelta - -import numpy as np -from parcels import AdvectionRK4, FieldSet, JITParticle, ParticleSet, Variable - -from .virtual_ship_configuration import VirtualShipConfiguration - - -def drifter_deployments(config: VirtualShipConfiguration, drifter_time): - """ - Deploy drifters. - - :param config: The cruise configuration. - :param drifter_time: TODO - """ - if len(config.drifter_deploylocations) > 0: - - fieldset = config.drifter_fieldset - - # Create particle to sample water underway - class DrifterParticle(JITParticle): - """Define a new particle class that samples Temperature as a surface drifter.""" - - temperature = Variable("temperature", initial=np.nan) - - # define function sampling Temperature - def SampleT(particle, fieldset, time): - particle.temperature = fieldset.T[ - time, particle.depth, particle.lat, particle.lon - ] - - def CheckError(particle, fieldset, time): - if particle.state >= 50: # This captures all Errors - particle.delete() - - # initialize drifters - lon = [] - lat = [] - for i in range(len(config.drifter_deploylocations)): - lon.append(config.drifter_deploylocations[i][0]) - lat.append(config.drifter_deploylocations[i][1]) - time = drifter_time - - # Create and execute drifter particles - pset = ParticleSet( - fieldset=fieldset, - pclass=DrifterParticle, - lon=lon, - lat=lat, - depth=np.repeat(fieldset.mindepth, len(time)), - time=time, - ) - output_file = pset.ParticleFile( - name=os.path.join("results", "Drifters.zarr"), outputdt=timedelta(hours=1) - ) - - fieldset_endtime = fieldset.time_origin.fulltime(fieldset.U.grid.time_full[-1]) - drifter_endtime = np.array( - ( - datetime.datetime.strptime( - config.requested_ship_time["start"], "%Y-%m-%dT%H:%M:%S" - ) - + timedelta(weeks=6) - ) - ).astype("datetime64[ms]") - - pset.execute( - [AdvectionRK4, SampleT, CheckError], - endtime=min(fieldset_endtime, drifter_endtime), - dt=timedelta(minutes=5), - output_file=output_file, - ) - - -def create_drifter_fieldset(config, data_dir: str): - """ - Create a fieldset from netcdf files for drifters, returns fieldset with negative depth values. - - :param config: The cruise configuration. - :param data_dir: TODO - :returns: The fieldset. - """ - filenames = { - "U": os.path.join(data_dir, "drifterdata_UV.nc"), - "V": os.path.join(data_dir, "drifterdata_UV.nc"), - "T": os.path.join(data_dir, "drifterdata_T.nc"), - } - variables = {"U": "uo", "V": "vo", "T": "thetao"} - dimensions = { - "lon": "longitude", - "lat": "latitude", - "time": "time", - "depth": "depth", - } - - # create the fieldset and set interpolation methods - fieldset = FieldSet.from_netcdf( - filenames, variables, dimensions, allow_time_extrapolation=False - ) - fieldset.T.interp_method = "linear_invdist_land_tracer" - for g in fieldset.gridset.grids: - if max(g.depth) > 0: - g.depth = -g.depth # make depth negative - fieldset.mindepth = -fieldset.U.depth[0] # uppermost layer in the hydrodynamic data - return fieldset diff --git a/virtual_ship/sailship.py b/virtual_ship/sailship.py index 51238069..ed0bc082 100644 --- a/virtual_ship/sailship.py +++ b/virtual_ship/sailship.py @@ -9,8 +9,8 @@ from shapely.geometry import Point, Polygon from .costs import costs -from .drifter_deployments import drifter_deployments from .instruments.argo_float import ArgoFloat, simulate_argo_floats +from .instruments.drifter import Drifter, simulate_drifters from .instruments.location import Location from .postprocess import postprocess from .virtual_ship_configuration import VirtualShipConfiguration @@ -137,11 +137,12 @@ def SampleT(particle, fieldset, time): # initialize drifters and argo floats drifter = 0 - drifter_time = [] + drifters: list[Drifter] = [] argo = 0 argo_floats: list[ArgoFloat] = [] - ARGO_MIN_DEPTH = -config.argo_float_fieldset.U.depth[0] + argo_min_depth = -config.argo_float_fieldset.U.depth[0] + drifter_min_depth = -config.drifter_fieldset.U.depth[0] # run the model for the length of the sample_lons list for i in range(len(sample_lons) - 1): @@ -203,14 +204,23 @@ def SampleT(particle, fieldset, time): pset_CTD.time[0] + timedelta(minutes=20).total_seconds() ) # add CTD time and 20 minutes for deployment - # check if we are at a drifter deployment location + # check if we are at a `drifter` deployment location if drifter < len(config.drifter_deploylocations): while ( abs(sample_lons[i] - config.drifter_deploylocations[drifter][0]) < 0.01 and abs(sample_lats[i] - config.drifter_deploylocations[drifter][1]) < 0.01 ): - drifter_time.append(total_time) + drifters.append( + Drifter( + location=Location( + latitude=config.drifter_deploylocations[drifter][0], + longitude=config.drifter_deploylocations[drifter][1], + ), + deployment_time=total_time, + min_depth=drifter_min_depth, + ) + ) drifter += 1 print( f"Drifter {drifter} deployed at {sample_lons[i]}, {sample_lats[i]}" @@ -231,7 +241,7 @@ def SampleT(particle, fieldset, time): longitude=config.argo_deploylocations[argo][1], ), deployment_time=total_time, - min_depth=ARGO_MIN_DEPTH, + min_depth=argo_min_depth, max_depth=config.argo_characteristics["maxdepth"], drift_depth=config.argo_characteristics["driftdepth"], vertical_speed=config.argo_characteristics["vertical_speed"], @@ -267,10 +277,15 @@ def SampleT(particle, fieldset, time): ) print("Cruise has ended. Please wait for drifters and/or Argo floats to finish.") - # simulate drifter deployments - drifter_deployments(config, drifter_time) + # simulate drifters + simulate_drifters( + drifters=drifters, + fieldset=config.drifter_fieldset, + out_file_name=os.path.join("results", "drifters.zarr"), + outputdt=timedelta(minutes=5), + ) - # simulate argo deployments + # simulate argo floats simulate_argo_floats( argo_floats=argo_floats, fieldset=config.argo_float_fieldset,