fargopy 0.3.3__py3-none-any.whl → 0.3.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fargopy/__init__.py CHANGED
@@ -8,6 +8,7 @@ from fargopy.version import *
8
8
  ###############################################################
9
9
  import warnings
10
10
  import os
11
+ import json
11
12
  import numpy as np
12
13
 
13
14
  ###############################################################
@@ -122,6 +123,24 @@ class Fargobj(object):
122
123
  self.fobject = True
123
124
  self.kwargs = kwargs
124
125
 
126
+ def save_object(self,filename=None,verbose=False):
127
+ """Save Fargobj into a filename in JSON format
128
+
129
+ Args:
130
+ filename: string, default = None:
131
+ Path of the file where the object will be saved.
132
+ If None the filename will be '/tmp/fargobj_{hash}.json'
133
+ where {hash} is the hash of the object attributes dictionary.
134
+ """
135
+ if filename is None:
136
+ object_hash = str(abs(hash(str(self.__dict__))))
137
+ filename = f"/tmp/fargobj_{object_hash}.json"
138
+ if verbose:
139
+ print(f"Saving object to {filename}...")
140
+ with open(filename,'w') as file_object:
141
+ file_object.write(json.dumps(self.__dict__,default=lambda obj:'<not serializable>'))
142
+ file_object.close()
143
+
125
144
  def set_property(self,property,default,method=lambda prop:prop):
