legend-dataflow-scripts 0.3.0a5__tar.gz → 0.3.0a6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {legend_dataflow_scripts-0.3.0a5/src/legend_dataflow_scripts.egg-info → legend_dataflow_scripts-0.3.0a6}/PKG-INFO +1 -1
  2. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6/src/legend_dataflow_scripts.egg-info}/PKG-INFO +1 -1
  3. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/_version.py +3 -3
  4. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/dsp/dplms.py +49 -0
  5. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/dsp/eopt.py +49 -0
  6. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/dsp/evtsel.py +87 -0
  7. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/dsp/nopt.py +38 -0
  8. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/dsp/pz.py +42 -0
  9. legend_dataflow_scripts-0.3.0a6/src/legenddataflowscripts/par/geds/dsp/svm.py +52 -0
  10. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/dsp/svm_build.py +30 -0
  11. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/hit/aoe.py +112 -2
  12. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/hit/ecal.py +333 -0
  13. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/hit/lq.py +139 -29
  14. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/hit/qc.py +86 -0
  15. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/tier/dsp.py +97 -0
  16. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/tier/hit.py +65 -0
  17. legend_dataflow_scripts-0.3.0a6/src/legenddataflowscripts/utils/alias_table.py +85 -0
  18. legend_dataflow_scripts-0.3.0a6/src/legenddataflowscripts/utils/cfgtools.py +38 -0
  19. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/utils/log.py +63 -8
  20. legend_dataflow_scripts-0.3.0a6/src/legenddataflowscripts/utils/plot_dict.py +39 -0
  21. legend_dataflow_scripts-0.3.0a6/src/legenddataflowscripts/utils/pulser_removal.py +32 -0
  22. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/workflow/execenv.py +80 -21
  23. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/workflow/filedb.py +35 -0
  24. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/workflow/pre_compile_catalog.py +20 -0
  25. legend_dataflow_scripts-0.3.0a6/src/legenddataflowscripts/workflow/utils.py +214 -0
  26. legend_dataflow_scripts-0.3.0a5/src/legenddataflowscripts/par/geds/dsp/svm.py +0 -28
  27. legend_dataflow_scripts-0.3.0a5/src/legenddataflowscripts/utils/alias_table.py +0 -56
  28. legend_dataflow_scripts-0.3.0a5/src/legenddataflowscripts/utils/cfgtools.py +0 -14
  29. legend_dataflow_scripts-0.3.0a5/src/legenddataflowscripts/utils/plot_dict.py +0 -13
  30. legend_dataflow_scripts-0.3.0a5/src/legenddataflowscripts/utils/pulser_removal.py +0 -16
  31. legend_dataflow_scripts-0.3.0a5/src/legenddataflowscripts/workflow/utils.py +0 -115
  32. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/LICENSE +0 -0
  33. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/README.md +0 -0
  34. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/pyproject.toml +0 -0
  35. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/setup.cfg +0 -0
  36. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legend_dataflow_scripts.egg-info/SOURCES.txt +0 -0
  37. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legend_dataflow_scripts.egg-info/dependency_links.txt +0 -0
  38. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legend_dataflow_scripts.egg-info/entry_points.txt +0 -0
  39. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legend_dataflow_scripts.egg-info/not-zip-safe +0 -0
  40. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legend_dataflow_scripts.egg-info/requires.txt +0 -0
  41. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legend_dataflow_scripts.egg-info/top_level.txt +0 -0
  42. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/__init__.py +0 -0
  43. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/__init__.py +0 -0
  44. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/__init__.py +0 -0
  45. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/dsp/__init__.py +0 -0
  46. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/par/geds/hit/__init__.py +0 -0
  47. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/tier/__init__.py +0 -0
  48. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/utils/__init__.py +0 -0
  49. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/utils/convert_np.py +0 -0
  50. {legend_dataflow_scripts-0.3.0a5 → legend_dataflow_scripts-0.3.0a6}/src/legenddataflowscripts/workflow/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: legend-dataflow-scripts
