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