Loaders removed from the reconstruction code (C.Cheshkov)
[u/mrichter/AliRoot.git] / PHOS / AliPHOSTracker.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15 /* $Id$ */
16
17 /* History of cvs commits:
18  *
19  * $Log$
20  * Revision 1.7  2007/08/07 14:12:03  kharlov
21  * Quality assurance added (Yves Schutz)
22  *
23  * Revision 1.6  2007/08/03 14:41:37  cvetan
24  * Missing header files
25  *
26  * Revision 1.5  2007/08/03 13:52:16  kharlov
27  * Working skeleton of matching the ESD tracks and ESD clusters (Iouri Belikov)
28  *
29  */
30
31 #include <TClonesArray.h>
32 #include <TMath.h>
33
34 #include <AliLog.h>
35 #include "AliPHOSTracker.h"
36 #include "AliPHOSEmcRecPoint.h"
37 #include "AliESDEvent.h"
38 #include "AliPHOSQualAssDataMaker.h" 
39 #include "AliPHOSGetter.h"
40 #include "AliESDtrack.h"
41 #include "AliPHOSTrackSegmentMakerv1.h"
42 #include "AliPHOSPIDv1.h"
43
44 //-------------------------------------------------------------------------
45 //                          PHOS tracker.
46 // Matches ESD tracks with the PHOS and makes the PID.  
47 //
48 //-------------------------------------------------------------------------
49
50 ClassImp(AliPHOSTracker)
51
52 Bool_t AliPHOSTracker::fgDebug = kFALSE ;  
53
54
55 // ***** Some geometrical constants (used in PropagateBack) 
56
57 const Double_t kR=460.+ 9;  // Radial coord. of the centre of EMC module (cm)
58
59 const Double_t kAlpha=20.*TMath::Pi()/180.;     // Segmentation angle (rad)
60 const Double_t kYmax=kR*TMath::Tan(0.5*kAlpha); // Maximal possible y-coord.(cm)
61 const Double_t kZmax=65.; // Approximately: the maximal possible z-coord.(cm)
62
63
64
65 //____________________________________________________________________________
66 AliPHOSTracker::AliPHOSTracker(): 
67   AliTracker()
68 {
69   //--------------------------------------------------------------------
70   // The default constructor
71   //--------------------------------------------------------------------
72   for (Int_t i=0; i<5; i++) 
73       fModules[i]=new TClonesArray("AliPHOSEmcRecPoint",777);
74 }
75
76 //____________________________________________________________________________
77 AliPHOSTracker::~AliPHOSTracker() 
78 {
79   //--------------------------------------------------------------------
80   // The destructor
81   //--------------------------------------------------------------------
82   for (Int_t i=0; i<5; i++) {
83       (fModules[i])->Delete();
84       delete fModules[i];
85   }
86 }
87
88 //____________________________________________________________________________
89 Int_t AliPHOSTracker::LoadClusters(TTree *cTree) {
90   //--------------------------------------------------------------------
91   // This function loads the PHOS clusters
92   //--------------------------------------------------------------------
93   TObjArray *arr=NULL;
94   TBranch *branch=cTree->GetBranch("PHOSEmcRP");
95   if (branch==0) {
96     AliError("No branch with the EMC clusters found !");
97     return 1;
98   }
99   branch->SetAddress(&arr);
100
101   Int_t nclusters=0;
102   Int_t nentr=(Int_t)branch->GetEntries();
103   for (Int_t i=0; i<nentr; i++) {
104     if (!branch->GetEvent(i)) continue;
105     Int_t ncl=arr->GetEntriesFast();
106     while (ncl--) {
107       AliPHOSEmcRecPoint *cl=(AliPHOSEmcRecPoint*)arr->UncheckedAt(ncl);
108
109       Int_t m=cl->GetPHOSMod();
110       if ((m<1)||(m>5)) {
111          AliError("Wrong module index !");
112          return 1;
113       }
114
115       // Here is how the alignment is treated
116       if (!cl->Misalign()) AliWarning("Can't misalign this cluster !");
117
118       cl->SetBit(14,kFALSE); // The clusters are not yet attached to any track
119
120       TClonesArray &module=*fModules[m-1];
121       Int_t idx=module.GetEntriesFast();
122       new (module[idx]) AliPHOSEmcRecPoint(*cl); 
123
124       nclusters++;
125
126     }
127   }  
128
129   Info("LoadClusters","Number of loaded clusters: %d",nclusters);
130
131   return 0;
132 }
133
134 //____________________________________________________________________________
135 Int_t AliPHOSTracker::PropagateBack(AliESDEvent *esd) {
136   //--------------------------------------------------------------------
137   // Called by AliReconstruction 
138   // Performs the track matching with the PHOS modules
139   // Makes the PID
140   //--------------------------------------------------------------------
141
142   Int_t nt=esd->GetNumberOfTracks();
143
144   // *** Select and sort the ESD track in accordance with their quality
145   Double_t *quality=new Double_t[nt];
146   Int_t *index=new Int_t[nt];  
147   for (Int_t i=0; i<nt; i++) {
148      AliESDtrack *esdTrack=esd->GetTrack(i);
149      quality[i] = esdTrack->GetSigmaY2() + esdTrack->GetSigmaZ2();
150   }
151   TMath::Sort(nt,quality,index,kFALSE);
152
153
154   // *** Start the matching
155   Double_t bz=GetBz(); 
156   Int_t matched=0;
157   for (Int_t i=0; i<nt; i++) {
158      AliESDtrack *esdTrack=esd->GetTrack(index[i]);
159
160      // Skip the tracks having "wrong" status (has to be checked/tuned)
161      ULong_t status = esdTrack->GetStatus();
162      if ((status & AliESDtrack::kTRDout)   == 0) continue;
163      if ((status & AliESDtrack::kTRDrefit) == 1) continue;
164
165      AliExternalTrackParam t(*esdTrack);
166
167      Int_t isec=Int_t(t.GetAlpha()/kAlpha);
168      Int_t imod=-isec-2; // PHOS module
169
170      Double_t y;                       // Some tracks do not reach the PHOS
171      if (!t.GetYAt(kR,bz,y)) continue; //    because of the bending
172
173      Double_t z; t.GetZAt(kR,bz,z);   
174      if (TMath::Abs(z) > kZmax) continue; // Some tracks miss the PHOS in Z
175  
176      Bool_t ok=kTRUE;
177      while (TMath::Abs(y) > kYmax) {   // Find the matching module
178         Double_t alp=t.GetAlpha();
179         if (y > kYmax) {
180           if (!t.Rotate(alp+kAlpha)) {ok=kFALSE; break;}
181           imod--;
182         } else if (y < -kYmax) {
183           if (!t.Rotate(alp-kAlpha)) {ok=kFALSE; break;}
184           imod++;
185         }
186         if (!t.GetYAt(kR,bz,y)) {ok=kFALSE; break;}
187      }
188      if (!ok) continue; // Track rotation failed
189  
190   
191      if ((imod<0)||(imod>4)) continue; // Some tracks miss the PHOS in azimuth
192
193      //t.CorrectForMaterial(...); // Correct for the TOF material, if needed
194      t.PropagateTo(kR,bz);        // Propagate to the matching module
195
196
197     // *** Search for the "best" cluster (can be improved)
198      TClonesArray &cArray=*fModules[imod];
199      Int_t ncl=cArray.GetEntriesFast();
200      AliPHOSEmcRecPoint *bestCluster=0;            // The "best" cluster
201      Double_t maxd2=400; // (cm^2)
202      for (Int_t i=0; i<ncl; i++) {
203        AliPHOSEmcRecPoint *c=(AliPHOSEmcRecPoint *)cArray.UncheckedAt(i);
204
205        if (c->TestBit(14)) continue; // This clusters is "used"
206
207        Double_t dy = t.GetY() - c->GetY(), dz = t.GetZ() - c->GetZ();
208        Double_t d2 = dy*dy + dz*dz;
209        if (d2 < maxd2) {
210           maxd2=d2;
211           bestCluster=c;
212        }
213      }
214
215      if (!bestCluster) continue;   // No reasonable matching found 
216
217      bestCluster->SetBit(14,kTRUE); // This clusters is now attached to a track
218
219      matched++;
220
221      // *** Now, do the PID with the "bestCluster"
222      // and add the corresponding info to the ESD track pointed by "esdTrack"  
223
224      /*
225      printf("%e %e %e %e\n",t.GetSign(), t.GetX() - bestCluster->GetX(),
226                                          t.GetY() - bestCluster->GetY(),
227                                          t.GetZ() - bestCluster->GetZ());
228      */
229   }
230     
231   Info("PropagateBack","Number of matched tracks: %d",matched);
232
233   delete[] quality;
234   delete[] index;
235
236   return 0;
237 }
238
239 //____________________________________________________________________________
240 AliCluster *AliPHOSTracker::GetCluster(Int_t index) const {
241   //--------------------------------------------------------------------
242   // Returns the pointer to a given cluster
243   //--------------------------------------------------------------------
244   Int_t m=(index & 0xf0000000) >> 28;  // Module number
245   Int_t i=(index & 0x0fffffff) >> 00;  // Index within the module
246   
247   return (AliCluster*)(fModules[m])->UncheckedAt(i);
248 }
249
250 //____________________________________________________________________________
251 void AliPHOSTracker::UnloadClusters() {
252   //--------------------------------------------------------------------
253   // This function unloads the PHOS clusters
254   //--------------------------------------------------------------------
255   for (Int_t i=0; i<5; i++) (fModules[i])->Delete();
256 }