winnet_class.py
Go to the documentation of this file.
1 # @Author: Moritz Reichert <mreichert>
2 # @Date: 2017-08-04T23:19:25+02:00
3 # @Last modified by: mreichert
4 # @Last modified time: 2017-09-17T13:12:16+02:00
5 
6 
7 
8 # Winnet class to analyze winnet runs
9 # Author: Moritz Reichert
10 # Date : 08.05.17
11 
12 from random import randint
13 from shutil import copyfile
14 from matplotlib import gridspec
15 from matplotlib.patches import Rectangle, Arrow, Circle,Wedge,PathPatch
16 from matplotlib import colors,cm,colorbar
17 from matplotlib.textpath import TextPath
18 from matplotlib.font_manager import FontProperties
19 from matplotlib.collections import PatchCollection,LineCollection
20 from matplotlib.offsetbox import AnchoredOffsetbox, TextArea
21 from mpl_toolkits.axes_grid1 import make_axes_locatable
22 from mpl_toolkits.mplot3d import Axes3D
23 from matplotlib import cm
24 from types import FunctionType
25 from scipy.interpolate import interp1d
26 from .nucleus_class import nucleus
27 import matplotlib as mpl
28 import matplotlib.animation as animation
29 import numpy as np
30 import pandas as pd
31 import matplotlib.pyplot as plt
32 import h5py
33 import os
34 import inspect
35 import sys
36 import scipy.interpolate
37 import math
38 import multiprocessing
39 
40 
41 class winnet(object):
42 
43  def __init__(self,runpath):
44  """
45  Class for analyzing Winnet runs
46  """
47 
48  # Make sure that a directory path is given and save the path into self.__path
49  if runpath[-1]!= '/':
50  runpath += '/'
51  self.__path = runpath
52 
53  #Database for element names
54  self.__elname = ('neutron','h','he','li','be','b','c','n','o','f','ne','na','mg','al','si','p','s','cl','ar','k','ca','sc','ti','v','cr','mn','fe',
55  'co','ni','cu','zn','ga','ge','as','se','br','kr','rb','sr','y','zr','nb','mo','tc','ru','rh','pd','ag','cd','in','sn','sb',
56  'te', 'i','xe','cs','ba','la','ce','pr','nd','pm','sm','eu','gd','tb','dy','ho','er','tm','yb','lu','hf','ta','w','re','os',
57  'ir','pt','au','hg','tl','pb','bi','po','at','rn','fr','ra','ac','th','pa','u','np','pu','am','cm','bk','cf','es','fm','md',
58  'no','lr','rf','db','sg','bh','hs','mt','ds','rg','ub','ut','uq','up','uh','us','uo')
59  # Note: ub is also known as cn
60 
61  #Storage for snapshot data
62  self.__time = []
64  self.__neutrons = []
65  self.__protons = []
66 
67 
68  #Storage for Finab data
69  self.__finab_nuclei = []
70  self.__finab_hydrogen = None
71  self.__finab_mass = []
72  self.__finab_protons = []
73  self.__finab_neutrons = []
74  self.__finab_ab = []
75 
76 
77 
78  #Storage for timescale data
79  self.__timescale_time = []
80  self.__timescale_temp = []
92 
93 
94  #Storage for mainout data
96  self.__mainout_time = []
97  self.__mainout_temp = []
98  self.__mainout_dens = []
99  self.__mainout_ye = []
100  self.__mainout_rad = []
101  self.__mainout_yn = []
102  self.__mainout_yp = []
103  self.__mainout_ya = []
106  self.__mainout_zbar = []
107  self.__mainout_abar = []
109 
110 
111  #Storage for tracked nuclei
112  self.__track_time = []
113  self.__track_Y = [] #[[y1],[y2],..]
114  self.__track_X = [] #[[y1],[y2],..]
116 
117  # Seed nuclei
118  self.__seed_nuclei = []
119 
120  #Storage for param.out
122  self.__param_data = []
123 
124  #Default hdf5name
125  self.__hdf5_name = "WinNet_data.h5"
126 
127 
128  def get_man(self):
129  """
130  Returns a string with a manual
131  """
132  man = '1. Create a Winnet instance. E.g. Win = winnet("path to winnet folder") \n'+\
133  '2. Load everything. For example: Win.read_run(), you can also specify what you want to read with Win.read_snapshots() or Win.read_finab()\n' +\
134  '3. Analyze your data. Win.get_Z_X() returns the atomic number and the mass fraction of the run'
135  return man
136 
137  def get_methods(self):
138  """
139  Returns a list of all methods of the class
140  """
141  return [method for method in dir(self) if callable(getattr(self, method))]
142 
143 
144  def __read_flow(self,filename):
145  """
146  Reads the flow of a given file (only one flow file)
147  Reading all files would result in a too high memory consumption.
148 
149  Originally from Christian Winteler and Urs Frischknecht.
150  Edited by Moritz Reichert (2.4.2017)
151 
152  INPUT: flow.dat file name including path
153  OUTPUT: dictionary,
154  for example ff['time'] will contain the time
155 
156  example calls:
157  flux=fdic.ff('../m25z01/LOGS/flow.dat')
158  then flux['time'] contains the time where the fluxes were calculated
159  """
160  if os.path.isfile(filename):
161  f = open(filename)
162  lines = f.readlines()[:4]
163  f.close()
164 
165  # read the stored variable names and store them in "names"
166  nvars = len(lines[0].split()+lines[2].split())
167 
168  fout={'names':lines[0].split()+lines[2].split()}
169  fout[fout['names'][0]] = float(lines[1].split()[0])
170  fout[fout['names'][1]] = float(lines[1].split()[1])
171  fout[fout['names'][2]] = float(lines[1].split()[2])
172 
173  # read data columns
174  nlines = len(lines)-3
175  ncols = len(lines[2].split())
176  b= np.loadtxt(filename,skiprows=3,unpack=True)
177 
178  for i in range(ncols):
179  fout[lines[2].split()[i]]= b[i]
180 
181  elif os.path.isfile(os.path.join(self.__path,self.__hdf5_name)):
182  f=h5py.File(os.path.join(self.__path,self.__hdf5_name),"r")
183  if "/flows" in f:
184  ######################################################################################################
185  num = ""
186  for s in filename:
187  if s.isdigit():
188  num+=s
189  number = int(num)
190  print(number,filename)
191  if "/flows/"+str(number) in f:
192  entry = "/flows/"+str(number)
193  fout={'nin' :f[entry+"/n_in"][:],
194  'nout':f[entry+"/n_out"][:],
195  'zin' :f[entry+"/p_in"][:],
196  'zout':f[entry+"/p_out"][:],
197  'yin' :f[entry+"/y_in"][:],
198  'yout':f[entry+"/y_out"][:],
199  'flow':f[entry+"/flow"][:],
200  'time':f[entry+"/time"][:],
201  'temp':f[entry+"/temp"][:],
202  'dens':f[entry+"/dens"][:],
203  }
204  else:
205  raise Exception("Flow out of range ("+str(number)+").")
206 
207  else:
208  raise Exception("No flows in hdf5 file.")
209  f.close()
210  else:
211  raise Exception("Could not open file "+str(filename))
212  return fout
213 
214 
215 
216 
217 
218  def read_run(self):
219  """
220  Read a whole run with snapshots and so on.
221  """
222  self.read_snapshots()
223  self.read_finab()
224  self.read_timescales()
225  self.read_mainout()
226  self.read_template()
227 
228  def read_template(self):
229  """
230  Read the templatefile or the run (param.out)
231  """
232  path = os.listdir(self.__path)
233  for p in path:
234  if p.endswith(".par"):
235  path_param = p
236  break
237  path = os.path.join(self.__path,path_param)
238 
239  #Read template file param.out
240  self.__param_parameter,self.__param_data = np.loadtxt(path,unpack=True,dtype=str,usecols=[0,1],delimiter='=')
241 
242  # Remove blanks
243  self.__param_parameter = [x.strip() for x in self.__param_parameter]
244 
245 
246  def read_seeds(self):
247  """
248  Read the seed composition of the run. Stores an array of nuclei class. If the seed file was not found, it stores the value np.nan
249  """
250  try:
251  # Read the template to get path to the seed file
252  self.read_template()
253  name_of_seed = self.__param_data[list(self.__param_parameter).index('seed_file')].strip().replace('"','')
254 
255  path = self.__path+name_of_seed
256  # Absolute or relative path?
257  if os.path.isfile(path): #Relative path
258  path = path
259  elif os.path.isfile(name_of_seed): #Absolute path
260  path = name_of_seed
261  else: #Path not found
262  self.__seed_nuclei = np.nan
263  return
264 
265  isotopes,massfractions = np.loadtxt(path,unpack=True,dtype=str,usecols=[0,1])
266 
267  # Cast the names to nuclei
268  list_nucs = [nucleus(name=x) for x in isotopes]
269 
270  # Set the abundances
271  for i in range(len(list_nucs)):
272  list_nucs[i].set_Y(float(massfractions[i])/float(list_nucs[i].get_A()))
273  self.__seed_nuclei = list_nucs
274 
275  except:
276  print("Error when reading seeds!")
277 
278 
279 
280 
281  def get_seed_nuclei(self):
282  """
283  Returns the seed nuclei as a list of the instance nuclei
284  """
285  return self.__seed_nuclei
286 
287  def __get_at_temp(self,temp,y_array):
288  """
289  Returns a given quantity at a given temperature.
290  If the trajectory heats up several times between the temperature
291  the last one is taken.
292  """
293  try:
294  # to make the code shorter
295  mt = self.__mainout_temp
296  my = y_array
297  # First get the index
298  for ind,t in enumerate(mt[::-1]):
299  if t>temp:
300  found_ind = len(mt)-ind-1
301  break
302  # Interpolate linear
303  out = np.interp(temp,[mt[found_ind],mt[found_ind+1]],[my[found_ind],my[found_ind+1]])
304  return out
305 
306 
307  except:
308  print("Read mainout first!")
309  sys.stop(1)
310 
311 
312  def get_ye_at_temp(self,temp):
313  """
314  Returns the electron fraction at a given temperature.
315  If the trajectory heats up several times between the temperature
316  the last one is taken
317  """
318  return self.__get_at_temp(temp,self.__mainout_ye)
319 
320 
321  def get_entr_at_temp(self,temp):
322  """
323  Returns the entropy at a given temperature.
324  If the trajectory heats up several times between the temperature
325  the last one is taken
326  """
327  return self.__get_at_temp(temp,self.__mainout_entropy)
328 
329 
330  def get_density_at_temp(self,temp):
331  """
332  Returns the entropy at a given temperature.
333  If the trajectory heats up several times between the temperature
334  the last one is taken
335  """
336  return self.__get_at_temp(temp,self.__mainout_density)
337 
338 
339  def get_yn_at_temp(self,temp):
340  """
341  Returns the entropy at a given temperature.
342  If the trajectory heats up several times between the temperature
343  the last one is taken
344  """
345  return self.__get_at_temp(temp,self.__mainout_yn)
346 
347 
348  def read_snapshots(self):
349  """
350  Reads the snapshots from @runpath@/snaps/
351  """
352  path_hdf5 = os.path.join(self.__path,self.__hdf5_name)
353  path = self.__path+'snaps/'
354  amount_snaps = len(os.listdir(path))
355 
356  # Read it from the ascii files
357  if amount_snaps != 0:
358  for i in range(amount_snaps):
359  currentfile = 'snapsh_'+str((i+1)).zfill(4)+'.dat'
360 
361  #Read time
362  count = 0
363  with open(path+currentfile) as f:
364 
365  for line in f.readlines():
366  count += 1
367  if count == 2:
368  self.__time.append(float(line.split()[0]))
369  if count > 2:
370  break
371 
372  #Read mass fractions
373  self.__neutrons,self.__protons,massfractions = np.loadtxt(path+currentfile,unpack=True,skiprows=3,usecols=[0,1,3])
374 
375  self.__allmassfractions.append(massfractions)
376 
377  elif os.path.isfile(path_hdf5):
378  f = h5py.File(path_hdf5,"r")
379  if "/snapshots" in f:
380  self.__time = f["/snapshots/time"][:]
381  self.__neutrons = f["/snapshots/N"][:]
382  self.__protons = f["/snapshots/Z"][:]
383  self.__allmassfractions = f["/snapshots/Y"][:,:]*f["/snapshots/A"][:]
384  else:
385  raise Exception("There are no snapshots to read!")
386  f.close()
387  else:
388  raise Exception("There are no snapshots to read!")
389 
390 
392  """
393  Read only the time from the snapshot files
394  """
395  path = self.__path+'snaps/'
396  amount_snaps = len(os.listdir(path))
397 
398  for i in range(amount_snaps):
399  currentfile = 'snapsh_'+str((i+1)).zfill(4)+'.dat'
400 
401  #Read time
402  count = 0
403  with open(path+currentfile) as f:
404 
405  for line in f.readlines():
406  count += 1
407  if count == 2:
408  self.__time.append(float(line.split()[0]))
409  if count > 2:
410  break
411  self.__time = np.array(self.__time)
412 
413 
414  def read_finab(self,finab_name="finab.dat"):
415  """
416  Reads the file finab.dat in the run folder
417  """
418 
419  # Read the file (File format : 1:A 2:Z 3:N 4:Yi 5:Xi)
420  self.__finab_mass, self.__finab_protons, self.__finab_neutrons, self.__finab_ab = np.loadtxt(os.path.join(self.__path,finab_name),usecols=[0,1,2,3],unpack=True)
421 
422  #Create instance of nuclei
423  self.__finab_nuclei = [nucleus(Z=int(self.__finab_protons[i]),N=int(self.__finab_neutrons[i]),Y=self.__finab_ab[i]) for i in range(len(self.__finab_mass)) ]
424  self.__finab_nuclei.sort()
425 
426  #Get hydrogen out of it
427  for nuc in self.__finab_nuclei:
428  if (nuc.get_Z() == 1 and nuc.get_N() == 0):
429  self.__finab_hydrogen = nuc
430  break
431 
432 
433  def read_timescales(self,subtract_first=True):
434  """
435  Read the timescales from a Winnet calculation
436  """
437 
438  path = os.path.join(self.__path, 'timescales.dat')
439  path_hdf5 = os.path.join(self.__path, self.__hdf5_name)
440 
441  if os.path.isfile(path):
444  # self.__timescale_time, self.__timescale_temp, self.__timescale_tau_ng , self.__timescale_tau_gn, self.__timescale_tau_pg, self.__timescale_tau_gp, self.__timescale_tau_np, self.__timescale_tau_pn, self.__timescale_tau_an, self.__timescale_tau_na, self.__timescale_tau_beta = np.loadtxt(path,unpack=True,skiprows=1)
445  if subtract_first:
447  elif os.path.isfile(path_hdf5):
448  f = h5py.File(path_hdf5,"r")
449  if "/timescales" in f:
450  self.__timescale_time = f["/timescales/time"][:]
451  self.__timescale_tau_ng = f["/timescales/tau_ng"][:]
452  self.__timescale_tau_gn = f["/timescales/tau_gn"][:]
453  self.__timescale_tau_pg = f["/timescales/tau_pg"][:]
454  self.__timescale_tau_gp = f["/timescales/tau_gp"][:]
455  self.__timescale_tau_np = f["/timescales/tau_np"][:]
456  self.__timescale_tau_pn = f["/timescales/tau_pn"][:]
457  self.__timescale_tau_an = f["/timescales/tau_an"][:]
458  self.__timescale_tau_na = f["/timescales/tau_na"][:]
459  self.__timescale_tau_ga = f["/timescales/tau_ga"][:]
460  self.__timescale_tau_ag = f["/timescales/tau_ag"][:]
461  self.__timescale_tau_ap = f["/timescales/tau_ap"][:]
462  self.__timescale_tau_pa = f["/timescales/tau_pa"][:]
463  self.__timescale_tau_beta = f["/timescales/tau_beta"][:]
464  self.__timescale_tau_alpha = f["/timescales/tau_alpha"][:]
465  self.__timescale_tau_nfiss = f["/timescales/tau_nfiss"][:]
466  self.__timescale_tau_sfiss = f["/timescales/tau_sfiss"][:]
467  self.__timescale_tau_bfiss = f["/timescales/tau_bfiss"][:]
468  if subtract_first:
470  else:
471  raise Exception('Timescales were not calculated in this run.')
472  else:
473  raise Exception('Timescales were not calculated in this run.')
474 
475  return
476 
477 
478  def read_mainout_fix(self):
479  """
480  Read the mainout with numbers like 1.8-392
481  """
482  path = self.__path + 'mainout.dat'
483 
484 
485  f = open(path)
486  line_number = 0
487  for line in f.readlines():
488 
489  line_number +=1
490 
491  if line_number<=4:
492  continue
493 
494  string_split = line.split()
495  split_corrected = []
496 
497  for i in string_split:
498  try:
499  c_float = float(i)
500  except:
501  c_float = 0.
502  split_corrected.append(c_float)
503 
504  self.__mainout_iteration.append(split_corrected[0 ])
505  self.__mainout_time .append(split_corrected[1 ])
506  self.__mainout_temp .append(split_corrected[2 ])
507  self.__mainout_dens .append(split_corrected[3 ])
508  self.__mainout_ye .append(split_corrected[4 ])
509  self.__mainout_rad .append(split_corrected[5 ])
510  self.__mainout_yn .append(split_corrected[6 ])
511  self.__mainout_yp .append(split_corrected[7 ])
512  self.__mainout_ya .append(split_corrected[8 ])
513  self.__mainout_ylight .append(split_corrected[9 ])
514  self.__mainout_yheavy .append(split_corrected[10])
515  self.__mainout_zbar .append(split_corrected[11])
516  self.__mainout_abar .append(split_corrected[12])
517  self.__mainout_entropy .append(split_corrected[13])
518 
519 
521  """
522  Read the nuclei data contained in the file tracked_nuclei. This file is helpfull, when you dont want to look at the full output.
523  """
524  path = self.__path + 'tracked_nuclei.dat'
525  # Check that the file exists
526  if (os.path.isfile(path)):
527  # Read the first line of the file and extract the nuclei names from the header
528  with open(path, 'r') as f:
529  first_line = f.readline()
530 
531  first_line = first_line.replace('Y(','')
532  first_line = first_line.replace(')','')
533  first_line = first_line.replace('#','')
534  self.__track_nuclei_names = first_line.split()[1:] # Since the first entry is "time"
535 
536  # Read the time and the abundances of the nuclei
537  alldata = np.loadtxt(path,unpack=True)
538  self.__track_time = alldata[0]
539  self.__track_Y = alldata[1:]
540 
541  # Save also the mass fraction
542  nuclei_helper_instance = np.array([nucleus(x).get_A() for x in self.__track_nuclei_names])
543  self.__track_X = np.array(list(map(lambda x,y: x*y ,self.__track_Y,nuclei_helper_instance)))
544  else:
545  print('No nuclei are tracked!')
546 
547 
548 
549 
550  def read_mainout(self,subtract_first=False):
551  """
552  Read the mainout from a Winnet calculation
553  """
554  path = self.__path + 'mainout.dat'
555  self.__mainout_iteration, self.__mainout_time, self.__mainout_temp, self.__mainout_dens, self.__mainout_ye, self.__mainout_rad, self.__mainout_yn, self.__mainout_yp, self.__mainout_ya, self.__mainout_ylight, self.__mainout_yheavy, self.__mainout_zbar, self.__mainout_abar, self.__mainout_entropy = np.loadtxt(path,skiprows = 3,unpack=True,usecols=np.arange(14),ndmin=1)
556 
557  if isinstance(self.__mainout_iteration,np.float64):
559  if subtract_first:
560  self.__mainout_time = self.__mainout_time-self.__mainout_time[0]
561 
562 
563  def read_engen(self):
564  """
565  Read the generated energy
566  """
567  path = self.__path + 'generated_energy.dat'
568  # Check that the file exists
569  if (os.path.isfile(path)):
570  with open(path, 'r') as f:
571  first_line = f.readline()
572  second_line = f.readline()
573 
574  self.__engen_keywords = second_line.split()[1:]
575  self.__engen = np.loadtxt(path,unpack=True)
576  else:
577  print('No generated energy was calculated!')
578 
579  def get_engen(self):
580  """
581  Return the generated energy
582  """
583  return self.__engen
584 
586  return self.__track_nuclei_names
587 
588  def get_tracked_nuclei(self,name,massfraction=True):
589  """
590  Get the abundance of a nuclei that was tracked.
591  Input:
592  name - Name of the nucleus (e.g. ti44)
593  massfraction - Return mass fractions or abundances?
594  """
595  # Get the lowercase of the input
596  name = name.lower()
597  try:
598  # Index of the names and track_Y is the same, so get it and return the values
599  index = self.__track_nuclei_names.index(name)
600  if massfraction:
601 
602  return self.__track_X[index]
603  else:
604  return self.__track_Y[index]
605  except:
606  print('"'+name+'" not contained in tracked nuclei.')
607  return None
608 
609 
610  def get_tracked_time(self):
611  """
612  Get the time, contained in the file tracked_nuclei.dat
613  """
614  return self.__track_time
615 
616 
617  def get_mainout_time(self):
618  """
619  Get the time, contained in mainout.dat
620  """
621  return self.__mainout_time
622 
623 
624  def get_mainout_yn(self):
625  """
626  Get the neutron abundance, contained in mainout.dat
627  """
628  return self.__mainout_yn
629 
630  def get_mainout_yp(self):
631  """
632  Get the proton abundance, contained in mainout.dat
633  """
634  return self.__mainout_yp
635 
636  def get_mainout_ya(self):
637  """
638  Get the alpha abundance, contained in mainout.dat
639  """
640  return self.__mainout_ya
641 
643  """
644  Get the yheavy abundance, contained in mainout.dat
645  """
646  return self.__mainout_yheavy
647 
648  def get_is_crashed(self):
649  """
650  Is the run crashed?
651  """
652  if not os.path.exists(self.__path+'finab.dat'):
653  return True
654  else:
655  return False
656 
657 
658  def get_trajectory(self):
659  """
660  Get all data from the trajectory
661  Output is:
662  time[s], radius[cm], dens[g/ccm], temp[GK], Ye, entr[kb/nucleon]
663  """
664 
665  if len(self.__param_parameter) == 0:
666  print('Call read_template first! Your script might not work now!')
667  return
668 
669  # Get path to trajectory file
670  ind = self.__param_parameter.index('trajectory_file')
671  traj_path = self.__param_data[ind].replace('"','').strip()
672  time, radius, dens, temp, Ye, entr = np.loadtxt(traj_path, unpack=True, skiprows=2)
673  return time,radius,dens,temp,Ye,entr
674 
676  """
677  Get all data from the trajectory
678  Output is the path to the trajectory
679  """
680 
681  if len(self.__param_parameter) == 0:
682  print('Call read_template first! Your script might not work now!')
683  return
684 
685  # Get path to trajectory file
686  ind = self.__param_parameter.index('trajectory_file')
687  traj_path = self.__param_data[ind].replace('"','').strip()
688  return traj_path
689 
690 
691  def get_mainout(self):
692  """
693  Returns the data from mainout.dat
694  Output is:
695  iteration, time, temperature, density, Ye, Radius, Yn, Yp, Y_alpha, Y_light, Y_heavy, Zbar, Abar, Entropy
696  """
698 
699 
700  def get_temperature(self):
701  """
702  Get the temperature [GK] from mainout.dat, it also returns the time
703  """
704  if len(self.__mainout_time) != 0:
705  return self.__mainout_time, self.__mainout_temp
706  else:
707  print('Call read_mainout first! Your script might not work now')
708 
709 
710  def get_density(self):
711  """
712  Get the density [g/ccm] from mainout.dat, it also returns the time
713  """
714  if len(self.__mainout_time) != 0:
715  return self.__mainout_time, self.__mainout_dens
716  else:
717  print('Call read_mainout first! Your script might not work now')
718 
719 
720  def get_ye(self):
721  """
722  Get the electron fraction from mainout.dat, it also returns the time
723  """
724  if len(self.__mainout_time) != 0:
725  return self.__mainout_time, self.__mainout_ye
726  else:
727  print('Call read_mainout first! Your script might not work now')
728 
729 
730  def get_radius(self):
731  """
732  Get the radius [km] from mainout.dat, it also returns the time
733  """
734  if len(self.__mainout_time) != 0:
735  return self.__mainout_time, self.__mainout_rad
736  else:
737  print('Call read_mainout first! Your script might not work now')
738 
739 
740  def get_ylight(self):
741  """
742  Get lighter elements (A<=4) from mainout.dat, it also returns the time
743  """
744  if len(self.__mainout_time) != 0:
745  return self.__mainout_time, self.__mainout_ylight
746  else:
747  print('Call read_mainout first! Your script might not work now')
748 
749 
750  def get_yheavy(self):
751  """
752  Get heavier elements (A>4) from mainout.dat, it also returns the time
753  """
754  if len(self.__mainout_time) != 0:
755  return self.__mainout_time, self.__mainout_yheavy
756  else:
757  print('Call read_mainout first! Your script might not work now')
758 
759 
760  def get_zbar(self):
761  """
762  Get average proton number from mainout.dat, it also returns the time
763  """
764  if len(self.__mainout_time) != 0:
765  return self.__mainout_time, self.__mainout_zbar
766  else:
767  print('Call read_mainout first! Your script might not work now')
768 
769 
770  def get_abar(self):
771  """
772  Get average mass number from mainout.dat, it also returns the time
773  """
774  if len(self.__mainout_time) != 0:
775  return self.__mainout_time, self.__mainout_abar
776  else:
777  print('Call read_mainout first! Your script might not work now')
778 
779 
780  def get_abar_at_time(self,t):
781  """
782  Get average mass number from mainout.dat at time t
783  """
784  if len(self.__mainout_time) != 0:
785  interfunc = interp1d(self.__mainout_time,self.__mainout_abar)
786  return interfunc(t)
787  else:
788  print('Call read_mainout first! Your script might not work now')
789 
790  def get_entropy(self):
791  """
792  Get entropy [kB/baryon] from mainout.dat, it also returns the time
793  """
794  if len(self.__mainout_time) != 0:
795  return self.__mainout_time, self.__mainout_entropy
796  else:
797  print('Call read_mainout first! Your script might not work now')
798 
799 
800  def get_timescales(self):
801  """
802  Returns the timescales of the run
803  Ouput is:
804  Time, Temperature[GK], ng, gn, pg, gp, np, pn, an, na, beta (all [1/s])
805  """
806  if len(self.__timescale_time) == 0:
807  print('Call read_timescales first !! The script might not work now!')
808  return
809 
811 
812 
813  def get_final_Z_Y(self):
814  """
815  Get abundances over proton number
816  Note: read_finab has to be called in advance
817  """
818 
819  if len(self.__finab_nuclei) == 0:
820  print('Call read_finab first !! The script might not work now!')
821  return
822 
823  #Sort it
824  for nuc in self.__finab_nuclei:
825  nuc.set_sortcriteria('Z')
826  self.__finab_nuclei.sort()
827 
828 
829  old_Z = -1
830 
831  fin_Z = []
832  fin_Y = []
833 
834  count = -1
835 
836  for nuc in self.__finab_nuclei:
837  if nuc.get_Z() == old_Z:
838  fin_Y[count] += nuc.get_Y()
839  else:
840  fin_Z.append(nuc.get_Z())
841  fin_Y.append(nuc.get_Y())
842  count += 1
843 
844  old_Z = nuc.get_Z()
845 
846  return np.array(fin_Z),np.array(fin_Y)
847 
848 
849  def get_final_Z_X(self):
850  """
851  Get mass fractions over proton number
852  Note: read_finab has to be called in advance
853  """
854 
855  if len(self.__finab_nuclei) == 0:
856  print('Call read_finab first !! The script might not work now!')
857  return
858 
859  #Sort it
860  for nuc in self.__finab_nuclei:
861  nuc.set_sortcriteria('Z')
862  self.__finab_nuclei.sort()
863 
864  old_Z = -1
865 
866  fin_Z = []
867  fin_X = []
868 
869  count = -1
870 
871  for nuc in self.__finab_nuclei:
872 
873  if nuc.get_Z() == old_Z:
874  fin_X[count] += nuc.get_X()
875  else:
876  fin_Z.append(nuc.get_Z())
877  fin_X.append(nuc.get_X())
878  count += 1
879 
880  old_Z = nuc.get_Z()
881 
882  return fin_Z,fin_X
883 
884 
885  def __get_x_to_seed(self,temperature,x):
886  """
887  Helper function to calculate Y(neutron) Y(proton) Y(alpha) to seed ratio without making too many repetitions
888  Input
889  Temperature - temperature in GK for which the ratio is calculated
890  x - Y(n), Y(p) or Y(alpha) of the mainout
891  Note: read_mainout should get called first
892  """
893 
894  mainout_length = len(self.__mainout_iteration)
895 
896  # Be sure that mainout was read in
897  if mainout_length == 0:
898  print('Call read_mainout first! Returning!')
899  return
900 
901  reverse_temp = self.__mainout_temp[::-1]
902 
903  # Get the correct index temperature
904  reversed_index = 0
905  for temp in reverse_temp:
906  reversed_index += 1
907  if temp >= temperature: # Assume monotonic increasing of the reversed temperature array
908  break
909 
910  # Transform reverse index to forward one
911  index = mainout_length - reversed_index - 1
912 
913 
914  # Interpolate (linearly)
915  x_int = interp1d(self.__mainout_temp[index:mainout_length],x[index:mainout_length])
916  yheavy_int = interp1d(self.__mainout_temp[index:mainout_length],self.__mainout_yheavy[index:mainout_length])
917  # Get the correct value at the input temperature
918  x_at_temp = x_int(temperature)
919  yheavy_at_temp = yheavy_int(temperature)
920  # Finally calculate the ratio
921  x_to_seed = np.log10(x_at_temp / yheavy_at_temp)
922 
923 
924  return x_to_seed
925 
926  def get_alpha_to_seed(self,temperature):
927  """
928  Get the alpha to seed ratio at given temperature [GK]
929  Note: read_mainout has get called first
930  """
931  alpha_to_seed = self.__get_x_to_seed(temperature,self.__mainout_ya) # Call helper function
932  return alpha_to_seed
933 
934  def get_n_to_seed(self,temperature):
935  """
936  Get the alpha to seed ratio at given temperature [GK]
937  Note: read_mainout has get called first
938  """
939  neutron_to_seed = self.__get_x_to_seed(temperature,self.__mainout_yn) # Call helper function
940  return neutron_to_seed
941 
942  def get_p_to_seed(self,temperature):
943  """
944  Get the alpha to seed ratio at given temperature [GK]
945  Note: read_mainout has get called first
946  """
947  proton_to_seed = self.__get_x_to_seed(temperature,self.__mainout_yp) # Call helper function
948  return proton_to_seed
949 
950  def get_final_abar(self):
951  """
952  Get the final abar from finab.dat. Therefore one has to call read_finab first.
953  """
954  #abar = sum(Xi)/sum(Yi)
955  abar = sum(np.array(self.__finab_mass) * np.array(self.__finab_ab) ) / sum(np.array(self.__finab_ab))
956  return abar
957 
958  def get_final_abar_heavy(self,min_mass):
959  """
960  Get the final abar calculated for A>min_mass from finab.dat. Therefore one has to call read_finab first.
961  """
962  #abar = sum(Xi)/sum(Yi)
963  for nuc in self.__finab_nuclei:
964  nuc.set_sortcriteria('A')
965 
966  nuc = sorted(self.__finab_nuclei)
967 
968  a_tmp = [x.get_A() for x in nuc]
969  Y_tmp = [x.get_Y() for x in nuc]
970 
971  for i in range(len(a_tmp)):
972  if a_tmp[i] > min_mass:
973  break
974 
975  abar_heavy = sum(np.array(a_tmp[i:]) * np.array(Y_tmp[i:]) ) / sum(np.array(Y_tmp[i:]))
976 
977  return abar_heavy
978 
979 
980  def get_finab_nuclei(self):
981  """
982  Returns a list containing the nuclei contained in finab (list of instance nucleus)
983  """
984  return self.__finab_nuclei
985 
986  def get_tracer_nr(self):
987  """
988  Returns the tracer number of the tracer of the current instance. If there is no digit in the foldername of the run, the return value is -1.
989  e.g. runpath is abc/dfg/tracer_4523.dat -> return value is 4523
990  """
991  run = os.path.basename(os.path.normpath(self.__path))
992  tr_nr = ''
993  for s in run:
994  if s.isdigit():
995  tr_nr = tr_nr+s
996  # Try to convert it to an integer
997  try:
998  tr_nr = int(tr_nr)
999  except:
1000  tr_nr = -1
1001 
1002  return tr_nr
1003 
1004 
1005  def plot_final_isotopes(self,figure=None,axlabel=True,lower_limit=1e-10,isotopes=None,isotope_label=True,ignore_isotope_names=None,text_clipping=True,\
1006  ytext_pos_factor= 1.2,xtext_pos_offset=-0.5,ytext_pos_offset=0.0,nuc_input=None,fig_is_ax=False,color_dict=None,**kwargs):
1007  """
1008  Plot the massfraction of the final isotopes over mass number.
1009  Input:
1010  lower_limit : lowest massfraction that will be plotted (default 10^-10)
1011  isotopes : isotopes to be plotted. If none (default), all isotopes of finab will get plotted. Type is list that contains the Z number
1012  isotope_label : Plot the labels of the isotopes?
1013  ignore_isotope_names : which name label should be ignored? (list contains Z number)
1014  text_clipping : Text clipping yes or no? ( Should the text shown outside the plotting area?
1015  ytext_pos_factor : offset factor for the y position of the labels. Only has an effect when isotope_label is true
1016  xtext_pos_offset : offset for the x position of the labels. Only has an effect when isotope_label is true
1017  nuc_input : Input of nuclei. If None is given, finab nuclei are used. (instance of list of nucleus)
1018  fig_is_ax : parameter figure either a figure object or an axes object?
1019  color_dict : Dictionary with atomic numbers and colors.
1020  """
1021 
1022 
1023  # Make a figure if no figure was given
1024  if figure == None:
1025  final_fig = plt.figure()
1026  else:
1027  final_fig = figure
1028 
1029  if not fig_is_ax:
1030  # Get the axis instance from figure
1031  ax = final_fig.gca()
1032  else:
1033  ax = figure
1034 
1035  if nuc_input is None:
1036  plotted_nuclei = self.__finab_nuclei
1037  else:
1038  plotted_nuclei = nuc_input
1039 
1040  # Sort the nuclei (atomic number criteria)
1041  for nuc in plotted_nuclei:
1042  nuc.set_sortcriteria('Z')
1043  nuc = sorted(plotted_nuclei)
1044 
1045  # Go through nuclei and make Z-cluster
1046  old_Z = nuc[0].get_Z()
1047  A_cluster = []
1048  X_cluster = []
1049  for n in nuc:
1050  current_Z = n.get_Z()
1051  current_A = n.get_A()
1052  current_X = n.get_X()
1053 
1054  # Cycle for to small mass fractions
1055  if current_X <= lower_limit:
1056  continue
1057 
1058 
1059  if current_Z != old_Z: # Plot it
1060 
1061  # Cycle for uninteressting isotopes
1062  if isotopes != None:
1063  if old_Z not in isotopes:
1064  A_cluster = [current_A]
1065  X_cluster = [current_X]
1066  old_Z = current_Z
1067  continue
1068 
1069  if color_dict is None:
1070  pl = ax.plot(A_cluster,X_cluster,marker='.',**kwargs)
1071  else:
1072  pl = ax.plot(A_cluster,X_cluster,marker='.',color=color_dict[int(old_Z)],**kwargs)
1073 
1074  # Set isotope labels
1075  if isotope_label:
1076  if X_cluster != []:
1077  if (ignore_isotope_names == None) or (not old_Z in ignore_isotope_names):
1078  pos_y = max(X_cluster)
1079  pos_x = A_cluster[X_cluster.index(max(X_cluster))]
1080  if color_dict is None:
1081  color = pl[-1].get_color() # Get current color
1082  ax.text(pos_x+xtext_pos_offset,pos_y*ytext_pos_factor+ytext_pos_offset,nam,color=color,fontsize=15,ha='center').set_clip_on(text_clipping)
1083  else:
1084  ax.text(pos_x+xtext_pos_offset,pos_y*ytext_pos_factor+ytext_pos_offset,nam,color=color_dict[int(old_Z)],fontsize=15,ha='center').set_clip_on(text_clipping)
1085 
1086 
1087  A_cluster = [current_A]
1088  X_cluster = [current_X]
1089  old_Z = current_Z
1090  else: # Collect data
1091  A_cluster.append(current_A)
1092  X_cluster.append(current_X)
1093 
1094  # Get the name and make sure that the first letter is in uppercase
1095  nam = n.get_elementname()
1096  nam = nam[0].upper()+nam[1:]
1097 
1098 
1099 
1100 
1101  # Set the labels
1102  if axlabel:
1103  ax.set_ylabel('Mass fraction X')
1104  ax.set_xlabel('Mass number A')
1105  ax.set_yscale('log')
1106 
1107  return final_fig
1108 
1109 
1110  def get_final_A_X(self):
1111  """
1112  Get mass fractions over proton number
1113  Note: read_finab has to be called in advance
1114  """
1115 
1116  if len(self.__finab_nuclei) == 0:
1117  print('Call read_finab first !! The script might not work now!')
1118  return
1119 
1120  #Sort it
1121  for nuc in self.__finab_nuclei:
1122  nuc.set_sortcriteria('A')
1123  self.__finab_nuclei.sort()
1124 
1125  old_A = -1
1126 
1127  fin_A = []
1128  fin_X = []
1129 
1130  count = -1
1131 
1132  for nuc in self.__finab_nuclei:
1133 
1134  if nuc.get_A() == old_A:
1135  fin_X[count] += nuc.get_X()
1136  else:
1137  fin_A.append(nuc.get_A())
1138  fin_X.append(nuc.get_X())
1139  count += 1
1140 
1141  old_A = nuc.get_A()
1142 
1143  return fin_A,fin_X
1144 
1145  def get_final_Z_A_X(self):
1146  """
1147  Get mass fractions over proton number
1148  Note: read_finab has to be called in advance
1149  """
1150 
1151  if len(self.__finab_nuclei) == 0:
1152  print('Call read_finab first !! The script might not work now!')
1153  return
1154 
1155  #Sort it
1156  for nuc in self.__finab_nuclei:
1157  nuc.set_sortcriteria('A')
1158  self.__finab_nuclei.sort()
1159 
1160  old_A = -1
1161 
1162  fin_A = []
1163  fin_Z = []
1164  fin_X = []
1165 
1166  count = -1
1167 
1168  for nuc in self.__finab_nuclei:
1169 
1170  fin_A.append(nuc.get_A())
1171  fin_Z.append(nuc.get_Z())
1172  fin_X.append(nuc.get_X())
1173  count += 1
1174 
1175  old_A = nuc.get_A()
1176  fin_A = np.array(fin_A)
1177  fin_Z = np.array(fin_Z)
1178  fin_X = np.array(fin_X)
1179  return fin_Z,fin_A,fin_X
1180 
1181 
1182  def get_final_A_Y(self):
1183  """
1184  Get Abundance over proton number
1185  Note: read_finab has to be called in advance
1186  """
1187 
1188  if len(self.__finab_nuclei) == 0:
1189  print('Call read_finab first !! The script might not work now!')
1190  return
1191 
1192  #Sort it
1193  for nuc in self.__finab_nuclei:
1194  nuc.set_sortcriteria('A')
1195  self.__finab_nuclei.sort()
1196 
1197  old_A = -1
1198 
1199  fin_A = []
1200  fin_Y = []
1201 
1202  count = -1
1203 
1204  for nuc in self.__finab_nuclei:
1205 
1206  if nuc.get_A() == old_A:
1207  fin_Y[count] += nuc.get_Y()
1208  else:
1209  fin_A.append(nuc.get_A())
1210  fin_Y.append(nuc.get_Y())
1211  count += 1
1212 
1213  old_A = nuc.get_A()
1214 
1215  return fin_A,fin_Y
1216 
1217 
1218 
1219  def get_final_Z_eps(self):
1220  """
1221  Get abundances over proton number
1222  Note: read_finab has to be called in advance
1223  """
1224 
1225  if len(self.__finab_nuclei) == 0:
1226  print('Call read_finab first !! The script might not work now!')
1227  return
1228 
1229  fin_Z,fin_Y = self.get_Z_Y()
1230 
1231  #log eps_A = log (Y_A/Y_H) + 12
1232  Y_eps = [np.log10(x / self.__finab_hydrogen.get_Y()) +12. for x in fin_Y]
1233 
1234 
1235  return fin_Z,Y_eps
1236 
1237 
1238  def get_time_evolution(self,nuc):
1239  """
1240  Return time and mass fraction for a given nucleus.
1241  Note: read_snapshots has to be called in advance!
1242  """
1243 
1244  if isinstance(nuc, str):
1245  nuc = nucleus(nuc)
1246 
1247  p = nuc.get_Z()
1248  n = nuc.get_N()
1249 
1250 
1251  for i in range(len(self.__neutrons)):
1252  current_n = self.__neutrons[i]
1253  current_p = self.__protons[i]
1254 
1255 
1256  if (current_n == n and current_p == p):
1257  index = i
1258  break
1259  try:
1260  massfraction_out = np.array(self.__allmassfractions)[:,index]
1261  except:
1262  raise Exception(nuc.get_name(), 'not in list!')
1263 
1264  return self.__time , massfraction_out
1265 
1266 
1267 
1268  def set_finab_nuclei(self,nucleilist):
1269  """
1270  Set the final abundances with a list of nuclei
1271  Input:
1272  nucleilist - List of instance of nuclei
1273  """
1274 
1275 
1276  # Super stupid to save it so often, in principle self.__finab_nuclei contains all these informations!
1277  self.__finab_mass = [x.get_A() for x in nucleilist]
1278  self.__finab_protons = [x.get_Z() for x in nucleilist]
1279  self.__finab_neutrons = [x.get_N() for x in nucleilist]
1280  self.__finab_ab = [x.get_Y() for x in nucleilist]
1281  # Save the instance of nuclei
1282  self.__finab_nuclei = nucleilist
1283  self.__finab_nuclei.sort()
1284 
1285  #Get hydrogen out of it
1286  for nuc in self.__finab_nuclei:
1287  if (nuc.get_Z() == 1 and nuc.get_N() == 0):
1288  self.__finab_hydrogen = nuc
1289  break
1290 
1291 
1292  def plot_engen(self,figure=None,axlabel=True,fig_is_ax=False,**kwargs):
1293  """
1294  Plot the final massfraction over mass number
1295  Returns a figure object
1296  """
1297  # Make a figure if no figure was given
1298  if figure == None:
1299  final_fig = plt.figure()
1300  else:
1301  final_fig = figure
1302 
1303  if fig_is_ax:
1304  ax = final_fig
1305  else:
1306  # Get the axis instance from figure
1307  ax = final_fig.gca()
1308 
1309  ax.set_yscale('log')
1310  ax.set_xscale('log')
1311  ax.set_ylabel('Generated energy [erg/g/s]')
1312  time = self.__engen[0]
1313  for ind,k in enumerate(self.__engen_keywords):
1314  if ind==0:
1315  continue
1316  elif ind==1:
1317  ax.plot(time,self.__engen[ind],label=k,lw=2,ls='--')
1318  else:
1319  ax.plot(time,self.__engen[ind],label=k)
1320  return final_fig
1321 
1322  def plot_final_A_X(self,figure=None,axlabel=True,fig_is_ax=False,**kwargs):
1323  """
1324  Plot the final massfraction over mass number
1325  Returns a figure object
1326  """
1327  # Make a figure if no figure was given
1328  if figure == None:
1329  final_fig = plt.figure()
1330  else:
1331  final_fig = figure
1332 
1333  if fig_is_ax:
1334  ax = final_fig
1335  else:
1336  # Get the axis instance from figure
1337  ax = final_fig.gca()
1338 
1339  # Collect data
1340  A,X = self.get_final_A_X()
1341 
1342  # Plot data
1343  ax.plot(A,X,**kwargs)
1344  ax.set_yscale('log')
1345 
1346  # Make labels
1347  if axlabel:
1348  ax.set_ylabel('Mass fraction')
1349  ax.set_xlabel('Mass number')
1350 
1351  return final_fig
1352 
1353 
1354  def plot_final_Z_X(self,figure=None,axlabel=True,fig_is_ax=False,**kwargs):
1355  """
1356  Plot the final massfraction over mass number
1357  Returns a figure object
1358  """
1359 
1360  # Make a figure if no figure was given
1361  if figure == None:
1362  final_fig = plt.figure()
1363  else:
1364  final_fig = figure
1365 
1366  if fig_is_ax:
1367  ax = final_fig
1368  else:
1369  # Get the axis instance from figure
1370  ax = final_fig.gca()
1371 
1372  # Collect data
1373  Z,X = self.get_final_Z_X()
1374 
1375  # Plot data
1376  ax.plot(Z,X,**kwargs)
1377  ax.set_yscale('log')
1378 
1379  # Make labels
1380  if axlabel:
1381  ax.set_ylabel('Mass fraction')
1382  ax.set_xlabel('Atomic number')
1383 
1384  return final_fig
1385 
1386 
1387  def plot_final_A_Y(self,figure=None,axlabel=True,fig_is_ax=False,**kwargs):
1388  """
1389  Plot the final abundances over mass number
1390  Returns a figure object
1391  """
1392 
1393  # Make a figure if no figure was given
1394  if figure == None:
1395  final_fig = plt.figure()
1396  else:
1397  final_fig = figure
1398 
1399  if fig_is_ax:
1400  ax = final_fig
1401  else:
1402  # Get the axis instance from figure
1403  ax = final_fig.gca()
1404 
1405  # Collect data
1406  A,Y = self.get_final_A_Y()
1407 
1408  # Plot data
1409  ax.plot(A,Y,**kwargs)
1410  ax.set_yscale('log')
1411 
1412  # Make labels
1413  if axlabel:
1414  ax.set_ylabel('Abundance')
1415  ax.set_xlabel('Mass number')
1416 
1417  return final_fig
1418 
1419 
1420  def plot_final_Z_Y(self,figure=None,axlabel=True,fig_is_ax=False,**kwargs):
1421  """
1422  Plot the final abundances over mass number
1423  Returns a figure object
1424  """
1425 
1426  # Make a figure if no figure was given
1427  if figure == None:
1428  final_fig = plt.figure()
1429  else:
1430  final_fig = figure
1431 
1432  if fig_is_ax:
1433  ax = final_fig
1434  else:
1435  # Get the axis instance from figure
1436  ax = final_fig.gca()
1437 
1438  # Collect data
1439  Z,Y = self.get_final_Z_Y()
1440 
1441  # Plot data
1442  ax.plot(Z,Y,**kwargs)
1443  ax.set_yscale('log')
1444 
1445  # Make labels
1446  if axlabel:
1447  ax.set_ylabel('Abundance')
1448  ax.set_xlabel('Atomic number')
1449 
1450  return final_fig
1451 
1452 
1453 
1454  def plot_temperature(self,figure=None,axlabel=True,**kwargs):
1455  """
1456  Plot the temperature [GK]
1457  Returns a figure object
1458  """
1459 
1460  # Make a figure if no figure was given
1461  if figure == None:
1462  final_fig = plt.figure()
1463  else:
1464  final_fig = figure
1465 
1466  # Get the axis instance from figure
1467  ax = final_fig.gca()
1468 
1469  # Collect data
1470  time,temp = self.get_temperature()
1471 
1472  # Plot data
1473  ax.plot(time,temp,**kwargs)
1474  ax.set_yscale('log')
1475 
1476  # Make labels
1477  if axlabel:
1478  ax.set_ylabel('Temperature [GK]')
1479  ax.set_xlabel('Time [s]')
1480 
1481  return final_fig
1482 
1483 
1484  def plot_density(self,figure=None,axlabel=True,**kwargs):
1485  """
1486  Plot the density [g/ccm]
1487  Returns a figure object
1488  """
1489 
1490  # Make a figure if no figure was given
1491  if figure == None:
1492  final_fig = plt.figure()
1493  else:
1494  final_fig = figure
1495 
1496  # Get the axis instance from figure
1497  ax = final_fig.gca()
1498 
1499  # Collect data
1500  time,dens = self.get_density()
1501 
1502  # Plot data
1503  ax.plot(time,dens,**kwargs)
1504  ax.set_yscale('log')
1505 
1506  # Make labels
1507  if axlabel:
1508  ax.set_ylabel('Density [g/ccm]')
1509  ax.set_xlabel('Time [s]')
1510 
1511  return final_fig
1512 
1513 
1514  def plot_abar(self,figure=None,axlabel=True,**kwargs):
1515  """
1516  Plot average mass number
1517  Returns a figure object
1518  """
1519 
1520  # Make a figure if no figure was given
1521  if figure == None:
1522  final_fig = plt.figure()
1523  else:
1524  final_fig = figure
1525 
1526  # Get the axis instance from figure
1527  ax = final_fig.gca()
1528 
1529  # Collect data
1530  time,abar = self.get_abar()
1531 
1532  # Plot data
1533  ax.plot(time,abar,**kwargs)
1534 
1535  # Make labels
1536  if axlabel:
1537  ax.set_ylabel(r'<$\bar{A}$>')
1538  ax.set_xlabel('Time [s]')
1539 
1540  return final_fig
1541 
1542 
1543  def plot_zbar(self,figure=None,axlabel=True,**kwargs):
1544  """
1545  Plot average proton number
1546  Returns a figure object
1547  """
1548 
1549  # Make a figure if no figure was given
1550  if figure == None:
1551  final_fig = plt.figure()
1552  else:
1553  final_fig = figure
1554 
1555  # Get the axis instance from figure
1556  ax = final_fig.gca()
1557 
1558  # Collect data
1559  time,zbar = self.get_zbar()
1560 
1561  # Plot data
1562  ax.plot(time,zbar,**kwargs)
1563 
1564  # Make labels
1565  if axlabel:
1566  ax.set_ylabel(r'<$\bar{Z}$>')
1567  ax.set_xlabel('Time [s]')
1568 
1569  return final_fig
1570 
1571 
1572  def plot_radius(self,figure=None,axlabel=True,**kwargs):
1573  """
1574  Plot the radius
1575  Returns a figure object
1576  """
1577 
1578  # Make a figure if no figure was given
1579  if figure == None:
1580  final_fig = plt.figure()
1581  else:
1582  final_fig = figure
1583 
1584  # Get the axis instance from figure
1585  ax = final_fig.gca()
1586 
1587  # Collect data
1588  time,radius = self.get_radius()
1589 
1590  # Plot data
1591  ax.plot(time,radius,**kwargs)
1592 
1593  # Make labels
1594  if axlabel:
1595  ax.set_ylabel(r'Radius [km]')
1596  ax.set_xlabel('Time [s]')
1597 
1598  return final_fig
1599 
1600 
1601  def plot_trajectory(self,figure=None,**kwargs):
1602  """
1603  Plot all quantities of the trajectory from trajectory file
1604  """
1605 
1606  # Make a figure if no figure was given
1607  if figure == None:
1608  final_fig = plt.figure()
1609  else:
1610  final_fig = figure
1611 
1612 
1613  # Get the axis instance from figure
1614  gs = gridspec.GridSpec(2,3)
1615  radiusplot = plt.subplot(gs[0,0])
1616  densplot = plt.subplot(gs[0,1])
1617  tempplot = plt.subplot(gs[0,2])
1618  yeplot = plt.subplot(gs[1,0])
1619  entrplot = plt.subplot(gs[1,1])
1620  dentempplot = plt.subplot(gs[1,2])
1621 
1622  plt.subplots_adjust(hspace=0.5,wspace=0.5)
1623 
1624  # Collect data
1625  time,radius,dens,temp,ye,entr = self.get_trajectory()
1626 
1627  radiusplot.plot(time,radius,**kwargs)
1628  radiusplot.set_ylabel('Radius [cm]')
1629  radiusplot.set_xlabel('Time [s]')
1630 
1631  densplot.plot(time,dens,**kwargs)
1632  densplot.set_ylabel('Density [g/ccm]')
1633  densplot.set_xlabel('Time [s]')
1634 
1635  tempplot.plot(time,temp,**kwargs)
1636  tempplot.set_ylabel('Temperature [GK]')
1637  tempplot.set_xlabel('Time [s]')
1638 
1639  yeplot.plot(time,ye,**kwargs)
1640  yeplot.set_ylabel('Ye')
1641  yeplot.set_xlabel('Time [s]')
1642 
1643  entrplot.plot(time,entr,**kwargs)
1644  entrplot.set_ylabel('Entropy [kB/nucleon]')
1645  entrplot.set_xlabel('Time [s]')
1646 
1647  dentempplot.plot(dens,temp,**kwargs)
1648  dentempplot.set_ylabel('Temperature [GK]')
1649  dentempplot.set_xlabel('Density [g/ccm]')
1650 
1651  return final_fig
1652 
1653 
1654 
1655 
1656 
1657  def plot_flow_range(self,start=1,end=0,outputpath='./',threads=5,silence=False,plotaxis=[0,0,0,0],ilabel=1,imlabel=0,imagic=0,prange=4,iplot=2):
1658  """
1659  Plot all flow files in a range from start to end. If end is 0 (default) all flow files will get plotted.
1660  The files will added to outputpath.
1661  This routine is also parallized, threads determines the number of cores used.
1662  Silence: should the routine print something?
1663  """
1664  # TODO parallize it
1665 
1666  if outputpath[-1] != '/':
1667  outputpath += '/'
1668 
1669  if end==0:
1670  end = len(os.listdir(self.__path+'flow/'))
1671 
1672  for i in range(start,end+1,1):
1673  fig = self.plot_flow(i,plotaxis=[1,20,1,20],ilabel=1,imlabel=0,imagic=0,prange=4,iplot=2)
1674  fig.savefig(outputpath+'flow_{n:04d}'.format(n=i))
1675 
1676 
1677  def plot_integrated_flow(self,figure=None,fig_is_ax=False,plotaxis=[0,0,0,0],ilabel=1,imlabel=0,imagic=0,prange=4,iplot=2):
1678  """
1679  Plot flows over all timesteps
1680  """
1681  if figure == None:
1682  final_fig = plt.figure()
1683  else:
1684  final_fig = figure
1685 
1686  if fig_is_ax:
1687  ax = final_fig
1688  else:
1689  # Get the axis instance from figure
1690  ax = final_fig.gca()
1691 
1692  # Count the flows in the folder
1693  all_flows = np.array(os.listdir(self.__path+'flow/'))
1694  flow_names = all_flows[np.array(['flow' in x for x in all_flows])]
1695 
1696  integrated_flow = None
1697 
1698  for flownumber in np.arange(1,len(flow_names)):
1699  inputfile = self.__path+'flow/flow_{n:04d}.dat'.format(n=flownumber)
1700  inputfile_next = self.__path+'flow/flow_{n:04d}.dat'.format(n=flownumber+1)
1701  # Give warning if flow file does not exist
1702  if (not os.path.exists(inputfile)) or (not os.path.exists(inputfile_next) ):
1703  print('Warning: flow_{n:04d}.dat'.format(n=flownumber)+' does not exist!' )
1704  continue
1705 
1706  # Read the flow file
1707  ff = self.__read_flow(inputfile)
1708  ff_next = self.__read_flow(inputfile_next)
1709 
1710  timestep = ff_next['time']-ff['time']
1711  print(timestep)
1712  flow = ff['flow']
1713  if integrated_flow is None:
1714  integrated_flow = flow
1715  else:
1716  integrated_flow+=flow*timestep
1717 
1718  integrated_flow = np.log10(integrated_flow+1e-99)
1719  flow = integrated_flow
1720  sort = flow.argsort()
1721  flow = flow[sort]
1722  nin = ff['nin'][sort]
1723  zin = ff['zin'][sort]
1724  yin = ff['yin'][sort]
1725  nout = ff['nout'][sort]
1726  zout = ff['zout'][sort]
1727  yout = ff['yout'][sort]
1728  maxflow = max(flow)
1729  nzmax = int(max(max(zin),max(zout)))+1
1730  nnmax = int(max(max(nin),max(nout)))+1
1731  nzycheck = np.zeros([nnmax,nzmax,3])
1732  for i in range(len(nin)):
1733  ni = int(nin[i])
1734  zi = int(zin[i])
1735  nzycheck[ni,zi,0] = 1
1736  nzycheck[ni,zi,1] = yin[i]
1737  if iplot==1 or iplot==2:
1738  no = int(nout[i])
1739  zo = int(zout[i])
1740  nzycheck[no,zo,0] = 1
1741  nzycheck[no,zo,1] = yout[i]
1742  if iplot==1 and flow[i]>maxflow-prange:
1743  nzycheck[ni,zi,2] = 1
1744  nzycheck[no,zo,2] = 1
1745 
1746  #### create plot
1747 
1748  ## define axis and plot style (colormap, size, fontsize etc.)
1749  if plotaxis==[0,0,0,0]:
1750  xdim=10
1751  ydim=6
1752  else:
1753  dx = plotaxis[1]-plotaxis[0]
1754  dy = plotaxis[3]-plotaxis[2]
1755  ydim = 10
1756  xdim = ydim*dx/dy
1757 
1758  format = 'png'#'pdf'
1759 
1760 
1761  # color map choice for abundances
1762  cmapa = cm.jet
1763  # color map choice for arrows
1764  cmapr = cm.jet#autumn
1765  # if a value is below the lower limit its set to white
1766  cmapa.set_under(color='w')
1767  cmapr.set_under(color='w')
1768  # set value range for abundance colors (log10(Y))
1769  norma = colors.Normalize(vmin=-10,vmax=-3)
1770  # declare scalarmappable for abundances
1771  a2c = cm.ScalarMappable(norm=norma,cmap=cmapa)
1772  a=[]
1773  a2c.set_array(np.array(a))
1774  # set x- and y-axis scale aspect ratio to 1
1775  ax.set_aspect('equal')
1776  #print time,temp and density on top
1777  temp = '%8.3e' %ff['temp']
1778  time = '%8.3e' %ff['time']
1779  dens = '%8.3e' %ff['dens']
1780 
1781 
1782  ## only abundance plotted
1783  if iplot==0 or iplot==2:
1784  patches = []
1785  color = []
1786 
1787  for i in range(nzmax):
1788  for j in range(nnmax):
1789  if nzycheck[j,i,0]==1:
1790  # abundance
1791  yab = nzycheck[j,i,1]
1792  col = a2c.to_rgba(np.log10(yab))
1793  xy = j-0.5,i-0.5
1794  rect = Rectangle(xy,1,1,ec='k',color=col,picker=True)
1795  rect.set_zorder(1)
1796  ax.add_patch(rect)
1797 
1798  cb=plt.colorbar(a2c)
1799 
1800  # colorbar label
1801  cb.set_label('log$_{10}$(Y)')
1802 
1803  # Add black frames for stable isotopes
1804  f = open(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))+'/data/stableiso.dat')
1805 
1806  #head = f.readline()
1807  stable = []
1808 
1809  for line in f.readlines():
1810  tmp = line.split()
1811  zz = int(tmp[2])
1812  nn = int(tmp[1])
1813  xy = nn,zz
1814  circ = Circle(xy,radius=0.1,fc='k')
1815  circ.set_zorder(2)
1816  ax.add_patch(circ)
1817 
1818  if iplot==1 or iplot==2:
1819  apatches = []
1820  acolor = []
1821  m = 0.8/prange
1822  vmax=np.ceil(max(flow))
1823  vmin=max(flow)-prange
1824  b=-vmin*m+0.1
1825  normr = colors.Normalize(vmin=vmin,vmax=vmax)
1826  ymax=0.
1827  xmax=0.
1828 
1829  for i in range(len(nin)):
1830  x = nin[i]
1831  y = zin[i]
1832  dx = nout[i]-nin[i]
1833  dy = zout[i]-zin[i]
1834 
1835  if flow[i]>=vmin:
1836  arrowwidth = flow[i]*m+b
1837  arrow = Arrow(x,y,dx,dy, width=arrowwidth)
1838  if xmax<x:
1839  xmax=x
1840  if ymax<y:
1841  ymax=y
1842  acol = flow[i]
1843  apatches.append(arrow)
1844  acolor.append(acol)
1845 
1846  if iplot==1:
1847  xy = x-0.5,y-0.5
1848  rect = Rectangle(xy,1,1,ec='k',fc='None',fill='False',lw=1.)
1849  rect.set_zorder(2)
1850  ax.add_patch(rect)
1851  xy = x+dx-0.5,y+dy-0.5
1852  rect = Rectangle(xy,1,1,ec='k',fc='None',fill='False',lw=1.)
1853  rect.set_zorder(2)
1854  ax.add_patch(rect)
1855 
1856 
1857  a = PatchCollection(apatches, cmap=cmapr, norm=normr)
1858  a.set_array(np.array(acolor))
1859  a.set_zorder(3)
1860  ax.add_collection(a)
1861  cb = plt.colorbar(a)
1862 
1863  # colorbar label
1864  cb.set_label('log$_{10}$(f)')
1865 
1866  # decide which array to take for label positions
1867  iarr = 0
1868  if iplot==1: iarr=2
1869 
1870  # plot element labels
1871  if ilabel==1:
1872  for z in range(nzmax):
1873  try:
1874  nmin = min(np.argwhere(nzycheck[:,z,iarr]))[0]-1
1875  ax.text(nmin,z,self.__elname[z],horizontalalignment='center',verticalalignment='center',fontsize='medium',clip_on=True)
1876  except:
1877  continue
1878 
1879  # plot mass numbers
1880  if imlabel==1:
1881  for z in range(nzmax):
1882  for n in range(nnmax):
1883  a = z+n
1884  if nzycheck[n,z,iarr]==1:
1885  ax.text(n,z,a,horizontalalignment='center',verticalalignment='center',fontsize='small',clip_on=True)
1886 
1887  # plot lines at magic numbers
1888  if imagic==1:
1889  ixymagic=[2, 8, 20, 28, 50, 82, 126]
1890  nmagic = len(ixymagic)
1891  for magic in ixymagic:
1892  if magic<=nzmax:
1893  try:
1894  xnmax = max(np.argwhere(nzycheck[:,magic,iarr]))[0]
1895  line = ax.plot([-0.5,xnmax+0.5],[magic-0.5,magic-0.5],lw=3.,color='r',ls='--')
1896  line = ax.plot([-0.5,xnmax+0.5],[magic+0.5,magic+0.5],lw=3.,color='r',ls='--')
1897  except ValueError:
1898  dummy=0
1899  if magic<=nnmax:
1900  try:
1901  yzmax = max(np.argwhere(nzycheck[magic,:,iarr]))[0]
1902  line = ax.plot([magic-0.5,magic-0.5],[-0.5,yzmax+0.5],lw=3.,color='r',ls='--')
1903  line = ax.plot([magic+0.5,magic+0.5],[-0.5,yzmax+0.5],lw=3.,color='r',ls='--')
1904  except ValueError:
1905  dummy=0
1906 
1907  # set axis limits
1908  if plotaxis==[0,0,0,0]:
1909  if iplot==2 or iplot==0:
1910  xmax=max(nin)
1911  ymax=max(zin)
1912  ax.axis([-0.5,xmax+0.5,-0.5,ymax+0.5])
1913  else:
1914  ax.axis([plotaxis[0]-0.5,plotaxis[1]+0.5,plotaxis[2]-0.5,plotaxis[3]+0.5])
1915 
1916  # set x- and y-axis label
1917  ax.set_xlabel('neutron number')
1918  ax.set_ylabel('proton number')
1919 
1920  def onpick1(event):
1921  # print event.artist
1922  if isinstance(event.artist, Rectangle):
1923  patch = event.artist
1924  pn = int(patch.get_x()+0.5)
1925  pz = int(patch.get_y()+0.5)
1926  pab = '%8.3e' %nzycheck[pn,pz,1]
1927  tmp = (pn+pz)*nzycheck[pn,pz,1]
1928  pmf = '%8.3e' %tmp
1929  print( self.__elname[pz] + str(pn+pz) + ' , Y = ' + pab + ' X = ' + pmf )
1930 
1931  return final_fig
1932 
1933  def plot_flow(self,flownumber,plotaxis=[0,0,0,0],ilabel=1,imlabel=0,imagic=0,prange=4,iplot=2):
1934  """
1935  Plot a flow with a given flownumber.
1936 
1937  Originally from Christian Winteler and Urs Frischknecht
1938  Edited by Moritz Reichert (2.4.2017)
1939 
1940  Plotting options are:
1941  plotaxis : Set axis limit: If default [0,0,0,0] the complete range in (N,Z) will be plotted, i.e. all isotopes, else specify the limits in plotaxis = [xmin,xmax,ymin,ymax]
1942  ilabel : elemental labels off/on [0/1]
1943  imlabel : label for isotopic masses off/on [0/1]
1944  prange : flow is plotted over "prange" dex. If flow < maxflow-prange it is not plotted
1945  iplot : plot handler abundance/flux/abundance+flux plot [0/1/2]
1946  """
1947 
1948 
1949  inputfile = self.__path+'flow/flow_{n:04d}.dat'.format(n=flownumber)
1950 
1951  ff = self.__read_flow(inputfile)
1952  try:
1953  flow = np.log10(ff['flow']+1.e-99)
1954  sort = flow.argsort()
1955  flow = flow[sort]
1956  nin = ff['nin'][sort]
1957  zin = ff['zin'][sort]
1958  yin = ff['yin'][sort]
1959  nout = ff['nout'][sort]
1960  zout = ff['zout'][sort]
1961  yout = ff['yout'][sort]
1962  maxflow = max(flow)
1963  nzmax = int(max(max(zin),max(zout)))+1
1964  nnmax = int(max(max(nin),max(nout)))+1
1965  except KeyError:
1966  if iplot==1 or iplot==2:
1967  sys.exit('The read file does not contain flow data')
1968  nin = ff['nin']
1969  zin = ff['zin']
1970  yin = ff['yin']
1971  nnmax = int(max(nin))+1
1972  nzmax = int(max(zin))+1
1973 
1974  nzycheck = np.zeros([nnmax,nzmax,3])
1975  for i in range(len(nin)):
1976  ni = int(nin[i])
1977  zi = int(zin[i])
1978  nzycheck[ni,zi,0] = 1
1979  nzycheck[ni,zi,1] = yin[i]
1980  if iplot==1 or iplot==2:
1981  no = int(nout[i])
1982  zo = int(zout[i])
1983  nzycheck[no,zo,0] = 1
1984  nzycheck[no,zo,1] = yout[i]
1985  if iplot==1 and flow[i]>maxflow-prange:
1986  nzycheck[ni,zi,2] = 1
1987  nzycheck[no,zo,2] = 1
1988 
1989  #### create plot
1990 
1991  ## define axis and plot style (colormap, size, fontsize etc.)
1992  if plotaxis==[0,0,0,0]:
1993  xdim=10
1994  ydim=6
1995  else:
1996  dx = plotaxis[1]-plotaxis[0]
1997  dy = plotaxis[3]-plotaxis[2]
1998  ydim = 10
1999  xdim = ydim*dx/dy
2000 
2001  format = 'png'#'pdf'
2002  params = {'axes.labelsize': 15,
2003  'text.fontsize': 15,
2004  'legend.fontsize': 15,
2005  'xtick.labelsize': 15,
2006  'ytick.labelsize': 15,
2007  'text.usetex': True}
2008  plt.rcParams.update(params)
2009  fig=plt.figure(figsize=(xdim,ydim),dpi=100)
2010  axx = 0.06
2011  axy = 0.10
2012  axw = 0.90
2013  axh = 0.8
2014  ax=plt.axes([axx,axy,axw,axh])
2015 
2016  # color map choice for abundances
2017  cmapa = cm.jet
2018  # color map choice for arrows
2019  cmapr = cm.jet#autumn
2020  # if a value is below the lower limit its set to white
2021  cmapa.set_under(color='w')
2022  cmapr.set_under(color='w')
2023  # set value range for abundance colors (log10(Y))
2024  norma = colors.Normalize(vmin=-10,vmax=-3)
2025  # declare scalarmappable for abundances
2026  a2c = cm.ScalarMappable(norm=norma,cmap=cmapa)
2027  a=[]
2028  a2c.set_array(np.array(a))
2029  # set x- and y-axis scale aspect ratio to 1
2030  ax.set_aspect('equal')
2031  #print time,temp and density on top
2032  temp = '%8.3e' %ff['temp']
2033  time = '%8.3e' %ff['time']
2034  dens = '%8.3e' %ff['dens']
2035 
2036  box1 = TextArea("t : " + time + " s~~/~~T$_{9}$ : " + temp + "~~/~~$\\rho_{b}$ : " \
2037  + dens + ' g/cm$^{3}$', textprops=dict(color="k"))
2038  anchored_box = AnchoredOffsetbox(loc=3,
2039  child=box1, pad=0.,
2040  frameon=False,
2041  bbox_to_anchor=(0., 1.02),
2042  bbox_transform=ax.transAxes,
2043  borderpad=0.,
2044  )
2045  ax.add_artist(anchored_box)
2046 
2047  ## only abundance plotted
2048  if iplot==0 or iplot==2:
2049  patches = []
2050  color = []
2051 
2052  for i in range(nzmax):
2053  for j in range(nnmax):
2054  if nzycheck[j,i,0]==1:
2055  # abundance
2056  yab = nzycheck[j,i,1]
2057  col = a2c.to_rgba(np.log10(yab))
2058  xy = j-0.5,i-0.5
2059  rect = Rectangle(xy,1,1,ec='k',color=col,picker=True)
2060  rect.set_zorder(1)
2061  ax.add_patch(rect)
2062 
2063  cb=plt.colorbar(a2c)
2064 
2065  # colorbar label
2066  cb.set_label('log$_{10}$(Y)')
2067 
2068  # Add black frames for stable isotopes
2069  f = open(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))+'/data/stableiso.dat')
2070 
2071  #head = f.readline()
2072  stable = []
2073 
2074  for line in f.readlines():
2075  tmp = line.split()
2076  zz = int(tmp[2])
2077  nn = int(tmp[1])
2078  xy = nn,zz
2079  circ = Circle(xy,radius=0.1,fc='k')
2080  circ.set_zorder(2)
2081  ax.add_patch(circ)
2082 
2083  if iplot==1 or iplot==2:
2084  apatches = []
2085  acolor = []
2086  m = 0.8/prange
2087  vmax=np.ceil(max(flow))
2088  vmin=max(flow)-prange
2089  b=-vmin*m+0.1
2090  normr = colors.Normalize(vmin=vmin,vmax=vmax)
2091  ymax=0.
2092  xmax=0.
2093 
2094  for i in range(len(nin)):
2095  x = nin[i]
2096  y = zin[i]
2097  dx = nout[i]-nin[i]
2098  dy = zout[i]-zin[i]
2099 
2100  if flow[i]>=vmin:
2101  arrowwidth = flow[i]*m+b
2102  arrow = Arrow(x,y,dx,dy, width=arrowwidth)
2103  if xmax<x:
2104  xmax=x
2105  if ymax<y:
2106  ymax=y
2107  acol = flow[i]
2108  apatches.append(arrow)
2109  acolor.append(acol)
2110 
2111  if iplot==1:
2112  xy = x-0.5,y-0.5
2113  rect = Rectangle(xy,1,1,ec='k',fc='None',fill='False',lw=1.)
2114  rect.set_zorder(2)
2115  ax.add_patch(rect)
2116  xy = x+dx-0.5,y+dy-0.5
2117  rect = Rectangle(xy,1,1,ec='k',fc='None',fill='False',lw=1.)
2118  rect.set_zorder(2)
2119  ax.add_patch(rect)
2120 
2121 
2122  a = PatchCollection(apatches, cmap=cmapr, norm=normr)
2123  a.set_array(np.array(acolor))
2124  a.set_zorder(3)
2125  ax.add_collection(a)
2126  cb = plt.colorbar(a)
2127 
2128  # colorbar label
2129  cb.set_label('log$_{10}$(f)')
2130 
2131  # decide which array to take for label positions
2132  iarr = 0
2133  if iplot==1: iarr=2
2134 
2135  # plot element labels
2136  if ilabel==1:
2137  for z in range(nzmax):
2138  try:
2139  nmin = min(np.argwhere(nzycheck[:,z,iarr]))[0]-1
2140  ax.text(nmin,z,self.__elname[z],horizontalalignment='center',verticalalignment='center',fontsize='medium',clip_on=True)
2141  except:
2142  continue
2143 
2144  # plot mass numbers
2145  if imlabel==1:
2146  for z in range(nzmax):
2147  for n in range(nnmax):
2148  a = z+n
2149  if nzycheck[n,z,iarr]==1:
2150  ax.text(n,z,a,horizontalalignment='center',verticalalignment='center',fontsize='small',clip_on=True)
2151 
2152  # plot lines at magic numbers
2153  if imagic==1:
2154  ixymagic=[2, 8, 20, 28, 50, 82, 126]
2155  nmagic = len(ixymagic)
2156  for magic in ixymagic:
2157  if magic<=nzmax:
2158  try:
2159  xnmax = max(np.argwhere(nzycheck[:,magic,iarr]))[0]
2160  line = ax.plot([-0.5,xnmax+0.5],[magic-0.5,magic-0.5],lw=3.,color='r',ls='--')
2161  line = ax.plot([-0.5,xnmax+0.5],[magic+0.5,magic+0.5],lw=3.,color='r',ls='--')
2162  except ValueError:
2163  dummy=0
2164  if magic<=nnmax:
2165  try:
2166  yzmax = max(np.argwhere(nzycheck[magic,:,iarr]))[0]
2167  line = ax.plot([magic-0.5,magic-0.5],[-0.5,yzmax+0.5],lw=3.,color='r',ls='--')
2168  line = ax.plot([magic+0.5,magic+0.5],[-0.5,yzmax+0.5],lw=3.,color='r',ls='--')
2169  except ValueError:
2170  dummy=0
2171 
2172  # set axis limits
2173  if plotaxis==[0,0,0,0]:
2174  if iplot==2 or iplot==0:
2175  xmax=max(nin)
2176  ymax=max(zin)
2177  ax.axis([-0.5,xmax+0.5,-0.5,ymax+0.5])
2178  else:
2179  ax.axis([plotaxis[0]-0.5,plotaxis[1]+0.5,plotaxis[2]-0.5,plotaxis[3]+0.5])
2180 
2181  # set x- and y-axis label
2182  ax.set_xlabel('neutron number')
2183  ax.set_ylabel('proton number')
2184 
2185  def onpick1(event):
2186  # print event.artist
2187  if isinstance(event.artist, Rectangle):
2188  patch = event.artist
2189  pn = int(patch.get_x()+0.5)
2190  pz = int(patch.get_y()+0.5)
2191  pab = '%8.3e' %nzycheck[pn,pz,1]
2192  tmp = (pn+pz)*nzycheck[pn,pz,1]
2193  pmf = '%8.3e' %tmp
2194  print( self.__elname[pz] + str(pn+pz) + ' , Y = ' + pab + ' X = ' + pmf )
2195 
2196  fig.canvas.mpl_connect('pick_event', onpick1)
2197  #~ fig.savefig('test.png',dpi=400)
2198  return fig
2199 
2200 
2201  def plot_ye(self,figure=None,axlabel=True,**kwargs):
2202  """
2203  Plot average proton number
2204  Returns a figure object
2205  """
2206 
2207  # Make a figure if no figure was given
2208  if figure == None:
2209  final_fig = plt.figure()
2210  else:
2211  final_fig = figure
2212 
2213  # Get the axis instance from figure
2214  ax = final_fig.gca()
2215 
2216  # Collect data
2217  time,ye = self.get_ye()
2218 
2219  # Plot data
2220  ax.plot(time,ye,**kwargs)
2221 
2222  # Make labels
2223  if axlabel:
2224  ax.set_ylabel(r'Y$_e$')
2225  ax.set_xlabel('Time [s]')
2226 
2227  return final_fig
2228 
2229 
2230  def plot_entropy(self,figure=None,axlabel=True,**kwargs):
2231  """
2232  Plot the entropy [kb/nucleon]
2233  Returns a figure object
2234  """
2235 
2236  # Make a figure if no figure was given
2237  if figure == None:
2238  final_fig = plt.figure()
2239  else:
2240  final_fig = figure
2241 
2242  # Get the axis instance from figure
2243  ax = final_fig.gca()
2244 
2245  # Collect data
2246  time,entr = self.get_entropy()
2247 
2248  # Plot data
2249  ax.plot(time,entr,**kwargs)
2250 
2251  # Make labels
2252  if axlabel:
2253  ax.set_ylabel(r'Entropy [kB/nucleon]')
2254  ax.set_xlabel('Time [s]')
2255 
2256  return final_fig
2257 
2258 
2259  def plot_timescales(self,figure=None,axlabel=True,**kwargs):
2260  """
2261  Plot the timescales for a Winnet run (ng, gn, pg, gp, np, pn, an, na, beta (all [1/s]))
2262  """
2263 
2264  # Make a figure if no figure was given
2265  if figure == None:
2266  final_fig = plt.figure()
2267  else:
2268  final_fig = figure
2269 
2270  # Get the axis instance from figure
2271  ax = final_fig.gca()
2272 
2273  # Collect data
2274  ts = self.get_timescales()
2275 
2276  time = ts[0]
2277  timescales = ts[2:]
2278  labels = [r'$\gamma$-a',r'a-$\gamma$',r'n-$\gamma$',r'$\gamma$-n',r'p-$\gamma$',r'$\gamma$-p',r'n-p',r'p-n',r'$\alpha$-n',r'n-$\alpha$',r'$\beta$']
2279  colors = ['red','blue','green','saddlebrown','cyan','magenta',"tab:orange"]
2280 
2281  # Plot data
2282  ax.set_yscale('log')
2283  ax.set_xscale('log')
2284  for i in range(len(labels)):
2285  if i % 2 == 0:
2286  col = colors[int(i/2)]
2287  ax.plot(time,timescales[i],ls='-',label=labels[i],color=col,**kwargs)
2288  else:
2289  ax.plot(time,timescales[i],ls='--',label=labels[i],color=col,**kwargs)
2290 
2291  # Make labels
2292  if axlabel:
2293  ax.set_ylabel(r'Timescale [s]')
2294  ax.set_xlabel('Time [s]')
2295 
2296  return final_fig
2297 
2298 
2299  def plot_sunet(self,figure=None):
2300  """
2301  Plot the contained nuclei of the run. The information is extracted from param.out
2302  """
2303  if len(self.__param_parameter) == 0:
2304  print('Call read_template first! Your script might not work now!')
2305  return
2306  # Get path to sunet file
2307  ind = self.__param_parameter.index('net_source')
2308  filewithnuclei = self.__param_data[ind].replace('"','').strip()
2309 
2310  stableisotopes = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))+'/data/stableiso.dat'
2311 
2312  #Get stable nuclei
2313  stable_n,stable_z = np.loadtxt(stableisotopes,unpack = True, usecols=(1,2))
2314 
2315  #Get the nuclei
2316  nucleilist = np.loadtxt(filewithnuclei,unpack = True,dtype=str)
2317 
2318  max_p = 0
2319  max_n = 0
2320 
2321  #make them to nucleiclass
2322  nucleiclass = []
2323  for nuc in nucleilist:
2324  nucleiclass.append(nucleus(nuc))
2325  if max_p < nucleus(nuc).get_Z():
2326  max_p = nucleus(nuc).get_Z()
2327  if max_n < nucleus(nuc).get_N():
2328  max_n = nucleus(nuc).get_N()
2329 
2330  amountneutrons = max_n + 1
2331  amountprotons = max_p + 1
2332 
2333  # Make a figure if no figure was given
2334  if figure == None:
2335  fig = plt.figure(figsize=(amountneutrons/10.,amountprotons/10.))
2336  else:
2337  fig = figure
2338 
2339  ax = fig.gca()
2340 
2341  #~ alphanuclei = [2,4,6,8,10,12,14,16,18,20,22,24,26,28]
2342  alphanuclei = []
2343  magicnumbers = [8,20,28,50,82,126]
2344 
2345  for nuc in nucleiclass:# plot nuclei
2346  z = nuc.get_Z()-0.5
2347  n = nuc.get_N()-0.5
2348  xy = n,z
2349 
2350  stable = False
2351  for i in range(len(stable_z)):
2352  if (stable_z[i] == nuc.get_Z()) and (stable_n[i] == nuc.get_N()):
2353  stable = True
2354  break
2355 
2356  # Uncomment to color the iron region
2357  #~ if nuc.get_Z()+nuc.get_N()>=50 and nuc.get_Z()+nuc.get_N()<=62:
2358  #~ rectcolor = '#6969ae'
2359  #~ else:
2360  rectcolor = '#d4e5ff'
2361 
2362  if not stable:
2363  rect = Rectangle(xy,1,1,ec='gray',zorder=1,lw=0.5,color=rectcolor)
2364  else:
2365  rect = Rectangle(xy,1,1,ec='k',zorder=2,lw=1,color=rectcolor)
2366 
2367  ax.add_patch(rect)
2368 
2369  if ((nuc.get_N() in alphanuclei) and (nuc.get_Z() == nuc.get_N())):
2370  xy = n + 0.05,z+0.05
2371  rect = Rectangle(xy,0.90,0.90,ec='red',zorder=3,lw=0.7,color=rectcolor)
2372  ax.add_patch(rect)
2373 
2374  #set the elementlabels
2375  for z in range(amountprotons):
2376 
2377  min_n = amountneutrons
2378 
2379  for nuc in nucleiclass:
2380  if (z == nuc.get_Z() and min_n > nuc.get_N()):
2381  min_n = nuc.get_N()
2382  name = nuc.get_elementname()
2383  if name == 'neutron':
2384  name = 'n'
2385  if name == 'h':
2386  name = 'p'
2387 
2388  if z==0:
2389  ax.text(min_n - 1 - 0.4*len(name), z-0.5, name, fontsize = 5)
2390  else:
2391  if ('l' in name) or ('i' in name):
2392  ax.text(min_n - 1 - 0.3*len(name), z-0.2, name, fontsize = 5)
2393  elif 'm' in name:
2394  ax.text(min_n - 1 - 0.5*len(name), z-0.2, name, fontsize = 5)
2395  else:
2396  ax.text(min_n - 1 - 0.4*len(name), z-0.2, name, fontsize = 5)
2397 
2398  #set the magic numbers
2399  for i in range(len(magicnumbers)):
2400  magic = magicnumbers[i]
2401 
2402  #neutron magic
2403  min_z = 10000
2404  max_z = -1
2405  min_N = -0.5
2406  max_N = 10000
2407  for nuc in nucleiclass:
2408  if nuc.get_N() == magic:
2409  if nuc.get_Z()<min_z:
2410  min_z=float(nuc.get_Z())
2411  if nuc.get_Z()>max_z:
2412  max_z=float(nuc.get_Z())
2413 
2414  if nuc.get_Z() == magic:
2415  if nuc.get_N()>min_N:
2416  min_N=float(nuc.get_N())
2417  if nuc.get_N()<max_N:
2418  max_N=float(nuc.get_N())
2419 
2420  width = 0.7
2421  dash = (3,2)
2422  #neutron magic
2423  ax.plot([magic-0.5, magic-0.5], [min_z-0.5, max_z+0.5], color='k',linestyle='--',lw=width, dashes=dash)
2424  ax.plot([magic+0.5, magic+0.5], [min_z-0.5, max_z+0.5], color='k',linestyle='--',lw=width, dashes=dash)
2425  #proton magic
2426  ax.plot([max_N-0.5,min_N+0.5],[magic-0.5, magic-0.5], color='k',linestyle='--',lw=width, dashes=dash)
2427  ax.plot([max_N-0.5,min_N+0.5],[magic+0.5, magic+0.5], color='k',linestyle='--',lw=width, dashes=dash)
2428 
2429  #remove the axis
2430  ax.get_xaxis().set_visible(False)
2431  ax.get_yaxis().set_visible(False)
2432 
2433  for axis in ['left','right','top','bottom']:
2434  ax.spines[axis].set_linewidth(0)
2435 
2436  ax.set_xlim(-1,amountneutrons)
2437  ax.set_ylim(-1,amountprotons)
2438 
2439  return fig
2440 
2441 
2442  def plot_mainout(self,figure=None,**kwargs):
2443  """
2444  Plot all information that are contained in mainout.dat
2445  iteration, time, temperature, density, Ye, Radius, Yn, Yp, Y_alpha, Y_light, Y_heavy, Zbar, Abar, Entropy
2446  """
2447  # Make a figure if no figure was given
2448  if figure == None:
2449  final_fig = plt.figure(figsize=(15,15))
2450  else:
2451  final_fig = figure
2452 
2453  # Get the axis instance from figure
2454  gs = gridspec.GridSpec(3,4)
2455  tempplot = plt.subplot(gs[0,0])
2456  densplot = plt.subplot(gs[0,1],sharex=tempplot)
2457  yeplot = plt.subplot(gs[0,2],sharex=tempplot)
2458  radiusplot = plt.subplot(gs[0,3],sharex=tempplot)
2459  ynplot = plt.subplot(gs[1,0],sharex=tempplot)
2460  ypplot = plt.subplot(gs[1,1],sharex=tempplot)
2461  yaplot = plt.subplot(gs[1,2],sharex=tempplot)
2462  ylightplot = plt.subplot(gs[1,3],sharex=tempplot)
2463  yheavyplot = plt.subplot(gs[2,0],sharex=tempplot)
2464  zbarplot = plt.subplot(gs[2,1],sharex=tempplot)
2465  abarplot = plt.subplot(gs[2,2],sharex=tempplot)
2466  entrplot = plt.subplot(gs[2,3],sharex=tempplot)
2467 
2468  plt.subplots_adjust(hspace=0.5,wspace=0.5)
2469 
2470  # Get data
2471  it,time,temp,dens,ye,rad,yn,yp,ya,ylight,yheavy,zbar,abar,entr = self.get_mainout()
2472 
2473  tempplot.plot(time,temp)
2474  tempplot.set_ylabel('Temperature [GK]')
2475  tempplot.set_xlabel('Time [s]')
2476  tempplot.set_xscale('log')
2477 
2478  densplot.plot(time,dens)
2479  densplot.set_yscale('log')
2480  densplot.set_ylabel('Density [g/ccm]')
2481  densplot.set_xlabel('Time [s]')
2482 
2483  yeplot.plot(time,ye)
2484  yeplot.set_ylabel('Ye')
2485  yeplot.set_xlabel('Time [s]')
2486 
2487  radiusplot.plot(time,rad)
2488  radiusplot.set_yscale('log')
2489  radiusplot.set_ylabel('Radius [km]')
2490  radiusplot.set_xlabel('Time [s]')
2491 
2492  ynplot.plot(time,yn)
2493  ynplot.set_ylabel('Yn')
2494  ynplot.set_xlabel('Time [s]')
2495  ynplot.set_yscale('log')
2496 
2497  ypplot.plot(time,yp)
2498  ypplot.set_ylabel('Yp')
2499  ypplot.set_xlabel('Time [s]')
2500  ypplot.set_yscale('log')
2501 
2502  yaplot.plot(time,ya)
2503  yaplot.set_ylabel('Yalpha')
2504  yaplot.set_xlabel('Time [s]')
2505  yaplot.set_yscale('log')
2506 
2507  ylightplot.plot(time,ylight)
2508  ylightplot.set_ylabel('Ylight')
2509  ylightplot.set_xlabel('Time [s]')
2510  ylightplot.set_yscale('log')
2511 
2512  yheavyplot.plot(time,yheavy)
2513  yheavyplot.set_ylabel('Yheavy')
2514  yheavyplot.set_xlabel('Time [s]')
2515  ylightplot.set_yscale('log')
2516 
2517  zbarplot.plot(time,zbar)
2518  zbarplot.set_ylabel('Zbar')
2519  zbarplot.set_xlabel('Time [s]')
2520 
2521  abarplot.plot(time,abar)
2522  abarplot.set_ylabel('Abar')
2523  abarplot.set_xlabel('Time [s]')
2524 
2525  entrplot.plot(time,entr)
2526  entrplot.set_ylabel('Entropy [kB/nucleon]')
2527  entrplot.set_xlabel('Time [s]')
2528 
2529  return final_fig
2530 
2531  def animate_nuclear_chart(self,figure=None,plot_magic=True,time_title=True,min_X=1e-8,max_X=None,cmap= cm.viridis,element_labels=True,**kwargs):
2532  """
2533  Make an animation of the mass fractions in the nuclear chart
2534  """
2535  # Make a figure if no figure was given
2536  if figure == None:
2537  final_fig = plt.figure(figsize=(10,5))
2538  else:
2539  final_fig = figure
2540 
2541  ax = final_fig.gca()
2542  ax.set_aspect(1)
2543 
2544  # Read time from the snapshots if not done already
2545  if len(self.__time)==0:
2546  self.read_snapshots()
2547 
2548  stable_n,stable_p,stable_a= np.loadtxt(\
2549  os.path.dirname(os.path.abspath(\
2550  inspect.getfile(inspect.currentframe())))+'/data/stableiso.dat',\
2551  unpack=True,usecols=[1,2,3])
2552  # Set a norm
2553  norm = mpl.colors.LogNorm(vmin=min_X, vmax=max_X,clip=False)
2554 
2555  def __init_anim():
2556  if time_title:
2557  snaps_time = self.__time[0]
2558  self.__helper_title = ax.text(0.02,0.95,"t = "+"{:.2e}".format(snaps_time)+" s",transform=ax.transAxes)
2559  current_n=self.__neutrons
2560  current_p=self.__protons
2561  mafra_out = self.__allmassfractions[0]
2562  rectangles = []
2563  edgecolors = []
2564  zorders = []
2565  stable_list = []
2566  linewidths = []
2567  for i in range(len(current_n)):
2568  n_tmp = current_n[i]
2569  p_tmp = current_p[i]
2570  xy = n_tmp-0.5,p_tmp-0.5
2571  is_stable = bool(sum((stable_n==n_tmp) & (stable_p==p_tmp)))
2572 
2573  if mafra_out[i]>= min_X:
2574  color_tmp = cmap(norm(mafra_out[i]))
2575  else:
2576  color_tmp = "w"
2577 
2578  if not is_stable:
2579  edgecolors.append("gray")
2580  zorders.append(1)
2581  rect = Rectangle(xy,1,1,zorder=1,lw=0.8)
2582  linewidths.append(0.8)
2583  stable_list.append(False)
2584  else:
2585  edgecolors.append("k")
2586  zorders.append(2)
2587  linewidths.append(1.2)
2588  stable_list.append(True)
2589 
2590  rect = Rectangle(xy,1,1)
2591  rectangles.append(rect)
2592  stable_list=np.array(stable_list)
2593 
2594  self.__helper_stab = stable_list
2595  # Sort it as the zorder is buggy in patch collections
2596  # Set the stable once as last so that they are drawn in the foreground
2597  rectangles =list(np.array(rectangles)[~stable_list])+list(np.array(rectangles)[stable_list])
2598  edgecolors=list(np.array(edgecolors)[~stable_list])+list(np.array(edgecolors)[stable_list])
2599  sorted_mafra=np.array(list(np.array(mafra_out)[~stable_list])+list(np.array(mafra_out)[stable_list]))
2600  linewidths=np.array(list(np.array(linewidths)[~stable_list])+list(np.array(linewidths)[stable_list]))
2601  # Create the collection
2602  # In principle, individual patches work as well, but with worse performance
2603  pc = PatchCollection(rectangles)
2604  self.__helper_pc = pc
2605  # Make it white
2606  cmap.set_under("w")
2607  pc.set(array=sorted_mafra, cmap=cmap,norm=norm,edgecolors=edgecolors,linewidths=linewidths,zorder=-30)
2608  ax.add_collection(pc)
2609 
2610  divider = make_axes_locatable(ax)
2611  cax = divider.append_axes("right", size="3%", pad=0.05)
2612  final_fig.colorbar(pc,shrink=0.5,label="Mass fraction", cax=cax)
2613 
2614  # Plot magic numbers?
2615  if plot_magic:
2616  magicnumbers = [8,20,28,50,82,126]
2617  #set the magic numbers
2618  lines = []
2619  for i in range(len(magicnumbers)):
2620  magic = magicnumbers[i]
2621 
2622  #neutron magic
2623  min_z = 10000
2624  max_z = -1
2625  min_N = -0.5
2626  max_N = 10000
2627  for ind,p in enumerate(current_p):
2628  if current_n[ind] == magic:
2629  if current_p[ind]<min_z:
2630  min_z=float(current_p[ind])
2631  if current_p[ind]>max_z:
2632  max_z=float(current_p[ind])
2633 
2634  if current_p[ind] == magic:
2635  if current_n[ind]>min_N:
2636  min_N=float(current_n[ind])
2637  if current_n[ind]<max_N:
2638  max_N=float(current_n[ind])
2639 
2640  width = 1.3
2641  dash = (3,2)
2642  if min_z!=10000:
2643  #neutron magic
2644  # a,= ax.plot([magic-0.5, magic-0.5], [min_z-0.5, max_z+0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2645  l = [(magic-0.5, min_z-0.5),( magic-0.5,max_z+0.5)]
2646  lines.append(l)
2647  # a,= ax.plot([magic+0.5, magic+0.5], [min_z-0.5, max_z+0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2648  l = [(magic+0.5, min_z-0.5), (magic+0.5, max_z+0.5)]
2649  lines.append(l)
2650  if max_N!=10000:
2651  #proton magic
2652  # a,= ax.plot([max_N-0.5,min_N+0.5],[magic-0.5, magic-0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2653  l = [(max_N-0.5,magic-0.5),(min_N+0.5, magic-0.5)]
2654  lines.append(l)
2655  # a,= ax.plot([max_N-0.5,min_N+0.5],[magic+0.5, magic+0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2656  l = [(max_N-0.5,magic+0.5),(min_N+0.5, magic+0.5)]
2657  lines.append(l)
2658 
2659  self.__helper_line_segments = LineCollection(lines,
2660  linewidths=1.3,
2661  linestyles='--',
2662  colors="k")
2663  ax.add_collection(self.__helper_line_segments)
2664 
2665  if element_labels:
2666  #set the elementlabels
2667  labels = []
2668  for z in current_p:
2669  min_n = min(current_n[current_p==z])
2670 
2671  n = nucleus(N=int(min_n),Z=int(z))
2672  name = n.get_elementname()
2673  if name == 'neutron':
2674  name = 'n'
2675  elif name == 'h':
2676  name = 'p'
2677  else:
2678  name = name[0].upper()+name[1:]
2679 
2680  l = TextPath((min_n - 1.8 , z-0.25), name, size=0.9,ha="right",va='center')
2681  labels.append(PathPatch(l))
2682 
2683  pc = PatchCollection(labels,color='k')
2684  ax.add_collection(pc)
2685 
2686  ax.set_xlabel('Neutron number')
2687  ax.set_ylabel('Proton number')
2688 
2689  if plot_magic and time_title:
2690  return self.__helper_pc,self.__helper_line_segments,self.__helper_title,
2691  if plot_magic and (not time_title):
2692  return self.__helper_pc,self.__helper_line_segments,
2693  else:
2694  return self.__helper_pc,
2695 
2696  def __animate(ind):
2697  if time_title:
2698  snaps_time = self.__time[ind]
2699  self.__helper_title.set_text("t = "+"{:.2e}".format(snaps_time)+" s")
2700 
2701  mafra_out = self.__allmassfractions[ind]
2702  sorted_mafra=np.array(list(np.array(mafra_out)[~self.__helper_stab])+list(np.array(mafra_out)[self.__helper_stab]))
2703  self.__helper_pc.set(array=sorted_mafra)
2704 
2705  if plot_magic and time_title:
2706  return self.__helper_pc,self.__helper_line_segments,self.__helper_title,
2707  if plot_magic and (not time_title):
2708  return self.__helper_pc,self.__helper_line_segments,
2709  else:
2710  return self.__helper_pc,
2711 
2712  anim = animation.FuncAnimation(final_fig, __animate, init_func=__init_anim,
2713  frames=len(self.__allmassfractions), blit=True)
2714 
2715  return anim
2716 
2717 
2718 
2719 
2720  def plot_nuclear_chart_at(self,time,figure=None,fig_is_ax=False,plot_magic=True,
2721  colorbar_inset=False,colorbar_position=[0.27, 0.8, 0.5, 0.025],colorbar=True,
2722  axes_label=True,time_title=True,min_X=1e-8,max_X=None,cmap= cm.viridis,element_labels=True,
2723  nuclei_linewidths=0.8,**kwargs):
2724  """
2725  Plot the abundances into the nuclear chart at a given time
2726  """
2727  # Make a figure if no figure was given
2728  if figure == None:
2729  final_fig = plt.figure(figsize=(10,5))
2730  else:
2731  final_fig = figure
2732 
2733  if not fig_is_ax:
2734  # Get the axis instance from figure
2735  ax = final_fig.gca()
2736  else:
2737  ax = figure
2738  final_fig = plt.gcf()
2739 
2740  ax.set_aspect(1)
2741 
2742  cmap = cmap.copy() # Avoid annoying deprecation warning
2743 
2744  stable_n,stable_p,stable_a = np.loadtxt(\
2745  os.path.dirname(os.path.abspath(\
2746  inspect.getfile(inspect.currentframe())))+'/data/stableiso.dat',unpack=True,usecols=[1,2,3])
2747 
2748  # Read time from the snapshots if not done already
2749  if len(self.__time)==0:
2750  self.__read_snapshot_time()
2751 
2752  # Get the difference for the time index
2753  ind = np.argmin(np.abs(self.__time - time))
2754 
2755  # corresponding snapshot file
2756  currentfile = 'snapsh_'+str((ind+1)).zfill(4)+'.dat'
2757  path = self.__path+'snaps/'
2758  snaps_time = self.__time[ind]
2759  if time_title:
2760  ax.set_title("t = "+"{:.2e}".format(snaps_time)+" s")
2761  current_n,current_p,mafra_out = np.loadtxt(path+currentfile,unpack=True,skiprows=3,usecols=[0,1,3])
2762 
2763  # Set the default upper value
2764  if max_X is None:
2765  max_X = np.max(mafra_out)
2766 
2767  # Set a norm
2768  norm = mpl.colors.LogNorm(vmin=min_X, vmax=max_X,clip=False)
2769 
2770  rectangles = []
2771  edgecolors = []
2772  zorders = []
2773  stable_list = []
2774  linewidths = []
2775  for i in range(len(current_n)):
2776  n_tmp = current_n[i]
2777  p_tmp = current_p[i]
2778  xy = n_tmp-0.5,p_tmp-0.5
2779  is_stable = bool(sum((stable_n==n_tmp) & (stable_p==p_tmp)))
2780 
2781  if mafra_out[i]>= min_X:
2782  color_tmp = cmap(norm(mafra_out[i]))
2783  else:
2784  color_tmp = "w"
2785 
2786  if not is_stable:
2787  edgecolors.append("gray")
2788  zorders.append(1)
2789  rect = Rectangle(xy,1,1,zorder=1,lw=nuclei_linewidths)
2790  linewidths.append(0.8)
2791  stable_list.append(False)
2792  else:
2793  edgecolors.append("k")
2794  zorders.append(2)
2795  linewidths.append(1.2)
2796  stable_list.append(True)
2797 
2798  rect = Rectangle(xy,1,1)
2799  rectangles.append(rect)
2800  stable_list=np.array(stable_list)
2801 
2802  # Sort it as the zorder is buggy in patch collections
2803  # Set the stable once as last so that they are drawn in the foreground
2804  rectangles =list(np.array(rectangles)[~stable_list])+list(np.array(rectangles)[stable_list])
2805  edgecolors=list(np.array(edgecolors)[~stable_list])+list(np.array(edgecolors)[stable_list])
2806  sorted_mafra=np.array(list(np.array(mafra_out)[~stable_list])+list(np.array(mafra_out)[stable_list]))
2807  linewidths=np.array(list(np.array(linewidths)[~stable_list])+list(np.array(linewidths)[stable_list]))
2808  # Create the collection
2809  # In principle, individual patches work as well, but with worse performance
2810  pc = PatchCollection(rectangles)
2811  # Make it white
2812  cmap.set_under("w")
2813  pc.set(array=sorted_mafra, cmap=cmap,norm=norm,edgecolors=edgecolors,linewidths=linewidths)
2814  ax.add_collection(pc)
2815 
2816  if colorbar:
2817  if not colorbar_inset:
2818  divider = make_axes_locatable(ax)
2819  cax = divider.append_axes("right", size="3%", pad=0.05)
2820  final_fig.colorbar(pc,shrink=0.5,label="Mass fraction", cax=cax)
2821  else:
2822  cax = final_fig.add_axes(colorbar_position)
2823  final_fig.colorbar(pc,shrink=0.5,label="Mass fraction", cax=cax, orientation='horizontal')
2824  cax.xaxis.set_label_position('top')
2825  cax.xaxis.set_ticks_position('top')
2826 
2827 
2828 
2829 
2830 
2831  # Plot magic numbers?
2832  if plot_magic:
2833  magicnumbers = [8,20,28,50,82,126]
2834  #set the magic numbers
2835  for i in range(len(magicnumbers)):
2836  magic = magicnumbers[i]
2837 
2838  #neutron magic
2839  min_z = 10000
2840  max_z = -1
2841  min_N = -0.5
2842  max_N = 10000
2843  for ind,p in enumerate(current_p):
2844  if current_n[ind] == magic:
2845  if current_p[ind]<min_z:
2846  min_z=float(current_p[ind])
2847  if current_p[ind]>max_z:
2848  max_z=float(current_p[ind])
2849 
2850  if current_p[ind] == magic:
2851  if current_n[ind]>min_N:
2852  min_N=float(current_n[ind])
2853  if current_n[ind]<max_N:
2854  max_N=float(current_n[ind])
2855 
2856  width = 1.3
2857  dash = (3,2)
2858  if min_z!=10000:
2859  #neutron magic
2860  ax.plot([magic-0.5, magic-0.5], [min_z-0.5, max_z+0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2861  ax.plot([magic+0.5, magic+0.5], [min_z-0.5, max_z+0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2862  if max_N!=10000:
2863  #proton magic
2864  ax.plot([max_N-0.5,min_N+0.5],[magic-0.5, magic-0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2865  ax.plot([max_N-0.5,min_N+0.5],[magic+0.5, magic+0.5], color='k',linestyle='--',lw=width, dashes=dash,zorder=100)
2866 
2867  if element_labels:
2868  font0 = FontProperties()
2869  font0.set_weight("ultralight")
2870  # font0.set_weight("light")
2871  #set the elementlabels
2872  labels = []
2873  for z in current_p:
2874  min_n = min(current_n[current_p==z])
2875 
2876  n = nucleus(N=int(min_n),Z=int(z))
2877  name = n.get_elementname()
2878  if name == 'neutron':
2879  name = 'n'
2880  elif name == 'h':
2881  name = 'p'
2882  else:
2883  name = name[0].upper()+name[1:]
2884 
2885  l = TextPath((min_n - 1.8 , z-0.25), name, size=0.9,ha="right",va='center',prop=font0)
2886  labels.append(PathPatch(l))
2887 
2888  pc = PatchCollection(labels,color='k')
2889  ax.add_collection(pc)
2890  if axes_label:
2891  ax.set_xlabel('Neutron number')
2892  ax.set_ylabel('Proton number')
2893  return final_fig
2894 
2895 
2896 
2897 
2898  def get_A_X_at_time(self,time,A_range=None):
2899  """
2900  Return the abundance at a given time.
2901  Output is:
2902  Mass number, Mass fraction, time of the nearest snapshot
2903  """
2904  plotting_time = time
2905 
2906  if len(self.__time) == 0:
2907  print('Call read_snapshots first !! The script might not work now!')
2908  return
2909 
2910  # Convert to numpy array and floats
2911  self.__time = np.array([float(x) for x in self.__time])
2912 
2913  # Get the difference for the time index
2914  diff = [abs(x - time) for x in self.__time]
2915  # Get the closest snapshot
2916  min_diff = min(diff)
2917  ind = list(diff).index(min_diff)
2918 
2919  # Get Neutrons and protons and mass number of the isotopes
2920  current_n = self.__neutrons
2921  current_p = self.__protons
2922  current_a = self.__protons + self.__neutrons
2923 
2924  mafra_out = np.array(self.__allmassfractions)[ind,:]
2925 
2926  # Add up mass fraction for equal mass numbers
2927  out_x = np.zeros(len(current_a))
2928  for i in range(len(current_a)):
2929  out_x[int(current_a[i])] += mafra_out[i]
2930 
2931  if A_range == None:
2932  # Remove zeros from behind
2933  for i in range(len(current_a)):
2934  if out_x[len(current_a)-1-i] >= 1e-20:
2935  break
2936  count = i
2937  else:
2938  count = len(current_a)-1-A_range
2939 
2940  return np.arange(len(current_a))[0:len(current_a)-1-count], out_x[0:len(current_a)-1-count], self.__time[ind] # Return A and X and the taken time
2941 
2942 
2943  def plot_A_X_time(self,figure=None,axlabel=True,**kwargs):
2944  """
2945  Plot massfractions over mass number and time in a 3D plot. This plot is ugly somehow!
2946  read_snapshots has to be called first!
2947  """
2948  # Make a figure if no figure was given
2949  if figure == None:
2950  final_fig = plt.figure()
2951  else:
2952  final_fig = figure
2953 
2954  # Get the axis instance from figure
2955  ax = final_fig.add_subplot(111, projection='3d')
2956 
2957  rang = 200
2958  A_2d = np.arange(rang)+1.
2959  X_2d = []
2960  # Collect data from every snapshot
2961  for t in self.__time:
2962  A_2d_tmp, X_2d_tmp, dummy = self.get_A_X_at_time(float(t),A_range=rang)
2963  X_2d.append(np.clip(np.log([max(x,1e-20) for x in np.array(X_2d_tmp)]), -10, 1, out=np.array(X_2d_tmp)))
2964 
2965  time = [np.log(float(x)) for x in self.__time]
2966 
2967  A_2d, time = np.meshgrid(A_2d, time)
2968 
2969  ax.plot_surface(time, A_2d, X_2d,cstride=1,shade=True)
2970  #~ ax.plot_wireframe(time, A_2d, X_2d)
2971  ax.set_ylabel('Mass number A')
2972  ax.set_xlabel('Log (Time [s])')
2973  ax.set_zlabel('Log (Mass fraction)')
2974  ax.set_zlim(-10,0)
2975  return final_fig
bin.class_files.winnet_class.winnet.plot_density
def plot_density(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:1484
bin.class_files.winnet_class.winnet.__mainout_abar
__mainout_abar
Definition: winnet_class.py:107
bin.class_files.winnet_class.winnet.get_engen
def get_engen(self)
Definition: winnet_class.py:579
bin.class_files.winnet_class.winnet.__engen
__engen
Definition: winnet_class.py:575
bin.class_files.winnet_class.winnet.get_density_at_temp
def get_density_at_temp(self, temp)
Definition: winnet_class.py:330
bin.class_files.winnet_class.winnet.__track_Y
__track_Y
Definition: winnet_class.py:113
bin.class_files.winnet_class.winnet.read_template
def read_template(self)
Definition: winnet_class.py:228
bin.class_files.winnet_class.winnet.__time
__time
Definition: winnet_class.py:62
bin.class_files.winnet_class.winnet.__timescale_tau_pn
__timescale_tau_pn
Definition: winnet_class.py:88
bin.class_files.winnet_class.winnet.__helper_title
__helper_title
Definition: winnet_class.py:2558
bin.class_files.winnet_class.winnet.__timescale_tau_gp
__timescale_tau_gp
Definition: winnet_class.py:86
bin.class_files.winnet_class.winnet.get_final_Z_A_X
def get_final_Z_A_X(self)
Definition: winnet_class.py:1145
bin.class_files.winnet_class.winnet.__timescale_tau_ag
__timescale_tau_ag
Definition: winnet_class.py:82
bin.class_files.winnet_class.winnet.__mainout_yn
__mainout_yn
Definition: winnet_class.py:101
bin.class_files.winnet_class.winnet.get_final_abar_heavy
def get_final_abar_heavy(self, min_mass)
Definition: winnet_class.py:958
bin.class_files.winnet_class.winnet.__helper_stab
__helper_stab
Definition: winnet_class.py:2594
bin.class_files.winnet_class.winnet.__read_flow
def __read_flow(self, filename)
Definition: winnet_class.py:144
bin.class_files.winnet_class.winnet.get_ylight
def get_ylight(self)
Definition: winnet_class.py:740
bin.class_files.winnet_class.winnet.__get_at_temp
def __get_at_temp(self, temp, y_array)
Definition: winnet_class.py:287
bin.class_files.winnet_class.winnet.__mainout_temp
__mainout_temp
Definition: winnet_class.py:97
bin.class_files.winnet_class.winnet.get_finab_nuclei
def get_finab_nuclei(self)
Definition: winnet_class.py:980
bin.class_files.winnet_class.winnet.plot_abar
def plot_abar(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:1514
bin.class_files.winnet_class.winnet.plot_zbar
def plot_zbar(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:1543
bin.class_files.winnet_class.winnet.plot_ye
def plot_ye(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:2201
bin.class_files.winnet_class.winnet.__param_data
__param_data
Definition: winnet_class.py:122
bin.class_files.winnet_class.winnet.plot_final_Z_X
def plot_final_Z_X(self, figure=None, axlabel=True, fig_is_ax=False, **kwargs)
Definition: winnet_class.py:1354
bin.class_files.winnet_class.winnet.__timescale_time
__timescale_time
Definition: winnet_class.py:79
bin.class_files.winnet_class.winnet.__init__
def __init__(self, runpath)
Definition: winnet_class.py:43
bin.class_files.winnet_class.winnet.get_n_to_seed
def get_n_to_seed(self, temperature)
Definition: winnet_class.py:934
bin.class_files.winnet_class.winnet.plot_engen
def plot_engen(self, figure=None, axlabel=True, fig_is_ax=False, **kwargs)
Definition: winnet_class.py:1292
bin.class_files.winnet_class.winnet.plot_A_X_time
def plot_A_X_time(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:2943
bin.class_files.winnet_class.winnet.__protons
__protons
Definition: winnet_class.py:65
bin.class_files.winnet_class.winnet.get_ye_at_temp
def get_ye_at_temp(self, temp)
Definition: winnet_class.py:312
bin.class_files.winnet_class.winnet.__finab_ab
__finab_ab
Definition: winnet_class.py:74
bin.class_files.winnet_class.winnet.get_tracked_time
def get_tracked_time(self)
Definition: winnet_class.py:610
bin.class_files.winnet_class.winnet.__mainout_ya
__mainout_ya
Definition: winnet_class.py:103
bin.class_files.winnet_class.winnet.__helper_pc
__helper_pc
Definition: winnet_class.py:2604
bin.class_files.winnet_class.winnet.get_mainout
def get_mainout(self)
Definition: winnet_class.py:691
bin.class_files.winnet_class.winnet.__timescale_tau_ng
__timescale_tau_ng
Definition: winnet_class.py:83
bin.class_files.winnet_class.winnet.__mainout_dens
__mainout_dens
Definition: winnet_class.py:98
bin.class_files.winnet_class.winnet.get_abar_at_time
def get_abar_at_time(self, t)
Definition: winnet_class.py:780
bin.class_files.winnet_class.winnet.get_ye
def get_ye(self)
Definition: winnet_class.py:720
bin.class_files.winnet_class.winnet.get_abar
def get_abar(self)
Definition: winnet_class.py:770
summarize.format
format
Definition: summarize.py:74
bin.class_files.winnet_class.winnet.plot_flow
def plot_flow(self, flownumber, plotaxis=[0, 0, 0, 0], ilabel=1, imlabel=0, imagic=0, prange=4, iplot=2)
Definition: winnet_class.py:1933
bin.class_files.winnet_class.winnet.read_mainout
def read_mainout(self, subtract_first=False)
Definition: winnet_class.py:550
bin.class_files.winnet_class.winnet
Definition: winnet_class.py:41
bin.class_files.winnet_class.winnet.__neutrons
__neutrons
Definition: winnet_class.py:64
bin.class_files.winnet_class.winnet.plot_flow_range
def plot_flow_range(self, start=1, end=0, outputpath='./', threads=5, silence=False, plotaxis=[0, 0, 0, 0], ilabel=1, imlabel=0, imagic=0, prange=4, iplot=2)
Definition: winnet_class.py:1657
bin.class_files.winnet_class.winnet.get_density
def get_density(self)
Definition: winnet_class.py:710
bin.class_files.winnet_class.winnet.plot_final_A_Y
def plot_final_A_Y(self, figure=None, axlabel=True, fig_is_ax=False, **kwargs)
Definition: winnet_class.py:1387
bin.class_files.winnet_class.winnet.__engen_keywords
__engen_keywords
Definition: winnet_class.py:574
bin.class_files.winnet_class.winnet.__track_nuclei_names
__track_nuclei_names
Definition: winnet_class.py:115
bin.class_files.winnet_class.winnet.get_mainout_yheavy
def get_mainout_yheavy(self)
Definition: winnet_class.py:642
bin.class_files.winnet_class.winnet.__finab_hydrogen
__finab_hydrogen
Definition: winnet_class.py:70
bin.class_files.winnet_class.winnet.__mainout_rad
__mainout_rad
Definition: winnet_class.py:100
bin.class_files.winnet_class.winnet.get_final_A_X
def get_final_A_X(self)
Definition: winnet_class.py:1110
bin.class_files.winnet_class.winnet.set_finab_nuclei
def set_finab_nuclei(self, nucleilist)
Definition: winnet_class.py:1268
bin.class_files.winnet_class.winnet.read_seeds
def read_seeds(self)
Definition: winnet_class.py:246
bin.class_files.winnet_class.winnet.__timescale_tau_ap
__timescale_tau_ap
Definition: winnet_class.py:461
bin.class_files.winnet_class.winnet.plot_mainout
def plot_mainout(self, figure=None, **kwargs)
Definition: winnet_class.py:2442
bin.class_files.winnet_class.winnet.get_final_Z_X
def get_final_Z_X(self)
Definition: winnet_class.py:849
bin.class_files.winnet_class.winnet.__timescale_tau_pa
__timescale_tau_pa
Definition: winnet_class.py:462
bin.class_files.winnet_class.winnet.get_p_to_seed
def get_p_to_seed(self, temperature)
Definition: winnet_class.py:942
bin.class_files.winnet_class.winnet.__finab_nuclei
__finab_nuclei
Definition: winnet_class.py:69
bin.class_files.winnet_class.winnet.get_trajectory_path
def get_trajectory_path(self)
Definition: winnet_class.py:675
bin.class_files.winnet_class.winnet.__timescale_tau_sfiss
__timescale_tau_sfiss
Definition: winnet_class.py:466
bin.class_files.winnet_class.winnet.get_entropy
def get_entropy(self)
Definition: winnet_class.py:790
inter_module::interp1d
subroutine, public interp1d(n, xp, xb, yp, res, flin, itype)
Interface for 1D interpolation routines.
Definition: inter_module.f90:100
bin.class_files.winnet_class.winnet.read_snapshots
def read_snapshots(self)
Definition: winnet_class.py:348
bin.class_files.winnet_class.winnet.get_temperature
def get_temperature(self)
Definition: winnet_class.py:700
bin.class_files.winnet_class.winnet.read_run
def read_run(self)
Definition: winnet_class.py:218
bin.class_files.winnet_class.winnet.get_mainout_time
def get_mainout_time(self)
Definition: winnet_class.py:617
bin.class_files.winnet_class.winnet.__timescale_tau_nfiss
__timescale_tau_nfiss
Definition: winnet_class.py:465
bin.class_files.winnet_class.winnet.__timescale_tau_pg
__timescale_tau_pg
Definition: winnet_class.py:85
bin.class_files.winnet_class.winnet.__mainout_entropy
__mainout_entropy
Definition: winnet_class.py:108
bin.class_files.winnet_class.winnet.get_tracer_nr
def get_tracer_nr(self)
Definition: winnet_class.py:986
bin.class_files.winnet_class.winnet.__mainout_ye
__mainout_ye
Definition: winnet_class.py:99
bin.class_files.winnet_class.winnet.plot_final_A_X
def plot_final_A_X(self, figure=None, axlabel=True, fig_is_ax=False, **kwargs)
Definition: winnet_class.py:1322
bin.class_files.winnet_class.winnet.__elname
__elname
Definition: winnet_class.py:54
bin.class_files.winnet_class.winnet.plot_sunet
def plot_sunet(self, figure=None)
Definition: winnet_class.py:2299
bin.class_files.winnet_class.winnet.__mainout_ylight
__mainout_ylight
Definition: winnet_class.py:104
bin.class_files.winnet_class.winnet.get_time_evolution
def get_time_evolution(self, nuc)
Definition: winnet_class.py:1238
bin.class_files.winnet_class.winnet.read_timescales
def read_timescales(self, subtract_first=True)
Definition: winnet_class.py:433
bin.class_files.winnet_class.winnet.get_yheavy
def get_yheavy(self)
Definition: winnet_class.py:750
bin.class_files.winnet_class.winnet.plot_radius
def plot_radius(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:1572
bin.class_files.winnet_class.winnet.get_trajectory
def get_trajectory(self)
Definition: winnet_class.py:658
bin.class_files.winnet_class.winnet.get_radius
def get_radius(self)
Definition: winnet_class.py:730
bin.class_files.winnet_class.winnet.get_final_Z_eps
def get_final_Z_eps(self)
Definition: winnet_class.py:1219
bin.class_files.winnet_class.winnet.__timescale_tau_alpha
__timescale_tau_alpha
Definition: winnet_class.py:464
bin.class_files.winnet_class.winnet.__timescale_temp
__timescale_temp
Definition: winnet_class.py:80
bin.class_files.winnet_class.winnet.get_tracked_nuclei_names
def get_tracked_nuclei_names(self)
Definition: winnet_class.py:585
bin.class_files.winnet_class.winnet.__mainout_yheavy
__mainout_yheavy
Definition: winnet_class.py:105
bin.class_files.winnet_class.winnet.get_final_A_Y
def get_final_A_Y(self)
Definition: winnet_class.py:1182
bin.class_files.winnet_class.winnet.get_seed_nuclei
def get_seed_nuclei(self)
Definition: winnet_class.py:281
bin.class_files.winnet_class.winnet.get_yn_at_temp
def get_yn_at_temp(self, temp)
Definition: winnet_class.py:339
bin.class_files.winnet_class.winnet.read_tracked_nuclei
def read_tracked_nuclei(self)
Definition: winnet_class.py:520
bin.class_files.winnet_class.winnet.get_tracked_nuclei
def get_tracked_nuclei(self, name, massfraction=True)
Definition: winnet_class.py:588
bin.class_files.winnet_class.winnet.plot_final_isotopes
def plot_final_isotopes(self, figure=None, axlabel=True, lower_limit=1e-10, isotopes=None, isotope_label=True, ignore_isotope_names=None, text_clipping=True, ytext_pos_factor=1.2, xtext_pos_offset=-0.5, ytext_pos_offset=0.0, nuc_input=None, fig_is_ax=False, color_dict=None, **kwargs)
Definition: winnet_class.py:1005
bin.class_files.winnet_class.winnet.__timescale_tau_an
__timescale_tau_an
Definition: winnet_class.py:89
bin.class_files.winnet_class.winnet.__finab_protons
__finab_protons
Definition: winnet_class.py:72
bin.class_files.winnet_class.winnet.plot_trajectory
def plot_trajectory(self, figure=None, **kwargs)
Definition: winnet_class.py:1601
bin.class_files.winnet_class.winnet.__timescale_tau_na
__timescale_tau_na
Definition: winnet_class.py:90
bin.class_files.winnet_class.winnet.__track_X
__track_X
Definition: winnet_class.py:114
bin.class_files.winnet_class.winnet.plot_entropy
def plot_entropy(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:2230
bin.class_files.winnet_class.winnet.read_engen
def read_engen(self)
Definition: winnet_class.py:563
bin.class_files.nucleus_class.nucleus
Definition: nucleus_class.py:9
bin.class_files.winnet_class.winnet.get_zbar
def get_zbar(self)
Definition: winnet_class.py:760
bin.class_files.winnet_class.winnet.get_methods
def get_methods(self)
Definition: winnet_class.py:137
bin.class_files.winnet_class.winnet.read_mainout_fix
def read_mainout_fix(self)
Definition: winnet_class.py:478
bin.class_files.winnet_class.winnet.__mainout_zbar
__mainout_zbar
Definition: winnet_class.py:106
bin.class_files.winnet_class.winnet.__hdf5_name
__hdf5_name
Definition: winnet_class.py:125
bin.class_files.winnet_class.winnet.__finab_neutrons
__finab_neutrons
Definition: winnet_class.py:73
bin.class_files.winnet_class.winnet.__path
__path
Definition: winnet_class.py:51
bin.class_files.winnet_class.winnet.__timescale_tau_beta
__timescale_tau_beta
Definition: winnet_class.py:91
bin.class_files.winnet_class.winnet.__get_x_to_seed
def __get_x_to_seed(self, temperature, x)
Definition: winnet_class.py:885
bin.class_files.winnet_class.winnet.animate_nuclear_chart
def animate_nuclear_chart(self, figure=None, plot_magic=True, time_title=True, min_X=1e-8, max_X=None, cmap=cm.viridis, element_labels=True, **kwargs)
Definition: winnet_class.py:2531
bin.class_files.winnet_class.winnet.__param_parameter
__param_parameter
Definition: winnet_class.py:121
bin.class_files.winnet_class.winnet.plot_nuclear_chart_at
def plot_nuclear_chart_at(self, time, figure=None, fig_is_ax=False, plot_magic=True, colorbar_inset=False, colorbar_position=[0.27, 0.8, 0.5, 0.025], colorbar=True, axes_label=True, time_title=True, min_X=1e-8, max_X=None, cmap=cm.viridis, element_labels=True, nuclei_linewidths=0.8, **kwargs)
Definition: winnet_class.py:2720
bin.class_files.winnet_class.winnet.get_mainout_yp
def get_mainout_yp(self)
Definition: winnet_class.py:630
bin.class_files.winnet_class.winnet.get_final_Z_Y
def get_final_Z_Y(self)
Definition: winnet_class.py:813
bin.class_files.winnet_class.winnet.__helper_line_segments
__helper_line_segments
Definition: winnet_class.py:2659
bin.class_files.winnet_class.winnet.read_finab
def read_finab(self, finab_name="finab.dat")
Definition: winnet_class.py:414
bin.class_files.winnet_class.winnet.__finab_mass
__finab_mass
Definition: winnet_class.py:71
bin.class_files.winnet_class.winnet.get_is_crashed
def get_is_crashed(self)
Definition: winnet_class.py:648
bin.class_files.winnet_class.winnet.get_man
def get_man(self)
Definition: winnet_class.py:128
bin.class_files.winnet_class.winnet.get_timescales
def get_timescales(self)
Definition: winnet_class.py:800
bin.class_files.winnet_class.winnet.__mainout_iteration
__mainout_iteration
Definition: winnet_class.py:95
bin.class_files.winnet_class.winnet.get_A_X_at_time
def get_A_X_at_time(self, time, A_range=None)
Definition: winnet_class.py:2898
bin.class_files.winnet_class.winnet.__mainout_time
__mainout_time
Definition: winnet_class.py:96
bin.class_files.winnet_class.winnet.__timescale_tau_gn
__timescale_tau_gn
Definition: winnet_class.py:84
bin.class_files.winnet_class.winnet.__timescale_tau_bfiss
__timescale_tau_bfiss
Definition: winnet_class.py:443
bin.class_files.winnet_class.winnet.plot_integrated_flow
def plot_integrated_flow(self, figure=None, fig_is_ax=False, plotaxis=[0, 0, 0, 0], ilabel=1, imlabel=0, imagic=0, prange=4, iplot=2)
Definition: winnet_class.py:1677
bin.class_files.winnet_class.winnet.__read_snapshot_time
def __read_snapshot_time(self)
Definition: winnet_class.py:391
bin.class_files.winnet_class.winnet.__seed_nuclei
__seed_nuclei
Definition: winnet_class.py:118
bin.class_files.winnet_class.winnet.__timescale_tau_np
__timescale_tau_np
Definition: winnet_class.py:87
bin.class_files.winnet_class.winnet.get_final_abar
def get_final_abar(self)
Definition: winnet_class.py:950
bin.class_files.winnet_class.winnet.plot_final_Z_Y
def plot_final_Z_Y(self, figure=None, axlabel=True, fig_is_ax=False, **kwargs)
Definition: winnet_class.py:1420
bin.class_files.winnet_class.winnet.plot_temperature
def plot_temperature(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:1454
Plot_me.cmap
cmap
Definition: Plot_me.py:23
bin.class_files.winnet_class.winnet.get_alpha_to_seed
def get_alpha_to_seed(self, temperature)
Definition: winnet_class.py:926
bin.class_files.winnet_class.winnet.__track_time
__track_time
Definition: winnet_class.py:112
tw_rate_module::sort
subroutine, private sort(cnt)
Sorts the entries in weak_rate in increasing order of the decaying nuclide.
Definition: tw_rate_module.f90:1281
bin.class_files.winnet_class.winnet.get_mainout_ya
def get_mainout_ya(self)
Definition: winnet_class.py:636
bin.class_files.winnet_class.winnet.__mainout_yp
__mainout_yp
Definition: winnet_class.py:102
bin.class_files.winnet_class.winnet.__timescale_tau_ga
__timescale_tau_ga
Definition: winnet_class.py:81
bin.class_files.winnet_class.winnet.get_mainout_yn
def get_mainout_yn(self)
Definition: winnet_class.py:624
bin.class_files.winnet_class.winnet.__allmassfractions
__allmassfractions
Definition: winnet_class.py:63
bin.class_files.winnet_class.winnet.get_entr_at_temp
def get_entr_at_temp(self, temp)
Definition: winnet_class.py:321
bin.class_files.winnet_class.winnet.plot_timescales
def plot_timescales(self, figure=None, axlabel=True, **kwargs)
Definition: winnet_class.py:2259