File indexing completed on 2026-10-27 08:41:18
0001
0002
0003 import math
0004 import os
0005
0006 import uproot
0007
0008 from pyrobird.dex import validate_dex
0009 from pyrobird.edm4eic import edm4eic_to_dex_dict
0010 from pyrobird.edm4hep import edm4hep_to_dex_dict
0011 from pyrobird.mc_particles import (
0012 interpolate_line_points,
0013 mc_particles_to_trajectories,
0014 C_LIGHT,
0015 DEFAULT_MC_MAX_POINTS,
0016 )
0017
0018 TEST_EDM4HEP_FILE = os.path.join(os.path.dirname(__file__), 'data', 'k_lambda_10x100_2evt.edm4hep.root')
0019 TEST_EDM4EIC_FILE = os.path.join(os.path.dirname(__file__), 'data', 'reco_2024-09_craterlake_2evt.edm4eic.root')
0020
0021
0022 def open_events_tree(path):
0023 return uproot.open(path)['events']
0024
0025
0026 def test_interpolate_line_points_grid():
0027
0028 points = interpolate_line_points(0, 0, 0, 3 * C_LIGHT, 0, 0,
0029 start_time=10.0, beta=1.0, step_time=1.0)
0030 assert len(points) == 4
0031 assert points[0] == [0, 0, 0, 10.0]
0032 assert points[-1][0] == 3 * C_LIGHT
0033 assert math.isclose(points[-1][3], 13.0)
0034
0035 assert math.isclose(points[1][3], 11.0)
0036 assert math.isclose(points[2][3], 12.0)
0037 assert math.isclose(points[1][0], C_LIGHT)
0038
0039
0040 def test_interpolate_line_points_max_points_cap():
0041
0042
0043 points = interpolate_line_points(0, 0, 0, 100000, 0, 0,
0044 start_time=0.0, beta=1.0, step_time=0.001, max_points=16)
0045 assert len(points) == 16
0046 assert points[-1][0] == 100000
0047 steps = [points[i + 1][3] - points[i][3] for i in range(len(points) - 1)]
0048 assert all(math.isclose(step, steps[0]) for step in steps)
0049
0050
0051 def test_interpolate_line_points_at_rest():
0052
0053 points = interpolate_line_points(1, 2, 3, 1, 2, 3, start_time=5.0, beta=0.0)
0054 assert points == [[1, 2, 3, 5.0], [1, 2, 3, 5.0]]
0055
0056
0057 def test_mc_particles_to_trajectories_edm4hep():
0058 tree = open_events_tree(TEST_EDM4HEP_FILE)
0059 piece = mc_particles_to_trajectories(tree, 0)
0060
0061 assert piece['name'] == 'MCParticles'
0062 assert piece['type'] == 'PointTrajectory'
0063 assert piece['pointColumns'] == ['x', 'y', 'z', 't']
0064
0065
0066 mc_count = len(tree['MCParticles/MCParticles.PDG'].array(entry_start=0, entry_stop=1)[0])
0067 assert piece['count'] == mc_count
0068 assert len(piece['points']) == mc_count
0069 for column in ('pdg', 'charge', 'gen_status', 'px', 'py', 'pz', 'p', 'mass'):
0070 assert len(piece['columns'][column]) == mc_count
0071
0072 for points in piece['points']:
0073 assert 2 <= len(points) <= DEFAULT_MC_MAX_POINTS
0074 times = [point[3] for point in points]
0075 assert times == sorted(times)
0076
0077
0078 def test_mc_particles_to_trajectories_edm4eic():
0079
0080 tree = open_events_tree(TEST_EDM4EIC_FILE)
0081 piece = mc_particles_to_trajectories(tree, 0)
0082 assert piece['count'] > 0
0083 assert piece['count'] == len(piece['points'])
0084
0085
0086 def test_mc_particles_in_default_conversions():
0087
0088
0089 hep_dex = edm4hep_to_dex_dict(open_events_tree(TEST_EDM4HEP_FILE), 0)
0090 validate_dex(hep_dex)
0091 assert any(p['name'] == 'MCParticles' for p in hep_dex['events'][0]['pieces'])
0092
0093 eic_dex = edm4eic_to_dex_dict(open_events_tree(TEST_EDM4EIC_FILE), 0)
0094 validate_dex(eic_dex)
0095 assert any(p['name'] == 'MCParticles' for p in eic_dex['events'][0]['pieces'])
0096
0097
0098 def test_mc_particles_collections_filter():
0099
0100 dex = edm4hep_to_dex_dict(open_events_tree(TEST_EDM4HEP_FILE), 0, collections=['mc_particles'])
0101 pieces = dex['events'][0]['pieces']
0102 assert len(pieces) == 1
0103 assert pieces[0]['name'] == 'MCParticles'
0104
0105
0106 dex = edm4eic_to_dex_dict(open_events_tree(TEST_EDM4EIC_FILE), 0, collections=['tracker_hits'])
0107 assert not any(p['name'] == 'MCParticles' for p in dex['events'][0]['pieces'])