3
- Version: 0.3.0a5
3
+ Version: 0.3.0a6
4
4
  Summary: Python package for the processing scripts for LEGEND-200 data
5
5
  Author-email: George Marshall <ggmarsh@uw.edu>, Luigi Pertoldi <gipert@pm.me>
6
6
  Maintainer: The LEGEND Collaboration
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: legend-dataflow-scripts
3
- Version: 0.3.0a5
3
+ Version: 0.3.0a6
4
4
  Summary: Python package for the processing scripts for LEGEND-200 data
5
5
  Author-email: George Marshall <ggmarsh@uw.edu>, Luigi Pertoldi <gipert@pm.me>
6
6
  Maintainer: The LEGEND Collaboration
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.3.0a5'
22
- __version_tuple__ = version_tuple = (0, 3, 0, 'a5')
21
+ __version__ = version = '0.3.0a6'
22
+ __version_tuple__ = version_tuple = (0, 3, 0, 'a6')
23
23
 
24
- __commit_id__ = commit_id = 'g2f2cce849'
24
+ __commit_id__ = commit_id = 'g66e026ac8'
@@ -15,6 +15,55 @@ from ....utils import build_log, convert_dict_np_to_float
15
15
 
16
16
 
17
17
  def par_geds_dsp_dplms() -> None:
18
+ """Compute DPLMS optimal filter coefficients for HPGe detectors.
19
+
20
+ CLI entry point registered as ``par-geds-dsp-dplms``. The *Discrete
21
+ Prolate Laplacian Maximum Signal* (DPLMS) filter is constructed from two
22
+ data samples:
23
+
24
+ 1. **FFT baselines** - low-energy (``daqenergy <= 10`` ADC) events from
25
+ dedicated FFT run files used to characterise the noise power spectrum.
26
+ 2. **Calibration peak events** - gamma-line events read from the
27
+ *peak-file* produced by :func:`par_geds_dsp_evtsel`.
28
+
29
+ The coefficients are computed by
30
+ :func:`pygama.pargen.dplms_ge_dict.dplms_ge_dict` and written to an LH5
31
+ file at *lh5-path* (so that the DSP chain can load them with
32
+ ``loadlh5(...)``). The DSP parameter database is updated with the filter
33
+ configuration and written to *dsp-pars*.
34
+
35
+ Notes
36
+ -----
37
+ **Command-line arguments**
38
+
39
+ ``--fft-raw-filelist`` : str
40
+ Path to a text file listing the FFT raw LH5 input files.
41
+ ``--peak-file`` : str
42
+ LH5 file containing preselected calibration peak events.
43
+ ``--inplots`` : str, optional
44
+ Existing pickle plot file to update with DPLMS plots.
45
+ ``--database`` : str
46
+ Path to the existing DSP parameter database (JSON/YAML).
47
+ ``--log`` : str, optional
48
+ Path to the log file.
49
+ ``--log-config`` : str, optional
50
+ Logging configuration file.
51
+ ``--processing-chain`` : list of str
52
+ Processing chain configuration file(s).
53
+ ``--config-file`` : list of str
54
+ DPLMS configuration file(s). Must contain ``run_dplms`` (bool),
55
+ ``n_baselines`` (int), and ``peaks_kev`` (list).
56
+ ``--channel`` : str
57
+ Channel identifier; used as the HDF5 group name in *lh5-path*.
58
+ ``--raw-table-name`` : str
59
+ LH5 table path within the raw and peak files.
60
+ ``--dsp-pars`` : str
61
+ Output path for the updated DSP parameter database (JSON/YAML).
62
+ ``--lh5-path`` : str
63
+ Output LH5 file path for the DPLMS filter coefficients.
64
+ ``--plot-path`` : str, optional
65
+ Output path for diagnostic plots (pickle).
66
+ """
18
67
  argparser = argparse.ArgumentParser()
