22#include "TStopwatch.h"
43 auto xDir = TMath::Cos(impactAng);
44 auto yDir = TMath::Sin(impactAng);
45 double slope = (TMath::Abs(xDir) < 1e-7) ? 1e7 : yDir / xDir;
46 auto laTan = TMath::Tan(laFit);
47 double lorentzSlope = (TMath::Abs(laTan) < 1e-7) ? 1e7 : 1. / laTan;
54 double xLorentzAnodeHit =
mAnodePlane / lorentzSlope;
58 double xLorentzDriftHit = xLorentzAnodeHit;
65 double impactAngleSim = TMath::ATan2(yAnodeHit, xAnodeHit);
67 double deltaXLorentzDriftHit = xAnodeHit - xLorentzDriftHitPreCorr;
68 double deltaYLorentzDriftHit = yAnodeHit - yLorentzDriftHitPreCorr;
69 double impactAngleRec = TMath::ATan2(deltaYLorentzDriftHit, deltaXLorentzDriftHit);
71 double deltaAngle = (impactAngleRec - impactAngleSim);
80 auto impactAngle = (
profiles[
currDet]->GetBinCenter(iBin) + 90) * TMath::DegToRad();
81 auto deltaAlpha =
profiles[
currDet]->GetBinContent(iBin) * TMath::DegToRad();
82 if (TMath::Abs(deltaAlpha) < 1e-7) {
89 sum += TMath::Power(deltaAlphaSim - deltaAlpha, 2);
100 mObjectVector.clear();
113 float lorentzAngleAvg = -1.f;
114 if (TMath::Abs(bz - 2) < 0.1f) {
115 lorentzAngleAvg = 3.f;
117 if (TMath::Abs(bz + 2) < 0.1f) {
118 lorentzAngleAvg = -5.f;
120 if (TMath::Abs(bz - 5) < 0.1f) {
121 lorentzAngleAvg = 7.f;
123 if (TMath::Abs(bz + 5) < 0.1f) {
124 lorentzAngleAvg = -9.f;
127 LOGP(info,
"b field: {} lorentz angle start: {}", bz, lorentzAngleAvg);
131 mFitFunctor.
mAnodePlane = GeometryBase::camHght() / (2.f * 100.f);
132 for (
int iDet = 0; iDet <
MAXCHAMBER; ++iDet) {
136 mFitter.SetFCN<
FitFunctor>(2, mFitFunctor, mParamsStart);
141 ROOT::Math::MinimizerOptions opt;
142 opt.SetMinimizerType(
"Minuit2");
143 opt.SetMinimizerAlgorithm(
"Migrad");
144 opt.SetPrintLevel(0);
145 opt.SetMaxFunctionCalls(1'000);
146 opt.SetTolerance(.001);
147 mFitter.Config().SetMinimizerOptions(opt);
151 mOutTree->Branch(
"lorentzAngle", &mFitFunctor.
laPreCorr);
152 mOutTree->Branch(
"vDrift", &mFitFunctor.
vdPreCorr);
153 for (
int iDet = 0; iDet <
MAXCHAMBER; ++iDet) {
154 mOutTree->Branch(fmt::format(
"residuals_{:d}", iDet).c_str(), mFitFunctor.
profiles[iDet].get());
166 std::string
msg =
"Default Object";
168 for (
int iDet = 0; iDet <
MAXCHAMBER; ++iDet) {
170 dataCalVdriftExB->getExB(iDet) !=
EXBDEFAULT) {
171 msg =
"Previous Object";
175 LOG(info) <<
"Calibrator: From CCDB retrieved " <<
msg;
178 for (
int iDet = 0; iDet <
MAXCHAMBER; ++iDet) {
179 mFitFunctor.
laPreCorr[iDet] = dataCalVdriftExB->getExB(iDet);
180 mFitFunctor.
vdPreCorr[iDet] = dataCalVdriftExB->getVdrift(iDet);
190 auto laFitResults = mFitFunctor.
laPreCorr;
191 auto vdFitResults = mFitFunctor.
vdPreCorr;
193 for (
int iDet = 0; iDet <
MAXCHAMBER; ++iDet) {
195 mFitFunctor.
profiles[iDet]->Reset();
199 auto angleDiffSum = residHists->getHistogramEntry(iDet *
NBINSANGLEDIFF + iBin);
200 auto nEntries = residHists->getBinCount(iDet *
NBINSANGLEDIFF + iBin);
201 sumEntries += nEntries;
207 if (sumEntries < mMinEntriesChamber) {
208 LOGF(
debug,
"Chamber %d did not reach minimum amount of entries for refit: %d", iDet, sumEntries);
211 float laPreCorrTemp = mFitFunctor.
laPreCorr[iDet];
212 float vdPreCorrTemp = mFitFunctor.
vdPreCorr[iDet];
221 auto fitResult = mFitter.Result();
222 if (fitResult.MinFcnValue() > 0.03) {
223 LOGF(
debug,
"Chamber %d fit did not converge properly, minimization value too high: %f", iDet, fitResult.MinFcnValue());
225 mFitFunctor.
laPreCorr[iDet] = laPreCorrTemp;
226 mFitFunctor.
vdPreCorr[iDet] = vdPreCorrTemp;
231 LOGF(
debug,
"Fit result for chamber %i: vd=%f, la=%f, minimizer value=%f", iDet, vdFitResults[iDet], laFitResults[iDet] * TMath::RadToDeg(), fitResult.MinFcnValue());
233 mFitFunctor.
laPreCorr[iDet] = laFitResults[iDet];
234 mFitFunctor.
vdPreCorr[iDet] = vdFitResults[iDet];
237 LOGF(info,
"Done fitting angular residual histograms. CPU time: %f, real time: %f", timer.CpuTime(), timer.RealTime());
242 for (
int iDet = 0; iDet <
MAXCHAMBER; ++iDet) {
243 LOGF(
debug,
"Fit result for chamber %i: vd=%f, la=%f", iDet, vdFitResults[iDet], laFitResults[iDet] * TMath::RadToDeg());
249 for (
int iDet = 0; iDet <
MAXCHAMBER; ++iDet) {
252 calObject.
setVdrift(iDet, vdFitResults[iDet]);
253 calObject.
setExB(iDet, laFitResults[iDet]);
257 std::map<std::string, std::string> metadata;
260 mObjectVector.push_back(calObject);
266 auto& slot = front ? container.emplace_front(tStart, tEnd) : container.emplace_back(tStart, tEnd);
267 slot.setContainer(std::make_unique<AngularResidHistos>());
273 mEnableOutput =
true;
274 mOutFile = std::make_unique<TFile>(
"trd_calibVdriftExB.root",
"RECREATE");
275 if (mOutFile->IsZombie()) {
276 LOG(error) <<
"Failed to create output file!";
277 mEnableOutput =
false;
280 mOutTree = std::make_unique<TTree>(
"calib",
"VDrift&ExB calibration");
281 LOG(info) <<
"Created output file trd_calibVdriftExB.root";
286 if (!mEnableOutput) {
296 }
catch (std::exception
const& e) {
297 LOG(error) <<
"Failed to write calibration data file, reason: " << e.what();
300 mEnableOutput =
false;
TimeSlot-based calibration of vDrift and ExB.
Definition of the Names Generator class.
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
o2::calibration::TFType TFType
long getStartTimeMS() const
const Container * getContainer() const
static std::string generateFileName(const std::string &inp)
static constexpr long HOUR
static constexpr long SECOND
InputRecord & inputs()
The inputs associated with this processing context.
void setExB(int iDet, float exb)
void setVdrift(int iDet, float vd)
void retrievePrev(o2::framework::ProcessingContext &pc)
void finalizeSlot(Slot &slot) final
Slot & emplaceNewSlot(bool front, TFType tStart, TFType tEnd) final
float sum(float s, o2::dcs::DataPointValue v)
constexpr double VDRIFTMIN
min value for vDrift
constexpr double EXBDEFAULT
default value for LorentzAngle
constexpr double EXBMAX
max value for LorentzAngle
constexpr int MAXCHAMBER
the maximum number of installed chambers
constexpr double EXBMIN
min value for LorentzAngle
constexpr double VDRIFTMAX
max value for vDrift
constexpr double VDRIFTDEFAULT
default value for vDrift
constexpr int NBINSANGLEDIFF
the number of bins for the track angle used for the vDrift and ExB calibration based on the tracking
constexpr float MAXIMPACTANGLE
the maximum impact angle for tracks relative to the TRD detector plane to be considered for vDrift an...
std::array< double, constants::MAXCHAMBER > laPreCorr
LorentzAngle from previous Run.
double mAnodePlane
distance of the TRD anode plane from the drift cathodes in m
int currDet
the current TRD chamber number
double operator()(const double *par) const
std::array< std::unique_ptr< TProfile >, constants::MAXCHAMBER > profiles
profile histograms for each TRD chamber
double calculateDeltaAlphaSim(double vdFit, double laFit, double impactAng) const
std::array< double, constants::MAXCHAMBER > vdPreCorr
vDrift from previous Run
float upperBoundAngleFit
upper bound for fit angle
float lowerBoundAngleFit
lower bound for fit angle
static std::string getClassName(const T &obj)
get the class name of the object
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
uint64_t const void const *restrict const msg