21#include "TLinearFitter.h"
29 fill(gsl::span(tracks.data(), tracks.size()));
36 mZmatchPairsTFA.clear();
37 mZmatchPairsTFC.clear();
45 mCalibDataTF.
nTrackTF.emplace_back();
48 for (
const auto& track : tracks) {
77 if (track.hasBothSidesClusters()) {
82 auto parOutAtLtr = track.getOuterParam();
85 if (parOutAtLtr.getX() < 220) {
90 float zTrack = parOutAtLtr.getZ();
93 if (mTriggerPos < 0) {
95 const float zOffset = (track.getTime0() + mTriggerPos) * mZbinWidth * mDriftV + 250;
98 parOutAtLtr.setZ(zTrack);
99 }
else if (mTriggerPos > 0) {
100 const float zOffset = mTriggerPos;
103 if (std::abs(zTrack) > 300) {
108 const int side = track.hasCSideClusters();
115 auto ltr = mLaserTracks.
getTrack(laserTrackID);
116 parOutAtLtr.rotateParam(ltr.getAlpha());
117 parOutAtLtr.propagateParamTo(ltr.getX(), mBz);
119 if (ltr.getSide() == 0) {
120 mZmatchPairsA.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
121 mZmatchPairsTFA.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
123 mZmatchPairsC.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
124 mZmatchPairsTFC.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
130 const auto dEdx = track.getdEdx().dEdxTotTPC;
131 mCalibData.
dEdx.emplace_back(dEdx);
132 mCalibDataTF.
dEdx.emplace_back(dEdx);
138 if (mWriteDebugTree) {
140 mDebugStream = std::make_unique<o2::utils::TreeStreamRedirector>(mDebugOutputName.data(),
"recreate");
143 auto writeTrack = track;
144 *mDebugStream <<
"ltrMatch"
145 <<
"tfStart=" << mTFstart
146 <<
"tfEnd=" << mTFend
148 <<
"trOutLtr=" << parOutAtLtr
149 <<
"TPCTracks=" << writeTrack
159 if (!outerParam.rotateParam(phisec)) {
164 side = outerParam.getZ() < 0;
171 float mindist = 1000;
173 const auto outerParamZ = std::abs(outerParam.getZ());
178 if (dist < mindist) {
193 for (
int i = 0;
i < outerParamsInBundle.size(); ++
i) {
194 const auto louterParam = outerParamsInBundle[
i];
196 outerParam.propagateParamTo(louterParam.getX(), mBz);
198 const float dist = std::abs(outerParam.getSnp() - louterParam.getSnp());
199 if (dist < mindist) {
205 if (mindist > 0.01) {
221 const auto xyzGlo =
param.getXYZGlo();
231 const auto xyzGlo =
param.getXYZGlo();
239void CalibLaserTracks::updateParameters()
244 mDriftV = gasParam.DriftV;
245 mZbinWidth = electronicsParam.ZbinWidth;
246 mTOffsetMUS = detpar.DriftTimeOffset * mZbinWidth;
257 const auto sizeAthis = mZmatchPairsA.size();
258 const auto sizeCthis = mZmatchPairsC.size();
259 const auto sizeAother =
other->mZmatchPairsA.size();
260 const auto sizeCother =
other->mZmatchPairsC.size();
262 mZmatchPairsA.insert(mZmatchPairsA.end(),
other->mZmatchPairsA.begin(),
other->mZmatchPairsA.end());
263 mZmatchPairsC.insert(mZmatchPairsC.end(),
other->mZmatchPairsC.begin(),
other->mZmatchPairsC.end());
266 auto& ltrIDsOther =
other->mCalibData.matchedLtrIDs;
267 ltrIDs.insert(ltrIDs.end(), ltrIDsOther.begin(), ltrIDsOther.end());
270 auto& nTrkOther =
other->mCalibData.nTrackTF;
271 nTrk.insert(nTrk.end(), nTrkOther.begin(), nTrkOther.end());
273 auto& dEdx = mCalibData.
dEdx;
274 auto& dEdxOther =
other->mCalibData.dEdx;
275 dEdx.insert(dEdx.end(), dEdxOther.begin(), dEdxOther.end());
283 LOGP(info,
"Merged CalibLaserTracks with mached pairs {} / {} + {} / {} = {} / {} (this +_other A- / C-Side)", sizeAthis, sizeCthis, sizeAother, sizeCother, mZmatchPairsA.size(), mZmatchPairsC.size());
289 LOGP(info,
"Ending time frame {} - {} with {} / {} matched laser tracks (total: {} / {}) on the A / C-Side", mTFstart, mTFend, mZmatchPairsTFA.size(), mZmatchPairsTFC.size(), mZmatchPairsA.size(), mZmatchPairsC.size());
290 fillCalibData(mCalibDataTF, mZmatchPairsTFA, mZmatchPairsTFC);
293 (*mDebugStream) <<
"tfData"
294 <<
"tfStart=" << mTFstart
295 <<
"tfEnf=" << mTFend
296 <<
"zPairsA=" << mZmatchPairsTFA
297 <<
"zPairsC=" << mZmatchPairsTFC
298 <<
"calibData=" << mCalibDataTF
310 fillCalibData(mCalibData, mZmatchPairsA, mZmatchPairsC);
317 (*mDebugStream) <<
"finalData"
318 <<
"zPairsA=" << mZmatchPairsA
319 <<
"zPairsC=" << mZmatchPairsC
320 <<
"calibData=" << mCalibData
323 mDebugStream->Close();
328void CalibLaserTracks::fillCalibData(
LtrCalibData& calibData,
const std::vector<TimePair>& pairsA,
const std::vector<TimePair>& pairsC)
330 auto dvA = fit(pairsA,
"A-Side");
331 auto dvC = fit(pairsC,
"C-Side");
332 calibData.
creationTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
336 calibData.
nTracksA = uint16_t(pairsA.size());
340 calibData.
nTracksC = uint16_t(pairsC.size());
348 if (!trackMatches.size()) {
352 static TLinearFitter
fit(2,
"pol1");
353 fit.StoreData(
false);
356 uint64_t meanTime = 0;
357 double minZrec = 1000;
358 double maxZrec = -1000;
359 for (
const auto& point : trackMatches) {
364 meanTime += point.time;
366 minZrec = std::min(
y, minZrec);
367 maxZrec = std::max(
y, maxZrec);
370 meanTime /= uint64_t(trackMatches.size());
372 const float robustFraction = 0.9;
373 const int minPoints = 6;
375 if (trackMatches.size() <
size_t(minPoints / robustFraction)) {
376 LOGP(warning,
"{} - Not enough points to perform the fit: {} < {}", info, trackMatches.size(),
size_t(minPoints / robustFraction));
379 if (std::abs(maxZrec - minZrec) < 50) {
380 LOGP(warning,
"{} - All points seem to be from one Layer: abs({}cm - {}cm) < 50cm, will not do fitting", info, trackMatches.size(), maxZrec, minZrec);
388 retVal.
x1 = float(fit.GetParameter(0));
389 retVal.x2 = float(fit.GetParameter(1));
398 std::sort(trackMatches.begin(), trackMatches.end(), [](
const auto&
first,
const auto& second) { return first.time < second.time; });
406 "Processed {} TFs from {} - {}; found tracks: {} / {}; fit offsets (cm): {} / {}; T0s (us): {} / {}; dv correction factors: {} / {} for A- / C-Side, reference: {}",
421 "Processed {} TFs from {} - {}; **Not finalized**",
427 "Last processed TF from {} - {}; found tracks: {} / {}; fit offsets (cm): {} / {}; T0s (us): {} / {}; dv correction factors: {} / {} for A- / C-Side, reference: {}",
calibration using laser tracks
General auxilliary methods.
Definition of the parameter class for the detector.
Definition of the parameter class for the detector electronics.
Definition of the parameter class for the detector gas.
static const ParameterGas & Instance()
void finalize()
Finalize full processing.
static float getPhiNearbyLaserRod(const TrackPar ¶m, int side)
calculate phi of nearest laser rod
void endTF()
End processing of this TF.
void fill(const gsl::span< const TrackTPC > tracks)
process all tracks of one TF
static bool hasNearbyLaserRod(const TrackPar ¶m, int side)
check if param is closer to a laser rod than 1/4 of a sector width
void processTrack(const TrackTPC &track)
process single track
void print() const
print information
void merge(const CalibLaserTracks *other)
merge data with other calibration object
void sort(std::vector< TimePair > &trackMatches)
sort TimePoint vectors
int findLaserTrackID(TrackPar track, int side=-1)
TimePair fit(const std::vector< TimePair > &trackMatches, std::string_view info) const
extract DV correction and T0 offset
LaserTrack const & getTrack(int id) const
gsl::span< const LaserTrack > getTracksInBundle(int side, int rod, int bundle)
get span with tracks in one bundle
static constexpr float SectorSpanRad
secotor width in rad
static constexpr int BundlesPerRod
number of micro-mirror bundle per laser rod
static constexpr int NumberOfTracks
Total number of laser tracks.
static constexpr float RodDistancePhi
phi distance of laser Rods
static constexpr int TracksPerBundle
number of micro-mirrors per bundle
static constexpr std::array< float, 4 > CoarseBundleZPos
coarse z-position of the laser bundles
static constexpr std::array< float, 2 > FirstRodPhi
phi pos of first laser rod, A-, C-Side
float to02PiGen(float phi)
Global TPC definitions and constants.
std::vector< uint16_t > nTrackTF
number of laser tracks per TF
float dvCorrectionA
drift velocity correction factor A-Side (inverse multiplicative)
float dvOffsetC
drift velocity trigger offset C-Side
float dvOffsetA
drift velocity trigger offset A-Side
float dvCorrectionC
drift velocity correction factor C-Side (inverse multiplicative)
std::vector< uint16_t > matchedLtrIDs
matched laser track IDs
std::vector< float > dEdx
dE/dx of each track
size_t processedTFs
number of processed TFs with laser track candidates
uint64_t lastTime
last time stamp of processed TFs
uint16_t nTracksC
number of tracks used for C-Side fit
long creationTime
time of creation
uint16_t nTracksA
number of tracks used for A-Side fit
float refTimeOffset
additive time offset reference (\mus)
float refVDrift
reference vdrift for which factor was extracted
uint64_t firstTime
first time stamp of processed TFs
VectorOfTObjectPtrs other