19
68
  argparser.add_argument("--fft-raw-filelist", help="fft_raw_filelist", type=str)
20
69
  argparser.add_argument("--peak-file", help="tcm_filelist", type=str, required=True)
@@ -29,6 +29,55 @@ except AttributeError: # np < 2
29
29
 
30
30
 
31
31
  def par_geds_dsp_eopt() -> None:
32
+ """Optimise DSP filter parameters for energy resolution using Bayesian optimisation.
33
+
34
+ CLI entry point registered as ``par-geds-dsp-eopt``. Reads calibration
35
+ peak events from an LH5 file produced by :func:`par_geds_dsp_evtsel` and
36
+ jointly optimises the shaping parameters (``sigma`` for CUSP and ZAC
37
+ filters, ``rise`` for the trapezoidal filter) and the charge-trapping
38
+ correction coefficient (``alpha``) for each filter type.
39
+
40
+ Optimisation uses a Gaussian-process surrogate model
41
+ (:class:`pygama.pargen.dsp_optimize.BayesianOptimizer`) with a configurable
42
+ acquisition function. Initial samples are evaluated first; subsequent
43
+ iterations are selected by the acquisition function. The optimal filter
44
+ parameters and CTC coefficients are written to *final-dsp-pars*, and the
45
+ trained optimiser objects are serialised to *qbb-grid-path*.
46
+
47
+ Notes
48
+ -----
49
+ **Command-line arguments**
50
+
51
+ ``--peak-file`` : str
52
+ LH5 file containing preselected calibration peak events (output of
53
+ ``par-geds-dsp-evtsel``).
54
+ ``--decay-const`` : str
55
+ JSON/YAML file with the current DSP parameter database (PZ constants,
56
+ etc.).
57
+ ``--inplots`` : str, optional
58
+ Existing pickle plot file to update with new optimisation plots.
59
+ ``--log`` : str, optional
60
+ Path to the log file.
61
+ ``--processing-chain`` : list of str
62
+ Processing chain configuration file(s).
63
+ ``--config-file`` : list of str
64
+ Energy optimisation configuration file(s). Must contain ``run_eopt``
65
+ (bool), ``peaks`` (list of keV values), ``kev_widths``, ``fom``,
66
+ ``fom_field``, ``fom_err_field``, ``initial_samples``, ``acq_func``,
67
+ ``batch_size``, and ``n_iter``.
68
+ ``--log-config`` : str, optional
69
+ Logging configuration file.
70
+ ``--raw-table-name`` : str
71
+ LH5 table path within the peak file.
72
+ ``--final-dsp-pars`` : str
73
+ Output path for the optimised DSP parameter database (JSON/YAML).
74
+ ``--qbb-grid-path`` : str
75
+ Output path for the serialised optimiser objects (pickle).
76
+ ``--plot-path`` : str, optional
77
+ Output path for diagnostic plots (pickle).
78
+ ``--plot-save-path`` : str, optional
79
+ Alternative save path for plots.
80
+ """
32
81
  argparser = argparse.ArgumentParser()
33
82
 
34
83
  argparser.add_argument("--peak-file", help="tcm_filelist", type=str, required=True)
@@ -34,6 +34,50 @@ def get_out_data(
34
34
  final_cut_field="is_valid_cal",
35
35
  energy_param="trapTmax",
36
36
  ):
