1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
20 ///////////////////////////////////////////////////////////////////////////////
22 // The TRD particle identification class //
24 // Its main purposes are: //
25 // - Creation and bookkeeping of the propability distributions //
26 // - Assignment of a e/pi propability to a given track //
28 ///////////////////////////////////////////////////////////////////////////////
35 #include <TObjArray.h>
38 #include <TParticle.h>
42 #include "AliTRDpid.h"
43 #include "AliTRDcluster.h"
44 #include "AliTRDtrack.h"
45 #include "AliTRDtracker.h"
46 #include "AliTRDgeometry.h"
50 //_____________________________________________________________________________
51 AliTRDpid::AliTRDpid():TNamed()
54 // AliTRDpid default constructor
70 //_____________________________________________________________________________
71 AliTRDpid::AliTRDpid(const char* name, const char* title):TNamed(name,title)
74 // AliTRDpid constructor
92 //_____________________________________________________________________________
93 AliTRDpid::AliTRDpid(const AliTRDpid &p)
96 // AliTRDpid copy constructor
99 ((AliTRDpid &) p).Copy(*this);
103 //_____________________________________________________________________________
104 AliTRDpid::~AliTRDpid()
107 // AliTRDpid destructor
111 fClusterArray->Delete();
112 delete fClusterArray;
116 fTrackArray->Delete();
132 //_____________________________________________________________________________
133 AliTRDpid &AliTRDpid::operator=(const AliTRDpid &p)
136 // Assignment operator
139 if (this != &p) ((AliTRDpid &) p).Copy(*this);
144 //_____________________________________________________________________________
145 void AliTRDpid::Copy(TObject &p)
151 fQHist->Copy(*((AliTRDpid &) p).fQHist);
152 fLQHist->Copy(*((AliTRDpid &) p).fLQHist);
154 ((AliTRDpid &) p).fTrackArray = NULL;
155 ((AliTRDpid &) p).fClusterArray = NULL;
156 ((AliTRDpid &) p).fGeometry = NULL;
158 ((AliTRDpid &) p).fNMom = fNMom;
159 ((AliTRDpid &) p).fMinMom = fMinMom;
160 ((AliTRDpid &) p).fMaxMom = fMaxMom;
161 ((AliTRDpid &) p).fWidMom = fWidMom;
165 //_____________________________________________________________________________
166 Bool_t AliTRDpid::Init()
169 // Initializes the PID object
172 fClusterArray = new TObjArray();
173 fTrackArray = new TObjArray();
179 //_____________________________________________________________________________
180 Bool_t AliTRDpid::AssignLQ(TObjArray *tarray)
183 // Assigns the e / pi Q-likelihood to all tracks in the array
186 Bool_t status = kTRUE;
190 TIter nextTrack(tarray);
191 while ((track = (AliTRDtrack *) nextTrack())) {
192 if (!AssignLQ(track)) {
202 //_____________________________________________________________________________
203 Bool_t AliTRDpid::AssignLQ(AliTRDtrack *t)
206 // Assigns the e / pi Q-likelihood to a given track
209 const Int_t kNplane = AliTRDgeometry::Nplan();
210 Float_t charge[kNplane];
212 // Calculate the total charge in each plane
213 if (!SumCharge(t,charge)) return kFALSE;
215 // Assign the likelihoods
216 t->SetLikelihoodPion(LQPion(charge));
217 t->SetLikelihoodElectron(LQElectron(charge));
223 //_____________________________________________________________________________
224 Bool_t AliTRDpid::CreateHistograms(const Int_t nmom
225 , const Float_t minmom
226 , const Float_t maxmom)
229 // Creates the likelihood histograms
236 const Int_t kNpla = AliTRDgeometry::Nplan();
241 fWidMom = (maxmom - minmom) / ((Float_t) nmom);
243 // The L-Q distributions
244 fLQHist = new TObjArray(kNpid * nmom);
245 for (imom = 0; imom < nmom; imom++) {
246 for (ipid = 0; ipid < kNpid; ipid++) {
247 Int_t index = GetIndexLQ(imom,ipid);
250 sprintf(name ,"hLQ%03d",index);
251 if (ipid == kElectron) {
252 sprintf(title,"L-Q electron p-bin %03d",imom);
255 sprintf(title,"L-Q pion p-bin %03d",imom);
257 TH1F *hTmp = new TH1F(name,title,416,-0.02,1.02);
258 fLQHist->AddAt(hTmp,index);
262 // The Q-distributions
263 fQHist = new TObjArray(kNpla * kNpid * nmom);
264 for (imom = 0; imom < nmom; imom++) {
265 for (ipid = 0; ipid < kNpid; ipid++) {
266 for (ipla = 0; ipla < kNpla; ipla++) {
267 Int_t index = GetIndexQ(imom,ipla,ipid);
270 sprintf(name ,"hQ%03d",index);
271 if (ipid == kElectron) {
272 sprintf(title,"Q electron p-bin %03d plane %d",imom,ipla);
275 sprintf(title,"Q pion p-bin %03d plane %d",imom,ipla);
277 TH1F *hTmp = new TH1F(name,title,100,0.0,5000.0);
278 fQHist->AddAt(hTmp,index);
287 //_____________________________________________________________________________
288 Bool_t AliTRDpid::FillQspectra()
291 // Fills the Q-spectra histograms.
294 Bool_t status = kTRUE;
298 TIter nextTrack(fTrackArray);
299 while ((track = (AliTRDtrack *) nextTrack())) {
300 if (!FillQspectra(track)) {
310 //_____________________________________________________________________________
311 Bool_t AliTRDpid::FillQspectra(const AliTRDtrack *t)
314 // Fills the Q-spectra histograms with track <t>.
317 const Int_t kNpla = AliTRDgeometry::Nplan();
319 if (isnan(t->GetP())) return kTRUE;
321 printf("----------------------------------------------------------\n");
322 Float_t charge[kNpla];
323 Float_t mom = t->GetP();
326 if (!SumCharge(t,charge)) return kFALSE;
328 printf(" ipid = %d\n",ipid);
329 printf(" mom = %f\n",mom);
330 printf(" charge = %8.2f, %8.2f, %8.2f, %8.2f, %8.2f, %8.2f\n"
331 ,charge[0],charge[1],charge[2],charge[3],charge[4],charge[5]);
333 for (Int_t ipla = 0; ipla < kNpla; ipla++) {
334 Int_t index = GetIndexQ(mom,ipla,ipid);
336 TH1F *hTmp = (TH1F *) fQHist->UncheckedAt(index);
337 hTmp->Fill(charge[ipla]);
345 //_____________________________________________________________________________
346 Bool_t AliTRDpid::Open(const Char_t *name, Int_t event)
349 // Opens and reads the kine tree, the geometry, the cluster array.
350 // and the track array from the file <name>
353 Bool_t status = kTRUE;
355 status = ReadKine(name,event);
356 status = ReadCluster(name);
357 status = ReadTracks(name);
363 //_____________________________________________________________________________
364 Bool_t AliTRDpid::Open(const Char_t *namekine
365 , const Char_t *namecluster
366 , const Char_t *nametracks
370 // Opens and reads the kine tree and the geometry from file <namekine>,
371 // the cluster array from file <namecluster>,
372 // and the track array from the file <nametracks>
375 Bool_t status = kTRUE;
377 status = ReadKine(namekine,event);
378 status = ReadCluster(namecluster);
379 status = ReadTracks(nametracks);
385 //_____________________________________________________________________________
386 Bool_t AliTRDpid::ReadKine(const Char_t *name, Int_t event)
389 // Opens and reads the kine tree and the geometry from the file <name>.
392 TFile *file = (TFile *) gROOT->GetListOfFiles()->FindObject(name);
394 printf("AliTRDpid::ReadKine -- ");
395 printf("Open file %s\n",name);
396 file = new TFile(name);
398 printf("AliTRDpid::ReadKine -- ");
399 printf("Cannot open file %s\n",name);
404 gAlice = (AliRun *) file->Get("gAlice");
406 printf("AliTRDpid::ReadKine -- ");
407 printf("No AliRun object found\n");
410 gAlice->GetEvent(event);
412 AliTRD *trd = (AliTRD *) gAlice->GetDetector("TRD");
414 printf("AliTRDpid::ReadKine -- ");
415 printf("No TRD object found\n");
419 fGeometry = trd->GetGeometry();
421 printf("AliTRDpid::ReadKine -- ");
422 printf("No TRD geometry found\n");
432 //_____________________________________________________________________________
433 Bool_t AliTRDpid::ReadCluster(const Char_t *name)
436 // Opens and reads the cluster array from the file <name>.
439 fClusterArray->Delete();
441 printf("AliTRDpid::ReadCluster -- ");
442 printf("Open file %s\n",name);
444 AliTRDtracker *tracker = new AliTRDtracker("dummy","dummy");
445 tracker->ReadClusters(fClusterArray,name);
447 if (!fClusterArray) {
448 printf("AliTRDpid::ReadCluster -- ");
449 printf("Error reading the cluster array from file %s\n",name);
459 //_____________________________________________________________________________
460 Bool_t AliTRDpid::ReadTracks(const Char_t *name)
463 // Opens and reads the track array from the file <name>.
466 fTrackArray->Delete();
468 TFile *file = (TFile *) gROOT->GetListOfFiles()->FindObject(name);
470 printf("AliTRDpid::ReadTracks -- ");
471 printf("Open file %s\n",name);
472 file = new TFile(name);
474 printf("AliTRDpid::ReadTracks -- ");
475 printf("Cannot open file %s\n",name);
480 TTree *trackTree = (TTree *) file->Get("TreeT");
481 TBranch *trackBranch = trackTree->GetBranch("tracks");
483 Int_t nEntry = ((Int_t) trackTree->GetEntries());
484 for (Int_t iEntry = 0; iEntry < nEntry; iEntry++) {
485 AliTRDtrack *track = new AliTRDtrack();
486 trackBranch->SetAddress(&track);
487 trackTree->GetEvent(iEntry);
488 fTrackArray->AddLast(track);
497 //_____________________________________________________________________________
498 Int_t AliTRDpid::GetIndexQ(const Float_t mom, const Int_t ipla, const Int_t ipid)
501 // Returns the Q-spectrum histogram index
504 if ((mom < fMinMom) || (mom > fMaxMom)) return -1;
505 Int_t imom = ((Int_t) ((mom - fMinMom) / fWidMom));
506 return GetIndexQ(imom,ipla,ipid);
510 //_____________________________________________________________________________
511 Int_t AliTRDpid::GetIndexQ(const Int_t imom, const Int_t ipla, const Int_t ipid)
514 // Returns the Q-spectrum histogram index
517 const Int_t kNpla = AliTRDgeometry::Nplan();
518 if ((ipid < 0) || (ipid >= kNpid)) return -1;
519 return imom * (kNpid * kNpla) + ipla * kNpid + ipid;
523 //_____________________________________________________________________________
524 Int_t AliTRDpid::GetIndexLQ(const Float_t mom, const Int_t ipid)
527 // Returns the Q-likelihood histogram index
530 if ((mom < fMinMom) || (mom > fMaxMom)) return -1;
531 Int_t imom = ((Int_t) ((mom - fMinMom) / fWidMom));
532 return GetIndexLQ(imom,ipid);
536 //_____________________________________________________________________________
537 Int_t AliTRDpid::GetIndexLQ(const Int_t imom, const Int_t ipid)
540 // Returns the Q-likelihood histogram index
543 if ((ipid < 0) || (ipid >= kNpid)) return -1;
544 return imom * kNpid + ipid;
548 //_____________________________________________________________________________
549 Int_t AliTRDpid::Pid(const AliTRDtrack *t)
552 // Determines the pid of the track <t>
553 // For a given track to be assigned an electron or pion pid it requires
554 // that more than a fraction of 0.7 of all associated cluster are 'pure'
555 // clusters -- meaning to have only contribution from one particle --
556 // of the specific particle type.
560 const Int_t kPdgEl = 11;
561 const Int_t kPdgPi = 211;
563 // Minimum fraction of cluster from one particle
564 const Float_t kRatioMin = 0.7;
566 AliTRDcluster *cluster;
569 Int_t nClusterEl = 0;
570 Int_t nClusterPi = 0;
571 Int_t nClusterNo = 0;
578 if (!fClusterArray) {
579 printf("AliTRDpid::Pid -- ");
580 printf("ClusterArray not defined. Initialize the PID object first\n");
584 // Loop through all clusters associated to this track
585 Int_t nCluster = t->GetNclusters();
586 for (Int_t iCluster = 0; iCluster < nCluster; iCluster++) {
589 Int_t index = t->GetClusterIndex(iCluster);
590 if (!(cluster = (AliTRDcluster *) fClusterArray->UncheckedAt(index))) {
594 // Get the first two MC track indices
595 Int_t track0 = cluster->GetTrackIndex(0);
596 Int_t track1 = cluster->GetTrackIndex(1);
597 printf(" track0 = %d, track1 = %d\n",track0,track1);
599 // Take only 'pure' cluster
600 if ((track0 > -1) && (track1 == -1)) {
602 particle = gAlice->Particle(track0);
603 switch (TMath::Abs(particle->GetPdgCode())) {
620 ratioEl = ((Float_t) nClusterEl) / ((Float_t) nCluster);
621 ratioPi = ((Float_t) nClusterPi) / ((Float_t) nCluster);
622 if (ratioEl > kRatioMin) {
625 else if (ratioPi > kRatioMin) {
629 printf(" nCluster = %d, nClusterEl = %d, nClusterPi = %d, nClusterNo = %d\n"
630 ,nCluster,nClusterEl,nClusterPi,nClusterNo);
631 printf(" ratioEl = %f, ratioPi = %f\n",ratioEl,ratioPi);
637 //_____________________________________________________________________________
638 Bool_t AliTRDpid::SumCharge(const AliTRDtrack *t, Float_t *charge)
641 // Sums up the charge in each plane for track <t>.
644 Bool_t status = kTRUE;
646 AliTRDcluster *cluster;
648 const Int_t kNplane = AliTRDgeometry::Nplan();
649 for (Int_t iPlane = 0; iPlane < kNplane; iPlane++) {
650 charge[iPlane] = 0.0;
653 if (!fClusterArray) {
654 printf("AliTRDpid::SumCharge -- ");
655 printf("ClusterArray not defined. Initialize the PID object first\n");
659 printf("AliTRDpid::SumCharge -- ");
660 printf("TRD geometry not defined. Initialize the PID object first\n");
664 // Loop through all clusters associated to this track
665 Int_t nCluster = t->GetNclusters();
666 for (Int_t iCluster = 0; iCluster < nCluster; iCluster++) {
669 Int_t index = t->GetClusterIndex(iCluster);
670 if (!(cluster = (AliTRDcluster *) fClusterArray->UncheckedAt(index))) {
676 Int_t plane = fGeometry->GetPlane(cluster->GetDetector());
677 charge[plane] += cluster->GetQ();
685 //_____________________________________________________________________________
686 Float_t AliTRDpid::LQElectron(const Float_t *charge)
689 // Returns the Q-likelihood to be a electron
696 //_____________________________________________________________________________
697 Float_t AliTRDpid::LQPion(const Float_t *charge)
700 // Returns the Q-likelihood to be a pion