]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PHOS/AliPHOSTrackSegmentMakerv1.cxx
First attempt to propagate global track to PHOS
[u/mrichter/AliRoot.git] / PHOS / AliPHOSTrackSegmentMakerv1.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 // Implementation version 1 of algorithm class to construct PHOS track segments
18 // Track segment for PHOS is list of 
19 //        EMC RecPoint + (possibly) CPV RecPoint + (possibly) PPSD RecPoint
20 // To find TrackSegments we do the following: 
21 //  for each EMC RecPoints we look at
22 //   CPV/PPSD RecPoints in the radious fRcpv. 
23 //  If there is such a CPV RecPoint, 
24 //   we make "Link" it is just indexes of EMC and CPV/PPSD RecPoint and distance
25 //   between them in the PHOS plane. 
26 //  Then we sort "Links" and starting from the 
27 //   least "Link" pointing to the unassined EMC and CPV RecPoints assing them to 
28 //   new TrackSegment. 
29 // If there is no CPV/PPSD RecPoint we make TrackSegment 
30 // consisting from EMC alone. There is no TrackSegments without EMC RecPoint.
31 //// In principle this class should be called from AliPHOSReconstructioner, but 
32 // one can use it as well in standalone mode.
33 // Use  case:
34 //  root [0] AliPHOSTrackSegmentMakerv1 * t = new AliPHOSTrackSegmentMaker("galice.root", "tracksegmentsname", "recpointsname")
35 //  Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
36 //               // reads gAlice from header file "galice.root", uses recpoints stored in the branch names "recpointsname" (default = "Default")
37 //               // and saves recpoints in branch named "tracksegmentsname" (default = "recpointsname")                       
38 //  root [1] t->ExecuteTask()
39 //  root [2] t->SetMaxEmcPpsdDistance(5)
40 //  root [3] t->SetTrackSegmentsBranch("max distance 5 cm")
41 //  root [4] t->ExecuteTask("deb all time") 
42 //                 
43 //*-- Author: Dmitri Peressounko (RRC Ki & SUBATECH) & Yves Schutz (SUBATECH) 
44 //
45
46 // --- ROOT system ---
47 #include "TTree.h"
48 #include "TBenchmark.h"
49
50 // --- Standard library ---
51
52 // --- AliRoot header files ---
53 #include "AliPHOSGeometry.h"
54 #include "AliPHOSTrackSegmentMakerv1.h"
55 #include "AliPHOSTrackSegment.h"
56 #include "AliPHOSLink.h"
57 #include "AliPHOSGetter.h"
58 #include "AliESD.h"
59 #include "AliESDtrack.h"
60
61 ClassImp( AliPHOSTrackSegmentMakerv1) 
62
63
64 //____________________________________________________________________________
65   AliPHOSTrackSegmentMakerv1::AliPHOSTrackSegmentMakerv1() : AliPHOSTrackSegmentMaker()
66 {
67   // default ctor (to be used mainly by Streamer)
68
69   InitParameters() ; 
70   fDefaultInit = kTRUE ; 
71 }
72
73 //____________________________________________________________________________
74  AliPHOSTrackSegmentMakerv1::AliPHOSTrackSegmentMakerv1(const TString alirunFileName, const TString eventFolderName)
75    :AliPHOSTrackSegmentMaker(alirunFileName, eventFolderName)
76 {
77   // ctor
78
79   InitParameters() ; 
80   Init() ;
81   fDefaultInit = kFALSE ; 
82   fESD = 0;
83 }
84
85 //____________________________________________________________________________
86  AliPHOSTrackSegmentMakerv1::~AliPHOSTrackSegmentMakerv1()
87
88   // dtor
89   // fDefaultInit = kTRUE if TrackSegmentMaker created by default ctor (to get just the parameters)
90   if (!fDefaultInit)  
91     delete fLinkUpArray ;
92 }
93
94
95 //____________________________________________________________________________
96 const TString AliPHOSTrackSegmentMakerv1::BranchName() const 
97 {  
98  
99   return GetName() ;
100 }
101
102 //____________________________________________________________________________
103 void  AliPHOSTrackSegmentMakerv1::FillOneModule()
104 {
105   // Finds first and last indexes between which 
106   // clusters from one PHOS module are
107
108   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
109   
110   TObjArray * emcRecPoints = gime->EmcRecPoints() ; 
111   TObjArray * cpvRecPoints = gime->CpvRecPoints() ; 
112  
113   //First EMC clusters
114   Int_t totalEmc = emcRecPoints->GetEntriesFast() ;
115   for(fEmcFirst = fEmcLast; (fEmcLast < totalEmc) &&  
116         ((dynamic_cast<AliPHOSRecPoint *>(emcRecPoints->At(fEmcLast)))->GetPHOSMod() == fModule ); 
117       fEmcLast ++)  ;
118   
119   //Now CPV clusters
120   Int_t totalCpv = cpvRecPoints->GetEntriesFast() ;
121
122     for(fCpvFirst = fCpvLast; (fCpvLast < totalCpv) && 
123          ((dynamic_cast<AliPHOSRecPoint *>(cpvRecPoints->At(fCpvLast)))->GetPHOSMod() == fModule ); 
124        fCpvLast ++) ;
125       
126 }
127
128 //____________________________________________________________________________
129 Float_t  AliPHOSTrackSegmentMakerv1::GetDistanceInPHOSPlane(AliPHOSEmcRecPoint * emcClu,AliPHOSRecPoint * cpvClu, Bool_t &toofar) const
130 {
131   // Calculates the distance between the EMC RecPoint and the PPSD RecPoint
132   // Clusters are sorted in "rows" and "columns" of width 1 cm
133
134   Float_t delta = 1 ;  // Width of the rows in sorting of RecPoints (in cm)
135                        // if you change this value, change it as well in xxxRecPoint::Compare()
136   Float_t distance = fRcpv ;
137  
138   TVector3 vecEmc ;   // Local position of EMC recpoint
139   TVector3 vecCpv ;   // Local position of CPV recpoint propagated to EMC
140   TVector3 vecDist ;  // Distance between local positions of two points
141   
142   emcClu->GetLocalPosition(vecEmc) ;
143   cpvClu->GetLocalPosition(vecCpv)  ; 
144
145   toofar = kTRUE ;
146   if(emcClu->GetPHOSMod() == cpvClu->GetPHOSMod()){ 
147
148     Info("GetDistanceInPHOSPlane","%z",fESD);
149     if (fESD != 0x0) {
150       // Extrapolate the global track direction if any to CPV and find the closest track
151       Int_t nTracks = fESD->GetNumberOfTracks();
152       Int_t iClosestTrack = -1;
153       Double_t distance;
154       Double_t minDistance = 1e6;
155       Double_t pxyz[3], xyz[3];
156       AliESDtrack *track;
157       for (Int_t iTrack=0; iTrack<nTracks; iTrack++) {
158         track = fESD->GetTrack(iTrack);
159         track->GetOuterXYZ(xyz);     // track coord on the cylinder of PHOS radius
160         track->GetOuterPxPyPz(pxyz); // track momentum ibid.
161         vecDist = PropagateToCPV(xyz,pxyz,cpvClu->GetPHOSMod());
162         vecDist -= vecCpv;
163         distance = TMath::Sqrt(vecDist.X()*vecDist.X() + vecDist.Z()*vecDist.Z());
164         // Find the closest track to the EMC recpoint
165         if (distance < minDistance) {
166           minDistance = distance;
167           iClosestTrack = iTrack;
168         }
169       }
170
171       if (iClosestTrack != -1) {
172         track = fESD->GetTrack(iClosestTrack);
173         track->GetOuterPxPyPz(pxyz); // track momentum ibid.
174         TVector3 vecCpvGlobal; // Global position of the CPV recpoint
175         AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
176         const AliPHOSGeometry * geom = gime->PHOSGeometry() ; 
177         geom->GetGlobal((AliRecPoint*)cpvClu,vecCpvGlobal);
178         for (Int_t ixyz=0; ixyz<3; ixyz++)
179           xyz[ixyz] = vecCpvGlobal[ixyz];
180         vecDist = PropagateToCPV(xyz,pxyz,cpvClu->GetPHOSMod());
181         vecDist -= vecEmc;
182         distance = TMath::Sqrt(vecDist.X()*vecDist.X() + vecDist.Z()*vecDist.Z());
183       }
184     } else {
185       // If no ESD, than simply find EMC-CPV distance
186       distance = (vecCpv - vecEmc).Mag() ;
187     }
188     if(distance < fRcpv + 2*delta )
189       toofar = kFALSE ;
190   } 
191   
192   return distance ;
193 }
194
195 //____________________________________________________________________________
196 TVector3  AliPHOSTrackSegmentMakerv1::PropagateToCPV(Double_t *x, Double_t *p,
197                                                      Int_t moduleNumber) const
198 {
199   // Propagate a straight-line track from the origin point x
200   // along the direction p to the CPV module moduleNumber
201   // Returns a local position of such a propagation
202
203   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
204   const AliPHOSGeometry * geom = gime->PHOSGeometry() ; 
205   TVector3 moduleCenter = geom->GetCpvModuleCenter(moduleNumber);
206   TVector3 vertex(x);
207   TVector3 direction(p);
208
209   Double_t time = (moduleCenter.Mag2() - vertex.Dot(moduleCenter)) /
210     (direction.Dot(moduleCenter));
211   TVector3 globalIntersection = vertex + direction*time;
212   return geom->Global2LocalCpv(globalIntersection,moduleNumber);
213 }
214
215 //____________________________________________________________________________
216 void  AliPHOSTrackSegmentMakerv1::Init()
217 {
218   // Make all memory allocations that are not possible in default constructor
219   
220   AliPHOSGetter* gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName.Data());
221   
222   fLinkUpArray  = new TClonesArray("AliPHOSLink", 1000); 
223   if ( !gime->TrackSegmentMaker() ) {
224     gime->PostTrackSegmentMaker(this);
225   }
226 }
227
228 //____________________________________________________________________________
229 void  AliPHOSTrackSegmentMakerv1::InitParameters()
230 {
231   //Initializes parameters
232   fRcpv      = 10. ;   
233   fEmcFirst  = 0 ;    
234   fEmcLast   = 0 ;   
235   fCpvFirst  = 0 ;   
236   fCpvLast   = 0 ;   
237   fLinkUpArray = 0 ;
238   fTrackSegmentsInRun       = 0 ; 
239   SetEventRange(0,-1) ;
240 }
241
242
243 //____________________________________________________________________________
244 void  AliPHOSTrackSegmentMakerv1::MakeLinks()const
245
246   // Finds distances (links) between all EMC and PPSD clusters, 
247   // which are not further apart from each other than fRcpv 
248   // and sort them in accordance with this distance
249   
250   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
251   TObjArray * emcRecPoints = gime->EmcRecPoints() ; 
252   TObjArray * cpvRecPoints = gime->CpvRecPoints() ; 
253
254   fLinkUpArray->Clear() ;    
255
256   AliPHOSRecPoint * cpv ;
257   AliPHOSEmcRecPoint * emcclu ;
258
259   Int_t iLinkUp  = 0 ;
260   
261   Int_t iEmcRP;
262   for(iEmcRP = fEmcFirst; iEmcRP < fEmcLast; iEmcRP++ ) {
263     emcclu = dynamic_cast<AliPHOSEmcRecPoint *>(emcRecPoints->At(iEmcRP)) ;
264
265     Bool_t toofar ;        
266     Int_t iCpv = 0 ;    
267     for(iCpv = fCpvFirst; iCpv < fCpvLast;iCpv++ ) { 
268       
269       cpv = dynamic_cast<AliPHOSRecPoint *>(cpvRecPoints->At(iCpv)) ;
270       Float_t r = GetDistanceInPHOSPlane(emcclu, cpv, toofar) ;
271       
272       if(toofar)
273         break ;  
274       if(r < fRcpv) { 
275         new ((*fLinkUpArray)[iLinkUp++])  AliPHOSLink(r, iEmcRP, iCpv) ;
276       }      
277     }
278   } 
279   
280   fLinkUpArray->Sort() ;  //first links with smallest distances
281 }
282
283 //____________________________________________________________________________
284 void  AliPHOSTrackSegmentMakerv1::MakePairs()
285
286   // Using the previously made list of "links", we found the smallest link - i.e. 
287   // link with the least distance between EMC and CPV and pointing to still 
288   // unassigned RecParticles. We assign these RecPoints to TrackSegment and 
289   // remove them from the list of "unassigned". 
290
291   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
292
293   TObjArray * emcRecPoints = gime->EmcRecPoints() ; 
294   TObjArray * cpvRecPoints = gime->CpvRecPoints() ; 
295   TClonesArray * trackSegments = gime->TrackSegments();
296     
297   //Make arrays to mark clusters already chosen
298   Int_t * emcExist = 0;
299   if(fEmcLast > fEmcFirst)
300     emcExist = new Int_t[fEmcLast-fEmcFirst] ;
301   
302   Int_t index;
303   for(index = 0; index <fEmcLast-fEmcFirst; index ++)
304     emcExist[index] = 1 ;
305   
306   Bool_t * cpvExist = 0;
307   if(fCpvLast > fCpvFirst)
308     cpvExist = new Bool_t[fCpvLast-fCpvFirst] ;
309   for(index = 0; index <fCpvLast-fCpvFirst; index ++)
310     cpvExist[index] = kTRUE ;
311   
312   
313   // Finds the smallest links and makes pairs of CPV and EMC clusters with smallest distance 
314   TIter nextUp(fLinkUpArray) ;
315   
316   AliPHOSLink * linkUp ;
317   
318   AliPHOSRecPoint * nullpointer = 0 ;
319   
320   while ( (linkUp =  static_cast<AliPHOSLink *>(nextUp()) ) ){  
321
322     if(emcExist[linkUp->GetEmc()-fEmcFirst] != -1){ //without ppsd Up yet 
323
324       if(cpvExist[linkUp->GetPpsd()-fCpvFirst]){ //CPV still exist
325        
326        new ((* trackSegments)[fNTrackSegments]) 
327          AliPHOSTrackSegment(dynamic_cast<AliPHOSEmcRecPoint *>(emcRecPoints->At(linkUp->GetEmc())) , 
328                            dynamic_cast<AliPHOSRecPoint *>(cpvRecPoints->At(linkUp->GetPpsd()))) ;
329        (dynamic_cast<AliPHOSTrackSegment *>(trackSegments->At(fNTrackSegments)))->SetIndexInList(fNTrackSegments);
330        fNTrackSegments++ ;
331        
332        emcExist[linkUp->GetEmc()-fEmcFirst] = -1 ; //Mark emc  that Cpv was found 
333        //mark CPV recpoint as already used 
334        cpvExist[linkUp->GetPpsd()-fCpvFirst] = kFALSE ;
335       } //if ppsdUp still exist
336     } 
337   }        
338
339   //look through emc recPoints left without CPV/PPSD
340   if(emcExist){ //if there is emc rec point
341     Int_t iEmcRP ;
342     for(iEmcRP = 0; iEmcRP < fEmcLast-fEmcFirst  ; iEmcRP++ ){
343       if(emcExist[iEmcRP] > 0 ){
344        new ((*trackSegments)[fNTrackSegments])  
345          AliPHOSTrackSegment(dynamic_cast<AliPHOSEmcRecPoint *>(emcRecPoints->At(iEmcRP+fEmcFirst)), 
346                            nullpointer) ;
347        (dynamic_cast<AliPHOSTrackSegment *>(trackSegments->At(fNTrackSegments)))->SetIndexInList(fNTrackSegments);
348        fNTrackSegments++;    
349       } 
350     }
351   }
352   delete [] emcExist ; 
353   delete [] cpvExist ; 
354 }
355
356 //____________________________________________________________________________
357 void  AliPHOSTrackSegmentMakerv1::Exec(Option_t *option)
358 {
359   // Steering method to perform track segment construction for events
360   // in the range from fFirstEvent to fLastEvent.
361   // This range is optionally set by SetEventRange().
362   // if fLastEvent=-1 (by default), then process events until the end.
363   
364   if(strstr(option,"tim"))
365     gBenchmark->Start("PHOSTSMaker");
366  
367   if(strstr(option,"print")) {
368     Print() ; 
369     return ; 
370   }
371   
372   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;  
373  
374   const AliPHOSGeometry * geom = gime->PHOSGeometry() ; 
375
376   if (fLastEvent == -1) fLastEvent = gime->MaxEvent() - 1 ;
377   else fLastEvent = TMath::Min(fFirstEvent,gime->MaxEvent());
378   Int_t nEvents   = fLastEvent - fFirstEvent + 1;
379
380   Int_t ievent ; 
381   for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
382     gime->Event(ievent,"R") ;
383     //Make some initializations 
384     fNTrackSegments = 0 ;
385     fEmcFirst = 0 ;    
386     fEmcLast  = 0 ;   
387     fCpvFirst = 0 ;   
388     fCpvLast  = 0 ;   
389     
390     gime->TrackSegments()->Clear();
391
392     //    if(!ReadRecPoints(ievent))   continue; //reads RecPoints for event ievent
393     
394     for(fModule = 1; fModule <= geom->GetNModules() ; fModule++ ) {
395       FillOneModule() ; 
396       MakeLinks() ;
397       MakePairs() ;
398     }
399
400     WriteTrackSegments() ;
401
402     if(strstr(option,"deb"))
403       PrintTrackSegments(option);
404     
405     //increment the total number of track segments per run 
406     fTrackSegmentsInRun += gime->TrackSegments()->GetEntriesFast() ; 
407
408   }
409   
410   if(strstr(option,"tim")){
411     gBenchmark->Stop("PHOSTSMaker");
412     Info("Exec", "took %f seconds for making TS %f seconds per event", 
413           gBenchmark->GetCpuTime("PHOSTSMaker"), 
414           gBenchmark->GetCpuTime("PHOSTSMaker")/nEvents) ;
415    }
416   Unload();
417 }
418
419 //____________________________________________________________________________
420 void AliPHOSTrackSegmentMakerv1::Unload() 
421 {
422   // Unloads the task from the folder
423   AliPHOSGetter * gime = AliPHOSGetter::Instance() ;  
424   gime->PhosLoader()->UnloadRecPoints() ;
425   gime->PhosLoader()->UnloadTracks() ;
426 }
427
428 //____________________________________________________________________________
429 void AliPHOSTrackSegmentMakerv1::Print()const
430 {
431   //  Print TrackSegmentMaker parameters
432
433   TString message("") ;
434   if( strcmp(GetName(), "") != 0 ) {
435     message = "\n======== AliPHOSTrackSegmentMakerv1 ========\n" ; 
436     message += "Making Track segments\n" ;
437     message += "with parameters:\n" ; 
438     message += "     Maximal EMC - CPV (PPSD) distance (cm) %f\n" ;
439     message += "============================================\n" ;
440     Info("Print", message.Data(),fRcpv) ;
441   }
442   else
443     Info("Print", "AliPHOSTrackSegmentMakerv1 not initialized ") ;
444 }
445
446 //____________________________________________________________________________
447 void AliPHOSTrackSegmentMakerv1::WriteTrackSegments()
448 {
449   // Writes found TrackSegments to TreeR. Creates branches 
450   // "PHOSTS" and "AliPHOSTrackSegmentMaker" with the same title.
451   // In the former branch found TrackSegments are stored, while 
452   // in the latter all parameters, with which TS were made. 
453   // ROOT does not allow overwriting existing branches, therefore
454   // first we check, if branches with the same title already exist.
455   // If yes - exits without writing.
456
457   AliPHOSGetter *gime = AliPHOSGetter::Instance() ; 
458
459   TClonesArray * trackSegments = gime->TrackSegments() ; 
460   trackSegments->Expand(trackSegments->GetEntriesFast()) ;
461
462   TTree * treeT = gime->TreeT();
463  
464   //First TS
465   Int_t bufferSize = 32000 ; 
466   TBranch * tsBranch = treeT->Branch("PHOSTS",&trackSegments,bufferSize);
467   tsBranch->Fill() ;  
468
469   gime->WriteTracks("OVERWRITE");
470   gime->WriteTrackSegmentMaker("OVERWRITE");
471 }
472
473
474 //____________________________________________________________________________
475 void AliPHOSTrackSegmentMakerv1::PrintTrackSegments(Option_t * option)
476 {
477   // option deb - prints # of found TrackSegments
478   // option deb all - prints as well indexed of found RecParticles assigned to the TS
479
480   TClonesArray * trackSegments = AliPHOSGetter::Instance()->TrackSegments() ; 
481
482   Info("PrintTrackSegments", "Results from TrackSegmentMaker:") ; 
483   printf("nevent: %d\n", gAlice->GetEvNumber()) ; 
484   printf("        Found %d TrackSegments\n", trackSegments->GetEntriesFast() ); 
485   
486   if(strstr(option,"all")) {  // printing found TS
487     printf("TrackSegment #  EMC RP#  CPV RP#\n") ; 
488     Int_t index;
489     for (index = 0 ; index <trackSegments->GetEntriesFast() ; index++) {
490       AliPHOSTrackSegment * ts = (AliPHOSTrackSegment * )trackSegments->At(index) ; 
491       printf("   %d           %d        %d \n", ts->GetIndexInList(), ts->GetEmcIndex(), ts->GetCpvIndex() ) ; 
492     }   
493   }
494 }