37
+ """Apply cuts and assemble a calibration output table for a single gamma peak.
38
+
39
+ Evaluates the expressions in *cut_dict* on *dsp_data* and *raw_dict* on
40
+ *raw_data*, selects events within the energy window
41
+ [*e_lower_lim*, *e_upper_lim*] that also pass the *final_cut_field* flag,
42
+ and returns a :class:`lgdo.Table` containing both the raw waveforms and
43
+ key reconstructed quantities.
44
+
45
+ Parameters
46
+ ----------
47
+ raw_data : lgdo.Table
48
+ Raw-tier data buffer for the current batch of events.
49
+ dsp_data : lgdo.Table
50
+ DSP-tier data for the same batch.
51
+ cut_dict : dict
52
+ Mapping of ``{column_name: {"expression": str, "parameters": dict}}``
53
+ defining quality-cut columns to add to *dsp_data*.
54
+ e_lower_lim : float
55
+ Lower ADC bound for energy window selection.
56
+ e_upper_lim : float
57
+ Upper ADC bound for energy window selection.
58
+ ecal_pars : float
59
+ ADC-to-keV conversion factor applied to ``trapTmax``.
60
+ raw_dict : dict
61
+ Mapping of ``{column_name: {"expression": str, "parameters": dict}}``
62
+ defining derived columns to add to *raw_data* (e.g. calibrated DAQ
63
+ energy).
64
+ peak : float
65
+ Nominal gamma-line energy in keV stored as a label column.
66
+ final_cut_field : str
67
+ Boolean column name in *dsp_data* used as the final event selection
68
+ mask. Defaults to ``"is_valid_cal"``.
69
+ energy_param : str
70
+ DSP energy parameter used for the window selection. Defaults to
71
+ ``"trapTmax"``.
72
+
73
+ Returns
74
+ -------
75
+ out_tbl : lgdo.Table
76
+ Table of selected events containing windowed and pre-summed waveforms
77
+ plus scalar quantities (timestamp, baseline, energies, peak label).
78
+ n_events : int
79
+ Number of events in *out_tbl*.
80
+ """
37
81
  for outname, info in cut_dict.items():
38
82
  outcol = dsp_data.eval(info["expression"], info.get("parameters", None))
39
83
  dsp_data.add_column(outname, outcol)
