Project
Loading...
Searching...
No Matches
DumpTracks.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
12#include <vector>
13#include <TStopwatch.h>
35
36namespace o2::trackstudy
37{
38
39using namespace o2::framework;
42
48
50
51class DumpTracksSpec : public Task
52{
53 public:
54 DumpTracksSpec(std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> gr, GTrackID::mask_t src, bool useMC)
55 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(src), mUseMC(useMC) {}
56 ~DumpTracksSpec() final = default;
57 void init(InitContext& ic) final;
58 void run(ProcessingContext& pc) final;
59 void endOfStream(EndOfStreamContext& ec) final;
60 void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final;
61 void process(o2::globaltracking::RecoContainer& recoData);
62
63 private:
64 void updateTimeDependentParams(ProcessingContext& pc);
65 std::shared_ptr<DataRequest> mDataRequest;
66 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
67 bool mUseMC{false};
68 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
69 GTrackID::mask_t mTracksSrc{};
70
71 std::vector<long> mGlobalBC;
72 o2::tpc::VDriftHelper mTPCVDriftHelper{};
73 int mBCToler = 0; // tolerance in BC for globalBC selections
74 int mVerbose = 0;
75 float mITSROFrameLengthMUS = 0;
76 float mMFTROFrameLengthMUS = 0;
77 float mMaxTPCDriftTimeMUS = 0;
78 float mTPCTDriftOffset = 0.f;
79 float mTPCBin2MUS = 0;
80};
81
83{
85 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>("trackStudy.root", "recreate");
86
87 mBCToler = ic.options().get<int>("bc-margin");
88 mVerbose = ic.options().get<int>("dump-verbosity");
89 auto bcstr = ic.options().get<std::string>("sel-bc");
90 auto bctok = o2::utils::Str::tokenize(bcstr, ',');
91 if (bctok.empty()) {
92 LOG(error) << "empty BC list is provided " << bcstr;
93 }
94 for (auto& bcs : bctok) {
95 try {
96 long bcglo = std::stol(bcs);
97 mGlobalBC.push_back(bcglo);
98 LOGP(info, "adding {} to global BCs to dump", bcglo);
99 } catch (...) {
100 LOGP(fatal, "failed to extract global BC from {}", bcstr);
101 }
102 }
103}
104
106{
108 recoData.collectData(pc, *mDataRequest.get()); // select tracks of needed type, with minimal cuts, the real selected will be done in the vertexer
109 updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions
110 process(recoData);
111}
112
113void DumpTracksSpec::updateTimeDependentParams(ProcessingContext& pc)
114{
116 mTPCVDriftHelper.extractCCDBInputs(pc);
117 static bool initOnceDone = false;
118 if (!initOnceDone) { // this params need to be queried only once
119 initOnceDone = true;
120 // put here init-once stuff
122 mITSROFrameLengthMUS = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::ITS) ? alpParamsITS.roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingMUS : alpParamsITS.roFrameLengthTrig * 1.e-3;
124 mMFTROFrameLengthMUS = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::MFT) ? alpParamsMFT.roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingMUS : alpParamsMFT.roFrameLengthTrig * 1.e-3;
125 LOGP(info, "VertexTrackMatcher ITSROFrameLengthMUS:{} MFTROFrameLengthMUS:{}", mITSROFrameLengthMUS, mMFTROFrameLengthMUS);
126 }
127 // we may have other params which need to be queried regularly
128 // VDrift may change from time to time
129 if (mTPCVDriftHelper.isUpdated()) {
131 auto& detParam = o2::tpc::ParameterDetector::Instance();
132 mTPCBin2MUS = elParam.ZbinWidth;
133 auto& vd = mTPCVDriftHelper.getVDriftObject();
134 mMaxTPCDriftTimeMUS = detParam.TPClength / (vd.refVDrift * vd.corrFact);
135 mTPCTDriftOffset = vd.getTimeOffset();
136 }
137}
138
140{
141 std::vector<TBracket> selBCTF;
142 auto irMin = recoData.startIR;
144 float tBCErr = mBCToler * o2::constants::lhc::LHCBunchSpacingMUS;
145 LOGP(info, "TF dump for {}:{}", irMin.asString(), irMax.asString());
146
147 for (const auto& bc : mGlobalBC) {
148 if (bc >= irMin.toLong() && bc < irMax.toLong()) {
150 float t = (bc - irMin.toLong()) * o2::constants::lhc::LHCBunchSpacingMUS;
151 LOGP(info, "Selected BC {}({}) -> {}({}) : {}({}) mus", bc, bcir.asString(),
152 t - tBCErr, (bcir - mBCToler).asString(),
153 t + tBCErr, (bcir + mBCToler).asString());
154 selBCTF.emplace_back(t - tBCErr, t + tBCErr);
155 }
156 }
157 if (selBCTF.empty()) {
158 LOGP(info, "No selections for {}:{}", irMin.asString(), irMax.asString());
159 return;
160 }
161
162 auto pvvec = recoData.getPrimaryVertices();
163 auto trackIndex = recoData.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
164 auto vtxRefs = recoData.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
165
166 float itsBias = 0.5 * mITSROFrameLengthMUS + o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance().roFrameBiasInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3; // ITS time is supplied in \mus as beginning of ROF
167 float mftBias = 0.5 * mMFTROFrameLengthMUS + o2::itsmft::DPLAlpideParam<o2::detectors::DetID::MFT>::Instance().roFrameBiasInBC * o2::constants::lhc::LHCBunchSpacingNS * 1e-3; // MFT time is supplied in \mus as beginning of ROF
168
170 auto creator = [this, &selBCTF, itsBias, mftBias, &recoData, &prevSrc](auto& _tr, GTrackID _origID, float t0, float terr) {
171 const auto& PVParams = o2::vertexing::PVertexerParams::Instance();
172 if constexpr (isTPCTrack<decltype(_tr)>()) {
173 // unconstrained TPC track, with t0 = TrackTPC.getTime0+0.5*(DeltaFwd-DeltaBwd) and terr = 0.5*(DeltaFwd+DeltaBwd) in TimeBins
174 t0 *= this->mTPCBin2MUS;
175 t0 -= this->mTPCTDriftOffset;
176 terr *= this->mTPCBin2MUS;
177 } else if constexpr (isITSTrack<decltype(_tr)>()) {
178 t0 += itsBias;
179 terr *= this->mITSROFrameLengthMUS; // error is supplied as a half-ROF duration, convert to \mus
180 } else if constexpr (isMFTTrack<decltype(_tr)>()) { // Same for MFT
181 t0 += mftBias;
182 terr *= this->mMFTROFrameLengthMUS;
183 } else if constexpr (!(isMCHTrack<decltype(_tr)>() || isGlobalFwdTrack<decltype(_tr)>())) {
184 // for all other tracks the time is in \mus with gaussian error
185 terr *= PVParams.nSigmaTimeTrack; // gaussian errors must be scaled by requested n-sigma
186 }
187
188 terr += PVParams.timeMarginTrackTime;
189 TBracket tb{t0 - terr, t0 + terr};
190 for (const auto& stb : selBCTF) {
191 if (tb.isOutside(stb)) {
192 return false;
193 }
194 }
195 auto curSrc = GTrackID::Source(_origID.getSource());
196 if (prevSrc != curSrc) {
197 prevSrc = curSrc;
198 LOGP(info, "Dumping {} tracks", GTrackID::getSourceName(prevSrc));
199 }
200
201 std::string outs;
202 if constexpr (isGlobalFwdTrack<decltype(_tr)>() || isMFTTrack<decltype(_tr)>() || isMCHTrack<decltype(_tr)>() || isMIDTrack<decltype(_tr)>()) {
203 outs = fmt::format("{:>15} {:8.3f}/{:5.3f} -> ", _origID.asString(), t0, terr);
204 } else {
205 outs = fmt::format("{:>15} {:8.3f}/{:5.3f} |{}| -> ", _origID.asString(), t0, terr, ((o2::track::TrackPar)_tr).asString());
206 }
207
208 // contributions
209 auto refs = recoData.getSingleDetectorRefs(_origID);
210 for (auto r : refs) {
211 if (r.isSourceSet()) {
212 outs += fmt::format(" {}", r.asString());
213 }
214 }
215 LOG(info) << outs;
216 return false; // allow redundancy
217 };
218
219 recoData.createTracksVariadic(creator);
220
221 // print matching vertices
222 int pvcnt = 0;
223 for (const auto& pv : pvvec) {
224 TBracket pbv{pv.getIRMin().differenceInBCMUS(irMin), pv.getIRMax().differenceInBCMUS(irMin)};
225 for (const auto& stb : selBCTF) {
226 if (!stb.isOutside(pbv)) {
227 LOG(info) << "#" << pvcnt << " " << pv;
228 LOG(info) << "References: " << vtxRefs[pvcnt];
229 for (int is = 0; is < VTIndex::NSources; is++) {
230 int ncontrib = 0, nambig = 0;
231 int idMin = vtxRefs[pvcnt].getFirstEntryOfSource(is), idMax = idMin + vtxRefs[pvcnt].getEntriesOfSource(is);
232 for (int i = idMin; i < idMax; i++) {
233 if (trackIndex[i].isPVContributor()) {
234 ncontrib++;
235 } else if (trackIndex[i].isAmbiguous()) {
236 nambig++;
237 }
238 }
239 if (vtxRefs[pvcnt].getEntriesOfSource(is)) {
240 LOGP(info, "{} : total attached: {}, contributors: {}, ambiguous: {}", VTIndex::getSourceName(is), vtxRefs[pvcnt].getEntriesOfSource(is), ncontrib, nambig);
241 }
242 if (mVerbose < 2) {
243 continue;
244 }
245 std::string trIDs;
246 int cntT = 0;
247 for (int i = idMin; i < idMax; i++) {
248 if (mVerbose > 2 || trackIndex[i].isPVContributor()) {
249 trIDs += trackIndex[i].asString() + " ";
250 if (!((++cntT) % 15)) {
251 LOG(info) << trIDs;
252 trIDs = "";
253 }
254 }
255 }
256 if (!trIDs.empty()) {
257 LOG(info) << trIDs;
258 }
259 }
260 }
261 pvcnt++;
262 }
263 }
264}
265
267{
268 mDBGOut.reset();
269}
270
272{
274 return;
275 }
276 if (mTPCVDriftHelper.accountCCDBInputs(matcher, obj)) {
277 return;
278 }
279 if (matcher == ConcreteDataMatcher("ITS", "ALPIDEPARAM", 0)) {
280 LOG(info) << "ITS Alpide param updated";
282 par.printKeyValues();
283 return;
284 }
285 if (matcher == ConcreteDataMatcher("MFT", "ALPIDEPARAM", 0)) {
286 LOG(info) << "MFT Alpide param updated";
288 par.printKeyValues();
289 return;
290 }
291}
292
294{
295 std::vector<OutputSpec> outputs;
296 auto dataRequest = std::make_shared<DataRequest>();
297
298 dataRequest->requestTracks(srcTracks, useMC);
299 dataRequest->requestClusters(srcClusters, useMC);
300 dataRequest->requestPrimaryVertices(useMC);
301 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
302 true, // GRPECS=true
303 false, // GRPLHCIF
304 false, // GRPMagField
305 false, // askMatLUT
307 dataRequest->inputs,
308 true);
309 o2::tpc::VDriftHelper::requestCCDBInputs(dataRequest->inputs);
310
311 return DataProcessorSpec{
312 "tracks-dump",
313 dataRequest->inputs,
314 outputs,
315 AlgorithmSpec{adaptFromTask<DumpTracksSpec>(dataRequest, ggRequest, srcTracks, useMC)},
316 Options{
317 {"sel-bc", VariantType::String, "", {"Dump tracks compatible with global BC list"}},
318 {"bc-margin", VariantType::Int, 0, {"Apply margin in BC to selected global BCs list"}},
319 {"dump-verbosity", VariantType::Int, 0, {"Dump verbosity level"}}}};
320}
321
322} // namespace o2::trackstudy
Wrapper container for different reconstructed object types.
uint64_t bc
Definition RawEventData.h:5
Definition of the FIT RecPoints class.
int32_t i
Helper for geometry and GRP related CCDB requests.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the Names Generator class.
Definition of the parameter class for the detector.
Definition of the parameter class for the detector electronics.
Wrapper container for different reconstructed object types.
Result of refitting TPC-ITS matched track.
Helper class to extract VDrift from different sources.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:58
static constexpr ID ITS
Definition DetID.h:63
static constexpr ID MFT
Definition DetID.h:71
ConfigParamRegistry const & options()
Definition InitContext.h:33
static void requestCCDBInputs(std::vector< o2::framework::InputSpec > &inputs, bool laser=true, bool itstpcTgl=true)
void extractCCDBInputs(o2::framework::ProcessingContext &pc, bool laser=true, bool itstpcTgl=true)
const VDriftCorrFact & getVDriftObject() const
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher &matcher, void *obj)
bool isUpdated() const
void init(InitContext &ic) final
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void process(o2::globaltracking::RecoContainer &recoData)
void run(ProcessingContext &pc) final
DumpTracksSpec(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, GTrackID::mask_t src, bool useMC)
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
GLenum src
Definition glcorearb.h:1767
GLboolean r
Definition glcorearb.h:1233
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition glcorearb.h:5034
constexpr double LHCBunchSpacingMUS
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
detail::Bracket< float > Bracketf_t
Definition Primitive2D.h:40
o2::framework::DataProcessorSpec getDumpTracksSpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool useMC)
create a processor spec
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
std::string asString() const
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
void createTracksVariadic(T creator, GTrackID::mask_t srcSel=GTrackID::getSourcesMask("all")) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"