]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PHOS/AliPHOSTrackSegmentMakerv1.cxx
26d814a4bd9548a50355a318a94fb06d296ccaf9
[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,AliPHOSCpvRecPoint * 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     if (fESD != 0x0) {
149       // Extrapolate the global track direction if any to CPV and find the closest track
150       Int_t nTracks = fESD->GetNumberOfTracks();
151       Int_t iClosestTrack = -1;
152       Double_t minDistance = 1e6;
153       Double_t pxyz[3], xyz[3];
154       AliESDtrack *track;
155       for (Int_t iTrack=0; iTrack<nTracks; iTrack++) {
156         track = fESD->GetTrack(iTrack);
157         track->GetOuterXYZ(xyz);     // track coord on the cylinder of PHOS radius
158         if ((TMath::Abs(xyz[0])+TMath::Abs(xyz[1])+TMath::Abs(xyz[2]))<=0)
159           continue;
160         track->GetOuterPxPyPz(pxyz); // track momentum ibid.
161         vecDist = PropagateToCPV(xyz,pxyz,cpvClu->GetPHOSMod());
162         Info("GetDistanceInPHOSPlane","YVK: Track %d propagation = (%f,%f,%f)",
163              iTrack,vecDist.X(),vecDist.Y(),vecDist.Z());
164         vecDist -= vecCpv;
165         distance = TMath::Sqrt(vecDist.X()*vecDist.X() + vecDist.Z()*vecDist.Z());
166         // Find the closest track to the EMC recpoint
167         if (distance < minDistance) {
168           minDistance = distance;
169           iClosestTrack = iTrack;
170         }
171       }
172
173       if (iClosestTrack != -1) {
174         track = fESD->GetTrack(iClosestTrack);
175         track->GetOuterPxPyPz(pxyz); // track momentum ibid.
176         TVector3 vecCpvGlobal; // Global position of the CPV recpoint
177         AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
178         const AliPHOSGeometry * geom = gime->PHOSGeometry() ; 
179         geom->GetGlobal((AliRecPoint*)cpvClu,vecCpvGlobal);
180         for (Int_t ixyz=0; ixyz<3; ixyz++)
181           xyz[ixyz] = vecCpvGlobal[ixyz];
182         vecDist = PropagateToCPV(xyz,pxyz,cpvClu->GetPHOSMod());
183         vecDist -= vecEmc;
184         distance = TMath::Sqrt(vecDist.X()*vecDist.X() + vecDist.Z()*vecDist.Z());
185       }
186     } else {
187       // If no ESD exists, than simply find EMC-CPV distance
188       distance = (vecCpv - vecEmc).Mag() ;
189     }
190     Info("GetDistanceInPHOSPlane","cpv-emc distance is %f cm",
191          distance);
192     if(distance < fRcpv + 2*delta )
193       toofar = kFALSE ;
194   } 
195   
196   return distance ;
197 }
198
199 //____________________________________________________________________________
200 TVector3  AliPHOSTrackSegmentMakerv1::PropagateToCPV(Double_t *x, Double_t *p,
201                                                      Int_t moduleNumber) const
202 {
203   // Propagate a straight-line track from the origin point x
204   // along the direction p to the CPV module moduleNumber
205   // Returns a local position of such a propagation
206
207   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
208   const AliPHOSGeometry * geom = gime->PHOSGeometry() ; 
209   TVector3 moduleCenter = geom->GetCpvModuleCenter(moduleNumber);
210   TVector3 vertex(x);
211   TVector3 direction(p);
212
213 //   Info("PropagateToCPV","YVK: center of the module %d is (%f,%f,%f)",
214 //        moduleNumber,moduleCenter[0],moduleCenter[1],moduleCenter[2]);
215
216   Double_t time = (moduleCenter.Mag2() - vertex.Dot(moduleCenter)) /
217     (direction.Dot(moduleCenter));
218   TVector3 globalIntersection = vertex + direction*time;
219   return geom->Global2LocalCpv(globalIntersection,moduleNumber);
220 }
221
222 //____________________________________________________________________________
223 void  AliPHOSTrackSegmentMakerv1::Init()
224 {
225   // Make all memory allocations that are not possible in default constructor
226   
227   AliPHOSGetter* gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName.Data());
228   
229   fLinkUpArray  = new TClonesArray("AliPHOSLink", 1000); 
230   if ( !gime->TrackSegmentMaker() ) {
231     gime->PostTrackSegmentMaker(this);
232   }
233 }
234
235 //____________________________________________________________________________
236 void  AliPHOSTrackSegmentMakerv1::InitParameters()
237 {
238   //Initializes parameters
239   fRcpv      = 10. ;   
240   fEmcFirst  = 0 ;    
241   fEmcLast   = 0 ;   
242   fCpvFirst  = 0 ;   
243   fCpvLast   = 0 ;   
244   fLinkUpArray = 0 ;
245   fTrackSegmentsInRun       = 0 ; 
246   SetEventRange(0,-1) ;
247 }
248
249
250 //____________________________________________________________________________
251 void  AliPHOSTrackSegmentMakerv1::MakeLinks()const
252
253   // Finds distances (links) between all EMC and PPSD clusters, 
254   // which are not further apart from each other than fRcpv 
255   // and sort them in accordance with this distance
256   
257   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
258   TObjArray * emcRecPoints = gime->EmcRecPoints() ; 
259   TObjArray * cpvRecPoints = gime->CpvRecPoints() ; 
260
261   fLinkUpArray->Clear() ;    
262
263   AliPHOSCpvRecPoint * cpv ;
264   AliPHOSEmcRecPoint * emcclu ;
265
266   Int_t iLinkUp  = 0 ;
267   
268   Int_t iEmcRP;
269   for(iEmcRP = fEmcFirst; iEmcRP < fEmcLast; iEmcRP++ ) {
270     emcclu = dynamic_cast<AliPHOSEmcRecPoint *>(emcRecPoints->At(iEmcRP)) ;
271
272     Bool_t toofar ;        
273     Int_t iCpv = 0 ;    
274     for(iCpv = fCpvFirst; iCpv < fCpvLast;iCpv++ ) { 
275       
276       cpv = dynamic_cast<AliPHOSCpvRecPoint *>(cpvRecPoints->At(iCpv)) ;
277       Float_t r = GetDistanceInPHOSPlane(emcclu, cpv, toofar) ;
278       
279       if(toofar)
280         break ;  
281       if(r < fRcpv) { 
282         new ((*fLinkUpArray)[iLinkUp++])  AliPHOSLink(r, iEmcRP, iCpv) ;
283       }      
284     }
285   } 
286   
287   fLinkUpArray->Sort() ;  //first links with smallest distances
288 }
289
290 //____________________________________________________________________________
291 void  AliPHOSTrackSegmentMakerv1::MakePairs()
292
293   // Using the previously made list of "links", we found the smallest link - i.e. 
294   // link with the least distance between EMC and CPV and pointing to still 
295   // unassigned RecParticles. We assign these RecPoints to TrackSegment and 
296   // remove them from the list of "unassigned". 
297
298   AliPHOSGetter * gime = AliPHOSGetter::Instance() ; 
299
300   TObjArray * emcRecPoints = gime->EmcRecPoints() ; 
301   TObjArray * cpvRecPoints = gime->CpvRecPoints() ; 
302   TClonesArray * trackSegments = gime->TrackSegments();
303     
304   //Make arrays to mark clusters already chosen
305   Int_t * emcExist = 0;
306   if(fEmcLast > fEmcFirst)
307     emcExist = new Int_t[fEmcLast-fEmcFirst] ;
308   
309   Int_t index;
310   for(index = 0; index <fEmcLast-fEmcFirst; index ++)
311     emcExist[index] = 1 ;
312   
313   Bool_t * cpvExist = 0;
314   if(fCpvLast > fCpvFirst)
315     cpvExist = new Bool_t[fCpvLast-fCpvFirst] ;
316   for(index = 0; index <fCpvLast-fCpvFirst; index ++)
317     cpvExist[index] = kTRUE ;
318   
319   
320   // Finds the smallest links and makes pairs of CPV and EMC clusters with smallest distance 
321   TIter nextUp(fLinkUpArray) ;
322   
323   AliPHOSLink * linkUp ;
324   
325   AliPHOSCpvRecPoint * nullpointer = 0 ;
326   
327   while ( (linkUp =  static_cast<AliPHOSLink *>(nextUp()) ) ){  
328
329     if(emcExist[linkUp->GetEmc()-fEmcFirst] != -1){ //without ppsd Up yet 
330
331       if(cpvExist[linkUp->GetPpsd()-fCpvFirst]){ //CPV still exist
332        
333        new ((* trackSegments)[fNTrackSegments]) 
334          AliPHOSTrackSegment(dynamic_cast<AliPHOSEmcRecPoint *>(emcRecPoints->At(linkUp->GetEmc())) , 
335                              dynamic_cast<AliPHOSCpvRecPoint *>(cpvRecPoints->At(linkUp->GetPpsd()))) ;
336        (dynamic_cast<AliPHOSTrackSegment *>(trackSegments->At(fNTrackSegments)))->SetIndexInList(fNTrackSegments);
337        fNTrackSegments++ ;
338        
339        emcExist[linkUp->GetEmc()-fEmcFirst] = -1 ; //Mark emc  that Cpv was found 
340        //mark CPV recpoint as already used 
341        cpvExist[linkUp->GetPpsd()-fCpvFirst] = kFALSE ;
342       } //if ppsdUp still exist
343     } 
344   }        
345
346   //look through emc recPoints left without CPV/PPSD
347   if(emcExist){ //if there is emc rec point
348     Int_t iEmcRP ;
349     for(iEmcRP = 0; iEmcRP < fEmcLast-fEmcFirst  ; iEmcRP++ ){
350       if(emcExist[iEmcRP] > 0 ){
351        new ((*trackSegments)[fNTrackSegments])  
352          AliPHOSTrackSegment(dynamic_cast<AliPHOSEmcRecPoint *>(emcRecPoints->At(iEmcRP+fEmcFirst)), 
353                            nullpointer) ;
354        (dynamic_cast<AliPHOSTrackSegment *>(trackSegments->At(fNTrackSegments)))->SetIndexInList(fNTrackSegments);
355        fNTrackSegments++;    
356       } 
357     }
358   }
359   delete [] emcExist ; 
360   delete [] cpvExist ; 
361 }
362
363 //____________________________________________________________________________
364 void  AliPHOSTrackSegmentMakerv1::Exec(Option_t *option)
365 {
366   // Steering method to perform track segment construction for events
367   // in the range from fFirstEvent to fLastEvent.
368   // This range is optionally set by SetEventRange().
369   // if fLastEvent=-1 (by default), then process events until the end.
370   
371   if(strstr(option,"tim"))
372     gBenchmark->Start("PHOSTSMaker");
373  
374   if(strstr(option,"print")) {
375     Print() ; 
376     return ; 
377   }
378   
379   AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle()) ;  
380  
381   const AliPHOSGeometry * geom = gime->PHOSGeometry() ; 
382
383   if (fLastEvent == -1) fLastEvent = gime->MaxEvent() - 1 ;
384   else fLastEvent = TMath::Min(fFirstEvent,gime->MaxEvent());
385   Int_t nEvents   = fLastEvent - fFirstEvent + 1;
386
387   Int_t ievent ; 
388   for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
389     gime->Event(ievent,"R") ;
390     //Make some initializations 
391     fNTrackSegments = 0 ;
392     fEmcFirst = 0 ;    
393     fEmcLast  = 0 ;   
394     fCpvFirst = 0 ;   
395     fCpvLast  = 0 ;   
396     
397     gime->TrackSegments()->Clear();
398
399     //    if(!ReadRecPoints(ievent))   continue; //reads RecPoints for event ievent
400     
401     for(fModule = 1; fModule <= geom->GetNModules() ; fModule++ ) {
402       FillOneModule() ; 
403       MakeLinks() ;
404       MakePairs() ;
405     }
406
407     WriteTrackSegments() ;
408
409     if(strstr(option,"deb"))
410       PrintTrackSegments(option);
411     
412     //increment the total number of track segments per run 
413     fTrackSegmentsInRun += gime->TrackSegments()->GetEntriesFast() ; 
414
415   }
416   
417   if(strstr(option,"tim")){
418     gBenchmark->Stop("PHOSTSMaker");
419     Info("Exec", "took %f seconds for making TS %f seconds per event", 
420           gBenchmark->GetCpuTime("PHOSTSMaker"), 
421           gBenchmark->GetCpuTime("PHOSTSMaker")/nEvents) ;
422    }
423   Unload();
424 }
425
426 //____________________________________________________________________________
427 void AliPHOSTrackSegmentMakerv1::Unload() 
428 {
429   // Unloads the task from the folder
430   AliPHOSGetter * gime = AliPHOSGetter::Instance() ;  
431   gime->PhosLoader()->UnloadRecPoints() ;
432   gime->PhosLoader()->UnloadTracks() ;
433 }
434
435 //____________________________________________________________________________
436 void AliPHOSTrackSegmentMakerv1::Print()const
437 {
438   //  Print TrackSegmentMaker parameters
439
440   TString message("") ;
441   if( strcmp(GetName(), "") != 0 ) {
442     message = "\n======== AliPHOSTrackSegmentMakerv1 ========\n" ; 
443     message += "Making Track segments\n" ;
444     message += "with parameters:\n" ; 
445     message += "     Maximal EMC - CPV (PPSD) distance (cm) %f\n" ;
446     message += "============================================\n" ;
447     Info("Print", message.Data(),fRcpv) ;
448   }
449   else
450     Info("Print", "AliPHOSTrackSegmentMakerv1 not initialized ") ;
451 }
452
453 //____________________________________________________________________________
454 void AliPHOSTrackSegmentMakerv1::WriteTrackSegments()
455 {
456   // Writes found TrackSegments to TreeR. Creates branches 
457   // "PHOSTS" and "AliPHOSTrackSegmentMaker" with the same title.
458   // In the former branch found TrackSegments are stored, while 
459   // in the latter all parameters, with which TS were made. 
460   // ROOT does not allow overwriting existing branches, therefore
461   // first we check, if branches with the same title already exist.
462   // If yes - exits without writing.
463
464   AliPHOSGetter *gime = AliPHOSGetter::Instance() ; 
465
466   TClonesArray * trackSegments = gime->TrackSegments() ; 
467   trackSegments->Expand(trackSegments->GetEntriesFast()) ;
468
469   TTree * treeT = gime->TreeT();
470  
471   //First TS
472   Int_t bufferSize = 32000 ; 
473   TBranch * tsBranch = treeT->Branch("PHOSTS",&trackSegments,bufferSize);
474   tsBranch->Fill() ;  
475
476   gime->WriteTracks("OVERWRITE");
477   gime->WriteTrackSegmentMaker("OVERWRITE");
478 }
479
480
481 //____________________________________________________________________________
482 void AliPHOSTrackSegmentMakerv1::PrintTrackSegments(Option_t * option)
483 {
484   // option deb - prints # of found TrackSegments
485   // option deb all - prints as well indexed of found RecParticles assigned to the TS
486
487   TClonesArray * trackSegments = AliPHOSGetter::Instance()->TrackSegments() ; 
488
489   Info("PrintTrackSegments", "Results from TrackSegmentMaker:") ; 
490   printf("nevent: %d\n", gAlice->GetEvNumber()) ; 
491   printf("        Found %d TrackSegments\n", trackSegments->GetEntriesFast() ); 
492   
493   if(strstr(option,"all")) {  // printing found TS
494     printf("TrackSegment #  EMC RP#  CPV RP#\n") ; 
495     Int_t index;
496     for (index = 0 ; index <trackSegments->GetEntriesFast() ; index++) {
497       AliPHOSTrackSegment * ts = (AliPHOSTrackSegment * )trackSegments->At(index) ; 
498       printf("   %d           %d        %d \n", ts->GetIndexInList(), ts->GetEmcIndex(), ts->GetCpvIndex() ) ; 
499     }   
500   }
501 }