Skip to content

Commit 7740993

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 f72e1a2 commit 7740993

File tree

5 files changed

+136
-46
lines changed

5 files changed

+136
-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: 100 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,61 @@ 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();
122133

123-
if ((mMaxTracksPerTF != -1) && (nTracks > mMaxTracksPerTF)) {
124-
// indices to good tracks
125-
std::vector<size_t> indices;
126-
indices.reserve(nTracks);
134+
o2::globaltracking::RecoContainer recoData;
135+
recoData.collectData(pc, *mDataRequest);
136+
const auto tracksTPC = recoData.getTPCTracks();
137+
const auto nTracks = tracksTPC.size();
138+
139+
// indices to good tracks
140+
std::vector<size_t> indices;
141+
indices.reserve(nTracks);
142+
143+
const auto useGlobalTracks = mTrackSourcesMask[GID::ITSTPC];
144+
o2::math_utils::Point3D<float> vertex = mVtx.getXYZ();
145+
146+
if (useGlobalTracks) {
147+
auto trackIndex = recoData.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
148+
auto vtxRefs = recoData.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
149+
std::vector<GID::Source> selSrc{GID::ITSTPC, GID::ITSTPCTRD, GID::ITSTPCTRDTOF}; // for Instance
150+
// LOGP(info, "Number of vertex tracks: {}", vtxRefs.size());
151+
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
152+
153+
for (int iv = 0; iv < nv; iv++) {
154+
const auto& vtref = vtxRefs[iv];
155+
//LOGP(info, "Processing vertex {} with {} tracks", iv, vtref.getEntries());
156+
vertex = recoData.getPrimaryVertex(iv).getXYZ();
157+
//LOGP(info, "Vertex position: x={} y={} z={}", vertex.x(), vertex.y(), vertex.z());
158+
159+
for (auto src : selSrc) {
160+
int idMin = vtxRefs[iv].getFirstEntryOfSource(src), idMax = idMin + vtxRefs[iv].getEntriesOfSource(src);
161+
//LOGP(info, "Source {}: idMin={} idMax={}", GID::getSourceName(src), idMin, idMax);
162+
163+
for (int i = idMin; i < idMax; i++) {
164+
auto vid = trackIndex[i];
165+
const auto& track = recoData.getTrackParam(vid); // this is a COPY of the track param which we will modify during DCA calculation
166+
auto gidTPC = recoData.getTPCContributorGID(vid);
167+
if (gidTPC.isSourceSet()) {
168+
const auto idxTPC = gidTPC.getIndex();
169+
if (mCuts.goodTrack(tracksTPC[idxTPC]) && acceptDCA(tracksTPC[idxTPC], vertex, true)) {
170+
indices.emplace_back(idxTPC);
171+
}
172+
}
173+
}
174+
}
175+
}
176+
177+
} else {
127178
for (size_t i = 0; i < nTracks; ++i) {
128-
if (mCuts.goodTrack(tracks[i]) && acceptDCA(tracks[i])) {
179+
if (mCuts.goodTrack(tracksTPC[i]) && acceptDCA(tracksTPC[i], vertex)) {
129180
indices.emplace_back(i);
130181
}
131182
}
183+
}
184+
185+
size_t nTracksSel = indices.size();
132186

187+
if ((mMaxTracksPerTF != -1) && (nTracksSel > mMaxTracksPerTF)) {
133188
// in case no good tracks have been found
134189
if (indices.empty()) {
135190
mMIPTracks.clear();
@@ -144,15 +199,14 @@ void MIPTrackFilterDevice::run(ProcessingContext& pc)
144199
std::shuffle(indices.begin(), indices.end(), rng);
145200

146201
// 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); });
202+
nTracksSel = (mMaxTracksPerTF > indices.size()) ? indices.size() : mMaxTracksPerTF;
203+
}
204+
205+
for (int i = 0; i < nTracksSel; ++i) {
206+
mMIPTracks.emplace_back(tracksTPC[indices[i]]);
153207
}
154208

155-
LOGP(info, "Filtered {} MIP tracks out of {} total tpc tracks", mMIPTracks.size(), tracks.size());
209+
LOGP(info, "Filtered {} / {} MIP tracks out of {} total tpc tracks, using {}", mMIPTracks.size(), indices.size(), tracksTPC.size(), useGlobalTracks ? "global tracks" : "TPC only tracks");
156210
sendOutput(pc.outputs());
157211
mMIPTracks.clear();
158212
}
@@ -162,6 +216,11 @@ void MIPTrackFilterDevice::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
162216
if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) {
163217
return;
164218
}
219+
if (matcher == ConcreteDataMatcher("GLO", "MEANVERTEX", 0)) {
220+
LOG(info) << "Setting new MeanVertex: " << ((const o2::dataformats::MeanVertexObject*)obj)->asString();
221+
mVtx = *(const o2::dataformats::MeanVertexObject*)obj;
222+
return;
223+
}
165224
}
166225

