21#include "TLinearFitter.h"
29 fill(gsl::span(tracks.data(), tracks.size()), tp);
36 mZmatchPairsTFA.clear();
37 mZmatchPairsTFC.clear();
45 mCalibDataTF.
nTrackTF.emplace_back();
48 for (
const auto& track : tracks) {
80 if (track.hasBothSidesClusters()) {
85 auto parOutAtLtr = track.getOuterParam();
88 if (parOutAtLtr.getX() < 220) {
93 float zTrack = parOutAtLtr.getZ();
96 if (mTriggerPos < 0) {
98 const float zOffset = (track.getTime0() + mTriggerPos) * mZbinWidth * mDriftV + 250;
101 parOutAtLtr.setZ(zTrack);
102 }
else if (mTriggerPos > 0) {
103 const float zOffset = mTriggerPos;
106 if (std::abs(zTrack) > 300) {
111 const int side = track.hasCSideClusters();
118 auto ltr = mLaserTracks.
getTrack(laserTrackID);
119 parOutAtLtr.rotateParam(ltr.getAlpha());
120 parOutAtLtr.propagateParamTo(ltr.getX(), mBz);
122 if (ltr.getSide() == 0) {
123 mZmatchPairsA.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
124 mZmatchPairsTFA.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
126 mZmatchPairsC.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
127 mZmatchPairsTFC.emplace_back(
TimePair{ltr.getZ(), parOutAtLtr.getZ(), mTFstart});
133 const auto dEdx = track.getdEdx().dEdxTotTPC;
134 mCalibData.
dEdx.emplace_back(dEdx);
135 mCalibDataTF.
dEdx.emplace_back(dEdx);
141 if (mWriteDebugTree) {
143 mDebugStream = std::make_unique<o2::utils::TreeStreamRedirector>(mDebugOutputName.data(),
"recreate");
146 auto writeTrack = track;
147 *mDebugStream <<
"ltrMatch"
148 <<
"tfStart=" << mTFstart
149 <<
"tfEnd=" << mTFend
151 <<
"trOutLtr=" << parOutAtLtr
152 <<
"TPCTracks=" << writeTrack
153 <<
"mDriftV=" << mDriftV
154 <<
"laserTrackID=" << laserTrackID
164 if (!outerParam.rotateParam(phisec)) {
169 side = outerParam.getZ() < 0;
176 float mindist = 1000;
178 const auto outerParamZ = std::abs(outerParam.getZ());
183 if (dist < mindist) {
198 for (
int i = 0;
i < outerParamsInBundle.size(); ++
i) {
199 const auto louterParam = outerParamsInBundle[
i];
201 outerParam.propagateParamTo(louterParam.getX(), mBz);
203 const float dist = std::abs(outerParam.getSnp() - louterParam.getSnp());
204 if (dist < mindist) {
210 if (mindist > 0.01) {
226 const auto xyzGlo =
param.getXYZGlo();
236 const auto xyzGlo =
param.getXYZGlo();
244void CalibLaserTracks::updateParameters()
249 mDriftV = gasParam.DriftV;
250 mZbinWidth = electronicsParam.ZbinWidth;
251 mTOffsetMUS = detpar.DriftTimeOffset * mZbinWidth;
262 const auto sizeAthis = mZmatchPairsA.size();
263 const auto sizeCthis = mZmatchPairsC.size();
264 const auto sizeAother =
other->mZmatchPairsA.size();
265 const auto sizeCother =
other->mZmatchPairsC.size();
267 mZmatchPairsA.insert(mZmatchPairsA.end(),
other->mZmatchPairsA.begin(),
other->mZmatchPairsA.end());
268 mZmatchPairsC.insert(mZmatchPairsC.end(),
other->mZmatchPairsC.begin(),
other->mZmatchPairsC.end());
271 auto& ltrIDsOther =
other->mCalibData.matchedLtrIDs;
272 ltrIDs.insert(ltrIDs.end(), ltrIDsOther.begin(), ltrIDsOther.end());
275 auto& nTrkOther =
other->mCalibData.nTrackTF;
276 nTrk.insert(nTrk.end(), nTrkOther.begin(), nTrkOther.end());
278 auto& dEdx = mCalibData.
dEdx;
279 auto& dEdxOther =
other->mCalibData.dEdx;
280 dEdx.insert(dEdx.end(), dEdxOther.begin(), dEdxOther.end());
285 if ((mAvgTP > 0) && (
other->mAvgTP > 0)) {
286 mAvgTP = (mAvgTP +
other->mAvgTP) / 2.0;
287 }
else if (
other->mAvgTP > 0) {
288 mAvgTP =
other->mAvgTP;
291 if ((mAvgDriftV > 0) && (
other->mAvgDriftV > 0)) {
292 mAvgDriftV = (mAvgDriftV +
other->mAvgDriftV) / 2.0;
293 }
else if (
other->mAvgDriftV > 0) {
294 mAvgDriftV =
other->mAvgDriftV;
300 LOGP(info,
"Merged CalibLaserTracks with mached pairs {} / {} + {} / {} = {} / {} (this +_other A- / C-Side)", sizeAthis, sizeCthis, sizeAother, sizeCother, mZmatchPairsA.size(), mZmatchPairsC.size());
306 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());
307 fillCalibData(mCalibDataTF, mZmatchPairsTFA, mZmatchPairsTFC);
310 (*mDebugStream) <<
"tfData"
311 <<
"tfStart=" << mTFstart
312 <<
"tfEnf=" << mTFend
313 <<
"zPairsA=" << mZmatchPairsTFA
314 <<
"zPairsC=" << mZmatchPairsTFC
315 <<
"calibData=" << mCalibDataTF
316 <<
"mDriftV=" << mDriftV
328 fillCalibData(mCalibData, mZmatchPairsA, mZmatchPairsC);
335 (*mDebugStream) <<
"finalData"
336 <<
"zPairsA=" << mZmatchPairsA
337 <<
"zPairsC=" << mZmatchPairsC
338 <<
"calibData=" << mCalibData
341 mDebugStream->Close();
346void CalibLaserTracks::fillCalibData(
LtrCalibData& calibData,
const std::vector<TimePair>& pairsA,
const std::vector<TimePair>& pairsC)
348 auto dvA = fit(pairsA,
"A-Side");
349 auto dvC = fit(pairsC,
"C-Side");
350 calibData.
creationTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
354 calibData.
nTracksA = uint16_t(pairsA.size());
358 calibData.
nTracksC = uint16_t(pairsC.size());
361 calibData.
tp = mAvgTP;
367 if (!trackMatches.size()) {
371 static TLinearFitter
fit(2,
"pol1");
372 fit.StoreData(
false);
375 uint64_t meanTime = 0;
376 double minZrec = 1000;
377 double maxZrec = -1000;
378 for (
const auto& point : trackMatches) {
383 meanTime += point.time;
385 minZrec = std::min(
y, minZrec);
386 maxZrec = std::max(
y, maxZrec);
389 meanTime /= uint64_t(trackMatches.size());
391 const float robustFraction = 0.9;
392 const int minPoints = 6;
394 if (trackMatches.size() <
size_t(minPoints / robustFraction)) {
395 LOGP(warning,
"{} - Not enough points to perform the fit: {} < {}", info, trackMatches.size(),
size_t(minPoints / robustFraction));
398 if (std::abs(maxZrec - minZrec) < 50) {
399 LOGP(warning,
"{} - All points seem to be from one Layer: abs({}cm - {}cm) < 50cm, will not do fitting", info, trackMatches.size(), maxZrec, minZrec);
407 retVal.
x1 = float(fit.GetParameter(0));
408 retVal.x2 = float(fit.GetParameter(1));
417 std::sort(trackMatches.begin(), trackMatches.end(), [](
const auto&
first,
const auto& second) { return first.time < second.time; });
425 "Processed {} TFs from {} - {}; found tracks: {} / {}; fit offsets (cm): {} / {}; T0s (us): {} / {}; dv correction factors: {} / {} for A- / C-Side, reference: {}",
440 "Processed {} TFs from {} - {}; **Not finalized**",
446 "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.
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 fill(const gsl::span< const TrackTPC > tracks, float tp=0)
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 tp
temperature over pressure ratio
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