-
Notifications
You must be signed in to change notification settings - Fork 225
CEMC SiPM pixel occupancy correction waveform sim #4286
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,7 @@ | |
| #include <TTree.h> | ||
| #include <algorithm> | ||
| #include <cassert> | ||
| #include <cmath> | ||
| #include <sstream> | ||
| #include <string> | ||
|
|
||
|
|
@@ -55,6 +56,11 @@ CaloWaveformSim::~CaloWaveformSim() | |
| gsl_rng_free(m_RandomGenerator); | ||
| } | ||
|
|
||
| void CaloWaveformSim::set_use_sipm_occupancy(bool use_sipm_occupancy) | ||
| { | ||
| m_use_sipm_occupancy = use_sipm_occupancy; | ||
| } | ||
|
|
||
| int CaloWaveformSim::InitRun(PHCompositeNode *topNode) | ||
| { | ||
| // Initialize random generator | ||
|
|
@@ -295,6 +301,7 @@ int CaloWaveformSim::process_event(PHCompositeNode *topNode) | |
| } | ||
|
|
||
| std::map<unsigned int,float> tbt_smear; | ||
| std::map<unsigned int, double> tower_photon_count_mean; | ||
|
|
||
|
|
||
| // loop over hits | ||
|
|
@@ -314,9 +321,11 @@ int CaloWaveformSim::process_event(PHCompositeNode *topNode) | |
| float correction = 1.; | ||
| maphitetaphi(hit, etabin, phibin, correction); | ||
| unsigned int key = encode_tower(etabin, phibin); | ||
| unsigned int tower_index = decode_tower(key); | ||
| float calibconst = cdbttree->GetFloatValue(key, m_fieldname); | ||
| float e_vis = hit->get_light_yield(); | ||
| e_vis *= correction; | ||
|
|
||
| if (m_smear_const) | ||
| { | ||
| auto it = tbt_smear.find(key); | ||
|
|
@@ -327,10 +336,28 @@ int CaloWaveformSim::process_event(PHCompositeNode *topNode) | |
| } | ||
| else | ||
| { | ||
| tbt_smear[key] = 1.0+ gsl_ran_gaussian(m_RandomGenerator,factor_const); | ||
| float val = 1.0+ gsl_ran_gaussian(m_RandomGenerator,factor_const); | ||
| if(val < 0.0f) | ||
| { | ||
| val = 0; | ||
| } | ||
| tbt_smear[key] = val; | ||
| e_vis *= tbt_smear[key]; | ||
| } | ||
| } | ||
|
|
||
| if (m_use_sipm_occupancy && m_dettype == CaloTowerDefs::CEMC) | ||
| { | ||
| constexpr double kSamplingFraction = 2e-2; | ||
| constexpr double kPhotoelectronsPerGeV = 500.; | ||
| constexpr double kPhotonElecYieldVisibleGeV = kPhotoelectronsPerGeV / kSamplingFraction; | ||
| const double photon_count_mean = static_cast<double>(e_vis) * kPhotonElecYieldVisibleGeV; | ||
| if (photon_count_mean > 0.) | ||
| { | ||
| tower_photon_count_mean[tower_index] += photon_count_mean; | ||
| } | ||
| } | ||
|
|
||
| float e_dep = e_vis / m_sampling_fraction; | ||
| float ADC = (calibconst != 0) ? e_dep / calibconst : 0.; | ||
| ADC *= m_gain; | ||
|
|
@@ -351,7 +378,6 @@ int CaloWaveformSim::process_event(PHCompositeNode *topNode) | |
| } | ||
|
|
||
| float t0 = hit->get_t(0) / m_sampletime; | ||
| unsigned int tower_index = decode_tower(key); | ||
| // here I will add the truth matching part | ||
| // for the cell reco, the truth matching info relys on edep not light yield, I will be consistent here :) | ||
| TowerInfo *tower = m_CaloWaveformContainer->get_tower_at_channel(tower_index); | ||
|
|
@@ -371,6 +397,31 @@ int CaloWaveformSim::process_event(PHCompositeNode *topNode) | |
| } | ||
| } | ||
|
|
||
| if (m_use_sipm_occupancy && m_dettype == CaloTowerDefs::CEMC) | ||
| { | ||
| constexpr double kSiPMEffectivePixel = 40000 * 4.; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is already a definition in RawTowerDigitizer.h |
||
| for (const auto &entry : tower_photon_count_mean) | ||
| { | ||
| const unsigned int tower_index = entry.first; | ||
| const double photon_count_mean = entry.second; | ||
| if (photon_count_mean <= 0. || tower_index >= m_waveforms.size()) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| const double poisson_param_per_pixel = photon_count_mean / kSiPMEffectivePixel; | ||
| const double expected_active_pixels = | ||
| kSiPMEffectivePixel * (1. - std::exp(-poisson_param_per_pixel)); | ||
| const double occupancy_ratio = | ||
| std::max(0., std::min(1., expected_active_pixels / photon_count_mean)); | ||
| //std::cout << "occupancy_ratio: " << occupancy_ratio << std::endl; | ||
| for (int isample = 0; isample < m_nsamples; ++isample) | ||
| { | ||
| m_waveforms.at(tower_index).at(isample) *= occupancy_ratio; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // do noise here and add to waveform | ||
|
|
||
| if (m_noiseType == NoiseType::NOISE_TREE) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -153,6 +153,7 @@ class CaloWaveformSim : public SubsysReco | |||||
|
|
||||||
| // Light collection model access | ||||||
| LightCollectionModel &get_light_collection_model() { return light_collection_model; } | ||||||
| void set_use_sipm_occupancy(bool use_sipm_occupancy); | ||||||
|
|
||||||
| private: | ||||||
| CaloTowerDefs::DetectorSystem m_dettype{CaloTowerDefs::CEMC}; | ||||||
|
|
@@ -227,6 +228,7 @@ class CaloWaveformSim : public SubsysReco | |||||
| CDBTTree *cdbttree_time{nullptr}, *cdbttree_MC_time{nullptr}; | ||||||
| TProfile *h_template{nullptr}; | ||||||
| LightCollectionModel light_collection_model; | ||||||
| bool m_use_sipm_occupancy{true}; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Default The new SiPM occupancy scaling feature defaults to enabled, which will change waveform amplitudes for all existing CEMC simulations without user intervention. Per collaboration guidelines, simulation behavior changes should document expected analysis impact and whether reprocessing is required. Consider defaulting to Suggested change- bool m_use_sipm_occupancy{true};
+ bool m_use_sipm_occupancy{false};Alternatively, document the expected impact on existing physics analyses in the PR description. Based on learnings: "If the PR changes simulation behavior, ensure the description states expected analysis impact and whether reprocessing is required." 📝 Committable suggestion
Suggested change
|
||||||
|
|
||||||
| NoiseType m_noiseType{NOISE_TREE}; | ||||||
|
|
||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded
kSamplingFractionmay diverge from configurablem_sampling_fraction.The photon count calculation uses a hardcoded
kSamplingFraction = 2e-2, but the energy deposit calculation at line 361 uses the configurablem_sampling_fractionmember. If a user overrides the sampling fraction viaset_sampling_fraction(), the photon statistics and energy calculations will be inconsistent.Similarly,
kPhotoelectronsPerGeV(500) has no corresponding configurable parameter, making it difficult to tune this model for different detector configurations.Suggested fix: use member variable
if (m_use_sipm_occupancy && m_dettype == CaloTowerDefs::CEMC) { - constexpr double kSamplingFraction = 2e-2; constexpr double kPhotoelectronsPerGeV = 500.; - constexpr double kPhotonElecYieldVisibleGeV = kPhotoelectronsPerGeV / kSamplingFraction; + const double kPhotonElecYieldVisibleGeV = kPhotoelectronsPerGeV / m_sampling_fraction; const double photon_count_mean = static_cast<double>(e_vis) * kPhotonElecYieldVisibleGeV;📝 Committable suggestion