8 script_path = os.path.dirname(os.path.realpath(__file__))
9 sys.path.append(os.path.join(script_path,
'src_files/'))
13 import matplotlib.pyplot
as plt
18 p = optparse.OptionParser()
19 p.add_option(
"-i",
"--input", action=
"store", dest=
"rundir", default=
'.', \
20 help=
"Simulation directory to visualize (default: current directory)")
21 p.add_option(
"--disable_flow", action=
"store_true", dest=
"plot_flow", default=
False, \
22 help=
"Whether or not to plot the flow arrows.")
23 p.add_option(
"--flow_min", action=
"store", dest=
"flow_min", default=
"", \
24 help=
"Lower limit of the flow.")
25 p.add_option(
"--flow_max", action=
"store", dest=
"flow_max", default=
"", \
26 help=
"Upper limit of the flow.")
27 p.add_option(
"--fix_flows", action=
"store_true", dest=
"fix_flows", default=
False, \
28 help=
"Whether or not the flows are adapted to the data or lie between flow_min and flow_max.")
29 p.add_option(
"--flow_range", action=
"store", dest=
"flow_range", default=
"", \
30 help=
"Log range of the flows in case that they are not fixed.")
31 p.add_option(
"--fix_flow_arrow_width", action=
"store_true", dest=
"fix_flow_arrow_width", default=
False, \
32 help=
"Fix the width of the flow arrows to constant width.")
33 p.add_option(
"--flow_cmap", action=
"store", dest=
"flow_cmap", default=
"", \
34 help=
"Colormap of the flows.")
35 p.add_option(
"--separate_fission", action=
"store_true", dest=
"separate_fission", default=
False, \
36 help=
"Whether or not to show arrows also for fission. If not present, hatched areas will be plotted.")
37 p.add_option(
"--fission_minflow", action=
"store", dest=
"fission_minflow", default=
"", \
38 help=
"Minimum flow to get indicated as fission region in case the separate fission flag is not given.")
39 p.add_option(
"--x_min", action=
"store", dest=
"x_min", default=
"", \
40 help=
"Lower limit of the mass fraction.")
41 p.add_option(
"--x_max", action=
"store", dest=
"x_max", default=
"", \
42 help=
"Upper limit of the mass fraction.")
43 p.add_option(
"--x_cmap", action=
"store", dest=
"x_cmap", default=
"", \
44 help=
"Colormap of the mass fractions.")
45 p.add_option(
"--disable_abar", action=
"store_true", dest=
"disable_abar", default=
False, \
46 help=
"Whether or not disabling the indication of Abar.")
47 p.add_option(
"--mass_bins_cmap", action=
"store", dest=
"mass_bins_cmap", default=
"", \
48 help=
"Colormap of the background colors.")
49 p.add_option(
"--disable_magic", action=
"store_true", dest=
"disable_magic", default=
False, \
50 help=
"Whether or not disabling the indication for the magic number.")
51 p.add_option(
"--additional_plot", action=
"store", dest=
"additional_plot", default=
"", \
52 help=
"Whether or not to show an additional plot in the top left corner. "+
53 "Possible options are 'timescales', 'tracked', 'mainout', or 'energy'"+
54 " for plotting average timescales, mass fractions of tracked nuclei, additional mainout data"+
55 ", or nuclear energy generation.")
56 p.add_option(
"--tau_min", action=
"store", dest=
"tau_min", default=
"", \
57 help=
"Lower limit of the average timescales.")
58 p.add_option(
"--tau_max", action=
"store", dest=
"tau_max", default=
"", \
59 help=
"Upper limit of the average timescales.")
60 p.add_option(
"--engen_min", action=
"store", dest=
"engen_min", default=
"", \
61 help=
"Lower limit of the Energy.")
62 p.add_option(
"--engen_max", action=
"store", dest=
"engen_max", default=
"", \
63 help=
"Upper limit of the Energy.")
64 p.add_option(
"--tracked_min", action=
"store", dest=
"tracked_min", default=
"", \
65 help=
"Lower limit of the tracked nuclei mass fractions.")
66 p.add_option(
"--tracked_max", action=
"store", dest=
"tracked_max", default=
"", \
67 help=
"Upper limit of the tracked nuclei mass fractions.")
68 p.add_option(
"--amainout_min", action=
"store", dest=
"amainout_min", default=
"", \
69 help=
"Lower limit of the additional mainout abundances.")
70 p.add_option(
"--amainout_max", action=
"store", dest=
"amainout_max", default=
"", \
71 help=
"Upper limit of the additional mainout abundances.")
72 p.add_option(
"--time_min", action=
"store", dest=
"t_min", default=
"", \
73 help=
"Lower limit of the time.")
74 p.add_option(
"--time_max", action=
"store", dest=
"t_max", default=
"", \
75 help=
"Upper limit of the time.")
76 p.add_option(
"--disable_mainout", action=
"store_true", dest=
"disable_mainout", default=
False, \
77 help=
"Whether or not disabling the mainout plot.")
78 p.add_option(
"--density_min", action=
"store", dest=
"density_min", default=
"", \
79 help=
"Lower limit of the density.")
80 p.add_option(
"--density_max", action=
"store", dest=
"density_max", default=
"", \
81 help=
"Upper limit of the density.")
82 p.add_option(
"--temperature_min", action=
"store", dest=
"temperature_min", default=
"", \
83 help=
"Lower limit of the temperatures.")
84 p.add_option(
"--temperature_max", action=
"store", dest=
"temperature_max", default=
"", \
85 help=
"Upper limit of the temperature.")
86 p.add_option(
"--ye_min", action=
"store", dest=
"ye_min", default=
"", \
87 help=
"Lower limit of the electron fraction.")
88 p.add_option(
"--ye_max", action=
"store", dest=
"ye_max", default=
"", \
89 help=
"Upper limit of the electron fraction.")
90 p.add_option(
"--indicate_r_path", action=
"store_true", dest=
"indicate_r_path", default=
False, \
91 help=
"Whether or not to indicate a theoretical r-process path that has been calculated assuming "+\
92 "(n,gamma)(gamma,n) equilibrium.")
93 p.add_option(
"--frame_min", action=
"store", dest=
"frame_min", default=
"", \
94 help=
"Value of the first frame (default = 1).")
95 p.add_option(
"--frame_max", action=
"store", dest=
"frame_max", default=
"", \
96 help=
"Value of the last frame (default = end of the simulation).")
97 p.add_option(
"--save", action=
"store_true", dest=
"save", default=
False, \
98 help=
"Whether or not saving the movie.")
99 p.add_option(
"--save_frames", action=
"store_true", dest=
"save_frames", default=
False, \
100 help=
"Whether or not saving the frames into a folder.")
101 p.add_option(
"--output", action=
"store", dest=
"output_name", default=
'flow_movie.mp4', \
102 help=
"Output name of the movie.")
103 p.add_option(
'--parallel_save', action=
'store_true', dest=
'parallel_save', default=
False, \
104 help=
'Whether or not to save the movie in parallel.')
105 p.add_option(
'--parallel_cpus', action=
'store', dest=
'parallel_cpus', default=
'5', \
106 help=
'Number of CPUs to use for parallel saving.')
107 p.add_option(
"--interval", action=
"store", dest=
"interval", default=
'10', \
108 help=
"Interval of the movie (larger value equals slower).")
109 p.add_option(
"--mpirun_path", action=
"store", dest=
"mpirun_path", default=
'', \
110 help=
"Path of the mpirun command to use for parallel saving.")
111 p.add_option(
"--interactive", action=
"store_true", default=
False, \
112 help=
"Whether to show the movie in interactive mode.")
114 Visualize a WinNet simulation. Ensure that at least
115 snapshot_every or h_snapshot_every parameter was enabled in the
116 parameter file. To plot timescales, energy, tracked nuclei, mainout,
117 or reaction flows, the necessary parameters have to be enabled in the
120 Usage: ./winnet_movie.py -i <rundir>
121 Example: ./winnet_movie.py -i runs/test""")
125 (options,args) = p.parse_args()
126 run_path = options.rundir
129 kwargs[
'interactive'] = options.interactive
130 kwargs[
'timescalerange'] = (1e-12, 1e10)
131 kwargs[
'trackedrange'] = (1e-8, 1e0)
132 kwargs[
'energyrange'] = (1e10, 1e20)
133 kwargs[
'timerange'] = (1e-5 , 1e5)
134 kwargs[
'densityrange'] = (1e-5, 1e12)
135 kwargs[
'temperaturerange'] = (0, 10)
136 kwargs[
'yerange'] = (0.0, 0.55)
137 kwargs[
'amainoutrange'] = (5e-10,1e0)
139 if options.flow_min: kwargs[
'flow_min'] = float(options.flow_min)
140 if options.flow_max: kwargs[
'flow_max'] = float(options.flow_max)
141 if options.plot_flow: kwargs[
'plot_flow'] =
False if options.plot_flow
else True
142 if options.separate_fission: kwargs[
'separate_fission'] =
True
143 if options.fission_minflow: kwargs[
'fission_minflow'] = float(options.fission_minflow)
144 if options.fix_flows: kwargs[
'flow_adapt_prange'] =
False
145 if options.flow_range: kwargs[
'flow_prange'] = float(options.flow_range)
146 if options.fix_flow_arrow_width: kwargs[
'flow_adapt_width'] =
True
147 if options.flow_cmap: kwargs[
'cmapNameFlow'] = options.flow_cmap
148 if options.x_min: kwargs[
'X_min'] = float(options.x_min)
149 if options.x_max: kwargs[
'X_max'] = float(options.x_max)
150 if options.x_cmap: kwargs[
'cmapNameX'] = options.x_cmap
151 if options.disable_abar: kwargs[
'plot_abar'] = (
not options.disable_abar)
152 if options.mass_bins_cmap: kwargs[
'cmapNameMassBins'] = options.mass_bins_cmap
153 if options.disable_magic: kwargs[
'plot_magic'] = (
not options.disable_magic)
154 if options.additional_plot: kwargs[
'additional_plot'] = options.additional_plot.lower().strip()
155 if options.tau_min: kwargs[
'timescalerange'] = (float(options.tau_min),kwargs[
'timescalerange'][1])
156 if options.tau_max: kwargs[
'timescalerange'] = (kwargs[
'timescalerange'][0], float(options.tau_max))
157 if options.engen_min: kwargs[
'energyrange'] = (float(options.engen_min), kwargs[
'energyrange'][1])
158 if options.engen_max: kwargs[
'energyrange'] = (kwargs[
'energyrange'][0], float(options.engen_max))
159 if options.tracked_min: kwargs[
'trackedrange'] = (float(options.tracked_min), kwargs[
'trackedrange'][1])
160 if options.tracked_max: kwargs[
'trackedrange'] = (kwargs[
'trackedrange'][0], float(options.tracked_max))
161 if options.t_min: kwargs[
'timerange'] = (float(options.t_min), kwargs[
'timerange'][1])
162 if options.t_max: kwargs[
'timerange'] = (kwargs[
'timerange'][0], float(options.t_max))
163 if options.disable_mainout: kwargs[
'plot_mainout'] = (
not options.disable_mainout)
164 if options.density_min: kwargs[
'densityrange'] = (float(options.density_min), kwargs[
'densityrange'][1])
165 if options.density_max: kwargs[
'densityrange'] = (kwargs[
'densityrange'][0], float(options.density_max))
166 if options.temperature_min: kwargs[
'temperaturerange'] = (float(options.temperature_min), kwargs[
'temperaturerange'][1])
167 if options.temperature_max: kwargs[
'temperaturerange'] = (kwargs[
'temperaturerange'][0], float(options.temperature_max))
168 if options.ye_min: kwargs[
'yerange'] = (float(options.ye_min), kwargs[
'yerange'][1])
169 if options.ye_max: kwargs[
'yerange'] = (kwargs[
'yerange'][0], float(options.ye_max))
170 if options.amainout_min: kwargs[
'amainoutrange'] = (float(options.amainout_min), kwargs[
'amainoutrange'][1])
171 if options.amainout_max: kwargs[
'amainoutrange'] = (kwargs[
'amainoutrange'][0], float(options.amainout_max))
172 if options.indicate_r_path: kwargs[
'indicate_r_path'] =
True
180 value = w.check_existence(
'snapshot')
182 raise ValueError(
'No snapshots found. Please enable snapshots in the parameter file.')
185 if options.additional_plot:
186 if options.additional_plot ==
'timescales':
187 value = w.check_existence(
'timescales')
189 print(
'No timescales found. Disabling timescales. Remove --additional_plot to disable this message.')
190 kwargs[
'additional_plot'] =
'none'
191 elif options.additional_plot ==
'energy':
192 value = w.check_existence(
'energy')
194 print(
'No energy found. Disabling energy. Remove --additional_plot to disable this message.')
195 kwargs[
'additional_plot'] =
'none'
196 elif options.additional_plot ==
'tracked':
197 value = w.check_existence(
'tracked_nuclei')
199 print(
'No tracked nuclei found. Disabling tracked nuclei. Remove --additional_plot to disable this message.')
200 kwargs[
'additional_plot'] =
'none'
201 elif options.additional_plot ==
'mainout':
202 value = w.check_existence(
'mainout')
204 print(
'No mainout found. Disabling mainout. Remove --additional_plot to disable this message.')
205 kwargs[
'additional_plot'] =
'none'
206 if options.indicate_r_path:
207 value = w.check_existence(
'mainout')
209 print(
'No mainout found. Disabling r-process path. Remove --indicate_r_path to disable this message.')
210 kwargs[
'indicate_r_path'] =
False
211 if options.indicate_r_path
or options.interactive:
213 winvn_path = w.template[
'isotopes_file']
214 if not os.path.exists(os.path.join(run_path, winvn_path)):
215 print(
'No winvn.dat found. Falling back to default winvn path.')
217 winvn_path = os.path.join(script_path,
'../../data/winvne_v2.0.dat')
218 kwargs[
'winvn_path'] = winvn_path
219 if options.interactive:
220 kwargs[
'additional_plot'] =
'none'
221 if not options.disable_mainout:
222 value = w.check_existence(
'mainout')
224 print(
'No mainout found. Disabling mainout. Set --disable_mainout to disable this message.')
225 kwargs[
'plot_mainout'] =
False
226 if not options.plot_flow:
227 value = w.check_existence(
'flows')
229 print(
'No flow found. Disabling flow. Set --disable_flow to disable this message.')
230 kwargs[
'plot_flow'] =
False
233 if options.frame_min: frame_min = int(options.frame_min)
235 if options.frame_max: frame_max = int(options.frame_max)
236 else: frame_max = w.nr_of_snaps
239 if options.save_frames
and options.save:
240 raise ValueError(
'Cannot save frames and movie at the same time. Please choose one of them.')
243 if options.save_frames:
245 if options.output_name:
246 os.mkdir(options.output_name)
248 if not options.parallel_save:
250 fig = plt.figure(figsize=(15, 8))
251 if options.output_name:
252 anim =
FlowAnimation(run_path, fig, frame_dir=options.output_name, **kwargs)
257 for i
in tqdm(range(frame_min, frame_max)):
262 from mpi4py
import MPI
264 raise ImportError(
'mpi4py not found. Please install it to use parallel saving.')
267 if os.system(
'ffmpeg -version > /dev/null') != 0:
268 raise ImportError(
'ffmpeg not found. Please install it to use parallel saving.')
271 script_path = os.path.dirname(os.path.realpath(__file__))
278 raise ImportError(
'pickle not found. Please install it to use parallel saving.')
280 option_dict_path = os.path.join(script_path,
'src_files/data/options.pkl')
281 with open(option_dict_path,
'wb')
as f:
282 pickle.dump(kwargs, f)
285 parallel_save_path = os.path.join(script_path,
'src_files',
'parallel_save.py')
288 if not options.mpirun_path:
290 mpirun = os.popen(
'whereis mpirun').read().strip().split()
292 mpirun = [m
for m
in mpirun
if 'oneapi' in m]
294 raise ImportError(
'No mpirun with oneapi found. Please install it to use parallel saving.')
298 mpirun = options.mpirun_path
301 if os.system(f
'{mpirun} -version > /dev/null') != 0:
302 raise ImportError(
'mpirun not found or wrong path. Please install it to use parallel saving.')
305 os.system(f
'{mpirun} -n {options.parallel_cpus} python {parallel_save_path} {run_path} {frame_min} {frame_max} {options.interval} TRUE')
308 os.remove(option_dict_path)
311 if options.output_name:
312 os.system(f
'mv {run_path}/frames/* {options.output_name}')
314 print(
'Finished saving frames!')
318 if not options.parallel_save:
320 fig = plt.figure(figsize=(15, 8))
325 ani = anim.get_funcanimation(frames=range(frame_min, frame_max))
326 ani.save(options.output_name, fps=int(options.interval))
330 from mpi4py
import MPI
332 raise ImportError(
'mpi4py not found. Please install it to use parallel saving.')
335 if os.system(
'ffmpeg -version > /dev/null') != 0:
336 raise ImportError(
'ffmpeg not found. Please install it to use parallel saving.')
339 script_path = os.path.dirname(os.path.realpath(__file__))
346 raise ImportError(
'pickle not found. Please install it to use parallel saving.')
348 option_dict_path = os.path.join(script_path,
'src_files/data/options.pkl')
349 with open(option_dict_path,
'wb')
as f:
350 pickle.dump(kwargs, f)
353 parallel_save_path = os.path.join(script_path,
'src_files',
'parallel_save.py')
356 if not options.mpirun_path:
358 mpirun = os.popen(
'whereis mpirun').read().strip().split()
360 mpirun = [m
for m
in mpirun
if 'oneapi' in m]
362 raise ImportError(
'No mpirun with oneapi found. Please install it to use parallel saving.')
366 mpirun = options.mpirun_path
369 if os.system(f
'{mpirun} -version > /dev/null') != 0:
370 raise ImportError(
'mpirun not found or wrong path. Please install it to use parallel saving.')
373 os.system(f
'{mpirun} -n {options.parallel_cpus} python {parallel_save_path} {run_path} {frame_min} {frame_max} {options.interval}')
376 os.remove(option_dict_path)
378 print(
'Finished saving movie!')
381 fig = plt.figure(figsize=(15, 8))
385 ani = anim.get_funcanimation(interval=int(options.interval), frames=range(frame_min, frame_max))