126
145
  """Set a property of object using a given method
127
146
 
fargopy/simulation.py CHANGED
@@ -7,6 +7,7 @@ import fargopy
7
7
  # Required packages
8
8
  ###############################################################
9
9
  import os
10
+ import json
10
11
  import numpy as np
11
12
  import re
12
13
  import subprocess
@@ -68,7 +69,31 @@ class Simulation(fargopy.Fargobj):
68
69
  super().__init__(**kwargs)
69
70
 
70
71
  # Load simulation configuration from a file
71
-
72
+ if ('load' in kwargs.keys()) and kwargs['load']:
73
+ if not 'setup' in kwargs.keys():
74
+ raise AssertionError(f"You must provide a setup name.")
75
+ else:
76
+ setup = kwargs['setup']
77
+ if 'fargo3d_dir' in kwargs.keys():
78
+ fargo3d_dir = kwargs['fargo3d_dir']
79
+ else:
80
+ fargo3d_dir = fargopy.Conf.FP_FARGO3D_DIR
81
+
82
+ load_from = f"{fargo3d_dir}/setups/{setup}".replace('//','/')
83
+ if not os.path.isdir(load_from):
84
+ print(f"Directory for loading simulation '{load_from}' not found.")
85
+ json_file = f"{load_from}/fargopy_simulation.json"
86
+ print(f"Loading simulation from '{json_file}'")
87
+ if not os.path.isfile(json_file):
88
+ print(f"Loading data '{json_file}' not found.")
89
+ with open(json_file) as file_handler:
90
+ attributes = json.load(file_handler)
91
+ self.__dict__.update(attributes)
92
+ self.set_fargo3d_dir(self.fargo3d_dir)
93
+ self.set_setup(self.setup)
94
+ self.set_output_dir(self.output_dir)
95
+ return
96
+
72
97
  # Set units by default
73
98
  self.set_units(UL=AU,UM=MSUN)
74
99
 
@@ -207,7 +232,7 @@ class Simulation(fargopy.Fargobj):
207
232
  print(f"Cleaning FARGO3D directory {self.fargo3d_dir}...")
208
233
  cmd = f"make -C {self.fargo3d_dir} clean mrproper"
209
234
  compl = f"rm -rf {self.fargo3d_dir}/fargo3d_*"
210
- error,self.output_clean = fargopy.Sys.run(cmd + '&&' + compl)
235
+ error,output_clean = fargopy.Sys.run(cmd + '&&' + compl)
211
236
 
212
237
  # Prepare compilation
213
238
  compile_options = f"SETUP={self.setup} PARALLEL={parallel} GPU={gpu} "+options
@@ -215,9 +240,10 @@ class Simulation(fargopy.Fargobj):
215
240
 
216
241
  # Compile binary
217
242
  print(f"Compiling {fargo3d_binary}...")
218
- cmd = f"cd {self.fargo3d_dir};make {compile_options}"
243
+ cmd = f"cd {self.fargo3d_dir};make {compile_options} 2>&1 |tee {self.setup_dir}/compilation.log"
219
244
  compl = f"mv fargo3d {fargo3d_binary}"
220
- error,self.output_compilation = fargopy.Sys.run(cmd+' && '+compl)
245
+ pipe = f""
246
+ error,output_compilation = fargopy.Sys.run(cmd+' && '+compl)
221
247
 
222
248
  # Check compilation result
223
249
  if os.path.isfile(f"{self.fargo3d_dir}/{fargo3d_binary}"):
@@ -229,7 +255,7 @@ class Simulation(fargopy.Fargobj):
229
255
  options=options
230
256
  )
231
257
  else:
232
- print(f"Something failed when compiling FARGO3D. For details check Simulation.output_compilation")
258
+ print(f"Something failed when compiling FARGO3D. For details check '{self.setup_dir}/compilation.log")
233
259
 
234
260
  def run(self,
235
261
  mode='async',
@@ -237,7 +263,8 @@ class Simulation(fargopy.Fargobj):
237
263
  mpioptions='-np 1',
238
264
  resume=False,
239
265
  cleanrun=False,
240
- test=False):
266
+ test=False,
267
+ unlock=True):
241
268
 
242
269
  if self.fargo3d_binary is None:
243
270
  print("You must first compile your simulation with: <simulation>.compile(<option>).")
@@ -271,8 +298,12 @@ class Simulation(fargopy.Fargobj):
271
298
 
272
299
  # Preparing command
273
300
  run_cmd = f"{precmd} ./{self.fargo3d_binary} {options} setups/{self.setup}/{self.setup}.par"
274
-
301
+
302
+ self.json_file = f"{self.setup_dir}/fargopy_simulation.json"
275
303
  if mode == 'sync':
304
+ # Save object
305
+ self.save_object(self.json_file)
306
+
276
307
  # Run synchronously
277
308
  cmd = f"cd {self.fargo3d_dir};{run_cmd} |tee {self.logfile}"
278
309
  print(f"Running synchronously: {cmd}")
@@ -289,6 +320,16 @@ class Simulation(fargopy.Fargobj):
289
320
  # Launch process
290
321
  print(f"Running asynchronously (test = {test}): {run_cmd}")
291
322
  if not test:
323
+
324
+ # Check it is not locked
325
+ lock_info = fargopy.Sys.is_locked(dir=self.setup_dir)
326
+ if lock_info:
327
+ if unlock:
328
+ self._unlock_simulation(lock_info)
329
+ else:
330
+ print(f"Output directory {self.setup_dir} is locked by a running process")
331
+ return
332
+
292
333
  process = subprocess.Popen(run_cmd.split(),cwd=self.fargo3d_dir,
293
334
  stdout=logfile_handler,stderr=logfile_handler)
294
335
  # Introduce a short delay to verify if the process has failed
@@ -298,16 +339,29 @@ class Simulation(fargopy.Fargobj):
298
339
  # Check if program is effectively running
299
340
  self.fargo3d_process = process
300
341
 
301
- # Create a lock on fargopy with the process id
302
- # fargopy.lock(self.frago3d_process.pid)
342
+ # Lock
343
+ fargopy.Sys.lock(
344
+ dir=self.setup_dir,
345
+ content=dict(pid=self.fargo3d_process.pid)
346
+ )
303
347
 
304
348
  # Setup output directory
305
349
  self.set_output_dir(f"{self.outputs_dir}/{self.setup}".replace('//','/'))
350
+
351
+ # Save object
352
+ self.save_object(self.json_file)
306
353
  else:
307
354
  print(f"Process running failed. Please check the logfile {self.logfile}")
355
+ else:
356
+ print(f"Mode {mode} not recognized (valid are 'sync', 'async')")
357
+ return
308
358
 
309
359
  def stop(self):
360
+ # Check if the directory is locked
361
+ lock_info = fargopy.Sys.is_locked(self.setup_dir)
362
+
310
363
  if not self._check_process():
364
+ self._unlock_simulation(lock_info)
311
365
  return
312
366
 
313
367
  poll = self.fargo3d_process.poll()
@@ -317,13 +371,16 @@ class Simulation(fargopy.Fargobj):
317
371
  del self.fargo3d_process
318
372
  self.fargo3d_process = None
319
373
  else:
320
- print(f"The process has already finished. Check logfile {self.logfile}.")
321
-
322
- def _save_simultation(self):
323
- """Save simulation configuration
324
- """
325
- pass
326
-
374
+ self._unlock_simulation(lock_info)
375
+ print(f"The process has finished. Check logfile {self.logfile}.")
376
+
377
+ def _unlock_simulation(self,lock_info):
378
+ if lock_info:
379
+ pid = lock_info['pid']
380
+ fargopy.Debug.trace(f"Unlocking simulation (pid = {pid})")
381
+ error,output = fargopy.Sys.run(f"kill -9 {pid}")
382
+ fargopy.Sys.unlock(self.setup_dir)
383
+
327
384
  def status(self,mode='isrunning',verbose=True,**kwargs):
328
385
  """Check the status of the running process
