Skip to content

Commit 8b67fc8

Browse files
TPC: Adding option to make timegain calib with gausian fits (#13641)
* TPC: Adding option to make timegain calib with gausian fits - setting tighter default momentum range for filtering MIPs to reject kaons and electrons - adding option to write CalibdEdx to local file by converting the boost histogram to a ROOT histogram - lowering minimum dEdx to 10 for better stabillity in A16 other changes: - TPC: make calculation of dedx parallelisable * TPC: Fixing variable names
1 parent 2a20074 commit 8b67fc8

File tree

11 files changed

+424
-75
lines changed

11 files changed

+424
-75
lines changed

DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ class CalibdEdxCorrection
9191

9292
void clear();
9393

94-
void writeToFile(std::string_view fileName) const;
95-
void loadFromFile(std::string_view fileName);
94+
void writeToFile(std::string_view fileName, std::string_view objName = "CalibdEdxCorrection") const;
95+
void loadFromFile(std::string_view fileName, std::string_view objName = "CalibdEdxCorrection");
9696

9797
/// \param outFileName name of the output file
9898
void dumpToTree(const char* outFileName = "calib_dedx.root") const;

DataFormats/Detectors/TPC/src/CalibdEdxCorrection.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ void CalibdEdxCorrection::clear()
3636
mDims = -1;
3737
}
3838

39-
void CalibdEdxCorrection::writeToFile(std::string_view fileName) const
39+
void CalibdEdxCorrection::writeToFile(std::string_view fileName, std::string_view objName) const
4040
{
4141
std::unique_ptr<TFile> file(TFile::Open(fileName.data(), "recreate"));
42-
file->WriteObject(this, "CalibdEdxCorrection");
42+
file->WriteObject(this, objName.data());
4343
}
4444

45-
void CalibdEdxCorrection::loadFromFile(std::string_view fileName)
45+
void CalibdEdxCorrection::loadFromFile(std::string_view fileName, std::string_view objName)
4646
{
4747
std::unique_ptr<TFile> file(TFile::Open(fileName.data()));
48-
auto tmp = file->Get<CalibdEdxCorrection>("CalibdEdxCorrection");
48+
auto tmp = file->Get<CalibdEdxCorrection>(objName.data());
4949
if (tmp != nullptr) {
5050
*this = *tmp;
5151
}

Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class CalculatedEdx
130130
float getMinChargeMaxThreshold() { return mMinChargeMaxThreshold; }
131131

132132
/// fill missing clusters with minimum charge (method=0) or minimum charge/2 (method=1) or Landau (method=2)
133-
void fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method);
133+
void fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method, std::array<std::vector<float>, 5>& chargeTotROC, std::array<std::vector<float>, 5>& chargeMaxROC);
134134

135135
/// get the truncated mean for the input track with the truncation range, charge type, region and corrections
136136
/// the cluster charge is normalized by effective length*gain, you can turn off the normalization by setting all corrections to false
@@ -242,9 +242,6 @@ class CalculatedEdx
242242
CalibdEdxContainer mCalibCont; ///< calibration container
243243
std::unique_ptr<o2::utils::TreeStreamRedirector> mStreamer{nullptr}; ///< debug streamer
244244

245-
std::array<std::vector<float>, 5> mChargeTotROC;
246-
std::array<std::vector<float>, 5> mChargeMaxROC;
247-
248245
CorrectdEdxDistortions mSCdEdxCorrection; ///< for space-charge correction of dE/dx
249246
};
250247

Detectors/TPC/calibration/include/TPCCalibration/CalibdEdx.h

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include <boost/histogram.hpp>
3434
#include "THn.h"
3535

