@@ -142,6 +142,11 @@ class ParticleTrackingManager:
142
142
Name of input/output module type to use for writing Lagrangian model output. Default is "netcdf".
143
143
use_cache : bool
144
144
Set to True to use cache for saving interpolators, by default True.
145
+ interpolator_filename : Optional[Union[pathlib.Path,str]], optional
146
+ Filename to save interpolators to, by default None. The full path should be given, but no suffix.
147
+ Use this to either read from an existing file at a non-default location or to save to a
148
+ non-default location. If None and use_cache==True, the filename is set to a built-in name to an
149
+ `appdirs` cache directory.
145
150
146
151
Notes
147
152
-----
@@ -198,6 +203,9 @@ def __init__(
198
203
output_file : Optional [str ] = config_ptm ["output_file" ]["default" ],
199
204
output_format : str = config_ptm ["output_format" ]["default" ],
200
205
use_cache : bool = config_ptm ["use_cache" ]["default" ],
206
+ interpolator_filename : Optional [Union [pathlib .Path , str ]] = config_ptm [
207
+ "interpolator_filename"
208
+ ]["default" ],
201
209
** kw ,
202
210
) -> None :
203
211
"""Inputs necessary for any particle tracking."""
@@ -231,24 +239,16 @@ def __init__(
231
239
232
240
self .output_file_initial = None
233
241
234
- # Set all attributes which will trigger some checks and changes in __setattr__
235
- # these will also update "value" in the config dict
236
- for key in sig .parameters .keys ():
237
- # no need to run through for init if value is None (already set to None)
238
- if locals ()[key ] is not None :
239
- self .__setattr__ (key , locals ()[key ])
240
-
241
- self .kw = kw
242
+ if output_file is None :
243
+ output_file = f"output-results_{ datetime .datetime .now ():%Y-%m-%dT%H%M:%SZ} "
242
244
243
- if self .__dict__ ["output_file" ] is None :
244
- self .__dict__ [
245
- "output_file"
246
- ] = f"output-results_{ datetime .datetime .now ():%Y-%m-%dT%H%M:%SZ} "
245
+ # want output_file to not include any suffix
246
+ output_file = output_file .rstrip (".nc" ).rstrip (".parq" )
247
247
248
248
## set up log for this simulation
249
249
# Create a file handler
250
- assert self . __dict__ [ " output_file" ] is not None
251
- logfile_name = self . __dict__ [ " output_file" ] + ".log"
250
+ assert output_file is not None
251
+ logfile_name = output_file + ".log"
252
252
self .file_handler = logging .FileHandler (logfile_name )
253
253
self .logfile_name = logfile_name
254
254
@@ -264,6 +264,56 @@ def __init__(
264
264
self .logger .info (f"filename: { logfile_name } " )
265
265
##
266
266
267
+ if interpolator_filename is not None and not use_cache :
268
+ raise ValueError (
269
+ "If interpolator_filename is input, use_cache must be True."
270
+ )
271
+
272
+ # deal with caching/interpolators
273
+ # save interpolators to save time
274
+ if use_cache :
275
+ cache_dir = pathlib .Path (
276
+ appdirs .user_cache_dir (
277
+ appname = "particle-tracking-manager" ,
278
+ appauthor = "axiom-data-science" ,
279
+ )
280
+ )
281
+ cache_dir .mkdir (parents = True , exist_ok = True )
282
+ cache_dir = cache_dir
283
+ if interpolator_filename is None :
284
+ interpolator_filename = cache_dir / pathlib .Path (
285
+ f"{ ocean_model } _interpolator"
286
+ ).with_suffix (".pickle" )
287
+ else :
288
+ interpolator_filename = pathlib .Path (interpolator_filename ).with_suffix (
289
+ ".pickle"
290
+ )
291
+ interpolator_filename = str (interpolator_filename )
292
+ self .save_interpolator = True
293
+ # if interpolator_filename already exists, load that
294
+ if pathlib .Path (interpolator_filename ).exists ():
295
+ self .logger .info (
296
+ f"Loading the interpolator from { interpolator_filename } ."
297
+ )
298
+ else :
299
+ self .logger .info (
300
+ f"A new interpolator will be saved to { interpolator_filename } ."
301
+ )
302
+ else :
303
+ self .save_interpolator = False
304
+ # this is already None
305
+ # self.interpolator_filename = None
306
+ self .logger .info ("Interpolators will not be saved." )
307
+
308
+ # Set all attributes which will trigger some checks and changes in __setattr__
309
+ # these will also update "value" in the config dict
310
+ for key in sig .parameters .keys ():
311
+ # no need to run through for init if value is None (already set to None)
312
+ if locals ()[key ] is not None :
313
+ self .__setattr__ (key , locals ()[key ])
314
+
315
+ self .kw = kw
316
+
267
317
def __setattr_model__ (self , name : str , value ) -> None :
268
318
"""Implement this in model class to add specific __setattr__ there too."""
269
319
pass
@@ -383,7 +433,8 @@ def __setattr__(self, name: str, value) -> None:
383
433
# by this point, output_file should already be a filename like what is
384
434
# available here, from OpenDrift (if run from there)
385
435
if self .output_file is not None :
386
- output_file = self .output_file .rstrip (".nc" )
436
+ output_file = self .output_file
437
+ # output_file = self.output_file.rstrip(".nc")
387
438
else :
388
439
output_file = (
389
440
f"output-results_{ datetime .datetime .now ():%Y-%m-%dT%H%M:%SZ} "
@@ -477,29 +528,6 @@ def __setattr__(self, name: str, value) -> None:
477
528
)
478
529
self .seed_seafloor = False
479
530
480
- # save interpolators to save time
481
- if name == "use_cache" :
482
- if value :
483
- cache_dir = pathlib .Path (
484
- appdirs .user_cache_dir (
485
- appname = "particle-tracking-manager" ,
486
- appauthor = "axiom-data-science" ,
487
- )
488
- )
489
- cache_dir .mkdir (parents = True , exist_ok = True )
490
- self .cache_dir = cache_dir
491
- self .interpolator_filename = cache_dir / pathlib .Path (
492
- f"{ self .ocean_model } _interpolator"
493
- )
494
- self .save_interpolator = True
495
- self .logger .info (
496
- f"Interpolators will be saved to { self .interpolator_filename } ."
497
- )
498
- else :
499
- self .save_interpolator = False
500
- self .interpolator_filename = None
501
- self .logger .info ("Interpolators will not be saved." )
502
-
503
531
# if reader, lon, and lat set, check inputs
504
532
if (
505
533
name == "has_added_reader"
0 commit comments