329
386
 
@@ -350,6 +407,10 @@ class Simulation(fargopy.Fargobj):
350
407
  if poll is None:
351
408
  vprint("\tThe process is running.")
352
409
  else:
410
+ # Unlock any remaining process
411
+ lock_info = fargopy.Sys.is_locked(self.setup_dir)
412
+ self._unlock_simulation(lock_info)
413
+
353
414
  vprint(f"\tThe process has ended with termination code {poll}.")
354
415
  else:
355
416
  vprint(f"\tThe process is stopped.")
@@ -411,7 +472,7 @@ class Simulation(fargopy.Fargobj):
411
472
 
412
473
  # Infinite loop checking for output
413
474
  n = 0
414
- print(f"Progress of the simulation (numstatus = {numstatus}):")
475
+ print(f"Progress of the simulation (numstatus = {numstatus}, interrupting may stop the process):")
415
476
  while True and (n<numstatus):
416
477
  if not self._is_running():
417
478
  print("The simulation is not running anymore")
@@ -440,6 +501,8 @@ class Simulation(fargopy.Fargobj):
440
501
  try:
441
502
  time.sleep(frequency)
442
503
  except KeyboardInterrupt:
504
+ time.sleep(1)
505
+ print("In some environment (IPython, Colab) stopping the progress status will stop the simulation. In that case just resume.")
443
506
  self.status('isrunning')
444
507
  return
445
508
 
@@ -487,6 +550,11 @@ class Simulation(fargopy.Fargobj):
487
550
  error,output = fargopy.Sys.run(cmd)
488
551
 
489
552
  def _is_running(self,verbose=False):
553
+ if not self.has('fargo3d_process'):
554
+ if verbose:
555
+ print("The simulation has not been run before.")
556
+ return False
557
+
490
558
  if self.fargo3d_process:
491
559
  poll = self.fargo3d_process.poll()
492
560
  if poll is None:
@@ -793,7 +861,8 @@ class Simulation(fargopy.Fargobj):
793
861
  return comps
794
862
 
795
863
  def __repr__(self):
796
- return self.__str__()
864
+ repr = f"""FARGOPY simulation (fargo3d_dir = '{self.fargo3d_dir}', setup = '{self.setup}')"""
865
+ return repr
797
866
 
798
867
  def __str__(self):
