Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify detsim to read nexus files with int instead of strings #870

Merged
merged 9 commits into from
May 13, 2024
9 changes: 8 additions & 1 deletion invisible_cities/cities/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from .. io .pmaps_io import pmap_writer
from .. io .rwf_io import buffer_writer
from .. io .mcinfo_io import load_mchits_df
from .. io .mcinfo_io import load_mcstringmap
from .. io .dst_io import df_writer
from .. types .ic_types import NoneType
from .. types .ic_types import xy
Expand Down Expand Up @@ -615,6 +616,10 @@ def MC_hits_from_files(files_in : List[str], rate: float) -> Generator:
hits_df = load_mchits_df(filename)
except tb.exceptions.NoSuchNodeError:
continue

l_type = hits_df.dtypes['label']
map_df = load_mcstringmap(filename) if l_type == np.int32 else None

for evt, hits in hits_df.groupby(level=0):
yield dict(event_number = evt,
x = hits.x .values,
Expand All @@ -623,7 +628,9 @@ def MC_hits_from_files(files_in : List[str], rate: float) -> Generator:
energy = hits.energy.values,
time = hits.time .values,
label = hits.label .values,
timestamp = timestamp(evt))
timestamp = timestamp(evt),
name = map_df.name .values if map_df is not None else "",
name_id = map_df.index.values if map_df is not None else 0)


@check_annotations
Expand Down
19 changes: 14 additions & 5 deletions invisible_cities/cities/detsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,19 @@ def hits_selector(active_only: bool=True):
:select_hits: Callable
function that select the hits depending on :active_only: parameter
"""
def select_hits(x, y, z, energy, time, label):
sel = (label == "ACTIVE")
def select_hits(x, y, z, energy, time, label, name, name_id):

if label.dtype == np.int32:
active = name_id[name == "ACTIVE"][0]
buff = name_id[name == "BUFFER"][0]
else:
active = 'ACTIVE'
buff = 'BUFFER'

sel = (label == active)
if not active_only:
sel = sel | (label == "BUFFER")
sel = sel | (label == buff)

return x[sel], y[sel], z[sel], energy[sel], time[sel], label[sel]
return select_hits

Expand Down Expand Up @@ -178,10 +187,10 @@ def detsim( *
out = ('x', 'y', 'z', 'energy', 'time', 'label'))

select_s1_candidate_hits = fl.map(hits_selector(False),
item = ('x', 'y', 'z', 'energy', 'time', 'label'))
item = ('x', 'y', 'z', 'energy', 'time', 'label', 'name', 'name_id'))

select_active_hits = fl.map(hits_selector(True),
args = ('x', 'y', 'z', 'energy', 'time', 'label'),
args = ('x', 'y', 'z', 'energy', 'time', 'label', 'name', 'name_id'),
out = ('x_a', 'y_a', 'z_a', 'energy_a', 'time_a', 'labels_a'))

filter_events_no_active_hits = fl.map(lambda x:np.any(x),
Expand Down
14 changes: 14 additions & 0 deletions invisible_cities/cities/detsim_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,17 @@ def test_detsim_buffer_times(ICDATADIR, output_tmpdir):

assert tstart == np.floor(s2_tmin / buffer_params["sipm_width"]) * buffer_params["sipm_width"]
assert tend == np.floor(s2_tmax / buffer_params["sipm_width"]) * buffer_params["sipm_width"]


def test_detsim_hits_without_strings(ICDATADIR, output_tmpdir):
PATH_IN = os.path.join(ICDATADIR , "nexus_next100_nostrings.h5")
PATH_OUT = os.path.join(output_tmpdir, "detsim_nostrings.h5")
conf = configure('detsim $ICTDIR/invisible_cities/config/detsim_next100.conf'.split())
conf.update(dict(files_in = PATH_IN,
file_out = PATH_OUT,
run_number = 0))
result = detsim(**conf)
assert result.evtnum_list == [0, 1]

df = pd.read_hdf(PATH_OUT, 'MC/string_map')
assert not df.empty
38 changes: 38 additions & 0 deletions invisible_cities/config/detsim_next100.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
files_in = "$ICDIR/database/test_data/nexus_next100_nostrings.h5"
file_out = "/tmp/detsim_out.h5"

event_range = all

detector_db = "next100"
run_number = 0

s1_lighttable = "$ICDIR/database/test_data/NEXT100_S1_LT.h5"
s2_lighttable = "$ICDIR/database/test_data/NEXT100_S2_LT.h5"
sipm_psf = "$ICDIR/database/test_data/NEXT100_PSF.h5"

physics_params = dict(ws = 39.2 * eV,
wi = 22.4 * eV,
fano_factor = 0.15,
conde_policarpo_factor = 1.00,
drift_velocity = 1.00 * mm / mus,
lifetime = 12 * ms,
transverse_diffusion = 1.20 * mm / cm**0.5,
longitudinal_diffusion = 0.30 * mm / cm**0.5,
el_gain = 365,
el_drift_velocity = 2.5 * mm / mus)


buffer_params = dict(pmt_width = 100 * ns,
sipm_width = 1 * mus,
max_time = 10 * ms,
length = 800 * mus,
pre_trigger = 100 * mus,
trigger_thr = 0)

# compression library
compression = "ZLIB4"

# How frequently to print events
print_mod = 1

rate = 0.5 * hertz
3 changes: 3 additions & 0 deletions invisible_cities/database/test_data/NEXT100_PSF.h5
Git LFS file not shown
3 changes: 3 additions & 0 deletions invisible_cities/database/test_data/NEXT100_S1_LT.h5
Git LFS file not shown
3 changes: 3 additions & 0 deletions invisible_cities/database/test_data/NEXT100_S2_LT.h5
Git LFS file not shown
Git LFS file not shown
21 changes: 21 additions & 0 deletions invisible_cities/io/mcinfo_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ def read_mc_tables(file_in : str ,
elif tbl is MCTableType.event_mapping :
evt_map = load_mcevent_mapping(file_in)
tbl_dict[tbl] = evt_map[evt_map.event_id.isin(evt_arr)]
elif tbl is MCTableType.string_map :
str_map = load_mcstringmap(file_in)
tbl_dict[tbl] = str_map
else :
raise TypeError("MC table has no reader")
return tbl_dict
Expand Down Expand Up @@ -948,3 +951,21 @@ def _read_mchit_info(h5f, event_range=(0, int(1e9))) -> Mapping[int, Sequence[MC
all_events[evt_number] = hits

return all_events


def load_mcstringmap(file_name : str) -> pd.DataFrame:
"""
Load the map between ints and strings to a pd.DataFrame

parameters
----------
file_name : str
Name of the file containing MC info.

returns
-------
pd.DataFrame with the int-string pairs within the file.
"""
map_df = pd.read_hdf(file_name, 'MC/string_map')
map_df.set_index('name_id', inplace=True)
return map_df
1 change: 1 addition & 0 deletions invisible_cities/types/symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class MCTableType(AutoNameEnumBase):
sns_positions = auto()
sns_response = auto()
waveforms = auto()
string_map = auto()


class NormStrategy(AutoNameEnumBase):
Expand Down
Loading