Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • simulation/km3buu
1 result
Show changes
Commits on Source (4)
......@@ -45,6 +45,7 @@ GSEAGEN_MEDIA_COMPOSITION_FILE = "MediaComposition.xml"
class Config(object):
def __init__(self, config_path=CONFIG_PATH):
self.config = ConfigParser()
self._config_path = config_path
......
......@@ -19,6 +19,7 @@ class DetectorVolume(ABC):
"""
Detector geometry class
"""
def __init__(self):
self._volume = -1.0
self._coord_origin = (0., 0., 0.)
......@@ -82,6 +83,7 @@ class CanVolume(DetectorVolume):
zmax: float [m] (default: 476.5)
Cylinder top z position
"""
def __init__(self, radius=403.4, zmin=0.0, zmax=476.5):
super().__init__()
self._radius = radius
......@@ -118,6 +120,7 @@ class SphericalVolume(DetectorVolume):
Coordinate center of the sphere
(x, y, z)
"""
def __init__(self, radius, coord_origin=(0, 0, 0)):
super().__init__()
self._radius = radius
......
......@@ -58,6 +58,7 @@ class Jobcard(f90nml.Namelist):
input_path: str
The input path pointing to the GiBUU lookup data which should be used
"""
def __init__(self,
*args,
filename=DEFAULT_JOBCARD_FILENAME,
......
......@@ -275,6 +275,7 @@ def read_nu_abs_xsection(filepath):
class GiBUUOutput:
def __init__(self, data_dir):
"""
Class for parsing GiBUU output files
......@@ -585,6 +586,7 @@ class GiBUUOutput:
return self._generated_events
def _determine_flux_index(self):
def fluxfunc(x, a, b):
return a * x**b
......@@ -606,6 +608,7 @@ class GiBUUOutput:
def write_detector_file(gibuu_output,
ofile="gibuu.offline.root",
no_files=1,
geometry=CanVolume(),
livetime=3.156e7,
propagate_tau=True): # pragma: no cover
......@@ -618,6 +621,8 @@ def write_detector_file(gibuu_output,
Output object which wraps the information from the GiBUU output files
ofile: str
Output filename
no_files: int (default: 1)
Number of output files written
geometry: DetectorVolume
The detector geometry which should be used
livetime: float
......@@ -626,12 +631,6 @@ def write_detector_file(gibuu_output,
if not isinstance(geometry, DetectorVolume):
raise TypeError("Geometry needs to be a DetectorVolume")
evt = ROOT.Evt()
outfile = ROOT.TFile.Open(ofile, "RECREATE")
tree = ROOT.TTree("E", "KM3NeT Evt Tree")
tree.Branch("Evt", evt, 32000, 4)
mc_trk_id = 0
def add_particles(particle_data, pos_offset, rotation, start_mc_trk_id,
timestamp, status):
nonlocal evt
......@@ -676,6 +675,10 @@ def write_detector_file(gibuu_output,
sec_lep_type *= -1
event_data = gibuu_output.arrays
if no_files > len(event_data):
raise IndexError("More files to write than contained events!")
bjorkenx = event_data.Bx
bjorkeny = event_data.By
......@@ -694,6 +697,7 @@ def write_detector_file(gibuu_output,
w2 = gibuu_output.w2weights(geometry.volume, targets_per_volume, 4 * np.pi)
global_generation_weight = gibuu_output.global_generation_weight(4 * np.pi)
mean_xsec_func = gibuu_output.mean_xsec
head = ROOT.Head()
header_dct = EMPTY_KM3NET_HEADER_DICT.copy()
......@@ -712,95 +716,113 @@ def write_detector_file(gibuu_output,
version, timestamp.strftime("%Y%m%d %H%M%S"))
header_dct["primary"] = "{:d}".format(nu_type)
for k, v in header_dct.items():
head.set_line(k, v)
head.Write("Head")
mean_xsec_func = gibuu_output.mean_xsec
for mc_event_id, event in enumerate(event_data):
evt.clear()
evt.id = mc_event_id
evt.mc_run_id = mc_event_id
# Weights
evt.w.push_back(geometry.volume) #w1 (can volume)
evt.w.push_back(w2[mc_event_id]) #w2
evt.w.push_back(-1.0) #w3 (= w2*flux)
# Event Information (w2list)
evt.w2list.resize(W2LIST_LENGTH)
evt.w2list[W2LIST_LOOKUP["PS"]] = global_generation_weight
evt.w2list[W2LIST_LOOKUP["EG"]] = gibuu_output.flux_index
evt.w2list[W2LIST_LOOKUP["XSEC_MEAN"]] = mean_xsec_func(event.lepIn_E)
evt.w2list[W2LIST_LOOKUP["XSEC"]] = event.xsec
evt.w2list[W2LIST_LOOKUP["TARGETA"]] = gibuu_output.A
evt.w2list[W2LIST_LOOKUP["TARGETZ"]] = gibuu_output.Z
evt.w2list[W2LIST_LOOKUP["BX"]] = bjorkenx[mc_event_id]
evt.w2list[W2LIST_LOOKUP["BY"]] = bjorkeny[mc_event_id]
evt.w2list[W2LIST_LOOKUP["CC"]] = ichan
evt.w2list[W2LIST_LOOKUP["ICHAN"]] = SCATTERING_TYPE_TO_GENIE[
event.evType]
evt.w2list[W2LIST_LOOKUP["VERINCAN"]] = 1
evt.w2list[W2LIST_LOOKUP["LEPINCAN"]] = 1
evt.w2list[W2LIST_LOOKUP["GIBUU_WEIGHT"]] = event.weight
evt.w2list[W2LIST_LOOKUP["GIBUU_SCAT_TYPE"]] = event.evType
#TODO
evt.w2list[W2LIST_LOOKUP["DXSEC"]] = np.nan
evt.w2list[W2LIST_LOOKUP["COLUMN_DEPTH"]] = np.nan
evt.w2list[W2LIST_LOOKUP["P_EARTH"]] = np.nan
evt.w2list[W2LIST_LOOKUP["WATER_INT_LEN"]] = np.nan
# Vertex Position
vtx_pos = np.array(geometry.random_pos())
# Direction
phi = np.random.uniform(0, 2 * np.pi)
cos_theta = np.random.uniform(-1, 1)
sin_theta = np.sqrt(1 - cos_theta**2)
dir_x = np.cos(phi) * sin_theta
dir_y = np.sin(phi) * sin_theta
dir_z = cos_theta
direction = np.array([dir_x, dir_y, dir_z])
theta = np.arccos(cos_theta)
R = Rotation.from_euler("yz", [theta, phi])
timestamp = np.random.uniform(0, livetime)
nu_in_trk = ROOT.Trk()
nu_in_trk.id = mc_trk_id
mc_trk_id += 1
nu_in_trk.mother_id = -1
nu_in_trk.type = nu_type
nu_in_trk.pos.set(*vtx_pos)
nu_in_trk.dir.set(*direction)
nu_in_trk.E = event.lepIn_E
nu_in_trk.t = timestamp
nu_in_trk.status = PARTICLE_MC_STATUS["TRK_ST_PRIMARYNEUTRINO"]
evt.mc_trks.push_back(nu_in_trk)
if tau_secondaries is not None:
event_tau_sec = tau_secondaries[mc_event_id]
add_particles(event_tau_sec, vtx_pos, R, mc_trk_id, timestamp,
PARTICLE_MC_STATUS["TRK_ST_FINALSTATE"])
mc_trk_id += len(event_tau_sec.E)
else:
lep_out_trk = ROOT.Trk()
lep_out_trk.id = mc_trk_id
for i in range(no_files):
start_id = 0
stop_id = len(event_data)
tmp_filename = ofile
if no_files > 1:
tmp_filename = ofile.replace(".root", ".{}.root".format(i + 1))
bunch_size = stop_id // no_files
start_id = i * bunch_size
stop_id = (i + 1) * bunch_size if i < (no_files - 1) else stop_id
evt = ROOT.Evt()
outfile = ROOT.TFile.Open(tmp_filename, "RECREATE")
tree = ROOT.TTree("E", "KM3NeT Evt Tree")
tree.Branch("Evt", evt, 32000, 4)
mc_trk_id = 0
for k, v in header_dct.items():
head.set_line(k, v)
head.Write("Head")
for mc_event_id, event in enumerate(event_data[start_id:stop_id]):
evt.clear()
evt.id = mc_event_id
evt.mc_run_id = mc_event_id
# Weights
evt.w.push_back(geometry.volume) #w1 (can volume)
evt.w.push_back(w2[mc_event_id]) #w2
evt.w.push_back(-1.0) #w3 (= w2*flux)
# Event Information (w2list)
evt.w2list.resize(W2LIST_LENGTH)
evt.w2list[W2LIST_LOOKUP["PS"]] = global_generation_weight
evt.w2list[W2LIST_LOOKUP["EG"]] = gibuu_output.flux_index
evt.w2list[W2LIST_LOOKUP["XSEC_MEAN"]] = mean_xsec_func(
event.lepIn_E)
evt.w2list[W2LIST_LOOKUP["XSEC"]] = event.xsec
evt.w2list[W2LIST_LOOKUP["TARGETA"]] = gibuu_output.A
evt.w2list[W2LIST_LOOKUP["TARGETZ"]] = gibuu_output.Z
evt.w2list[W2LIST_LOOKUP["BX"]] = bjorkenx[mc_event_id]
evt.w2list[W2LIST_LOOKUP["BY"]] = bjorkeny[mc_event_id]
evt.w2list[W2LIST_LOOKUP["CC"]] = ichan
evt.w2list[W2LIST_LOOKUP["ICHAN"]] = SCATTERING_TYPE_TO_GENIE[
event.evType]
evt.w2list[W2LIST_LOOKUP["VERINCAN"]] = 1
evt.w2list[W2LIST_LOOKUP["LEPINCAN"]] = 1
evt.w2list[W2LIST_LOOKUP["GIBUU_WEIGHT"]] = event.weight
evt.w2list[W2LIST_LOOKUP["GIBUU_SCAT_TYPE"]] = event.evType
#TODO
evt.w2list[W2LIST_LOOKUP["DXSEC"]] = np.nan
evt.w2list[W2LIST_LOOKUP["COLUMN_DEPTH"]] = np.nan
evt.w2list[W2LIST_LOOKUP["P_EARTH"]] = np.nan
evt.w2list[W2LIST_LOOKUP["WATER_INT_LEN"]] = np.nan
# Vertex Position
vtx_pos = np.array(geometry.random_pos())
# Direction
phi = np.random.uniform(0, 2 * np.pi)
cos_theta = np.random.uniform(-1, 1)
sin_theta = np.sqrt(1 - cos_theta**2)
dir_x = np.cos(phi) * sin_theta
dir_y = np.sin(phi) * sin_theta
dir_z = cos_theta
direction = np.array([dir_x, dir_y, dir_z])
theta = np.arccos(cos_theta)
R = Rotation.from_euler("yz", [theta, phi])
timestamp = np.random.uniform(0, livetime)
nu_in_trk = ROOT.Trk()
nu_in_trk.id = mc_trk_id
mc_trk_id += 1
lep_out_trk.mother_id = 0
lep_out_trk.type = sec_lep_type
lep_out_trk.pos.set(*vtx_pos)
mom = np.array([event.lepOut_Px, event.lepOut_Py, event.lepOut_Pz])
p_dir = R.apply(mom / np.linalg.norm(mom))
lep_out_trk.dir.set(*p_dir)
lep_out_trk.E = event.lepOut_E
lep_out_trk.t = timestamp
lep_out_trk.status = PARTICLE_MC_STATUS["TRK_ST_FINALSTATE"]
evt.mc_trks.push_back(lep_out_trk)
add_particles(event, vtx_pos, R, mc_trk_id, timestamp,
PARTICLE_MC_STATUS["TRK_ST_FINALSTATE"])
tree.Fill()
outfile.Write()
outfile.Close()
del outfile
nu_in_trk.mother_id = -1
nu_in_trk.type = nu_type
nu_in_trk.pos.set(*vtx_pos)
nu_in_trk.dir.set(*direction)
nu_in_trk.E = event.lepIn_E
nu_in_trk.t = timestamp
nu_in_trk.status = PARTICLE_MC_STATUS["TRK_ST_PRIMARYNEUTRINO"]
evt.mc_trks.push_back(nu_in_trk)
if tau_secondaries is not None:
event_tau_sec = tau_secondaries[mc_event_id]
add_particles(event_tau_sec, vtx_pos, R, mc_trk_id, timestamp,
PARTICLE_MC_STATUS["TRK_ST_FINALSTATE"])
mc_trk_id += len(event_tau_sec.E)
else:
lep_out_trk = ROOT.Trk()
lep_out_trk.id = mc_trk_id
mc_trk_id += 1
lep_out_trk.mother_id = 0
lep_out_trk.type = sec_lep_type
lep_out_trk.pos.set(*vtx_pos)
mom = np.array(
[event.lepOut_Px, event.lepOut_Py, event.lepOut_Pz])
p_dir = R.apply(mom / np.linalg.norm(mom))
lep_out_trk.dir.set(*p_dir)
lep_out_trk.E = event.lepOut_E
lep_out_trk.t = timestamp
lep_out_trk.status = PARTICLE_MC_STATUS["TRK_ST_FINALSTATE"]
evt.mc_trks.push_back(lep_out_trk)
add_particles(event, vtx_pos, R, mc_trk_id, timestamp,
PARTICLE_MC_STATUS["TRK_ST_FINALSTATE"])
tree.Fill()
outfile.Write()
outfile.Close()
del outfile
del evt
del tree
......@@ -109,6 +109,7 @@ HE_PARAMS = {
def _get_particle_rest_mass(pdgid):
@np.vectorize
def vfunc(x):
try:
......
......@@ -32,6 +32,7 @@ path=/tmp/gseagen
class TestConfig(unittest.TestCase):
def setUp(self):
self.cfg_tmpfile = NamedTemporaryFile(delete=False)
self.mock_image_file = NamedTemporaryFile(delete=False)
......
......@@ -25,6 +25,7 @@ TESTDATA_DIR = data_path("gibuu")
class TestCTRLbyJobcardFile(unittest.TestCase):
def setUp(self):
self.filename = join(TESTDATA_DIR, "km3net_testdata.job")
self.output_dir = TemporaryDirectory()
......@@ -48,6 +49,7 @@ class TestCTRLbyJobcardFile(unittest.TestCase):
class TestCTRLbyJobcardObject(unittest.TestCase):
def setUp(self):
log = get_logger("ctrl.py")
log.setLevel("INFO")
......
......@@ -19,6 +19,7 @@ from km3buu import DOCKER_URL, IMAGE_NAME
class TestBuild(unittest.TestCase):
def test_wrong_dir_path(self):
wrong_path = "foobar"
try:
......
......@@ -17,12 +17,14 @@ import numpy as np
class TestGeneralGeometry(unittest.TestCase):
def test_abstract_init(self):
with self.assertRaises(TypeError) as ctx:
d = DetectorVolume()
class TestSphere(unittest.TestCase):
def setUp(self):
self.detector_geometry = SphericalVolume(20, (2, 2, 2))
......@@ -44,6 +46,7 @@ class TestSphere(unittest.TestCase):
class TestCan(unittest.TestCase):
def setUp(self):
self.detector_geometry = CanVolume()
......
......@@ -20,6 +20,7 @@ from tempfile import TemporaryFile, TemporaryDirectory
class TestJobcard(unittest.TestCase):
def setUp(self):
self.test_jobcard = Jobcard()
# Insert some test elements
......@@ -49,6 +50,7 @@ class TestJobcard(unittest.TestCase):
class TestNeutrinoEnergyRangeJobcard(unittest.TestCase):
def setUp(self):
self.test_fluxfile = TemporaryFile()
self.test_Z = np.random.randint(1, 100)
......@@ -99,6 +101,7 @@ class TestNeutrinoEnergyRangeJobcard(unittest.TestCase):
class TestNeutrinoSingleEnergyJobcard(unittest.TestCase):
def setUp(self):
self.test_fluxfile = TemporaryFile()
self.test_Z = np.random.randint(1, 100)
......@@ -133,6 +136,7 @@ class TestNeutrinoSingleEnergyJobcard(unittest.TestCase):
class TestJobcardSeed(unittest.TestCase):
def setUp(self):
jc = generate_neutrino_jobcard(100,
"CC",
......
......@@ -90,7 +90,7 @@ class TestGiBUUOutput(unittest.TestCase):
@pytest.mark.skipif(not KM3NET_LIB_AVAILABLE,
reason="KM3NeT dataformat required")
class TestAANET(unittest.TestCase):
class TestOfflineFile(unittest.TestCase):
def setUp(self):
output = GiBUUOutput(TESTDATA_DIR)
datafile = NamedTemporaryFile(suffix=".root")
......@@ -140,3 +140,91 @@ class TestAANET(unittest.TestCase):
np.testing.assert_equal(evt.w2list[10], 2)
# GiBUU weight
np.testing.assert_almost_equal(evt.w2list[23], 0.004062418521597373)
@pytest.mark.skipif(not KM3NET_LIB_AVAILABLE,
reason="KM3NeT dataformat required")
class TestMultiFileOutput(unittest.TestCase):
def setUp(self):
output = GiBUUOutput(TESTDATA_DIR)
datafile = NamedTemporaryFile(suffix=".root")
np.random.seed(1234)
write_detector_file(output, datafile.name, no_files=2)
self.fobj1 = km3io.OfflineReader(
datafile.name.replace(".root", ".1.root"))
self.fobj2 = km3io.OfflineReader(
datafile.name.replace(".root", ".2.root"))
def test_numbering(self):
np.testing.assert_array_equal(self.fobj1.events.id, range(2002))
np.testing.assert_array_equal(self.fobj2.events.id, range(2003))
def test_firstevent_first_file(self):
evt = self.fobj1.events[0]
np.testing.assert_array_equal(evt.mc_tracks.pdgid,
[12, 11, 2212, 111, 211, -211])
np.testing.assert_array_equal(evt.mc_tracks.status,
[100, 1, 1, 1, 1, 1])
np.testing.assert_array_almost_equal(evt.mc_tracks.E, [
11.90433897, 2.1818, 1.45689677, 0.49284856, 8.33975778, 0.28362369
])
np.testing.assert_array_almost_equal(evt.mc_tracks.dir_x, [
0.18255849, -0.2469, 0.48623089, 0.23767571, 0.24971059, 0.11284916
])
np.testing.assert_array_almost_equal(evt.mc_tracks.dir_y, [
-0.80816248, -0.619212, -0.49241334, -0.84679953, -0.83055629,
-0.82624071
])
np.testing.assert_array_almost_equal(evt.mc_tracks.dir_z, [
0.55995162, 0.745398, 0.72187854, 0.47585798, 0.4978161,
-0.55189796
])
# Test dataset is elec CC -> outgoing particles are placed at vertex pos
np.testing.assert_allclose(evt.mc_tracks.t, 8603022.62272017)
np.testing.assert_allclose(evt.mc_tracks.pos_x, -127.07940486)
np.testing.assert_allclose(evt.mc_tracks.pos_y, -122.54421157)
np.testing.assert_allclose(evt.mc_tracks.pos_z, 208.57726764)
usr = evt.mc_tracks.usr[0]
# XSEC
np.testing.assert_almost_equal(evt.w2list[13], 40.62418521597373)
# Bx
np.testing.assert_almost_equal(evt.w2list[7], 0.35479262672400624)
# By
np.testing.assert_almost_equal(evt.w2list[8], 0.8167222969153614)
# iChannel
np.testing.assert_equal(evt.w2list[9], 3)
# CC/NC
np.testing.assert_equal(evt.w2list[10], 2)
# GiBUU weight
np.testing.assert_almost_equal(evt.w2list[23], 0.004062418521597373)
def test_firstevent_second_file(self):
evt = self.fobj2.events[0]
np.testing.assert_array_equal(evt.mc_tracks.pdgid, [12, 11, 2212, 111])
np.testing.assert_array_equal(evt.mc_tracks.status, [100, 1, 1, 1])
np.testing.assert_array_almost_equal(
evt.mc_tracks.E, [7.043544, 3.274632, 4.429621, 0.21289])
np.testing.assert_array_almost_equal(
evt.mc_tracks.dir_x, [0.997604, 0.824817, 0.941969, 0.00302])
np.testing.assert_array_almost_equal(
evt.mc_tracks.dir_y, [-0.058292, -0.553647, 0.327013, -0.097914])
np.testing.assert_array_almost_equal(
evt.mc_tracks.dir_z, [0.037271, 0.114683, -0.075871, 0.99519])
# Test dataset is elec CC -> outgoing particles are placed at vertex pos
np.testing.assert_allclose(evt.mc_tracks.t, 1951721.26185)
np.testing.assert_allclose(evt.mc_tracks.pos_x, -171.8025)
np.testing.assert_allclose(evt.mc_tracks.pos_y, -55.656482)
np.testing.assert_allclose(evt.mc_tracks.pos_z, 363.950535)
usr = evt.mc_tracks.usr[0]
# XSEC
np.testing.assert_almost_equal(evt.w2list[13], 4.218262109165907)
# Bx
np.testing.assert_almost_equal(evt.w2list[7], 0.35479262672400624)
# By
np.testing.assert_almost_equal(evt.w2list[8], 0.8167222969153614)
# iChannel
np.testing.assert_equal(evt.w2list[9], 3)
# CC/NC
np.testing.assert_equal(evt.w2list[10], 2)
# GiBUU weight
np.testing.assert_almost_equal(evt.w2list[23], 0.00042182621091659065)
......@@ -28,6 +28,7 @@ MUON_TESTFILE = join(dirname(__file__), "data/muon_range_seawater.txt")
class TestMuonRangeSeaWater(unittest.TestCase):
def setUp(self):
self.ref_values = np.loadtxt(MUON_TESTFILE).T
......@@ -39,6 +40,7 @@ class TestMuonRangeSeaWater(unittest.TestCase):
class TestVisEnergyParticle(unittest.TestCase):
def setUp(self):
with open(PARTICLE_TESTFILE, "r") as f:
tmp = f.readline()
......@@ -57,6 +59,7 @@ class TestVisEnergyParticle(unittest.TestCase):
class TestVisEnergyWeightFunctions(unittest.TestCase):
def setUp(self):
self.ref_values = np.loadtxt(FUNCTIONS_TESTFILE).T
......
......@@ -28,6 +28,7 @@ pp.RandomGenerator.get().set_seed(1234)
@pytest.mark.skip(reason="CI boost lib problem")
class TestTauPropagation(unittest.TestCase):
def setUp(self):
data = ak.Array({
"lepOut_E": [
......