Skip to content

Commit 6dce44a

Browse files
committed
Extend time gain calibration
- allow for using TPC tracks from global track matches - use DCA from global track in case global track match is required - improve method for reading back a previous calibration
1 parent 8757471 commit 6dce44a

File tree

5 files changed

+135
-46
lines changed

5 files changed

+135
-46
lines changed

Detectors/TPC/calibration/src/CalibdEdx.cxx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -754,17 +754,28 @@ void CalibdEdx::dumpToFile(const char* outFile)
754754

755755
CalibdEdx CalibdEdx::readFromFile(const char* inFile)
756756
{
757-
TFile f(inFile, "READ");
758-
auto* obj = (CalibdEdx*)f.Get("calib");
757+
std::unique_ptr<TFile> f(TFile::Open(inFile));
758+
if (!f || f->IsZombie()) {
759+
LOGP(error, "Could not open file: {}", inFile);
760+
CalibdEdx calTmp;
761+
return calTmp;
762+
}
763+
764+
auto obj = f->Get<CalibdEdx>("calib");
759765
if (!obj) {
766+
LOGP(error, "Could not read CalibdEdx object from file: {}", inFile);
760767
CalibdEdx calTmp;
761768
return calTmp;
762769
}
770+
771+
THnF* hTmp = f->Get<THnF>("histogram_data");
772+
763773
CalibdEdx cal(*obj);
764-
THnF* hTmp = (THnF*)f.Get("histogram_data");
774+
delete obj;
775+
765776
if (!hTmp) {
766-
CalibdEdx calTmp;
767-
return calTmp;
777+
LOGP(warning, "Could not read histogram from file: {}. Returning empty histogram", inFile);
778+
return cal;
768779
}
769780
cal.setFromRootHist(hTmp);
770781
return cal;

Detectors/TPC/workflow/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ o2_add_executable(idc-test-ft
200200
o2_add_executable(miptrack-filter
201201
COMPONENT_NAME tpc
202202
SOURCES src/tpc-miptrack-filter.cxx
203-
PUBLIC_LINK_LIBRARIES O2::TPCWorkflow)
203+
PUBLIC_LINK_LIBRARIES O2::TPCWorkflow O2::GlobalTrackingWorkflow)
204204

205205
o2_add_executable(track-and-cluster-filter
206206
COMPONENT_NAME tpc

Detectors/TPC/workflow/include/TPCWorkflow/MIPTrackFilterSpec.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717
#define O2_TPC_MIPTRACKFILTERSPEC_H_
1818

1919
#include "Framework/DataProcessorSpec.h"
20+
#include "ReconstructionDataFormats/GlobalTrackID.h"
21+
using GID = o2::dataformats::GlobalTrackID;
2022

2123
using namespace o2::framework;
2224

2325
namespace o2::tpc
2426
{
2527

2628
/// create a processor spec
27-
o2::framework::DataProcessorSpec getMIPTrackFilterSpec();
29+
o2::framework::DataProcessorSpec getMIPTrackFilterSpec(GID::mask_t srcTracks = GID::getSourcesMask("TPC"));
2830

2931
} // namespace o2::tpc
3032

Detectors/TPC/workflow/src/MIPTrackFilterSpec.cxx

Lines changed: 99 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@
1616
#include "TPCWorkflow/MIPTrackFilterSpec.h"
1717

1818
#include <algorithm>
19-
#include <iterator>
2019
#include <vector>
2120
#include <memory>
2221
#include <random>
2322

2423
// o2 includes
2524
#include "DataFormatsTPC/TrackTPC.h"
2625
#include "DataFormatsTPC/TrackCuts.h"
27-
#include "DetectorsCalibration/Utils.h"
26+
#include "Framework/CCDBParamSpec.h"
2827
#include "Framework/Logger.h"
2928
#include "DetectorsBase/GRPGeomHelper.h"
3029
#include "Framework/Task.h"
@@ -33,16 +32,23 @@
3332
#include "Framework/ConfigParamRegistry.h"
3433
#include "TPCWorkflow/ProcessingHelpers.h"
3534
#include "Headers/DataHeader.h"
35+
#include "DataFormatsGlobalTracking/RecoContainer.h"
36+
#include "ReconstructionDataFormats/PrimaryVertex.h"
37+
#include "DataFormatsCalibration/MeanVertexObject.h"
38+
#include "ReconstructionDataFormats/VtxTrackRef.h"
3639

3740
using namespace o2::framework;
41+
using DataRequest = o2::globaltracking::DataRequest;
42+
using GID = o2::dataformats::GlobalTrackID;
3843

3944
namespace o2::tpc
4045
{
4146

4247
class MIPTrackFilterDevice : public Task
4348
{
4449
public:
45-
MIPTrackFilterDevice(std::shared_ptr<o2::base::GRPGeomRequest> gr) : mGRPGeomRequest(gr) {}
50+
MIPTrackFilterDevice(std::shared_ptr<o2::base::GRPGeomRequest> gr, std::shared_ptr<DataRequest> dr, GID::mask_t trackSourcesMask)
51+
: mGRPGeomRequest(gr), mDataRequest(dr), mTrackSourcesMask(trackSourcesMask) {}
4652

4753
void init(framework::InitContext& ic) final;
4854
void run(ProcessingContext& pc) final;
@@ -53,16 +59,20 @@ class MIPTrackFilterDevice : public Task
5359
void sendOutput(DataAllocator& output);
5460

5561
std::shared_ptr<o2::base::GRPGeomRequest> mGRPGeomRequest;
56-
TrackCuts mCuts{}; ///< Tracks cuts object
57-
std::vector<TrackTPC> mMIPTracks; ///< Filtered MIP tracks
58-
unsigned int mProcessEveryNthTF{1}; ///< process every Nth TF only
59-
int mMaxTracksPerTF{-1}; ///< max number of MIP tracks processed per TF
60-
uint32_t mTFCounter{0}; ///< counter to keep track of the TFs
61-
int mProcessNFirstTFs{0}; ///< number of first TFs which are not sampled
62-
float mDCACut{-1}; ///< DCA cut
63-
bool mSendDummy{false}; ///< send empty data in case TF is skipped
64-
65-
bool acceptDCA(const TrackTPC& track);
62+
std::shared_ptr<DataRequest> mDataRequest;
63+
GID::mask_t mTrackSourcesMask;
64+
TrackCuts mCuts{}; ///< Tracks cuts object
65+
std::vector<TrackTPC> mMIPTracks; ///< Filtered MIP tracks
66+
o2::dataformats::MeanVertexObject mVtx; ///< Mean vertex object
67+
unsigned int mProcessEveryNthTF{1}; ///< process every Nth TF only
68+
int mMaxTracksPerTF{-1}; ///< max number of MIP tracks processed per TF
69+
uint32_t mTFCounter{0}; ///< counter to keep track of the TFs
70+
int mProcessNFirstTFs{0}; ///< number of first TFs which are not sampled
71+
float mDCACut{-1}; ///< DCA cut
72+
float mDCAZCut{-1}; ///< DCA z cut
73+
bool mSendDummy{false}; ///< send empty data in case TF is skipped
74+
75+
bool acceptDCA(o2::track::TrackPar propTrack, o2::math_utils::Point3D<float> refPoint, bool useDCAz = false);
6676
};
6777

6878
void MIPTrackFilterDevice::init(framework::InitContext& ic)
@@ -100,13 +110,16 @@ void MIPTrackFilterDevice::init(framework::InitContext& ic)
100110
mCuts.setCutLooper(cutLoopers);
101111

102112
mDCACut = ic.options().get<float>("dca-cut");
113+
mDCAZCut = ic.options().get<float>("dca-z-cut");
103114

104115
o2::base::GRPGeomHelper::instance().setRequest(mGRPGeomRequest);
105116
}
106117

107118
void MIPTrackFilterDevice::run(ProcessingContext& pc)
108119
{
109120
o2::base::GRPGeomHelper::instance().checkUpdates(pc);
121+
pc.inputs().get<o2::dataformats::MeanVertexObject*>("meanvtx");
122+
110123
const auto currentTF = processing_helpers::getCurrentTF(pc);
111124
if ((mTFCounter++ % mProcessEveryNthTF) && (currentTF >= mProcessNFirstTFs)) {
112125
LOGP(info, "Skipping TF {}", currentTF);
@@ -117,19 +130,60 @@ void MIPTrackFilterDevice::run(ProcessingContext& pc)
117130
return;
118131
}
119132

120-
const auto tracks = pc.inputs().get<gsl::span<TrackTPC>>("tracks");
121-
const auto nTracks = tracks.size();
133+
o2::globaltracking::RecoContainer recoData;
134+
recoData.collectData(pc, *mDataRequest);
135+
const auto tracksTPC = recoData.getTPCTracks();
136+
const auto nTracks = tracksTPC.size();
137+
138+
// indices to good tracks
139+
std::vector<size_t> indices;
140+
indices.reserve(nTracks);
141+
142+
const auto useGlobalTracks = mTrackSourcesMask[GID::ITSTPC];
143+
o2::math_utils::Point3D<float> vertex = mVtx.getXYZ();
144+
145+
if (useGlobalTracks) {
146+
auto trackIndex = recoData.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
147+
auto vtxRefs = recoData.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
148+
std::vector<GID::Source> selSrc{GID::ITSTPC, GID::ITSTPCTRD, GID::ITSTPCTRDTOF}; // for Instance
149+
// LOGP(info, "Number of vertex tracks: {}", vtxRefs.size());
150+
const auto nv = (vtxRefs.size() > 0) ? vtxRefs.size() - 1 : 0; // note: the last entry groups the tracks which were not related to any vertex, to skip them, use vtxRefs.size()-1
151+
152+
for (int iv = 0; iv < nv; iv++) {
153+
const auto& vtref = vtxRefs[iv];
154+
// LOGP(info, "Processing vertex {} with {} tracks", iv, vtref.getEntries());
155+
vertex = recoData.getPrimaryVertex(iv).getXYZ();
156+
// LOGP(info, "Vertex position: x={} y={} z={}", vertex.x(), vertex.y(), vertex.z());
157+
158+
for (auto src : selSrc) {
159+
int idMin = vtxRefs[iv].getFirstEntryOfSource(src), idMax = idMin + vtxRefs[iv].getEntriesOfSource(src);
160+
// LOGP(info, "Source {}: idMin={} idMax={}", GID::getSourceName(src), idMin, idMax);
161+
162+
for (int i = idMin; i < idMax; i++) {
163+
auto vid = trackIndex[i];
164+
const auto& track = recoData.getTrackParam(vid); // this is a COPY of the track param which we will modify during DCA calculation
165+
auto gidTPC = recoData.getTPCContributorGID(vid);
166+
if (gidTPC.isSourceSet()) {
167+
const auto idxTPC = gidTPC.getIndex();
168+
if (mCuts.goodTrack(tracksTPC[idxTPC]) && acceptDCA(tracksTPC[idxTPC], vertex, true)) {
169+
indices.emplace_back(idxTPC);
170+
}
171+
}
172+
}
173+
}
174+
}
122175

123-
if ((mMaxTracksPerTF != -1) && (nTracks > mMaxTracksPerTF)) {
124-
// indices to good tracks
125-
std::vector<size_t> indices;
126-
indices.reserve(nTracks);
176+
} else {
127177
for (size_t i = 0; i < nTracks; ++i) {
128-
if (mCuts.goodTrack(tracks[i]) && acceptDCA(tracks[i])) {
178+
if (mCuts.goodTrack(tracksTPC[i]) && acceptDCA(tracksTPC[i], vertex)) {
129179
indices.emplace_back(i);
130180
}
131181
}
182+
}
183+
184+
size_t nTracksSel = indices.size();
132185

186+
if ((mMaxTracksPerTF != -1) && (nTracksSel > mMaxTracksPerTF)) {
133187
// in case no good tracks have been found
134188
if (indices.empty()) {
135189
mMIPTracks.clear();
@@ -144,15 +198,14 @@ void MIPTrackFilterDevice::run(ProcessingContext& pc)
144198
std::shuffle(indices.begin(), indices.end(), rng);
145199

146200
// copy good tracks
147-
const int loopEnd = (mMaxTracksPerTF > indices.size()) ? indices.size() : mMaxTracksPerTF;
148-
for (int i = 0; i < loopEnd; ++i) {
149-
mMIPTracks.emplace_back(tracks[indices[i]]);
150-
}
151-
} else {
152-
std::copy_if(tracks.begin(), tracks.end(), std::back_inserter(mMIPTracks), [this](const auto& track) { return mCuts.goodTrack(track) && acceptDCA(track); });
201+
nTracksSel = (mMaxTracksPerTF > indices.size()) ? indices.size() : mMaxTracksPerTF;
202+
}
203+
204+
for (int i = 0; i < nTracksSel; ++i) {
205+
mMIPTracks.emplace_back(tracksTPC[indices[i]]);
153206
}
154207

155-
LOGP(info, "Filtered {} MIP tracks out of {} total tpc tracks", mMIPTracks.size(), tracks.size());
208+
LOGP(info, "Filtered {} / {} MIP tracks out of {} total tpc tracks, using {}", mMIPTracks.size(), indices.size(), tracksTPC.size(), useGlobalTracks ? "global tracks" : "TPC only tracks");
156209
sendOutput(pc.outputs());
157210
mMIPTracks.clear();
158211
}
@@ -162,6 +215,11 @@ void MIPTrackFilterDevice::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
162215
if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
163216
return;
164217
}
218+
if (matcher == ConcreteDataMatcher("GLO", "MEANVERTEX", 0)) {
219+
LOG(info) << "Setting new MeanVertex: " << ((const o2::dataformats::MeanVertexObject*)obj)->asString();
220+
mVtx = *(const o2::dataformats::MeanVertexObject*)obj;
221+
return;
222+
}
165223
}
166224

167225
void MIPTrackFilterDevice::sendOutput(DataAllocator& output) { output.snapshot(Output{header::gDataOriginTPC, "MIPS", 0}, mMIPTracks); }
@@ -171,44 +229,46 @@ void MIPTrackFilterDevice::endOfStream(EndOfStreamContext& eos)
171229
LOG(info) << "Finalizig MIP Tracks filter";
172230
}
173231

174-
bool MIPTrackFilterDevice::acceptDCA(const TrackTPC& track)
232+
bool MIPTrackFilterDevice::acceptDCA(o2::track::TrackPar propTrack, o2::math_utils::Point3D<float> refPoint, bool useDCAz)
175233
{
176234
if (mDCACut < 0) {
177235
return true;
178236
}
179237

180238
auto propagator = o2::base::Propagator::Instance();
181239
std::array<float, 2> dca;
182-
const o2::math_utils::Point3D<float> refPoint{0, 0, 0};
183-
o2::track::TrackPar propTrack(track);
184240
const auto ok = propagator->propagateToDCABxByBz(refPoint, propTrack, 2., o2::base::Propagator::MatCorrType::USEMatCorrLUT, &dca);
185241
const auto dcar = std::abs(dca[0]);
186242

187-
return ok && (dcar < mDCACut);
243+
return ok && (dcar < mDCACut) && (!useDCAz || (std::abs(dca[1]) < mDCAZCut));
188244
}
189245

190-
DataProcessorSpec getMIPTrackFilterSpec()
246+
DataProcessorSpec getMIPTrackFilterSpec(GID::mask_t srcTracks)
191247
{
192248
std::vector<OutputSpec> outputs;
193249
outputs.emplace_back(header::gDataOriginTPC, "MIPS", 0, Lifetime::Sporadic);
194250

195-
std::vector<InputSpec> inputs;
196-
inputs.emplace_back("tracks", "TPC", "TRACKS");
251+
const auto useMC = false;
252+
auto dataRequest = std::make_shared<DataRequest>();
253+
dataRequest->requestTracks(srcTracks, useMC);
254+
dataRequest->requestPrimaryVertices(useMC);
197255

198256
auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
199257
true, // GRPECS=true
200258
false, // GRPLHCIF
201259
true, // GRPMagField
202260
true, // askMatLUT
203261
o2::base::GRPGeomRequest::Aligned, // geometry
204-
inputs,
262+
dataRequest->inputs,
205263
true);
206264

265+
dataRequest->inputs.emplace_back("meanvtx", "GLO", "MEANVERTEX", 0, Lifetime::Condition, o2::framework::ccdbParamSpec("GLO/Calib/MeanVertex", {}, 1));
266+
207267
return DataProcessorSpec{
208268
"tpc-miptrack-filter",
209-
inputs,
269+
dataRequest->inputs,
210270
outputs,
211-
adaptFromTask<MIPTrackFilterDevice>(ggRequest),
271+
adaptFromTask<MIPTrackFilterDevice>(ggRequest, dataRequest, srcTracks),
212272
Options{
213273
{"min-momentum", VariantType::Double, 0.35, {"minimum momentum cut"}},
214274
{"max-momentum", VariantType::Double, 0.55, {"maximum momentum cut"}},
@@ -220,7 +280,8 @@ DataProcessorSpec getMIPTrackFilterSpec()
220280
{"process-first-n-TFs", VariantType::Int, 1, {"Number of first TFs which are not sampled"}},
221281
{"send-dummy-data", VariantType::Bool, false, {"Send empty data in case TF is skipped"}},
222282
{"dont-cut-loopers", VariantType::Bool, false, {"Do not cut loopers by comparing zout-zin"}},
223-
{"dca-cut", VariantType::Float, 3.f, {"DCA cut in cm, < 0 to disable"}},
283+
{"dca-cut", VariantType::Float, 3.f, {"DCA cut in xy (cm), < 0 to disable cut in xy and z"}},
284+
{"dca-z-cut", VariantType::Float, 5.f, {"DCA cut in z (cm)"}},
224285
}};
225286
}
226287

Detectors/TPC/workflow/src/tpc-miptrack-filter.cxx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
#include "TPCWorkflow/MIPTrackFilterSpec.h"
1414
#include "Framework/ConfigParamSpec.h"
1515
#include "DataFormatsTPC/TrackTPC.h"
16+
#include "GlobalTrackingWorkflowHelpers/InputHelper.h"
17+
#include "ReconstructionDataFormats/GlobalTrackID.h"
18+
19+
using GID = o2::dataformats::GlobalTrackID;
1620

1721
template <typename T>
1822
using BranchDefinition = MakeRootTreeWriterSpec::BranchDefinition<T>;
@@ -21,6 +25,8 @@ void customize(std::vector<ConfigParamSpec>& workflowOptions)
2125
{
2226
std::vector<ConfigParamSpec> options{
2327
{"enable-writer", VariantType::Bool, false, {"selection string input specs"}},
28+
{"use-global-tracks", VariantType::Bool, false, {"use global matched tracks instead of TPC only"}},
29+
{"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}},
2430
};
2531

2632
std::swap(workflowOptions, options);
@@ -33,8 +39,17 @@ WorkflowSpec defineDataProcessing(ConfigContext const& config)
3339
{
3440
using namespace o2::tpc;
3541

42+
const auto useGlobal = config.options().get<bool>("use-global-tracks");
3643
WorkflowSpec workflow;
37-
workflow.emplace_back(getMIPTrackFilterSpec());
44+
45+
const auto useMC = false;
46+
auto srcTracks = GID::getSourcesMask("TPC");
47+
const auto srcCls = GID::getSourcesMask("");
48+
if (useGlobal) {
49+
srcTracks = GID::getSourcesMask("ITS,TPC,ITS-TPC,ITS-TPC-TRD,ITS-TPC-TOF,ITS-TPC-TRD-TOF");
50+
}
51+
52+
workflow.emplace_back(getMIPTrackFilterSpec(srcTracks));
3853

3954
if (config.options().get<bool>("enable-writer")) {
4055
const char* processName = "tpc-mips-writer";

0 commit comments

Comments
 (0)