167226
void MIPTrackFilterDevice::sendOutput(DataAllocator& output) { output.snapshot(Output{header::gDataOriginTPC, "MIPS", 0}, mMIPTracks); }
@@ -171,44 +230,46 @@ void MIPTrackFilterDevice::endOfStream(EndOfStreamContext& eos)
171230
LOG(info) << "Finalizig MIP Tracks filter";
172231
}
173232

174-
bool MIPTrackFilterDevice::acceptDCA(const TrackTPC& track)
233+
bool MIPTrackFilterDevice::acceptDCA(o2::track::TrackPar propTrack, o2::math_utils::Point3D<float> refPoint, bool useDCAz)
175234
{
176235
if (mDCACut < 0) {
177236
return true;
178237
}
179238

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

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

190-
DataProcessorSpec getMIPTrackFilterSpec()
247+
DataProcessorSpec getMIPTrackFilterSpec(GID::mask_t srcTracks)
191248
{
192249
std::vector<OutputSpec> outputs;
193250
outputs.emplace_back(header::gDataOriginTPC, "MIPS", 0, Lifetime::Sporadic);
194251

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

198257
auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
199258
true, // GRPECS=true
200259
false, // GRPLHCIF
201260
true, // GRPMagField
202261
true, // askMatLUT
203262
o2::base::GRPGeomRequest::Aligned, // geometry
204-
inputs,
263+
dataRequest->inputs,
205264
true);
206265

266+
dataRequest->inputs.emplace_back("meanvtx", "GLO", "MEANVERTEX", 0, Lifetime::Condition, o2::framework::ccdbParamSpec("GLO/Calib/MeanVertex", {}, 1));
267+
207268
return DataProcessorSpec{
208269
"tpc-miptrack-filter",
209-
inputs,
270+
dataRequest->inputs,
210271
outputs,
211-
adaptFromTask<MIPTrackFilterDevice>(ggRequest),
272+
adaptFromTask<MIPTrackFilterDevice>(ggRequest, dataRequest, srcTracks),
212273
Options{
213274
{"min-momentum", VariantType::Double, 0.35, {"minimum momentum cut"}},
214275
{"max-momentum", VariantType::Double, 0.55, {"maximum momentum cut"}},
@@ -220,7 +281,8 @@ DataProcessorSpec getMIPTrackFilterSpec()
220281
{"process-first-n-TFs", VariantType::Int, 1, {"Number of first TFs which are not sampled"}},
221282
{"send-dummy-data", VariantType::Bool, false, {"Send empty data in case TF is skipped"}},
222283
{"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"}},
284+
{"dca-cut", VariantType::Float, 3.f, {"DCA cut in xy (cm), < 0 to disable cut in xy and z"}},
285+
{"dca-z-cut", VariantType::Float, 5.f, {"DCA cut in z (cm)"}},
224286
}};
225287
}
226288

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)