799
868
  str = f"""Simulation information:
fargopy/sys.py CHANGED
@@ -7,6 +7,7 @@ import fargopy
7
7
  # Required packages
8
8
  ###############################################################
9
9
  import os
10
+ import json
10
11
  import subprocess
11
12
  import inspect
12
13
  import signal
@@ -142,3 +143,41 @@ class Sys(object):
142
143
  print(f"There is a lockfile in {fargopy.FP_FARGO3D_LOCKFILE}")
143
144
  return True
144
145
  return False
146
+
147
+ @staticmethod
148
+ def lock(dir,content=dict()):
149
+ """Lock a directory using content information
150
+ """
151
+ if not os.path.isdir(dir):
152
+ print(f"Locking directory '{dir}' not found.")
153
+ return
154
+ filename = f"{dir}/fargopy.lock"
155
+
156
+ with open(filename,'w') as file_object:
157
+ file_object.write(json.dumps(content,default=lambda obj:'<not serializable>'))
158
+ file_object.close()
159
+
160
+ @staticmethod
161
+ def unlock(dir):
162
+ """UnLock a directory
163
+ """
164
+ if not os.path.isdir(dir):
165
+ print(f"Locking directory '{dir}' not found.")
166
+ return
167
+ filename = f"{dir}/fargopy.lock"
168
+ if os.path.isfile(filename):
169
+ fargopy.Sys.simple(f"rm -rf {filename}")
170
+
171
+ @staticmethod
172
+ def is_locked(dir,verbose=False):
173
+ if not os.path.isdir(dir):
174
+ if verbose:
175
+ print(f"Locking directory '{dir}' not found.")
176
+ return False
177
+ filename = f"{dir}/fargopy.lock"
178
+ if os.path.isfile(filename):
179
+ if verbose:
180
+ print(f"The directory '{dir}' is locked")
181
+ with open(filename) as file_handler:
182
+ info = json.load(file_handler)
183
+ return info
fargopy/version.py CHANGED
@@ -1 +1 @@
1
- version='0.3.3'
1
+ version='0.3.5'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fargopy
3
- Version: 0.3.3
3
+ Version: 0.3.5
4
4
  Summary: FARGO3D Wrapping
5
5
  Home-page: https://pypi.org/project/fargopy
6
6
  Author: Jorge Zuluaga, Matias Montesinos
@@ -39,12 +39,14 @@ This is an animation created with a few lines of code using `FARGOpy` (for the c
39
39
  `FARGOpy` is available at the `Python` package index and can be installed using:
40
40
 
41
41
  ```bash
42
- $ pip install fargopy
42
+ $ sudo pip install fargopy
43
43
  ```
44
44
  as usual this command will install all dependencies (excluding `FARGO3D` which must be installed indepently as explained before) and download some useful data, scripts and constants.
45
45
 
46
46
 
47
47
 
48
+ > **NOTE**: If you don't have access to `sudo`, you can install `FARGOpy` in your local environmen (usually at `~/.local/`). In that case you need to add to your `PATH` environmental variable the location of the local python installation. Add to `~/.bashrc` the line `export PATH=$HOME/.local/bin:$PATH`
49
+
48
50
  Since `FARGOpy` is a python wrap for `FARGO3D` the ideal environment to work with the package is `IPython`/`Jupyter`. It works really fine in `Google Colab` ensuing training and demonstration purposes. This README, for instance, can be ran in `Google Colab`
49
51
 
50
52
  <a target="_blank" href="https://colab.research.google.com/github/seap-udea/fargopy/blob/main/README.ipynb">
@@ -55,7 +57,7 @@ If you are running in colab use:
55
57
 
56
58
 
57
59
  ```python
58
- #!pip install -Uq fargopy
60
+ #!sudo pip install -Uq fargopy
59
61
  ```
60
62
 
61
63
  If you are working in `Jupyter` or in `Google Colab`, the configuration directory and its content will be crated the first time you import the package:
@@ -69,7 +71,7 @@ import fargopy as fp
69
71
  %autoreload 2
70
72
  ```
71
73
 
72
- Running FARGOpy version 0.3.2
74
+ Running FARGOpy version 0.3.4
73
75
 
74
76
 
75
77
  If you are working on a remote Linux server, it is better to run the package using `IPython`. For this purpose, after installation, `FARGOpy` provides a special initialization command:
@@ -195,14 +197,12 @@ Or check the progress of the simulation:
195
197
  sim.status('progress')
196
198
  ```
197
199
 
198
- Progress of the simulation (numstatus = 5):
199
- 1:OUTPUTS 2 at date t = 12.566371 OK [output pace = 0.1 secs]
200
- 2:OUTPUTS 3 at date t = 18.849556 OK [output pace = 0.1 secs]
201
- 3:OUTPUTS 4 at date t = 25.132741 OK [output pace = 0.7 secs]
202
-
203
- ################################################################################
204
- Running status of the process:
205
- The process is running.
200
+ Progress of the simulation (numstatus = 5, interrupting may stop the process):
201
+ 1:OUTPUTS 0 at date t = 0.000000 OK [output pace = 0.1 secs]
202
+ 2:OUTPUTS 1 at date t = 6.283185 OK [output pace = 0.1 secs]
203
+ 3:OUTPUTS 2 at date t = 12.566371 OK [output pace = 1.6 secs]
204
+ 4:OUTPUTS 3 at date t = 18.849556 OK [output pace = 4.9 secs]
205
+ 5:OUTPUTS 4 at date t = 25.132741 OK [output pace = 4.9 secs]
206
206
 
207
207
 
208
208
  You may stop the simulation at any time using:
@@ -212,7 +212,7 @@ You may stop the simulation at any time using:
212
212
  sim.stop()
213
213
  ```
214
214
 
215
- Stopping FARGO3D process (pid = 24648)
215
+ Stopping FARGO3D process (pid = 18717)
216
216
 
217
217
 
218
218
  Check the status of the simulation using:
@@ -222,7 +222,7 @@ Check the status of the simulation using:
222
222
  sim.status('summary')
223
223
  ```
224
224
 
225
- The simulation has been ran for 7 time-steps (including the initial one).
225
+ The simulation has been ran for 6 time-steps (including the initial one).
226
226
 
227
227
 
228
228
  Once stopped you may resume the simulation at any snapshot or at the latest resumable snapshot:
@@ -232,8 +232,8 @@ Once stopped you may resume the simulation at any snapshot or at the latest resu
232
232
  sim.resume()
233
233
  ```
234
234
 
235
- Resuming from snapshot 5...
236
- Running asynchronously (test = False): ./fargo3d_SETUP-fargo_PARALLEL-0_GPU-0 -m -t -S 5 -t setups/fargo/fargo.par
235
+ Resuming from snapshot 4...
236
+ Running asynchronously (test = False): ./fargo3d_SETUP-fargo_PARALLEL-0_GPU-0 -m -t -S 4 -t -S 4 -t setups/fargo/fargo.par
237
237
  Now you are connected with output directory '/home/jzuluaga/fargo3d/outputs/fargo'
238
238
 
239
239
 
@@ -365,13 +365,26 @@ fp.Simulation.download_precomputed(setup='fargo')
365
365
  Downloading...
366
366
  From: https://docs.google.com/uc?export=download&id=1YXLKlf9fCGHgLej2fSOHgStD05uFB2C3
367
367
  To: /tmp/fargo.tgz
368
- 100%|██████████| 54.7M/54.7M [00:01<00:00, 31.2MB/s]
368
+ 100%|██████████| 54.7M/54.7M [01:14<00:00, 738kB/s]
369
369
 
370
370
 
371
371
  Uncompressing fargo.tgz into /tmp/fargo
372
372
  Done.
373
373
 
374
374
 
375
+ Once downloaded you may connect with simulation using:
376
+
377
+
378
+ ```python
379
+ sim = fp.Simulation(output_dir = '/tmp/fargo')
380
+ ```
381
+
382
+ Your simulation is now connected with '/home/jzuluaga/fargo3d/'
383
+ Now you are connected with output directory '/tmp/fargo'
384
+
385
+
386
+ and perform the postprocessing as explained before.
387
+
375
388
  We have prepared a set of precomputed simulations covering some interesting scientific cases. You may see the list of precomputed simulations available in the `FARGOpy` [cloud repository](https://drive.google.com/drive/folders/1NRdNOcmxRK-pHv_8vR-aAAJGWXxIOY0J?usp=sharing):
376
389
 
377
390
 
@@ -0,0 +1,13 @@
1
+ fargopy/__init__.py,sha256=U_z9F-T_dHEGDdoMpMrnaaUsQYcf3WREWFh7leP8nxc,11917
2
+ fargopy/fields.py,sha256=4sBm--gxgMdQcd6lsdPQ7ADnnGL550Cy_H2mNz80A-o,8837
3
+ fargopy/simulation.py,sha256=AJ0v9CtKA4Id1dedRH-o6G7bzdd-Ft-UntCzONKY1WE,37375
4
+ fargopy/sys.py,sha256=UQJXB4IHPujUNHsKX_hZChZBIlPaQbxafLShF2NDlsY,5589
5
+ fargopy/util.py,sha256=y39aTcvK1lM3vbuK11lE2bfj-eCcOzc0lKMvyBRW2-M,1584
6
+ fargopy/version.py,sha256=ZzAopkzJJDyniYfbnOQqEHng4wgVC2f65Lv2uZQOvsQ,16
7
+ fargopy-0.3.5.data/scripts/ifargopy,sha256=t5E07jKzOLtNnlNyElQZbzjCW6wnR0bc8uCaZpw9yS8,382
8
+ fargopy-0.3.5.dist-info/LICENSE,sha256=aIckKnNVrkXQMqEKlzGn_REfTwc82TF35BHMCRwPXCI,1097
9
+ fargopy-0.3.5.dist-info/METADATA,sha256=mtwwYtXGfzdSqhVncvdhU7o4cqZOXfn3ZO9XuueAzTo,15355
10
+ fargopy-0.3.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
11
+ fargopy-0.3.5.dist-info/entry_points.txt,sha256=555NPKYbLCN0fgJbdW4b4azZ5sqjhqVqTUxujBBYEJY,49
12
+ fargopy-0.3.5.dist-info/top_level.txt,sha256=_r66v1_-9T7dB5sQa12AdxaAdsv9-OTwtR-vft4OPBU,8
13
+ fargopy-0.3.5.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- fargopy/__init__.py,sha256=IReUK0HAUK6YXzeGrQVohGFBpe2znllaTae7MFoUnsY,11091
2
- fargopy/fields.py,sha256=4sBm--gxgMdQcd6lsdPQ7ADnnGL550Cy_H2mNz80A-o,8837
3
- fargopy/simulation.py,sha256=0bSDZNKMFuokWuAsLEiBetyJo_OAp8xLFsDtN7pK4qg,34260
4
- fargopy/sys.py,sha256=-RnUZJ5GnYHwIlI7UtjPlnyS88ptnrSBa9FvnF_2gDM,4311
5
- fargopy/util.py,sha256=y39aTcvK1lM3vbuK11lE2bfj-eCcOzc0lKMvyBRW2-M,1584
6
- fargopy/version.py,sha256=-ZmYFrDcd4hQWTPKmNo0_Nd2rsa4wiEtEUrlb_4E2Co,16
7
- fargopy-0.3.3.data/scripts/ifargopy,sha256=t5E07jKzOLtNnlNyElQZbzjCW6wnR0bc8uCaZpw9yS8,382
8
- fargopy-0.3.3.dist-info/LICENSE,sha256=aIckKnNVrkXQMqEKlzGn_REfTwc82TF35BHMCRwPXCI,1097
9
- fargopy-0.3.3.dist-info/METADATA,sha256=mNN5hzV5yUneDAqrvkxWgWMHZQiBYGI9sXw7vjRJaeE,14718
10
- fargopy-0.3.3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
11
- fargopy-0.3.3.dist-info/entry_points.txt,sha256=555NPKYbLCN0fgJbdW4b4azZ5sqjhqVqTUxujBBYEJY,49
12
- fargopy-0.3.3.dist-info/top_level.txt,sha256=_r66v1_-9T7dB5sQa12AdxaAdsv9-OTwtR-vft4OPBU,8
13
- fargopy-0.3.3.dist-info/RECORD,,