Line data Source code
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.9 2007/10/10 09:05:10 schutz
21 : * Changing name QualAss to QA
22 : *
23 : * Revision 1.8 2007/08/28 12:55:08 policheh
24 : * Loaders removed from the reconstruction code (C.Cheshkov)
25 : *
26 : * Revision 1.7 2007/08/07 14:12:03 kharlov
27 : * Quality assurance added (Yves Schutz)
28 : *
29 : * Revision 1.6 2007/08/03 14:41:37 cvetan
30 : * Missing header files
31 : *
32 : * Revision 1.5 2007/08/03 13:52:16 kharlov
33 : * Working skeleton of matching the ESD tracks and ESD clusters (Iouri Belikov)
34 : *
35 : */
36 :
37 : #include <TClonesArray.h>
38 : #include <TMath.h>
39 :
40 : #include <AliLog.h>
41 : #include "AliPHOSTracker.h"
42 : #include "AliPHOSEmcRecPoint.h"
43 : #include "AliPHOSGeometry.h"
44 : #include "AliESDEvent.h"
45 : #include "AliESDtrack.h"
46 : #include "AliPHOSTrackSegmentMakerv1.h"
47 : #include "AliPHOSPIDv1.h"
48 :
49 : //-------------------------------------------------------------------------
50 : // PHOS tracker.
51 : // Matches ESD tracks with the PHOS and makes the PID.
52 : //
53 : //-------------------------------------------------------------------------
54 :
55 22 : ClassImp(AliPHOSTracker)
56 :
57 : Bool_t AliPHOSTracker::fgDebug = kFALSE ;
58 :
59 : //____________________________________________________________________________
60 : AliPHOSTracker::AliPHOSTracker():
61 2 : AliTracker()
62 10 : {
63 : //--------------------------------------------------------------------
64 : // The default constructor
65 : //--------------------------------------------------------------------
66 24 : for (Int_t i=0; i<5; i++)
67 30 : fModules[i]=new TClonesArray("AliPHOSEmcRecPoint",777);
68 :
69 4 : }
70 :
71 : //____________________________________________________________________________
72 : AliPHOSTracker::~AliPHOSTracker()
73 12 : {
74 : //--------------------------------------------------------------------
75 : // The destructor
76 : //--------------------------------------------------------------------
77 24 : for (Int_t i=0; i<5; i++) {
78 10 : (fModules[i])->Delete();
79 20 : delete fModules[i];
80 : }
81 6 : }
82 :
83 : //____________________________________________________________________________
84 : Int_t AliPHOSTracker::LoadClusters(TTree *cTree) {
85 : //--------------------------------------------------------------------
86 : // This function loads the PHOS clusters
87 : //--------------------------------------------------------------------
88 :
89 16 : TObjArray *arr=NULL;
90 8 : TBranch *branch=cTree->GetBranch("PHOSEmcRP");
91 8 : if (branch==0) {
92 0 : AliError("No branch with the EMC clusters found !");
93 0 : return 1;
94 : }
95 8 : branch->SetAddress(&arr);
96 :
97 96 : for(Int_t m=0;m<5; m++) fModules[m]->Clear("C") ;
98 :
99 : Int_t nclusters=0;
100 8 : Int_t nentr=(Int_t)branch->GetEntries();
101 32 : for (Int_t i=0; i<nentr; i++) {
102 8 : if (!branch->GetEvent(i)) continue;
103 8 : Int_t ncl=arr->GetEntriesFast();
104 26 : while (ncl--) {
105 10 : AliPHOSEmcRecPoint *cl=(AliPHOSEmcRecPoint*)arr->UncheckedAt(ncl);
106 :
107 10 : Int_t m=cl->GetPHOSMod();
108 10 : if ((m<1)||(m>5)) {
109 0 : AliError(Form("Wrong module index: %d !",m));
110 0 : continue ;
111 : }
112 :
113 : // Here is how the alignment is treated
114 : // Misalignment is already in cluster coordinates
115 : // if (!cl->Misalign()) AliWarning("Can't misalign this cluster !");
116 :
117 10 : cl->SetBit(14,kFALSE); // The clusters are not yet attached to any track
118 :
119 10 : TClonesArray &module=*fModules[m-1];
120 10 : Int_t idx=module.GetEntriesFast();
121 10 : new (module[idx]) AliPHOSEmcRecPoint(*cl);
122 :
123 10 : nclusters++;
124 :
125 10 : }
126 8 : }
127 8 : arr->Delete();
128 8 : Info("LoadClusters","Number of loaded clusters: %d",nclusters);
129 :
130 : return 0;
131 :
132 8 : }
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 16 : Int_t nt=esd->GetNumberOfTracks();
143 :
144 : // *** Select and sort the ESD track in accordance with their quality
145 8 : Double_t *quality=new Double_t[nt];
146 8 : Int_t *index=new Int_t[nt];
147 320 : for (Int_t i=0; i<nt; i++) {
148 152 : AliESDtrack *esdTrack=esd->GetTrack(i);
149 152 : quality[i] = esdTrack->GetSigmaY2() + esdTrack->GetSigmaZ2();
150 : }
151 8 : TMath::Sort(nt,quality,index,kFALSE);
152 :
153 8 : AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
154 :
155 : // *** Start the matching
156 8 : TVector3 vecEmc ; // Local position of EMC recpoint
157 8 : Double_t bz = GetBz() ; //For approximate matching
158 8 : Double_t b[3]; //For final matching
159 8 : Double_t gposTrack[3] ;
160 : Int_t matched=0;
161 320 : for (Int_t i=0; i<nt; i++) {
162 152 : AliESDtrack *esdTrack=esd->GetTrack(index[i]);
163 :
164 : // Skip the tracks having "wrong" status (has to be checked/tuned)
165 152 : ULong_t status = esdTrack->GetStatus();
166 170 : if ((status & AliESDtrack::kTPCout) == 0) continue;
167 : // if ((status & AliESDtrack::kTRDout) == 0) continue;
168 : // if ((status & AliESDtrack::kTRDrefit) == 1) continue;
169 :
170 : //Continue extrapolation from TPC outer surface
171 134 : const AliExternalTrackParam *outerParam=esdTrack->GetOuterParam();
172 134 : if (!outerParam) continue;
173 134 : AliExternalTrackParam t(*outerParam);
174 :
175 134 : t.GetBxByBz(b) ;
176 :
177 : //Loop over PHOS modules
178 : Double_t dx=0,dz=0;
179 : Double_t minDistance=999. ;
180 : Int_t emcIndex=0 ;
181 1714 : for(Int_t mod=1; mod<=5; mod++){
182 1324 : if(fModules[mod-1]->GetEntriesFast()==0) //no PHOS clusters in this module or module does not exist
183 : continue ;
184 :
185 : //Approximate direction to the current PHOS module
186 134 : Double_t phiMod=(330.-20.*mod)/180.*TMath::Pi() ;
187 268 : if(!t.Rotate(phiMod))
188 96 : continue ;
189 38 : TVector3 globaPos ;
190 38 : geom->Local2Global(mod, 0.,0., globaPos) ;
191 38 : const Double_t rPHOS = globaPos.Pt() ; //Distance to center of PHOS module
192 : const Double_t kYmax = 72.+10. ; //Size of the module (with some reserve) in phi direction
193 : const Double_t kZmax = 64.+20. ; //Size of the module (with some reserve) in z direction
194 :
195 38 : Double_t y; // Some tracks do not reach the PHOS
196 100 : if (!t.GetYAt(rPHOS,bz,y)) continue; // because of the bending
197 :
198 14 : Double_t z;
199 28 : if(!t.GetZAt(rPHOS,bz,z))
200 0 : continue ;
201 14 : if (TMath::Abs(z) > kZmax)
202 2 : continue; // Some tracks miss the PHOS in Z
203 12 : if(TMath::Abs(y) < kYmax){
204 4 : t.PropagateToBxByBz(rPHOS,b); // Propagate to the matching module
205 : //t.CorrectForMaterial(...); // Correct for the TOF material, if needed
206 4 : t.GetXYZ(gposTrack) ;
207 4 : TVector3 globalPositionTr(gposTrack) ;
208 4 : TVector3 localPositionTr ;
209 4 : geom->Global2Local(localPositionTr,globalPositionTr,mod) ;
210 36 : for(Int_t icl=0;icl<fModules[mod-1]->GetEntriesFast();icl++){
211 16 : AliPHOSEmcRecPoint * clu =static_cast<AliPHOSEmcRecPoint*>(fModules[mod-1]->At(icl)) ;
212 8 : clu->GetLocalPosition(vecEmc) ;
213 8 : Double_t ddx = vecEmc.X()-localPositionTr.X();
214 8 : Double_t ddz = vecEmc.Z()-localPositionTr.Z();
215 8 : Double_t d2 = ddx*ddx + ddz*ddz;
216 8 : if(d2 < minDistance) {
217 : dx = ddx ;
218 : dz = ddz ;
219 4 : emcIndex=clu->GetIndexInList() ;
220 : minDistance=d2 ;
221 4 : }
222 : }
223 : break ;
224 4 : }
225 60 : } //Loop over modules
226 :
227 134 : if(minDistance<999.){
228 : //found some match
229 4 : esdTrack->SetStatus(AliESDtrack::kPHOSmatch) ;
230 4 : esdTrack->SetPHOScluster(-emcIndex) ; //Should be ESDCaloCluster index which is not known yet. Will be transformed later in FillESD().
231 4 : esdTrack->SetPHOSdxdz(dx,dz) ;
232 4 : matched++;
233 4 : }
234 :
235 134 : }
236 :
237 8 : Info("PropagateBack","Number of matched tracks: %d",matched);
238 :
239 16 : delete[] quality;
240 16 : delete[] index;
241 :
242 : return 0;
243 :
244 8 : }
245 :
246 : //____________________________________________________________________________
247 : AliCluster *AliPHOSTracker::GetCluster(Int_t index) const {
248 : //--------------------------------------------------------------------
249 : // Returns the pointer to a given cluster
250 : //--------------------------------------------------------------------
251 0 : Int_t m=(index & 0xf0000000) >> 28; // Module number
252 0 : Int_t i=(index & 0x0fffffff) >> 00; // Index within the module
253 :
254 0 : return (AliCluster*)(fModules[m])->UncheckedAt(i);
255 : }
256 :
257 : //____________________________________________________________________________
258 : void AliPHOSTracker::UnloadClusters() {
259 : //--------------------------------------------------------------------
260 : // This function unloads the PHOS clusters
261 : //--------------------------------------------------------------------
262 : // for (Int_t i=0; i<5; i++) (fModules[i])->Delete();
263 16 : }
|