9 #include <reconstruction/modules/CDCDedxCorrection/CDCDedxCorrectionModule.h>
10 #include <reconstruction/dataobjects/CDCDedxTrack.h>
11 #include <reconstruction/dataobjects/DedxConstants.h>
25 setDescription(
"Apply hit level corrections to the dE/dx measurements.");
26 addParam(
"relativeCorrections", m_relative,
"If true, apply corrections relative to those used in production",
true);
27 addParam(
"momentumCor", m_momCor,
"Boolean to apply momentum correction",
false);
28 addParam(
"momentumCorFromDB", m_useDBMomCor,
"Boolean to apply momentum correction from DB",
false);
29 addParam(
"scaleCor", m_scaleCor,
"Boolean to apply scale correction",
false);
30 addParam(
"cosineCor", m_cosineCor,
"Boolean to apply cosine correction",
false);
31 addParam(
"wireGain", m_wireGain,
"Boolean to apply wire gains",
false);
32 addParam(
"runGain", m_runGain,
"Boolean to apply run gain",
false);
33 addParam(
"twoDCell", m_twoDCell,
"Boolean to apply 2D correction",
false);
34 addParam(
"oneDCell", m_oneDCell,
"Boolean to apply 1D correction",
false);
35 addParam(
"cosineEdge", m_cosineEdge,
"Boolean to apply cosine edge correction",
true);
36 addParam(
"nonlADC", m_nonlADC,
"Boolean to apply non-linear adc correction",
true);
37 addParam(
"removeLowest", m_removeLowest,
"portion of events with low dE/dx that should be discarded",
double(0.05));
38 addParam(
"removeHighest", m_removeHighest,
"portion of events with high dE/dx that should be discarded",
double(0.25));
46 m_cdcDedxTracks.isRequired();
50 if (m_DBRunGain->getRunGain() == 0) {
51 B2WARNING(
"Run gain is zero for this run");
55 for (
unsigned int i = 0; i < 14336; ++i) {
56 if (m_DBWireGains->getWireGain(i) == 0)
57 B2WARNING(
"Wire gain is zero for this wire: " << i);
61 unsigned int ncosbins = m_DBCosineCor->getSize();
62 for (
unsigned int i = 0; i < ncosbins; ++i) {
63 double gain = m_DBCosineCor->getMean(i);
65 B2ERROR(
"Cosine gain is zero for this bin " << i);
69 if (!m_DBHadronCor || m_DBHadronCor->getSize() == 0) {
70 B2WARNING(
"No hadron correction parameters!");
71 for (
int i = 0; i < 4; ++i)
72 m_hadronpars.push_back(0.0);
73 m_hadronpars.push_back(1.0);
74 }
else m_hadronpars = m_DBHadronCor->getHadronPars();
83 for (
auto& dedxTrack : m_cdcDedxTracks) {
84 if (dedxTrack.size() == 0) {
85 B2WARNING(
"No good hits on this track...");
93 int nhits = dedxTrack.size();
94 double costh = dedxTrack.getCosTheta();
95 std::vector<double> newLayerHits;
96 double newLayerDe = 0, newLayerDx = 0;
98 if (costh < TMath::Cos(150.0 * TMath::DegToRad()))
continue;
99 if (costh > TMath::Cos(17.0 * TMath::DegToRad()))
continue;
101 for (
int i = 0; i < nhits; ++i) {
106 int jadcbase = dedxTrack.getADCBaseCount(i);
107 double jLayer = dedxTrack.getHitLayer(i);
108 double jWire = dedxTrack.getWire(i);
109 double jNDocaRS = dedxTrack.getDocaRS(i) / dedxTrack.getCellHalfWidth(i);
110 double jEntaRS = dedxTrack.getEntaRS(i);
111 double jPath = dedxTrack.getPath(i);
113 double correction = dedxTrack.m_scale * dedxTrack.m_runGain * dedxTrack.m_cosCor * dedxTrack.m_cosEdgeCor *
114 dedxTrack.getTwoDCorrection(i) * dedxTrack.getOneDCorrection(i) * dedxTrack.getNonLADCCorrection(i);
115 if (dedxTrack.getWireGain(i) > 0)correction *= dedxTrack.getWireGain(i);
118 double newhitdedx = (m_relative) ? 1 / correction : 1.0;
119 StandardCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, jPath, costh, newhitdedx);
120 dedxTrack.setDedx(i, newhitdedx);
128 correction *= GetCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, costh);
129 if (!m_DBWireGains && dedxTrack.getWireGain(i) == 0)correction = 0;
132 correction = GetCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, costh);
136 if (correction != 0) {
137 newLayerDe += jadcbase / correction;
141 if (i + 1 < nhits && dedxTrack.getHitLayer(i + 1) == jLayer) {
144 if (newLayerDx != 0)newLayerHits.push_back(newLayerDe / newLayerDx * std::sqrt(1 - costh * costh));
151 calculateMeans(&(dedxTrack.m_dedxAvg),
152 &(dedxTrack.m_dedxAvgTruncatedNoSat),
153 &(dedxTrack.m_dedxAvgTruncatedErr),
156 dedxTrack.m_dedxAvgTruncated = dedxTrack.m_dedxAvgTruncatedNoSat;
157 HadronCorrection(costh, dedxTrack.m_dedxAvgTruncated);
164 B2INFO(
"CDCDedxCorrectionModule exiting...");
170 double gain = m_DBRunGain->getRunGain();
178 double gain = m_DBWireGains->getWireGain(wireID);
179 if (gain != 0) dedx = dedx / gain;
183 if (m_relative)dedx = 0;
190 double gain = (m_DB2DCell) ? m_DB2DCell->getMean(layer, doca, enta) : 1.0;
191 if (gain != 0) dedx = dedx / gain;
198 double gain = (m_DB1DCell) ? m_DB1DCell->getMean(layer, enta) : 1.0;
199 if (gain != 0) dedx = dedx / gain;
205 double coscor = m_DBCosineCor->getMean(costh);
206 if (coscor != 0) dedx = dedx / coscor;
213 double cosedgecor = m_DBCosEdgeCor->getMean(costh);
214 if (cosedgecor != 0) dedx = dedx / cosedgecor;
221 dedx = D2I(costheta, I2D(costheta, 1.00) / 1.00 * dedx);
225 double costheta,
double& dedx)
const
228 if (!m_relative && m_nonlADC)
229 adc = m_DBNonlADC->getCorrectedADC(adc, layer);
231 dedx *= adc * std::sqrt(1 - costheta * costheta) / length;
234 double scale = m_DBScaleFactor->getScaleFactor();
235 if (scale != 0) dedx = dedx / scale;
240 RunGainCorrection(dedx);
243 WireGainCorrection(wireID, dedx);
246 CosineCorrection(costheta, dedx);
249 if (!m_relative && m_cosineEdge && (costheta <= -0.850 || costheta >= 0.950))
250 CosineEdgeCorrection(costheta, dedx);
253 TwoDCorrection(layer, doca, enta, dedx);
256 OneDCorrection(layer, enta, dedx);
263 double correction = 1.0;
264 if (m_scaleCor) correction *= m_DBScaleFactor->getScaleFactor();
265 if (m_runGain) correction *= m_DBRunGain->getRunGain();
266 if (m_wireGain) correction *= m_DBWireGains->getWireGain(wireID);
267 if (m_twoDCell) correction *= m_DB2DCell->getMean(layer, doca, enta);
268 if (m_oneDCell) correction *= m_DB1DCell->getMean(layer, enta);
269 if (m_cosineCor) correction *= m_DBCosineCor->getMean(costheta);
273 if (m_nonlADC)adc = m_DBNonlADC->getCorrectedADC(adc, layer);
274 if (m_cosineEdge && (costheta <= -0.850 || costheta >= 0.950)) {
275 correction *= m_DBCosEdgeCor->getMean(costheta);
284 double absCosTheta = fabs(cosTheta);
285 double projection = pow(absCosTheta, m_hadronpars[3]) + m_hadronpars[2];
286 if (projection == 0) {
287 B2WARNING(
"Something wrong with dE/dx hadron constants!");
291 double chargeDensity = D / projection;
292 double numerator = 1 + m_hadronpars[0] * chargeDensity;
293 double denominator = 1 + m_hadronpars[1] * chargeDensity;
295 if (denominator == 0) {
296 B2WARNING(
"Something wrong with dE/dx hadron constants!");
300 double I = D * m_hadronpars[4] * numerator / denominator;
306 double absCosTheta = fabs(cosTheta);
307 double projection = pow(absCosTheta, m_hadronpars[3]) + m_hadronpars[2];
309 if (projection == 0 || m_hadronpars[4] == 0) {
310 B2WARNING(
"Something wrong with dE/dx hadron constants!");
314 double a = m_hadronpars[0] / projection;
315 double b = 1 - m_hadronpars[1] / projection * (I / m_hadronpars[4]);
316 double c = -1.0 * I / m_hadronpars[4];
318 if (b == 0 && a == 0) {
319 B2WARNING(
"both a and b coefficiants for hadron correction are 0");
323 double D = (a != 0) ? (-b + sqrt(b * b - 4.0 * a * c)) / (2.0 * a) : -c / b;
325 B2WARNING(
"D is less 0! will try another solution");
326 D = (a != 0) ? (-b - sqrt(b * b + 4.0 * a * c)) / (2.0 * a) : -c / b;
328 B2WARNING(
"D is still less 0! just return uncorrectecd value");
338 const std::vector<double>& dedx)
const
342 std::vector<double> sortedDedx = dedx;
343 std::sort(sortedDedx.begin(), sortedDedx.end());
344 sortedDedx.erase(std::remove(sortedDedx.begin(), sortedDedx.end(), 0), sortedDedx.end());
345 sortedDedx.shrink_to_fit();
347 double truncatedMeanTmp = 0.0;
348 double meanTmp = 0.0;
349 double sumOfSquares = 0.0;
350 int numValuesTrunc = 0;
351 const int numDedx = sortedDedx.size();
354 const int lowEdgeTrunc = int(numDedx * m_removeLowest + 0.51);
355 const int highEdgeTrunc = int(numDedx * (1 - m_removeHighest) + 0.51);
356 for (
int i = 0; i < numDedx; i++) {
357 meanTmp += sortedDedx[i];
358 if (i >= lowEdgeTrunc and i < highEdgeTrunc) {
359 truncatedMeanTmp += sortedDedx[i];
360 sumOfSquares += sortedDedx[i] * sortedDedx[i];
368 if (numValuesTrunc != 0) {
369 truncatedMeanTmp /= numValuesTrunc;
371 truncatedMeanTmp = meanTmp;
375 *truncatedMean = truncatedMeanTmp;
377 if (numValuesTrunc > 1) {
378 *truncatedMeanErr = sqrt(sumOfSquares /
double(numValuesTrunc) - truncatedMeanTmp * truncatedMeanTmp) / double(
381 *truncatedMeanErr = 0;
This module may be used to apply the corrections to dE/dx per the calibration constants.
double D2I(const double cosTheta, const double D) const
Saturation correction: convert the measured ionization (D) to actual ionization (I)
void WireGainCorrection(int wireID, double &dedx) const
Perform a wire gain correction.
void TwoDCorrection(int layer, double doca, double enta, double &dedx) const
Perform a 2D correction.
virtual void initialize() override
Initialize the Module.
virtual void event() override
This method is called for each event.
double I2D(const double cosTheta, const double I) const
Saturation correction: convert the actural ionization (I) to measured ionization (D)
void OneDCorrection(int layer, double enta, double &dedx) const
Perform a wire gain correction.
virtual void terminate() override
End of the event processing.
void HadronCorrection(double costheta, double &dedx) const
Perform a hadron saturation correction.
void calculateMeans(double *mean, double *truncatedMean, double *truncatedMeanErr, const std::vector< double > &dedx) const
Recalculate the dE/dx mean values after corrections.
virtual ~CDCDedxCorrectionModule()
Destructor.
void CosineEdgeCorrection(double costh, double &dedx) const
Perform the cosine edge correction.
double GetCorrection(int &adc, int layer, int wireID, double doca, double enta, double costheta) const
Get the standard set of corrections.
void CosineCorrection(double costheta, double &dedx) const
Perform the cosine correction.
void RunGainCorrection(double &dedx) const
Perform a run gain correction.
void StandardCorrection(int adc, int layer, int wireID, double doca, double enta, double length, double costheta, double &dedx) const
Perform a standard set of corrections.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.