Project
Loading...
Searching...
No Matches
PIDStudy.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
16#include "ITSStudies/PIDStudy.h"
18
19#include "Framework/Task.h"
23#include "ITStracking/IOUtils.h"
40
41#include <numeric>
42#include <TH1F.h>
43#include <TH2F.h>
44#include <THStack.h>
45#include <TFile.h>
46#include <TCanvas.h>
47#include <TLine.h>
48#include <TStyle.h>
49#include <TNtuple.h>
50
51namespace o2
52{
53namespace its
54{
55namespace study
56{
57using namespace o2::framework;
58using namespace o2::globaltracking;
59
71using PID = o2::track::PID;
72
73// structure for storing the output tree
74struct particle {
75 // mc properties
76 int pdg = -1;
77 bool fakeMatch = 0;
78 // reco properties
79 int sign = -1;
84 std::array<int, 7> clSizesITS;
85};
86
87class PIDStudy : public Task
88{
89 public:
90 PIDStudy(std::shared_ptr<DataRequest> dr,
91 std::shared_ptr<o2::base::GRPGeomRequest> gr,
92 bool isMC,
93 std::shared_ptr<o2::steer::MCKinematicsReader> kineReader) : mDataRequest{dr}, mGGCCDBRequest(gr), mUseMC(isMC), mKineReader(kineReader){};
94 ~PIDStudy() final = default;
95 void init(InitContext& ic) final;
96 void run(ProcessingContext&) final;
98 void finaliseCCDB(ConcreteDataMatcher&, void*) final;
99 void setClusterDictionary(const o2::itsmft::TopologyDictionary* d) { mDict = d; }
100
101 private:
102 // Other functions
104 void loadData(o2::globaltracking::RecoContainer&);
105
106 // Helper functions
107 void saveOutput();
108 void updateTimeDependentParams(ProcessingContext& pc);
109 void getClusterSizes(std::vector<int>&, const gsl::span<const o2::itsmft::CompClusterExt>, gsl::span<const unsigned char>::iterator&, const o2::itsmft::TopologyDictionary*);
110 std::array<int, 7> getTrackClusterSizes(const TrackITS& track);
111 float computeNSigma(PID pid, TrackTPC& tpcTrack, float resolution);
112
113 // Running options
114 bool mUseMC;
115
116 PIDResponse mPIDresponse;
117 float mBBres;
118 // Data
119 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
120 std::shared_ptr<DataRequest> mDataRequest;
121 std::vector<int> mClusterSizes;
122 gsl::span<const o2::itsmft::CompClusterExt> mClusters;
123 gsl::span<const int> mInputITSidxs;
124 const o2::itsmft::TopologyDictionary* mDict = nullptr;
125
126 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
127 std::string mOutName;
128 std::shared_ptr<o2::steer::MCKinematicsReader> mKineReader;
129};
130
132{
134 LOGP(info, "Starting average cluster size study...");
135
136 if (mUseMC) { // for counting the missed K0shorts
137 mKineReader = std::make_unique<o2::steer::MCKinematicsReader>("collisioncontext.root");
138 }
140 mOutName = params.outFileName;
141 mPIDresponse.setBetheBlochParams(params.mBBpars);
142 mBBres = params.mBBres;
143 LOGP(info, "PID size study initialized.");
144
145 // prepare output tree
146 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(mOutName.c_str(), "recreate");
147}
148
150{
151 // auto geom = o2::its::GeometryTGeo::Instance();
153 recoData.collectData(pc, *mDataRequest.get());
154 updateTimeDependentParams(pc); // Make sure this is called after recoData.collectData, which may load some conditions
155 process(recoData);
156}
157
158void PIDStudy::getClusterSizes(std::vector<int>& clusSizeVec, const gsl::span<const o2::itsmft::CompClusterExt> ITSclus, gsl::span<const unsigned char>::iterator& pattIt, const o2::itsmft::TopologyDictionary* mdict)
159{
160 for (unsigned int iClus{0}; iClus < ITSclus.size(); ++iClus) {
161 auto& clus = ITSclus[iClus];
162 auto pattID = clus.getPatternID();
163 int npix;
165
166 if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mdict->isGroup(pattID)) {
167 patt.acquirePattern(pattIt);
168 npix = patt.getNPixels();
169 } else {
170 npix = mdict->getNpixels(pattID);
171 patt = mdict->getPattern(pattID);
172 }
173 clusSizeVec[iClus] = npix;
174 }
175}
176
177void PIDStudy::loadData(o2::globaltracking::RecoContainer& recoData)
178{
179 mInputITSidxs = recoData.getITSTracksClusterRefs();
180 mClusters = recoData.getITSClusters();
181 auto clusPatt = recoData.getITSClustersPatterns();
182 mClusterSizes.resize(mClusters.size());
183 auto pattIt = clusPatt.begin();
184 getClusterSizes(mClusterSizes, mClusters, pattIt, mDict);
185}
186
187void PIDStudy::process(o2::globaltracking::RecoContainer& recoData)
188{
189 loadData(recoData);
190 auto ITSTPCtracks = recoData.getTPCITSTracks();
191 LOGP(debug, "Found {} ITSTPC tracks.", ITSTPCtracks.size());
192
193 gsl::span<const o2::MCCompLabel> mcLabelsITS, mcLabelsTPC;
194 if (mUseMC) {
195 mcLabelsITS = recoData.getITSTracksMCLabels();
196 mcLabelsTPC = recoData.getTPCTracksMCLabels();
197 LOGP(debug, "Found {} ITS labels.", mcLabelsITS.size());
198 LOGP(debug, "Found {} TPC labels.", mcLabelsTPC.size());
199 }
200
201 for (unsigned int iTrack{0}; iTrack < ITSTPCtracks.size(); ++iTrack) {
202
203 auto& ITSTPCtrack = ITSTPCtracks[iTrack];
204 if (ITSTPCtrack.getRefITS().getSource() == GTrackID::ITSAB) { // excluding Afterburned tracks
205 continue;
206 }
207 particle part;
208 auto ITStrack = recoData.getITSTrack(ITSTPCtrack.getRefITS());
209 auto TPCtrack = recoData.getTPCTrack(ITSTPCtrack.getRefTPC());
210
211 if (mUseMC) {
212 // MC info
213 auto& mcLabelITS = mcLabelsITS[ITSTPCtrack.getRefITS().getIndex()];
214 auto& mcLabelTPC = mcLabelsTPC[ITSTPCtrack.getRefTPC().getIndex()];
215 if (mcLabelITS.getTrackID() != (int)mcLabelTPC.getTrackID()) {
216 part.fakeMatch = 1;
217 }
218 auto mctrk = mKineReader->getTrack(mcLabelITS);
219 part.pdg = mctrk->GetPdgCode();
220 }
221
222 part.sign = ITSTPCtrack.getSign();
223 part.clSizesITS = getTrackClusterSizes(ITStrack);
224 part.p = ITSTPCtrack.getP();
225 part.pt = ITSTPCtrack.getPt();
226 part.pTPC = TPCtrack.getP();
227 part.pITS = ITStrack.getP();
228 part.eta = ITSTPCtrack.getEta();
229 part.phi = ITSTPCtrack.getPhi();
230 part.tgL = ITSTPCtrack.getTgl();
231 part.chi2ITS = ITStrack.getChi2();
232 part.chi2TPC = TPCtrack.getChi2();
233 part.chi2ITSTPC = ITSTPCtrack.getChi2Match();
234
235 part.clSizeL0 = part.clSizesITS[0];
236 part.clSizeL1 = part.clSizesITS[1];
237 part.clSizeL2 = part.clSizesITS[2];
238 part.clSizeL3 = part.clSizesITS[3];
239 part.clSizeL4 = part.clSizesITS[4];
240 part.clSizeL5 = part.clSizesITS[5];
241 part.clSizeL6 = part.clSizesITS[6];
242
243 // PID info
244 part.dEdx = TPCtrack.getdEdx().dEdxTotTPC;
245 part.nClusTPC = TPCtrack.getNClusters();
246 // 7% resolution for all particles
247 part.nSigmaDeu = computeNSigma(PID::Deuteron, TPCtrack, mBBres);
248 part.nSigmaP = computeNSigma(PID::Proton, TPCtrack, mBBres);
249 part.nSigmaK = computeNSigma(PID::Kaon, TPCtrack, mBBres);
250 part.nSigmaPi = computeNSigma(PID::Pion, TPCtrack, mBBres);
251 part.nSigmaE = computeNSigma(PID::Electron, TPCtrack, mBBres);
252
253 if (mUseMC) {
254 (*mDBGOut) << "outTree"
255 << "pdg=" << part.pdg << "fakeMatch=" << part.fakeMatch;
256 }
257 (*mDBGOut) << "outTree"
258 << "sign=" << part.sign << "p=" << part.p << "pt=" << part.pt << "pTPC=" << part.pTPC << "pITS=" << part.pITS
259 << "eta=" << part.eta << "phi=" << part.phi << "tgL=" << part.tgL << "chi2ITS=" << part.chi2ITS << "chi2TPC="
260 << part.chi2TPC << "chi2ITSTPC=" << part.chi2ITSTPC << "dEdx=" << part.dEdx << "nClusTPC=" << part.nClusTPC
261 << "nSigmaDeu=" << part.nSigmaDeu << "nSigmaP=" << part.nSigmaP << "nSigmaK=" << part.nSigmaK << "nSigmaPi="
262 << part.nSigmaPi << "nSigmaE=" << part.nSigmaE << "clSizeL0=" << part.clSizeL0 << "clSizeL1=" << part.clSizeL1
263 << "clSizeL2=" << part.clSizeL2 << "clSizeL3=" << part.clSizeL3 << "clSizeL4=" << part.clSizeL4 << "clSizeL5="
264 << part.clSizeL5 << "clSizeL6=" << part.clSizeL6 << "\n";
265 }
266}
267
268std::array<int, 7> PIDStudy::getTrackClusterSizes(const TrackITS& track)
269{
271 std::array<int, 7> clusSizes = {-1, -1, -1, -1, -1, -1, -1};
272 auto firstClus = track.getFirstClusterEntry();
273 auto ncl = track.getNumberOfClusters();
274 for (int icl = 0; icl < ncl; icl++) {
275 auto& clus = mClusters[mInputITSidxs[firstClus + icl]];
276 auto& clSize = mClusterSizes[mInputITSidxs[firstClus + icl]];
277 auto layer = geom->getLayer(clus.getSensorID());
278 clusSizes[layer] = clSize;
279 }
280 return clusSizes;
281}
282
283void PIDStudy::updateTimeDependentParams(ProcessingContext& pc)
284{
286 static bool initOnceDone = false;
287 if (!initOnceDone) { // this param need to be queried only once
288 initOnceDone = true;
291 }
292}
293
294void PIDStudy::saveOutput()
295{
296 mDBGOut.reset();
297 LOGP(info, "Stored histograms into {}", mOutName.c_str());
298}
299
301{
302 // saveOutput();
303}
304
306{
308 return;
309 }
310 // o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj);
311 if (matcher == ConcreteDataMatcher("ITS", "CLUSDICT", 0)) {
313 return;
314 }
315}
316
317float PIDStudy::computeNSigma(PID pid, TrackTPC& tpcTrack, float resolution)
318{
319 float nSigma = -999;
320 float bb = mPIDresponse.getExpectedSignal(tpcTrack, pid);
321 if (tpcTrack.getdEdx().dEdxTotTPC > 0) {
322 nSigma = (tpcTrack.getdEdx().dEdxTotTPC - bb) / (resolution * bb);
323 }
324 return nSigma;
325}
326
327DataProcessorSpec getPIDStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr<o2::steer::MCKinematicsReader> kineReader)
328{
329 std::vector<OutputSpec> outputs;
330 auto dataRequest = std::make_shared<DataRequest>();
331 dataRequest->requestTracks(srcTracksMask, useMC);
332 dataRequest->requestClusters(srcClustersMask, useMC);
333
334 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
335 true, // GRPECS=true
336 false, // GRPLHCIF
337 false, // GRPMagField
338 false, // askMatLUT
340 dataRequest->inputs,
341 true);
342 return DataProcessorSpec{
343 "its-pid-study",
344 dataRequest->inputs,
345 outputs,
346 AlgorithmSpec{adaptFromTask<PIDStudy>(dataRequest, ggRequest, useMC, kineReader)},
347 Options{}};
348}
349} // namespace study
350} // namespace its
351} // namespace o2
Wrapper container for different reconstructed object types.
particle ids, masses, names class definition
Base track model for the Barrel, params only, w/o covariance.
const int16_t bb
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.
Result of refitting TPC-ITS matched track.
std::ostringstream debug
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:66
void setClusterDictionary(const o2::itsmft::TopologyDictionary *d)
Definition PIDStudy.cxx:99
void finaliseCCDB(ConcreteDataMatcher &, void *) final
Definition PIDStudy.cxx:305
void run(ProcessingContext &) final
Definition PIDStudy.cxx:149
PIDStudy(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, bool isMC, std::shared_ptr< o2::steer::MCKinematicsReader > kineReader)
Definition PIDStudy.cxx:90
~PIDStudy() final=default
void endOfStream(EndOfStreamContext &) final
This is invoked whenever we have an EndOfStream event.
Definition PIDStudy.cxx:300
void init(InitContext &ic) final
Definition PIDStudy.cxx:131
void acquirePattern(iterator &pattIt)
int getNPixels() const
Returns the number of fired pixels.
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.
PID response class.
Definition PIDResponse.h:39
static constexpr ID Electron
Definition PID.h:94
static constexpr ID Kaon
Definition PID.h:97
static constexpr ID Pion
Definition PID.h:96
static constexpr ID Deuteron
Definition PID.h:99
static constexpr ID Proton
Definition PID.h:98
GLenum const GLfloat * params
Definition glcorearb.h:272
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
o2::framework::DataProcessorSpec getPIDStudy(mask_t srcTracksMask, mask_t srcClustersMask, bool useMC, std::shared_ptr< o2::steer::MCKinematicsReader > kineReader)
Definition PIDStudy.cxx:327
o2::track::TrackParCov Track
o2::dataformats::GlobalTrackID::mask_t mask_t
o2::BaseCluster< float > ITSCluster
TrackParCovF TrackParCov
Definition Track.h:33
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
std::array< int, 7 > clSizesITS
Definition PIDStudy.cxx:84
static constexpr int T2L
Definition Cartesian.h:55
static constexpr int T2GRot
Definition Cartesian.h:57
static constexpr int T2G
Definition Cartesian.h:56