14 import matplotlib.pyplot
as plt
19 p = optparse.OptionParser()
20 p.add_option(
"-i",
"--input" , action=
"store", dest=
"rundir", default=
'.', \
21 help=
"Simulation directory to summarize (default: current directory)")
22 p.add_option(
"-o",
"--output", action=
"store", dest=
"outdir", default=
'./summary.hdf5', \
23 help=
"Output path (default: summary.hdf5)")
24 p.add_option(
"-b",
"--buf" , action=
"store", dest=
"buffersize", default=
'500', \
25 help=
"Buffer size before writing to the file (default: 500)")
26 p.add_option(
"-f",
"--force", action=
"store_true", dest=
"force", default=
False, \
27 help=
"Force overwrite of the output file (default: False)")
28 p.add_option(
"-v",
"--verbose", action=
"store_true", dest=
"verbose", default=
False, \
29 help=
"Enable verbose output. If enabled, output is written to 'debug.log' (default: False)")
30 p.add_option(
"--time_file", action=
"store", dest=
"time_file", default=
None, \
31 help=
"File containing a time grid in seconds to map the data to (default: None)")
32 p.add_option(
"--time_final", action=
"store", dest=
"time_final", default=
None, \
33 help=
"Final time for the time grid. Only used if '--time_file' "+\
34 "is not given (default: Read from template file)")
35 p.add_option(
"--time_initial", action=
"store", dest=
"time_initial", default=
None, \
36 help=
"Initial time for the time grid. Only used if '--time_file' "+\
37 "is not given (default: 1e-5)")
38 p.add_option(
"--time_number", action=
"store", dest=
"time_number", default=
None, \
39 help=
"Number of time steps for the time grid. Only used if '--time_file' "+\
40 "is not given (default: 200)")
41 p.add_option(
"--sunet_path", action=
"store", dest=
"sunet_path", default=
None, \
42 help=
"Path to the sunet file (default: Read from template)")
43 p.add_option(
"--disable_mainout", action=
"store_true", dest=
"disable_mainout", default=
False, \
44 help=
"Disable the summary of the mainout output (default: False)")
45 p.add_option(
"--disable_energy", action=
"store_true", dest=
"disable_energy", default=
False, \
46 help=
"Disable the summary of the energy output (default: False)")
47 p.add_option(
"--disable_timescales", action=
"store_true", dest=
"disable_timescales", default=
False, \
48 help=
"Disable the summary of the timescales output (default: False)")
49 p.add_option(
"--disable_tracked_nuclei", action=
"store_true", dest=
"disable_tracked_nuclei", default=
False, \
50 help=
"Disable the summary of the tracked_nuclei output (default: False)")
51 p.add_option(
"--disable_nuloss", action=
"store_true", dest=
"disable_nuloss", default=
False, \
52 help=
"Disable the summary of the nuloss output (default: False)")
53 p.add_option(
"--disable_snapshots", action=
"store_true", dest=
"disable_snapshots", default=
False, \
54 help=
"Disable the summary of the snapshots output (default: False)")
57 Usage: ./summarize.py -i <rundir>
58 Example: ./summarize.py -i runs/test""")
62 (options,args) = p.parse_args()
63 run_path = options.rundir
67 buffsize = int(options.buffersize)
74 format=
"%(asctime)s - %(levelname)-10s - %(message)s",
76 datefmt=
"%Y-%m-%d %H:%M",
79 file_handler = logging.FileHandler(
"debug.log", mode=
"w", encoding=
"utf-8")
80 logger = logging.getLogger(__name__)
82 file_handler.setFormatter(logging.Formatter(
83 fmt=
"%(asctime)s - %(levelname)s - %(message)s",
84 datefmt=
"%Y-%m-%d %H:%M",
87 logger.addHandler(file_handler)
90 logging.basicConfig(level=logging.ERROR)
91 logger = logging.getLogger(__name__)
94 logger.propagate =
False
96 logger.info(f
"Started summarizing run at {run_path}.")
99 dirs = [d
for d
in os.listdir(run_path)
if os.path.isdir(os.path.join(run_path, d))
and d !=
"network_data"]
102 logger.info(f
"Found {len(dirs)} directories in {run_path}.")
106 output_file = options.outdir
108 if os.path.exists(output_file)
and not options.force:
109 logger.error(f
"Output file {output_file} already exists. Exiting.")
110 raise ValueError(f
"Output file {output_file} already exists. Either delete or use -f option to overwrite.")
111 elif os.path.exists(output_file)
and options.force:
112 logger.warning(f
"Output file {output_file} already exists. Overwriting it.")
113 f_hdf = h5py.File(output_file,
'w')
121 if not data.is_crashed:
122 logger.info(f
"Found {d} to look up the output.")
127 logger.error(
"All runs are crashed!")
128 raise ValueError(
"All runs are crashed!")
131 template_name = [f
for f
in os.listdir(os.path.join(run_path, d))
if f.endswith(
'.par')][0]
132 t =
template(os.path.join(run_path, d, template_name))
135 if options.sunet_path
is not None:
136 net_source = options.sunet_path
138 if (
not "net_source" in t.entries):
140 raise ValueError(
"net_source not given in the template file.")
143 net_source = t[
"net_source"]
146 logger.info(f
"Using sunet file from {net_source}.")
147 nuclei = np.loadtxt(net_source,dtype=str)
152 if options.time_file
is not None:
153 logger.info(f
"Using time grid from {options.time_file}.")
154 mainout_time = np.loadtxt(options.time_file, dtype=float, unpack=
True)
156 if options.time_final
is not None:
157 final_time = float(options.time_final)
162 if "termination_criterion" in t.entries:
163 if t[
"termination_criterion"] ==
"1":
164 if "final_time" in t.entries:
165 final_time = float(t[
"final_time"])
167 if options.time_initial
is not None:
168 initial_time = float(options.time_initial)
172 if options.time_number
is not None:
173 time_number = int(options.time_number)
177 mainout_time = np.logspace(np.log10(initial_time), np.log10(final_time), time_number)
181 possible_entries = []
182 if not options.disable_mainout:
183 possible_entries.append(
"mainout")
185 logger.info(
"Ignoring mainout output.")
186 if not options.disable_energy:
187 possible_entries.append(
"energy")
189 logger.info(
"Ignoring energy output.")
190 if not options.disable_timescales:
191 possible_entries.append(
"timescales")
193 logger.info(
"Ignoring timescales output.")
194 if not options.disable_tracked_nuclei:
195 possible_entries.append(
"tracked_nuclei")
197 logger.info(
"Ignoring tracked_nuclei output.")
198 if not options.disable_nuloss:
199 possible_entries.append(
"nuloss")
201 logger.info(
"Ignoring nuloss output.")
205 for entry
in possible_entries:
207 if data.check_existence(entry) != 0:
208 entry_dict[entry] = {}
209 for key
in data[entry].keys():
211 if ((key ==
"iteration")
or (key ==
"time")
or (key ==
"A")
or (key ==
"Z")
or (key ==
"N")
212 or (key ==
"names")
or (key ==
"latex_names")):
215 if (entry ==
"nuloss")
and ((key ==
"temp")
or (key ==
"dens")
or (key ==
"rad")):
217 entry_dict[entry][key] = np.zeros((len(mainout_time),buffsize))
220 f_hdf[entry+
"/time"] = mainout_time
223 logger.info(f
"Found {entry} in the data.")
234 if (data.check_existence(
"snapshot") != 0)
and (
not options.disable_snapshots):
235 if (
"custom_snapshots" in t.entries)
or (
"h_custom_snapshots" in t.entries):
237 summarize_snapshots =
False
238 if (
"custom_snapshots" in t.entries):
239 summarize_snapshots = (t[
"custom_snapshots"].strip().lower() ==
"yes")
241 if (t[
"custom_snapshots"].strip().lower() ==
"yes"):
242 logger.info(
"Found custom snapshots in ascii format.")
243 if (
"h_custom_snapshots" in t.entries):
244 summarize_snapshots = (summarize_snapshots
or (t[
"h_custom_snapshots"].strip().lower() ==
"yes"))
246 if (t[
"h_custom_snapshots"].strip().lower() ==
"yes"):
247 logger.info(
"Found custom snapshots in hdf5 format.")
250 if summarize_snapshots:
251 if "snapshot_file" not in t.entries:
252 raise ValueError(
"Invalid template file. snapshot_file not given in the template file.")
253 snapshot_time = np.loadtxt(os.path.join(t[
"snapshot_file"]),dtype=float)
255 snapshot_time *= 24*3600
257 f_hdf[
"snapshots/time"] = snapshot_time
259 f_hdf[
"snapshots/A"] = nuclei_data.A
260 f_hdf[
"snapshots/Z"] = nuclei_data.Z
261 f_hdf[
"snapshots/N"] = nuclei_data.N
263 snapshot_data = np.zeros((len(nuclei),len(snapshot_time),buffsize))
264 logger.info(f
"Summarize custom snapshots as well.")
266 summarize_snapshots =
False
268 summarize_snapshots =
False
269 if not options.disable_snapshots:
270 logger.info(
"Ignoring snapshots output.")
274 finab_data_Y = np.zeros((len(nuclei),buffsize))
275 finab_data_X = np.zeros((len(nuclei),buffsize))
278 f_hdf[
"finab/A"] = nuclei_data.A
279 f_hdf[
"finab/Z"] = nuclei_data.Z
280 f_hdf[
"finab/N"] = nuclei_data.N
283 dtype_nuclei = np.dtype([(
'A', int), (
'Z', int)])
284 nuclei_struct = np.array(list(zip(nuclei_data.A.astype(int), nuclei_data.Z.astype(int))), dtype=dtype_nuclei)
286 nuclei_sorted_idx = np.argsort(nuclei_struct)
287 sorted_nuclei_struct = nuclei_struct[nuclei_sorted_idx]
291 run_names = np.zeros(buffsize,dtype=
"S100")
292 run_ids = np.zeros(buffsize,dtype=int)
296 for counter, d
in enumerate(tqdm(dirs)):
298 data =
wreader(os.path.join(run_path, d),silent=
True)
301 logger.warning(f
"Run {d} is crashed. Skipping it.")
317 if ind % buffsize == 0
and ind != 0:
319 if "finab/Y" not in f_hdf:
320 f_hdf.create_dataset(
"finab/Y", (len(nuclei),ind+1), maxshape=(len(nuclei),
None))
321 f_hdf.create_dataset(
"finab/X", (len(nuclei),ind+1), maxshape=(len(nuclei),
None))
324 f_hdf[
"finab/Y"].resize((len(nuclei),ind+1))
325 f_hdf[
"finab/X"].resize((len(nuclei),ind+1))
327 f_hdf[
"finab/Y"][:,ind-buffsize:ind] = finab_data_Y
328 f_hdf[
"finab/X"][:,ind-buffsize:ind] = finab_data_X
331 finab_struct = np.array(list(zip(data.finab[
"A"].astype(int), data.finab[
"Z"].astype(int))), dtype=dtype_nuclei)
334 matching_idx = np.searchsorted(sorted_nuclei_struct, finab_struct)
336 indices = nuclei_sorted_idx[matching_idx]
339 finab_data_Y[:,ind % buffsize] = 0
340 finab_data_X[:,ind % buffsize] = 0
341 finab_data_Y[indices,ind % buffsize] = data.finab[
"Y"][:]
342 finab_data_X[indices,ind % buffsize] = data.finab[
"X"][:]
348 if ind % buffsize == 0
and ind != 0:
350 if "run_names" not in f_hdf:
351 f_hdf.create_dataset(
"run_names", (ind+1,), maxshape=(
None,),dtype=
"S100")
354 f_hdf[
"run_names"].resize((ind+1,))
356 f_hdf[
"run_names"][ind-buffsize:ind] = run_names
359 run_names[ind % buffsize] = d
364 if ind % buffsize == 0
and ind != 0:
366 if "run_ids" not in f_hdf:
367 f_hdf.create_dataset(
"run_ids", (ind+1,), maxshape=(
None,),dtype=int)
370 f_hdf[
"run_ids"].resize((ind+1,))
372 f_hdf[
"run_ids"][ind-buffsize:ind] = run_ids
375 run_ids[ind % buffsize] = int(re.findall(
r'\d+', d)[-1])
377 run_ids[ind % buffsize] = -1
382 if summarize_snapshots:
384 snapstime = data.snapshot_time
387 indexes = np.searchsorted(snapstime, snapshot_time)
390 if (len(snapstime) < len(snapshot_time)):
391 mask = np.zeros(len(snapshot_time),dtype=bool)
393 mask[np.min(np.abs(snapstime - snapshot_time[:,np.newaxis]),axis=1) > 1e-5] =
True
399 finab_struct = np.array(list(zip(data.A.astype(int), data.Z.astype(int))), dtype=dtype_nuclei)
402 matching_idx = np.searchsorted(sorted_nuclei_struct, finab_struct)
404 indices_nuclei = nuclei_sorted_idx[matching_idx]
407 if ind % buffsize == 0
and ind != 0:
409 if "snapshots/Y" not in f_hdf:
410 f_hdf.create_dataset(
"snapshots/Y", (len(nuclei),len(snapshot_time),ind+1), maxshape=(len(nuclei),len(snapshot_time),
None))
411 f_hdf.create_dataset(
"snapshots/X", (len(nuclei),len(snapshot_time),ind+1), maxshape=(len(nuclei),len(snapshot_time),
None))
414 f_hdf[
"snapshots/Y"].resize((len(nuclei),len(snapshot_time),ind+1))
415 f_hdf[
"snapshots/X"].resize((len(nuclei),len(snapshot_time),ind+1))
417 f_hdf[
"snapshots/Y"][:,:,ind-buffsize:ind] = snapshot_data
418 f_hdf[
"snapshots/X"][:,:,ind-buffsize:ind] = snapshot_data*nuclei_data.A[:,np.newaxis,np.newaxis]
421 snapshot_data[:,:,ind % buffsize] = 0
422 snapshot_data[indices_nuclei,:,ind % buffsize] = data.Y[indexes][:, :].T
426 snapshot_data[:,mask,ind % buffsize] = np.nan
432 for entry
in entry_dict.keys():
434 if ind % buffsize == 0
and ind != 0:
435 for key
in entry_dict[entry].keys():
437 if entry+
"/"+key
not in f_hdf:
438 f_hdf.create_dataset(entry+
"/"+key, (len(mainout_time),ind+1), maxshape=(len(mainout_time),
None))
441 f_hdf[entry+
"/"+key].resize((len(mainout_time),ind+1))
443 f_hdf[entry+
"/"+key][:,ind-buffsize:ind] = entry_dict[entry][key]
446 for key
in entry_dict[entry].keys():
447 entry_dict[entry][key][:,ind % buffsize] = np.interp(mainout_time,data[entry][
"time"],data[entry][key],left=np.nan,right=np.nan)
452 logger.info(f
"Finished looping over all directories, writing the last data to the hdf5 file.")
460 if "finab/Y" not in f_hdf:
461 f_hdf.create_dataset(
"finab/Y", (len(nuclei),ind+1), maxshape=(len(nuclei),
None))
462 f_hdf.create_dataset(
"finab/X", (len(nuclei),ind+1), maxshape=(len(nuclei),
None))
464 f_hdf[
"finab/Y"].resize((len(nuclei),ind+1))
465 f_hdf[
"finab/X"].resize((len(nuclei),ind+1))
468 f_hdf[
"finab/Y"][:,ind-buffsize+1:ind+1] = finab_data_Y[:,:buffsize]
469 f_hdf[
"finab/X"][:,ind-buffsize+1:ind+1] = finab_data_X[:,:buffsize]
471 f_hdf[
"finab/Y"][:,:ind+1] = finab_data_Y[:,:ind+1]
472 f_hdf[
"finab/X"][:,:ind+1] = finab_data_X[:,:ind+1]
478 if "run_names" not in f_hdf:
479 f_hdf.create_dataset(
"run_names", (ind+1,), maxshape=(
None,),dtype=
"S100")
481 f_hdf[
"run_names"].resize((ind+1,))
484 f_hdf[
"run_names"][ind-buffsize+1:ind+1] = run_names[:buffsize]
486 f_hdf[
"run_names"][:ind+1] = run_names[:ind+1]
489 if "run_ids" not in f_hdf:
490 f_hdf.create_dataset(
"run_ids", (ind+1,), maxshape=(
None,),dtype=int)
492 f_hdf[
"run_ids"].resize((ind+1,))
495 f_hdf[
"run_ids"][ind-buffsize+1:ind+1] = run_ids[:buffsize]
497 f_hdf[
"run_ids"][:ind+1] = run_ids[:ind+1]
503 if summarize_snapshots:
504 if "snapshots/Y" not in f_hdf:
505 f_hdf.create_dataset(
"snapshots/Y", (len(nuclei),len(snapshot_time),ind+1), maxshape=(len(nuclei),len(snapshot_time),
None))
506 f_hdf.create_dataset(
"snapshots/X", (len(nuclei),len(snapshot_time),ind+1), maxshape=(len(nuclei),len(snapshot_time),
None))
508 f_hdf[
"snapshots/Y"].resize((len(nuclei),len(snapshot_time),ind+1))
509 f_hdf[
"snapshots/X"].resize((len(nuclei),len(snapshot_time),ind+1))
512 f_hdf[
"snapshots/Y"][:,:,ind-buffsize+1:ind+1] = snapshot_data[:,:,:buffsize]
513 f_hdf[
"snapshots/X"][:,:,ind-buffsize+1:ind+1] = snapshot_data[:,:,:buffsize]*nuclei_data.A[:,np.newaxis,np.newaxis]
515 f_hdf[
"snapshots/Y"][:,:,:ind+1] = snapshot_data[:,:,:ind+1]
516 f_hdf[
"snapshots/X"][:,:,:ind+1] = snapshot_data[:,:,:ind+1]*nuclei_data.A[:,np.newaxis,np.newaxis]
522 for entry
in entry_dict.keys():
523 for key
in entry_dict[entry].keys():
524 if entry+
"/"+key
not in f_hdf:
525 f_hdf.create_dataset(entry+
"/"+key, (len(mainout_time),ind+1), maxshape=(len(mainout_time),
None))
527 f_hdf[entry+
"/"+key].resize((len(mainout_time),ind+1))
530 f_hdf[entry+
"/"+key][:,ind-buffsize+1:ind+1] = entry_dict[entry][key][:,:buffsize]
532 f_hdf[entry+
"/"+key][:,:ind+1] = entry_dict[entry][key][:,:ind+1]
537 logger.info(f
"Finished summarizing run at {run_path}.")