@@ -82,6 +126,49 @@ def get_out_data(
82
126
 
83
127
 
84
128
  def par_geds_dsp_evtsel() -> None:
129
+ """Select calibration peak events for DSP parameter optimisation.
130
+
131
+ CLI entry point registered as ``par-geds-dsp-evtsel``. Scans raw LH5
132
+ files, applies pulser and discharge-recovery masks, performs a rough
133
+ energy calibration (or uses a provided calibration curve), and collects
134
+ events near each specified gamma-line energy. For each peak the data are
135
+ run through the DSP chain to derive quality cuts, and the surviving
136
+ waveforms together with reconstructed quantities are written to *peak-file*
137
+ in LH5 format for consumption by :func:`par_geds_dsp_eopt` and
138
+ :func:`par_geds_dsp_dplms`.
139
+
140
+ Notes
141
+ -----
142
+ **Command-line arguments**
143
+
144
+ ``--raw-filelist`` : list of str
145
+ Raw LH5 input file(s) or a single ``.filelist`` file.
146
+ ``--pulser-file`` : str, optional
147
+ Path to the pulser mask file.
148
+ ``-p`` / ``--no-pulse``
149
+ Flag indicating that no pulser is present.
150
+ ``--decay-const`` : str
151
+ JSON/YAML file with the current DSP parameter database.
152
+ ``--raw-cal-curve`` : list of str, optional
153
+ Pre-computed raw calibration curve file(s). When provided, the
154
+ ``--channel`` argument is also required.
155
+ ``--channel`` : str, optional (required with ``--raw-cal-curve``)
156
+ Channel identifier used to extract the calibration curve.
157
+ ``--log`` : str, optional
158
+ Path to the log file.
159
+ ``--processing-chain`` : list of str
160
+ Processing chain configuration file(s).
161
+ ``--config-file`` : list of str
162
+ Event selection configuration file(s). Must contain ``run_selection``
163
+ (bool), ``peaks`` (list of keV), ``kev_widths``, ``cut_parameters``,
164
+ ``n_events``, and ``final_cut_field``.
165
+ ``--log-config`` : str, optional
166
+ Logging configuration file.
167
+ ``--raw-table-name`` : str
168
+ LH5 table path within the raw file.
169
+ ``--peak-file`` : str
170
+ Output LH5 file path for selected peak events.
171
+ """
85
172
  argparser = argparse.ArgumentParser()
86
173
  argparser.add_argument("--raw-filelist", help="raw_filelist", type=str, nargs="*")
87
174
  argparser.add_argument(
@@ -16,6 +16,44 @@ from ....utils import build_log
16
16
 
17
17
 
18
18
  def par_geds_dsp_nopt() -> None:
19
+ """Optimise DSP filter parameters for noise performance.
20
+
21
+ CLI entry point registered as ``par-geds-dsp-nopt``. Selects low-energy
22
+ baseline events (``daqenergy ≤ 10`` ADC) from raw LH5 files, applies
23
+ quality cuts derived from the preliminary DSP output, and passes the clean
24
+ baseline sample to :func:`pygama.pargen.noise_optimization.noise_optimization`
25
+ to determine optimal filter shaping parameters for noise rejection.
26
+
27
+ The resulting noise-optimisation parameters are merged with the existing
28
+ DSP parameter database and written to *dsp-pars*. Optionally, diagnostic
29
+ plots are serialised to *plot-path*.
30
+
31
+ Notes
32
+ -----
33
+ **Command-line arguments**
34
+
35
+ ``--raw-filelist`` : str
36
+ Path to a text file listing the raw LH5 input files (one per line).
37
+ ``--database`` : str
38
+ Path to the existing DSP parameter database (JSON/YAML).
39
+ ``--inplots`` : str, optional
40
+ Existing pickle plot file to update with new noise-optimisation plots.
41
+ ``--log`` : str, optional
42
+ Path to the log file.
43
+ ``--processing-chain`` : list of str
44
+ Processing chain configuration file(s).
45
+ ``--config-file`` : list of str
46
+ Noise optimisation configuration file(s). Must contain ``run_nopt``
47
+ (bool), ``n_events`` (int), and ``cut_pars``.
48
+ ``--log-config`` : str, optional
49
+ Logging configuration file.
50
+ ``--raw-table-name`` : str
51
+ LH5 table path within the raw file.
52
+ ``--dsp-pars`` : str
53
+ Output path for the merged DSP parameter database (JSON/YAML).
54
+ ``--plot-path`` : str, optional
55
+ Output path for diagnostic plots (pickle).
56
+ """
19
57
  argparser = argparse.ArgumentParser()
20
58
  argparser.add_argument("--raw-filelist", help="raw_filelist", type=str)
21
59
  argparser.add_argument("--database", help="database", type=str, required=True)
@@ -20,6 +20,48 @@ from ....utils import (
20
20
 
21
21
 
22
22
  def par_geds_dsp_pz() -> None:
23
+ """Determine the pole-zero (PZ) decay constant(s) for HPGe waveforms.
24
+
25
+ CLI entry point registered as ``par-geds-dsp-pz``. Selects high-energy
26
+ events from raw LH5 files (above an ADC threshold, excluding pulser and
27
+ discharge-recovery events), processes them through a preliminary DSP chain,
28
+ and uses :class:`pygama.pargen.pz_correct.PZCorrect` to fit either a
29
+ single- or double-exponential decay model to the waveform tails.
30
+
31
+ The fitted time constant(s) are written to *output-file* in JSON/YAML
32
+ format. Optionally, diagnostic waveform and slope plots are serialised to
33
+ a pickle file at *plot-path*.
34
+
35
+ Notes
36
+ -----
37
+ **Command-line arguments**
38
+
39
+ ``--processing-chain`` : list of str
40
+ Processing chain configuration file(s).
41
+ ``--config-file`` : list of str
42
+ PZ calibration configuration file(s). Must contain ``run_tau``
43
+ (bool), ``threshold`` (ADC), ``n_events`` (int), ``wf_field`` (str),
44
+ and ``mode`` (``"single"`` or ``"double"``).
45
+ ``--log-config`` : str, optional
46
+ Logging configuration file.
47
+ ``--raw-table-name`` : str
48
+ LH5 table path within the raw file (e.g. ``ch1057600/raw``).
49
+ ``--plot-path`` : str, optional
50
+ Output path for the diagnostic pickle file.
51
+ ``--output-file`` : str
52
+ Output path for the fitted PZ parameters (JSON/YAML).
53
+ ``--pulser-file`` : str, optional
54
+ Path to the pulser mask file.
55
+ ``-p`` / ``--no-pulse``
56
+ Flag indicating that no pulser is present; skips pulser masking.
57
+ ``--raw-files`` : list of str
58
+ Raw LH5 input file(s).
59
+ ``--pz-files`` : list of str, optional
60
+ Alternative input file(s) used instead of ``--raw-files`` when
61
+ present (e.g. preselected PZ calibration events).
62
+ ``--log`` : str, optional
63
+ Path to the log file.
64
+ """
23
65
  argparser = argparse.ArgumentParser()
24
66
  argparser.add_argument("--log", help="log file", type=str)
25
67
  argparser.add_argument(
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from pathlib import Path
5
+
6
+ from dbetto.catalog import Props
7
+
8
+
9
+ def par_geds_dsp_svm() -> None:
10
+ """Register a pre-trained SVM model file in the DSP parameter database.
11
+
12
+ CLI entry point registered as ``par-geds-dsp-svm``. Reads an existing
13
+ DSP parameter file from *input-file*, appends a ``svm`` key that points to
14
+ the SVM model pickle file via a ``loadlh5``-compatible path template, and
15
+ writes the result to *output-file*.
16
+
17
+ The model path is stored as a relative reference using the ``$_``
18
+ directory variable so the parameter file remains portable when the
19
+ production directory is relocated.
20
+
21
+ Notes
22
+ -----
23
+ **Command-line arguments**
24
+
25
+ ``--log`` : str, optional
26
+ Path to the log file.
27
+ ``--output-file`` : str
28
+ Output path for the updated DSP parameter file (JSON/YAML).
29
+ ``--input-file`` : str
30
+ Input DSP parameter file (JSON/YAML) to update.
31
+ ``--svm-file`` : str
32
+ Path to the serialised SVM model pickle file.
33
+ """
34
+ argparser = argparse.ArgumentParser()
35
+ argparser.add_argument("--log", help="log file", type=str)
36
+ argparser.add_argument(
37
+ "--output-file", help="output par file", type=str, required=True
38
+ )
39
+ argparser.add_argument(
40
+ "--input-file", help="input par file", type=str, required=True
41
+ )
42
+ argparser.add_argument("--svm-file", help="svm file", required=True)
43
+ args = argparser.parse_args()
44
+
45
+ par_data = Props.read_from(args.input_file)
46
+
47
+ file = f"'$_/{Path(args.svm_file).name}'"
48
+
49
+ par_data["svm"] = {"model_file": file}
50
+
51
+ Path(args.output_file).parent.mkdir(parents=True, exist_ok=True)
52
+ Props.write_to(args.output_file, par_data)
@@ -12,6 +12,36 @@ from ....utils import build_log
12
12
 
13
13
 
14
14
  def par_geds_dsp_svm_build() -> None:
15
+ """Train a Support Vector Machine (SVM) classifier for HPGe pulse-shape discrimination.
16
+
17
+ CLI entry point registered as ``par-geds-dsp-svm-build``. Loads
18
+ pre-processed training data from LH5 files (table ``ml_train/dsp``),
19
+ extracts the normalised discrete wavelet transform features
20
+ (``dwt_norm``) and class labels (``dc_label``), trains a
21
+ :class:`sklearn.svm.SVC` with configurable hyperparameters, and serialises
22
+ the trained model to *output-file* as a pickle file.
23
+
24
+ When no training data files are provided (``--train-data`` is empty or
25
+ absent) the output file is written with ``None`` as the model, acting as a
26
+ placeholder.
27
+
28
+ Notes
29
+ -----
30
+ **Command-line arguments**
31
+
32
+ ``--log`` : str, optional
33
+ Path to the log file.
34
+ ``--log-config`` : str, optional
35
+ Logging configuration file.
36
+ ``--output-file`` : str
37
+ Output path for the serialised SVM model (pickle).
38
+ ``--train-data`` : list of str, optional
39
+ LH5 file(s) containing training data under ``ml_train/dsp``.
40
+ ``--train-hyperpars`` : list of str, optional
41
+ JSON/YAML file(s) with SVM hyperparameters: ``random_state``,
42
+ ``kernel``, ``decision_function_shape``, ``class_weight``, ``C``,
43
+ and ``gamma``.
44
+ """
15
45
  argparser = argparse.ArgumentParser()
16
46
  argparser.add_argument("--log", help="log file", type=str)
17
47
 
@@ -28,6 +28,21 @@ warnings.filterwarnings(action="ignore", category=RuntimeWarning)
28
28
 
29
29
 
30
30
  def get_results_dict(aoe_class):
31
+ """Extract serialisable results from a calibrated :class:`~pygama.pargen.AoE_cal.CalAoE` object.
32
+
33
+ Parameters
34
+ ----------
35
+ aoe_class : pygama.pargen.AoE_cal.CalAoE
36
+ Calibrated A/E object after calling :meth:`~pygama.pargen.AoE_cal.CalAoE.calibrate`.
37
+
38
+ Returns
39
+ -------
40
+ dict
41
+ Mapping of run timestamp → results dictionary. Each entry contains
42
+ the calibration energy parameter, drift-time parameter, correction
43
+ fit results, low-side and two-sided survival fractions (both overall
44
+ and per-run), and the A/E cut values.
45
+ """
31
46
  result_dict = {}
32
47
  for tstamp in aoe_class.low_side_sfs_by_run:
33
48
  result_dict[tstamp] = {
@@ -58,6 +73,52 @@ def run_aoe_calibration(
58
73
  debug_mode=False,
59
74
  override_dict=None,
60
75
  ):
76
+ """Run the A/E calibration and update all output dictionaries.
77
+
78
+ Instantiates :class:`~pygama.pargen.AoE_cal.CalAoE` and calls
79
+ :meth:`~pygama.pargen.AoE_cal.CalAoE.calibrate` on *data*. All input
80
+ mapping arguments are keyed by run timestamp and the corresponding output
81
+ mappings are returned with the A/E results merged in.
82
+
83
+ Parameters
84
+ ----------
85
+ data : pandas.DataFrame
86
+ Event-level data containing the energy, current-amplitude, and
87
+ drift-time parameters required by the A/E calibration.
88
+ cal_dicts : dict
89
+ ``{timestamp: operations_dict}`` mapping of existing hit-level
90
+ calibration operations. Updated in-place with the A/E cut
91
+ expressions.
92
+ results_dicts : dict
93
+ ``{timestamp: results_dict}`` mapping of calibration results from
94
+ preceding steps (energy calibration, partition calibration).
95
+ object_dicts : dict
96
+ ``{timestamp: object_dict}`` mapping of pickled calibration objects
97
+ from preceding steps.
98
+ plot_dicts : dict
99
+ ``{timestamp: plot_dict}`` mapping of existing plot dictionaries.
100
+ config : dict or str or list
101
+ A/E calibration configuration. Must contain ``run_aoe`` (bool),
102
+ ``current_param``, ``energy_param``, ``cal_energy_param``,
103
+ ``cut_field``, and ``threshold``.
104
+ debug_mode : bool
105
+ Activates additional diagnostic output in :class:`~pygama.pargen.AoE_cal.CalAoE`.
106
+ Defaults to ``False``.
107
+ override_dict : dict, optional
108
+ Per-detector override parameters passed to
109
+ :meth:`~pygama.pargen.AoE_cal.CalAoE.calibrate`.
110
+
111
+ Returns
112
+ -------
113
+ cal_dicts : dict
114
+ Updated calibration operations mappings.
115
+ out_result_dicts : dict
116
+ Updated results mappings including A/E results.
117
+ out_object_dicts : dict
118
+ Updated object mappings including the ``CalAoE`` instance.
119
+ out_plot_dicts : dict
120
+ Updated plot mappings including A/E diagnostic figures.
121
+ """
61
122
  if isinstance(config, str | list):
62
123
  config = Props.read_from(config)
63
124
 
@@ -182,6 +243,55 @@ def run_aoe_calibration(
182
243
 
183
244
 
184
245
  def par_geds_hit_aoe() -> None:
246
+ """Calibrate the A/E (current-amplitude over energy) pulse-shape discriminant.
247
+
248
+ CLI entry point registered as ``par-geds-hit-aoe``. Loads DSP data for a
249
+ single detector channel, applies energy and pulser masks, and runs
250
+ :func:`run_aoe_calibration` to derive the A/E mean, width, and cut
251
+ values as a function of energy and (optionally) drift time. Results are
252
+ written to *hit-pars* (JSON/YAML) and the calibration object is serialised
253
+ to *aoe-results* (pickle).
254
+
255
+ Notes
256
+ -----
257
+ **Command-line arguments**
258
+
259
+ ``files`` : list of str
260
+ One or more file lists (``.filelist``) containing DSP LH5 paths.
261
+ ``--pulser-file`` : str, optional
262
+ Path to the pulser mask file.
263
+ ``--tcm-filelist`` : str, optional
264
+ Unused placeholder.
265
+ ``--ecal-file`` : str
266
+ Energy calibration output file (JSON/YAML with ``pars`` and
267
+ ``results`` keys).
268
+ ``--eres-file`` : str
269
+ Energy calibration pickle file containing calibration objects.
270
+ ``--inplots`` : str, optional
271
+ Existing pickle plot file to merge with A/E plots.
272
+ ``--timestamp`` : str
273
+ Run timestamp label (default ``"20000101T000000Z"``).
274
+ ``--log`` : str, optional
275
+ Path to the log file.
276
+ ``--log-config`` : str, optional
277
+ Logging configuration file.
278
+ ``--config-file`` : list of str
279
+ A/E calibration configuration file(s).
280
+ ``--table-name`` : str
281
+ LH5 table path within the DSP files.
282
+ ``--detector`` : str, optional
283
+ Detector name used to look up override parameters.
284
+ ``--override-files`` : list of str, optional
285
+ JSON/YAML file(s) with detector-specific override parameters.
286
+ ``--plot-file`` : str, optional
287
+ Output path for diagnostic plots (pickle).
288
+ ``--hit-pars`` : str
289
+ Output path for the A/E hit parameters (JSON/YAML).
290
+ ``--aoe-results`` : str
291
+ Output path for the serialised A/E calibration object (pickle).
292
+ ``-d`` / ``--debug``
293
+ Enable debug mode for additional diagnostic output.
294
+ """
185
295
  argparser = argparse.ArgumentParser()
186
296
  argparser.add_argument("files", help="files", nargs="*", type=str)
187
297
  argparser.add_argument(
@@ -294,8 +404,8 @@ def par_geds_hit_aoe() -> None:
294
404
 
295
405
  data["run_timestamp"] = args.timestamp
296
406
 
297
- if args.override.files:
298
- override_dict = Props.read_from(args.override.files)
407
+ if args.override_files:
408
+ override_dict = Props.read_from(args.override_files)
299
409
  override_dict = override_dict.get(args.detector, None)
300
410
 
301
411
  cal_dict, results_dicts, object_dicts, plot_dicts = run_aoe_calibration(