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
31 import matplotlib.pyplot
as plt
36 import scipy.interpolate
38 import multiprocessing
45 Class for analyzing Winnet runs
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')
130 Returns a string with a manual
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'
139 Returns a list of all methods of the class
141 return [method
for method
in dir(self)
if callable(getattr(self, method))]
146 Reads the flow of a given file (only one flow file)
147 Reading all files would result in a too high memory consumption.
149 Originally from Christian Winteler and Urs Frischknecht.
150 Edited by Moritz Reichert (2.4.2017)
152 INPUT: flow.dat file name including path
154 for example ff['time'] will contain the time
157 flux=fdic.ff('../m25z01/LOGS/flow.dat')
158 then flux['time'] contains the time where the fluxes were calculated
160 if os.path.isfile(filename):
162 lines = f.readlines()[:4]
166 nvars = len(lines[0].split()+lines[2].split())
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])
174 nlines = len(lines)-3
175 ncols = len(lines[2].split())
176 b= np.loadtxt(filename,skiprows=3,unpack=
True)
178 for i
in range(ncols):
179 fout[lines[2].split()[i]]= b[i]
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"][:],
205 raise Exception(
"Flow out of range ("+str(number)+
").")
208 raise Exception(
"No flows in hdf5 file.")
211 raise Exception(
"Could not open file "+str(filename))
220 Read a whole run with snapshots and so on.
230 Read the templatefile or the run (param.out)
232 path = os.listdir(self.
__path)
234 if p.endswith(
".par"):
237 path = os.path.join(self.
__path,path_param)
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
255 path = self.
__path+name_of_seed
257 if os.path.isfile(path):
259 elif os.path.isfile(name_of_seed):
265 isotopes,massfractions = np.loadtxt(path,unpack=
True,dtype=str,usecols=[0,1])
268 list_nucs = [
nucleus(name=x)
for x
in isotopes]
271 for i
in range(len(list_nucs)):
272 list_nucs[i].set_Y(float(massfractions[i])/float(list_nucs[i].get_A()))
276 print(
"Error when reading seeds!")
283 Returns the seed nuclei as a list of the instance nuclei
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.
298 for ind,t
in enumerate(mt[::-1]):
300 found_ind = len(mt)-ind-1
303 out = np.interp(temp,[mt[found_ind],mt[found_ind+1]],[my[found_ind],my[found_ind+1]])
308 print(
"Read mainout first!")
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
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
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
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
350 Reads the snapshots from @runpath@/snaps/
353 path = self.
__path+
'snaps/'
354 amount_snaps = len(os.listdir(path))
357 if amount_snaps != 0:
358 for i
in range(amount_snaps):
359 currentfile =
'snapsh_'+str((i+1)).zfill(4)+
'.dat'
363 with open(path+currentfile)
as f:
365 for line
in f.readlines():
368 self.
__time.append(float(line.split()[0]))
373 self.
__neutrons,self.
__protons,massfractions = np.loadtxt(path+currentfile,unpack=
True,skiprows=3,usecols=[0,1,3])
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"][:]
385 raise Exception(
"There are no snapshots to read!")
388 raise Exception(
"There are no snapshots to read!")
393 Read only the time from the snapshot files
395 path = self.
__path+
'snaps/'
396 amount_snaps = len(os.listdir(path))
398 for i
in range(amount_snaps):
399 currentfile =
'snapsh_'+str((i+1)).zfill(4)+
'.dat'
403 with open(path+currentfile)
as f:
405 for line
in f.readlines():
408 self.
__time.append(float(line.split()[0]))
416 Reads the file finab.dat in the run folder
428 if (nuc.get_Z() == 1
and nuc.get_N() == 0):
435 Read the timescales from a Winnet calculation
438 path = os.path.join(self.
__path,
'timescales.dat')
441 if os.path.isfile(path):
442 self.
__timescale_time, self.
__timescale_temp, self.
__timescale_tau_ga ,self.
__timescale_tau_ag, 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, \
447 elif os.path.isfile(path_hdf5):
448 f = h5py.File(path_hdf5,
"r")
449 if "/timescales" in f:
471 raise Exception(
'Timescales were not calculated in this run.')
473 raise Exception(
'Timescales were not calculated in this run.')
480 Read the mainout with numbers like 1.8-392
482 path = self.
__path +
'mainout.dat'
487 for line
in f.readlines():
494 string_split = line.split()
497 for i
in string_split:
502 split_corrected.append(c_float)
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.
524 path = self.
__path +
'tracked_nuclei.dat'
526 if (os.path.isfile(path)):
528 with open(path,
'r')
as f:
529 first_line = f.readline()
531 first_line = first_line.replace(
'Y(',
'')
532 first_line = first_line.replace(
')',
'')
533 first_line = first_line.replace(
'#',
'')
537 alldata = np.loadtxt(path,unpack=
True)
543 self.
__track_X = np.array(list(map(
lambda x,y: x*y ,self.
__track_Y,nuclei_helper_instance)))
545 print(
'No nuclei are tracked!')
552 Read the mainout from a Winnet calculation
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)
558 (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) = ([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])
565 Read the generated energy
567 path = self.
__path +
'generated_energy.dat'
569 if (os.path.isfile(path)):
570 with open(path,
'r')
as f:
571 first_line = f.readline()
572 second_line = f.readline()
577 print(
'No generated energy was calculated!')
581 Return the generated energy
590 Get the abundance of a nuclei that was tracked.
592 name - Name of the nucleus (e.g. ti44)
593 massfraction - Return mass fractions or abundances?
606 print(
'"'+name+
'" not contained in tracked nuclei.')
612 Get the time, contained in the file tracked_nuclei.dat
619 Get the time, contained in mainout.dat
626 Get the neutron abundance, contained in mainout.dat
632 Get the proton abundance, contained in mainout.dat
638 Get the alpha abundance, contained in mainout.dat
644 Get the yheavy abundance, contained in mainout.dat
652 if not os.path.exists(self.
__path+
'finab.dat'):
660 Get all data from the trajectory
662 time[s], radius[cm], dens[g/ccm], temp[GK], Ye, entr[kb/nucleon]
666 print(
'Call read_template first! Your script might not work now!')
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
677 Get all data from the trajectory
678 Output is the path to the trajectory
682 print(
'Call read_template first! Your script might not work now!')
687 traj_path = self.
__param_data[ind].replace(
'"',
'').strip()
693 Returns the data from mainout.dat
695 iteration, time, temperature, density, Ye, Radius, Yn, Yp, Y_alpha, Y_light, Y_heavy, Zbar, Abar, Entropy
697 return 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
702 Get the temperature [GK] from mainout.dat, it also returns the time
707 print(
'Call read_mainout first! Your script might not work now')
712 Get the density [g/ccm] from mainout.dat, it also returns the time
717 print(
'Call read_mainout first! Your script might not work now')
722 Get the electron fraction from mainout.dat, it also returns the time
727 print(
'Call read_mainout first! Your script might not work now')
732 Get the radius [km] from mainout.dat, it also returns the time
737 print(
'Call read_mainout first! Your script might not work now')
742 Get lighter elements (A<=4) from mainout.dat, it also returns the time
747 print(
'Call read_mainout first! Your script might not work now')
752 Get heavier elements (A>4) from mainout.dat, it also returns the time
757 print(
'Call read_mainout first! Your script might not work now')
762 Get average proton number from mainout.dat, it also returns the time
767 print(
'Call read_mainout first! Your script might not work now')
772 Get average mass number from mainout.dat, it also returns the time
777 print(
'Call read_mainout first! Your script might not work now')
782 Get average mass number from mainout.dat at time t
788 print(
'Call read_mainout first! Your script might not work now')
792 Get entropy [kB/baryon] from mainout.dat, it also returns the time
797 print(
'Call read_mainout first! Your script might not work now')
802 Returns the timescales of the run
804 Time, Temperature[GK], ng, gn, pg, gp, np, pn, an, na, beta (all [1/s])
807 print(
'Call read_timescales first !! The script might not work now!')
810 return self.
__timescale_time, self.
__timescale_temp,self.
__timescale_tau_ga , self.
__timescale_tau_ag, 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
815 Get abundances over proton number
816 Note: read_finab has to be called in advance
820 print(
'Call read_finab first !! The script might not work now!')
825 nuc.set_sortcriteria(
'Z')
837 if nuc.get_Z() == old_Z:
838 fin_Y[count] += nuc.get_Y()
840 fin_Z.append(nuc.get_Z())
841 fin_Y.append(nuc.get_Y())
846 return np.array(fin_Z),np.array(fin_Y)
851 Get mass fractions over proton number
852 Note: read_finab has to be called in advance
856 print(
'Call read_finab first !! The script might not work now!')
861 nuc.set_sortcriteria(
'Z')
873 if nuc.get_Z() == old_Z:
874 fin_X[count] += nuc.get_X()
876 fin_Z.append(nuc.get_Z())
877 fin_X.append(nuc.get_X())
887 Helper function to calculate Y(neutron) Y(proton) Y(alpha) to seed ratio without making too many repetitions
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
897 if mainout_length == 0:
898 print(
'Call read_mainout first! Returning!')
905 for temp
in reverse_temp:
907 if temp >= temperature:
911 index = mainout_length - reversed_index - 1
918 x_at_temp = x_int(temperature)
919 yheavy_at_temp = yheavy_int(temperature)
921 x_to_seed = np.log10(x_at_temp / yheavy_at_temp)
928 Get the alpha to seed ratio at given temperature [GK]
929 Note: read_mainout has get called first
936 Get the alpha to seed ratio at given temperature [GK]
937 Note: read_mainout has get called first
940 return neutron_to_seed
944 Get the alpha to seed ratio at given temperature [GK]
945 Note: read_mainout has get called first
948 return proton_to_seed
952 Get the final abar from finab.dat. Therefore one has to call read_finab first.
960 Get the final abar calculated for A>min_mass from finab.dat. Therefore one has to call read_finab first.
964 nuc.set_sortcriteria(
'A')
968 a_tmp = [x.get_A()
for x
in nuc]
969 Y_tmp = [x.get_Y()
for x
in nuc]
971 for i
in range(len(a_tmp)):
972 if a_tmp[i] > min_mass:
975 abar_heavy = sum(np.array(a_tmp[i:]) * np.array(Y_tmp[i:]) ) / sum(np.array(Y_tmp[i:]))
982 Returns a list containing the nuclei contained in finab (list of instance nucleus)
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
991 run = os.path.basename(os.path.normpath(self.
__path))
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):
1008 Plot the massfraction of the final isotopes over mass number.
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.
1025 final_fig = plt.figure()
1031 ax = final_fig.gca()
1035 if nuc_input
is None:
1038 plotted_nuclei = nuc_input
1041 for nuc
in plotted_nuclei:
1042 nuc.set_sortcriteria(
'Z')
1043 nuc = sorted(plotted_nuclei)
1046 old_Z = nuc[0].get_Z()
1050 current_Z = n.get_Z()
1051 current_A = n.get_A()
1052 current_X = n.get_X()
1055 if current_X <= lower_limit:
1059 if current_Z != old_Z:
1062 if isotopes !=
None:
1063 if old_Z
not in isotopes:
1064 A_cluster = [current_A]
1065 X_cluster = [current_X]
1069 if color_dict
is None:
1070 pl = ax.plot(A_cluster,X_cluster,marker=
'.',**kwargs)
1072 pl = ax.plot(A_cluster,X_cluster,marker=
'.',color=color_dict[int(old_Z)],**kwargs)
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()
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)
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)
1087 A_cluster = [current_A]
1088 X_cluster = [current_X]
1091 A_cluster.append(current_A)
1092 X_cluster.append(current_X)
1095 nam = n.get_elementname()
1096 nam = nam[0].upper()+nam[1:]
1103 ax.set_ylabel(
'Mass fraction X')
1104 ax.set_xlabel(
'Mass number A')
1105 ax.set_yscale(
'log')
1112 Get mass fractions over proton number
1113 Note: read_finab has to be called in advance
1117 print(
'Call read_finab first !! The script might not work now!')
1122 nuc.set_sortcriteria(
'A')
1134 if nuc.get_A() == old_A:
1135 fin_X[count] += nuc.get_X()
1137 fin_A.append(nuc.get_A())
1138 fin_X.append(nuc.get_X())
1147 Get mass fractions over proton number
1148 Note: read_finab has to be called in advance
1152 print(
'Call read_finab first !! The script might not work now!')
1157 nuc.set_sortcriteria(
'A')
1170 fin_A.append(nuc.get_A())
1171 fin_Z.append(nuc.get_Z())
1172 fin_X.append(nuc.get_X())
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
1184 Get Abundance over proton number
1185 Note: read_finab has to be called in advance
1189 print(
'Call read_finab first !! The script might not work now!')
1194 nuc.set_sortcriteria(
'A')
1206 if nuc.get_A() == old_A:
1207 fin_Y[count] += nuc.get_Y()
1209 fin_A.append(nuc.get_A())
1210 fin_Y.append(nuc.get_Y())
1221 Get abundances over proton number
1222 Note: read_finab has to be called in advance
1226 print(
'Call read_finab first !! The script might not work now!')
1229 fin_Z,fin_Y = self.get_Z_Y()
1240 Return time and mass fraction for a given nucleus.
1241 Note: read_snapshots has to be called in advance!
1244 if isinstance(nuc, str):
1256 if (current_n == n
and current_p == p):
1262 raise Exception(nuc.get_name(),
'not in list!')
1264 return self.
__time , massfraction_out
1270 Set the final abundances with a list of nuclei
1272 nucleilist - List of instance of nuclei
1280 self.
__finab_ab = [x.get_Y()
for x
in nucleilist]
1287 if (nuc.get_Z() == 1
and nuc.get_N() == 0):
1292 def plot_engen(self,figure=None,axlabel=True,fig_is_ax=False,**kwargs):
1294 Plot the final massfraction over mass number
1295 Returns a figure object
1299 final_fig = plt.figure()
1307 ax = final_fig.gca()
1309 ax.set_yscale(
'log')
1310 ax.set_xscale(
'log')
1311 ax.set_ylabel(
'Generated energy [erg/g/s]')
1317 ax.plot(time,self.
__engen[ind],label=k,lw=2,ls=
'--')
1319 ax.plot(time,self.
__engen[ind],label=k)
1324 Plot the final massfraction over mass number
1325 Returns a figure object
1329 final_fig = plt.figure()
1337 ax = final_fig.gca()
1343 ax.plot(A,X,**kwargs)
1344 ax.set_yscale(
'log')
1348 ax.set_ylabel(
'Mass fraction')
1349 ax.set_xlabel(
'Mass number')
1356 Plot the final massfraction over mass number
1357 Returns a figure object
1362 final_fig = plt.figure()
1370 ax = final_fig.gca()
1376 ax.plot(Z,X,**kwargs)
1377 ax.set_yscale(
'log')
1381 ax.set_ylabel(
'Mass fraction')
1382 ax.set_xlabel(
'Atomic number')
1389 Plot the final abundances over mass number
1390 Returns a figure object
1395 final_fig = plt.figure()
1403 ax = final_fig.gca()
1409 ax.plot(A,Y,**kwargs)
1410 ax.set_yscale(
'log')
1414 ax.set_ylabel(
'Abundance')
1415 ax.set_xlabel(
'Mass number')
1422 Plot the final abundances over mass number
1423 Returns a figure object
1428 final_fig = plt.figure()
1436 ax = final_fig.gca()
1442 ax.plot(Z,Y,**kwargs)
1443 ax.set_yscale(
'log')
1447 ax.set_ylabel(
'Abundance')
1448 ax.set_xlabel(
'Atomic number')
1456 Plot the temperature [GK]
1457 Returns a figure object
1462 final_fig = plt.figure()
1467 ax = final_fig.gca()
1473 ax.plot(time,temp,**kwargs)
1474 ax.set_yscale(
'log')
1478 ax.set_ylabel(
'Temperature [GK]')
1479 ax.set_xlabel(
'Time [s]')
1486 Plot the density [g/ccm]
1487 Returns a figure object
1492 final_fig = plt.figure()
1497 ax = final_fig.gca()
1503 ax.plot(time,dens,**kwargs)
1504 ax.set_yscale(
'log')
1508 ax.set_ylabel(
'Density [g/ccm]')
1509 ax.set_xlabel(
'Time [s]')
1516 Plot average mass number
1517 Returns a figure object
1522 final_fig = plt.figure()
1527 ax = final_fig.gca()
1533 ax.plot(time,abar,**kwargs)
1537 ax.set_ylabel(
r'<$\bar{A}$>')
1538 ax.set_xlabel(
'Time [s]')
1545 Plot average proton number
1546 Returns a figure object
1551 final_fig = plt.figure()
1556 ax = final_fig.gca()
1562 ax.plot(time,zbar,**kwargs)
1566 ax.set_ylabel(
r'<$\bar{Z}$>')
1567 ax.set_xlabel(
'Time [s]')
1575 Returns a figure object
1580 final_fig = plt.figure()
1585 ax = final_fig.gca()
1591 ax.plot(time,radius,**kwargs)
1595 ax.set_ylabel(
r'Radius [km]')
1596 ax.set_xlabel(
'Time [s]')
1603 Plot all quantities of the trajectory from trajectory file
1608 final_fig = plt.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])
1622 plt.subplots_adjust(hspace=0.5,wspace=0.5)
1627 radiusplot.plot(time,radius,**kwargs)
1628 radiusplot.set_ylabel(
'Radius [cm]')
1629 radiusplot.set_xlabel(
'Time [s]')
1631 densplot.plot(time,dens,**kwargs)
1632 densplot.set_ylabel(
'Density [g/ccm]')
1633 densplot.set_xlabel(
'Time [s]')
1635 tempplot.plot(time,temp,**kwargs)
1636 tempplot.set_ylabel(
'Temperature [GK]')
1637 tempplot.set_xlabel(
'Time [s]')
1639 yeplot.plot(time,ye,**kwargs)
1640 yeplot.set_ylabel(
'Ye')
1641 yeplot.set_xlabel(
'Time [s]')
1643 entrplot.plot(time,entr,**kwargs)
1644 entrplot.set_ylabel(
'Entropy [kB/nucleon]')
1645 entrplot.set_xlabel(
'Time [s]')
1647 dentempplot.plot(dens,temp,**kwargs)
1648 dentempplot.set_ylabel(
'Temperature [GK]')
1649 dentempplot.set_xlabel(
'Density [g/ccm]')
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):
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?
1666 if outputpath[-1] !=
'/':
1670 end = len(os.listdir(self.
__path+
'flow/'))
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))
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):
1679 Plot flows over all timesteps
1682 final_fig = plt.figure()
1690 ax = final_fig.gca()
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])]
1696 integrated_flow =
None
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)
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!' )
1710 timestep = ff_next[
'time']-ff[
'time']
1713 if integrated_flow
is None:
1714 integrated_flow = flow
1716 integrated_flow+=flow*timestep
1718 integrated_flow = np.log10(integrated_flow+1e-99)
1719 flow = integrated_flow
1720 sort = flow.argsort()
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]
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)):
1735 nzycheck[ni,zi,0] = 1
1736 nzycheck[ni,zi,1] = yin[i]
1737 if iplot==1
or iplot==2:
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
1749 if plotaxis==[0,0,0,0]:
1753 dx = plotaxis[1]-plotaxis[0]
1754 dy = plotaxis[3]-plotaxis[2]
1766 cmapa.set_under(color=
'w')
1767 cmapr.set_under(color=
'w')
1769 norma = colors.Normalize(vmin=-10,vmax=-3)
1771 a2c = cm.ScalarMappable(norm=norma,cmap=cmapa)
1773 a2c.set_array(np.array(a))
1775 ax.set_aspect(
'equal')
1777 temp =
'%8.3e' %ff[
'temp']
1778 time =
'%8.3e' %ff[
'time']
1779 dens =
'%8.3e' %ff[
'dens']
1783 if iplot==0
or iplot==2:
1787 for i
in range(nzmax):
1788 for j
in range(nnmax):
1789 if nzycheck[j,i,0]==1:
1791 yab = nzycheck[j,i,1]
1792 col = a2c.to_rgba(np.log10(yab))
1794 rect = Rectangle(xy,1,1,ec=
'k',color=col,picker=
True)
1798 cb=plt.colorbar(a2c)
1801 cb.set_label(
'log$_{10}$(Y)')
1804 f = open(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))+
'/data/stableiso.dat')
1809 for line
in f.readlines():
1814 circ = Circle(xy,radius=0.1,fc=
'k')
1818 if iplot==1
or iplot==2:
1822 vmax=np.ceil(max(flow))
1823 vmin=max(flow)-prange
1825 normr = colors.Normalize(vmin=vmin,vmax=vmax)
1829 for i
in range(len(nin)):
1836 arrowwidth = flow[i]*m+b
1837 arrow = Arrow(x,y,dx,dy, width=arrowwidth)
1843 apatches.append(arrow)
1848 rect = Rectangle(xy,1,1,ec=
'k',fc=
'None',fill=
'False',lw=1.)
1851 xy = x+dx-0.5,y+dy-0.5
1852 rect = Rectangle(xy,1,1,ec=
'k',fc=
'None',fill=
'False',lw=1.)
1857 a = PatchCollection(apatches, cmap=cmapr, norm=normr)
1858 a.set_array(np.array(acolor))
1860 ax.add_collection(a)
1861 cb = plt.colorbar(a)
1864 cb.set_label(
'log$_{10}$(f)')
1872 for z
in range(nzmax):
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)
1881 for z
in range(nzmax):
1882 for n
in range(nnmax):
1884 if nzycheck[n,z,iarr]==1:
1885 ax.text(n,z,a,horizontalalignment=
'center',verticalalignment=
'center',fontsize=
'small',clip_on=
True)
1889 ixymagic=[2, 8, 20, 28, 50, 82, 126]
1890 nmagic = len(ixymagic)
1891 for magic
in ixymagic:
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=
'--')
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=
'--')
1908 if plotaxis==[0,0,0,0]:
1909 if iplot==2
or iplot==0:
1912 ax.axis([-0.5,xmax+0.5,-0.5,ymax+0.5])
1914 ax.axis([plotaxis[0]-0.5,plotaxis[1]+0.5,plotaxis[2]-0.5,plotaxis[3]+0.5])
1917 ax.set_xlabel(
'neutron number')
1918 ax.set_ylabel(
'proton number')
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]
1929 print( self.
__elname[pz] + str(pn+pz) +
' , Y = ' + pab +
' X = ' + pmf )
1933 def plot_flow(self,flownumber,plotaxis=[0,0,0,0],ilabel=1,imlabel=0,imagic=0,prange=4,iplot=2):
1935 Plot a flow with a given flownumber.
1937 Originally from Christian Winteler and Urs Frischknecht
1938 Edited by Moritz Reichert (2.4.2017)
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]
1949 inputfile = self.
__path+
'flow/flow_{n:04d}.dat'.
format(n=flownumber)
1953 flow = np.log10(ff[
'flow']+1.e-99)
1954 sort = flow.argsort()
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]
1963 nzmax = int(max(max(zin),max(zout)))+1
1964 nnmax = int(max(max(nin),max(nout)))+1
1966 if iplot==1
or iplot==2:
1967 sys.exit(
'The read file does not contain flow data')
1971 nnmax = int(max(nin))+1
1972 nzmax = int(max(zin))+1
1974 nzycheck = np.zeros([nnmax,nzmax,3])
1975 for i
in range(len(nin)):
1978 nzycheck[ni,zi,0] = 1
1979 nzycheck[ni,zi,1] = yin[i]
1980 if iplot==1
or iplot==2:
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
1992 if plotaxis==[0,0,0,0]:
1996 dx = plotaxis[1]-plotaxis[0]
1997 dy = plotaxis[3]-plotaxis[2]
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)
2014 ax=plt.axes([axx,axy,axw,axh])
2021 cmapa.set_under(color=
'w')
2022 cmapr.set_under(color=
'w')
2024 norma = colors.Normalize(vmin=-10,vmax=-3)
2026 a2c = cm.ScalarMappable(norm=norma,cmap=cmapa)
2028 a2c.set_array(np.array(a))
2030 ax.set_aspect(
'equal')
2032 temp =
'%8.3e' %ff[
'temp']
2033 time =
'%8.3e' %ff[
'time']
2034 dens =
'%8.3e' %ff[
'dens']
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,
2041 bbox_to_anchor=(0., 1.02),
2042 bbox_transform=ax.transAxes,
2045 ax.add_artist(anchored_box)
2048 if iplot==0
or iplot==2:
2052 for i
in range(nzmax):
2053 for j
in range(nnmax):
2054 if nzycheck[j,i,0]==1:
2056 yab = nzycheck[j,i,1]
2057 col = a2c.to_rgba(np.log10(yab))
2059 rect = Rectangle(xy,1,1,ec=
'k',color=col,picker=
True)
2063 cb=plt.colorbar(a2c)
2066 cb.set_label(
'log$_{10}$(Y)')
2069 f = open(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))+
'/data/stableiso.dat')
2074 for line
in f.readlines():
2079 circ = Circle(xy,radius=0.1,fc=
'k')
2083 if iplot==1
or iplot==2:
2087 vmax=np.ceil(max(flow))
2088 vmin=max(flow)-prange
2090 normr = colors.Normalize(vmin=vmin,vmax=vmax)
2094 for i
in range(len(nin)):
2101 arrowwidth = flow[i]*m+b
2102 arrow = Arrow(x,y,dx,dy, width=arrowwidth)
2108 apatches.append(arrow)
2113 rect = Rectangle(xy,1,1,ec=
'k',fc=
'None',fill=
'False',lw=1.)
2116 xy = x+dx-0.5,y+dy-0.5
2117 rect = Rectangle(xy,1,1,ec=
'k',fc=
'None',fill=
'False',lw=1.)
2122 a = PatchCollection(apatches, cmap=cmapr, norm=normr)
2123 a.set_array(np.array(acolor))
2125 ax.add_collection(a)
2126 cb = plt.colorbar(a)
2129 cb.set_label(
'log$_{10}$(f)')
2137 for z
in range(nzmax):
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)
2146 for z
in range(nzmax):
2147 for n
in range(nnmax):
2149 if nzycheck[n,z,iarr]==1:
2150 ax.text(n,z,a,horizontalalignment=
'center',verticalalignment=
'center',fontsize=
'small',clip_on=
True)
2154 ixymagic=[2, 8, 20, 28, 50, 82, 126]
2155 nmagic = len(ixymagic)
2156 for magic
in ixymagic:
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=
'--')
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=
'--')
2173 if plotaxis==[0,0,0,0]:
2174 if iplot==2
or iplot==0:
2177 ax.axis([-0.5,xmax+0.5,-0.5,ymax+0.5])
2179 ax.axis([plotaxis[0]-0.5,plotaxis[1]+0.5,plotaxis[2]-0.5,plotaxis[3]+0.5])
2182 ax.set_xlabel(
'neutron number')
2183 ax.set_ylabel(
'proton number')
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]
2194 print( self.
__elname[pz] + str(pn+pz) +
' , Y = ' + pab +
' X = ' + pmf )
2196 fig.canvas.mpl_connect(
'pick_event', onpick1)
2201 def plot_ye(self,figure=None,axlabel=True,**kwargs):
2203 Plot average proton number
2204 Returns a figure object
2209 final_fig = plt.figure()
2214 ax = final_fig.gca()
2220 ax.plot(time,ye,**kwargs)
2224 ax.set_ylabel(
r'Y$_e$')
2225 ax.set_xlabel(
'Time [s]')
2232 Plot the entropy [kb/nucleon]
2233 Returns a figure object
2238 final_fig = plt.figure()
2243 ax = final_fig.gca()
2249 ax.plot(time,entr,**kwargs)
2253 ax.set_ylabel(
r'Entropy [kB/nucleon]')
2254 ax.set_xlabel(
'Time [s]')
2261 Plot the timescales for a Winnet run (ng, gn, pg, gp, np, pn, an, na, beta (all [1/s]))
2266 final_fig = plt.figure()
2271 ax = final_fig.gca()
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"]
2282 ax.set_yscale(
'log')
2283 ax.set_xscale(
'log')
2284 for i
in range(len(labels)):
2286 col = colors[int(i/2)]
2287 ax.plot(time,timescales[i],ls=
'-',label=labels[i],color=col,**kwargs)
2289 ax.plot(time,timescales[i],ls=
'--',label=labels[i],color=col,**kwargs)
2293 ax.set_ylabel(
r'Timescale [s]')
2294 ax.set_xlabel(
'Time [s]')
2301 Plot the contained nuclei of the run. The information is extracted from param.out
2304 print(
'Call read_template first! Your script might not work now!')
2308 filewithnuclei = self.
__param_data[ind].replace(
'"',
'').strip()
2310 stableisotopes = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))+
'/data/stableiso.dat'
2313 stable_n,stable_z = np.loadtxt(stableisotopes,unpack =
True, usecols=(1,2))
2316 nucleilist = np.loadtxt(filewithnuclei,unpack =
True,dtype=str)
2323 for nuc
in nucleilist:
2324 nucleiclass.append(
nucleus(nuc))
2325 if max_p <
nucleus(nuc).get_Z():
2327 if max_n <
nucleus(nuc).get_N():
2330 amountneutrons = max_n + 1
2331 amountprotons = max_p + 1
2335 fig = plt.figure(figsize=(amountneutrons/10.,amountprotons/10.))
2343 magicnumbers = [8,20,28,50,82,126]
2345 for nuc
in nucleiclass:
2351 for i
in range(len(stable_z)):
2352 if (stable_z[i] == nuc.get_Z())
and (stable_n[i] == nuc.get_N()):
2360 rectcolor =
'#d4e5ff'
2363 rect = Rectangle(xy,1,1,ec=
'gray',zorder=1,lw=0.5,color=rectcolor)
2365 rect = Rectangle(xy,1,1,ec=
'k',zorder=2,lw=1,color=rectcolor)
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)
2375 for z
in range(amountprotons):
2377 min_n = amountneutrons
2379 for nuc
in nucleiclass:
2380 if (z == nuc.get_Z()
and min_n > nuc.get_N()):
2382 name = nuc.get_elementname()
2383 if name ==
'neutron':
2389 ax.text(min_n - 1 - 0.4*len(name), z-0.5, name, fontsize = 5)
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)
2394 ax.text(min_n - 1 - 0.5*len(name), z-0.2, name, fontsize = 5)
2396 ax.text(min_n - 1 - 0.4*len(name), z-0.2, name, fontsize = 5)
2399 for i
in range(len(magicnumbers)):
2400 magic = magicnumbers[i]
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())
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())
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)
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)
2430 ax.get_xaxis().set_visible(
False)
2431 ax.get_yaxis().set_visible(
False)
2433 for axis
in [
'left',
'right',
'top',
'bottom']:
2434 ax.spines[axis].set_linewidth(0)
2436 ax.set_xlim(-1,amountneutrons)
2437 ax.set_ylim(-1,amountprotons)
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
2449 final_fig = plt.figure(figsize=(15,15))
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)
2468 plt.subplots_adjust(hspace=0.5,wspace=0.5)
2471 it,time,temp,dens,ye,rad,yn,yp,ya,ylight,yheavy,zbar,abar,entr = self.
get_mainout()
2473 tempplot.plot(time,temp)
2474 tempplot.set_ylabel(
'Temperature [GK]')
2475 tempplot.set_xlabel(
'Time [s]')
2476 tempplot.set_xscale(
'log')
2478 densplot.plot(time,dens)
2479 densplot.set_yscale(
'log')
2480 densplot.set_ylabel(
'Density [g/ccm]')
2481 densplot.set_xlabel(
'Time [s]')
2483 yeplot.plot(time,ye)
2484 yeplot.set_ylabel(
'Ye')
2485 yeplot.set_xlabel(
'Time [s]')
2487 radiusplot.plot(time,rad)
2488 radiusplot.set_yscale(
'log')
2489 radiusplot.set_ylabel(
'Radius [km]')
2490 radiusplot.set_xlabel(
'Time [s]')
2492 ynplot.plot(time,yn)
2493 ynplot.set_ylabel(
'Yn')
2494 ynplot.set_xlabel(
'Time [s]')
2495 ynplot.set_yscale(
'log')
2497 ypplot.plot(time,yp)
2498 ypplot.set_ylabel(
'Yp')
2499 ypplot.set_xlabel(
'Time [s]')
2500 ypplot.set_yscale(
'log')
2502 yaplot.plot(time,ya)
2503 yaplot.set_ylabel(
'Yalpha')
2504 yaplot.set_xlabel(
'Time [s]')
2505 yaplot.set_yscale(
'log')
2507 ylightplot.plot(time,ylight)
2508 ylightplot.set_ylabel(
'Ylight')
2509 ylightplot.set_xlabel(
'Time [s]')
2510 ylightplot.set_yscale(
'log')
2512 yheavyplot.plot(time,yheavy)
2513 yheavyplot.set_ylabel(
'Yheavy')
2514 yheavyplot.set_xlabel(
'Time [s]')
2515 ylightplot.set_yscale(
'log')
2517 zbarplot.plot(time,zbar)
2518 zbarplot.set_ylabel(
'Zbar')
2519 zbarplot.set_xlabel(
'Time [s]')
2521 abarplot.plot(time,abar)
2522 abarplot.set_ylabel(
'Abar')
2523 abarplot.set_xlabel(
'Time [s]')
2525 entrplot.plot(time,entr)
2526 entrplot.set_ylabel(
'Entropy [kB/nucleon]')
2527 entrplot.set_xlabel(
'Time [s]')
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):
2533 Make an animation of the mass fractions in the nuclear chart
2537 final_fig = plt.figure(figsize=(10,5))
2541 ax = final_fig.gca()
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])
2553 norm = mpl.colors.LogNorm(vmin=min_X, vmax=max_X,clip=
False)
2557 snaps_time = self.
__time[0]
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)))
2573 if mafra_out[i]>= min_X:
2574 color_tmp =
cmap(norm(mafra_out[i]))
2579 edgecolors.append(
"gray")
2581 rect = Rectangle(xy,1,1,zorder=1,lw=0.8)
2582 linewidths.append(0.8)
2583 stable_list.append(
False)
2585 edgecolors.append(
"k")
2587 linewidths.append(1.2)
2588 stable_list.append(
True)
2590 rect = Rectangle(xy,1,1)
2591 rectangles.append(rect)
2592 stable_list=np.array(stable_list)
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]))
2603 pc = PatchCollection(rectangles)
2607 pc.set(array=sorted_mafra, cmap=cmap,norm=norm,edgecolors=edgecolors,linewidths=linewidths,zorder=-30)
2608 ax.add_collection(pc)
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)
2616 magicnumbers = [8,20,28,50,82,126]
2619 for i
in range(len(magicnumbers)):
2620 magic = magicnumbers[i]
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])
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])
2645 l = [(magic-0.5, min_z-0.5),( magic-0.5,max_z+0.5)]
2648 l = [(magic+0.5, min_z-0.5), (magic+0.5, max_z+0.5)]
2653 l = [(max_N-0.5,magic-0.5),(min_N+0.5, magic-0.5)]
2656 l = [(max_N-0.5,magic+0.5),(min_N+0.5, magic+0.5)]
2669 min_n = min(current_n[current_p==z])
2671 n =
nucleus(N=int(min_n),Z=int(z))
2672 name = n.get_elementname()
2673 if name ==
'neutron':
2678 name = name[0].upper()+name[1:]
2680 l = TextPath((min_n - 1.8 , z-0.25), name, size=0.9,ha=
"right",va=
'center')
2681 labels.append(PathPatch(l))
2683 pc = PatchCollection(labels,color=
'k')
2684 ax.add_collection(pc)
2686 ax.set_xlabel(
'Neutron number')
2687 ax.set_ylabel(
'Proton number')
2689 if plot_magic
and time_title:
2691 if plot_magic
and (
not time_title):
2698 snaps_time = self.
__time[ind]
2705 if plot_magic
and time_title:
2707 if plot_magic
and (
not time_title):
2712 anim = animation.FuncAnimation(final_fig, __animate, init_func=__init_anim,
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):
2725 Plot the abundances into the nuclear chart at a given time
2729 final_fig = plt.figure(figsize=(10,5))
2735 ax = final_fig.gca()
2738 final_fig = plt.gcf()
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])
2753 ind = np.argmin(np.abs(self.
__time - time))
2756 currentfile =
'snapsh_'+str((ind+1)).zfill(4)+
'.dat'
2757 path = self.
__path+
'snaps/'
2758 snaps_time = self.
__time[ind]
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])
2765 max_X = np.max(mafra_out)
2768 norm = mpl.colors.LogNorm(vmin=min_X, vmax=max_X,clip=
False)
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)))
2781 if mafra_out[i]>= min_X:
2782 color_tmp =
cmap(norm(mafra_out[i]))
2787 edgecolors.append(
"gray")
2789 rect = Rectangle(xy,1,1,zorder=1,lw=nuclei_linewidths)
2790 linewidths.append(0.8)
2791 stable_list.append(
False)
2793 edgecolors.append(
"k")
2795 linewidths.append(1.2)
2796 stable_list.append(
True)
2798 rect = Rectangle(xy,1,1)
2799 rectangles.append(rect)
2800 stable_list=np.array(stable_list)
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]))
2810 pc = PatchCollection(rectangles)
2813 pc.set(array=sorted_mafra, cmap=cmap,norm=norm,edgecolors=edgecolors,linewidths=linewidths)
2814 ax.add_collection(pc)
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)
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')
2833 magicnumbers = [8,20,28,50,82,126]
2835 for i
in range(len(magicnumbers)):
2836 magic = magicnumbers[i]
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])
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])
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)
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)
2868 font0 = FontProperties()
2869 font0.set_weight(
"ultralight")
2874 min_n = min(current_n[current_p==z])
2876 n =
nucleus(N=int(min_n),Z=int(z))
2877 name = n.get_elementname()
2878 if name ==
'neutron':
2883 name = name[0].upper()+name[1:]
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))
2888 pc = PatchCollection(labels,color=
'k')
2889 ax.add_collection(pc)
2891 ax.set_xlabel(
'Neutron number')
2892 ax.set_ylabel(
'Proton number')
2900 Return the abundance at a given time.
2902 Mass number, Mass fraction, time of the nearest snapshot
2904 plotting_time = time
2906 if len(self.
__time) == 0:
2907 print(
'Call read_snapshots first !! The script might not work now!')
2911 self.
__time = np.array([float(x)
for x
in self.
__time])
2914 diff = [abs(x - time)
for x
in self.
__time]
2916 min_diff = min(diff)
2917 ind = list(diff).index(min_diff)
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]
2933 for i
in range(len(current_a)):
2934 if out_x[len(current_a)-1-i] >= 1e-20:
2938 count = len(current_a)-1-A_range
2940 return np.arange(len(current_a))[0:len(current_a)-1-count], out_x[0:len(current_a)-1-count], self.
__time[ind]
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!
2950 final_fig = plt.figure()
2955 ax = final_fig.add_subplot(111, projection=
'3d')
2958 A_2d = np.arange(rang)+1.
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)))
2965 time = [np.log(float(x))
for x
in self.
__time]
2967 A_2d, time = np.meshgrid(A_2d, time)
2969 ax.plot_surface(time, A_2d, X_2d,cstride=1,shade=
True)
2971 ax.set_ylabel(
'Mass number A')
2972 ax.set_xlabel(
'Log (Time [s])')
2973 ax.set_zlabel(
'Log (Mass fraction)')