FlowAnimation.py
Go to the documentation of this file.
1 # Authors: M. Jacobi, J. Kuske, M. Reichert
2 ################################################################################
3 import os
4 import numpy as np
5 import matplotlib.pyplot as plt
6 import matplotlib as mpl
7 import matplotlib.patches as patches
8 import matplotlib.patheffects as PathEffects
9 from matplotlib.collections import PatchCollection
10 from tqdm import tqdm
11 from matplotlib import cm
12 from matplotlib.patches import Arrow, FancyBboxPatch
13 from matplotlib.colors import LogNorm, SymLogNorm
14 from matplotlib.colors import ListedColormap, LinearSegmentedColormap
15 from matplotlib.animation import FuncAnimation
16 from wreader import wreader
17 from h5py import File
18 from nucleus_multiple_class import nucleus_multiple
19 
20 ################################################################################
21 
22 class FlowAnimation(object):
23  """
24  Class to create an animation of the abundances and their flow for the nuclear reaction network WinNet.
25  """
26 
27  def __init__(
28  self,
29  path,
30  fig,
31  # Folder to save the frames in
32  frame_dir = None,
33  # Flows
34  plot_flow = True,
35  # flow_group = 'flows',
36  flow_min = 1e-8,
37  flow_max = 1e1,
38  separate_fission = True,
39  fission_minflow = 1e-10,
40  flow_cbar = True,
41  flow_adapt_prange = True,
42  flow_prange = 5,
43  flow_adapt_width = True,
44  flow_maxArrowWidth= 2.0,
45  flow_minArrowWidth= 0.3,
46  cmapNameFlow = 'viridis',
47  # Mass fractions
48  abun_cbar = True,
49  X_min = 1e-8,
50  X_max = 1,
51  cmapNameX = 'inferno',
52  # Mass bins
53  plot_abar = True,
54  plotMassBins = True,
55  addMassBinLabels = True,
56  alphaMassBins = 0.5,
57  cmapNameMassBins = 'jet',
58  massBins = [[1,1],[2,71],[72,93],[94,110],[111,144],[145,169],[170,187],[188,205],[206,252],[253,337]],
59  massBinLabels = ['','','1st peak','','2nd peak','rare earths', '', '3rd peak', '', 'fissioning'],
60  # Magic numbers
61  plot_magic = True,
62  # Additional plots
63  additional_plot = 'none',
64  # Tracked nuclei
65  trackedrange = (1e-8, 1),
66  # Energy
67  energyrange = (1e10, 1e20),
68  # Timescales
69  timescalerange = (1e-12, 1e10),
70  timerange = (1e-5 , 1e5),
71  # Mainout
72  plot_mainout = True,
73  densityrange = (1e-5, 1e12),
74  temperaturerange = (0, 10),
75  yerange = (0.0, 0.55),
76  plot_logo = True
77  ):
78  """
79  Parameters
80  ----------
81  path : str
82  Path to the WinNet data.
83  fig : matplotlib.figure.Figure
84  Figure to plot the animation on.
85  frame_dir : str
86  Folder to save the frames in, default is path/frames.
87  plot_flow : bool
88  Plot the flow of the abundances.
89  flow_min : float
90  Minimum value for the flow.
91  flow_max : float
92  Maximum value for the flow.
93  separate_fission : bool
94  Separate the fissioning region from the fission products in the flow plot.
95  fission_minflow : float
96  Minimum value to indicate a fission region.
97  flow_cbar : bool
98  Plot the colorbar for the flow.
99  flow_adapt_prange : bool
100  Adapt the color range of the flow to the data.
101  flow_prange : float
102  Range (in log10) of the flow.
103  flow_adapt_width : bool
104  Adapt the width of the flow arrows to the flow.
105  flow_maxArrowWidth : float
106  Maximum width of the flow arrows.
107  flow_minArrowWidth : float
108  Minimum width of the flow arrows.
109  cmapNameFlow : str
110  Name of the colormap for the flow.
111  abun_cbar : bool
112  Plot the colorbar for the mass fractions.
113  X_min : float
114  Minimum value for the mass fractions.
115  X_max : float
116  Maximum value for the mass fractions.
117  cmapNameX : str
118  Name of the colormap for the mass fractions.
119  plot_abar : bool
120  Plot the average mass number.
121  plotMassBins : bool
122  Plot the mass bins.
123  addMassBinLabels : bool
124  Add labels to the mass bins.
125  alphaMassBins : float
126  Transparency of the mass bins.
127  cmapNameMassBins : str
128  Name of the colormap for the mass bin color.
129  massBins : list
130  List of mass bins.
131  massBinLabels : list
132  List of labels for the mass bins.
133  plot_magic : bool
134  Plot the magic numbers in the abundance plot.
135  additional_plot : str
136  Additional plot to be made, possible values: 'None', 'timescales', 'energy', 'tracked'.
137  trackedrange : tuple
138  Range of the tracked nuclei plot.
139  energyrange : tuple
140  Range of the energy axis.
141  timescalerange : tuple
142  Range of the timescales.
143  timerange : tuple
144  Range of the time axis.
145  plot_mainout : bool
146  Plot the mainout data.
147  densityrange : tuple
148  Range of the density axis in the mainout plot.
149  temperaturerange : tuple
150  Range of the temperature axis in the mainout plot.
151  yerange : tuple
152  Range of the electron fraction axis in the mainout plot.
153  plot_logo : bool
154  Plot the WinNet logo.
155  """
156 
157 
158  # Make some sanity check and ensure that the user has the correct version of Matplotlib
159  if (mpl.__version__ < '3.8.0'):
160  print('Using old version of Matplotlib ('+str(mpl.__version__)+'), some features may not work.')
161  print('Need 3.8 or higher.')
162 
163  # Set the paths
164  # Data directory:
165  # Remember where this file is located
166  self.__script_path = os.path.dirname(os.path.abspath(__file__))
167  self.__data_path = os.path.join(self.__script_path,"data")
168  # Frame directory:
169  if frame_dir is None:
170  self.frame_dir = f'{path}/frames'
171  else:
172  self.frame_dir = frame_dir
173 
174  # WinNet run path
175  self.path = path
176 
177 
178 
179 
180  # Save the parameters in class variables
181  self.X_min = X_min # Minimum value for the mass fractions
182  self.X_max = X_max # Maximum value for the mass fractions
183  self.plotMassBins = plotMassBins # Plot the mass bins
184  self.plot_abar = plot_abar # Plot the average mass number
185  self.addMassBinLabels = addMassBinLabels # Add labels to the mass bins
186  self.alphaMassBins = alphaMassBins # Transparency of the mass bins
187  self.cmapNameMassBins = cmapNameMassBins # Name of the colormap for the mass bin color
188  self.massBins = massBins # List of mass bins
189  self.massBinLabels = massBinLabels # List of labels for the mass bins
190  self.additional_plot = additional_plot.lower() # Additional plot to be made, possible values: 'None', 'timescales', 'energy', 'tracked'
191  self.energyrange = energyrange # Range of the energy axis
192  self.trackedrange = trackedrange # Range of the tracked nuclei plot
193  self.timescalerange = timescalerange # Range of the timescales
194  self.timerange = timerange # Range of the time axis
195  self.plot_mainout = plot_mainout # Plot the mainout data
196  self.plot_logo = plot_logo # Plot the WinNet logo
197  self.flow_group = 'flows' # Name of the group in the HDF5 file that contains the flow data
198  self.plot_flow = plot_flow # Plot the flow of the abundances
199  self.fig = fig # Figure to plot the animation on
200  self.separate_fission = separate_fission # Separate the fissioning region from the fission products in the flow plot
201  self.plot_magic = plot_magic # Plot the magic numbers in the abundance plot
202  self.densityrange = densityrange # Range of the density axis in the mainout plot
203  self.temperaturerange = temperaturerange # Range of the temperature axis in the mainout plot
204  self.yerange = yerange # Range of the electron fraction axis in the mainout plot
205  self.cmapNameX = cmapNameX # Name of the colormap for the mass fractions
206  self.cmapNameFlow = cmapNameFlow # Name of the colormap for the flow
207  self.flow_adapt_width = flow_adapt_width # Adapt the width of the flow arrows to the flow
208  self.flow_maxArrowWidth = flow_maxArrowWidth # Maximum width of the flow arrows
209  self.flow_minArrowWidth = flow_minArrowWidth # Minimum width of the flow arrows
210  self.flow_min = flow_min # Minimum value for the flow
211  self.flow_max = flow_max # Maximum value for the flow
212  self.flow_adapt_prange = flow_adapt_prange # Adapt the color range of the flow to the data
213  self.fission_minflow = fission_minflow # Minimum value for the fission flow
214 
215  if (self.flow_adapt_prange):
216  self.flow_prange = flow_prange # Range (in log10) of the flow
217  else:
218  self.flow_prange = np.log10(self.flow_max) - np.log10(self.flow_min)
219 
220  # Check which additional plot should be made
221  if self.additional_plot == 'timescales':
222  self.plot_timescales = True
223  self.plot_energy = False
224  self.plot_tracked = False
225  elif self.additional_plot == 'energy':
226  self.plot_timescales = False
227  self.plot_energy = True
228  self.plot_tracked = False
229  elif self.additional_plot == 'tracked':
230  self.plot_timescales = False
231  self.plot_energy = False
232  self.plot_tracked = True
233  elif self.additional_plot == 'none':
234  self.plot_timescales = False
235  self.plot_energy = False
236  self.plot_tracked = False
237  else:
238  raise ValueError(f"Additional plot {self.additional_plot} not recognized. Possible values: 'None', 'timescales', 'energy', 'tracked'")
239 
240  # Initialize a class to read WinNet data
241  self.wreader = wreader(path)
242 
243  # Read the stable isotopes
244  self.N_stab, self.Z_stab = np.loadtxt(os.path.join(self.__data_path,'../../../class_files/data/stableiso.dat'),
245  unpack=True, usecols=(1, 2), dtype=int)
246 
247  # Read the nuclear chart nuclei
248  sunet_path = os.path.join(self.__data_path, "sunet_really_complete")
249  nuclei_names = np.loadtxt(sunet_path,dtype=str)
250  nm = nucleus_multiple(names=nuclei_names)
251  self.__A_plot = nm.A
252  self.__Z_plot = nm.Z
253  self.__N_plot = nm.N
254  self.__min_N, self.__max_N = np.min(self.__N_plot), np.max(self.__N_plot)
255  self.__min_Z, self.__max_Z = np.min(self.__Z_plot), np.max(self.__Z_plot)
256 
257 
258  # Other data that does not change like magic numbers
259  self.nMagic = [8, 20, 28, 50, 82, 126, 184] # Magic numbers in neutrons
260  self.zMagic = [8, 20, 28, 50, 82, 114] # Magic numbers in protons
261  self.magic_excess = 4 # How long should the line stick out over the nuc. chart?
262 
263  # Timescale plotting parameters
264  self.timescale_colors = ["C1","C2","C3","C4","C5","C6","C7","C8","C9","C0"]
265  self.timescale_entries = [['ag','ga'],['ng','gn'],['an','na'],['np','pn'],['pg','gp'],['ap','pa'],["beta"],["bfiss"],["nfiss"],["sfiss"]]
266  self.timescale_labels = [r"$\tau_{\alpha,\gamma}$",r"$\tau_{n,\gamma}$",r"$\tau_{\alpha,n}$",r"$\tau_{n,p}$",r"$\tau_{p,\gamma}$",
267  r"$\tau_{\alpha,p}$",r"$\tau_{\beta}$",r"$\tau_{\rm{bfiss}}$",r"$\tau_{\rm{nfiss}}$",r"$\tau_{\rm{sfiss}}$"]
268 
269  # Energy plotting parameters
270  self.energy_colors = ["k","C2","C3","C4","C5","C6","C7","C8","C9","C0"]
271  self.energy_entries = ['tot', 'ag_ga', 'ng_gn', 'an_na', 'np_pn', 'pg_gp', 'ap_pa', 'beta', 'fiss']
272  self.energy_labels = ['Total', r"$( \alpha,\gamma )$", r"$( n,\gamma )$", r"$( \alpha,n )$", r"$( n,p )$",
273  r"$( p,\gamma )$", r"$( \alpha,p )$", r"$\beta$", r"$\rm{fission}$"]
274  self.energy_lw = np.ones(len(self.energy_entries))
275  self.energy_lw[0] = 2
276 
277  # Set up the norm of the flow
278  self.flow_norm = LogNorm(flow_min, flow_max, clip=True)
279  # In case of adaptive flow ranges, keep track of the maximums to adapt the ranges with a rolling average
280  self.flow_max_history = np.ones(5)*np.nan
281 
282  # If the flow is not plotted, then the fissioning region should not be separated
283  # and the flow colorbar should not be plotted
284  if (not self.plot_flow):
285  self.separate_fission = False
286  flow_cbar = False
287 
288  # Initialize the axes and figure
289  self.init_axes()
290  # Initialize the data
291  self.init_data()
292  # Initialize the plot
293  self.init_plot()
294  # Initialize the colorbars
295  self.init_cbars(abun_cbar, flow_cbar)
296 
297 
298  def init_axes(self):
299  """
300  Initialize the axes and everything figure related of the plot.
301  """
302  # Make the hatch linewidth smaller
303  mpl.rcParams['hatch.linewidth'] = 0.8
304 
305  # Set up the figure
306  self.ax = self.fig.gca()
307  self.ax.set_aspect('equal')
308 
309  # Set up the axes for the nuclear chart
310  self.__init_nucchart_ax()
311 
312  # Set up the axes for the mainout plot
313  if self.plot_mainout:
314  self.__init_axMainout()
315 
316  # Set up the axes for the mass fraction plot
317  self.__init_axAbund()
318 
319  # Timescale stuff
320  if self.plot_timescales:
321  self.__init_axTimescales()
322 
323  # Energy stuff
324  if self.plot_energy:
325  self.__init_axEnergy()
326 
327  # Tracked nuclei
328  if self.plot_tracked:
329  self.__init_axTracked()
330 
331  # WinNet logo
332  if self.plot_logo:
333  self.__init_logo()
334 
335 
337  """
338  Initialize the axes and everything figure related of the nuclear chart.
339  """
340  # Set up the main figure of the nuclear chart, i.e., remove borders, ticks, etc.
341  self.ax.xaxis.set_visible(False)
342  self.ax.yaxis.set_visible(False)
343  self.ax.spines[['right', 'top', "bottom", "left"]].set_visible(False)
344 
345 
346  def __init_axAbund(self):
347  """
348  Initialize the axes and everything figure related of the mass fraction plot.
349  """
350  # Add summed mass fraction plot
351  self.axAbund = plt.axes([0.15,0.78,0.35,0.15])
352  self.axAbund.set_xlabel(r'Mass number $A$')
353  self.axAbund.set_ylabel(r'X(A)')
354  self.axAbund.set_xlim(0,300)
355  self.axAbund.set_yscale('log')
356  self.axAbund.set_ylim(self.X_min, self.X_max)
357  if self.plot_abar:
358  self.axAbund.axvline(np.nan, color='tab:red',label=r"$\bar{A}$")
359  self.axAbund.legend(loc='upper right')
360  # Add mass fraction bins if needed
361  if self.plotMassBins:
362  self.axMassFrac = self.axAbund.twinx()
363  self.axMassFrac.set_ylabel(r'$X(A)$')
364  self.axMassFrac.set_ylim(0,1)
365  self.axMassFrac.set_yscale('linear')
366 
367 
369  """
370  Initialize the axes and everything figure related of the timescales plot.
371  """
372  self.axTimescales = plt.axes([0.15,0.55,0.20,0.17])
373  self.axTimescales.set_xlabel('Time [s]')
374  self.axTimescales.set_ylabel('Timescales [s]')
375  self.axTimescales.set_yscale('log')
376  self.axTimescales.set_ylim(self.timescalerange[0],self.timescalerange[1])
377  self.axTimescales.set_xscale('log')
378  self.axTimescales.set_xlim(self.timerange[0],self.timerange[1])
379 
380  def __init_axTracked(self):
381  """
382  Initialize the axes and everything figure related of the tracked nuclei plot.
383  """
384  self.axTracked = plt.axes([0.15,0.55,0.20,0.17])
385  self.axTracked.set_xlabel('Time [s]')
386  self.axTracked.set_ylabel('Mass fractions')
387  self.axTracked.set_yscale('log')
388  self.axTracked.set_ylim(self.trackedrange[0],self.trackedrange[1])
389  self.axTracked.set_xscale('log')
390  self.axTracked.set_xlim(self.timerange[0],self.timerange[1])
391 
392  def __init_axEnergy(self):
393  """
394  Initialize the axes and everything figure related of the energy plot.
395  """
396  self.axEnergy = plt.axes([0.15,0.55,0.20,0.17])
397  self.axEnergy.set_xlabel('Time [s]')
398  self.axEnergy.set_ylabel('Energy [erg/g/s]')
399  self.axEnergy.set_yscale('log')
400  self.axEnergy.set_ylim(self.energyrange[0],self.energyrange[1])
401  self.axEnergy.set_xscale('log')
402  self.axEnergy.set_xlim(self.timerange[0],self.timerange[1])
403 
404  def __init_axMainout(self):
405  """
406  Initialize the axes and everything figure related of the mainout plot.
407  """
408  def make_patch_spines_invisible(ax):
409  ax.set_frame_on(True)
410  ax.patch.set_visible(False)
411  for sp in ax.spines.values():
412  sp.set_visible(False)
413  # Density
414  self.axMainout = plt.axes([0.65,0.2,0.25,0.25])
415  self.axMainout.set_xlabel('Time [s]')
416  self.axMainout.set_ylabel(r'Density [g/cm$^3$]')
417  self.axMainout.set_yscale('log')
418  self.axMainout.set_ylim(self.densityrange[0],self.densityrange[1])
419  self.axMainout.set_xscale('log')
420  self.axMainout.set_xlim(self.timerange[0],self.timerange[1])
421  # Temperature
422  self.axMainout_temp = self.axMainout.twinx()
423  self.axMainout_temp.set_ylabel(r'Temperature [GK]')
424  self.axMainout_temp.set_ylim(self.temperaturerange[0],self.temperaturerange[1])
425  self.axMainout_temp.spines["left"].set_position(("axes", -0.2))
426  make_patch_spines_invisible(self.axMainout_temp)
427  self.axMainout_temp.spines["left"].set_visible(True)
428  self.axMainout_temp.yaxis.set_label_position('left')
429  self.axMainout_temp.yaxis.set_ticks_position('left')
430  self.axMainout_temp.yaxis.label.set_color("tab:red")
431  self.axMainout_temp.yaxis.set_tick_params(colors="tab:red")
432  # Ye
433  self.axMainout_ye = self.axMainout.twinx()
434  self.axMainout_ye.set_ylabel(r'Electron fraction')
435  self.axMainout_ye.set_ylim(self.yerange[0],self.yerange[1])
436  make_patch_spines_invisible(self.axMainout_ye)
437  self.axMainout_ye.spines["right"].set_visible(True)
438  self.axMainout_ye.yaxis.set_label_position('right')
439  self.axMainout_ye.yaxis.set_ticks_position('right')
440  self.axMainout_ye.yaxis.label.set_color("tab:blue")
441  self.axMainout_ye.yaxis.set_tick_params(colors="tab:blue")
442 
443 
444  def __init_logo(self):
445  """
446  Initialize the axes and everything figure related of the WinNet logo.
447  """
448  self.axLogo = plt.axes([0.75,0.45,0.15,0.15])
449  self.axLogo.axis('off')
450  self.axLogo.imshow(plt.imread(os.path.join(self.__data_path,'WinNet_logo.png')))
451 
452 
453  def init_data(self):
454  """
455  Initialize the data for the plot.
456  """
457  # Read all things related to the snapshots
458  self.Z = self.wreader.Z
459  self.N = self.wreader.N
460  self.A = self.wreader.A
461  self.X = self.wreader.X[0,:]
462  # Get the number of timesteps, i.e., the number of snapshots
463  self.n_timesteps = self.wreader.nr_of_snaps
464 
465  # Set up timescale data
466  if self.plot_timescales:
467  self.ts_time = self.wreader.tau['time']
468  self.ts_data = [ [ self.wreader.tau["tau_"+str(self.timescale_entries[i][j])]
469  for j in range(len(self.timescale_entries[i]))] for i in range(len(self.timescale_entries)) ]
470 
471  # Set up energy data
472  if self.plot_energy:
473  self.energy_time = self.wreader.energy['time']
474  self.energy_data = [ self.wreader.energy['engen_'+self.energy_entries[i]] for i in range(len(self.energy_entries)) ]
475 
476  # Set up tracked nuclei data
477  if self.plot_tracked:
478  self.tracked_time = self.wreader.tracked_nuclei['time']
479  self.track_nuclei_data = [ self.wreader.tracked_nuclei[n] for n in self.wreader.tracked_nuclei['names'] ]
480  self.track_nuclei_labels= self.wreader.tracked_nuclei['latex_names']
481 
482 
483  # Set up mainout data
484  if self.plot_mainout:
485  self.mainout_time = self.wreader.mainout['time']
486  self.mainout_density = self.wreader.mainout['dens']
487  self.mainout_temperature = self.wreader.mainout['temp']
488  self.mainout_ye = self.wreader.mainout['ye']
489 
490  self.time = 0
491 
492  # Set up the Abar
493  self.Abar = 1.0/np.sum(self.X/self.A)
494  # Set up the sum of the mass fractions
495  self.Asum, self.Xsum = self.sum_over_A(self.A, self.X)
496  # Set up the mass fraction bins
497  self.Xbins = np.zeros(len(self.massBins),dtype=float)
498 
499  # Create custom colormap, with colormap for abundances and also the background colors
500  abucmap = mpl.colormaps[self.cmapNameX]
501  abundance_colors = abucmap(np.linspace(0, 1, 256))
502  massbin_colormap = mpl.colormaps[self.cmapNameMassBins]
503  amount_mass_bins = len(self.massBins)
504  massbin_colors = massbin_colormap(np.linspace(0, 1, amount_mass_bins))
505  massbin_colors[:,3] = self.alphaMassBins
506  self.massbin_colors = massbin_colors
507  newcolors = np.vstack((massbin_colors, abundance_colors))
508  self.__abundance_colors = ListedColormap(newcolors)
509  # Create the values for the colors
510  dist = (np.log10(self.X_max)-np.log10(self.X_min))/256.0
511  self.values = np.linspace(np.log10(self.X_min)-amount_mass_bins*dist, np.log10(self.X_max),num=256+amount_mass_bins+1,endpoint=True)
512 
513  # Create the background array that will contain numbers according to the background colors
514  background_Y = np.empty((self.__max_N+1, self.__max_Z+1))
515  background_Y[:,:] = np.nan
516  for index, mbin in enumerate(self.massBins):
517  mask = (self.__A_plot >= self.massBins[index][0]) & (self.__A_plot <= self.massBins[index][1])
518  background_Y[self.__N_plot[mask],self.__Z_plot[mask]] = self.values[index]
519  self.__background_Y = background_Y
520 
521  # Set up the axes for the nuclear chart
522  self.n = np.arange(0, self.__max_N+1)
523  self.z = np.arange(0, self.__max_Z+1)
524 
525  # Set up the abundance array
526  self.abun = self.__background_Y
527 
528  # Set up the array for the fission region
529  self.fis_region = np.zeros_like(self.abun)
530 
531  # Set up the flow arrays if necessary
532  if (self.plot_flow):
533  self.flow_N, self.flow_Z = np.array([0]), np.array([0])
534  self.flow_dn, self.flow_dz = np.array([0]), np.array([0])
535  self.flow = np.array([0])
536 
537 
538  def init_plot(self):
539  """
540  Initialize the plots.
541  """
542 
543  # Plot the nuclear chart
544  self.abun_im = self.ax.pcolormesh(self.n,self.z,self.abun.T,
545  cmap = self.__abundance_colors,vmin=(min(self.values)),
546  vmax=(max(self.values)),linewidth=0.0,edgecolor="face")
547 
548 
549  if (self.plot_flow):
550  # Plot the flows as quiver
551  self.quiver = self.ax.quiver(
552  self.flow_N, self.flow_Z,
553  self.flow_dn, self.flow_dz,
554  self.flow,
555  norm=self.flow_norm,
556  cmap=self.cmapNameFlow, angles='xy', scale_units='xy', scale=1,
557  units='xy', width=0.1, headwidth=3, headlength=4
558  )
559 
560  if self.flow_adapt_width:
561  # Create patchcollection of arrows
562  width = (self.flow_maxArrowWidth-self.flow_minArrowWidth)/self.flow_prange
563  with np.errstate(divide='ignore'):
564  arrowwidth = (np.log10(self.flow)-np.log10(self.flow_min))*width + self.flow_minArrowWidth
565  flow_arrows = [Arrow(self.flow_N[i],self.flow_Z[i],self.flow_dn[i],self.flow_dz[i],width=arrowwidth[i],color='k') for i in range(len(self.flow))]
566  a = PatchCollection(flow_arrows, cmap=self.cmapNameFlow, norm=self.flow_norm)
567  a.set_array(self.flow)
568  self.flow_patch = self.ax.add_collection(a)
569 
570  # Plot the fission region of positive fission products
571  fisspos = self.fis_region.T
572  fisspos[:] = np.nan
573  self.fis_im_pos = self.ax.pcolor(self.n,self.z,
574  fisspos,hatch='//////', edgecolor='tab:red',facecolor='none',
575  linewidth=0.0,zorder=1000
576  )
577 
578  # Plot the fission region of negative fission products
579  fissneg = self.fis_region.T
580  fissneg[:] = np.nan
581  self.fis_im_neg = self.ax.pcolor(self.n,self.z,
582  fissneg,hatch='//////', edgecolor='tab:blue',facecolor='none',
583  linewidth=0.0,zorder=1000
584  )
585 
586 
587  # Plot stable isotopes as black rectangles
588  edgecolors = np.full((max(self.n+1),max(self.z+1)),"none")
589  edgecolors[self.N_stab, self.Z_stab] = "k"
590  edgecolors = edgecolors.T.ravel()
591  self.stable_im = self.ax.pcolormesh(self.n,self.z,self.abun.T,
592  facecolor="none",linewidth=0.5,edgecolor=edgecolors)
593  # Alternatively make a scatter
594  # self.stable_im = self.ax.scatter(
595  # N_stab, Z_stab, c='k', marker='o', s=1)
596 
597  # Plot the sum of the mass fractions
598  self.mafra_plot = self.axAbund.plot(self.Asum, self.Xsum, color='k', lw=1.2)
599 
600  if self.plotMassBins:
601  # Plot the mass bins
602  self.mafrabin_plot = [self.axMassFrac.bar(self.massBins[i][0], self.Xbins[i],
603  width=self.massBins[i][1]+1-self.massBins[i][0], align='edge',
604  color=self.massbin_colors[i], edgecolor='grey') for i in range(len(self.massBins))]
605 
606  for i,b in enumerate(self.massBins):
607  px = (b[0])+1
608  py = 1
609  axis_to_data = self.axAbund.transAxes + self.axAbund.transData.inverted()
610  data_to_axis = axis_to_data.inverted()
611  trans = data_to_axis.transform((px,py))
612  txt = self.axAbund.text(trans[0],1.1,self.massBinLabels[i],transform = self.axAbund.transAxes,
613  ha='left',va='center',clip_on=False, fontsize=8,color=self.massbin_colors[i])
614  txt.set_path_effects([PathEffects.withStroke(linewidth=0.5, foreground='k')])
615 
616  # Plot the average mass number as red vertical line
617  if self.plot_abar:
618  self.Abar_plot = self.axAbund.axvline(self.Abar, color='tab:red', lw=1)
619 
620  # Plot the mainout data
621  if self.plot_mainout:
622  self.mainout_dens_plot = self.axMainout.plot (np.nan, np.nan, color='k' , lw=2, label=r"$\rho$")
623  self.mainout_temp_plot = self.axMainout_temp.plot(np.nan, np.nan, color='tab:red' , lw=2, label=r"T$_9$")
624  self.mainout_ye_plot = self.axMainout_ye.plot (np.nan, np.nan, color='tab:blue', lw=2, label=r"Y$_e$")
625  # Create the legend
626  lines = [self.mainout_dens_plot[0], self.mainout_temp_plot[0], self.mainout_ye_plot[0]]
627  self.axMainout.legend(lines, [l.get_label() for l in lines],loc='upper right')
628 
629  # Set the Textbox for the mainout data
630  left_side = "$t$"+"\n"+rf"$\rho$"+"\n"+rf"$T_9$"+"\n"+rf"$Y_e$"
631  right_side = f"= {self.format_time(self.mainout_time[-1])[0]}\n"+\
632  f"= {self.to_latex_exponent(self.mainout_density[-1])}\n"+\
633  f"= {self.to_latex_exponent(self.mainout_temperature[-1])}\n"+\
634  f"= {self.mainout_ye[-1]:.3f}"
635  units = f"{self.format_time(self.mainout_time[-1])[1]}\n"+\
636  f"g/cm$^3$\n"+\
637  "GK\n"+\
638  ""
639 
640  # Make a background box
641  y_pos = 0.07
642  rect = patches.FancyBboxPatch((0.35, y_pos-0.01), 0.17, 0.135, transform=self.ax.transAxes, boxstyle="round,pad=0.01", ec="k", fc="lightgrey", zorder=1,alpha=0.5)
643  self.ax.add_patch(rect)
644 
645  # Plot the text
646  self.ax.text(0.35, y_pos, left_side, transform=self.ax.transAxes, fontsize=12,)
647  self.Mainout_text = self.ax.text(0.37, y_pos, right_side, transform=self.ax.transAxes, fontsize=12,)
648  self.Mainout_units = self.ax.text(0.48, y_pos, units, transform=self.ax.transAxes, fontsize=12,)
649 
650 
651  # Set the arrow at the bottom left
652  arrowLength = 20
653  self.ax.arrow(-8, -8, arrowLength, 0, head_width=2, head_length=2, fc='k', ec='k')
654  self.ax.arrow(-8, -8, 0, arrowLength, head_width=2, head_length=2, fc='k', ec='k')
655  self.ax.text(arrowLength-8+3,0-8,'N',horizontalalignment='left',verticalalignment='center',fontsize=14,clip_on=True)
656  self.ax.text(0-8,arrowLength-8+3,'Z',horizontalalignment='center',verticalalignment='bottom',fontsize=14,clip_on=True)
657 
658  # Plot the timescales
659  if self.plot_timescales:
660  ls = ["-","--"]
661  self.ts_plot = [ [ self.axTimescales.plot(self.ts_time,self.ts_data[i][j], color=self.timescale_colors[i], ls=ls[j],
662  label=(self.timescale_labels[i] if (j == 0) else "")) for j in range(len(self.ts_data[i]))] for i in range(len(self.ts_data))]
663  # Also make the background of the box non-transparent
664  self.axTimescales.legend(loc='upper right', ncol=2, bbox_to_anchor=(1.3, 1.0), frameon=True, facecolor='white', edgecolor='black', framealpha=1.0, fontsize=8)
665 
666  # Plot the energy
667  if self.plot_energy:
668  self.energy_plot = [self.axEnergy.plot(self.energy_time,self.energy_data[i], color=self.energy_colors[i],
669  label=self.energy_labels[i], lw=self.energy_lw[i]) for i in range(len(self.energy_data))]
670  # Also make the background of the box non-transparent
671  self.axEnergy.legend(loc='upper right', ncol=2, bbox_to_anchor=(1.3, 1.0), frameon=True, facecolor='white', edgecolor='black', framealpha=1.0, fontsize=8)
672 
673  # Plot the tracked nuclei
674  if self.plot_tracked:
675  self.tracked_plot = [self.axTracked.plot(self.tracked_time,self.track_nuclei_data[i],
676  label=self.track_nuclei_labels[i]) for i in range(len(self.track_nuclei_labels))]
677  # Also make the background of the box non-transparent
678  self.axTracked.legend(loc='upper right', ncol=2, bbox_to_anchor=(1.3, 1.0), frameon=True, facecolor='white', edgecolor='black', framealpha=1.0, fontsize=8)
679 
680  # Plot magic numbers
681  if self.plot_magic:
682  # First neutron numbers
683  for n in self.nMagic:
684  if (any(self.__N_plot == n)):
685  # Find minimum and maximum Z for this N
686  zmin = np.min(self.__Z_plot[self.__N_plot == n])
687  zmax = np.max(self.__Z_plot[self.__N_plot == n])
688  # Plot horizontal line from zmin - self.magic_excess to zmax + self.magic_excess
689  self.ax.plot([n-0.5, n-0.5],[zmin-self.magic_excess, zmax+self.magic_excess], color='k', ls="--", lw=0.5)
690  self.ax.plot([n+0.5, n+0.5],[zmin-self.magic_excess, zmax+self.magic_excess], color='k', ls="--", lw=0.5)
691  # write the number on the bottom, truncate text when out of range
692  self.ax.text(n,zmin-self.magic_excess-1,int(n),ha='center',va='top',clip_on=True)
693  # Second proton numbers
694  for z in self.zMagic:
695  # Find minimum and maximum N for this Z
696  if (any(self.__Z_plot == z)):
697  nmin = np.min(self.__N_plot[self.__Z_plot == z])
698  nmax = np.max(self.__N_plot[self.__Z_plot == z])
699  self.ax.plot([nmin-self.magic_excess, nmax+self.magic_excess],[z-0.5, z-0.5], color='k', ls="--", lw=0.5)
700  self.ax.plot([nmin-self.magic_excess, nmax+self.magic_excess],[z+0.5, z+0.5], color='k', ls="--", lw=0.5)
701  # write the number on the bottom
702  self.ax.text(nmin-self.magic_excess-1,z,int(z),ha='right',va='center',clip_on=True)
703 
704  if self.separate_fission:
705  # Make a legend
706  # Get the ratio of x and y of the figure
707  ratio = self.fig.get_figwidth()/self.fig.get_figheight()
708  self.ax.add_patch(mpl.patches.Rectangle((0.88, 0.70), 0.01, 0.01*ratio, fill=False, transform=self.ax.transAxes, hatch="////", edgecolor='tab:blue', lw=1))
709  self.ax.text(0.9, 0.70, 'Fissioning region', transform=self.ax.transAxes, fontsize=8, verticalalignment='bottom', horizontalalignment='left')
710  self.ax.add_patch(mpl.patches.Rectangle((0.88, 0.67), 0.01, 0.01*ratio, fill=False, transform=self.ax.transAxes, hatch="////", edgecolor='tab:red', lw=1))
711  self.ax.text(0.9, 0.67, 'Fission products', transform=self.ax.transAxes, fontsize=8, verticalalignment='bottom', horizontalalignment='left')
712 
713 
714  def init_cbars(self, abun_cbar, flow_cbar):
715  """
716  Initialize the colorbars.
717  """
718  # Set up the number of colorbars
719  n_cbars = abun_cbar + flow_cbar
720  if n_cbars == 0:
721  self.cax = []
722  return
723  if n_cbars == 1:
724  self.cax = [self.fig.add_axes([0.75, 0.88, 0.14, 0.02])]
725  elif n_cbars == 2:
726  self.cax = [self.fig.add_axes([0.58, 0.88, 0.14, 0.02]),
727  self.fig.add_axes([0.75, 0.88, 0.14, 0.02])]
728 
729  # Counter for the colorbars
730  ii = 0
731  # Plot the abundance colorbar
732  if abun_cbar:
733  # Make a custom colormap since the abundance one has the background colors in as well
734  self.abun_cbar = self.fig.colorbar(mpl.cm.ScalarMappable(norm=LogNorm(vmin=self.X_min,vmax=self.X_max), cmap="inferno"),
735  cax=self.cax[ii], orientation='horizontal', label='')
736  self.abun_cbar.ax.set_title('Mass fraction')
737  ii += 1
738 
739  # Plot the flow colorbar
740  if flow_cbar:
741  self.flow_cbar=self.fig.colorbar(
742  self.quiver,
743  cax=self.cax[ii],
744  orientation='horizontal',
745  label='',
746  )
747  self.flow_cbar.ax.set_title('Flow')
748  ii += 1
749 
750 
751  def update_data(self, ii):
752  """
753  Update the data for the plot.
754  """
755 
756  self.time = self.wreader.snapshot_time[ii]
757  yy = self.wreader.Y[ii]
758  xx = yy * self.A
759  self.abun = self.__background_Y.copy()
760  mask = xx > self.X_min
761  self.abun[self.N[mask], self.Z[mask]] = np.log10(xx[mask])
762 
763  self.Asum, self.Xsum = self.sum_over_A(self.A, xx)
764  self.Abar = 1.0/np.sum(yy)
765 
766  for i in range(len(self.massBins)):
767  mask = (self.A >= self.massBins[i][0]) & (self.A <= self.massBins[i][1])
768  self.Xbins[i] = np.sum(xx[mask])
769 
770 
771  if self.plot_timescales:
772  self.ts_time = self.wreader.tau['time'][:ii]
773  self.ts_time = self.ts_time-self.ts_time[0]
774  self.ts_data = [ [ self.wreader.tau['tau_'+str(self.timescale_entries[i][j])][:ii]
775  for j in range(len(self.timescale_entries[i]))] for i in range(len(self.timescale_entries)) ]
776 
777  if self.plot_energy:
778  self.energy_time = self.wreader.energy['time'][:ii]
779  self.energy_time = self.energy_time-self.energy_time[0]
780  self.energy_data = [ self.wreader.energy['engen_'+self.energy_entries[i]][:ii] for i in range(len(self.energy_entries)) ]
781 
782  if self.plot_tracked:
783  self.tracked_time = self.wreader.tracked_nuclei['time'][:ii]
784  self.tracked_time = self.tracked_time-self.tracked_time[0]
785  self.track_nuclei_data = [ self.wreader.tracked_nuclei[n][:ii] for n in self.wreader.tracked_nuclei['names'] ]
786 
787  if self.plot_mainout:
788  self.mainout_time = self.wreader.mainout['time'][:ii]
789  self.mainout_time = self.mainout_time-self.mainout_time[0]
790  self.mainout_density = self.wreader.mainout['dens'][:ii]
791  self.mainout_temperature = self.wreader.mainout['temp'][:ii]
792  self.mainout_ye = self.wreader.mainout['ye'][:ii]
793 
794  if ii == 0: return # no flows in first timestep
795 
796  if self.plot_flow:
797  fpath=f'{self.path}/WinNet_data.h5'
798  flow_dict = self.wreader.flow_entry(ii, self.flow_group)
799  nin = flow_dict['n_in']
800  zin = flow_dict['p_in']
801  nout = flow_dict['n_out']
802  zout = flow_dict['p_out']
803  flow = flow_dict['flow']
804  dz = zout - zin
805  dn = nout - nin
806  mask = flow > min(self.flow_norm.vmin,self.fission_minflow)
807  self.flow_N = nin[mask]
808  self.flow_Z = zin[mask]
809  self.flow_dn = dn[mask]
810  self.flow_dz = dz[mask]
811  self.flow = flow[mask]
812  # Keep track of the maximum flows for the colorbar
813  self.flow_max_history = np.roll(self.flow_max_history,1)
814  self.flow_max_history[0] = np.max(self.flow)
815  if self.separate_fission:
816  self.handle_fission()
817 
818 
819 
820  def handle_fission(self,):
821  """
822  Separate the fissioning region from the fission products in the flow plot.
823  """
824 
825  fis_mask = np.abs(self.flow_dn + self.flow_dz) > 32
826  fis_N = self.flow_N[fis_mask]
827  fis_Z = self.flow_Z[fis_mask]
828  fis_dn = self.flow_dn[fis_mask]
829  fis_dz = self.flow_dz[fis_mask]
830  fis_flow = self.flow[fis_mask]
831 
832  mask = self.flow>self.flow_norm.vmin
833 
834  self.flow_N = self.flow_N[((~fis_mask) & mask)]
835  self.flow_Z = self.flow_Z[((~fis_mask) & mask)]
836  self.flow_dn = self.flow_dn[((~fis_mask) & mask)]
837  self.flow_dz = self.flow_dz[((~fis_mask) & mask)]
838  self.flow = self.flow[((~fis_mask) & mask)]
839 
840  self.fis_region.fill(0)
841  for nn, zz, dn, dz, ff in zip(fis_N, fis_Z, fis_dn, fis_dz, fis_flow):
842  self.fis_region[nn, zz] -= ff
843  self.fis_region[nn+dn, zz+dz] += ff
844  self.fis_region[(self.fis_region == 0)] = np.nan
845 
846 
847  def update_abun_plot(self,):
848  self.abun_im.set_array(self.abun.T)
849  self.mafra_plot[0].set_ydata(self.Xsum)
850  if self.plot_abar:
851  self.Abar_plot.set_xdata([self.Abar])
852  if self.plotMassBins:
853  [self.mafrabin_plot[i][0].set_height(self.Xbins[i]) for i in range(len(self.massBins))]
854  if self.plot_timescales:
855  [ [ self.ts_plot[i][j][0].set_xdata(self.ts_time) for j in range(len(self.ts_plot[i]))] for i in range(len(self.ts_plot)) ]
856  [ [ self.ts_plot[i][j][0].set_ydata(self.ts_data[i][j]) for j in range(len(self.ts_plot[i]))] for i in range(len(self.ts_plot)) ]
857  if self.plot_energy:
858  [ self.energy_plot[i][0].set_xdata(self.energy_time) for i in range(len(self.energy_plot))]
859  [ self.energy_plot[i][0].set_ydata(self.energy_data[i]) for i in range(len(self.energy_plot))]
860  if self.plot_tracked:
861  [ self.tracked_plot[i][0].set_xdata(self.tracked_time) for i in range(len(self.tracked_plot))]
862  [ self.tracked_plot[i][0].set_ydata(self.track_nuclei_data[i]) for i in range(len(self.tracked_plot))]
863 
864  if self.plot_mainout:
865  self.mainout_dens_plot[0].set_xdata(self.mainout_time)
866  self.mainout_dens_plot[0].set_ydata(self.mainout_density)
867  self.mainout_temp_plot[0].set_xdata(self.mainout_time)
868  self.mainout_temp_plot[0].set_ydata(self.mainout_temperature)
869  self.mainout_ye_plot[0].set_xdata(self.mainout_time)
870  self.mainout_ye_plot[0].set_ydata(self.mainout_ye)
871  right_side = f"= {self.to_latex_exponent(self.format_time(self.mainout_time[-1])[0])}\n"+\
872  f"= {self.to_latex_exponent(self.mainout_density[-1])}\n"+\
873  f"= {self.to_latex_exponent(self.mainout_temperature[-1])}\n"+\
874  f"= {self.mainout_ye[-1]:.3f}"
875  self.Mainout_text.set_text(right_side)
876  units = f"{self.format_time(self.mainout_time[-1])[1]}\n"+\
877  f"g/cm$^3$\n"+\
878  "GK\n"+\
879  ""
880  self.Mainout_units.set_text(units)
881 
882 
884  if self.plot_flow:
885  fisspos = self.fis_region.T.copy()
886  fisspos[self.fis_region.T<0] = np.nan
887  self.fis_im_pos.set_array(fisspos)
888  fissneg = self.fis_region.T.copy()
889  fissneg[self.fis_region.T>0] = np.nan
890  self.fis_im_neg.set_array(fissneg)
891 
892  def update_flow_plot(self,):
893  if self.plot_flow:
894  # Adapt flowmin and flowmax
895  if self.flow_adapt_prange:
896  lmaxflow = (np.nanmean(np.log10(self.flow_max_history)))+0.5
897  lminflow = lmaxflow-self.flow_prange
898  self.flow_cbar.mappable.set_clim(vmin=10**lminflow, vmax=10**lmaxflow)
899  self.flow_max = 10**lmaxflow
900  self.flow_min = 10**lminflow
901 
902  # Plot with a quiver as the width does not have to be adapted
903  if not self.flow_adapt_width:
904  self.quiver.N=len(self.flow_N)
905  self.quiver.set_offsets(np.array([self.flow_N, self.flow_Z]).T)
906  self.quiver.set_UVC(self.flow_dn, self.flow_dz, self.flow)
907  else:
908  # Quiver does not allow for changing the width of the arrows
909  # Therefore, we have to us a patchcollection and draw it everytime new.
910  self.flow_patch.remove()
911  width = (self.flow_maxArrowWidth-self.flow_minArrowWidth)/self.flow_prange
912  with np.errstate(divide='ignore'):
913  arrowwidth = (np.log10(self.flow)-np.log10(self.flow_min))*width + self.flow_minArrowWidth
914  flow_arrows = [Arrow(self.flow_N[i],self.flow_Z[i],self.flow_dn[i],self.flow_dz[i],width=arrowwidth[i],color='k') for i in range(len(self.flow))]
915  a = PatchCollection(flow_arrows, cmap=self.cmapNameFlow, norm=self.flow_norm)
916  a.set_array(self.flow)
917  self.flow_patch = self.ax.add_collection(a)
918 
919 
920  def update_frame(self, ii):
921  self.update_data(ii)
922 
923  self.update_abun_plot()
924  self.update_fission_plot()
925  self.update_flow_plot()
926  return ii
927 
928 
929  def save_frame(self, ii):
930  self.update_frame(ii)
931  # self.fig.canvas.draw()
932  # self.fig.canvas.flush_events()
933  plt.savefig(f'{self.frame_dir}/frame_{ii}.png',
934  dpi=300, bbox_inches='tight')
935  return ii
936 
937  def get_funcanimation(self, frames=None, **kwargs):
938  if frames is None:
939  frames = range(self.n_timesteps)
940  return FuncAnimation(self.fig, self.update_frame,
941  frames=frames, **kwargs)
942 
943 
944  @staticmethod
946  """
947  Convert a number to a latex string with exponent.
948  """
949  if x == 0:
950  return '0'
951  exponent = np.floor(np.log10(x))
952  mantissa = x / 10**exponent
953  return f'{mantissa:.2f}'+r'$\times 10^{'+f'{int(exponent)}'+r'}$'
954 
955 
956  @staticmethod
957  def format_time(time):
958  """
959  Format a time in seconds to a more human readable format.
960  """
961  if time < 1:
962  return time*1000, 'ms'
963  if time < 60:
964  return time, 's'
965  if time < 3600:
966  return time/60, 'min'
967  if time < 3600*24:
968  return time/3600, 'h'
969  if time < 3600*24*365:
970  return time/86400, 'd'
971  if time < 3600*24*365*1000:
972  return time/31536000, 'y'
973  if time < 3600*24*365*1000*1000:
974  return time/31536000/1000, 'ky'
975  else:
976  return time/31536000_000_000, 'My'
977 
978  def sum_over_A(self,A,X):
979  A_unique = np.arange(max(A)+1)
980  X_sum = np.zeros_like(A_unique,dtype=float)
981  for a, x in zip(A,X):
982  X_sum[int(a)] += x
983  return A_unique, X_sum
984 
985 ################################################################################
986 
987 # Funcanimation
988 
989 if __name__ == "__main__":
990  run_path = "../Example_NSM_dyn_ejecta_rosswog_hdf5"
991  fig = plt.figure(figsize=(15, 8))
992 
993  # z_drip , n_drip = np.loadtxt('/home/mjacobi/frdm/dripline.dat', unpack=True)
994  # plt.plot(n_drip, z_drip, 'k--', lw=1)
995 
996  anim = FlowAnimation(run_path, fig, flow_group='flows')
997  ani = anim.get_funcanimation(interval=10, frames=range(1, anim.n_timesteps))
998  plt.show()
src_files.FlowAnimation.FlowAnimation.format_time
def format_time(time)
Definition: FlowAnimation.py:957
src_files.FlowAnimation.FlowAnimation.mainout_density
mainout_density
Definition: FlowAnimation.py:486
src_files.FlowAnimation.FlowAnimation.update_abun_plot
def update_abun_plot(self)
Definition: FlowAnimation.py:847
src_files.FlowAnimation.FlowAnimation.axMainout
axMainout
Definition: FlowAnimation.py:414
src_files.FlowAnimation.FlowAnimation.__A_plot
__A_plot
Definition: FlowAnimation.py:201
src_files.FlowAnimation.FlowAnimation.timescale_entries
timescale_entries
Definition: FlowAnimation.py:215
src_files.FlowAnimation.FlowAnimation.flow_adapt_prange
flow_adapt_prange
Definition: FlowAnimation.py:162
src_files.FlowAnimation.FlowAnimation.cmapNameX
cmapNameX
Definition: FlowAnimation.py:155
src_files.FlowAnimation.FlowAnimation.stable_im
stable_im
Definition: FlowAnimation.py:591
src_files.FlowAnimation.FlowAnimation.ts_plot
ts_plot
Definition: FlowAnimation.py:661
src_files.FlowAnimation.FlowAnimation.magic_excess
magic_excess
Definition: FlowAnimation.py:211
src_files.FlowAnimation.FlowAnimation.plot_timescales
plot_timescales
Definition: FlowAnimation.py:172
src_files.FlowAnimation.FlowAnimation.__init_axEnergy
def __init_axEnergy(self)
Definition: FlowAnimation.py:392
src_files.FlowAnimation.FlowAnimation.Xsum
Xsum
Definition: FlowAnimation.py:495
src_files.FlowAnimation.FlowAnimation.axLogo
axLogo
Definition: FlowAnimation.py:448
src_files.FlowAnimation.FlowAnimation.axMainout_ye
axMainout_ye
Definition: FlowAnimation.py:433
src_files.FlowAnimation.FlowAnimation.n
n
Definition: FlowAnimation.py:522
src_files.FlowAnimation.FlowAnimation.cax
cax
Definition: FlowAnimation.py:721
src_files.FlowAnimation.FlowAnimation.densityrange
densityrange
Definition: FlowAnimation.py:152
src_files.FlowAnimation.FlowAnimation.quiver
quiver
Definition: FlowAnimation.py:551
src_files.FlowAnimation.FlowAnimation.Abar
Abar
Definition: FlowAnimation.py:493
src_files.FlowAnimation.FlowAnimation.Z_stab
Z_stab
Definition: FlowAnimation.py:194
src_files.FlowAnimation.FlowAnimation.flow_maxArrowWidth
flow_maxArrowWidth
Definition: FlowAnimation.py:158
src_files.FlowAnimation.FlowAnimation.mafrabin_plot
mafrabin_plot
Definition: FlowAnimation.py:602
src_files.FlowAnimation.FlowAnimation.z
z
Definition: FlowAnimation.py:523
src_files.FlowAnimation.FlowAnimation.plot_mainout
plot_mainout
Definition: FlowAnimation.py:145
src_files.FlowAnimation.FlowAnimation.sum_over_A
def sum_over_A(self, A, X)
Definition: FlowAnimation.py:978
src_files.FlowAnimation.FlowAnimation.frame_dir
frame_dir
Definition: FlowAnimation.py:120
src_files.FlowAnimation.FlowAnimation.flow_min
flow_min
Definition: FlowAnimation.py:160
src_files.FlowAnimation.FlowAnimation.alphaMassBins
alphaMassBins
Definition: FlowAnimation.py:136
src_files.FlowAnimation.FlowAnimation.to_latex_exponent
def to_latex_exponent(x)
Definition: FlowAnimation.py:945
src_files.FlowAnimation.FlowAnimation.ts_time
ts_time
Definition: FlowAnimation.py:467
src_files.FlowAnimation.FlowAnimation.fis_region
fis_region
Definition: FlowAnimation.py:529
src_files.FlowAnimation.FlowAnimation.massBins
massBins
Definition: FlowAnimation.py:138
src_files.FlowAnimation.FlowAnimation.axTimescales
axTimescales
Definition: FlowAnimation.py:372
src_files.FlowAnimation.FlowAnimation.init_axes
def init_axes(self)
Definition: FlowAnimation.py:298
src_files.FlowAnimation.FlowAnimation.plot_tracked
plot_tracked
Definition: FlowAnimation.py:174
src_files.FlowAnimation.FlowAnimation.separate_fission
separate_fission
Definition: FlowAnimation.py:150
src_files.FlowAnimation.FlowAnimation.n_timesteps
n_timesteps
Definition: FlowAnimation.py:463
src_files.FlowAnimation.FlowAnimation.flow_max
flow_max
Definition: FlowAnimation.py:161
src_files.FlowAnimation.FlowAnimation.__init_axTimescales
def __init_axTimescales(self)
Definition: FlowAnimation.py:368
src_files.FlowAnimation.FlowAnimation.flow_patch
flow_patch
Definition: FlowAnimation.py:568
src_files.FlowAnimation.FlowAnimation.Z
Z
Definition: FlowAnimation.py:458
src_files.FlowAnimation.FlowAnimation.flow_Z
flow_Z
Definition: FlowAnimation.py:533
src_files.FlowAnimation.FlowAnimation.ax
ax
Definition: FlowAnimation.py:306
src_files.FlowAnimation.FlowAnimation.track_nuclei_labels
track_nuclei_labels
Definition: FlowAnimation.py:480
src_files.FlowAnimation.FlowAnimation.energyrange
energyrange
Definition: FlowAnimation.py:141
src_files.FlowAnimation.FlowAnimation.axTracked
axTracked
Definition: FlowAnimation.py:384
src_files.FlowAnimation.FlowAnimation.__Z_plot
__Z_plot
Definition: FlowAnimation.py:202
src_files.FlowAnimation.FlowAnimation.values
values
Definition: FlowAnimation.py:511
src_files.FlowAnimation.FlowAnimation.energy_plot
energy_plot
Definition: FlowAnimation.py:668
src_files.FlowAnimation.FlowAnimation.__init__
def __init__(self, path, fig, frame_dir=None, plot_flow=True, flow_min=1e-8, flow_max=1e1, separate_fission=True, fission_minflow=1e-10, flow_cbar=True, flow_adapt_prange=True, flow_prange=5, flow_adapt_width=True, flow_maxArrowWidth=2.0, flow_minArrowWidth=0.3, cmapNameFlow='viridis', abun_cbar=True, X_min=1e-8, X_max=1, cmapNameX='inferno', plot_abar=True, plotMassBins=True, addMassBinLabels=True, alphaMassBins=0.5, cmapNameMassBins='jet', massBins=[[1, 1],[2, 71],[72, 93],[94, 110],[111, 144],[145, 169],[170, 187],[188, 205],[206, 252],[253, 337]], massBinLabels=['','', '1st peak','', '2nd peak', 'rare earths', '', '3rd peak', '', 'fissioning'], plot_magic=True, additional_plot='none', trackedrange=(1e-8, 1), energyrange=(1e10, 1e20), timescalerange=(1e-12, 1e10), timerange=(1e-5, 1e5), plot_mainout=True, densityrange=(1e-5, 1e12), temperaturerange=(0, 10), yerange=(0.0, 0.55), plot_logo=True)
Definition: FlowAnimation.py:27
src_files.FlowAnimation.FlowAnimation.__N_plot
__N_plot
Definition: FlowAnimation.py:203
src_files.FlowAnimation.FlowAnimation.Xbins
Xbins
Definition: FlowAnimation.py:497
src_files.FlowAnimation.FlowAnimation.Abar_plot
Abar_plot
Definition: FlowAnimation.py:618
src_files.FlowAnimation.FlowAnimation.tracked_time
tracked_time
Definition: FlowAnimation.py:478
src_files.FlowAnimation.FlowAnimation.zMagic
zMagic
Definition: FlowAnimation.py:210
src_files.FlowAnimation.FlowAnimation.abun
abun
Definition: FlowAnimation.py:526
src_files.FlowAnimation.FlowAnimation.flow_minArrowWidth
flow_minArrowWidth
Definition: FlowAnimation.py:159
src_files.FlowAnimation.FlowAnimation.X
X
Definition: FlowAnimation.py:461
src_files.FlowAnimation.FlowAnimation.temperaturerange
temperaturerange
Definition: FlowAnimation.py:153
src_files.FlowAnimation.FlowAnimation.update_frame
def update_frame(self, ii)
Definition: FlowAnimation.py:920
src_files.FlowAnimation.FlowAnimation.Mainout_text
Mainout_text
Definition: FlowAnimation.py:647
src_files.FlowAnimation.FlowAnimation.massBinLabels
massBinLabels
Definition: FlowAnimation.py:139
src_files.FlowAnimation.FlowAnimation.Mainout_units
Mainout_units
Definition: FlowAnimation.py:648
src_files.FlowAnimation.FlowAnimation.trackedrange
trackedrange
Definition: FlowAnimation.py:142
src_files.FlowAnimation.FlowAnimation.flow_norm
flow_norm
Definition: FlowAnimation.py:228
src_files.FlowAnimation.FlowAnimation.mainout_temp_plot
mainout_temp_plot
Definition: FlowAnimation.py:623
src_files.FlowAnimation.FlowAnimation.init_data
def init_data(self)
Definition: FlowAnimation.py:453
src_files.FlowAnimation.FlowAnimation.__init_logo
def __init_logo(self)
Definition: FlowAnimation.py:444
src_files.FlowAnimation.FlowAnimation.flow_dn
flow_dn
Definition: FlowAnimation.py:809
src_files.FlowAnimation.FlowAnimation.timescalerange
timescalerange
Definition: FlowAnimation.py:143
src_files.FlowAnimation.FlowAnimation.track_nuclei_data
track_nuclei_data
Definition: FlowAnimation.py:479
src_files.FlowAnimation.FlowAnimation.time
time
Definition: FlowAnimation.py:490
src_files.FlowAnimation.FlowAnimation.path
path
Definition: FlowAnimation.py:125
src_files.FlowAnimation.FlowAnimation.init_cbars
def init_cbars(self, abun_cbar, flow_cbar)
Definition: FlowAnimation.py:714
src_files.FlowAnimation.FlowAnimation.wreader
wreader
Definition: FlowAnimation.py:191
src_files.FlowAnimation.FlowAnimation.flow_N
flow_N
Definition: FlowAnimation.py:807
src_files.FlowAnimation.FlowAnimation.A
A
Definition: FlowAnimation.py:460
src_files.FlowAnimation.FlowAnimation.__data_path
__data_path
Definition: FlowAnimation.py:117
src_files.FlowAnimation.FlowAnimation.axMainout_temp
axMainout_temp
Definition: FlowAnimation.py:422
src_files.FlowAnimation.FlowAnimation.energy_labels
energy_labels
Definition: FlowAnimation.py:222
src_files.FlowAnimation.FlowAnimation.additional_plot
additional_plot
Definition: FlowAnimation.py:140
src_files.FlowAnimation.FlowAnimation.flow_max_history
flow_max_history
Definition: FlowAnimation.py:230
src_files.FlowAnimation.FlowAnimation.mainout_ye
mainout_ye
Definition: FlowAnimation.py:488
src_files.FlowAnimation.FlowAnimation.update_fission_plot
def update_fission_plot(self)
Definition: FlowAnimation.py:883
src_files.FlowAnimation.FlowAnimation.N
N
Definition: FlowAnimation.py:459
src_files.FlowAnimation.FlowAnimation.__max_N
__max_N
Definition: FlowAnimation.py:204
src_files.FlowAnimation.FlowAnimation.flow
flow
Definition: FlowAnimation.py:535
src_files.FlowAnimation.FlowAnimation.massbin_colors
massbin_colors
Definition: FlowAnimation.py:506
src_files.FlowAnimation.FlowAnimation.fig
fig
Definition: FlowAnimation.py:149
Plot_me.colorbar
colorbar
Definition: Plot_me.py:33
src_files.FlowAnimation.FlowAnimation.__init_axMainout
def __init_axMainout(self)
Definition: FlowAnimation.py:404
src_files.FlowAnimation.FlowAnimation.mainout_dens_plot
mainout_dens_plot
Definition: FlowAnimation.py:622
src_files.FlowAnimation.FlowAnimation.__background_Y
__background_Y
Definition: FlowAnimation.py:519
src_files.FlowAnimation.FlowAnimation.abun_im
abun_im
Definition: FlowAnimation.py:544
src_files.FlowAnimation.FlowAnimation.energy_time
energy_time
Definition: FlowAnimation.py:473
src_files.FlowAnimation.FlowAnimation.flow_group
flow_group
Definition: FlowAnimation.py:147
src_files.FlowAnimation.FlowAnimation.nMagic
nMagic
Definition: FlowAnimation.py:209
src_files.FlowAnimation.FlowAnimation.mafra_plot
mafra_plot
Definition: FlowAnimation.py:598
src_files.FlowAnimation.FlowAnimation.flow_dz
flow_dz
Definition: FlowAnimation.py:534
src_files.FlowAnimation.FlowAnimation.cmapNameMassBins
cmapNameMassBins
Definition: FlowAnimation.py:137
src_files.FlowAnimation.FlowAnimation.energy_data
energy_data
Definition: FlowAnimation.py:474
src_files.FlowAnimation.FlowAnimation.__script_path
__script_path
Definition: FlowAnimation.py:116
src_files.FlowAnimation.FlowAnimation.addMassBinLabels
addMassBinLabels
Definition: FlowAnimation.py:135
src_files.FlowAnimation.FlowAnimation.update_flow_plot
def update_flow_plot(self)
Definition: FlowAnimation.py:892
src_files.FlowAnimation.FlowAnimation.X_max
X_max
Definition: FlowAnimation.py:132
src_files.FlowAnimation.FlowAnimation.plotMassBins
plotMassBins
Definition: FlowAnimation.py:133
src_files.FlowAnimation.FlowAnimation.energy_lw
energy_lw
Definition: FlowAnimation.py:224
src_files.FlowAnimation.FlowAnimation.handle_fission
def handle_fission(self)
Definition: FlowAnimation.py:820
src_files.FlowAnimation.FlowAnimation.save_frame
def save_frame(self, ii)
Definition: FlowAnimation.py:929
src_files.FlowAnimation.FlowAnimation.cmapNameFlow
cmapNameFlow
Definition: FlowAnimation.py:156
src_files.FlowAnimation.FlowAnimation.mainout_time
mainout_time
Definition: FlowAnimation.py:485
src_files.FlowAnimation.FlowAnimation.axMassFrac
axMassFrac
Definition: FlowAnimation.py:362
src_files.FlowAnimation.FlowAnimation.get_funcanimation
def get_funcanimation(self, frames=None, **kwargs)
Definition: FlowAnimation.py:937
src_files.FlowAnimation.FlowAnimation.timescale_labels
timescale_labels
Definition: FlowAnimation.py:216
src_files.FlowAnimation.FlowAnimation.plot_energy
plot_energy
Definition: FlowAnimation.py:173
src_files.FlowAnimation.FlowAnimation.energy_entries
energy_entries
Definition: FlowAnimation.py:221
src_files.nucleus_multiple_class.nucleus_multiple
Definition: nucleus_multiple_class.py:10
src_files.FlowAnimation.FlowAnimation.fis_im_pos
fis_im_pos
Definition: FlowAnimation.py:573
src_files.FlowAnimation.FlowAnimation.plot_magic
plot_magic
Definition: FlowAnimation.py:151
src_files.FlowAnimation.FlowAnimation.timerange
timerange
Definition: FlowAnimation.py:144
src_files.FlowAnimation.FlowAnimation.plot_flow
plot_flow
Definition: FlowAnimation.py:148
src_files.FlowAnimation.FlowAnimation.axAbund
axAbund
Definition: FlowAnimation.py:351
src_files.FlowAnimation.FlowAnimation.mainout_temperature
mainout_temperature
Definition: FlowAnimation.py:487
src_files.FlowAnimation.FlowAnimation.__max_Z
__max_Z
Definition: FlowAnimation.py:205
src_files.FlowAnimation.FlowAnimation.plot_logo
plot_logo
Definition: FlowAnimation.py:146
src_files.FlowAnimation.FlowAnimation.energy_colors
energy_colors
Definition: FlowAnimation.py:220
src_files.FlowAnimation.FlowAnimation.X_min
X_min
Definition: FlowAnimation.py:131
src_files.FlowAnimation.FlowAnimation.yerange
yerange
Definition: FlowAnimation.py:154
src_files.FlowAnimation.FlowAnimation.flow_prange
flow_prange
Definition: FlowAnimation.py:166
src_files.FlowAnimation.FlowAnimation.update_data
def update_data(self, ii)
Definition: FlowAnimation.py:751
src_files.FlowAnimation.FlowAnimation.__init_axAbund
def __init_axAbund(self)
Definition: FlowAnimation.py:346
src_files.FlowAnimation.FlowAnimation.tracked_plot
tracked_plot
Definition: FlowAnimation.py:675
src_files.FlowAnimation.FlowAnimation.fis_im_neg
fis_im_neg
Definition: FlowAnimation.py:581
src_files.wreader.wreader
Definition: wreader.py:11
src_files.FlowAnimation.FlowAnimation.__abundance_colors
__abundance_colors
Definition: FlowAnimation.py:508
src_files.FlowAnimation.FlowAnimation.timescale_colors
timescale_colors
Definition: FlowAnimation.py:214
src_files.FlowAnimation.FlowAnimation.abun_cbar
abun_cbar
Definition: FlowAnimation.py:734
src_files.FlowAnimation.FlowAnimation.ts_data
ts_data
Definition: FlowAnimation.py:468
src_files.FlowAnimation.FlowAnimation.axEnergy
axEnergy
Definition: FlowAnimation.py:396
src_files.FlowAnimation.FlowAnimation
Definition: FlowAnimation.py:22
src_files.FlowAnimation.FlowAnimation.fission_minflow
fission_minflow
Definition: FlowAnimation.py:163
src_files.FlowAnimation.FlowAnimation.__init_nucchart_ax
def __init_nucchart_ax(self)
Definition: FlowAnimation.py:336
src_files.FlowAnimation.FlowAnimation.__init_axTracked
def __init_axTracked(self)
Definition: FlowAnimation.py:380
src_files.FlowAnimation.FlowAnimation.init_plot
def init_plot(self)
Definition: FlowAnimation.py:538
src_files.FlowAnimation.FlowAnimation.mainout_ye_plot
mainout_ye_plot
Definition: FlowAnimation.py:624
src_files.FlowAnimation.FlowAnimation.flow_adapt_width
flow_adapt_width
Definition: FlowAnimation.py:157
src_files.FlowAnimation.FlowAnimation.plot_abar
plot_abar
Definition: FlowAnimation.py:134
src_files.FlowAnimation.FlowAnimation.flow_cbar
flow_cbar
Definition: FlowAnimation.py:741