Skip to content

Commit 1c64317

Browse files
Implement TRD extra data processing in AODProducerWorkflowSpec.cxx
This commit enables the workflow to generate TRD-specific extra tables in the AOD, applying calibration and noise corrections to improve reconstruction fidelity for TRD tracks.
1 parent 4cd13f8 commit 1c64317

File tree

1 file changed

+101
-8
lines changed

1 file changed

+101
-8
lines changed

Detectors/AOD/src/AODProducerWorkflowSpec.cxx

Lines changed: 101 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "DataFormatsPHOS/TriggerRecord.h"
3434
#include "DataFormatsPHOS/EventHandler.h"
3535
#include "DataFormatsTPC/TrackTPC.h"
36-
#include "DataFormatsTRD/TriggerRecord.h"
3736
#include "DataFormatsZDC/BCRecData.h"
3837
#include "DataFormatsZDC/ZDCEnergy.h"
3938
#include "DataFormatsZDC/ZDCTDCData.h"
@@ -45,6 +44,9 @@
4544
#include "CommonDataFormat/InteractionRecord.h"
4645
#include "DataFormatsTRD/TrackTRD.h"
4746
#include "DataFormatsTRD/TrackTriggerRecord.h"
47+
#include "DataFormatsTRD/CalibratedTracklet.h"
48+
#include "DataFormatsTRD/TriggerRecord.h"
49+
#include "DataFormatsTRD/Tracklet64.h"
4850
#include "DataFormatsGlobalTracking/RecoContainer.h"
4951
#include "Framework/AnalysisDataModel.h"
5052
#include "Framework/ConfigParamRegistry.h"
@@ -390,6 +392,79 @@ void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACurs
390392
mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdZ);
391393
}
392394

395+
template <typename TRDsExtraCursorType>
396+
void AODProducerWorkflowDPL::addToTRDsExtra(const o2::globaltracking::RecoContainer& recoData, TRDsExtraCursorType& trdExtraCursor, const GIndex& trkIdx, int trkTableIdx)
397+
{
398+
int q0s[6] = {-1}, q1s[6] = {-1}, q2s[6] = {-1};
399+
float q0sCor[6] = {-1}, q1sCor[6] = {-1}, q2sCor[6] = {-1};
400+
float ttgls[6] = {-999}, tphis[6] = {-999};
401+
402+
auto contributorsGID = recoData.getSingleDetectorRefs(trkIdx);
403+
if (!contributorsGID[GIndex::Source::TRD].isIndexSet()) { // should be redunant
404+
return;
405+
}
406+
const auto& trk = recoData.getTrack<o2::trd::TrackTRD>(contributorsGID[GIndex::Source::TRD]);
407+
o2::track::TrackPar trkC{contributorsGID[GIndex::Source::ITSTPC].isIndexSet() ? recoData.getTPCITSTrack(contributorsGID[GIndex::Source::ITSTPC]).getParamOut() : recoData.getTPCTrack(contributorsGID[GIndex::Source::TPC]).getParamOut() };
408+
const auto& trklets = recoData.getTRDTracklets();
409+
const auto& ctrklets = recoData.getTRDCalibratedTracklets();
410+
for (int iLay{0}; iLay < 6; ++iLay) {
411+
q0s[iLay] = q1s[iLay] = q2s[iLay] = -1;
412+
q0sCor[iLay] = q1sCor[iLay] = q2sCor[iLay] = -1;
413+
tphis[iLay] = ttgls[iLay] = -999;
414+
auto trkltId = trk.getTrackletIndex(iLay);
415+
if (trkltId < 0) {
416+
continue;
417+
}
418+
const auto& tracklet = trklets[trkltId];
419+
if (mTRDNoiseMap->isTrackletFromNoisyMCM(tracklet)) {
420+
continue;
421+
}
422+
// we need to propagate into TRD local system
423+
int trkltDet = tracklet.getDetector();
424+
int trkltSec = trkltDet / 30;
425+
if (trkltSec != o2::math_utils::angle2Sector(trkC.getAlpha())) {
426+
if (!trkC.rotate(o2::math_utils::sector2Angle(trkltSec))) {
427+
break;
428+
}
429+
}
430+
if (!o2::base::Propagator::Instance()->PropagateToXBxByBz(trkC, ctrklets[trkltId].getX(), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr)) {
431+
break;
432+
}
433+
434+
auto tphi = trkC.getSnp() / std::sqrt((1.f - trkC.getSnp()) * (1.f + trkC.getSnp()));
435+
auto trackletLength = std::sqrt(1.f + tphi * tphi + trkC.getTgl() * trkC.getTgl());
436+
float cor = mTRDLocalGain->getValue(tracklet.getHCID() / 2, tracklet.getPadCol(), tracklet.getPadRow()) * trackletLength;
437+
q0s[iLay] = tracklet.getQ0();
438+
q1s[iLay] = tracklet.getQ1();
439+
q2s[iLay] = tracklet.getQ2();
440+
q0sCor[iLay] = (float)tracklet.getQ0() / cor;
441+
q1sCor[iLay] = (float)tracklet.getQ1() / cor;
442+
q2sCor[iLay] = (float)tracklet.getQ2() / cor;
443+
ttgls[iLay] = trkC.getTgl();
444+
tphis[iLay] = tphi;
445+
446+
// z-row merging
447+
if (trk.getIsCrossingNeighbor(iLay) && trk.getHasNeighbor()) {
448+
for (const auto& trklt : trklets) {
449+
if (tracklet.getTrackletWord() == trklt.getTrackletWord()) {
450+
continue;
451+
}
452+
if (std::abs(tracklet.getPadCol() - trklt.getPadCol()) <= 1 && std::abs(tracklet.getPadRow() - trklt.getPadRow()) == 1) {
453+
cor = mTRDLocalGain->getValue(trklt.getHCID() / 2, trklt.getPadCol(), trklt.getPadRow()) * trackletLength;
454+
q0s[iLay] += trklt.getQ0();
455+
q1s[iLay] += trklt.getQ1();
456+
q2s[iLay] += trklt.getQ2();
457+
q0sCor[iLay] += (float)trklt.getQ0() / cor;
458+
q1sCor[iLay] += (float)trklt.getQ1() / cor;
459+
q2sCor[iLay] += (float)trklt.getQ2() / cor;
460+
}
461+
}
462+
}
463+
}
464+
465+
trdExtraCursor(trkTableIdx, q0s, q1s, q2s, q0sCor, q1sCor, q2sCor, ttgls, tphis);
466+
}
467+
393468
template <typename mftTracksCursorType, typename AmbigMFTTracksCursorType>
394469
void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
395470
GIndex trackID, const o2::globaltracking::RecoContainer& data, int collisionID,
@@ -430,8 +505,7 @@ void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksC
430505
ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
431506
}
432507
}
433-
434-
template <typename TracksCursorType, typename TracksCovCursorType, typename TracksExtraCursorType, typename TracksQACursorType, typename AmbigTracksCursorType,
508+
template <typename TracksCursorType, typename TracksCovCursorType, typename TracksExtraCursorType, typename TracksQACursorType, typename TRDsExtraCursor, typename AmbigTracksCursorType,
435509
typename MFTTracksCursorType, typename MFTTracksCovCursorType, typename AmbigMFTTracksCursorType,
436510
typename FwdTracksCursorType, typename FwdTracksCovCursorType, typename AmbigFwdTracksCursorType, typename FwdTrkClsCursorType>
437511
void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID,
@@ -443,6 +517,7 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID,
443517
TracksCovCursorType& tracksCovCursor,
444518
TracksExtraCursorType& tracksExtraCursor,
445519
TracksQACursorType& tracksQACursor,
520+
TRDsExtraCursor& trdsExtraCursor,
446521
AmbigTracksCursorType& ambigTracksCursor,
447522
MFTTracksCursorType& mftTracksCursor,
448523
MFTTracksCovCursorType& mftTracksCovCursor,
@@ -553,7 +628,9 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID,
553628
addToTracksTable(tracksCursor, tracksCovCursor, trOrig, collisionID, aod::track::TrackIU);
554629
}
555630
addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
556-
631+
if (mEnableTRDextra && trackIndex.includesDet(GIndex::Source::TRD)) {
632+
addToTRDsExtra(data, trdsExtraCursor, trackIndex, mTableTrID);
633+
}
557634
// collecting table indices of barrel tracks for V0s table
558635
if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
559636
ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
@@ -1934,6 +2011,12 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc)
19342011
auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
19352012
auto originCursor = createTableCursor<o2::aod::Origins>(pc);
19362013

2014+
/// Extra tables
2015+
o2::framework::Produces<o2::aod::TRDsExtra> trdExtraCursor;
2016+
if (mEnableTRDextra) {
2017+
trdExtraCursor = createTableCursor<o2::aod::TRDsExtra>(pc);
2018+
}
2019+
19372020
// Declare MC cursors type without adding the output for a table
19382021
o2::framework::Produces<o2::aod::McCollisionLabels> mcColLabelsCursor;
19392022
o2::framework::Produces<o2::aod::McCollisions> mcCollisionsCursor;
@@ -2298,7 +2381,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc)
22982381
// so that all unassigned tracks are stored in the beginning of the table together
22992382
auto& trackRef = primVer2TRefs.back(); // references to unassigned tracks are at the end
23002383
// fixme: interaction time is undefined for unassigned tracks (?)
2301-
fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2384+
fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor,
23022385
ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
23032386
fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
23042387

@@ -2340,7 +2423,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc)
23402423

23412424
auto& trackRef = primVer2TRefs[collisionID];
23422425
// passing interaction time in [ps]
2343-
fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2426+
fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor, ambigTracksCursor,
23442427
mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
23452428
fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
23462429
collisionID++;
@@ -3011,6 +3094,10 @@ void AODProducerWorkflowDPL::updateTimeDependentParams(ProcessingContext& pc)
30113094
mFieldON = std::abs(o2::base::Propagator::Instance()->getNominalBz()) > 0.01;
30123095

30133096
pc.inputs().get<o2::ctp::CTPConfiguration*>("ctpconfig");
3097+
if (mEnableTRDextra) {
3098+
mTRDLocalGain = pc.inputs().get<o2::trd::LocalGainFactor*>("trdlocalgainfactors").get();
3099+
mTRDNoiseMap = pc.inputs().get<o2::trd::NoiseStatusMCM*>("trdnoisemap").get();
3100+
}
30143101
}
30153102
if (mPropTracks) {
30163103
pc.inputs().get<o2::dataformats::MeanVertexObject*>("meanvtx");
@@ -3222,7 +3309,7 @@ void AODProducerWorkflowDPL::endOfStream(EndOfStreamContext& /*ec*/)
32223309
mStreamer.reset();
32233310
}
32243311

3225-
DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableStrangenessTracking, bool useMC, bool CTPConfigPerRun, bool enableFITextra)
3312+
DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableStrangenessTracking, bool useMC, bool CTPConfigPerRun, bool enableFITextra, bool enableTRDextra)
32263313
{
32273314
auto dataRequest = std::make_shared<DataRequest>();
32283315
dataRequest->inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/Config", CTPConfigPerRun));
@@ -3313,6 +3400,12 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo
33133400
OutputSpec{"TFF", "TFFilename"},
33143401
OutputSpec{"AMD", "AODMetadataKeys"},
33153402
OutputSpec{"AMD", "AODMetadataVals"}};
3403+
/// Extra tables
3404+
if (enableTRDextra) {
3405+
outputs.push_back(OutputForTable<TRDsExtra>::spec());
3406+
dataRequest->inputs.emplace_back("trdlocalgainfactors", "TRD", "LOCALGAINFACTORS", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/LocalGainFactor"));
3407+
dataRequest->inputs.emplace_back("trdnoisemap", "TRD", "NOISEMAP", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/NoiseMapMCM"));
3408+
}
33163409

33173410
if (useMC) {
33183411
outputs.insert(outputs.end(),
@@ -3336,7 +3429,7 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo
33363429
"aod-producer-workflow",
33373430
dataRequest->inputs,
33383431
outputs,
3339-
AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3432+
AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(src, dataRequest, ggRequest, enableSV, useMC, enableFITextra, enableTRDextra)},
33403433
Options{
33413434
ConfigParamSpec{"run-number", VariantType::Int64, -1L, {"The run-number. If left default we try to get it from DPL header."}},
33423435
ConfigParamSpec{"aod-timeframe-id", VariantType::Int64, -1L, {"Set timeframe number"}},

0 commit comments

Comments
 (0)