36+
class TLinearFitter;
37+
3638
namespace o2::tpc
3739
{
3840

@@ -74,7 +76,7 @@ class CalibdEdx
7476

7577
/// \param angularBins number of bins for Tgl and Snp
7678
/// \param fitSnp enable Snp correction
77-
CalibdEdx(int dEdxBins = 60, float mindEdx = 20, float maxdEdx = 90, int angularBins = 36, bool fitSnp = false);
79+
CalibdEdx(int dEdxBins = 70, float mindEdx = 10, float maxdEdx = 90, int angularBins = 36, bool fitSnp = false);
7880

7981
void setCuts(const TrackCuts& cuts) { mCuts = cuts; }
8082
void setApplyCuts(bool apply) { mApplyCuts = apply; }
@@ -124,7 +126,8 @@ class CalibdEdx
124126

125127
/// Compute MIP position from dEdx histograms and save result in the correction container.
126128
/// To retrieve the correction call `CalibdEdx::getCalib()`
127-
void finalize();
129+
/// \param useGausFits make gaussian fits of dEdx vs tgl instead of fitting the mean dEdx
130+
void finalize(const bool useGausFits = true);
128131

129132
/// Return calib data histogram
130133
const Hist& getHist() const { return mHist; }
@@ -170,6 +173,17 @@ class CalibdEdx
170173
constexpr static float scaleTgl(float tgl, GEMstack rocType) { return tgl / conf_dedx_corr::TglScale[rocType]; }
171174
constexpr static float recoverTgl(float scaledTgl, GEMstack rocType) { return scaledTgl * conf_dedx_corr::TglScale[rocType]; }
172175

176+
/// dump this object to a file - the boost histogram is converted to a ROOT histogram -
177+
void dumpToFile(const char* outFile, const char* outName) const;
178+
179+
/// read the object from a file
180+
static CalibdEdx readFromFile(const char* inFile, const char* inName);
181+
182+
/// set lower and upper range in units of sigma which are used for the gaussian fits
183+
/// \param lowerSigma low sigma range
184+
/// \param upperSigma upper sigma range
185+
void setSigmaFitRange(const float lowerSigma, const float upperSigma);
186+
173187
private:
174188
// ATTENTION: Adjust copy constructor
175189
bool mFitSnp{};
@@ -182,15 +196,26 @@ class CalibdEdx
182196
float mFitLowCutFactor = 1.5; ///< dEdx cut multiplier for the lower dE/dx range
183197
int mFitPasses = 3; ///< number of fit passes used to remove electron tracks
184198
TFIDInfo mTFID{}; ///< current TFID
199+
float mSigmaUpper = 1.; ///< mSigma*sigma_gaus used for cutting electrons in case gaussian fits are performed
200+
float mSigmaLower = 1.5; ///< mSigma*sigma_gaus used for cutting electrons in case gaussian fits are performed
185201

186-
Hist mHist; ///< dEdx multidimensional histogram
202+
Hist mHist; ///<! dEdx multidimensional histogram
187203
CalibdEdxCorrection mCalib{}; ///< Calibration output
188204
CalibdEdxCorrection mCalibIn{}; ///< Calibration output
189205

190206
o2::base::Propagator::MatCorrType mMatType{}; ///< material type for track propagation
191207

192-
std::unique_ptr<o2::utils::TreeStreamRedirector> mDebugOutputStreamer; ///< Debug output streamer
193-
ClassDefNV(CalibdEdx, 4);
208+
std::unique_ptr<o2::utils::TreeStreamRedirector> mDebugOutputStreamer; ///<! Debug output streamer
209+
210+
THnF* getTHnF() const;
211+
212+
/// make fits of dEdx as a function of tgl and perform the calibration fit
213+
void fitHistGaus(TLinearFitter& fitter, CalibdEdxCorrection& corr, const CalibdEdxCorrection* stackMean = nullptr);
214+
215+
/// set boost histogram containing the data from root histogram
216+
void setFromRootHist(const THnF* hist);
217+
218+
ClassDefNV(CalibdEdx, 5);
194219
};
195220

196221
} // namespace o2::tpc

Detectors/TPC/calibration/include/TPCCalibration/CalibratordEdx.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class CalibratordEdx final : public o2::calibration::TimeSlotCalibration<o2::tpc
6060
void setApplyCuts(bool apply) { mApplyCuts = apply; }
6161
void setElectronCut(std::tuple<float, int, float> values) { mElectronCut = values; }
6262
void setMaterialType(o2::base::Propagator::MatCorrType materialType) { mMatType = materialType; }
63+
void setMakeGaussianFits(const bool makeGaussianFits) { mMakeGaussianFits = makeGaussianFits; }
6364

6465
/// \brief Check if there are enough data to compute the calibration.
6566
/// \return false if any of the histograms has less entries than mMinEntries
@@ -117,14 +118,15 @@ class CalibratordEdx final : public o2::calibration::TimeSlotCalibration<o2::tpc
117118
std::tuple<float, int, float> mElectronCut{}; ///< Values passed to CalibdEdx::setElectronCut
118119
TrackCuts mCuts; ///< Cut object
119120
o2::base::Propagator::MatCorrType mMatType{}; ///< material type for track propagation
121+
bool mMakeGaussianFits{}; ///< fit mean of gaussian fits instead of mean dedx
120122

