diff --git a/scripts/nuclei_xsections.py b/scripts/nuclei_xsections.py index 6cf70a9a393a1aa5b915a56f66fde414c8b41984..04664c2f0da1ea30c8a4d81c42d53ef2103af88e 100755 --- a/scripts/nuclei_xsections.py +++ b/scripts/nuclei_xsections.py @@ -22,7 +22,6 @@ import os import time import numpy as np import km3pipe as kp -import matplotlib.pyplot as plt from tempfile import TemporaryDirectory from os.path import dirname, abspath from collections import defaultdict @@ -73,7 +72,7 @@ def generate_neutrino_jobcard(process, flavor, energy, target): # INPUT jc.set_property("input", "numTimeSteps", 0) jc.set_property("input", "eventtype", 5) - jc.set_property("input", "numEnsembles", 100) + jc.set_property("input", "numEnsembles", 10000) jc.set_property("input", "delta_T", 0.2) jc.set_property("input", "localEnsemble", True) jc.set_property("input", "num_runs_SameEnergy", 1) @@ -94,8 +93,7 @@ def worker(energy, Z, anti_flag=False): process = "anticc" # create a neutrino jobcard for oxygen tmpjc = generate_neutrino_jobcard(process, "electron", energy, (Z, 2 * Z)) - datadir = TemporaryDirectory(dir=dirname(__file__), - prefix="%sGeV" % energy) + datadir = TemporaryDirectory(dir=dirname('.'), prefix="%sGeV" % energy) run_jobcard(tmpjc, datadir.name) data = GiBUUOutput(datadir) return data @@ -103,23 +101,49 @@ def worker(energy, Z, anti_flag=False): def plot(datafile, plotfile): import h5py - f = h5py.File(datafile, 'r') - data = f['xsec'][()] - data = data[['energy', 'Z', 'sum']] - energies = np.sort(np.unique(data['energy'])) - Zrange = np.sort(np.unique(data['Z'])) - fig, ax = plt.subplots() - h = ax.hist2d(x=data['energy'], - y=data['Z'], - bins=(energies, Zrange), - weights=np.divide(data['sum'], data['energy'])) - cb = plt.colorbar(h[3], ax=ax) - cb.ax.get_yaxis().labelpad = 15 - cb.ax.set_ylabel(r"$\nu$ Crosssection / E [$10^-38cm^{cm^2}/GeV$]") - plt.xlabel("Energy [GeV]") - plt.ylabel(r"Z") - plt.xscale('log') - plt.savefig(plotfile) + import matplotlib.pyplot as plt + from matplotlib.backends.backend_pdf import PdfPages + import matplotlib.colors as colors + with PdfPages(plotfile) as pdf: + f = h5py.File(datafile, 'r') + data = f['xsec'][()] + data = data[['energy', 'Z', 'sum']] + energies = np.sort(np.unique(data['energy'])) + Zrange = np.sort(np.unique(data['Z'])) + fig, ax = plt.subplots() + h = ax.hist2d(x=data['energy'], + y=data['Z'], + bins=(energies, Zrange), + weights=np.divide(data['sum'], data['energy'])) + cb = plt.colorbar(h[3], ax=ax) + cb.ax.get_yaxis().labelpad = 15 + cb.ax.set_ylabel(r"$\nu$ Crosssection / E [$10^-38cm^{cm^2}/GeV$]") + plt.xlabel("Energy [GeV]") + plt.ylabel(r"Z") + plt.xscale('log') + pdf.savefig() + plt.close() + data = f['particles'][()] + data = data[['energy', 'Z', 'multiplicity', 'particles']] + particle_ids = np.unique(data['particles']) + for p in particle_ids: + mask = data['particles'] == p + fig, ax = plt.subplots() + tmp = data[mask] + h = ax.hist2d(x=tmp['energy'], + y=tmp['Z'], + bins=(energies, Zrange), + weights=tmp['multiplicity'], + norm=colors.LogNorm()) + cb = plt.colorbar(h[3], ax=ax) + cb.ax.get_yaxis().labelpad = 15 + cb.ax.set_ylabel(r"Particle Count") + plt.xlabel("Energy [GeV]") + plt.ylabel(r"Z") + plt.xscale('log') + plt.title('Particle %s' % p) + pdf.savefig() + plt.close() class GiBUUTaskPump(kp.Module): @@ -135,10 +159,19 @@ class GiBUUTaskPump(kp.Module): key = list(self.tasks.keys())[0] task = self.tasks.pop(key) res = task.result() - - dct = dict(res.xsection._xsections) + xsec = res.xsection + dct = dict(zip(xsec.dtype.names, xsec.tolist())) dct.update({'energy': self.energies[key[0]], 'Z': self.Zrange[key[1]]}) blob['Xsection'] = kp.Table(dct, h5loc='xsec') + ev = res.events[:] + ids, counts = np.unique(ev['id'], return_counts=True) + dct = { + 'energy': self.energies[key[0]], + 'Z': self.Zrange[key[1]], + 'particles': ids, + 'multiplicity': counts + } + blob['Particles'] = kp.Table(dct, h5loc='particles') return blob @@ -165,7 +198,7 @@ def main(): if args['--Zmax']: Zmax = int(args['--Zmax']) - energies = np.logspace(-1, 1, 40) + energies = np.logspace(-1, 3, 100) Zrange = range(Zmin, Zmax + 1) tasks = {} with ThreadPoolExecutor(max_workers=workers) as executor: