Skip to content

Commit 56ddbe2

Browse files
committed
Fixes in processCosmics, allow pipelining
Only cosmic tracks with at least one TRD or TOF contribution will be accepted in the tpc-refitter. Added options for cosmics processing: --ignore-legs-wo-outer-det will skip cosmic legs w/o TRD or TOF constraint even if other leg is well constrained --use-cosmic-leg-timing will prefer the timestamp of each leg to (if available) for the refit, otherwise use cosmic track timestamp. When the workflow is run with >1 lane, the streamer output XX.root of each lane will appear with suffix: XX_<lane>.root
1 parent 281f6ce commit 56ddbe2

2 files changed

Lines changed: 42 additions & 32 deletions

File tree

Detectors/TPC/workflow/src/TPCRefitter.cxx

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "DetectorsBase/Propagator.h"
2323
#include "Framework/ConfigParamRegistry.h"
2424
#include "Framework/ControlService.h"
25+
#include "Framework/DeviceSpec.h"
2526
#include "Framework/Task.h"
2627
#include "MathUtils/Tsallis.h"
2728
#include "DetectorsCommonDataFormats/DetID.h"
@@ -96,6 +97,8 @@ class TPCRefitterSpec final : public Task
9697
int mWriteTrackClusters = 0; ///< bitmask of which cluster information to dump to the tree: 0x1 = cluster native, 0x2 = corrected cluster positions, 0x4 = uncorrected cluster positions, 0x8 occupancy info
9798
bool mDoSampling{false}; ///< perform sampling of unbinned data
9899
bool mDoRefit{true}; ///< perform refit of TPC track
100+
bool mIgnorLegsWOGoodTime{false}; ///< ignore cosmic legs w/o TRD or TOF constraint instead of using the time of other constraned leg
101+
bool mUseCosmicLegTiming{false}; ///< use the timestamp from the cosmic track leg instead of using cosmic track timestamp
99102
std::vector<size_t> mClusterOccupancy; ///< binned occupancy of all clusters
100103
std::vector<size_t> mITSTPCTrackOccupanyTPCTime; ///< binned occupancy for ITS-TPC matched tracks using the TPC track time
101104
std::vector<size_t> mITSTPCTrackOccupanyCombinedTime; ///< binned occupancy for ITS-TPC matched tracks using the combined track time
@@ -152,6 +155,9 @@ void TPCRefitterSpec::init(InitContext& ic)
152155
mStudyType = ic.options().get<int>("study-type");
153156
mWriterType = ic.options().get<int>("writer-type");
154157
mWriteTrackClusters = ic.options().get<int>("write-track-clusters");
158+
mIgnorLegsWOGoodTime = ic.options().get<bool>("ignore-legs-wo-outer-det");
159+
mUseCosmicLegTiming = ic.options().get<bool>("use-cosmic-leg-timing");
160+
155161
const auto occBinsPerDrift = ic.options().get<uint32_t>("occupancy-bins-per-drift");
156162
mTimeBinsPerTF = (o2::raw::HBFUtils::Instance().nHBFPerTF * o2::constants::lhc::LHCMaxBunches) / 8 + 2 * mTimeBinsPerDrift; // add one drift before and after the TF
157163
mOccupancyBinsPerTF = static_cast<uint32_t>(std::ceil(float(mTimeBinsPerTF * occBinsPerDrift) / mTimeBinsPerDrift));
@@ -160,19 +166,23 @@ void TPCRefitterSpec::init(InitContext& ic)
160166
mITSTPCTrackOccupanyCombinedTime.resize(mOccupancyBinsPerTF);
161167
LOGP(info, "Using {} bins for the occupancy per TF", mOccupancyBinsPerTF);
162168

169+
int lane = ic.services().get<const o2::framework::DeviceSpec>().inputTimesliceId;
170+
int maxLanes = ic.services().get<const o2::framework::DeviceSpec>().maxInputTimeslices;
171+
auto composeName = [maxLanes, lane](const std::string& seed) { return maxLanes > 1 ? fmt::format("{}_{}.root", seed, lane) : fmt::format("{}.root", seed); };
172+
163173
if ((mWriterType & WriterType::Streamer) == WriterType::Streamer) {
164174
if ((mStudyType & StudyType::TPC) == StudyType::TPC) {
165-
mDBGOutTPC = std::make_unique<o2::utils::TreeStreamRedirector>("tpctracks-study-streamer.root", "recreate");
175+
mDBGOutTPC = std::make_unique<o2::utils::TreeStreamRedirector>(composeName("tpctracks-study-streamer").c_str(), "recreate");
166176
}
167177
if ((mStudyType & StudyType::ITSTPC) == StudyType::ITSTPC) {
168-
mDBGOutITSTPC = std::make_unique<o2::utils::TreeStreamRedirector>("itstpctracks-study-streamer.root", "recreate");
178+
mDBGOutITSTPC = std::make_unique<o2::utils::TreeStreamRedirector>(composeName("itstpctracks-study-streamer").c_str(), "recreate");
169179
}
170180
if ((mStudyType & StudyType::Cosmics) == StudyType::Cosmics) {
171-
mDBGOutCosmics = std::make_unique<o2::utils::TreeStreamRedirector>("cosmics-study-streamer.root", "recreate");
181+
mDBGOutCosmics = std::make_unique<o2::utils::TreeStreamRedirector>(composeName("cosmics-study-streamer").c_str(), "recreate");
172182
}
173183
}
174184
if (ic.options().get<bool>("dump-clusters")) {
175-
mDBGOutCl = std::make_unique<o2::utils::TreeStreamRedirector>("tpc-trackStudy-cl.root", "recreate");
185+
mDBGOutCl = std::make_unique<o2::utils::TreeStreamRedirector>(composeName("tpc-trackStudy-cl").c_str(), "recreate");
176186
}
177187

178188
if (mXRef < 0.) {
@@ -677,35 +687,36 @@ bool TPCRefitterSpec::processTPCTrack(o2::tpc::TrackTPC tr, o2::MCCompLabel lbl,
677687

678688
void TPCRefitterSpec::processCosmics(o2::globaltracking::RecoContainer& recoData)
679689
{
680-
auto tof = recoData.getTOFClusters();
681690
const auto& par = o2::tpc::ParameterElectronics::Instance();
682691
const auto invBinWidth = 1.f / par.ZbinWidth;
683692

684693
for (const auto& cosmic : mCosmics) {
685694
//
686-
const auto& gidtop = cosmic.getRefTop();
687-
const auto& gidbot = cosmic.getRefBottom();
688-
689-
// LOGP(info, "Sources: {} - {}", o2::dataformats::GlobalTrackID::getSourceName(gidtop.getSource()), o2::dataformats::GlobalTrackID::getSourceName(gidbot.getSource()));
690-
691-
std::array<GTrackID, GTrackID::NSources> contributorsGID[2] = {recoData.getSingleDetectorRefs(cosmic.getRefTop()), recoData.getSingleDetectorRefs(cosmic.getRefBottom())};
692-
const auto trackTime = cosmic.getTimeMUS().getTimeStamp() * invBinWidth;
693-
694-
// check if track has TPC & TOF for top and bottom part
695-
// loop over both parts
696-
for (const auto& comsmicInfo : contributorsGID) {
697-
auto& tpcGlobal = comsmicInfo[GTrackID::TPC];
698-
auto& tofGlobal = comsmicInfo[GTrackID::TOF];
699-
if (tpcGlobal.isIndexSet() && tofGlobal.isIndexSet()) {
700-
const auto itrTPC = tpcGlobal.getIndex();
701-
const auto itrTOF = tofGlobal.getIndex();
702-
const auto& tofCl = tof[itrTOF];
703-
const auto tofTime = tofCl.getTime() * 1e-6 * invBinWidth; // ps -> us -> time bins
704-
const auto tofTimeRaw = tofCl.getTimeRaw() * 1e-6 * invBinWidth; // ps -> us -> time bins
705-
const auto& trackTPC = mTPCTracksArray[itrTPC];
706-
// LOGP(info, "Cosmic time: {}, TOF time: {}, TOF time raw: {}, TPC time: {}", trackTime, tofTime, tofTimeRaw, trackTPC.getTime0());
707-
processTPCTrack(trackTPC, mUseMC ? mTPCTrkLabels[itrTPC] : o2::MCCompLabel{}, mDBGOutCosmics.get(), nullptr, nullptr, false, tofTime);
695+
const GTrackID gidTopBot[] = {cosmic.getRefTop(), cosmic.getRefBottom()};
696+
// LOGP(info, "Sources: {} - {}", o2::dataformats::GlobalTrackID::getSourceName(gidTopBot[0].getSource()), o2::dataformats::GlobalTrackID::getSourceName(gidTopBot[1].getSource()));
697+
// Wequire at least one TRD of TOF contribution to constrain the timestamp
698+
bool hasGoodTime[2] = {false, false};
699+
std::array<GTrackID, GTrackID::NSources> contributorsGID[2];
700+
for (int i = 0; i < 2; i++) {
701+
contributorsGID[i] = recoData.getSingleDetectorRefs(gidTopBot[i]);
702+
hasGoodTime[i] = gidTopBot[i].includesDet(DetID::TOF) || gidTopBot[i].includesDet(DetID::TRD);
703+
}
704+
if (!hasGoodTime[0] && !hasGoodTime[1]) {
705+
continue;
706+
}
707+
float trackTime = cosmic.getTimeMUS().getTimeStamp() * invBinWidth; // this time corresponds to the center of top/bottom legs time-brackers intersection, i.e. should be the most precise one
708+
709+
for (int i = 0; i < 2; i++) {
710+
if (!contributorsGID[i][GTrackID::TPC].isSourceSet() || (mIgnorLegsWOGoodTime && !hasGoodTime[i])) {
711+
continue;
712+
}
713+
const auto& trackTPC = mTPCTracksArray[contributorsGID[i][GTrackID::TPC]];
714+
float useTrackTime = trackTime, dummyError = 0.f;
715+
if (mUseCosmicLegTiming && hasGoodTime[i]) { // track out time was requested (if available)
716+
recoData.getTrackTime(gidTopBot[i], useTrackTime, dummyError);
717+
useTrackTime *= invBinWidth;
708718
}
719+
processTPCTrack(trackTPC, mUseMC ? mTPCTrkLabels[contributorsGID[i][GTrackID::TPC]] : o2::MCCompLabel{}, mDBGOutCosmics.get(), nullptr, nullptr, false, useTrackTime);
709720
}
710721
}
711722
}
@@ -731,6 +742,8 @@ DataProcessorSpec getTPCRefitterSpec(GTrackID::mask_t srcTracks, GTrackID::mask_
731742
{"study-type", VariantType::Int, 1, {"Bitmask of study type: 0x1 = TPC only, 0x2 = TPC + ITS, 0x4 = Cosmics"}},
732743
{"writer-type", VariantType::Int, 1, {"Bitmask of writer type: 0x1 = per track streamer, 0x2 = per TF vectors"}},
733744
{"occupancy-bins-per-drift", VariantType::UInt32, 31u, {"number of bin for occupancy histogram per drift time (500tb)"}},
745+
{"ignore-legs-wo-outer-det", VariantType::Bool, false, {"Ignore cosmic legs w/o TRD or TOF constraint even if other leg is well constrained"}},
746+
{"use-cosmic-leg-timing", VariantType::Bool, false, {"Use leg-specific timestamp instead of cosmic track final timestamp"}},
734747
};
735748
auto dataRequest = std::make_shared<DataRequest>();
736749

Detectors/TPC/workflow/src/tpc-refitter-workflow.cxx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,8 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
6666
auto sclOpt = o2::tpc::CorrectionMapsOptions::parseGlobalOptions(configcontext.options());
6767
const auto enableCosmics = configcontext.options().get<bool>("enable-cosmics");
6868

69-
GID::mask_t allowedSourcesTrc = GID::getSourcesMask("ITS,TPC,ITS-TPC,TPC-TOF");
70-
GID::mask_t allowedSourcesClus = GID::getSourcesMask("TPC,TOF");
71-
if (enableCosmics) {
72-
allowedSourcesTrc = allowedSourcesTrc | GID::getSourcesMask("ITS-TPC-TRD,ITS-TPC-TOF,ITS-TPC-TRD-TOF");
73-
}
69+
GID::mask_t allowedSourcesTrc = GID::getSourcesMask("TPC,ITS-TPC,TPC-TOF,TPC-TRD,ITS-TPC-TRD,TPC-TRD-TOF,ITS-TPC-TOF,ITS-TPC-TRD-TOF");
70+
GID::mask_t allowedSourcesClus = GID::getSourcesMask("TPC");
7471

7572
GID::mask_t srcTrc = allowedSourcesTrc & GID::getSourcesMask(configcontext.options().get<std::string>("track-sources"));
7673
GID::mask_t srcCls = allowedSourcesClus & GID::getSourcesMask(configcontext.options().get<std::string>("cluster-sources"));

0 commit comments

Comments
 (0)