Project
Loading...
Searching...
No Matches
PrimaryVertexReaderSpec.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
14#include <vector>
15
18#include "Framework/Logger.h"
21#include "TFile.h"
22#include "TTree.h"
28
29using namespace o2::framework;
30
31namespace o2
32{
33namespace vertexing
34{
35
36// read primary vertices produces by the o2-primary-vertexing-workflow
38{
39 using Label = o2::MCEventLabel;
43
44 public:
45 PrimaryVertexReader(bool useMC) : mUseMC(useMC) {}
46 ~PrimaryVertexReader() override = default;
47 void init(o2::framework::InitContext& ic) final;
49
50 protected:
51 void connectTree();
52
53 int mVerbose = 0;
54 bool mUseMC = false;
55
56 std::vector<PVertex> mVertices, *mVerticesPtr = &mVertices;
57 std::vector<Label> mLabels, *mLabelsPtr = &mLabels;
59 std::vector<GIndex> mPV2MatchIdx, *mPV2MatchIdxPtr = &mPV2MatchIdx;
60
61 std::unique_ptr<TFile> mFile;
62 std::unique_ptr<TTree> mTree;
63 std::string mFileName = "";
64 std::string mFileNameMatches = "";
65 std::string mVertexTreeName = "o2sim";
66 std::string mVertexBranchName = "PrimaryVertex";
67 std::string mVertexTrackIDsBranchName = "PVTrackIndices";
68 std::string mVertex2TrackIDRefsBranchName = "PV2TrackRefs";
69 std::string mVertexLabelsBranchName = "PVMCTruth";
70};
71
73{
75 ic.options().get<std::string>("primary-vertex-infile"));
76 mVerbose = ic.options().get<int>("vertex-verbosity");
78}
79
81{
82 auto ent = mTree->GetReadEntry() + 1;
83 // A timeframe holds no collision at all whenever the interaction rate is low enough, and
84 // the tree then has no entry to read. Publish empty containers instead of reading past the
85 // end and pushing branch addresses that GetEntry has not filled, so that the consumers
86 // downstream still see the timeframe. (This used to be an assert, which is compiled out of
87 // every production build since ENABLE_CASSERT defaults to OFF.)
88 const bool noEntry = ent >= mTree->GetEntries();
89 if (noEntry) {
90 LOG(info) << "no entry to read, publishing empty output";
91 } else {
92 mTree->GetEntry(ent);
93 }
94 LOG(info) << "Pushing " << mVerticesPtr->size() << " vertices at entry " << ent;
95
96 pc.outputs().snapshot(Output{"GLO", "PVTX", 0}, mVertices);
97 pc.outputs().snapshot(Output{"GLO", "PVTX_TRMTC", 0}, mPV2MatchIdx);
98 pc.outputs().snapshot(Output{"GLO", "PVTX_TRMTCREFS", 0}, mPV2MatchIdxRef);
99
100 if (mUseMC) {
101 pc.outputs().snapshot(Output{"GLO", "PVTX_MCTR", 0}, mLabels);
102 }
103
104 if (mVerbose) {
105 size_t nrec = mPV2MatchIdxRef.size();
106 for (size_t cnt = 0; cnt < nrec; cnt++) {
107 if (cnt < mVertices.size()) {
108 const auto& vtx = mVertices[cnt];
109 Label lb;
110 if (mUseMC) {
111 lb = mLabels[cnt];
112 }
113 LOG(info) << "#" << cnt << " " << mVertices[cnt] << " | MC:" << lb.asString();
114 } else {
115 LOG(info) << "#" << cnt << " this is not a vertex";
116 }
117 LOG(info) << "References: " << mPV2MatchIdxRef[cnt];
118 for (int is = 0; is < GIndex::NSources; is++) {
119 int ncontrib = 0, nambig = 0;
120 int idMin = mPV2MatchIdxRef[cnt].getFirstEntryOfSource(is), idMax = idMin + mPV2MatchIdxRef[cnt].getEntriesOfSource(is);
121 for (int i = idMin; i < idMax; i++) {
122 if (mPV2MatchIdx[i].isPVContributor()) {
123 ncontrib++;
124 } else if (mPV2MatchIdx[i].isAmbiguous()) {
125 nambig++;
126 }
127 }
128 if (mPV2MatchIdxRef[cnt].getEntriesOfSource(is)) {
129 LOGP(info, "{} : total attached: {}, contributors: {}, ambiguous: {}", GIndex::getSourceName(is), mPV2MatchIdxRef[cnt].getEntriesOfSource(is), ncontrib, nambig);
130 }
131 if (mVerbose < 2) {
132 continue;
133 }
134 std::string trIDs;
135 int cntT = 0;
136 for (int i = idMin; i < idMax; i++) {
137 if (mVerbose > 2 || mPV2MatchIdx[i].isPVContributor()) {
138 trIDs += mPV2MatchIdx[i].asString() + " ";
139 if (!((++cntT) % 15)) {
140 LOG(info) << trIDs;
141 trIDs = "";
142 }
143 }
144 }
145 if (!trIDs.empty()) {
146 LOG(info) << trIDs;
147 }
148 }
149 }
150 }
151
152 if (noEntry || mTree->GetReadEntry() + 1 >= mTree->GetEntries()) {
154 pc.services().get<ControlService>().readyToQuit(QuitRequest::Me);
155 }
156}
157
159{
160 mTree.reset(nullptr); // in case it was already loaded
161 mFile.reset(TFile::Open(mFileName.c_str()));
162 assert(mFile && !mFile->IsZombie());
163 mTree.reset((TTree*)mFile->Get(mVertexTreeName.c_str()));
164 assert(mTree);
165 assert(mTree->GetBranch(mVertexBranchName.c_str()));
166 assert(mTree->GetBranch(mVertexTrackIDsBranchName.c_str()));
167 assert(mTree->GetBranch(mVertex2TrackIDRefsBranchName.c_str()));
168
169 mTree->SetBranchAddress(mVertexBranchName.c_str(), &mVerticesPtr);
170 mTree->SetBranchAddress(mVertexTrackIDsBranchName.c_str(), &mPV2MatchIdxPtr);
171 mTree->SetBranchAddress(mVertex2TrackIDRefsBranchName.c_str(), &mPV2MatchIdxRefPtr);
172
173 if (mUseMC) {
174 assert(mTree->GetBranch(mVertexLabelsBranchName.c_str()));
175 mTree->SetBranchAddress(mVertexLabelsBranchName.c_str(), &mLabelsPtr);
176 }
177
178 LOG(info) << "Loaded " << mVertexTreeName << " tree from " << mFileName << " with " << mTree->GetEntries() << " entries";
179}
180
182{
183 std::vector<OutputSpec> outputs;
184 outputs.emplace_back("GLO", "PVTX", 0, Lifetime::Timeframe);
185 outputs.emplace_back("GLO", "PVTX_TRMTC", 0, Lifetime::Timeframe);
186 outputs.emplace_back("GLO", "PVTX_TRMTCREFS", 0, Lifetime::Timeframe);
187
188 if (useMC) {
189 outputs.emplace_back("GLO", "PVTX_MCTR", 0, Lifetime::Timeframe);
190 }
191
192 return DataProcessorSpec{
193 "primary-vertex-reader",
194 Inputs{},
195 outputs,
196 AlgorithmSpec{adaptFromTask<PrimaryVertexReader>(useMC)},
197 Options{
198 {"primary-vertex-infile", VariantType::String, "o2_primary_vertex.root", {"Name of the input primary vertex file"}},
199 {"vertex-track-matches-infile", VariantType::String, "o2_pvertex_track_matches.root", {"Name of the input file with primary vertex - tracks matches"}},
200 {"input-dir", VariantType::String, "none", {"Input directory"}},
201 {"vertex-verbosity", VariantType::Int, 0, {"Print vertex/tracks info: 1) number of contributor and attached, 2) dump contributors 3) full dump"}}}};
202}
203
204} // namespace vertexing
205} // namespace o2
int32_t i
Definition of the Names Generator class.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
std::string asString() const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
Definition InitContext.h:33
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
ServiceRegistryRef services()
The services registry associated with this processing context.
virtual void endOfStream(EndOfStreamContext &context)
This is invoked whenever we have an EndOfStream event.
Definition Task.h:43
~PrimaryVertexReader() override=default
void run(o2::framework::ProcessingContext &pc) final
void init(o2::framework::InitContext &ic) final
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::vector< ConfigParamSpec > Options
std::vector< InputSpec > Inputs
o2::framework::DataProcessorSpec getPrimaryVertexReaderSpec(bool useMC)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static std::string rectifyDirectory(const std::string_view p)
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"