feat: apply dRICH and pfRICH quantum efficiency at photon generation (stacking) stage#48
feat: apply dRICH and pfRICH quantum efficiency at photon generation (stacking) stage#48Copilot wants to merge 11 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR moves dRICH and pfRICH quantum-efficiency (QE) photon suppression from downstream digitization into the npsim generation/stacking stage, so unproductive optical photons are killed early. It also generalizes OpticalPhotonEfficiencyStackingAction to accept a non-uniform lambda grid (LambdaValues) and to match logical volumes by regex (needed because dRICH/pfRICH photocathode logical volumes are numbered, e.g. DRICH_pss_sec0..N and PFRICH-photocathode-00..NN).
Changes:
- Generalize
OpticalPhotonEfficiencyStackingActionto supportLambdaValues(non-uniform grid), regexLogicalVolumematching, and a unified interpolation path viastd::call_onceinitialization. - Add dRICH and pfRICH QE stacking-action entries to
npsim.py, retaining the existing hpDIRC entry. - Use
std::regex_matchagainst compiled regex for per-photon volume filtering.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/plugins/include/npdet/OpticalPhotonEfficiencyStackingAction.h | Adds LambdaValues property, regex volume matching, unified interpolation, lazy initialization. |
| src/dd4pod/python/npsim.py | Registers generation-stage QE stacking actions for dRICH and pfRICH photocathodes. |
Comments suppressed due to low confidence (1)
src/plugins/include/npdet/OpticalPhotonEfficiencyStackingAction.h:136
- Behavior regression for the single-element
Efficiencycase when onlyLambdaValues(and notLambdaMin/LambdaMax) is provided. Ininitialize(),m_interp_lambda_valuesis only populated whenm_efficiency.size() > 1orm_lambda_values.size() > 1. WithEfficiency=[x]and a singleLambdaValues=[y],m_interp_lambda_valuesstays empty, so the range check at lines 78-80 falls back tom_lambda_min/m_lambda_max(defaults of 0), and no photon ever passes the range test. The previous code supported "single constant value over [LambdaMin, LambdaMax] range"; the new code only supports that case whenLambdaMin/LambdaMaxare also provided. Consider populatingm_interp_lambda_values(or otherwise tracking the effective lambda range) for the single-efficiency case as well, or document the constraint.
if (m_efficiency.size() > 1) {
if (m_lambda_values.size() == m_efficiency.size()) {
m_interp_lambda_values = m_lambda_values;
} else {
auto lambda_min_nm = m_lambda_min / CLHEP::nm;
auto lambda_max_nm = m_lambda_max / CLHEP::nm;
m_interp_lambda_values.reserve(m_efficiency.size());
auto lambda_step = (lambda_max_nm - lambda_min_nm) / (m_efficiency.size() - 1);
for (std::size_t i = 0; i < m_efficiency.size(); ++i) {
m_interp_lambda_values.push_back(lambda_min_nm + i * lambda_step);
}
}
} else if (m_lambda_values.size() > 1) {
m_interp_lambda_values = m_lambda_values;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Agent-Logs-Url: https://github.com/eic/npsim/sessions/f21a9097-2f8b-4486-92e3-771e522e8a8f Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/3adbb508-8d8e-415a-a9be-edc3274a6e86 Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/1a0bce3d-a9bd-4818-9cc7-9f6d4ea19785 Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/ba4e2433-66ae-4dbf-8578-1179788a6269 Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/45003b90-638f-41c1-82a2-67a63baea600 Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/cadf4be9-5ff6-4152-b088-8895b02fa8a8 Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
0bb9f1c to
2ed77b2
Compare
Capybara summary for PR 48
|
- Photons outside the specified lambda range now get killed (efficiency=0 outside the QE table boundaries) instead of being kept. This is physically correct: a photocathode with 0% QE at its wavelength boundaries has 0% QE outside that range too. Previously, UV Cherenkov photons (below 315 nm) were passing unfiltered, dramatically reducing the expected hit count reduction. - Change the destructor summary printout from DEBUG to WARNING so the 'Suppressed N of M photons in lv ...' message appears in CI runs (which use -v WARNING). This provides in-CI verification that the stacking action is active and killing photons at the expected rate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lumes
The stacking action should filter photons when they are created in the
radiator volumes, not when they arrive at the sensor surface. This is
the correct place to apply generation-stage QE: the photon wavelength
is set at creation, and any photon that would not pass the sensor QE
can be killed immediately, saving simulation time.
DRICH radiator volumes (both gas ring Cherenkov and proximity-focus
aerogel): DRICH_gas and DRICH_aerogel -> regex DRICH_(gas|aerogel)
PFRICH radiator volumes (gas volume and individual aerogel tiles):
PFRICH_GasVol and PFRICH-aerogel-{ir}-{ia} -> regex
PFRICH(_GasVol|-aerogel-[0-9]+-[0-9]+)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated import statements for consistency and clarity.
|
FYI @chchatte92 This reduces the number of optical photons we need to handle in simulation, speeding up the simulations. Of course, we then cannot again apply QE in the digitization in EICrecon. |
Hi Wouter, so whenever we change the QE in future for our testing purpose, we change directly in here? Chandra |
You can do either. It's the product that matters. If you want to study the impact of the quantum efficiency, then you'll probably want to run 1 simulation, and then apply QE in EICrecon for multiple assumptions of QE. But for production campaigns it makes more sense to apply the QE here in npsim, so that should be the one that should be correct. |
dRICH QE was only applied in downstream digitization, forcing simulation of many photons that are later discarded. This PR moves dRICH QE suppression into npsim generation-time optical stacking, consistent with the existing hpDIRC pattern.
Generation-stage dRICH QE in
npsim.pyOpticalPhotonEfficiencyStackingActionfor dRICH photosensitive logical volumes (DRICH_pss_sec0..5), so optical photons are filtered before full tracking/digitization.Stacking action support for non-uniform QE tables
OpticalPhotonEfficiencyStackingActionwith optionalWavelengthsproperty.Wavelengths+Efficiency) while preserving legacy uniform-grid behavior (LambdaMin/LambdaMax+Efficiency).Behavioral intent