15#include <unordered_map>
60 mSlotLength = ic.
options().
get<uint32_t>(
"sec-per-slot");
61 mProcessSeeds = ic.
options().
get<
bool>(
"process-seeds");
62 mMatCorr = ic.
options().
get<
int>(
"matCorrType");
63 if (mProcessSeeds && mSources != mSourcesMap) {
64 LOG(fatal) <<
"process-seeds option is not compatible with using different track sources for vDrift and map extraction";
68 mInterpolation.
setLane(lane, maxLanes);
70 if (!mSendTrackData) {
71 LOG(warning) <<
"MC truth is stored aligned with the track data, but send-track-data is not set: no MC truth will be sent";
73 mMCReader = std::make_unique<o2::steer::MCKinematicsReader>();
74 auto mcContext = ic.
options().
get<std::string>(
"mc-collision-context");
75 if (!mMCReader->initFromDigitContext(mcContext)) {
76 LOG(fatal) <<
"Could not initialize the MC kinematics reader from " << mcContext;
85 static bool initOnceDone =
false;
92 mInterpolation.
init(mSources, mSourcesMap);
93 if (mProcessITSTPConly) {
97 bool limitTracks = (
param.maxTracksPerCalibSlot < 0) ?
false : true;
98 int nTracksPerTfMax = (nTfs > 0 && limitTracks) ?
param.maxTracksPerCalibSlot / nTfs : -1;
99 if (nTracksPerTfMax > 0) {
100 LOGP(info,
"We will stop processing tracks after validating {} tracks per TF, since we want to accumulate {} tracks for a slot with {} TFs",
101 nTracksPerTfMax,
param.maxTracksPerCalibSlot, nTfs);
102 if (
param.additionalTracksMap > 0) {
103 int nTracksAdditional =
param.additionalTracksMap / nTfs;
104 LOGP(info,
"In addition up to {} additional tracks are processed per TF", nTracksAdditional);
107 }
else if (nTracksPerTfMax < 0) {
108 LOG(info) <<
"The number of processed tracks per TF is not limited";
110 LOG(error) <<
"No tracks will be processed. maxTracksPerCalibSlot must be greater than slot length in TFs";
126 LOGP(info,
"Updating TPC fast transform map with new VDrift factor of {} wrt reference {} and DriftTimeOffset correction {} wrt {} from source {}",
144 LOG(info) <<
"cluster dictionary updated";
155 updateTimeDependentParams(pc);
159 LOGF(info,
"TPC interpolation timing: Cpu: %.3e Real: %.3e s", mTimer.CpuTime(), mTimer.RealTime());
163 if (mSendTrackData) {
169 if (mUseMC && mSendTrackData) {
170 fillMCTruth(recoData);
173 mInterpolation.
reset();
176void TPCInterpolationDPL::fillMCTruth(
const RecoContainer& recoData)
185 mTrackDataMC.clear();
186 mTrackDataMC.resize(trkData.size());
192 std::vector<Lookup> lookups;
193 lookups.reserve(2 * trkData.size());
194 for (
size_t i = 0;
i < trkData.size(); ++
i) {
195 auto& mc = mTrackDataMC[
i];
201 if (gidITS.isIndexSet()) {
207 if (mc.labelITS.isValid() && mc.labelTPC.isValid() && mc.labelITS.getTrackEventSourceID() != mc.labelTPC.getTrackEventSourceID()) {
210 const auto& lblITS = mc.labelITS.
isValid() ? mc.labelITS : mc.label;
211 const auto& lblTPC = mc.labelTPC.isValid() ? mc.labelTPC : mc.label;
212 if (lblITS.isValid()) {
213 lookups.push_back({lblITS, uint32_t(
i), 0});
215 if (lblTPC.isValid()) {
216 lookups.push_back({lblTPC, uint32_t(
i), 1});
219 lookups.push_back({mc.label.isValid() ? mc.label : lblTPC, uint32_t(
i), 2});
221 if (lblTPC.isValid()) {
222 lookups.push_back({mc.label.isValid() ? mc.label : lblTPC, uint32_t(
i), 3});
226 std::sort(lookups.begin(), lookups.end(), [](
const Lookup&
a,
const Lookup&
b) {
227 return a.lbl.getSourceID() != b.lbl.getSourceID() ? a.lbl.getSourceID() < b.lbl.getSourceID() : a.lbl.getEventID() < b.lbl.getEventID();
229 auto pdgToPID = [](
int pdg) {
230 switch (std::abs(pdg)) {
252 std::array<float, 3> xyz{
ref.X(),
ref.Y(),
ref.Z()};
253 std::array<float, 3> pxyz{
ref.Px(),
ref.Py(),
ref.Pz()};
260 for (
const auto& lk : lookups) {
261 const auto& lbl = lk.lbl;
262 if (lbl.getSourceID() != curSrc || lbl.getEventID() != curEv) {
264 mMCReader->releaseTracksForSourceAndEvent(curSrc, curEv);
266 curSrc = lbl.getSourceID();
267 curEv = lbl.getEventID();
269 const auto& trk = trkData[lk.idx];
270 auto& mc = mTrackDataMC[lk.idx];
271 const auto* mcTrk = mMCReader->getTrack(lbl);
272 int pdg = mcTrk ? mcTrk->GetPdgCode() : 0;
274 int charge = pPDG ?
int(std::lround(pPDG->Charge() / 3.)) : 0;
275 auto refs = mMCReader->getTrackRefs(lbl.getSourceID(), lbl.getEventID(), lbl.getTrackID());
278 float bestD2 = 1e30f;
279 auto xyzReco = trk.par.getXYZGlo();
280 for (
const auto&
ref : refs) {
281 if (
ref.getDetectorId() != DetID::ITS) {
284 float dx =
ref.X() - xyzReco.X();
285 float dy =
ref.Y() - xyzReco.Y();
286 float dz =
ref.Z() - xyzReco.Z();
287 float d2 = dx * dx + dy * dy + dz * dz;
294 auto par = refToPar(*best,
charge, pdg,
false);
295 if (
par.rotateParam(trk.par.getAlpha()) && prop->PropagateToXBxByBz(par, trk.par.getX(), 0.999f, o2::base::Propagator::MAX_STEP, matCorr)) {
297 mc.distITSRef = std::sqrt(bestD2);
301 }
else if (lk.kind == 1) {
303 for (
const auto&
ref : refs) {
304 if (
ref.getDetectorId() == DetID::TPC && (!
first ||
ref.getTime() <
first->getTime())) {
313 const UnbinnedResid* inner =
nullptr;
314 for (
int ic = trk.clIdx.getFirstEntry(); ic < trk.clIdx.getFirstEntry() + trk.clIdx.getEntries(); ++ic) {
315 if (clRes[ic].
row < constants::MAXGLOBALPADROW && (!inner || clRes[ic].row < inner->
row)) {
320 auto par = mc.parTPCIn;
321 float yCl = inner->
y * param::MaxY / 0x7fff + inner->dy * param::MaxResid / 0x7fff;
322 float zCl = inner->z * param::MaxZ / 0x7fff + inner->dz * param::MaxResid / 0x7fff;
323 if (
par.rotateParam(
o2::math_utils::sector2Angle(inner->sec)) && prop->PropagateToXBxByBz(par, param::RowX[inner->row], 0.999f, o2::base::Propagator::MAX_STEP, matCorr)) {
324 mc.distTPCRef = std::hypot(
par.getY() - yCl,
par.getZ() - zCl);
328 }
else if (lk.kind == 3) {
333 if (mcTrk->isPrimary()) {
336 mc.process = mcTrk->getProcess();
337 mc.prodX = mcTrk->GetStartVertexCoordinatesX();
338 mc.prodY = mcTrk->GetStartVertexCoordinatesY();
339 mc.prodZ = mcTrk->GetStartVertexCoordinatesZ();
340 mc.prodPx = mcTrk->GetStartVertexMomentumX();
341 mc.prodPy = mcTrk->GetStartVertexMomentumY();
342 mc.prodPz = mcTrk->GetStartVertexMomentumZ();
343 int motherId = mcTrk->getMotherTrackId();
345 mc.motherLabel =
o2::MCCompLabel(motherId, lbl.getEventID(), lbl.getSourceID());
346 const auto* mother = mMCReader->getTrack(lbl.getSourceID(), lbl.getEventID(), motherId);
347 mc.motherPdg = mother ? mother->GetPdgCode() : 0;
351 for (
const auto&
ref : refs) {
352 if (
ref.getDetectorId() == DetID::TRD && (!
first ||
ref.getTime() <
first->getTime())) {
364 for (
int iLayer = 0; iLayer < o2::trd::constants::NLAYER; iLayer++) {
365 int trkltIdx = trkTRD.getTrackletIndex(iLayer);
369 const auto& sp = trkltsCalib[trkltIdx];
370 int sec =
tracklets[trkltIdx].getDetector() / (o2::trd::constants::NLAYER * o2::trd::constants::NSTACK);
372 float cs = std::cos(
alpha);
373 float sn = std::sin(
alpha);
374 float gx = sp.getX() * cs - sp.getY() * sn;
375 float gy = sp.getX() * sn + sp.getY() * cs;
376 float gz = sp.getZ();
378 float bestD2 = 1e30f;
379 for (
const auto&
ref : refs) {
380 if (
ref.getDetectorId() != DetID::TRD) {
383 float dx =
ref.X() - gx;
384 float dy =
ref.Y() - gy;
385 float dz =
ref.Z() - gz;
386 float d2 = dx * dx + dy * dy + dz * dz;
392 auto par = refToPar(*best,
charge, pdg,
false);
393 if (
par.rotateParam(
alpha) && prop->PropagateToXBxByBz(par, sp.getX(), 0.999f, o2::base::Propagator::MAX_STEP, matCorr)) {
394 mc.yTRD[iLayer] =
par.getY();
395 mc.zTRD[iLayer] =
par.getZ();
396 mc.trdLayerMask |=
uint8_t(1) << iLayer;
402 mMCReader->releaseTracksForSourceAndEvent(curSrc, curEv);
405 std::unordered_map<uint64_t, std::vector<uint32_t>> daughters;
406 for (uint32_t
i = 0;
i < mTrackDataMC.size(); ++
i) {
407 if (mTrackDataMC[
i].motherLabel.isSet()) {
408 daughters[mTrackDataMC[
i].motherLabel.getTrackEventSourceID()].push_back(
i);
411 for (
const auto& [mother, idx] : daughters) {
412 for (
size_t k = 0;
idx.size() > 1 && k <
idx.size(); ++k) {
413 mTrackDataMC[
idx[k]].sisterIdx =
idx[(k + 1) %
idx.size()];
421 LOGF(info,
"TPC residuals extraction total timing: Cpu: %.3e Real: %.3e s in %d slots",
422 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
427 auto dataRequest = std::make_shared<DataRequest>();
428 dataRequest->setITSPerLayer(itsStag);
429 std::vector<OutputSpec> outputs;
431 dataRequest->requestTracks(srcVtx,
false);
432 dataRequest->requestClusters(srcCls,
false);
433 dataRequest->requestPrimaryVertices(
false);
438 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
447 outputs.emplace_back(
"GLO",
"UNBINNEDRES", 0, Lifetime::Timeframe);
448 outputs.emplace_back(
"GLO",
"DETINFORES", 0, Lifetime::Timeframe);
449 outputs.emplace_back(
"GLO",
"TRKREFS", 0, Lifetime::Timeframe);
451 outputs.emplace_back(
"GLO",
"TRKDATA", 0, Lifetime::Timeframe);
454 outputs.emplace_back(
"GLO",
"TRKDATAEXT", 0, Lifetime::Timeframe);
456 if (useMC && sendTrackData) {
457 outputs.emplace_back(
"GLO",
"TRKDATAMC", 0, Lifetime::Timeframe);
461 "tpc-track-interpolation",
464 AlgorithmSpec{adaptFromTask<TPCInterpolationDPL>(dataRequest, srcTrk, srcTrkMap, ggRequest, useMC, processITSTPConly, sendTrackData, debugOutput, extDetResid)},
466 {
"matCorrType", VariantType::Int, 2, {
"material correction type (definition in Propagator.h)"}},
467 {
"sec-per-slot", VariantType::UInt32, 300u, {
"number of seconds per calibration time slot (put 0 for infinite slot length)"}},
468 {
"process-seeds", VariantType::Bool,
false, {
"do not remove duplicates, e.g. for ITS-TPC-TRD track also process its seeding ITS-TPC part"}},
469 {
"mc-collision-context", VariantType::String,
"collisioncontext.root", {
"collision context used to access the MC kinematics and track references (MC only)"}}}};
Class of a TPC cluster in TPC-native coordinates (row, time)
Definition of the GeometryManager class.
Definition of the GeometryTGeo class.
Wrapper container for different reconstructed object types.
Parameters used for TPC space point calibration.
Definition of the ITS track.
Result of refitting TPC-ITS matched track.
Helper class to obtain TPC clusters / digits / labels from DPL.
static TDatabasePDG * Instance()
void checkUpdates(o2::framework::ProcessingContext &pc)
static int getNHBFPerTF()
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const SpacePointsCalibConfParam & Instance()
Static class with identifiers, bitmasks and names for ALICE detectors.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ServiceRegistryRef services()
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
static GeometryTGeo * Instance()
void fillMatrixCache(int mask) override
~TPCInterpolationDPL() override
void endOfStream(EndOfStreamContext &ec) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void init(InitContext &ic) final
void run(ProcessingContext &pc) final
void prepareInputTrackSample(const o2::globaltracking::RecoContainer &inp)
Prepare input track sample (not relying on CreateTracksVariadic functionality)
std::vector< TrackData > & getReferenceTracks()
void setExtDetResid(bool v)
std::vector< TrackDataExtended > & getTrackDataExtended()
const std::vector< o2::dataformats::GlobalTrackID > & getTRDGIDsSuccess() const
ITS-TPC-TRD track whose tracklets gave the TRD residuals of each stored track (not set if none),...
void setMatCorr(MatCorrType matCorr)
Sets the flag if material correction should be applied when extrapolating the tracks.
void setProcessSeeds()
Enable processing of seeds.
void setMaxTracksPerTF(int n)
Sets the maximum number of tracks to be processed (successfully) per TF.
std::vector< TrackDataCompact > & getTrackDataCompact()
void setAddTracksForMapPerTF(int n)
In addition to mMaxTracksPerTF up to the set number of additional tracks can be processed.
void setLane(int lID, int nL)
std::vector< DetInfoResid > & getClusterResidualsDetInfo()
void process()
Main processing function.
void setITSClusterDictionary(const o2::itsmft::TopologyDictionary *dict)
Allow setting the ITS cluster dictionary from outside.
std::vector< UnbinnedResid > & getClusterResiduals()
void setDumpTrackPoints()
Enable full output.
void setTPCVDrift(const o2::tpc::VDriftCorrFact &v)
void setProcessITSTPConly()
Enable ITS-TPC only processing.
void setSqrtS(float s)
Set the centre of mass energy required for pT downsampling Tsalis function.
void reset()
Reset cache and output vectors.
void init(o2::dataformats::GlobalTrackID::mask_t src, o2::dataformats::GlobalTrackID::mask_t srcMap)
Initialize everything, set the requested track sources.
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs, bool laser=true, bool itstpcTgl=true)
void extractCCDBInputs(o2::framework::ProcessingContext &pc, bool laser=true, bool itstpcTgl=true)
const VDriftCorrFact & getVDriftObject() const
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
static std::string_view getSourceName(Source s)
GPUd() bool getPosDirGlo(std value_t value_t & y
GLfloat GLfloat GLfloat alpha
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
uint8_t int statusCode int
uint8_t itsSharedClusterMap uint8_t
Defining ITS Vertex explicitly as messageable.
std::vector< ConfigParamSpec > Options
const bool const bool const int FollowDirection BestTrial TrackITSInternal< NLayers > & best
o2::track::TrackParametrization< float > par
float sector2Angle(int sect)
framework::DataProcessorSpec getTPCInterpolationSpec(o2::dataformats::GlobalTrackID::mask_t srcCls, o2::dataformats::GlobalTrackID::mask_t srcVtx, o2::dataformats::GlobalTrackID::mask_t srcTrk, o2::dataformats::GlobalTrackID::mask_t srcTrkMap, bool useMC, bool processITSTPConly, bool sendTrackData, bool debugOutput, bool extDetResid, bool itsStag)
create a processor spec
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
gsl::span< const o2::trd::CalibratedTracklet > getTRDCalibratedTracklets() const
o2::MCCompLabel getTrackMCLabel(GTrackID id) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
auto getITSTPCTRDTrack(GTrackID id) const
gsl::span< const o2::trd::Tracklet64 > getTRDTracklets() const
@ FakeITSTPC
ITS and TPC parts of the track have different MC labels.
@ HasTPCIn
parTPCIn is filled
@ HasITSOut
parITSOut is filled
@ HasTRDIn
parTRDIn is filled
float refTimeOffset
additive time offset reference (\mus)
float refVDrift
reference vdrift for which factor was extracted
float timeOffsetCorr
additive time offset correction (\mus)
float corrFact
drift velocity correction factor (multiplicative)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Tracklet64 > tracklets