9#include <reconstruction/modules/CDCDedxCorrection/CDCDedxCorrectionModule.h>
20 setDescription(
"Apply hit level corrections to the dE/dx measurements.");
21 addParam(
"relativeCorrections",
m_relative,
"If true, apply corrections relative",
true);
22 addParam(
"momentumCor",
m_momCor,
"Boolean to apply momentum correction",
false);
32 addParam(
"nonlADC",
m_nonlADC,
"Boolean to apply non-linear adc correction",
true);
47 B2WARNING(
"Run gain is zero for this run");
51 for (
unsigned int i = 0; i < c_nSenseWires; ++i) {
53 B2WARNING(
"Wire gain is zero for this wire: " << i);
58 for (
unsigned int i = 0; i < ncosbins; ++i) {
61 B2ERROR(
"Cosine gain is zero for this bin " << i);
66 B2WARNING(
"No hadron correction parameters!");
67 for (
int i = 0; i < 4; ++i)
73 B2INFO(
"Creating CDCGeometryPar object");
76 for (
unsigned int il = 0; il < c_maxNSenseLayers; il++) {
80 for (
unsigned int iw = 0; iw < cdcgeo.
nWiresInLayer(il); ++iw) {
88 if (activewires > 0)
m_lgainavg[il] /= activewires;
101 if (dedxTrack.size() == 0) {
102 B2WARNING(
"No good hits on this track...");
110 int nhits = dedxTrack.size();
111 double costh = dedxTrack.getCosTheta();
112 std::vector<double> newLayerHits;
113 double newLayerDe = 0, newLayerDx = 0;
115 if (costh < TMath::Cos(150.0 * TMath::DegToRad()))
continue;
116 if (costh > TMath::Cos(17.0 * TMath::DegToRad()))
continue;
119 double injtime = dedxTrack.getInjectionTime();
120 double injring = dedxTrack.getInjectionRing();
124 if (injtime == -1 || injring == -1) {
127 injtime =
m_TTDInfo->getTimeSinceLastInjectionInMicroSeconds();
130 dedxTrack.m_injring = injring;
131 dedxTrack.m_injtime = injtime;
134 for (
int i = 0; i < nhits; ++i) {
139 int jadcbase = dedxTrack.getADCBaseCount(i);
140 double jLayer = dedxTrack.getHitLayer(i);
141 double jWire = dedxTrack.getWire(i);
142 double jNDocaRS = dedxTrack.getDocaRS(i) / dedxTrack.getCellHalfWidth(i);
143 double jEntaRS = dedxTrack.getEntaRS(i);
144 double jPath = dedxTrack.getPath(i);
146 double correction = dedxTrack.m_scale * dedxTrack.m_runGain * dedxTrack.m_timeGain * dedxTrack.m_cosCor * dedxTrack.m_cosEdgeCor *
147 dedxTrack.getTwoDCorrection(i) * dedxTrack.getOneDCorrection(i) * dedxTrack.getNonLADCCorrection(i);
148 if (dedxTrack.getWireGain(i) > 0)correction *= dedxTrack.getWireGain(i);
151 double newhitdedx = (
m_relative) ? 1 / correction : 1.0;
152 StandardCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, jPath, costh, injring, injtime, newhitdedx);
153 dedxTrack.setDedx(i, newhitdedx);
161 correction *=
GetCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, costh, injring, injtime);
162 if (!
m_DBWireGains && dedxTrack.getWireGain(i) == 0)correction = 0;
165 correction =
GetCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, costh, injring, injtime);
169 if (correction != 0) {
170 newLayerDe += jadcbase / correction;
174 if (i + 1 < nhits && dedxTrack.getHitLayer(i + 1) == jLayer) {
177 if (newLayerDx != 0)newLayerHits.push_back(newLayerDe / newLayerDx * std::sqrt(1 - costh * costh));
185 &(dedxTrack.m_dedxAvgTruncatedNoSat),
186 &(dedxTrack.m_dedxAvgTruncatedErr),
189 dedxTrack.m_dedxAvgTruncated = dedxTrack.m_dedxAvgTruncatedNoSat;
197 B2INFO(
"CDCDedxCorrectionModule exiting...");
219 if (gain != 0) dedx = dedx / gain;
234 if (gain != 0) dedx = dedx / gain;
242 if (gain != 0) dedx = dedx / gain;
249 if (coscor != 0) dedx = dedx / coscor;
257 if (cosedgecor != 0) dedx = dedx / cosedgecor;
264 dedx =
D2I(costheta,
I2D(costheta, 1.00) / 1.00 * dedx);
268 double costheta,
double ring,
double time,
double& dedx)
const
274 dedx *= adc * std::sqrt(1 - costheta * costheta) / length;
278 if (scale != 0) dedx = dedx / scale;
307 double ring,
double time)
const
309 double correction = 1.0;
321 if (
m_cosineEdge && (costheta <= -0.850 || costheta >= 0.950)) {
331 double absCosTheta = fabs(cosTheta);
333 if (projection == 0) {
334 B2WARNING(
"Something wrong with dE/dx hadron constants!");
338 double chargeDensity = D / projection;
340 double denominator = 1 +
m_hadronpars[1] * chargeDensity;
342 if (denominator == 0) {
343 B2WARNING(
"Something wrong with dE/dx hadron constants!");
347 double I = D *
m_hadronpars[4] * numerator / denominator;
353 double absCosTheta = fabs(cosTheta);
357 B2WARNING(
"Something wrong with dE/dx hadron constants!");
365 if (b == 0 && a == 0) {
366 B2WARNING(
"both a and b coefficiants for hadron correction are 0");
370 double discr = b * b - 4.0 * a * c;
372 B2WARNING(
"negative discriminant; return uncorrectecd value");
376 double D = (a != 0) ? (-b +
sqrt(discr)) / (2.0 * a) : -c / b;
378 B2WARNING(
"D is less 0! will try another solution");
379 D = (a != 0) ? (-b -
sqrt(discr)) / (2.0 * a) : -c / b;
381 B2WARNING(
"D is still less 0! just return uncorrectecd value");
391 const std::vector<double>& dedx)
const
395 std::vector<double> sortedDedx = dedx;
396 std::sort(sortedDedx.begin(), sortedDedx.end());
397 sortedDedx.erase(std::remove(sortedDedx.begin(), sortedDedx.end(), 0), sortedDedx.end());
398 sortedDedx.shrink_to_fit();
400 double truncatedMeanTmp = 0.0;
401 double meanTmp = 0.0;
402 double sumOfSquares = 0.0;
403 int numValuesTrunc = 0;
404 const int numDedx = sortedDedx.size();
409 for (
int i = 0; i < numDedx; i++) {
410 meanTmp += sortedDedx[i];
411 if (i >= lowEdgeTrunc and i < highEdgeTrunc) {
412 truncatedMeanTmp += sortedDedx[i];
413 sumOfSquares += sortedDedx[i] * sortedDedx[i];
421 if (numValuesTrunc != 0) {
422 truncatedMeanTmp /= numValuesTrunc;
424 truncatedMeanTmp = meanTmp;
428 *truncatedMean = truncatedMeanTmp;
430 if (numValuesTrunc > 1) {
431 *truncatedMeanErr =
sqrt(sumOfSquares /
double(numValuesTrunc) - truncatedMeanTmp * truncatedMeanTmp) / double(
434 *truncatedMeanErr = 0;
bool m_twoDCell
boolean to apply 2D correction
double D2I(const double cosTheta, const double D) const
Saturation correction: convert the measured ionization (D) to actual ionization (I)
bool m_runGain
boolean to apply run gains
StoreObjPtr< EventLevelTriggerTimeInfo > m_TTDInfo
Store Object Ptr: EventLevelTriggerTimeInfo.
std::vector< double > m_hadronpars
hadron saturation parameters
bool m_cosineEdge
boolean to apply cosine edge
DBObjPtr< CDCDedxRunGain > m_DBRunGain
Run gain DB object.
bool m_useDBMomCor
boolean to apply momentum correction from DB
void TwoDCorrection(int layer, double doca, double enta, double &dedx) const
Perform a 2D correction.
bool m_momCor
boolean to apply momentum correction
virtual void initialize() override
Initialize the Module.
bool m_scaleCor
boolean to apply scale factor
DBObjPtr< CDCDedxHadronCor > m_DBHadronCor
hadron saturation parameters
virtual void event() override
This method is called for each event.
double m_removeHighest
upper bound for truncated mean
DBObjPtr< CDCDedxCosineEdge > m_DBCosEdgeCor
cosine edge calibration
double I2D(const double cosTheta, const double I) const
Saturation correction: convert the actural ionization (I) to measured ionization (D)
std::array< double, 56 > m_lgainavg
average calibration factor for the layer
void OneDCorrection(int layer, double enta, double &dedx) const
Perform a wire gain correction.
DBObjPtr< CDCDedxADCNonLinearity > m_DBNonlADC
hadron saturation non linearity
DBObjPtr< CDCDedx1DCell > m_DB1DCell
1D correction DB object
virtual void terminate() override
End of the event processing.
bool m_oneDCell
boolean to apply 1D correction
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.
void StandardCorrection(int adc, int layer, int wireID, double doca, double enta, double length, double costheta, double ring, double time, double &dedx) const
Perform a standard set of corrections.
DBObjPtr< CDCDedx2DCell > m_DB2DCell
2D correction DB object
bool m_nonlADC
boolean to apply non linear ADC
bool m_relative
boolean to apply relative or absolute correction
virtual ~CDCDedxCorrectionModule()
Destructor.
DBObjPtr< CDCDedxCosineCor > m_DBCosineCor
Electron saturation correction DB object.
StoreArray< CDCDedxTrack > m_cdcDedxTracks
Store array: CDCDedxTrack.
bool m_timeGain
boolean to apply injection time gains
void CosineEdgeCorrection(double costh, double &dedx) const
Perform the cosine edge correction.
DBObjPtr< CDCDedxWireGain > m_DBWireGains
Wire gain DB object.
void CosineCorrection(double costheta, double &dedx) const
Perform the cosine correction.
void WireGainCorrection(int wireID, double &dedx, int layer) const
Perform a wire gain correction.
CDCDedxCorrectionModule()
Constructor.
bool m_cosineCor
boolean to apply cosine correction
void RunGainCorrection(double &dedx) const
Perform a run gain correction.
double GetCorrection(int &adc, int layer, int wireID, double doca, double enta, double costheta, double ring, double time) const
Get the standard set of corrections.
double m_removeLowest
lower bound for truncated mean
DBObjPtr< CDCDedxInjectionTime > m_DBInjectTime
time gain/reso DB object
DBObjPtr< CDCDedxScaleFactor > m_DBScaleFactor
Scale factor to make electrons ~1.
void TimeGainCorrection(double &dedx, double ring, double time) const
Perform a injection time gain correction.
bool m_wireGain
boolean to apply wire gains
The Class for CDC Geometry Parameters.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
void setDescription(const std::string &description)
Sets the description of the module.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.