1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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 fR0.
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
29 // If there is no CPV/PPSD RecPoint we make TrackSegment
30 // consisting from EMC alone. There is no TrackSegments without EMC RecPoint.
32 // In principle this class should be called from AliPHOSReconstructioner, but
33 // one can use it as well in standalone mode.
35 // root [0] AliPHOSTrackSegmentMakerv1 * t = new AliPHOSTrackSegmentMaker("galice.root")
36 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
37 // root [1] t->ExecuteTask()
38 // root [2] t->SetMaxEmcPpsdDistance(5)
39 // root [3] t->SetTrackSegmentsBranch("max distance 5 cm")
40 // root [4] t->ExecuteTask("deb all time")
42 //*-- Author: Dmitri Peressounko (RRC Ki & SUBATECH)
45 // --- ROOT system ---
50 #include "TBenchmark.h"
51 // --- Standard library ---
56 // --- AliRoot header files ---
58 #include "AliPHOSTrackSegmentMakerv1.h"
59 #include "AliPHOSClusterizerv1.h"
60 #include "AliPHOSTrackSegment.h"
61 #include "AliPHOSCpvRecPoint.h"
62 #include "AliPHOSPpsdRecPoint.h"
63 #include "AliPHOSLink.h"
67 ClassImp( AliPHOSTrackSegmentMakerv1)
70 //____________________________________________________________________________
71 AliPHOSTrackSegmentMakerv1::AliPHOSTrackSegmentMakerv1() : AliPHOSTrackSegmentMaker()
74 SetTitle("version 1") ;
75 SetName("AliPHOSTrackSegmentMaker") ;
85 fIsInitialized = kFALSE ;
87 //____________________________________________________________________________
88 AliPHOSTrackSegmentMakerv1::AliPHOSTrackSegmentMakerv1(const char* headerFile, const char* branchTitle):
89 AliPHOSTrackSegmentMaker()
92 SetTitle("version 1") ;
93 SetName("AliPHOSTrackSegmentMaker") ;
102 fHeaderFileName = headerFile ;
103 fRecPointsBranchTitle = branchTitle ;
104 fIsInitialized = kFALSE ;
109 //____________________________________________________________________________
110 void AliPHOSTrackSegmentMakerv1::Init()
112 // Make all memory allocations that are not possible in default constructor
115 if(fHeaderFileName.IsNull())
116 fHeaderFileName = "galice.root" ;
118 TFile * file = (TFile*) gROOT->GetFile(fHeaderFileName.Data() ) ;
121 if(fHeaderFileName.Contains("rfio")) // if we read file using HPSS
122 file = TFile::Open(fHeaderFileName.Data(),"update") ;
124 file = new TFile(fHeaderFileName.Data(),"update") ;
125 gAlice = (AliRun *) file->Get("gAlice") ;
128 AliPHOS * phos = (AliPHOS *) gAlice->GetDetector("PHOS") ;
129 fGeom = AliPHOSGeometry::GetInstance(phos->GetGeometry()->GetName(),phos->GetGeometry()->GetTitle() );
131 fEmcRecPoints = new TObjArray(200) ;
132 fCpvRecPoints = new TObjArray(200) ;
133 fClusterizer = new AliPHOSClusterizerv1() ;
135 fTrackSegments = new TClonesArray("AliPHOSTrackSegment",200) ;
137 fLinkLowArray = new TClonesArray("AliPHOSLink", 1000);
138 fLinkUpArray = new TClonesArray("AliPHOSLink", 1000);
140 fIsInitialized = kTRUE ;
144 //____________________________________________________________________________
145 AliPHOSTrackSegmentMakerv1::~AliPHOSTrackSegmentMakerv1()
148 if(fLinkLowArray) delete fLinkLowArray ;
149 if(fLinkUpArray) delete fLinkUpArray ;
152 //____________________________________________________________________________
153 void AliPHOSTrackSegmentMakerv1::FillOneModule()
155 // Finds first and last indexes between which
156 // clusters from one PHOS module are
160 Int_t totalEmc = fEmcRecPoints->GetEntriesFast() ;
161 for(fEmcFirst = fEmcLast; (fEmcLast < totalEmc) &&
162 (((AliPHOSRecPoint *) fEmcRecPoints->At(fEmcLast))->GetPHOSMod() == fModule );
167 Int_t totalCpv = fCpvRecPoints->GetEntriesFast() ;
169 if(fModule <= fGeom->GetNCPVModules()){ // in CPV geometry
171 for(fCpvFirst = fCpvLast; (fCpvLast < totalCpv) &&
172 (((AliPHOSRecPoint *) fCpvRecPoints->At(fCpvLast))->GetPHOSMod() == fModule );
175 fPpsdFirst = fCpvLast ; //To avoid scanning RecPoints between fPpsdFirst and fPpsdLast
176 fPpsdLast = fCpvLast ; //and to be ready to switch to mixed geometry
178 else{ //in PPSD geometry
179 fCpvLast = fPpsdLast ;
181 for(fCpvFirst = fCpvLast; (fCpvLast < totalCpv) &&
182 (((AliPHOSPpsdRecPoint *) fCpvRecPoints->At(fCpvLast))->GetPHOSMod() == fModule ) &&
183 (((AliPHOSPpsdRecPoint *) fCpvRecPoints->At(fCpvLast))->GetUp()) ;
186 fPpsdLast= fCpvLast ;
187 for(fPpsdFirst = fPpsdLast; (fPpsdLast < totalCpv) &&
188 (((AliPHOSPpsdRecPoint *) fCpvRecPoints->At(fPpsdLast))->GetPHOSMod() == fModule ) &&
189 (!((AliPHOSPpsdRecPoint *) fCpvRecPoints->At(fPpsdLast))->GetUp()) ;
194 //____________________________________________________________________________
195 Float_t AliPHOSTrackSegmentMakerv1::GetDistanceInPHOSPlane(AliPHOSEmcRecPoint * emcClu,AliPHOSRecPoint * cpvClu, Bool_t &toofar)const
197 // Calculates the distance between the EMC RecPoint and the PPSD RecPoint
198 // Clusters are sorted in "rows" and "columns" of width 1 cm
200 Float_t delta = 1 ; // Width of the rows in sorting of RecPoints (in cm)
201 // if you change this value, change it as well in xxxRecPoint::Compare()
207 emcClu->GetLocalPosition(vecEmc) ;
208 cpvClu->GetLocalPosition(vecCpv) ;
210 if(emcClu->GetPHOSMod() == cpvClu->GetPHOSMod()){
211 if(vecCpv.X() <= vecEmc.X() + fR0 + 2*delta ){
213 vecCpv = vecCpv - vecEmc ;
217 } // if xPpsd >= xEmc + ...
230 //____________________________________________________________________________
231 void AliPHOSTrackSegmentMakerv1::MakeLinks()const
233 // Finds distances (links) between all EMC and PPSD clusters,
234 // which are not further apart from each other than fR0
235 // and sort them in accordance with this distance
237 fLinkUpArray->Clear() ;
238 fLinkLowArray->Clear() ;
240 AliPHOSRecPoint * ppsd ;
241 AliPHOSRecPoint * cpv ;
242 AliPHOSEmcRecPoint * emcclu ;
248 for(iEmcRP = fEmcFirst; iEmcRP < fEmcLast; iEmcRP++ ) {
249 emcclu = (AliPHOSEmcRecPoint *) fEmcRecPoints->At(iEmcRP) ;
253 for(iPpsd = fPpsdFirst; iPpsd < fPpsdLast;iPpsd++ ) {
255 ppsd = (AliPHOSRecPoint *) fCpvRecPoints->At(iPpsd) ;
256 Float_t r = GetDistanceInPHOSPlane(emcclu, ppsd, toofar) ;
261 new ((*fLinkLowArray)[iLinkLow++]) AliPHOSLink(r, iEmcRP, iPpsd) ;
265 for(iCpv = fCpvFirst; iCpv < fCpvLast;iCpv++ ) {
267 cpv = (AliPHOSRecPoint *) fCpvRecPoints->At(iCpv) ;
268 Float_t r = GetDistanceInPHOSPlane(emcclu, cpv, toofar) ;
273 new ((*fLinkUpArray)[iLinkUp++]) AliPHOSLink(r, iEmcRP, iCpv) ;
278 fLinkLowArray->Sort() ; //first links with smallest distances
279 fLinkUpArray->Sort() ;
282 //____________________________________________________________________________
283 void AliPHOSTrackSegmentMakerv1::MakePairs()
285 // Using the previously made list of "links", we found the smallest link - i.e.
286 // link with the least distance between EMC and CPV and pointing to still
287 // unassigned RecParticles. We assign these RecPoints to TrackSegment and
288 // remove them from the list of "unassigned".
290 //Make arrays to mark clusters already chousen
291 Int_t * emcExist = 0;
292 if(fEmcLast > fEmcFirst)
293 emcExist = new Int_t[fEmcLast-fEmcFirst] ;
296 for(index = 0; index <fEmcLast-fEmcFirst; index ++)
297 emcExist[index] = 1 ;
299 Bool_t * cpvExist = 0;
300 if(fCpvLast > fCpvFirst)
301 cpvExist = new Bool_t[fCpvLast-fCpvFirst] ;
302 for(index = 0; index <fCpvLast-fCpvFirst; index ++)
303 cpvExist[index] = kTRUE ;
305 Bool_t * ppsdExist = 0;
306 if(fPpsdLast > fPpsdFirst)
307 ppsdExist = new Bool_t[fPpsdLast-fPpsdFirst] ;
308 for(index = 0; index <fPpsdLast-fPpsdFirst; index ++)
309 ppsdExist[index] = kTRUE ;
311 // Finds the smallest links and makes pairs of CPV and EMC clusters with smallest distance
312 TIter nextLow(fLinkLowArray) ;
313 TIter nextUp(fLinkUpArray) ;
315 AliPHOSLink * linkLow ;
316 AliPHOSLink * linkUp ;
319 AliPHOSRecPoint * nullpointer = 0 ;
321 while ( (linkLow = (AliPHOSLink *)nextLow() ) ){
323 if( (emcExist[linkLow->GetEmc()-fEmcFirst]> 0) &&
324 ppsdExist[linkLow->GetPpsd()-fPpsdFirst] ){ // RecPoints not removed yet
325 new ((*fTrackSegments)[fNTrackSegments]) AliPHOSTrackSegment((AliPHOSEmcRecPoint *) fEmcRecPoints->At(linkLow->GetEmc()),
327 (AliPHOSRecPoint *)fCpvRecPoints->At(linkLow->GetPpsd()) ) ;
329 ((AliPHOSTrackSegment* )fTrackSegments->At(fNTrackSegments))->SetIndexInList(fNTrackSegments);
330 //replace index of emc to negative and shifted index of TS
331 emcExist[linkLow->GetEmc()-fEmcFirst] = -2 - fNTrackSegments ;
333 ppsdExist[linkLow->GetPpsd()-fPpsdFirst] = kFALSE ;
339 while ( (linkUp = (AliPHOSLink *)nextUp() ) ){
340 if(emcExist[linkUp->GetEmc()-fEmcFirst] != -1){ //without ppsd Up yet
342 if(cpvExist[linkUp->GetPpsd()-fCpvFirst]){ //CPV still exist
344 if(emcExist[linkUp->GetEmc()-fEmcFirst] > 0){ //without ppsd Low => create new TS
346 new ((* fTrackSegments)[fNTrackSegments]) AliPHOSTrackSegment((AliPHOSEmcRecPoint *) fEmcRecPoints->At(linkUp->GetEmc()) ,
347 (AliPHOSRecPoint *)fCpvRecPoints->At(linkUp->GetPpsd()),
349 ((AliPHOSTrackSegment *) fTrackSegments->At(fNTrackSegments))->SetIndexInList(fNTrackSegments);
352 else{ // append ppsd Up to existing TS
353 ((AliPHOSTrackSegment *)fTrackSegments->At(-2-emcExist[linkUp->GetEmc()-fEmcFirst]))->SetCpvRecPoint((AliPHOSCpvRecPoint *)fCpvRecPoints->At(linkUp->GetPpsd()));
356 emcExist[linkUp->GetEmc()-fEmcFirst] = -1 ; //Mark emc that Cpv was found
357 //mark CPV recpoint as already used
358 cpvExist[linkUp->GetPpsd()-fCpvFirst] = kFALSE ;
359 } //if ppsdUp still exist
363 //look through emc recPoints left without CPV/PPSD
364 if(emcExist){ //if there is emc rec point
366 for(iEmcRP = 0; iEmcRP < fEmcLast-fEmcFirst ; iEmcRP++ ){
367 if(emcExist[iEmcRP] > 0 ){
368 new ((*fTrackSegments)[fNTrackSegments]) AliPHOSTrackSegment((AliPHOSEmcRecPoint *)fEmcRecPoints->At(iEmcRP+fEmcFirst),
371 ((AliPHOSTrackSegment *) fTrackSegments->At(fNTrackSegments))->SetIndexInList(fNTrackSegments);
379 //____________________________________________________________________________
380 void AliPHOSTrackSegmentMakerv1::Exec(Option_t * option)
384 if(! fIsInitialized) Init() ;
386 if(strstr(option,"tim"))
387 gBenchmark->Start("PHOSTSMaker");
389 Int_t nEvents = (Int_t) gAlice->TreeE()->GetEntries() ;
391 for(fEvent = 0;fEvent< nEvents; fEvent++){
392 if(!ReadRecPoints()) //reads RecPoints for event fEvent
395 for(fModule = 1; fModule <= fGeom->GetNModules() ; fModule++ ){
405 WriteTrackSegments() ;
406 if(strstr(option,"deb"))
407 PrintTrackSegments(option) ;
410 if(strstr(option,"tim")){
411 gBenchmark->Stop("PHOSTSMaker");
412 cout << "AliPHOSTSMaker:" << endl ;
413 cout << " took " << gBenchmark->GetCpuTime("PHOSTSMaker") << " seconds for making TS "
414 << gBenchmark->GetCpuTime("PHOSTSMaker")/nEvents << " seconds per event " << endl ;
420 //____________________________________________________________________________
421 void AliPHOSTrackSegmentMakerv1::Print(Option_t * option)const
423 // Print TrackSegmentMaker parameters
426 cout << "======== AliPHOSTrackSegmentMakerv1 ========" << endl ;
427 cout << "Making Track segments "<< endl ;
428 cout << " Headers file: " << fHeaderFileName.Data() << endl ;
429 cout << " RecPoints branch file name: " << fRecPointsBranchTitle.Data() << endl ;
430 cout << " TrackSegments Branch file name: " << fTSBranchTitle.Data() << endl ;
431 cout << "with parameters: " << endl ;
432 cout << " Maximal EMC - CPV (PPSD) distance (cm)" << fR0 << endl ;
433 cout << "============================================" << endl ;
436 cout << "AliPHOSTrackSegmentMakerv1 not initialized " << endl ;
438 //____________________________________________________________________________
439 Bool_t AliPHOSTrackSegmentMakerv1::ReadRecPoints()
441 // Reads Emc and CPV recPoints with given title (fRecPointsBranchTitle)
442 // made previously with Clusterizer.
445 //Make some initializations
446 fEmcRecPoints->Clear() ;
447 fCpvRecPoints->Clear() ;
448 fTrackSegments->Clear() ;
449 fNTrackSegments = 0 ;
458 gAlice->GetEvent(fEvent) ;
460 // Get TreeR header from file
461 if(gAlice->TreeR()==0){
463 sprintf(treeName,"TreeR%d",fEvent);
464 cout << "Error in AliPHOSTrackSegmentMakerv1 : no "<<treeName << endl ;
465 cout << " Do nothing " << endl ;
470 //Find RecPoints with title fRecPointsBranchTitle
471 TBranch * emcBranch = 0;
472 TBranch * cpvBranch = 0;
473 TBranch * clusterizerBranch = 0;
475 TObjArray * branches = gAlice->TreeR()->GetListOfBranches() ;
477 Bool_t emcNotFound = kTRUE ;
478 Bool_t cpvNotFound = kTRUE ;
479 Bool_t clusterizerNotFound = kTRUE ;
481 for(ibranch = 0;ibranch <branches->GetEntries();ibranch++){
484 emcBranch=(TBranch *) branches->At(ibranch) ;
485 if( fRecPointsBranchTitle.CompareTo(emcBranch->GetTitle())==0 )
486 if( strcmp(emcBranch->GetName(),"PHOSEmcRP") == 0) {
487 emcNotFound = kFALSE ;
492 cpvBranch=(TBranch *) branches->At(ibranch) ;
493 if( fRecPointsBranchTitle.CompareTo(cpvBranch->GetTitle())==0 )
494 if( strcmp(cpvBranch->GetName(),"PHOSCpvRP") == 0)
495 cpvNotFound = kFALSE ;
498 if(clusterizerNotFound){
499 clusterizerBranch = (TBranch *) branches->At(ibranch) ;
500 if( fRecPointsBranchTitle.CompareTo(clusterizerBranch->GetTitle()) == 0)
501 if( strcmp(clusterizerBranch->GetName(),"AliPHOSClusterizer") == 0)
502 clusterizerNotFound = kFALSE ;
507 if(clusterizerNotFound || emcNotFound || cpvNotFound){
508 cout << "AliPHOSTrackSegmentMakerv1: " << endl ;
509 cout << " Can't find Branch with RecPoints or Clusterizer " ;
510 cout << " Do nothing" <<endl ;
514 emcBranch->SetAddress(&fEmcRecPoints) ;
515 cpvBranch->SetAddress(&fCpvRecPoints) ;
516 clusterizerBranch->SetAddress(&fClusterizer) ;
518 emcBranch->GetEntry(0) ;
519 cpvBranch->GetEntry(0) ;
520 clusterizerBranch->GetEntry(0) ;
525 //____________________________________________________________________________
526 void AliPHOSTrackSegmentMakerv1::WriteTrackSegments()
528 // Writes found TrackSegments to TreeR. Creates branches
529 // "PHOSTS" and "AliPHOSTrackSegmentMaker" with the same title.
530 // In the former branch found TrackSegments are stored, while
531 // in the latter all parameters, with which TS were made.
532 // ROOT does not allow overwriting existing branches, therefore
533 // first we check, if branches with the same title already exist.
534 // If yes - exits without writing.
536 //First, check, if branches already exist
537 TBranch * tsMakerBranch = 0;
538 TBranch * tsBranch = 0;
540 TObjArray * branches = gAlice->TreeR()->GetListOfBranches() ;
542 Bool_t tsMakerNotFound = kTRUE ;
543 Bool_t tsNotFound = kTRUE ;
545 for(ibranch = 0;(ibranch <branches->GetEntries())&&(tsMakerNotFound||tsNotFound);ibranch++){
547 tsMakerBranch=(TBranch *) branches->At(ibranch) ;
548 if( (strcmp(tsMakerBranch->GetName(),"AliPHOSTrackSegmentMaker") == 0) &&
549 (fTSBranchTitle.CompareTo( tsMakerBranch->GetTitle())==0 ))
550 tsMakerNotFound = kFALSE ;
553 tsBranch=(TBranch *) branches->At(ibranch) ;
554 if( (strcmp(tsBranch->GetName(),"PHOSTS") == 0) &&
555 (fTSBranchTitle.CompareTo( tsBranch->GetTitle())==0 ))
556 tsNotFound = kFALSE ;
560 if(!(tsMakerNotFound && tsNotFound )){
561 cout << "AliPHOSTrackSegmentMakerv1 error:"<< endl ;
562 cout << " Branches PHOSTS and AliPHOSTrackSegementMaker " << endl ;
563 cout << " with title '"<<fTSBranchTitle.Data() << "' already exist " << endl ;
564 cout << " can not overwrite " << endl ;
568 //Make branch in TreeR for TrackSegments
570 if(gSystem->Getenv("CONFIG_SPLIT_FILE")!=0){ //generating file name
571 filename = new char[strlen(gAlice->GetBaseFile())+20] ;
572 sprintf(filename,"%s/PHOS.Reco.root",gAlice->GetBaseFile()) ;
575 TDirectory *cwd = gDirectory;
578 Int_t bufferSize = 32000 ;
579 tsBranch = gAlice->TreeR()->Branch("PHOSTS",&fTrackSegments,bufferSize);
580 tsBranch->SetTitle(fTSBranchTitle.Data());
582 tsBranch->SetFile(filename);
583 TIter next( tsBranch->GetListOfBranches());
585 while ((sb=(TBranch*)next())) {
586 sb->SetFile(filename);
592 Int_t splitlevel = 0 ;
593 AliPHOSTrackSegmentMakerv1 * ts = this ;
594 tsMakerBranch = gAlice->TreeR()->Branch("AliPHOSTrackSegmentMaker","AliPHOSTrackSegmentMakerv1",
595 &ts,bufferSize,splitlevel);
596 tsMakerBranch->SetTitle(fTSBranchTitle.Data());
598 tsMakerBranch->SetFile(filename);
599 TIter next( tsMakerBranch->GetListOfBranches());
601 while ((sb=(TBranch*)next())) {
602 sb->SetFile(filename);
608 tsMakerBranch->Fill() ;
610 gAlice->TreeR()->Write(0,kOverwrite) ;
615 //____________________________________________________________________________
616 void AliPHOSTrackSegmentMakerv1::PrintTrackSegments(Option_t * option)
618 // option deb - prints # of found TrackSegments
619 // option deb all - prints as well indexed of found RecParticles assigned to the TS
622 cout << "AliPHOSTrackSegmentMakerv1: " << endl ;
623 cout << " Found " << fTrackSegments->GetEntriesFast() << " trackSegments " << endl ;
625 if(strstr(option,"all")) { // printing found TS
626 cout << "TrackSegment # " << " EMC RP# " << " CPV RP# " << " PPSD RP#" << endl ;
629 for (index = 0 ; index <fTrackSegments->GetEntriesFast() ; index++) {
630 AliPHOSTrackSegment * ts = (AliPHOSTrackSegment * )fTrackSegments->At(index) ;
631 cout<<" "<< setw(4) << ts->GetIndexInList() << " "
632 <<setw(4) << ts->GetEmcIndex()<< " "
633 <<setw(4) << ts->GetCpvIndex()<< " "
634 <<setw(4) << ts->GetPpsdIndex()<< endl ;
637 cout << "-------------------------------------------------------"<< endl ;