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 EMCAL track segments
18 // Track segment for EMCAL is list of
19 // ECAL RecPoint + (possibly) PRE RecPoint + (possibly) HCAL RecPoint
20 // To find TrackSegments we do the following:
21 // for each ECAL RecPoint we look for PRE and HC RecPoints with same direction within fSame.
22 // If there is such a PRE or ECAL RecPoint,
23 // we make a "Link": indexes of ECAL and PRE, HCAL RecPoints and their scalar product.
24 // Then we sort "Links", starting from the
25 // least "Link" pointing to the unassigned RecPoints assigning them to a new TrackSegment.
26 // If there is no PRE, HCAL RecPoint we make a TrackSegment
27 // consisting from ECAL alone. There is no TrackSegments without ECAL RecPoint.
28 //// In principle this class should be called from AliEMCALReconstructioner, but
29 // one can use it as well in standalone mode.
31 //*-- Author: Dmitri Peressounko (RRC Ki & SUBATECH) & Yves Schutz (SUBATECH)
34 // --- ROOT system ---
40 #include "TBenchmark.h"
42 // --- Standard library ---
44 // --- AliRoot header files ---
46 #include "AliEMCALTrackSegmentMakerv1.h"
47 #include "AliEMCALClusterizerv1.h"
48 #include "AliEMCALTrackSegment.h"
49 #include "AliEMCALLink.h"
50 #include "AliEMCALGetter.h"
53 ClassImp( AliEMCALTrackSegmentMakerv1)
56 //____________________________________________________________________________
57 AliEMCALTrackSegmentMakerv1::AliEMCALTrackSegmentMakerv1() : AliEMCALTrackSegmentMaker()
59 // default ctor (to be used mainly by Streamer)
62 fDefaultInit = kTRUE ;
65 //____________________________________________________________________________
66 AliEMCALTrackSegmentMakerv1::AliEMCALTrackSegmentMakerv1(const TString alirunFileName, const TString eventFolderName)
67 :AliEMCALTrackSegmentMaker(alirunFileName, eventFolderName)
73 fDefaultInit = kFALSE ;
77 //____________________________________________________________________________
78 AliEMCALTrackSegmentMakerv1::~AliEMCALTrackSegmentMakerv1()
81 // fDefaultInit = kTRUE if TrackSegmentMaker created by default ctor (to get just the parameters)
84 delete fPRELinkArray ;
85 delete fHCALinkArray ;
89 //____________________________________________________________________________
90 const TString AliEMCALTrackSegmentMakerv1::BranchName() const
96 //____________________________________________________________________________
97 Float_t AliEMCALTrackSegmentMakerv1::HowClose(AliEMCALTowerRecPoint * ec, AliEMCALTowerRecPoint * rp, Bool_t &toofar)const
99 // Calculates the distance between the EMC RecPoint and the PPSD RecPoint
100 // Clusters are sorted in "rows" and "columns" of width 1 cm
103 Float_t delta = 10. ; // large enough to be ineffective ??!
106 TVector3 vecEC = ec->XYZInAlice() ;
107 TVector3 vecRP = rp->XYZInAlice() ;
109 Float_t pro = TMath::Abs(1 - (vecEC * vecRP / ( vecEC.Mag() * vecRP.Mag() ))) ;
119 Info("HowClose", "ec = %d, rp = %d pro = %f, toofar=%d", ec->GetIndexInList(), rp->GetIndexInList(), pro, toofar ) ;
124 //____________________________________________________________________________
125 void AliEMCALTrackSegmentMakerv1::Init()
127 // Make all memory allocations that are not possible in default constructor
129 AliEMCALGetter* gime = AliEMCALGetter::Instance(GetTitle(), fEventFolderName.Data());
131 fPRELinkArray = new TClonesArray("AliEMCALLink", 1000);
132 fHCALinkArray = new TClonesArray("AliEMCALLink", 1000);
133 if ( !gime->TrackSegmentMaker() ) {
134 gime->PostTrackSegmentMaker(this);
138 //____________________________________________________________________________
139 void AliEMCALTrackSegmentMakerv1::InitParameters()
144 fTrackSegmentsInRun = 0 ;
148 //____________________________________________________________________________
149 void AliEMCALTrackSegmentMakerv1::MakeLinks()const
151 // Finds distances (links) between all PRE, EC and HC clusters,
152 // which are not further apart from each other than fDangle
153 // and sort them in accordance with this distance
155 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
156 TObjArray * aECARecPoints = gime->ECARecPoints() ;
157 TObjArray * aPRERecPoints = gime->PRERecPoints() ;
158 TObjArray * aHCARecPoints = gime->HCARecPoints() ;
160 fPRELinkArray->Clear() ;
161 fHCALinkArray->Clear() ;
163 AliEMCALTowerRecPoint * pre ;
164 AliEMCALTowerRecPoint * eca ;
165 AliEMCALTowerRecPoint * hca ;
171 for(iECARP = 0; iECARP < aECARecPoints->GetEntriesFast(); iECARP++ ) {
172 eca = dynamic_cast<AliEMCALTowerRecPoint *>(aECARecPoints->At(iECARP)) ;
173 Bool_t toofar = kTRUE ;
175 for(iPRERP = 0; iPRERP < aPRERecPoints->GetEntriesFast(); iPRERP++ ) {
176 pre = dynamic_cast<AliEMCALTowerRecPoint *>(aPRERecPoints->At(iPRERP)) ;
177 Float_t prod = HowClose(eca, pre, toofar) ;
181 new ((*fPRELinkArray)[iPRELink++]) AliEMCALLink(prod, iECARP, iPRERP, 0) ;
186 for(iHCARP = 0; iHCARP < aHCARecPoints->GetEntriesFast(); iHCARP++ ) {
187 hca = dynamic_cast<AliEMCALTowerRecPoint *>(aHCARecPoints->At(iHCARP)) ;
188 Float_t prod = HowClose(eca, hca, toofar) ;
192 new ((*fHCALinkArray)[iHCALink++]) AliEMCALLink(prod, iECARP, iHCARP, 1) ;
197 fPRELinkArray->Sort() ; //first links with largest scalar product
198 fHCALinkArray->Sort() ; //first links with largest scalar product
201 //____________________________________________________________________________
202 void AliEMCALTrackSegmentMakerv1::MakePairs()
204 // Using the previously made list of "links", we found the best link - i.e.
205 // link with the largest scalar product (closest to one) to still
206 // unassigned RecParticles. We assign these RecPoints to TrackSegment and
207 // remove them from the list of "unassigned".
209 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
210 TObjArray * aECARecPoints = gime->ECARecPoints() ;
211 TObjArray * aPRERecPoints = gime->PRERecPoints() ;
212 TObjArray * aHCARecPoints = gime->HCARecPoints() ;
213 TClonesArray * trackSegments = gime->TrackSegments() ;
215 //Make arrays to mark clusters already chosen
216 Int_t * ecaExist = 0;
217 Int_t nECA = aECARecPoints->GetEntriesFast() ;
219 ecaExist = new Int_t[nECA] ;
222 for(index = 0; index < nECA; index ++)
223 ecaExist[index] = 1 ;
225 Bool_t * preExist = 0;
226 Int_t nPRE = aPRERecPoints->GetEntriesFast() ;
228 preExist = new Bool_t[nPRE] ;
229 for(index = 0; index < nPRE; index ++)
230 preExist[index] = kTRUE ;
232 Bool_t * hcaExist = 0;
233 Int_t nHCA = aHCARecPoints->GetEntriesFast() ;
235 hcaExist = new Bool_t[nHCA] ;
236 for(index = 0; index < nHCA; index ++)
237 hcaExist[index] = kTRUE ;
239 AliEMCALTowerRecPoint * null = 0 ;
240 // Finds the smallest links and makes pairs of PRE and ECAL clusters with largest scalar product
242 TIter nextPRE(fPRELinkArray) ;
243 AliEMCALLink * linkPRE ;
245 while ( (linkPRE = static_cast<AliEMCALLink *>(nextPRE()) ) ){
247 if(ecaExist[linkPRE->GetECA()] != -1){ //without PRE yet
249 if(preExist[linkPRE->GetOther()]){ // PRE still exist
251 new ((* trackSegments)[fNTrackSegments])
252 AliEMCALTrackSegment(dynamic_cast<AliEMCALTowerRecPoint *>(aECARecPoints->At(linkPRE->GetECA())) ,
253 dynamic_cast<AliEMCALTowerRecPoint *>(aPRERecPoints->At(linkPRE->GetOther())), null) ;
254 (dynamic_cast<AliEMCALTrackSegment *>(trackSegments->At(fNTrackSegments)))->SetIndexInList(fNTrackSegments);
257 Info("MakePairs", "ECAL section with PRE section") ;
258 ecaExist[linkPRE->GetECA()] = -1 ; //Mark ecal that pre was found
259 //mark PRE recpoint as already used
260 preExist[linkPRE->GetOther()] = kFALSE ;
261 } //if PRE still exist
265 // Finds the smallest links and makes pairs of HCAL and ECAL clusters with largest scalar product
267 TIter nextHCA(fHCALinkArray) ;
268 AliEMCALLink * linkHCA ;
270 while ( (linkHCA = static_cast<AliEMCALLink *>(nextHCA()) ) ){
272 if(ecaExist[linkHCA->GetECA()] != -2){ //without HCAL yet
274 if(hcaExist[linkHCA->GetOther()]){ // HCAL still exist
275 // search among the already existing track segments
277 Bool_t found = kFALSE ;
278 AliEMCALTrackSegment * ts = 0 ;
279 for ( ii = 0 ; ii < fNTrackSegments ; ii++ ) {
280 ts = dynamic_cast<AliEMCALTrackSegment *>(trackSegments->At(ii)) ;
281 if ( ts->GetECAIndex() == linkHCA->GetECA() ) {
287 ts->SetHCARecPoint( dynamic_cast<AliEMCALTowerRecPoint *>(aHCARecPoints->At(linkHCA->GetOther())) ) ;
289 Info("MakePairs", "ECAL section with PRE and HCAL sections") ;
292 new ((* trackSegments)[fNTrackSegments])
293 AliEMCALTrackSegment(dynamic_cast<AliEMCALTowerRecPoint *>(aECARecPoints->At(linkHCA->GetECA())), null,
294 dynamic_cast<AliEMCALTowerRecPoint *>(aHCARecPoints->At(linkHCA->GetOther()))) ;
295 (dynamic_cast<AliEMCALTrackSegment *>(trackSegments->At(fNTrackSegments)))->SetIndexInList(fNTrackSegments);
298 Info("MakePairs", "ECAL section with HCAL section") ;
300 ecaExist[linkHCA->GetECA()] = -2 ; //Mark ecal that hcal was found
301 //mark HCAL recpoint as already used
302 hcaExist[linkHCA->GetOther()] = kFALSE ;
303 } //if HCAL still exist
308 //look through ECAL recPoints left without PRE/HCAL
309 if(ecaExist){ //if there is ecal rec point
311 for(iECARP = 0; iECARP < nECA ; iECARP++ ){
312 if(ecaExist[iECARP] > 0 ){
313 new ((*trackSegments)[fNTrackSegments])
314 AliEMCALTrackSegment(dynamic_cast<AliEMCALTowerRecPoint *>(aECARecPoints->At(iECARP)), null, null) ;
315 (dynamic_cast<AliEMCALTrackSegment *>(trackSegments->At(fNTrackSegments)))->SetIndexInList(fNTrackSegments);
318 Info("MakePairs", "ECAL section alone") ;
327 //____________________________________________________________________________
328 void AliEMCALTrackSegmentMakerv1::Exec(Option_t * option)
333 if(strstr(option,"tim"))
334 gBenchmark->Start("EMCALTSMaker");
336 if(strstr(option,"print")) {
341 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
343 Int_t nevents = gime->MaxEvent() ;
346 for(ievent = 0; ievent < nevents; ievent++){
347 gime->Event(ievent,"R") ;
348 //Make some initializations
349 fNTrackSegments = 0 ;
351 gime->TrackSegments()->Clear() ;
356 WriteTrackSegments() ;
358 if(strstr(option,"deb"))
359 PrintTrackSegments(option) ;
361 //increment the total number of track segments per run
362 fTrackSegmentsInRun += gime->TrackSegments()->GetEntriesFast() ;
366 if(strstr(option,"tim")){
367 gBenchmark->Stop("EMCALTSMaker");
368 Info("Exec", "took %f seconds for making TS %f seconds per event",
369 gBenchmark->GetCpuTime("EMCALTSMaker"), gBenchmark->GetCpuTime("EMCALTSMaker")/nevents) ;
374 //____________________________________________________________________________
375 void AliEMCALTrackSegmentMakerv1::Unload()
377 AliEMCALGetter * gime = AliEMCALGetter::Instance() ;
378 gime->EmcalLoader()->UnloadRecPoints() ;
379 gime->EmcalLoader()->UnloadTracks() ;
382 //____________________________________________________________________________
383 void AliEMCALTrackSegmentMakerv1::Print(Option_t * /*option*/)const
385 // Print TrackSegmentMaker parameters
387 Info("Print", "TrackSegmentMakerv1 parameters:") ;
388 if( strcmp(GetName(), "") != 0 ) {
389 printf("Making Track segments with parameters:\n") ;
390 printf(" Allowed spred on the scalar product of two recpoints with same direction: %f\n", fClose) ;
391 printf("============================================\n") ;
394 printf("AliEMCALTrackSegmentMakerv1 not initialized ") ;
397 //____________________________________________________________________________
398 void AliEMCALTrackSegmentMakerv1::WriteTrackSegments()
400 // Writes found TrackSegments to TreeR. Creates branches
401 // "EMCALTS" and "AliEMCALTrackSegmentMaker" with the same title.
402 // In the former branch found TrackSegments are stored, while
403 // in the latter all parameters, with which TS were made.
404 // ROOT does not allow overwriting existing branches, therefore
405 // first we check, if branches with the same title already exist.
406 // If yes - exits without writing.
408 AliEMCALGetter *gime = AliEMCALGetter::Instance() ;
410 TClonesArray * trackSegments = gime->TrackSegments() ;
411 trackSegments->Expand(trackSegments->GetEntriesFast()) ;
413 TTree * treeT = gime->TreeT();
416 Int_t bufferSize = 32000 ;
417 TBranch * tsBranch = treeT->Branch("EMCALTS",&trackSegments,bufferSize);
420 gime->WriteTracks("OVERWRITE");
421 gime->WriteTrackSegmentMaker("OVERWRITE");
425 //____________________________________________________________________________
426 void AliEMCALTrackSegmentMakerv1::PrintTrackSegments(Option_t * option)
428 // option deb - prints # of found TrackSegments
429 // option deb all - prints as well indexed of found RecParticles assigned to the TS
431 TClonesArray * trackSegments = AliEMCALGetter::Instance()->TrackSegments() ;
434 Info("PrintTrackSegments", "Results from TrackSegmentMaker:") ;
435 printf("nevent: %d\n", gAlice->GetEvNumber()) ;
436 printf(" Found %d TrackSegments\n", trackSegments->GetEntriesFast() );
438 if(strstr(option,"all")) { // printing found TS
439 printf("TrackSegment# ECAL RP# PRE RP# HCAL RP# \n") ;
441 for (index = 0 ; index < fNTrackSegments ; index++) {
442 AliEMCALTrackSegment * ts = (AliEMCALTrackSegment * )trackSegments->At(index) ;
443 printf(" %d %d %d %d \n",
444 ts->GetIndexInList(), ts->GetECAIndex(), ts->GetPREIndex(), ts->GetHCAIndex() );