121123
TFinterval mTFIntervals; ///< start and end time frame IDs of each calibration time slots
122124
TimeInterval mTimeIntervals; ///< start and end times of each calibration time slots
123125
CalibVector mCalibs; ///< vector of MIP positions, each element is filled in "process" when we finalize one slot (multiple can be finalized during the same "process", which is why we have a vector. Each element is to be considered the output of the device
124126

125127
std::unique_ptr<o2::utils::TreeStreamRedirector> mDebugOutputStreamer; ///< Debug output streamer
126128

127-
ClassDefOverride(CalibratordEdx, 2);
129+
ClassDefOverride(CalibratordEdx, 3);
128130
};
129131

130132
} // namespace o2::tpc

Detectors/TPC/calibration/src/CalculatedEdx.cxx

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void CalculatedEdx::setRefit(const unsigned int nHbfPerTf)
5353
mRefit = std::make_unique<o2::gpu::GPUO2InterfaceRefit>(mClusterIndex, &mTPCCorrMapsHelper, mFieldNominalGPUBz, mTPCTrackClIdxVecInput->data(), nHbfPerTf, mTPCRefitterShMap.data(), mTPCRefitterOccMap.data(), mTPCRefitterOccMap.size());
5454
}
5555

56-
void CalculatedEdx::fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method)
56+
void CalculatedEdx::fillMissingClusters(int missingClusters[4], float minChargeTot, float minChargeMax, int method, std::array<std::vector<float>, 5>& chargeTotROC, std::array<std::vector<float>, 5>& chargeMaxROC)
5757
{
5858
if (method != 0 && method != 1) {
5959
LOGP(info, "Unrecognized subthreshold cluster treatment. Not adding virtual charges to the track!");
@@ -65,11 +65,11 @@ void CalculatedEdx::fillMissingClusters(int missingClusters[4], float minChargeT
6565
float chargeTot = (method == 1) ? minChargeTot / 2.f : minChargeTot;
6666
float chargeMax = (method == 1) ? minChargeMax / 2.f : minChargeMax;
6767

68-
mChargeTotROC[roc].emplace_back(chargeTot);
69-
mChargeTotROC[4].emplace_back(chargeTot);
68+
chargeTotROC[roc].emplace_back(chargeTot);
69+
chargeTotROC[4].emplace_back(chargeTot);
7070

71-
mChargeMaxROC[roc].emplace_back(chargeMax);
72-
mChargeMaxROC[4].emplace_back(chargeMax);
71+
chargeMaxROC[roc].emplace_back(chargeMax);
72+
chargeMaxROC[4].emplace_back(chargeMax);
7373
}
7474
}
7575
}
@@ -82,17 +82,13 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl
8282
int nClsROC[4] = {0, 0, 0, 0};
8383
int nClsSubThreshROC[4] = {0, 0, 0, 0};
8484

85-
mChargeTotROC[0].clear();
86-
mChargeTotROC[1].clear();
87-
mChargeTotROC[2].clear();
88-
mChargeTotROC[3].clear();
89-
mChargeTotROC[4].clear();
90-
91-
mChargeMaxROC[0].clear();
92-
mChargeMaxROC[1].clear();
93-
mChargeMaxROC[2].clear();
94-
mChargeMaxROC[3].clear();
95-
mChargeMaxROC[4].clear();
85+
const int nType = 5;
86+
std::array<std::vector<float>, nType> chargeTotROC;
87+
std::array<std::vector<float>, nType> chargeMaxROC;
88+
for (int i = 0; i < nType; ++i) {
89+
chargeTotROC[i].reserve(Mapper::PADROWS);
90+
chargeMaxROC[i].reserve(Mapper::PADROWS);
91+
}
9692

9793
// debug vectors
9894
std::vector<int> excludeClVector;
@@ -356,25 +352,25 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl
356352
}
357353

