From db677967684c5bb5de167d9bd6c586ef40a5bd3f Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 2 Nov 2026 21:52:30 -0500 Subject: [PATCH 1/4] mcsmear: new FDC smearing options FDC:DRIFT_SMEAR_NS, FDC:CATHODE_SIGMA and FDC:EFFVSDOCA_PAR0..3; defaults leave the output unchanged [rtj] - FDC:DRIFT_SMEAR_NS (ns, default 0 = off): a Gaussian drift-time shift drawn once per track per chamber and applied to the wire hit and to the strip hits of that track together. The strips see the charge induced by the wire avalanche, so a fluctuation of the drift delay moves both by the same amount; the existing independent smearing (FDC_TDRIFT_SIGMA) is kept. No random numbers are drawn when the option is 0. - FDC:CATHODE_SIGMA (microns, default < 0 = CCDB): overrides FDC_CATHODE_SIGMA from /FDC/fdc_parms, which sets the strip pedestal noise, so the strip resolution can be tuned without a CCDB change. - FDC:EFFVSDOCA_PAR0..3: the parameters of the doca-dependent wire efficiency, previously hard-coded; the defaults are the former values. The settings in use are printed at startup. In the GlueX rho0 data/MC study of 2026-10/11 the tuned values were FDC:DRIFT_SMEAR_NS=3, FDC:CATHODE_SIGMA=85 and FDC:USE_EFFVSDOCA=0. Co-Authored-By: Claude Opus 5.5 (cherry picked from commit 52c79adf7b982139333548640386133d2c74c49b) --- src/programs/Simulation/mcsmear/FDCSmearer.cc | 28 +++++++++++++++---- src/programs/Simulation/mcsmear/FDCSmearer.h | 3 ++ .../Simulation/mcsmear/MyProcessor.cc | 7 +++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/programs/Simulation/mcsmear/FDCSmearer.cc b/src/programs/Simulation/mcsmear/FDCSmearer.cc index 96b1f83cd..046917466 100644 --- a/src/programs/Simulation/mcsmear/FDCSmearer.cc +++ b/src/programs/Simulation/mcsmear/FDCSmearer.cc @@ -8,6 +8,9 @@ #include bool fdc_config_t::FDC_EFFVSDOCA(1); +double fdc_config_t::FDC_CATHODE_SIGMA_SET(-1.); +double fdc_config_t::FDC_DRIFT_SMEAR_NS(0.); +double fdc_config_t::FDC_EFFVSDOCA_PAR_SET[4] = {0.999, 3.75e-4, 0.506, 3.75e-2}; //----------- // fdc_config_t (constructor) @@ -40,7 +43,10 @@ fdc_config_t::fdc_config_t(const std::shared_ptr& event) // Calculate ped noise level based on position resolution // FDC_PED_NOISE = -0.004594 + 0.008711*FDC_CATHODE_SIGMA + // 0.000010*FDC_CATHODE_SIGMA*FDC_CATHODE_SIGMA; //pC + if (FDC_CATHODE_SIGMA_SET >= 0) FDC_CATHODE_SIGMA = FDC_CATHODE_SIGMA_SET; FDC_PED_NOISE = -0.0938 + 0.0485*FDC_CATHODE_SIGMA; + jout << "FDC_DRIFT_SMEAR_NS = " << FDC_DRIFT_SMEAR_NS << endl; + jout << "FDC_CATHODE_SIGMA = " << FDC_CATHODE_SIGMA << " um, FDC_PED_NOISE = " << FDC_PED_NOISE << endl; // load efficiency correction factors @@ -69,10 +75,9 @@ fdc_config_t::fdc_config_t(const std::shared_ptr& event) } } - FDC_EFFVSDOCA_PAR[0] = 0.999; - FDC_EFFVSDOCA_PAR[1] = 3.75e-4; - FDC_EFFVSDOCA_PAR[2] = 0.506; - FDC_EFFVSDOCA_PAR[3] = 3.75e-2; + for (int i = 0; i < 4; i++) FDC_EFFVSDOCA_PAR[i] = FDC_EFFVSDOCA_PAR_SET[i]; + jout << "FDC eff vs doca: use " << FDC_EFFVSDOCA << " par " << FDC_EFFVSDOCA_PAR[0] << " " << FDC_EFFVSDOCA_PAR[1] + << " " << FDC_EFFVSDOCA_PAR[2] << " " << FDC_EFFVSDOCA_PAR[3] << jendl; } @@ -88,6 +93,17 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) hddm_s::FdcChamberList::iterator iter; for (iter = chambers.begin(); iter != chambers.end(); ++iter) { + // drift-time fluctuation common to the wire hit and the strip hits induced by the same track in this chamber + // (the strips see the charge induced by the wire avalanche, so the drift delay is the same for both); one shift per itrack + std::map drift_shift_ns; + auto drift_shift = [&](int itrack) { + if (!config->SMEAR_HITS || fdc_config->FDC_DRIFT_SMEAR_NS <= 0) return 0.; + auto it = drift_shift_ns.find(itrack); + if (it == drift_shift_ns.end()) + it = drift_shift_ns.emplace(itrack, gDRandom.SampleGaussian(fdc_config->FDC_DRIFT_SMEAR_NS)).first; + return it->second; + }; + // Add pedestal noise to strip charge data hddm_s::FdcCathodeStripList strips = iter->getFdcCathodeStrips(); hddm_s::FdcCathodeStripList::iterator siter; @@ -104,7 +120,7 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) continue; double q = titer->getQ(); - double t = titer->getT(); + double t = titer->getT() + drift_shift(titer->getItrack()); if(config->SMEAR_HITS) { q += gDRandom.SampleGaussian(fdc_config->FDC_PED_NOISE); t += gDRandom.SampleGaussian(fdc_config->FDC_TDRIFT_SIGMA)*1.0e9; @@ -138,7 +154,7 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) && !gDRandom.DecideToAcceptHit(fdc_config->GetEfficiencyVsDOCA(doca))) continue; - double t = titer->getT(); + double t = titer->getT() + drift_shift(titer->getItrack()); if(config->SMEAR_HITS) { t += gDRandom.SampleGaussian(fdc_config->FDC_TDRIFT_SIGMA)*1.0e9; } diff --git a/src/programs/Simulation/mcsmear/FDCSmearer.h b/src/programs/Simulation/mcsmear/FDCSmearer.h index d710cb636..979ce2c12 100644 --- a/src/programs/Simulation/mcsmear/FDCSmearer.h +++ b/src/programs/Simulation/mcsmear/FDCSmearer.h @@ -20,6 +20,9 @@ class fdc_config_t double FDC_THRESH_KEV; // fdc anode discriminator threshold static bool FDC_EFFVSDOCA; + static double FDC_DRIFT_SMEAR_NS; // FDC:DRIFT_SMEAR_NS, Gaussian drift-time smear (ns) common to the wire and strip hits of one track in one chamber (0 = off) + static double FDC_CATHODE_SIGMA_SET; // FDC:CATHODE_SIGMA, override of FDC_CATHODE_SIGMA in microns (< 0 = use CCDB) + static double FDC_EFFVSDOCA_PAR_SET[4]; // FDC:EFFVSDOCA_PAR0..3, wire efficiency vs doca (defaults = the former hard-coded values) double FDC_EFFVSDOCA_PAR[4]; vector< vector > channel_efficiencies; diff --git a/src/programs/Simulation/mcsmear/MyProcessor.cc b/src/programs/Simulation/mcsmear/MyProcessor.cc index b05db5af6..14b321366 100644 --- a/src/programs/Simulation/mcsmear/MyProcessor.cc +++ b/src/programs/Simulation/mcsmear/MyProcessor.cc @@ -166,6 +166,13 @@ void MyProcessor::Init(void) "Turn on/off fdc doca-dependent wire hit efficiency," " \"0\"=no efficiency correction," " \"1\"=standard efficiency correction (default)"); + app->SetDefaultParameter("FDC:DRIFT_SMEAR_NS", fdc_config_t::FDC_DRIFT_SMEAR_NS, + "Gaussian drift-time smear in ns, common to the wire and strip hits of one track in one chamber; 0 = off"); + app->SetDefaultParameter("FDC:CATHODE_SIGMA", fdc_config_t::FDC_CATHODE_SIGMA_SET, + "FDC_CATHODE_SIGMA override in microns, sets the strip pedestal noise; < 0 = CCDB"); + for (int i = 0; i < 4; i++) + app->SetDefaultParameter("FDC:EFFVSDOCA_PAR" + std::to_string(i), fdc_config_t::FDC_EFFVSDOCA_PAR_SET[i], + "fdc wire efficiency vs doca parameter"); return; //NOERROR; } From 10dd7e4882e29de6f2bdc079880f1f36eadd78d0 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 2 Nov 2026 21:54:08 -0500 Subject: [PATCH 2/4] mcsmear: apply the FDC anode discriminator threshold FDC_THRESH_KEV to the wire hits [rtj] FDC_THRESH_KEV was read from /FDC/fdc_parms but never used by mcsmear, so the only wire threshold in the simulation chain was the one applied by hdgeant4 to each track segment. mcsmear now drops an anode truth hit whose deposited energy is below FDC_THRESH_KEV. The cut acts on the energy that hdgeant4 summed over the segments it combined into the hit, which is closer to what the discriminator sees, and it makes the effective wire threshold adjustable without rerunning hdgeant4 (by giving mcsmear a CCDB in which FDC_THRESH_KEV differs from the one used for hdgeant4). The value in use is printed at startup. No random numbers are drawn by the cut. With the same CCDB for both programs the output is unchanged: every hit that hdgeant4 kept already has dE above the threshold. (In the drift-cluster mode of hdgeant4, DRIFTCLUSTERS != 0, dE holds the integrated pulse instead of a deposited energy, so FDC_THRESH_KEV should be set accordingly there.) Co-Authored-By: Claude Opus 5.5 (cherry picked from commit 68b8a9b147772a9b4d5a1c8bc0b9da4f592afd85) --- src/programs/Simulation/mcsmear/FDCSmearer.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/programs/Simulation/mcsmear/FDCSmearer.cc b/src/programs/Simulation/mcsmear/FDCSmearer.cc index 046917466..395dd5ede 100644 --- a/src/programs/Simulation/mcsmear/FDCSmearer.cc +++ b/src/programs/Simulation/mcsmear/FDCSmearer.cc @@ -46,6 +46,7 @@ fdc_config_t::fdc_config_t(const std::shared_ptr& event) if (FDC_CATHODE_SIGMA_SET >= 0) FDC_CATHODE_SIGMA = FDC_CATHODE_SIGMA_SET; FDC_PED_NOISE = -0.0938 + 0.0485*FDC_CATHODE_SIGMA; jout << "FDC_DRIFT_SMEAR_NS = " << FDC_DRIFT_SMEAR_NS << endl; + jout << "FDC_THRESH_KEV = " << FDC_THRESH_KEV << " (anode wire threshold)" << endl; jout << "FDC_CATHODE_SIGMA = " << FDC_CATHODE_SIGMA << " um, FDC_PED_NOISE = " << FDC_PED_NOISE << endl; @@ -145,6 +146,10 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) hddm_s::FdcAnodeTruthHitList thits = witer->getFdcAnodeTruthHits(); hddm_s::FdcAnodeTruthHitList::iterator titer; for (titer = thits.begin(); titer != thits.end(); ++titer) { + // anode discriminator threshold, applied to the energy deposited on the wire + // (dE in GeV, summed by hdgeant4 over the track segments it combined into this hit) + if (titer->getDE() * 1e6 < fdc_config->FDC_THRESH_KEV) + continue; // correct simulation efficiencies if (config->APPLY_EFFICIENCY_CORRECTIONS && !gDRandom.DecideToAcceptHit(fdc_config->GetEfficiencyCorrectionFactor(witer))) From 782fb1315b2bb7e64134455cd68edd7a0d7f1feb Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Sun, 8 Nov 2026 18:45:38 -0500 Subject: [PATCH 3/4] mcsmear: FDC gas-gain, signal attenuation and threshold options [rtj] New command-line options for the FDC smearing. Every default leaves the output unchanged. FDC:GAIN_SCALE gas-gain factor on the strip charge q and on the anode wire dE, applied before the thresholds (1) FDC:GAIN_PKG1..4 extra gain factor per FDC package (modules 1-2, 3-4, 5-6, 7-8), times FDC:GAIN_SCALE (1) FDC:GAIN_SIGMA s avalanche gain fluctuation: one log-normal factor exp(s G - s^2/2) per chamber and track, shared by the wire hit and the strips it induces (0) FDC:DOCA_ATTEN a wire dE and the track's strip q in the chamber scaled by max(0.05, 1 - a doca^2), doca in cm (0) FDC:STRIP_THRESHOLD strip charge threshold in pC; < 0 keeps FDC_THRESHOLD_FACTOR * FDC_PED_NOISE from CCDB (-1) FDC:WIRE_THRESHOLD_KEV anode threshold on the gain-scaled wire dE in keV; < 0 keeps FDC_THRESH_KEV from CCDB (-1) Motivation: the FDC gas gain of the real detector changes with time and differs between packages (e.g. a 40% drop of the strip signal between 2019-11 runs 71362 and 71483), which changes the FDC hit efficiency and with it the tracking efficiency. With per-period gains fitted only to the data's FDC plane-used fractions (not to any cross section), the rho(0) photoproduction cross section of ten run segments (2018-01 to 2023-01) agrees to about 2% (RMS, beyond statistics). Builds on the FDC smearing options of this PR. Independent of the strip peakAmp PR (the thresholds act on the charge q, not on peakAmp) and of #423. Co-Authored-By: Claude Opus 5.5 (cherry picked from commit 4a42d96a075a63ad9cdcdc6c11edcda409abaea4) --- src/programs/Simulation/mcsmear/FDCSmearer.cc | 44 ++++++++++++++++++- src/programs/Simulation/mcsmear/FDCSmearer.h | 6 +++ .../Simulation/mcsmear/MyProcessor.cc | 13 ++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/programs/Simulation/mcsmear/FDCSmearer.cc b/src/programs/Simulation/mcsmear/FDCSmearer.cc index 395dd5ede..264f51c1a 100644 --- a/src/programs/Simulation/mcsmear/FDCSmearer.cc +++ b/src/programs/Simulation/mcsmear/FDCSmearer.cc @@ -10,6 +10,12 @@ bool fdc_config_t::FDC_EFFVSDOCA(1); double fdc_config_t::FDC_CATHODE_SIGMA_SET(-1.); double fdc_config_t::FDC_DRIFT_SMEAR_NS(0.); +double fdc_config_t::FDC_GAIN_SCALE(1.); +double fdc_config_t::FDC_GAIN_PKG[4] = {1., 1., 1., 1.}; +double fdc_config_t::FDC_DOCA_ATTEN(0.); +double fdc_config_t::FDC_GAIN_SIGMA(0.); +double fdc_config_t::FDC_STRIP_THR_SET(-1.); +double fdc_config_t::FDC_WIRE_THR_KEV_SET(-1.); double fdc_config_t::FDC_EFFVSDOCA_PAR_SET[4] = {0.999, 3.75e-4, 0.506, 3.75e-2}; //----------- @@ -46,6 +52,7 @@ fdc_config_t::fdc_config_t(const std::shared_ptr& event) if (FDC_CATHODE_SIGMA_SET >= 0) FDC_CATHODE_SIGMA = FDC_CATHODE_SIGMA_SET; FDC_PED_NOISE = -0.0938 + 0.0485*FDC_CATHODE_SIGMA; jout << "FDC_DRIFT_SMEAR_NS = " << FDC_DRIFT_SMEAR_NS << endl; + jout << "FDC_GAIN_SCALE = " << FDC_GAIN_SCALE << " x package " << FDC_GAIN_PKG[0] << "/" << FDC_GAIN_PKG[1] << "/" << FDC_GAIN_PKG[2] << "/" << FDC_GAIN_PKG[3] << ", FDC_DOCA_ATTEN = " << FDC_DOCA_ATTEN << ", FDC_GAIN_SIGMA = " << FDC_GAIN_SIGMA << ", FDC_STRIP_THRESHOLD = " << FDC_STRIP_THR_SET << " pC, FDC_WIRE_THRESHOLD_KEV = " << FDC_WIRE_THR_KEV_SET << " (< 0: CCDB)" << endl; jout << "FDC_THRESH_KEV = " << FDC_THRESH_KEV << " (anode wire threshold)" << endl; jout << "FDC_CATHODE_SIGMA = " << FDC_CATHODE_SIGMA << " um, FDC_PED_NOISE = " << FDC_PED_NOISE << endl; @@ -89,10 +96,15 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) { double t_max = config->TRIGGER_LOOKBACK_TIME + fdc_config->FDC_TIME_WINDOW; double threshold = fdc_config->FDC_THRESHOLD_FACTOR * fdc_config->FDC_PED_NOISE; // for sparsification + if (fdc_config->FDC_STRIP_THR_SET >= 0) threshold = fdc_config->FDC_STRIP_THR_SET; + double wire_thr_kev = (fdc_config->FDC_WIRE_THR_KEV_SET >= 0) ? fdc_config->FDC_WIRE_THR_KEV_SET : fdc_config->FDC_THRESH_KEV; + double gain_global = fdc_config->FDC_GAIN_SCALE; // gas gain relative to the simulation: scales the avalanche charge seen on wires and strips hddm_s::FdcChamberList chambers = record->getFdcChambers(); hddm_s::FdcChamberList::iterator iter; for (iter = chambers.begin(); iter != chambers.end(); ++iter) { + int pkg = (iter->getModule() - 1) / 2; // FDC package 0-3 (3 planes per module, 2 modules per package) + double gain = gain_global * ((pkg >= 0 && pkg < 4) ? fdc_config->FDC_GAIN_PKG[pkg] : 1.); // drift-time fluctuation common to the wire hit and the strip hits induced by the same track in this chamber // (the strips see the charge induced by the wire avalanche, so the drift delay is the same for both); one shift per itrack @@ -105,6 +117,33 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) return it->second; }; + // signal attenuation vs the track's doca to its wire in this chamber (charge lost at the cell edge), per itrack, from the anode truth hits + std::map atten; + auto atten_of_doca = [&](double d) { return std::max(0.05, 1. - fdc_config->FDC_DOCA_ATTEN * d * d); }; + if (fdc_config->FDC_DOCA_ATTEN > 0) { + hddm_s::FdcAnodeWireList awires = iter->getFdcAnodeWires(); + for (auto aw = awires.begin(); aw != awires.end(); ++aw) { + hddm_s::FdcAnodeTruthHitList ath = aw->getFdcAnodeTruthHits(); + for (auto at = ath.begin(); at != ath.end(); ++at) { + double a = atten_of_doca(at->getD()); + auto it = atten.find(at->getItrack()); + if (it == atten.end() || a > it->second) atten[at->getItrack()] = a; // the wire with the closest approach + } + } + } + auto atten_of_track = [&](int itrack) { auto it = atten.find(itrack); return (it == atten.end()) ? 1. : it->second; }; + // avalanche gain fluctuation, one factor per track in this chamber (the strips see the charge induced by the same wire avalanche) + std::map fluct; + auto fluct_of_track = [&](int itrack) { + if (fdc_config->FDC_GAIN_SIGMA <= 0) return 1.; + auto it = fluct.find(itrack); + if (it == fluct.end()) { + double s = fdc_config->FDC_GAIN_SIGMA; + it = fluct.emplace(itrack, exp(gDRandom.SampleGaussian(s) - 0.5 * s * s)).first; + } + return it->second; + }; + // Add pedestal noise to strip charge data hddm_s::FdcCathodeStripList strips = iter->getFdcCathodeStrips(); hddm_s::FdcCathodeStripList::iterator siter; @@ -120,7 +159,7 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) && !gDRandom.DecideToAcceptHit(fdc_config->GetEfficiencyCorrectionFactor(siter))) continue; - double q = titer->getQ(); + double q = titer->getQ() * gain * atten_of_track(titer->getItrack()) * fluct_of_track(titer->getItrack()); double t = titer->getT() + drift_shift(titer->getItrack()); if(config->SMEAR_HITS) { q += gDRandom.SampleGaussian(fdc_config->FDC_PED_NOISE); @@ -148,7 +187,8 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) for (titer = thits.begin(); titer != thits.end(); ++titer) { // anode discriminator threshold, applied to the energy deposited on the wire // (dE in GeV, summed by hdgeant4 over the track segments it combined into this hit) - if (titer->getDE() * 1e6 < fdc_config->FDC_THRESH_KEV) + double att = (fdc_config->FDC_DOCA_ATTEN > 0) ? atten_of_doca(titer->getD()) : 1.; + if (titer->getDE() * gain * att * fluct_of_track(titer->getItrack()) * 1e6 < wire_thr_kev) continue; // correct simulation efficiencies if (config->APPLY_EFFICIENCY_CORRECTIONS diff --git a/src/programs/Simulation/mcsmear/FDCSmearer.h b/src/programs/Simulation/mcsmear/FDCSmearer.h index 979ce2c12..4ad4a2ad1 100644 --- a/src/programs/Simulation/mcsmear/FDCSmearer.h +++ b/src/programs/Simulation/mcsmear/FDCSmearer.h @@ -22,6 +22,12 @@ class fdc_config_t static bool FDC_EFFVSDOCA; static double FDC_DRIFT_SMEAR_NS; // FDC:DRIFT_SMEAR_NS, Gaussian drift-time smear (ns) common to the wire and strip hits of one track in one chamber (0 = off) static double FDC_CATHODE_SIGMA_SET; // FDC:CATHODE_SIGMA, override of FDC_CATHODE_SIGMA in microns (< 0 = use CCDB) + static double FDC_GAIN_SCALE; // FDC:GAIN_SCALE, gas-gain factor applied to the strip charge q and the wire dE before the thresholds (1 = off) + static double FDC_GAIN_PKG[4]; // FDC:GAIN_PKG1..4, extra gain factor per FDC package (modules 1-2, 3-4, 5-6, 7-8), times FDC_GAIN_SCALE (1 = off) + static double FDC_STRIP_THR_SET; // FDC:STRIP_THRESHOLD, strip charge threshold in pC (< 0 = FDC_THRESHOLD_FACTOR * FDC_PED_NOISE from CCDB) + static double FDC_GAIN_SIGMA; // FDC:GAIN_SIGMA s, avalanche gain fluctuation: one log-normal factor exp(s G - s^2/2) per chamber and track, shared by its wire hit and the strips it induces (0 = off) + static double FDC_DOCA_ATTEN; // FDC:DOCA_ATTEN a, signal (wire dE and the track's strip q in the chamber) scaled by max(0.05, 1 - a doca^2), doca in cm (0 = off) + static double FDC_WIRE_THR_KEV_SET; // FDC:WIRE_THRESHOLD_KEV, anode threshold on the gain-scaled wire dE in keV (< 0 = FDC_THRESH_KEV from CCDB) static double FDC_EFFVSDOCA_PAR_SET[4]; // FDC:EFFVSDOCA_PAR0..3, wire efficiency vs doca (defaults = the former hard-coded values) double FDC_EFFVSDOCA_PAR[4]; diff --git a/src/programs/Simulation/mcsmear/MyProcessor.cc b/src/programs/Simulation/mcsmear/MyProcessor.cc index 14b321366..a753910f7 100644 --- a/src/programs/Simulation/mcsmear/MyProcessor.cc +++ b/src/programs/Simulation/mcsmear/MyProcessor.cc @@ -170,6 +170,19 @@ void MyProcessor::Init(void) "Gaussian drift-time smear in ns, common to the wire and strip hits of one track in one chamber; 0 = off"); app->SetDefaultParameter("FDC:CATHODE_SIGMA", fdc_config_t::FDC_CATHODE_SIGMA_SET, "FDC_CATHODE_SIGMA override in microns, sets the strip pedestal noise; < 0 = CCDB"); + app->SetDefaultParameter("FDC:GAIN_SCALE", fdc_config_t::FDC_GAIN_SCALE, + "FDC gas-gain factor on the strip charge and wire dE before the thresholds; 1 = off"); + for (int i = 0; i < 4; i++) + app->SetDefaultParameter("FDC:GAIN_PKG" + std::to_string(i + 1), fdc_config_t::FDC_GAIN_PKG[i], + "FDC extra gain factor for package " + std::to_string(i + 1) + " (times FDC:GAIN_SCALE); 1 = off"); + app->SetDefaultParameter("FDC:GAIN_SIGMA", fdc_config_t::FDC_GAIN_SIGMA, + "FDC avalanche gain fluctuation (log-normal sigma), one factor per chamber and track for wire and strips; 0 = off"); + app->SetDefaultParameter("FDC:DOCA_ATTEN", fdc_config_t::FDC_DOCA_ATTEN, + "FDC signal attenuation a: wire dE and strip q scaled by max(0.05, 1 - a doca^2) (doca in cm); 0 = off"); + app->SetDefaultParameter("FDC:STRIP_THRESHOLD", fdc_config_t::FDC_STRIP_THR_SET, + "FDC strip charge threshold in pC; < 0 = FDC_THRESHOLD_FACTOR * FDC_PED_NOISE (CCDB)"); + app->SetDefaultParameter("FDC:WIRE_THRESHOLD_KEV", fdc_config_t::FDC_WIRE_THR_KEV_SET, + "FDC anode threshold on the gain-scaled wire dE in keV; < 0 = FDC_THRESH_KEV (CCDB)"); for (int i = 0; i < 4; i++) app->SetDefaultParameter("FDC:EFFVSDOCA_PAR" + std::to_string(i), fdc_config_t::FDC_EFFVSDOCA_PAR_SET[i], "fdc wire efficiency vs doca parameter"); From a9b8c02451e136f6784c97d6990c2573b5368ba6 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 12 Nov 2026 09:43:20 -0500 Subject: [PATCH 4/4] mcsmear: remove the old FDC wire efficiency-vs-doca curve (GetEfficiencyVsDOCA, FDC:USE_EFFVSDOCA, FDC:EFFVSDOCA_PAR0..3), superseded by FDC:DOCA_ATTEN [rtj] Co-Authored-By: Claude Opus 5.5 --- src/programs/Simulation/mcsmear/FDCSmearer.cc | 10 ---------- src/programs/Simulation/mcsmear/FDCSmearer.h | 16 ---------------- src/programs/Simulation/mcsmear/MyProcessor.cc | 10 ---------- 3 files changed, 36 deletions(-) diff --git a/src/programs/Simulation/mcsmear/FDCSmearer.cc b/src/programs/Simulation/mcsmear/FDCSmearer.cc index 264f51c1a..2dbf8041b 100644 --- a/src/programs/Simulation/mcsmear/FDCSmearer.cc +++ b/src/programs/Simulation/mcsmear/FDCSmearer.cc @@ -7,7 +7,6 @@ #include -bool fdc_config_t::FDC_EFFVSDOCA(1); double fdc_config_t::FDC_CATHODE_SIGMA_SET(-1.); double fdc_config_t::FDC_DRIFT_SMEAR_NS(0.); double fdc_config_t::FDC_GAIN_SCALE(1.); @@ -16,7 +15,6 @@ double fdc_config_t::FDC_DOCA_ATTEN(0.); double fdc_config_t::FDC_GAIN_SIGMA(0.); double fdc_config_t::FDC_STRIP_THR_SET(-1.); double fdc_config_t::FDC_WIRE_THR_KEV_SET(-1.); -double fdc_config_t::FDC_EFFVSDOCA_PAR_SET[4] = {0.999, 3.75e-4, 0.506, 3.75e-2}; //----------- // fdc_config_t (constructor) @@ -82,10 +80,6 @@ fdc_config_t::fdc_config_t(const std::shared_ptr& event) channel_efficiencies.push_back( new_strip_efficiencies[2*chamber] ); } } - - for (int i = 0; i < 4; i++) FDC_EFFVSDOCA_PAR[i] = FDC_EFFVSDOCA_PAR_SET[i]; - jout << "FDC eff vs doca: use " << FDC_EFFVSDOCA << " par " << FDC_EFFVSDOCA_PAR[0] << " " << FDC_EFFVSDOCA_PAR[1] - << " " << FDC_EFFVSDOCA_PAR[2] << " " << FDC_EFFVSDOCA_PAR[3] << jendl; } @@ -194,10 +188,6 @@ void FDCSmearer::SmearEvent(hddm_s::HDDM *record) if (config->APPLY_EFFICIENCY_CORRECTIONS && !gDRandom.DecideToAcceptHit(fdc_config->GetEfficiencyCorrectionFactor(witer))) continue; - double doca = titer->getD(); - if (config->APPLY_EFFICIENCY_CORRECTIONS - && !gDRandom.DecideToAcceptHit(fdc_config->GetEfficiencyVsDOCA(doca))) - continue; double t = titer->getT() + drift_shift(titer->getItrack()); if(config->SMEAR_HITS) { diff --git a/src/programs/Simulation/mcsmear/FDCSmearer.h b/src/programs/Simulation/mcsmear/FDCSmearer.h index 4ad4a2ad1..24858421e 100644 --- a/src/programs/Simulation/mcsmear/FDCSmearer.h +++ b/src/programs/Simulation/mcsmear/FDCSmearer.h @@ -19,7 +19,6 @@ class fdc_config_t double FDC_TIME_WINDOW; double FDC_THRESH_KEV; // fdc anode discriminator threshold - static bool FDC_EFFVSDOCA; static double FDC_DRIFT_SMEAR_NS; // FDC:DRIFT_SMEAR_NS, Gaussian drift-time smear (ns) common to the wire and strip hits of one track in one chamber (0 = off) static double FDC_CATHODE_SIGMA_SET; // FDC:CATHODE_SIGMA, override of FDC_CATHODE_SIGMA in microns (< 0 = use CCDB) static double FDC_GAIN_SCALE; // FDC:GAIN_SCALE, gas-gain factor applied to the strip charge q and the wire dE before the thresholds (1 = off) @@ -28,8 +27,6 @@ class fdc_config_t static double FDC_GAIN_SIGMA; // FDC:GAIN_SIGMA s, avalanche gain fluctuation: one log-normal factor exp(s G - s^2/2) per chamber and track, shared by its wire hit and the strips it induces (0 = off) static double FDC_DOCA_ATTEN; // FDC:DOCA_ATTEN a, signal (wire dE and the track's strip q in the chamber) scaled by max(0.05, 1 - a doca^2), doca in cm (0 = off) static double FDC_WIRE_THR_KEV_SET; // FDC:WIRE_THRESHOLD_KEV, anode threshold on the gain-scaled wire dE in keV (< 0 = FDC_THRESH_KEV from CCDB) - static double FDC_EFFVSDOCA_PAR_SET[4]; // FDC:EFFVSDOCA_PAR0..3, wire efficiency vs doca (defaults = the former hard-coded values) - double FDC_EFFVSDOCA_PAR[4]; vector< vector > channel_efficiencies; @@ -58,19 +55,6 @@ class fdc_config_t return channel_efficiencies.at(gPlane).at(element-1); } - - double GetEfficiencyVsDOCA(double doca) { - // Introduce a DOCA-dependent efficiency that cuts off the hit efficiency - // for tracks that cross through the cell at a large distance from the wire. - double eff = FDC_EFFVSDOCA_PAR[0] - FDC_EFFVSDOCA_PAR[1] * - (1 / (pow(FDC_EFFVSDOCA_PAR[2] - doca, 2) + - pow(FDC_EFFVSDOCA_PAR[3], 2)) - - 2 * FDC_EFFVSDOCA_PAR[2] * doca / - pow(pow(FDC_EFFVSDOCA_PAR[2], 2) + - pow(FDC_EFFVSDOCA_PAR[3], 2), 2) - ); - return (!FDC_EFFVSDOCA)? 1 : (eff < 0)? 0 : eff*eff; - } }; diff --git a/src/programs/Simulation/mcsmear/MyProcessor.cc b/src/programs/Simulation/mcsmear/MyProcessor.cc index a753910f7..1ff0ee1f2 100644 --- a/src/programs/Simulation/mcsmear/MyProcessor.cc +++ b/src/programs/Simulation/mcsmear/MyProcessor.cc @@ -159,13 +159,6 @@ void MyProcessor::Init(void) bzero(&input_file_mutex_last_owner, sizeof(pthread_t)); bzero(&smearer_mutex_last_owner, sizeof(pthread_t)); - // By default, the empirical fdc DOCA-dependent efficiency - // is applied to fdc wire hits in FDCSmearer. This can be - // disabled by this commandline option. - app->SetDefaultParameter("FDC:USE_EFFVSDOCA", fdc_config_t::FDC_EFFVSDOCA, - "Turn on/off fdc doca-dependent wire hit efficiency," - " \"0\"=no efficiency correction," - " \"1\"=standard efficiency correction (default)"); app->SetDefaultParameter("FDC:DRIFT_SMEAR_NS", fdc_config_t::FDC_DRIFT_SMEAR_NS, "Gaussian drift-time smear in ns, common to the wire and strip hits of one track in one chamber; 0 = off"); app->SetDefaultParameter("FDC:CATHODE_SIGMA", fdc_config_t::FDC_CATHODE_SIGMA_SET, @@ -183,9 +176,6 @@ void MyProcessor::Init(void) "FDC strip charge threshold in pC; < 0 = FDC_THRESHOLD_FACTOR * FDC_PED_NOISE (CCDB)"); app->SetDefaultParameter("FDC:WIRE_THRESHOLD_KEV", fdc_config_t::FDC_WIRE_THR_KEV_SET, "FDC anode threshold on the gain-scaled wire dE in keV; < 0 = FDC_THRESH_KEV (CCDB)"); - for (int i = 0; i < 4; i++) - app->SetDefaultParameter("FDC:EFFVSDOCA_PAR" + std::to_string(i), fdc_config_t::FDC_EFFVSDOCA_PAR_SET[i], - "fdc wire efficiency vs doca parameter"); return; //NOERROR; }