From 5542ca3fff1aedfc10350d255ea78e962231c235 Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Mon, 7 Sep 2026 23:07:27 +0100 Subject: [PATCH 1/8] Handle masked SiPMs in Pyrrha --- invisible_cities/reco/wfm_functions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/invisible_cities/reco/wfm_functions.py b/invisible_cities/reco/wfm_functions.py index d13c15115..b24d6521d 100644 --- a/invisible_cities/reco/wfm_functions.py +++ b/invisible_cities/reco/wfm_functions.py @@ -319,8 +319,10 @@ def spatial_selection_method(wfs : np.ndarray, selected_wfs : 2D array of shape (n_selected_sipms, n_time_bins) with the waveforms of the selected SiPMs. """ detector_info = load_db.DataSiPM(detector_db, run_number) - sipm_x = np.array(detector_info.X) - sipm_y = np.array(detector_info.Y) + active_sipms = np.array(detector_info.Active).astype(bool) + active_ids = np.where(active_sipms)[0] + sipm_x = np.array(detector_info.X)[active_ids] + sipm_y = np.array(detector_info.Y)[active_ids] if selection_method is SiPMSelectionMethod.median_std_method: starting_ids = median_std_method(wfs, **selection_kwargs) From 4bf9197f3b93bfa5fba27d5f248cacd96ff61d7b Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Mon, 21 Sep 2026 14:50:03 +0100 Subject: [PATCH 2/8] Amend masked SiPM handling in `spatial_selection_method()` --- invisible_cities/reco/wfm_functions.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/invisible_cities/reco/wfm_functions.py b/invisible_cities/reco/wfm_functions.py index b24d6521d..60699784a 100644 --- a/invisible_cities/reco/wfm_functions.py +++ b/invisible_cities/reco/wfm_functions.py @@ -2,6 +2,7 @@ This module includes functions to manipulate waveforms. authors: J.J. Gomez-Cadenas, G. Martinez """ +from invisible_cities.core.random_sampling_test import run_number import numpy as np from typing import Optional from typing import Tuple @@ -318,16 +319,16 @@ def spatial_selection_method(wfs : np.ndarray, selected_ids : Array of shape (n_sipms,) containing the indices of the selected SiPMs. selected_wfs : 2D array of shape (n_selected_sipms, n_time_bins) with the waveforms of the selected SiPMs. """ - detector_info = load_db.DataSiPM(detector_db, run_number) - active_sipms = np.array(detector_info.Active).astype(bool) - active_ids = np.where(active_sipms)[0] - sipm_x = np.array(detector_info.X)[active_ids] - sipm_y = np.array(detector_info.Y)[active_ids] + detector_info = load_db.DataSiPM(detector_db, run_number) + active_sipms = detector_info.Active.values.astype(bool) + active_sipm_ids = np.where(active_sipms)[0] + sipm_x = detector_info.X.values[active_sipms] + sipm_y = detector_info.Y.values[active_sipms] if selection_method is SiPMSelectionMethod.median_std_method: - starting_ids = median_std_method(wfs, **selection_kwargs) + starting_ids = median_std_method(wfs[active_sipms], **selection_kwargs) elif selection_method is SiPMSelectionMethod.top_n_method: - starting_ids = top_n_method(wfs, **selection_kwargs) + starting_ids = top_n_method(wfs[active_sipms], **selection_kwargs) else: raise ValueError(f"Selection method {selection_method} not recognized.") @@ -345,7 +346,7 @@ def spatial_selection_method(wfs : np.ndarray, padding_radius ) - selected_ids = np.where(sipm_ids_with_signal)[0] + selected_ids = active_sipm_ids[np.where(sipm_ids_with_signal)[0]] selected_wfs = wfs[selected_ids] return selected_ids, selected_wfs From b3f3f8a32019600b7d78c999469c18a2a0ee3db3 Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Mon, 21 Sep 2026 16:30:41 +0100 Subject: [PATCH 3/8] Add NEXT-100 data with masked SiPMs --- .../test_data/run_16016_0000_ldc1_trg0.waveforms_1evt.h5 | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 invisible_cities/database/test_data/run_16016_0000_ldc1_trg0.waveforms_1evt.h5 diff --git a/invisible_cities/database/test_data/run_16016_0000_ldc1_trg0.waveforms_1evt.h5 b/invisible_cities/database/test_data/run_16016_0000_ldc1_trg0.waveforms_1evt.h5 new file mode 100644 index 000000000..479a297d8 --- /dev/null +++ b/invisible_cities/database/test_data/run_16016_0000_ldc1_trg0.waveforms_1evt.h5 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:868fbfa631384070f1dafecc2cf5f00315882df95d9c6414362304300a6e0f78 +size 10021820 From 84d8fe5cead50cd47702ef260075d1921f0662c5 Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Mon, 21 Sep 2026 16:39:50 +0100 Subject: [PATCH 4/8] Test that Pyrrha works with masked SiPMs --- invisible_cities/cities/irene_test.py | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/invisible_cities/cities/irene_test.py b/invisible_cities/cities/irene_test.py index a3f7a4151..daed4b92a 100644 --- a/invisible_cities/cities/irene_test.py +++ b/invisible_cities/cities/irene_test.py @@ -25,6 +25,7 @@ from .. types.symbols import SiPMThreshold from .. database.load_db import DetDB +from .. database.load_db import DataSiPM from .. io .pmaps_io import load_pmaps from . irene import irene @@ -495,3 +496,46 @@ def test_irene_other_sample_widths(ICDATADIR, config_tmpdir): got = getattr( output_file.root, table) expected = getattr(true_output_file.root, table) assert_tables_equality(got, expected) + + +@ignore_warning.no_config_group +def test_irene_masked_sipms_pyrrha(ICDIR, config_tmpdir): + # Test that masked SiPMs are handled in Pyrrha + run_number = 16016 + + PATH_IN = os.path.join(ICDIR, 'database/test_data/', 'run_16016_0000_ldc1_trg0.waveforms_1evt.h5') + PATH_OUT = os.path.join(config_tmpdir, 'run_16016_0000_ldc1_trg0.waveforms_1evt_pmaps.h5') + + nrequired = 1 + + conf = configure('dummy invisible_cities/config/irene_pyrrha.conf'.split()) + cutting_params = conf['cutting_params'].copy() + cutting_params.update(run_number = run_number, + detector_db = DetDB.next100) + conf.update(dict(run_number = run_number, + detector_db = DetDB.next100, + files_in = PATH_IN, + file_out = PATH_OUT, + event_range = (0, nrequired), + cutting_params = cutting_params)) + + cnt = irene(**conf) + assert cnt.events_in > 0 + + # Find masked SiPMs in DB and compare to the PMAP output + detector_info = DataSiPM(DetDB.next100, run_number) + active_sipms = np.array(detector_info.Active).astype(bool) + masked_ids = set(np.where(~active_sipms)[0]) + + assert masked_ids, "Expected run 16016 to have some masked SiPMs" + + pmaps_out = load_pmaps(PATH_OUT) + + found_masked = [] + for evt, pmap in pmaps_out.items(): + for s2si in pmap.s2s: + for sipm_id in s2si.sipms.ids: + if sipm_id in masked_ids: + found_masked.append((evt, sipm_id)) + + assert not found_masked, (f"Masked SiPMs leaked through pyrrha: {found_masked}") \ No newline at end of file From 7c321855e794e25e423798d0af3ae2b31eb6ca2d Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Mon, 21 Sep 2026 16:59:04 +0100 Subject: [PATCH 5/8] Remove unnecessary assertion --- invisible_cities/cities/irene_test.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/invisible_cities/cities/irene_test.py b/invisible_cities/cities/irene_test.py index daed4b92a..2fe5f143a 100644 --- a/invisible_cities/cities/irene_test.py +++ b/invisible_cities/cities/irene_test.py @@ -527,8 +527,6 @@ def test_irene_masked_sipms_pyrrha(ICDIR, config_tmpdir): active_sipms = np.array(detector_info.Active).astype(bool) masked_ids = set(np.where(~active_sipms)[0]) - assert masked_ids, "Expected run 16016 to have some masked SiPMs" - pmaps_out = load_pmaps(PATH_OUT) found_masked = [] From e93f560d86636c084db8ef70e4fd3acd3bf90c66 Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Tue, 22 Sep 2026 13:37:30 +0100 Subject: [PATCH 6/8] Remove clutter from `spatial_selection_method()` --- invisible_cities/reco/wfm_functions.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/invisible_cities/reco/wfm_functions.py b/invisible_cities/reco/wfm_functions.py index 60699784a..e9a868b6d 100644 --- a/invisible_cities/reco/wfm_functions.py +++ b/invisible_cities/reco/wfm_functions.py @@ -321,14 +321,13 @@ def spatial_selection_method(wfs : np.ndarray, """ detector_info = load_db.DataSiPM(detector_db, run_number) active_sipms = detector_info.Active.values.astype(bool) - active_sipm_ids = np.where(active_sipms)[0] sipm_x = detector_info.X.values[active_sipms] sipm_y = detector_info.Y.values[active_sipms] if selection_method is SiPMSelectionMethod.median_std_method: - starting_ids = median_std_method(wfs[active_sipms], **selection_kwargs) + starting_ids = median_std_method(wfs, **selection_kwargs) elif selection_method is SiPMSelectionMethod.top_n_method: - starting_ids = top_n_method(wfs[active_sipms], **selection_kwargs) + starting_ids = top_n_method(wfs, **selection_kwargs) else: raise ValueError(f"Selection method {selection_method} not recognized.") @@ -346,7 +345,7 @@ def spatial_selection_method(wfs : np.ndarray, padding_radius ) - selected_ids = active_sipm_ids[np.where(sipm_ids_with_signal)[0]] + selected_ids = np.where(sipm_ids_with_signal)[0] selected_wfs = wfs[selected_ids] return selected_ids, selected_wfs From bceaf48186081946232f95af10cc8da3e7a1ec87 Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Tue, 22 Sep 2026 15:39:28 +0100 Subject: [PATCH 7/8] Fix newlines --- invisible_cities/cities/irene_test.py | 2 +- invisible_cities/reco/wfm_functions.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/invisible_cities/cities/irene_test.py b/invisible_cities/cities/irene_test.py index 2fe5f143a..ad17eb67c 100644 --- a/invisible_cities/cities/irene_test.py +++ b/invisible_cities/cities/irene_test.py @@ -536,4 +536,4 @@ def test_irene_masked_sipms_pyrrha(ICDIR, config_tmpdir): if sipm_id in masked_ids: found_masked.append((evt, sipm_id)) - assert not found_masked, (f"Masked SiPMs leaked through pyrrha: {found_masked}") \ No newline at end of file + assert not found_masked, (f"Masked SiPMs leaked through pyrrha: {found_masked}") diff --git a/invisible_cities/reco/wfm_functions.py b/invisible_cities/reco/wfm_functions.py index e9a868b6d..f09a796fa 100644 --- a/invisible_cities/reco/wfm_functions.py +++ b/invisible_cities/reco/wfm_functions.py @@ -349,4 +349,3 @@ def spatial_selection_method(wfs : np.ndarray, selected_wfs = wfs[selected_ids] return selected_ids, selected_wfs - From 1077d598ffa48ba3b45627e7e1ce8c8dd581904b Mon Sep 17 00:00:00 2001 From: Ian0sborne Date: Tue, 22 Sep 2026 15:42:48 +0100 Subject: [PATCH 8/8] Remove unnecessary import --- invisible_cities/reco/wfm_functions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/invisible_cities/reco/wfm_functions.py b/invisible_cities/reco/wfm_functions.py index f09a796fa..37759de01 100644 --- a/invisible_cities/reco/wfm_functions.py +++ b/invisible_cities/reco/wfm_functions.py @@ -2,7 +2,6 @@ This module includes functions to manipulate waveforms. authors: J.J. Gomez-Cadenas, G. Martinez """ -from invisible_cities.core.random_sampling_test import run_number import numpy as np from typing import Optional from typing import Tuple