358354
if (stack == GEMstack::IROCgem) {
359-
mChargeTotROC[0].emplace_back(chargeTot);
360-
mChargeMaxROC[0].emplace_back(chargeMax);
355+
chargeTotROC[0].emplace_back(chargeTot);
356+
chargeMaxROC[0].emplace_back(chargeMax);
361357
nClsROC[0]++;
362358
} else if (stack == GEMstack::OROC1gem) {
363-
mChargeTotROC[1].emplace_back(chargeTot);
364-
mChargeMaxROC[1].emplace_back(chargeMax);
359+
chargeTotROC[1].emplace_back(chargeTot);
360+
chargeMaxROC[1].emplace_back(chargeMax);
365361
nClsROC[1]++;
366362
} else if (stack == GEMstack::OROC2gem) {
367-
mChargeTotROC[2].emplace_back(chargeTot);
368-
mChargeMaxROC[2].emplace_back(chargeMax);
363+
chargeTotROC[2].emplace_back(chargeTot);
364+
chargeMaxROC[2].emplace_back(chargeMax);
369365
nClsROC[2]++;
370366
} else if (stack == GEMstack::OROC3gem) {
371-
mChargeTotROC[3].emplace_back(chargeTot);
372-
mChargeMaxROC[3].emplace_back(chargeMax);
367+
chargeTotROC[3].emplace_back(chargeTot);
368+
chargeMaxROC[3].emplace_back(chargeMax);
373369
nClsROC[3]++;
374370
};
375371

376-
mChargeTotROC[4].emplace_back(chargeTot);
377-
mChargeMaxROC[4].emplace_back(chargeMax);
372+
chargeTotROC[4].emplace_back(chargeTot);
373+
chargeMaxROC[4].emplace_back(chargeMax);
378374

379375
// for debugging
380376
if (mDebug) {
@@ -418,7 +414,7 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl
418414

419415
// fill subthreshold clusters if not excluded
420416
if (((clusterMask & ClusterFlags::ExcludeSubthresholdCl) == ClusterFlags::None)) {
421-
fillMissingClusters(nClsSubThreshROC, minChargeTot, minChargeMax, subthresholdMethod);
417+
fillMissingClusters(nClsSubThreshROC, minChargeTot, minChargeMax, subthresholdMethod, chargeTotROC, chargeMaxROC);
422418
}
423419
} else {
424420
output.NHitsIROC = nClsROC[0];
@@ -428,21 +424,21 @@ void CalculatedEdx::calculatedEdx(o2::tpc::TrackTPC& track, dEdxInfo& output, fl
428424
}
429425

430426
// copy corrected cluster charges
431-
auto chargeTotVector = mChargeTotROC[4];
432-
auto chargeMaxVector = mChargeMaxROC[4];
427+
auto chargeTotVector = mDebug ? chargeTotROC[4] : std::vector<float>();
428+
auto chargeMaxVector = mDebug ? chargeMaxROC[4] : std::vector<float>();
433429

434430
// calculate dEdx
435-
output.dEdxTotIROC = getTruncMean(mChargeTotROC[0], low, high);
436-
output.dEdxTotOROC1 = getTruncMean(mChargeTotROC[1], low, high);
437-
output.dEdxTotOROC2 = getTruncMean(mChargeTotROC[2], low, high);
438-
output.dEdxTotOROC3 = getTruncMean(mChargeTotROC[3], low, high);
439-
output.dEdxTotTPC = getTruncMean(mChargeTotROC[4], low, high);
440-
441-
output.dEdxMaxIROC = getTruncMean(mChargeMaxROC[0], low, high);
442-
output.dEdxMaxOROC1 = getTruncMean(mChargeMaxROC[1], low, high);
443-
output.dEdxMaxOROC2 = getTruncMean(mChargeMaxROC[2], low, high);
444-
output.dEdxMaxOROC3 = getTruncMean(mChargeMaxROC[3], low, high);
445-
output.dEdxMaxTPC = getTruncMean(mChargeMaxROC[4], low, high);
431+
output.dEdxTotIROC = getTruncMean(chargeTotROC[0], low, high);
432+
output.dEdxTotOROC1 = getTruncMean(chargeTotROC[1], low, high);
433+
output.dEdxTotOROC2 = getTruncMean(chargeTotROC[2], low, high);
434+
output.dEdxTotOROC3 = getTruncMean(chargeTotROC[3], low, high);
435+
output.dEdxTotTPC = getTruncMean(chargeTotROC[4], low, high);
436+
437+
output.dEdxMaxIROC = getTruncMean(chargeMaxROC[0], low, high);
438+
output.dEdxMaxOROC1 = getTruncMean(chargeMaxROC[1], low, high);
439+
output.dEdxMaxOROC2 = getTruncMean(chargeMaxROC[2], low, high);
440+
output.dEdxMaxOROC3 = getTruncMean(chargeMaxROC[3], low, high);
441+
output.dEdxMaxTPC = getTruncMean(chargeMaxROC[4], low, high);
446442

447443
// for debugging
448444
if (mDebug) {

0 commit comments

Comments
 (0)