Project
Loading...
Searching...
No Matches
AvgClusSize.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
15
18
19#include "Framework/Task.h"
23#include "ITStracking/IOUtils.h"
38
39#include <cmath>
40#include <numeric>
41#include <TH1F.h>
42#include <TH2F.h>
43#include <THStack.h>
44#include <TFile.h>
45#include <TCanvas.h>
46#include <TLine.h>
47#include <TStyle.h>
48#include <TNtuple.h>
49
50namespace o2
51{
52namespace its
53{
54namespace study
55{
56using namespace o2::framework;
57using namespace o2::globaltracking;
58
68
69class AvgClusSizeStudy final : public Task
70{
71 public:
72 AvgClusSizeStudy(std::shared_ptr<DataRequest> dr,
73 std::shared_ptr<o2::base::GRPGeomRequest> gr,
74 bool isMC,
75 std::shared_ptr<o2::steer::MCKinematicsReader> kineReader) : mDataRequest{dr}, mGGCCDBRequest(gr), mUseMC(isMC), mKineReader(kineReader){};
76 ~AvgClusSizeStudy() final = default;
77 void init(InitContext& ic) final;
78 void run(ProcessingContext&) final;
80 void finaliseCCDB(ConcreteDataMatcher&, void*) final;
81 void setClusterDictionary(const o2::itsmft::TopologyDictionary* d) { mDict = d; }
82
83 private:
84 // Other functions
87
88 // Helper functions
89 void prepareOutput();
90 void setStyle();
91 void updateTimeDependentParams(ProcessingContext& pc);
92 float getAverageClusterSize(o2::its::TrackITS*);
93 float calcV0HypoMass(const V0&, PID, PID);
94 void calcAPVars(const V0&, float*, float*);
95 void getClusterSizes(std::vector<int>&, int offs, const gsl::span<const o2::itsmft::CompClusterExt>, gsl::span<const unsigned char>::iterator&, const o2::itsmft::TopologyDictionary*);
96 void saveHistograms();
97 void plotHistograms();
98 void fillEtaBin(float eta, float clusSize, int i);
99
100 // Running options
101 bool mUseMC;
102
103 // Data
104 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
105 std::shared_ptr<DataRequest> mDataRequest;
106 o2::itsmft::ClustersPerLayer<int> mClusterSizes; // addressed by the composed (layer,index) ID
107 gsl::span<const int> mInputITSidxs;
108 std::vector<o2::MCTrack> mMCTracks;
109 const o2::itsmft::TopologyDictionary* mDict = nullptr;
110
111 // Output plots
112 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
113 std::unique_ptr<TNtuple> mOutputNtupleAll;
114 std::unique_ptr<TNtuple> mOutputNtupleCut;
115
116 std::unique_ptr<THStack> mMCR{};
117 std::unique_ptr<THStack> mMCCosPA{};
118 std::unique_ptr<THStack> mMCPosACS{};
119 std::unique_ptr<THStack> mMCNegACS{};
120 std::unique_ptr<THStack> mMCDauDCA{};
121 std::unique_ptr<THStack> mMCPosPVDCA{};
122 std::unique_ptr<THStack> mMCNegPVDCA{};
123 std::unique_ptr<THStack> mMCV0PVDCA{};
124
125 std::unique_ptr<TH1F> mMCRisTg{};
126 std::unique_ptr<TH1F> mMCRisBg{};
127 std::unique_ptr<TH1F> mMCCosPAisTg{};
128 std::unique_ptr<TH1F> mMCCosPAisBg{};
129 std::unique_ptr<TH1F> mMCPosACSisTg{};
130 std::unique_ptr<TH1F> mMCPosACSisBg{};
131 std::unique_ptr<TH1F> mMCNegACSisTg{};
132 std::unique_ptr<TH1F> mMCNegACSisBg{};
133 std::unique_ptr<TH1F> mMCDauDCAisTg{};
134 std::unique_ptr<TH1F> mMCDauDCAisBg{};
135 std::unique_ptr<TH1F> mMCPosPVDCAisTg{};
136 std::unique_ptr<TH1F> mMCPosPVDCAisBg{};
137 std::unique_ptr<TH1F> mMCNegPVDCAisTg{};
138 std::unique_ptr<TH1F> mMCNegPVDCAisBg{};
139 std::unique_ptr<TH1F> mMCV0PVDCAisTg{};
140 std::unique_ptr<TH1F> mMCV0PVDCAisBg{};
141
142 std::unique_ptr<TH2F> mMCArmPodolisTg{};
143 std::unique_ptr<TH2F> mMCArmPodolisBg{};
144
145 std::unique_ptr<THStack> mAvgClusSizeCEta{};
146 std::vector<std::unique_ptr<TH1F>> mAvgClusSizeCEtaVec{};
147
148 std::vector<float> mEtaBinUL; // upper edges for eta bins
149
150 // Counters for target V0 identification
151 int nNotValid = 0;
152 int nNullptrs = 0;
153 int nMotherIDMismatch = 0;
154 int nEvIDMismatch = 0;
155 int nTargetV0 = 0;
156 int nNotTargetV0 = 0;
157 int nV0OutOfEtaRange = 0;
158
159 std::string mOutName;
160 std::shared_ptr<o2::steer::MCKinematicsReader> mKineReader;
161};
162
164{
166 LOGP(info, "Starting average cluster size study...");
167
168 prepareOutput();
169
170 if (mUseMC) { // for counting the missed K0shorts
171 mKineReader = std::make_unique<o2::steer::MCKinematicsReader>("collisioncontext.root");
172 for (int iEvent{0}; iEvent < mKineReader->getNEvents(0); iEvent++) {
173 auto mctrk = mKineReader->getTracks(0, iEvent);
174 mMCTracks.insert(mMCTracks.end(), mctrk.begin(), mctrk.end());
175 }
176 }
177
178 LOGP(info, "Cluster size study initialized.");
179}
180
181void AvgClusSizeStudy::prepareOutput()
182{
184 mOutName = params.outFileName;
185 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(mOutName.c_str(), "recreate");
186 mOutputNtupleAll = std::make_unique<TNtuple>("v0_data", "v0 data", "dPosACS:dNegACS:cosPA:V0R:eta:dauDCA:dPospvDCA:dNegpvDCA:v0pvDCA:alpha:pT:K0mass:lambdaMass:antilambdaMass:v0PDGcode");
187 mOutputNtupleCut = std::make_unique<TNtuple>("cut_v0_data", "v0 data (cut)", "dPosACS:dNegACS:cosPA:V0R:eta:dauDCA:dPospvDCA:dNegpvDCA:v0pvDCA:alpha:pT:K0mass:lambdaMass:antilambdaMass:v0PDGcode");
188
189 mMCR = std::make_unique<THStack>("R", "V0 decay length R;R (cm?)");
190 mMCCosPA = std::make_unique<THStack>("cosPA", "cos(#theta_{p})");
191 mMCPosACS = std::make_unique<THStack>("acsPos", "Average cluster size per track;pixels / cluster / track");
192 mMCNegACS = std::make_unique<THStack>("acsNeg", "Average cluster size per track;pixels / cluster / track");
193 mMCDauDCA = std::make_unique<THStack>("dauDCA", "Prong-prong DCA;cm?");
194 mMCPosPVDCA = std::make_unique<THStack>("posPVDCA", "Positive prong-primary vertex DCA;cm?");
195 mMCNegPVDCA = std::make_unique<THStack>("negPVDCA", "Negative prong-primary vertex DCA;cm?");
196 mMCV0PVDCA = std::make_unique<THStack>("v0PVDCA", "V0 reconstructed track-primary vertex DCA;cm?");
197
198 mMCRisTg = std::make_unique<TH1F>("mcRTg", "target V0", 40, 0, 2);
199 mMCRisBg = std::make_unique<TH1F>("mcRBg", "background", 100, 0, 2);
200 mMCCosPAisTg = std::make_unique<TH1F>("mcCosPATg", "target V0", 40, 0, 1);
201 mMCCosPAisBg = std::make_unique<TH1F>("mcCosPABg", "background", 100, 0, 1);
202 mMCPosACSisTg = std::make_unique<TH1F>("mcPosACSTg", "target V0", 60, 0, 30);
203 mMCPosACSisBg = std::make_unique<TH1F>("mcPosACSBg", "background", 150, 0, 30);
204 mMCNegACSisTg = std::make_unique<TH1F>("mcNegACSTg", "target V0", 60, 0, 30);
205 mMCNegACSisBg = std::make_unique<TH1F>("mcNegACSBg", "background", 150, 0, 30);
206 mMCDauDCAisTg = std::make_unique<TH1F>("mcDauDCATg", "target V0", 40, 0, 2);
207 mMCDauDCAisBg = std::make_unique<TH1F>("mcDauDCABg", "background", 100, 0, 2);
208 mMCPosPVDCAisTg = std::make_unique<TH1F>("mcPosPVDCATg", "target V0", 40, 0, 15);
209 mMCPosPVDCAisBg = std::make_unique<TH1F>("mcPosPVDCABg", "background", 100, 0, 15);
210 mMCNegPVDCAisTg = std::make_unique<TH1F>("mcNegPVDCATg", "target V0", 40, 0, 15);
211 mMCNegPVDCAisBg = std::make_unique<TH1F>("mcNegPVDCABg", "background", 100, 0, 15);
212 mMCV0PVDCAisTg = std::make_unique<TH1F>("mcV0PVDCATg", "target V0", 40, 0, 15);
213 mMCV0PVDCAisBg = std::make_unique<TH1F>("mcV0PVDCABg", "background", 100, 0, 15);
214
215 mMCArmPodolisTg = std::make_unique<TH2F>("apPlotTg", "Armenteros-Podolanski;#alpha_{Arm};p_{T}^{Arm} (GeV/c)", 150, -2, 2, 150, 0, 0.5);
216 mMCArmPodolisBg = std::make_unique<TH2F>("apPlotBg", "Armenteros-Podolanski;#alpha_{Arm};p_{T}^{Arm} (GeV/c)", 150, -2, 2, 150, 0, 0.5);
217
218 mAvgClusSizeCEta = std::make_unique<THStack>("avgclussizeeta", "Average cluster size per track;pixels / cluster / track"); // auto-set axis ranges
219 float binWidth = (params.etaMax - params.etaMin) / (float)params.etaNBins;
220 mEtaBinUL.reserve(params.etaNBins);
221 for (int i = 0; i < params.etaNBins; i++) {
222 mEtaBinUL.emplace_back(params.etaMin + (binWidth * (i + 1)));
223 mAvgClusSizeCEtaVec.push_back(std::make_unique<TH1F>(Form("avgclussize%i", i), Form("%.2f < #eta < %.2f", mEtaBinUL[i] - binWidth, mEtaBinUL[i]), params.sizeNBins, 0, params.sizeMax));
224 mAvgClusSizeCEtaVec[i]->SetDirectory(nullptr);
225 mAvgClusSizeCEta->Add(mAvgClusSizeCEtaVec[i].get());
226 }
227
228 mMCRisTg->SetDirectory(nullptr);
229 mMCRisBg->SetDirectory(nullptr);
230 mMCCosPAisTg->SetDirectory(nullptr);
231 mMCCosPAisBg->SetDirectory(nullptr);
232 mMCDauDCAisTg->SetDirectory(nullptr);
233 mMCDauDCAisBg->SetDirectory(nullptr);
234 mMCPosACSisTg->SetDirectory(nullptr);
235 mMCPosACSisBg->SetDirectory(nullptr);
236 mMCNegACSisTg->SetDirectory(nullptr);
237 mMCNegACSisBg->SetDirectory(nullptr);
238 mMCPosPVDCAisTg->SetDirectory(nullptr);
239 mMCPosPVDCAisBg->SetDirectory(nullptr);
240 mMCNegPVDCAisTg->SetDirectory(nullptr);
241 mMCNegPVDCAisBg->SetDirectory(nullptr);
242 mMCV0PVDCAisTg->SetDirectory(nullptr);
243 mMCV0PVDCAisBg->SetDirectory(nullptr);
244
245 mMCArmPodolisTg->SetDirectory(nullptr);
246 mMCArmPodolisBg->SetDirectory(nullptr);
247
248 mOutputNtupleAll->SetDirectory(nullptr);
249 mOutputNtupleCut->SetDirectory(nullptr);
250
251 mMCR->Add(mMCRisTg.get());
252 mMCR->Add(mMCRisBg.get());
253 mMCCosPA->Add(mMCCosPAisTg.get());
254 mMCCosPA->Add(mMCCosPAisBg.get());
255 mMCPosACS->Add(mMCPosACSisTg.get());
256 mMCPosACS->Add(mMCPosACSisBg.get());
257 mMCNegACS->Add(mMCNegACSisTg.get());
258 mMCNegACS->Add(mMCNegACSisBg.get());
259 mMCDauDCA->Add(mMCDauDCAisTg.get());
260 mMCDauDCA->Add(mMCDauDCAisBg.get());
261 mMCPosPVDCA->Add(mMCPosPVDCAisTg.get());
262 mMCPosPVDCA->Add(mMCPosPVDCAisBg.get());
263 mMCNegPVDCA->Add(mMCNegPVDCAisTg.get());
264 mMCNegPVDCA->Add(mMCNegPVDCAisBg.get());
265 mMCV0PVDCA->Add(mMCV0PVDCAisTg.get());
266 mMCV0PVDCA->Add(mMCV0PVDCAisBg.get());
267}
268
269void AvgClusSizeStudy::setStyle()
270{
271 gStyle->SetPalette(kRainBow);
272 std::vector<int> colors = {1, 2, 3, 4, 6, 7, 41, 47};
273 std::vector<int> markers = {2, 3, 4, 5, 25, 26, 27, 28, 32};
274 for (int i = 0; i < mAvgClusSizeCEtaVec.size(); i++) {
275 mAvgClusSizeCEtaVec[i]->SetMarkerStyle(markers[i]);
276 mAvgClusSizeCEtaVec[i]->SetMarkerColor(colors[i]);
277 mAvgClusSizeCEtaVec[i]->SetLineColor(colors[i]);
278 }
279
280 mMCRisTg->SetLineColor(kRed);
281 mMCCosPAisTg->SetLineColor(kRed);
282 mMCPosACSisTg->SetLineColor(kRed);
283 mMCNegACSisTg->SetLineColor(kRed);
284 mMCDauDCAisTg->SetLineColor(kRed);
285 mMCPosPVDCAisTg->SetLineColor(kRed);
286 mMCNegPVDCAisTg->SetLineColor(kRed);
287 mMCV0PVDCAisTg->SetLineColor(kRed);
288}
289
291{
292 // auto geom = o2::its::GeometryTGeo::Instance();
294 recoData.collectData(pc, *mDataRequest.get());
295 updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions
296 process(recoData);
297}
298
299void AvgClusSizeStudy::getClusterSizes(std::vector<int>& clusSizeVec, int offs, const gsl::span<const o2::itsmft::CompClusterExt> ITSclus, gsl::span<const unsigned char>::iterator& pattIt, const o2::itsmft::TopologyDictionary* mdict)
300{
301 for (unsigned int iClus{0}; iClus < ITSclus.size(); ++iClus) {
302 auto& clus = ITSclus[iClus];
303 auto pattID = clus.getPatternID();
304 int npix;
306
307 if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mdict->isGroup(pattID)) {
308 patt.acquirePattern(pattIt);
309 npix = patt.getNPixels();
310 } else {
311 npix = mdict->getNpixels(pattID);
312 patt = mdict->getPattern(pattID);
313 }
314 clusSizeVec[offs + iClus] = npix;
315 }
316}
317
318void AvgClusSizeStudy::loadData(o2::globaltracking::RecoContainer& recoData)
319{
320 mInputITSidxs = recoData.getITSTracksClusterRefs();
321 int nLr = recoData.getITSPerLayer() ? o2::globaltracking::MaxITSLayers : 1;
322 mClusterSizes.init(nLr);
323 for (int lr = 0; lr < nLr; lr++) { // with a single (monolithic) input all clusters are in the layer slot 0
324 mClusterSizes.beginLayer(lr);
325 auto compClus = recoData.getITSClusters(lr);
326 auto clusPatt = recoData.getITSClustersPatterns(lr);
327 auto pattIt = clusPatt.begin();
328 auto& sizes = mClusterSizes.getClusters();
329 int offs = (int)sizes.size();
330 sizes.resize(offs + compClus.size());
331 getClusterSizes(sizes, offs, compClus, pattIt, mDict);
332 }
333 mClusterSizes.finalize();
334}
335
336void AvgClusSizeStudy::process(o2::globaltracking::RecoContainer& recoData)
337{
339 float dPosACS, dNegACS, dauDCA, cosPA, v0R, eta, dPospvDCA, dNegpvDCA, v0pvDCA, tgV0HypoMass, bgV0HypoMass, alphaArm, pT; // ACS=average cluster size
340 bool isMCTarget = false;
341 int targetPDGCode = 310;
342 TrackITS dPosRecoTrk, dNegRecoTrk; // daughter ITS tracks
343 DCA dPosDCA, dNegDCA, v0DCA; // DCA object for prong to primary vertex (DCA = o2::dataformats::DCA)
344 PVertex pv;
345
346 PID targetV0 = PID("K0");
347 PID backgroundV0 = PID("Lambda");
348 PID tgPos, tgNeg, bgPos, bgNeg;
349 if (params.targetV0 == "K0") {
350 bgPos = PID("Proton");
351 LOGP(info, "V0 target set to K0-short.");
352 } else if (params.targetV0 == "Lambda") {
353 targetV0 = PID("Lambda");
354 tgPos = PID("Proton");
355 backgroundV0 = PID("K0");
356 targetPDGCode = 3122;
357 LOGP(info, "V0 target set to Lambda.");
358 } else {
359 LOGP(warning, "Given V0 target not recognized, defaulting to K0-short.");
360 bgPos = PID("Proton");
361 }
362
363 // Variables for MC analysis
364 gsl::span<const o2::MCCompLabel> mcLabels;
365 o2::MCCompLabel dPosLab, dNegLab;
366 const o2::MCTrack *V0mcTrk, *dPosMCTrk, *dNegMCTrk;
367 int V0PdgCode, mPosTrkId, mNegTrkId;
368
369 loadData(recoData);
370 auto V0s = recoData.getV0s();
371 auto V0sIdx = recoData.getV0sIdx();
372 size_t nV0s = V0sIdx.size();
373 if (nV0s && nV0s != V0s.size()) {
374 LOGP(fatal, "This data has not secondary vertices kinematics filled");
375 }
376
377 LOGP(info, "Found {} reconstructed V0s.", nV0s);
378 LOGP(info, "Found {} ITS tracks.", recoData.getITSTracks().size());
379 LOGP(info, "Found {} ROFs.", recoData.getITSTracksROFRecords().size());
380 if (mUseMC) {
381 mcLabels = recoData.getITSTracksMCLabels();
382 LOGP(info, "Found {} labels.", mcLabels.size());
383 }
384
385 for (size_t iv = 0; iv < nV0s; iv++) {
386 auto v0 = V0s[iv];
387 const auto& v0Idx = V0sIdx[iv];
388 dPosRecoTrk = recoData.getITSTrack(v0Idx.getProngID(0)); // cannot use v0.getProng() since it returns TrackParCov not TrackITS
389 dNegRecoTrk = recoData.getITSTrack(v0Idx.getProngID(1));
390
391 pv = recoData.getPrimaryVertex(v0Idx.getVertexID()); // extract primary vertex
392 dPosRecoTrk.propagateToDCA(pv, params.b, &dPosDCA); // calculate and store DCA objects for both prongs
393 dNegRecoTrk.propagateToDCA(pv, params.b, &dNegDCA);
394 v0.propagateToDCA(pv, params.b, &v0DCA);
395
396 dPospvDCA = std::sqrt(dPosDCA.getR2()); // extract DCA distance from DCA object
397 dNegpvDCA = std::sqrt(dNegDCA.getR2());
398 v0pvDCA = std::sqrt(v0DCA.getR2());
399
400 eta = v0.getEta();
401 dauDCA = v0.getDCA();
402 cosPA = v0.getCosPA();
403 v0R = std::sqrt(v0.calcR2()); // gives distance from pvertex to origin? in centimeters (?) NOTE: unsure if this is to the primary vertex or to origin
404
405 dPosACS = getAverageClusterSize(&dPosRecoTrk);
406 dNegACS = getAverageClusterSize(&dNegRecoTrk);
407
408 tgV0HypoMass = calcV0HypoMass(v0, tgPos, tgNeg);
409 bgV0HypoMass = calcV0HypoMass(v0, bgPos, bgNeg);
410 calcAPVars(v0, &alphaArm, &pT);
411
412 if (mUseMC) { // check whether queried V0 is the target V0 in MC, and fill the cut validation plots
413 V0PdgCode = 0;
414 isMCTarget = false;
415 dPosLab = mcLabels[v0Idx.getProngID(0)]; // extract MC labels for the prongs
416 dNegLab = mcLabels[v0Idx.getProngID(1)];
417 if (!dPosLab.isValid() || !dNegLab.isValid()) {
418 LOGP(debug, "Daughter MCCompLabel not valid: {}(+) and {}(-). Skipping.", dPosLab.isValid(), dNegLab.isValid());
419 nNotValid++;
420 } else {
421 dPosMCTrk = mKineReader->getTrack(dPosLab);
422 dNegMCTrk = mKineReader->getTrack(dNegLab);
423 if (dPosMCTrk == nullptr || dNegMCTrk == nullptr) {
424 LOGP(debug, "Nullptr found: {}(+) and {}(-). Skipping.", (void*)dPosMCTrk, (void*)dNegMCTrk);
425 nNullptrs++;
426 } else {
427 mPosTrkId = dPosMCTrk->getMotherTrackId();
428 mNegTrkId = dNegMCTrk->getMotherTrackId();
429 LOGP(debug, "Daughter PDG codes: {}(+) and {}(-)", dPosMCTrk->GetPdgCode(), dNegMCTrk->GetPdgCode());
430 if (mPosTrkId != mNegTrkId || mPosTrkId == -1 || mNegTrkId == -1) {
431 LOGP(debug, "Mother track ID mismatch or default -1: {}(+) and {}(-). Skipping.", mPosTrkId, mNegTrkId);
432 nMotherIDMismatch++;
433 } else {
434 if (dNegLab.getEventID() != dPosLab.getEventID()) {
435 LOGP(debug, "Daughter EvID mismatch: {}(+) and {}(-). Skipping.", dPosLab.getEventID(), dNegLab.getEventID());
436 nEvIDMismatch++;
437 } else {
438 V0mcTrk = mKineReader->getTrack(dNegLab.getEventID(), mPosTrkId); // assume daughter MCTracks are in same event as V0 MCTrack
439 V0PdgCode = V0mcTrk->GetPdgCode();
440 if (V0PdgCode == targetPDGCode) {
441 isMCTarget = true;
442 nTargetV0++;
443 } else {
444 nNotTargetV0++;
445 }
446 }
447 }
448 }
449 }
450 if (isMCTarget) {
451 mMCCosPAisTg->Fill(cosPA);
452 mMCDauDCAisTg->Fill(dauDCA);
453 mMCRisTg->Fill(v0R);
454 mMCPosPVDCAisTg->Fill(dPospvDCA);
455 mMCNegPVDCAisTg->Fill(dNegpvDCA);
456 mMCPosACSisTg->Fill(dPosACS);
457 mMCNegACSisTg->Fill(dNegACS);
458 mMCV0PVDCAisTg->Fill(v0pvDCA);
459 mMCArmPodolisTg->Fill(alphaArm, pT);
460 } else {
461 mMCCosPAisBg->Fill(cosPA);
462 mMCDauDCAisBg->Fill(dauDCA);
463 mMCRisBg->Fill(v0R);
464 mMCPosPVDCAisBg->Fill(dPospvDCA);
465 mMCNegPVDCAisBg->Fill(dNegpvDCA);
466 mMCPosACSisBg->Fill(dPosACS);
467 mMCNegACSisBg->Fill(dNegACS);
468 mMCV0PVDCAisBg->Fill(v0pvDCA);
469 mMCArmPodolisBg->Fill(alphaArm, pT);
470 }
471 }
472
473 mOutputNtupleAll->Fill(dPosACS, dNegACS, cosPA, v0R, eta, dauDCA, dPospvDCA, dNegpvDCA, v0pvDCA, alphaArm, pT, calcV0HypoMass(v0, PID::Pion, PID::Pion), calcV0HypoMass(v0, PID::Proton, PID::Pion), calcV0HypoMass(v0, PID::Pion, PID::Proton), (float)V0PdgCode);
474 if ((cosPA > params.cosPAmin || params.disableCosPA) && (v0R < params.Rmax || params.disableRmax) && (v0R > params.Rmin || params.disableRmin) && (dauDCA < params.prongDCAmax || params.disableProngDCAmax) && (dPospvDCA > params.dauPVDCAmin || params.disableDauPVDCAmin) && (dNegpvDCA > params.dauPVDCAmin || params.disableDauPVDCAmin) && (v0pvDCA < params.v0PVDCAmax || params.disableV0PVDCAmax) && (std::abs(bgV0HypoMass - backgroundV0.getMass()) > params.bgV0window || params.disableMassHypoth) && (std::abs(tgV0HypoMass - targetV0.getMass()) < params.tgV0window || params.disableMassHypoth)) {
475 mOutputNtupleCut->Fill(dPosACS, dNegACS, cosPA, v0R, eta, dauDCA, dPospvDCA, dNegpvDCA, v0pvDCA, alphaArm, pT, calcV0HypoMass(v0, PID::Pion, PID::Pion), calcV0HypoMass(v0, PID::Proton, PID::Pion), calcV0HypoMass(v0, PID::Pion, PID::Proton), (float)V0PdgCode);
476 if (eta > params.etaMin && eta < params.etaMax) {
477 fillEtaBin(eta, dPosACS, 0);
478 fillEtaBin(eta, dNegACS, 0);
479 } else {
480 nV0OutOfEtaRange++;
481 }
482 }
483 }
484
485 if (mUseMC) {
486 LOGP(info, "MONTE CARLO OVERALL STATISTICS: {} total V0s, {} nonvalid daughter labels, {} nullptrs, {} motherID mismatches, {} evID mismatches, {} matching target, {} not matching target", V0s.size(), nNotValid, nNullptrs, nMotherIDMismatch, nEvIDMismatch, nTargetV0, nNotTargetV0);
487 int nPrimaryTargetV0 = 0;
488 for (auto& mcTrk : mMCTracks) { // search through all MC tracks to find primary target V0s, whether reconstructed or not
489 if (mcTrk.GetPdgCode() == targetPDGCode && mcTrk.isPrimary()) {
490 nPrimaryTargetV0++;
491 }
492 }
493 LOGP(info, "MONTE CARLO OVERALL STATISTICS: {} MC target V0s (isPrimary) found in MC tracks out of {} total MC tracks", nPrimaryTargetV0, mMCTracks.size());
494 }
495 LOGP(info, "{} V0s out of eta range ({}, {})", nV0OutOfEtaRange, params.etaMin, params.etaMax);
496}
497
498float AvgClusSizeStudy::getAverageClusterSize(TrackITS* daughter)
499{
500 int totalSize{0};
501 auto firstClus = daughter->getFirstClusterEntry();
502 auto ncl = daughter->getNumberOfClusters();
503 for (int icl = 0; icl < ncl; icl++) {
504 totalSize += mClusterSizes[mInputITSidxs[firstClus + icl]];
505 }
506 return (float)totalSize / (float)ncl;
507}
508
509float AvgClusSizeStudy::calcV0HypoMass(const V0& v0, PID hypothPIDPos, PID hypothPIDNeg)
510{
511 // Mass hypothesis calculation; taken from o2::strangeness_tracking::StrangenessTracker::calcMotherMass()
512 std::array<float, 3> pPos, pNeg, pV0;
513 v0.getProng(0).getPxPyPzGlo(pPos);
514 v0.getProng(1).getPxPyPzGlo(pNeg);
515 v0.getPxPyPzGlo(pV0);
516 double m2Pos = PID::getMass2(hypothPIDPos);
517 double m2Neg = PID::getMass2(hypothPIDNeg);
518 double p2Pos = (pPos[0] * pPos[0]) + (pPos[1] * pPos[1]) + (pPos[2] * pPos[2]);
519 double p2Neg = (pNeg[0] * pNeg[0]) + (pNeg[1] * pNeg[1]) + (pNeg[2] * pNeg[2]);
520 double ePos = std::sqrt(p2Pos + m2Pos), eNeg = std::sqrt(p2Neg + m2Neg);
521 double e2V0 = (ePos + eNeg) * (ePos + eNeg);
522 double pxV0 = (pPos[0] + pNeg[0]);
523 double pyV0 = (pPos[1] + pNeg[1]);
524 double pzV0 = (pPos[2] + pNeg[2]);
525 double p2V0 = (pxV0 * pxV0) + (pyV0 * pyV0) + (pzV0 * pzV0);
526 return (float)std::sqrt(e2V0 - p2V0);
527}
528
529void AvgClusSizeStudy::calcAPVars(const V0& v0, float* alphaArm, float* pT)
530{
531 // Calculation of the Armenteros-Podolanski variables
532 std::array<float, 3> pV0, pPos, pNeg;
533 v0.getProng(0).getPxPyPzGlo(pPos);
534 v0.getProng(1).getPxPyPzGlo(pNeg);
535 v0.getPxPyPzGlo(pV0);
536 double p2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1] + pV0[2] * pV0[2];
537 double qNeg = pNeg[0] * pV0[0] + pNeg[1] * pV0[1] + pNeg[2] * pV0[2];
538 double qPos = pPos[0] * pV0[0] + pPos[1] * pV0[1] + pPos[2] * pV0[2];
539 *alphaArm = (float)(qPos - qNeg) / (qPos + qNeg);
540 double p2Pos = pPos[0] * pPos[0] + pPos[1] * pPos[1] + pPos[2] * pPos[2];
541 *pT = (float)std::sqrt(p2Pos - ((qPos * qPos) / p2V0));
542};
543
544void AvgClusSizeStudy::fillEtaBin(float eta, float clusSize, int i)
545{
546 if (eta < mEtaBinUL[i]) {
547 mAvgClusSizeCEtaVec[i]->Fill(clusSize);
548 } else {
549 fillEtaBin(eta, clusSize, i + 1);
550 }
551}
552
553void AvgClusSizeStudy::updateTimeDependentParams(ProcessingContext& pc)
554{
556 static bool initOnceDone = false;
557 if (!initOnceDone) { // this param need to be queried only once
558 initOnceDone = true;
560 geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::T2GRot, o2::math_utils::TransformType::T2G));
561 }
562}
563
564void AvgClusSizeStudy::saveHistograms()
565{
566 mDBGOut.reset();
567 TFile fout(mOutName.c_str(), "RECREATE");
568
569 fout.WriteTObject(mOutputNtupleAll.get());
570 fout.WriteTObject(mOutputNtupleCut.get());
571 fout.WriteTObject(mMCR.get());
572 fout.WriteTObject(mMCCosPA.get());
573 fout.WriteTObject(mMCPosACS.get());
574 fout.WriteTObject(mMCNegACS.get());
575 fout.WriteTObject(mMCDauDCA.get());
576 fout.WriteTObject(mMCPosPVDCA.get());
577 fout.WriteTObject(mMCNegPVDCA.get());
578 fout.WriteTObject(mMCV0PVDCA.get());
579 fout.WriteTObject(mMCArmPodolisTg.get());
580 fout.WriteTObject(mMCArmPodolisBg.get());
581
582 fout.WriteTObject(mAvgClusSizeCEta.get());
583 fout.Close();
584
585 LOGP(info, "Stored histograms into {}", mOutName.c_str());
586}
587
588void AvgClusSizeStudy::plotHistograms()
589{
590 if (mUseMC) {
591 TCanvas* cMCR = new TCanvas();
592 mMCR->Draw("nostack");
593 cMCR->BuildLegend();
594 cMCR->Print("mcR.png");
595 TCanvas* cMCCosPA = new TCanvas();
596 mMCCosPA->Draw("nostack");
597 cMCCosPA->BuildLegend();
598 cMCCosPA->Print("mcCosPA.png");
599 TCanvas* cMCPosACS = new TCanvas();
600 mMCPosACS->Draw("nostack");
601 cMCPosACS->BuildLegend();
602 cMCPosACS->Print("mcPosACS.png");
603 TCanvas* cMCNegACS = new TCanvas();
604 mMCNegACS->Draw("nostack");
605 cMCNegACS->BuildLegend();
606 cMCNegACS->Print("mcNegACS.png");
607 TCanvas* cMCDauDCA = new TCanvas();
608 mMCDauDCA->Draw("nostack");
609 cMCDauDCA->BuildLegend();
610 cMCDauDCA->Print("mcDauDCA.png");
611 TCanvas* cMCPosPVDCA = new TCanvas();
612 mMCPosPVDCA->Draw("nostack");
613 cMCPosPVDCA->BuildLegend();
614 cMCPosPVDCA->Print("mcPosPVDCA.png");
615 TCanvas* cMCNegPVDCA = new TCanvas();
616 mMCNegPVDCA->Draw("nostack");
617 cMCNegPVDCA->BuildLegend();
618 cMCNegPVDCA->Print("mcNegPVDCA.png");
619 TCanvas* cMCV0PVDCA = new TCanvas();
620 mMCV0PVDCA->Draw("nostack");
621 cMCV0PVDCA->BuildLegend();
622 cMCV0PVDCA->Print("mcV0PVDCA.png");
623 TCanvas* cMCArmPodolTg = new TCanvas();
624 mMCArmPodolisTg->Draw("COLZ");
625 cMCArmPodolTg->Print("mcArmPodolTg.png");
626 TCanvas* cMCArmPodolBg = new TCanvas();
627 mMCArmPodolisBg->Draw("COLZ");
628 cMCArmPodolBg->Print("mcArmPodolBg.png");
629 }
630
631 TCanvas* c10 = new TCanvas();
632 mAvgClusSizeCEta->Draw("P NOSTACK");
633 c10->BuildLegend(0.6, 0.6, 0.8, 0.8);
634 c10->Print("clusSizeEta.png");
635}
636
638{
640 setStyle();
641 saveHistograms();
642 if (params.generatePlots) {
643 plotHistograms();
644 }
645}
646
648{
650 return;
651 }
652 // o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj);
653 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
655 return;
656 }
657}
658
659DataProcessorSpec getAvgClusSizeStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr<o2::steer::MCKinematicsReader> kineReader, bool itsStag)
660{
661 std::vector<OutputSpec> outputs;
662 auto dataRequest = std::make_shared<DataRequest>();
663 dataRequest->setITSPerLayer(itsStag);
664 dataRequest->requestTracks(srcTracksMask, useMC);
665 dataRequest->requestClusters(srcClustersMask, useMC);
666 dataRequest->requestSecondaryVertices(useMC);
667 dataRequest->requestPrimaryVertices(useMC); // NOTE: may be necessary to use requestPrimaryVerticesTMP()...
668 // dataRequest->requestPrimaryVerticesTMP(useMC);
669
670 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
671 true, // GRPECS=true
672 false, // GRPLHCIF
673 false, // GRPMagField
674 false, // askMatLUT
676 dataRequest->inputs,
677 true);
678 return DataProcessorSpec{
679 "its-study-AvgClusSize",
680 dataRequest->inputs,
681 outputs,
682 AlgorithmSpec{adaptFromTask<AvgClusSizeStudy>(dataRequest, ggRequest, useMC, kineReader)},
683 Options{}};
684}
685} // namespace study
686} // namespace its
687} // namespace o2
Container of the ITS/MFT clusters addressed by the composed (layer,index) ID.
Wrapper container for different reconstructed object types.
particle ids, masses, names class definition
Base track model for the Barrel, params only, w/o covariance.
std::ostringstream debug
int32_t i
Helper for geometry and GRP related CCDB requests.
Header of the General Run Parameters object.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the GeometryTGeo class.
Definition of the MCTrack class.
Definition of the ITS track.
int getEventID() const
bool isValid() const
Definition MCCompLabel.h:82
Int_t GetPdgCode() const
Accessors.
Definition MCTrack.h:72
Int_t getMotherTrackId() const
Definition MCTrack.h:73
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
o2::gpu::gpustd::bitset< 32 > mask_t
static GeometryTGeo * Instance()
void fillMatrixCache(int mask) override
int getFirstClusterEntry() const
Definition TrackITS.h:71
AvgClusSizeStudy(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, bool isMC, std::shared_ptr< o2::steer::MCKinematicsReader > kineReader)
void init(InitContext &ic) final
void setClusterDictionary(const o2::itsmft::TopologyDictionary *d)
void finaliseCCDB(ConcreteDataMatcher &, void *) final
void run(ProcessingContext &) final
void endOfStream(EndOfStreamContext &) final
This is invoked whenever we have an EndOfStream event.
void acquirePattern(iterator &pattIt)
int getNPixels() const
Returns the number of fired pixels.
void beginLayer(int lr)
to be called once all the layers were filled
void init(int nLr)
< prepare for filling nLr layer slots, discarding the previous content
static constexpr unsigned short InvalidPatternID
Definition CompCluster.h:46
const ClusterPattern & getPattern(int n) const
Returns the pattern of the topology.
int getNpixels(int n) const
Returns the number of fired pixels of the n_th element.
bool isGroup(int n) const
Returns true if the element corresponds to a group of rare topologies.
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
Definition glcorearb.h:2595
GLenum const GLfloat * params
Definition glcorearb.h:272
GLfloat v0
Definition glcorearb.h:811
uint8_t int statusCode int
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::vector< ConfigParamSpec > Options
constexpr int MaxITSLayers
auto get(const std::byte *buffer, size_t=0)
Definition DataHeader.h:457
o2::dataformats::DCA DCA
o2::track::TrackParCov Track
o2::framework::DataProcessorSpec getAvgClusSizeStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr< o2::steer::MCKinematicsReader > kineReader, bool itsStag)
o2::track::PID PID
TrackParCovF TrackParCov
Definition Track.h:33
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
auto getITSClustersPatterns(int layer=0) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::dataformats::PrimaryVertex & getPrimaryVertex(int i) const
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
auto getITSClusters(int layer=0) const