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