9#include <cdc/modules/CDCDedxCorrection/CDCDedxCorrectionModule.h>
11#include <cdc/geometry/CDCGeometryPar.h>
23 setDescription(
"Apply hit level corrections to the dE/dx measurements.");
24 addParam(
"relativeCorrections",
m_relative,
"If true, apply corrections relative",
true);
25 addParam(
"momentumCor",
m_momCor,
"Boolean to apply momentum correction",
false);
35 addParam(
"nonlADC",
m_nonlADC,
"Boolean to apply non-linear adc correction",
true);
50 B2WARNING(
"Run gain is zero for this run");
54 for (
unsigned int i = 0; i < c_nSenseWires; ++i) {
56 B2WARNING(
"Wire gain is zero for this wire: " << i);
60 for (
unsigned int il = 0; il < c_maxNSenseLayers; ++il) {
63 for (
unsigned int i = 0; i < ncosbins; ++i) {
66 B2ERROR(
"Cosine gain is zero for this bin " << i);
72 B2WARNING(
"No hadron correction parameters!");
73 for (
int i = 0; i < 4; ++i)
79 B2INFO(
"Creating CDCGeometryPar object");
82 for (
unsigned int il = 0; il < c_maxNSenseLayers; il++) {
86 for (
unsigned int iw = 0; iw < cdcgeo.
nWiresInLayer(il); ++iw) {
94 if (activewires > 0)
m_lgainavg[il] /= activewires;
107 if (dedxTrack.size() == 0) {
108 B2WARNING(
"No good hits on this track...");
116 int nhits = dedxTrack.size();
117 double costh = dedxTrack.getCosTheta();
118 std::vector<double> newLayerHits;
119 double newLayerDe = 0, newLayerDx = 0;
121 if (costh < TMath::Cos(150.0 * TMath::DegToRad()))
continue;
122 if (costh > TMath::Cos(17.0 * TMath::DegToRad()))
continue;
125 double injtime = dedxTrack.getInjectionTime();
126 double injring = dedxTrack.getInjectionRing();
128 for (
int i = 0; i < nhits; ++i) {
133 int jadcbase = dedxTrack.getADCBaseCount(i);
134 double jLayer = dedxTrack.getHitLayer(i);
135 double jWire = dedxTrack.getWire(i);
136 double jNDocaRS = dedxTrack.getDocaRS(i) / dedxTrack.getCellHalfWidth(i);
137 double jEntaRS = dedxTrack.getEntaRS(i);
138 double jPath = dedxTrack.getPath(i);
140 double correction = dedxTrack.m_scale * dedxTrack.m_runGain * dedxTrack.m_timeGain * dedxTrack.getCosineCorrection(
141 i) * dedxTrack.m_cosEdgeCor *
142 dedxTrack.getTwoDCorrection(i) * dedxTrack.getOneDCorrection(i) * dedxTrack.getNonLADCCorrection(i);
143 if (dedxTrack.getWireGain(i) > 0)correction *= dedxTrack.getWireGain(i);
146 double newhitdedx = (
m_relative) ? 1 / correction : 1.0;
147 StandardCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, jPath, costh, injring, injtime, newhitdedx);
148 dedxTrack.setDedx(i, newhitdedx);
156 correction *=
GetCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, costh, injring, injtime);
157 if (!
m_DBWireGains && dedxTrack.getWireGain(i) == 0)correction = 0;
160 correction =
GetCorrection(jadcbase, jLayer, jWire, jNDocaRS, jEntaRS, costh, injring, injtime);
164 if (correction != 0) {
165 newLayerDe += jadcbase / correction;
169 if (i + 1 < nhits && dedxTrack.getHitLayer(i + 1) == jLayer) {
172 if (newLayerDx != 0)newLayerHits.push_back(newLayerDe / newLayerDx * std::sqrt(1 - costh * costh));
180 &(dedxTrack.m_dedxAvgTruncatedNoSat),
181 &(dedxTrack.m_dedxAvgTruncatedErr),
184 dedxTrack.m_dedxAvgTruncated = dedxTrack.m_dedxAvgTruncatedNoSat;
192 B2INFO(
"CDCDedxCorrectionModule exiting...");
214 if (gain != 0) dedx = dedx / gain;
229 if (gain != 0) dedx = dedx / gain;
237 if (gain != 0) dedx = dedx / gain;
244 if (coscor != 0) dedx = dedx / coscor;
252 if (cosedgecor != 0) dedx = dedx / cosedgecor;
259 dedx =
D2I(costheta,
I2D(costheta, 1.00) / 1.00 * dedx);
263 double costheta,
double ring,
double time,
double& dedx)
const
269 dedx *= adc * std::sqrt(1 - costheta * costheta) / length;
273 if (scale != 0) dedx = dedx / scale;
302 double ring,
double time)
const
304 double correction = 1.0;
316 if (
m_cosineEdge && (costheta <= -0.850 || costheta >= 0.950)) {
326 double absCosTheta = fabs(cosTheta);
328 if (projection == 0) {
329 B2WARNING(
"Something wrong with dE/dx hadron constants!");
333 double chargeDensity = D / projection;
335 double denominator = 1 +
m_hadronpars[1] * chargeDensity;
337 if (denominator == 0) {
338 B2WARNING(
"Something wrong with dE/dx hadron constants!");
342 double I = D *
m_hadronpars[4] * numerator / denominator;
348 double absCosTheta = fabs(cosTheta);
352 B2WARNING(
"Something wrong with dE/dx hadron constants!");
360 if (b == 0 && a == 0) {
361 B2WARNING(
"both a and b coefficiants for hadron correction are 0");
365 double discr = b * b - 4.0 * a * c;
367 B2WARNING(
"negative discriminant; return uncorrectecd value");
371 double D = (a != 0) ? (-b +
sqrt(discr)) / (2.0 * a) : -c / b;
373 B2WARNING(
"D is less 0! will try another solution");
374 D = (a != 0) ? (-b -
sqrt(discr)) / (2.0 * a) : -c / b;
376 B2WARNING(
"D is still less 0! just return uncorrectecd value");
386 const std::vector<double>& dedx)
const
390 std::vector<double> sortedDedx = dedx;
391 std::sort(sortedDedx.begin(), sortedDedx.end());
392 sortedDedx.erase(std::remove(sortedDedx.begin(), sortedDedx.end(), 0), sortedDedx.end());
393 sortedDedx.shrink_to_fit();
395 double truncatedMeanTmp = 0.0;
396 double meanTmp = 0.0;
397 double sumOfSquares = 0.0;
398 int numValuesTrunc = 0;
399 const int numDedx = sortedDedx.size();
404 for (
int i = 0; i < numDedx; i++) {
405 meanTmp += sortedDedx[i];
406 if (i >= lowEdgeTrunc and i < highEdgeTrunc) {
407 truncatedMeanTmp += sortedDedx[i];
408 sumOfSquares += sortedDedx[i] * sortedDedx[i];
416 if (numValuesTrunc != 0) {
417 truncatedMeanTmp /= numValuesTrunc;
419 truncatedMeanTmp = meanTmp;
423 *truncatedMean = truncatedMeanTmp;
425 if (numValuesTrunc > 1) {
426 *truncatedMeanErr =
sqrt(sumOfSquares /
double(numValuesTrunc) - truncatedMeanTmp * truncatedMeanTmp) / double(
429 *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
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 actual 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
void CosineCorrection(unsigned int superlayer, double costheta, double &dedx) const
Perform the cosine correction.
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 WireGainCorrection(int wireID, double &dedx, int layer) const
Perform a wire gain correction.
CDCDedxCorrectionModule()
Constructor.
~CDCDedxCorrectionModule() override
Destructor.
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.