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 **************************************************************************/
18 /* History of cvs commits:
21 * Revision 1.108 2007/06/18 07:00:51 kharlov
22 * Bug fix for attempt to use AliPHOSEmcRecPoint after its deletion
24 * Revision 1.107 2007/05/25 14:12:26 policheh
25 * Local to tracking CS transformation added for CPV rec. points
27 * Revision 1.106 2007/05/24 13:01:22 policheh
28 * Local to tracking CS transformation invoked for each EMC rec.point
30 * Revision 1.105 2007/05/02 13:41:22 kharlov
31 * Mode protection against absence of calib.data from AliPHOSCalibData to AliPHOSClusterizerv1::GetCalibrationParameters()
33 * Revision 1.104 2007/04/27 16:55:53 kharlov
34 * Calibration stops if PHOS CDB objects do not exist
36 * Revision 1.103 2007/04/11 11:55:45 policheh
37 * SetDistancesToBadChannels() added.
39 * Revision 1.102 2007/03/28 19:18:15 kharlov
40 * RecPoints recalculation in TSM removed
42 * Revision 1.101 2007/03/06 06:51:27 kharlov
43 * Calculation of cluster properties dep. on vertex posponed to TrackSegmentMaker
45 * Revision 1.100 2007/01/10 11:07:26 kharlov
46 * Raw digits writing to file (B.Polichtchouk)
48 * Revision 1.99 2006/11/07 16:49:51 kharlov
49 * Corrections for next event switch in case of raw data (B.Polichtchouk)
51 * Revision 1.98 2006/10/27 17:14:27 kharlov
52 * Introduce AliDebug and AliLog (B.Polichtchouk)
54 * Revision 1.97 2006/08/29 11:41:19 kharlov
55 * Missing implementation of ctors and = operator are added
57 * Revision 1.96 2006/08/25 16:56:30 kharlov
58 * Compliance with Effective C++
60 * Revision 1.95 2006/08/11 12:36:26 cvetan
61 * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root)
63 * Revision 1.94 2006/08/07 12:27:49 hristov
64 * Removing obsolete code which affected the event numbering scheme
66 * Revision 1.93 2006/08/01 12:20:17 cvetan
67 * 1. Adding a possibility to read and reconstruct an old rcu formatted raw data. This is controlled by an option of AliReconstruction and AliPHOSReconstructor. 2. In case of raw data processing (without galice.root) create the default AliPHOSGeometry object. Most likely this should be moved to the CDB
69 * Revision 1.92 2006/04/29 20:26:46 hristov
70 * Separate EMC and CPV calibration (Yu.Kharlov)
72 * Revision 1.91 2006/04/22 10:30:17 hristov
73 * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
75 * Revision 1.90 2006/04/11 15:22:59 hristov
76 * run number in query set to -1: forces AliCDBManager to use its run number (A.Colla)
78 * Revision 1.89 2006/03/13 14:05:42 kharlov
79 * Calibration objects for EMC and CPV
81 * Revision 1.88 2006/01/11 08:54:52 hristov
82 * Additional protection in case no calibration entry was found
84 * Revision 1.87 2005/11/22 08:46:43 kharlov
85 * Updated to new CDB (Boris Polichtchouk)
87 * Revision 1.86 2005/11/14 21:52:43 hristov
90 * Revision 1.85 2005/09/27 16:08:08 hristov
91 * New version of CDB storage framework (A.Colla)
93 * Revision 1.84 2005/09/21 10:02:47 kharlov
94 * Reading calibration from CDB (Boris Polichtchouk)
96 * Revision 1.82 2005/09/02 15:43:13 kharlov
97 * Add comments in GetCalibrationParameters and Calibrate
99 * Revision 1.81 2005/09/02 14:32:07 kharlov
100 * Calibration of raw data
102 * Revision 1.80 2005/08/24 15:31:36 kharlov
103 * Setting raw digits flag
105 * Revision 1.79 2005/07/25 15:53:53 kharlov
108 * Revision 1.78 2005/05/28 14:19:04 schutz
109 * Compilation warnings fixed by T.P.
113 //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (SUBATECH & Kurchatov Institute)
114 //////////////////////////////////////////////////////////////////////////////
115 // Clusterization class. Performs clusterization (collects neighbouring active cells) and
116 // unfolds the clusters having several local maxima.
117 // Results are stored in TreeR#, branches PHOSEmcRP (EMC recPoints),
118 // PHOSCpvRP (CPV RecPoints) and AliPHOSClusterizer (Clusterizer with all
119 // parameters including input digits branch title, thresholds etc.)
120 // This TTask is normally called from Reconstructioner, but can as well be used in
123 // root [0] AliPHOSClusterizerv1 * cl = new AliPHOSClusterizerv1("galice.root", "recpointsname", "digitsname")
124 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
125 // // reads gAlice from header file "galice.root", uses digits stored in the branch names "digitsname" (default = "Default")
126 // // and saves recpoints in branch named "recpointsname" (default = "digitsname")
127 // root [1] cl->ExecuteTask()
128 // //finds RecPoints in all events stored in galice.root
129 // root [2] cl->SetDigitsBranch("digits2")
130 // //sets another title for Digitis (input) branch
131 // root [3] cl->SetRecPointsBranch("recp2")
132 // //sets another title four output branches
133 // root [4] cl->SetEmcLocalMaxCut(0.03)
134 // //set clusterization parameters
135 // root [5] cl->ExecuteTask("deb all time")
136 // //once more finds RecPoints options are
137 // // deb - print number of found rec points
138 // // deb all - print number of found RecPoints and some their characteristics
139 // // time - print benchmarking results
141 // --- ROOT system ---
146 #include "TBenchmark.h"
148 // --- Standard library ---
150 // --- AliRoot header files ---
152 #include "AliRunLoader.h"
153 #include "AliGenerator.h"
154 #include "AliPHOSGetter.h"
155 #include "AliPHOSGeometry.h"
156 #include "AliPHOSClusterizerv1.h"
157 #include "AliPHOSEmcRecPoint.h"
158 #include "AliPHOSCpvRecPoint.h"
159 #include "AliPHOSDigit.h"
160 #include "AliPHOSDigitizer.h"
161 #include "AliPHOSCalibrationDB.h"
162 #include "AliCDBManager.h"
163 #include "AliCDBStorage.h"
164 #include "AliCDBEntry.h"
165 #include "AliPHOSReconstructor.h"
166 #include "AliPHOSRecoParam.h"
168 ClassImp(AliPHOSClusterizerv1)
170 //____________________________________________________________________________
171 AliPHOSClusterizerv1::AliPHOSClusterizerv1() :
172 AliPHOSClusterizer(),
173 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
174 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
175 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
176 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
177 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
178 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
179 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
182 // default ctor (to be used mainly by Streamer)
185 fDefaultInit = kTRUE ;
188 //____________________________________________________________________________
189 AliPHOSClusterizerv1::AliPHOSClusterizerv1(const TString alirunFileName, const TString eventFolderName) :
190 AliPHOSClusterizer(alirunFileName, eventFolderName),
191 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
192 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
193 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
194 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
195 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
196 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
197 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
200 // ctor with the indication of the file where header Tree and digits Tree are stored
204 fDefaultInit = kFALSE ;
207 //____________________________________________________________________________
208 AliPHOSClusterizerv1::AliPHOSClusterizerv1(const AliPHOSClusterizerv1 & obj) :
209 AliPHOSClusterizer(obj),
210 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
211 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
212 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
213 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
214 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
215 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
216 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
221 //____________________________________________________________________________
222 AliPHOSClusterizerv1::~AliPHOSClusterizerv1()
227 //____________________________________________________________________________
228 const TString AliPHOSClusterizerv1::BranchName() const
233 //____________________________________________________________________________
234 Float_t AliPHOSClusterizerv1::CalibrateEMC(Float_t amp, Int_t absId)
236 // Convert EMC measured amplitude into real energy.
237 // Calibration parameters are taken from calibration data base for raw data,
238 // or from digitizer parameters for simulated data.
242 AliPHOSGetter *gime = AliPHOSGetter::Instance();
243 gime->PHOSGeometry()->AbsToRelNumbering(absId,relId) ;
244 Int_t module = relId[0];
245 Int_t column = relId[3];
246 Int_t row = relId[2];
247 if(absId <= fEmcCrystals) { // this is EMC
248 fADCchanelEmc = fCalibData->GetADCchannelEmc (module,column,row);
249 return amp*fADCchanelEmc ;
253 if(absId <= fEmcCrystals) // this is EMC
254 return fADCpedestalEmc + amp*fADCchanelEmc ;
259 //____________________________________________________________________________
260 Float_t AliPHOSClusterizerv1::CalibrateCPV(Int_t amp, Int_t absId)
262 // Convert digitized CPV amplitude into charge.
263 // Calibration parameters are taken from calibration data base for raw data,
264 // or from digitizer parameters for simulated data.
268 AliPHOSGetter *gime = AliPHOSGetter::Instance();
269 gime->PHOSGeometry()->AbsToRelNumbering(absId,relId) ;
270 Int_t module = relId[0];
271 Int_t column = relId[3];
272 Int_t row = relId[2];
273 if(absId > fEmcCrystals) { // this is CPV
274 fADCchanelCpv = fCalibData->GetADCchannelCpv (module,column,row);
275 fADCpedestalCpv = fCalibData->GetADCpedestalCpv(module,column,row);
276 return fADCpedestalCpv + amp*fADCchanelCpv ;
280 if(absId > fEmcCrystals) // this is CPV
281 return fADCpedestalCpv+ amp*fADCchanelCpv ;
286 //____________________________________________________________________________
287 void AliPHOSClusterizerv1::Exec(Option_t *option)
289 // Steering method to perform clusterization for events
290 // in the range from fFirstEvent to fLastEvent.
291 // This range is optionally set by SetEventRange().
292 // if fLastEvent=-1 (by default), then process events until the end.
294 if(strstr(option,"tim"))
295 gBenchmark->Start("PHOSClusterizer");
297 if(strstr(option,"print")) {
302 GetCalibrationParameters() ;
304 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
306 gime->SetRawDigits(kFALSE);
308 gime->SetRawDigits(kTRUE);
310 if (fLastEvent == -1)
311 fLastEvent = gime->MaxEvent() - 1 ;
313 fLastEvent = TMath::Min(fFirstEvent, gime->MaxEvent()); // one event at the time
314 Int_t nEvents = fLastEvent - fFirstEvent + 1;
317 for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
319 gime->Event(ievent ,"D"); // Read digits from simulated data
321 AliRunLoader * rl = AliRunLoader::GetRunLoader(gime->PhosLoader()->GetTitle());
322 rl->GetEvent(ievent);
323 gime->Event(fRawReader,"W",fIsOldRCUFormat); // Read digits from raw data
325 fNumberOfEmcClusters = fNumberOfCpvClusters = 0 ;
329 AliDebug(2,Form(" ---- Printing clusters (%d) of event %d.\n",
330 gime->EmcRecPoints()->GetEntries(),ievent));
331 if(AliLog::GetGlobalDebugLevel()>1)
332 gime->EmcRecPoints()->Print();
339 if(strstr(option,"deb"))
340 PrintRecPoints(option) ;
342 //increment the total number of recpoints per run
343 fRecPointsInRun += gime->EmcRecPoints()->GetEntriesFast() ;
344 fRecPointsInRun += gime->CpvRecPoints()->GetEntriesFast() ;
347 if(fWrite) //do not unload in "on flight" mode
350 if(strstr(option,"tim")){
351 gBenchmark->Stop("PHOSClusterizer");
352 AliInfo(Form("took %f seconds for Clusterizing %f seconds per event \n",
353 gBenchmark->GetCpuTime("PHOSClusterizer"),
354 gBenchmark->GetCpuTime("PHOSClusterizer")/nEvents )) ;
358 //____________________________________________________________________________
359 Bool_t AliPHOSClusterizerv1::FindFit(AliPHOSEmcRecPoint * emcRP, AliPHOSDigit ** maxAt, Float_t * maxAtEnergy,
360 Int_t nPar, Float_t * fitparameters) const
362 // Calls TMinuit to fit the energy distribution of a cluster with several maxima
363 // The initial values for fitting procedure are set equal to the positions of local maxima.
364 // Cluster will be fitted as a superposition of nPar/3 electromagnetic showers
367 AliPHOSGetter * gime = AliPHOSGetter::Instance();
368 TClonesArray * digits = gime->Digits();
370 gMinuit->mncler(); // Reset Minuit's list of paramters
371 gMinuit->SetPrintLevel(-1) ; // No Printout
372 gMinuit->SetFCN(AliPHOSClusterizerv1::UnfoldingChiSquare) ;
373 // To set the address of the minimization function
375 TList * toMinuit = new TList();
376 toMinuit->AddAt(emcRP,0) ;
377 toMinuit->AddAt(digits,1) ;
379 gMinuit->SetObjectFit(toMinuit) ; // To tranfer pointer to UnfoldingChiSquare
381 // filling initial values for fit parameters
382 AliPHOSDigit * digit ;
386 Int_t nDigits = (Int_t) nPar / 3 ;
390 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
392 for(iDigit = 0; iDigit < nDigits; iDigit++){
393 digit = maxAt[iDigit];
398 geom->AbsToRelNumbering(digit->GetId(), relid) ;
399 geom->RelPosInModule(relid, x, z) ;
401 Float_t energy = maxAtEnergy[iDigit] ;
403 gMinuit->mnparm(index, "x", x, 0.1, 0, 0, ierflg) ;
406 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : x = %f\n", x ) ;
409 gMinuit->mnparm(index, "z", z, 0.1, 0, 0, ierflg) ;
412 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : z =%f\n", z ) ;
415 gMinuit->mnparm(index, "Energy", energy , 0.05*energy, 0., 4.*energy, ierflg) ;
418 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : energy = %f\n", energy ) ;
423 Double_t p0 = 0.1 ; // "Tolerance" Evaluation stops when EDM = 0.0001*p0 ; The number of function call slightly
428 gMinuit->mnexcm("SET STR", &p2, 0, ierflg) ; // force TMinuit to reduce function calls
429 gMinuit->mnexcm("SET GRA", &p1, 1, ierflg) ; // force TMinuit to use my gradient
430 gMinuit->SetMaxIterations(5);
431 gMinuit->mnexcm("SET NOW", &p2 , 0, ierflg) ; // No Warnings
433 gMinuit->mnexcm("MIGRAD", &p0, 0, ierflg) ; // minimize
435 if(ierflg == 4){ // Minimum not found
436 Warning("FindFit", "PHOS Unfolding fit not converged, cluster abandoned\n" );
439 for(index = 0; index < nPar; index++){
442 gMinuit->GetParameter(index, val, err) ; // Returns value and error of parameter index
443 fitparameters[index] = val ;
451 //____________________________________________________________________________
452 void AliPHOSClusterizerv1::GetCalibrationParameters()
454 // Set calibration parameters:
455 // if calibration database exists, they are read from database,
456 // otherwise, reconstruction stops in the constructor of AliPHOSCalibData
458 // It is a user responsilibity to open CDB before reconstruction, for example:
459 // AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage("local://CalibDB");
461 fCalibData = new AliPHOSCalibData(-1); //use AliCDBManager's run number
462 if (fCalibData->GetCalibDataEmc() == 0)
463 AliFatal("Calibration parameters for PHOS EMC not found. Stop reconstruction.\n");
464 if (fCalibData->GetCalibDataCpv() == 0)
465 AliFatal("Calibration parameters for PHOS CPV not found. Stop reconstruction.\n");
469 //____________________________________________________________________________
470 void AliPHOSClusterizerv1::Init()
472 // Make all memory allocations which can not be done in default constructor.
473 // Attach the Clusterizer task to the list of PHOS tasks
475 AliPHOSGetter* gime = AliPHOSGetter::Instance() ;
477 gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName.Data());
479 AliPHOSGeometry * geom = gime->PHOSGeometry();
481 fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ;
484 gMinuit = new TMinuit(100);
486 if ( !gime->Clusterizer() ) {
487 gime->PostClusterizer(this);
491 //____________________________________________________________________________
492 void AliPHOSClusterizerv1::InitParameters()
495 fNumberOfCpvClusters = 0 ;
496 fNumberOfEmcClusters = 0 ;
498 const AliPHOSRecoParam* parEmc = AliPHOSReconstructor::GetRecoParamEmc();
499 if(!parEmc) AliFatal("Reconstruction parameters for EMC not set!");
501 const AliPHOSRecoParam* parCpv = AliPHOSReconstructor::GetRecoParamCpv();
502 if(!parCpv) AliFatal("Reconstruction parameters for CPV not set!");
504 fCpvClusteringThreshold = parCpv->GetClusteringThreshold();
505 fEmcClusteringThreshold = parEmc->GetClusteringThreshold();
507 fEmcLocMaxCut = parEmc->GetLocalMaxCut();
508 fCpvLocMaxCut = parCpv->GetLocalMaxCut();
510 fEmcMinE = parEmc->GetMinE();
511 fCpvMinE = parCpv->GetMinE();
513 fW0 = parEmc->GetLogWeight();
514 fW0CPV = parCpv->GetLogWeight();
516 fEmcTimeGate = 1.e-8 ;
520 fRecPointsInRun = 0 ;
526 SetEventRange(0,-1) ;
528 fIsOldRCUFormat = kFALSE;
531 //____________________________________________________________________________
532 Int_t AliPHOSClusterizerv1::AreNeighbours(AliPHOSDigit * d1, AliPHOSDigit * d2)const
534 // Gives the neighbourness of two digits = 0 are not neighbour but continue searching
536 // = 2 are not neighbour but do not continue searching
537 // neighbours are defined as digits having at least a common vertex
538 // The order of d1 and d2 is important: first (d1) should be a digit already in a cluster
539 // which is compared to a digit (d2) not yet in a cluster
541 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
546 geom->AbsToRelNumbering(d1->GetId(), relid1) ;
549 geom->AbsToRelNumbering(d2->GetId(), relid2) ;
551 if ( (relid1[0] == relid2[0]) && (relid1[1]==relid2[1]) ) { // inside the same PHOS module
552 Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;
553 Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;
555 if (( coldiff <= 1 ) && ( rowdiff <= 1 )){
556 if((relid1[1] != 0) || (TMath::Abs(d1->GetTime() - d2->GetTime() ) < fEmcTimeGate))
560 if((relid2[2] > relid1[2]) && (relid2[3] > relid1[3]+1))
561 rv = 2; // Difference in row numbers is too large to look further
567 if( (relid1[0] < relid2[0]) || (relid1[1] != relid2[1]) )
574 //____________________________________________________________________________
575 void AliPHOSClusterizerv1::CleanDigits(TClonesArray * digits)
577 // Remove digits with amplitudes below threshold
579 for(Int_t i=0; i<digits->GetEntriesFast(); i++){
580 AliPHOSDigit * digit = static_cast<AliPHOSDigit*>(digits->At(i)) ;
581 if ( (IsInEmc(digit) && CalibrateEMC(digit->GetEnergy(),digit->GetId()) < fEmcMinE) ||
582 (IsInCpv(digit) && CalibrateCPV(digit->GetAmp() ,digit->GetId()) < fCpvMinE) )
583 digits->RemoveAt(i) ;
586 for (Int_t i = 0 ; i < digits->GetEntriesFast() ; i++) {
587 AliPHOSDigit *digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
588 digit->SetIndexInList(i) ;
591 //Overwrite digits tree
592 AliPHOSGetter* gime = AliPHOSGetter::Instance();
593 TTree * treeD = gime->TreeD();
594 treeD->Branch("PHOS", &digits);
596 gime->WriteDigits("OVERWRITE");
597 gime->PhosLoader()->UnloadDigits() ;
599 //____________________________________________________________________________
600 Bool_t AliPHOSClusterizerv1::IsInEmc(AliPHOSDigit * digit) const
602 // Tells if (true) or not (false) the digit is in a PHOS-EMC module
605 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
607 Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
609 if(digit->GetId() <= nEMC ) rv = kTRUE;
614 //____________________________________________________________________________
615 Bool_t AliPHOSClusterizerv1::IsInCpv(AliPHOSDigit * digit) const
617 // Tells if (true) or not (false) the digit is in a PHOS-CPV module
621 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
623 Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
625 if(digit->GetId() > nEMC ) rv = kTRUE;
630 //____________________________________________________________________________
631 void AliPHOSClusterizerv1::Unload()
633 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
634 gime->PhosLoader()->UnloadDigits() ;
635 gime->PhosLoader()->UnloadRecPoints() ;
638 //____________________________________________________________________________
639 void AliPHOSClusterizerv1::WriteRecPoints()
642 // Creates new branches with given title
643 // fills and writes into TreeR.
645 AliPHOSGetter * gime = AliPHOSGetter::Instance();
647 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
648 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
649 TClonesArray * digits = gime->Digits() ;
652 //Evaluate position, dispersion and other RecPoint properties..
653 Int_t nEmc = emcRecPoints->GetEntriesFast();
654 for(index = 0; index < nEmc; index++){
655 AliPHOSEmcRecPoint * rp =
656 dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) );
657 rp->Purify(fEmcMinE) ;
658 if(rp->GetMultiplicity()==0){
659 emcRecPoints->RemoveAt(index) ;
664 // No vertex is available now, calculate corrections in PID
665 rp->EvalAll(fW0,digits) ;
666 TVector3 fakeVtx(0.,0.,0.) ;
667 rp->EvalAll(fW0,fakeVtx,digits) ;
668 rp->EvalLocal2TrackingCSTransform();
670 emcRecPoints->Compress() ;
671 // emcRecPoints->Sort() ; //Can not sort until position is calculated!
672 // emcRecPoints->Expand(emcRecPoints->GetEntriesFast()) ;
673 for(index = 0; index < emcRecPoints->GetEntries(); index++){
674 dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) )->SetIndexInList(index) ;
677 //For each rec.point set the distance to the nearest bad crystal (BVP)
678 SetDistancesToBadChannels();
680 //Now the same for CPV
681 for(index = 0; index < cpvRecPoints->GetEntries(); index++){
682 AliPHOSCpvRecPoint * rp = dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(index) );
683 rp->EvalAll(fW0CPV,digits) ;
684 rp->EvalLocal2TrackingCSTransform();
686 // cpvRecPoints->Sort() ;
688 for(index = 0; index < cpvRecPoints->GetEntries(); index++)
689 dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(index) )->SetIndexInList(index) ;
691 cpvRecPoints->Expand(cpvRecPoints->GetEntriesFast()) ;
693 if(fWrite){ //We write TreeR
694 TTree * treeR = gime->TreeR();
696 Int_t bufferSize = 32000 ;
697 Int_t splitlevel = 0 ;
700 TBranch * emcBranch = treeR->Branch("PHOSEmcRP","TObjArray",&emcRecPoints,bufferSize,splitlevel);
701 emcBranch->SetTitle(BranchName());
704 TBranch * cpvBranch = treeR->Branch("PHOSCpvRP","TObjArray",&cpvRecPoints,bufferSize,splitlevel);
705 cpvBranch->SetTitle(BranchName());
710 gime->WriteRecPoints("OVERWRITE");
711 gime->WriteClusterizer("OVERWRITE");
715 //____________________________________________________________________________
716 void AliPHOSClusterizerv1::MakeClusters()
718 // Steering method to construct the clusters stored in a list of Reconstructed Points
719 // A cluster is defined as a list of neighbour digits
722 AliPHOSGetter * gime = AliPHOSGetter::Instance();
724 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
725 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
727 emcRecPoints->Delete() ;
728 cpvRecPoints->Delete() ;
730 TClonesArray * digits = gime->Digits() ;
732 //Remove digits below threshold
733 CleanDigits(digits) ;
735 TClonesArray * digitsC = static_cast<TClonesArray*>( digits->Clone() ) ;
737 // Clusterization starts
739 TIter nextdigit(digitsC) ;
740 AliPHOSDigit * digit ;
741 Bool_t notremoved = kTRUE ;
743 while ( (digit = dynamic_cast<AliPHOSDigit *>( nextdigit()) ) ) { // scan over the list of digitsC
746 AliPHOSRecPoint * clu = 0 ;
748 TArrayI clusterdigitslist(1500) ;
751 if (( IsInEmc (digit) &&
752 CalibrateEMC(digit->GetEnergy(),digit->GetId()) > fEmcClusteringThreshold ) ||
754 CalibrateCPV(digit->GetAmp() ,digit->GetId()) > fCpvClusteringThreshold ) ) {
755 Int_t iDigitInCluster = 0 ;
757 if ( IsInEmc(digit) ) {
758 // start a new EMC RecPoint
759 if(fNumberOfEmcClusters >= emcRecPoints->GetSize())
760 emcRecPoints->Expand(2*fNumberOfEmcClusters+1) ;
762 emcRecPoints->AddAt(new AliPHOSEmcRecPoint(""), fNumberOfEmcClusters) ;
763 clu = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(fNumberOfEmcClusters) ) ;
764 fNumberOfEmcClusters++ ;
765 clu->AddDigit(*digit, CalibrateEMC(digit->GetEnergy(),digit->GetId())) ;
766 clusterdigitslist[iDigitInCluster] = digit->GetIndexInList() ;
768 digitsC->Remove(digit) ;
772 // start a new CPV cluster
773 if(fNumberOfCpvClusters >= cpvRecPoints->GetSize())
774 cpvRecPoints->Expand(2*fNumberOfCpvClusters+1);
776 cpvRecPoints->AddAt(new AliPHOSCpvRecPoint(""), fNumberOfCpvClusters) ;
778 clu = dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(fNumberOfCpvClusters) ) ;
779 fNumberOfCpvClusters++ ;
780 clu->AddDigit(*digit, CalibrateCPV(digit->GetAmp(),digit->GetId()) ) ;
781 clusterdigitslist[iDigitInCluster] = digit->GetIndexInList() ;
783 digitsC->Remove(digit) ;
786 // Here we remove remaining EMC digits, which cannot make a cluster
789 while( ( digit = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) {
791 digitsC->Remove(digit) ;
795 notremoved = kFALSE ;
802 AliPHOSDigit * digitN ;
804 while (index < iDigitInCluster){ // scan over digits already in cluster
805 digit = dynamic_cast<AliPHOSDigit*>( digits->At(clusterdigitslist[index]) ) ;
807 while ( (digitN = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) { // scan over the reduced list of digits
808 Int_t ineb = AreNeighbours(digit, digitN); // call (digit,digitN) in THAT oder !!!!!
810 case 0 : // not a neighbour
812 case 1 : // are neighbours
813 if (IsInEmc (digitN))
814 clu->AddDigit(*digitN, CalibrateEMC( digitN->GetEnergy(), digitN->GetId() ) );
816 clu->AddDigit(*digitN, CalibrateCPV( digitN->GetAmp() , digitN->GetId() ) );
818 clusterdigitslist[iDigitInCluster] = digitN->GetIndexInList() ;
820 digitsC->Remove(digitN) ;
822 case 2 : // too far from each other
831 } // loop over cluster
842 //____________________________________________________________________________
843 void AliPHOSClusterizerv1::MakeUnfolding()
845 // Unfolds clusters using the shape of an ElectroMagnetic shower
846 // Performs unfolding of all EMC/CPV clusters
848 AliPHOSGetter * gime = AliPHOSGetter::Instance();
850 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
852 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
853 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
854 TClonesArray * digits = gime->Digits() ;
856 // Unfold first EMC clusters
857 if(fNumberOfEmcClusters > 0){
859 Int_t nModulesToUnfold = geom->GetNModules() ;
861 Int_t numberofNotUnfolded = fNumberOfEmcClusters ;
863 for(index = 0 ; index < numberofNotUnfolded ; index++){
865 AliPHOSEmcRecPoint * emcRecPoint = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) ) ;
866 if(emcRecPoint->GetPHOSMod()> nModulesToUnfold)
869 Int_t nMultipl = emcRecPoint->GetMultiplicity() ;
870 AliPHOSDigit ** maxAt = new AliPHOSDigit*[nMultipl] ;
871 Float_t * maxAtEnergy = new Float_t[nMultipl] ;
872 Int_t nMax = emcRecPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy,fEmcLocMaxCut,digits) ;
874 if( nMax > 1 ) { // if cluster is very flat (no pronounced maximum) then nMax = 0
875 UnfoldCluster(emcRecPoint, nMax, maxAt, maxAtEnergy) ;
876 emcRecPoints->Remove(emcRecPoint);
877 emcRecPoints->Compress() ;
879 fNumberOfEmcClusters -- ;
880 numberofNotUnfolded-- ;
883 emcRecPoint->SetNExMax(1) ; //Only one local maximum
887 delete[] maxAtEnergy ;
890 // Unfolding of EMC clusters finished
893 // Unfold now CPV clusters
894 if(fNumberOfCpvClusters > 0){
896 Int_t nModulesToUnfold = geom->GetNModules() ;
898 Int_t numberofCpvNotUnfolded = fNumberOfCpvClusters ;
900 for(index = 0 ; index < numberofCpvNotUnfolded ; index++){
902 AliPHOSRecPoint * recPoint = dynamic_cast<AliPHOSRecPoint *>( cpvRecPoints->At(index) ) ;
904 if(recPoint->GetPHOSMod()> nModulesToUnfold)
907 AliPHOSEmcRecPoint * emcRecPoint = dynamic_cast<AliPHOSEmcRecPoint*>(recPoint) ;
909 Int_t nMultipl = emcRecPoint->GetMultiplicity() ;
910 AliPHOSDigit ** maxAt = new AliPHOSDigit*[nMultipl] ;
911 Float_t * maxAtEnergy = new Float_t[nMultipl] ;
912 Int_t nMax = emcRecPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy,fCpvLocMaxCut,digits) ;
914 if( nMax > 1 ) { // if cluster is very flat (no pronounced maximum) then nMax = 0
915 UnfoldCluster(emcRecPoint, nMax, maxAt, maxAtEnergy) ;
916 cpvRecPoints->Remove(emcRecPoint);
917 cpvRecPoints->Compress() ;
919 numberofCpvNotUnfolded-- ;
920 fNumberOfCpvClusters-- ;
924 delete[] maxAtEnergy ;
927 //Unfolding of Cpv clusters finished
931 //____________________________________________________________________________
932 Double_t AliPHOSClusterizerv1::ShowerShape(Double_t x, Double_t z)
934 // Shape of the shower (see PHOS TDR)
935 // If you change this function, change also the gradient evaluation in ChiSquare()
937 //for the moment we neglect dependence on the incident angle.
939 Double_t r2 = x*x + z*z ;
940 Double_t r4 = r2*r2 ;
941 Double_t r295 = TMath::Power(r2, 2.95/2.) ;
942 Double_t shape = TMath::Exp( -r4 * (1. / (2.32 + 0.26 * r4) + 0.0316 / (1 + 0.0652 * r295) ) ) ;
946 //____________________________________________________________________________
947 void AliPHOSClusterizerv1::UnfoldCluster(AliPHOSEmcRecPoint * iniEmc,
949 AliPHOSDigit ** maxAt,
950 Float_t * maxAtEnergy)
952 // Performs the unfolding of a cluster with nMax overlapping showers
954 AliPHOSGetter * gime = AliPHOSGetter::Instance();
956 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
958 const TClonesArray * digits = gime->Digits() ;
959 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
960 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
962 Int_t nPar = 3 * nMax ;
963 Float_t * fitparameters = new Float_t[nPar] ;
965 Bool_t rv = FindFit(iniEmc, maxAt, maxAtEnergy, nPar, fitparameters) ;
967 // Fit failed, return and remove cluster
968 iniEmc->SetNExMax(-1) ;
969 delete[] fitparameters ;
973 // create ufolded rec points and fill them with new energy lists
974 // First calculate energy deposited in each sell in accordance with fit (without fluctuations): efit[]
975 // and later correct this number in acordance with actual energy deposition
977 Int_t nDigits = iniEmc->GetMultiplicity() ;
978 Float_t * efit = new Float_t[nDigits] ;
979 Float_t xDigit=0.,zDigit=0. ;
980 Float_t xpar=0.,zpar=0.,epar=0. ;
982 AliPHOSDigit * digit = 0 ;
983 Int_t * emcDigits = iniEmc->GetDigitsList() ;
989 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
990 digit = dynamic_cast<AliPHOSDigit*>( digits->At(emcDigits[iDigit] ) ) ;
991 geom->AbsToRelNumbering(digit->GetId(), relid) ;
992 geom->RelPosInModule(relid, xDigit, zDigit) ;
996 while(iparam < nPar ){
997 xpar = fitparameters[iparam] ;
998 zpar = fitparameters[iparam+1] ;
999 epar = fitparameters[iparam+2] ;
1001 // geom->GetIncidentVector(fVtx,relid[0],xpar,zpar,vIncid) ;
1002 // efit[iDigit] += epar * ShowerShape(xDigit - xpar,zDigit - zpar,vIncid) ;
1003 efit[iDigit] += epar * ShowerShape(xDigit - xpar,zDigit - zpar) ;
1008 // Now create new RecPoints and fill energy lists with efit corrected to fluctuations
1009 // so that energy deposited in each cell is distributed betwin new clusters proportionally
1010 // to its contribution to efit
1012 Float_t * emcEnergies = iniEmc->GetEnergiesList() ;
1016 while(iparam < nPar ){
1017 xpar = fitparameters[iparam] ;
1018 zpar = fitparameters[iparam+1] ;
1019 epar = fitparameters[iparam+2] ;
1021 // geom->GetIncidentVector(fVtx,iniEmc->GetPHOSMod(),xpar,zpar,vIncid) ;
1023 AliPHOSEmcRecPoint * emcRP = 0 ;
1025 if(iniEmc->IsEmc()){ //create new entries in fEmcRecPoints...
1027 if(fNumberOfEmcClusters >= emcRecPoints->GetSize())
1028 emcRecPoints->Expand(2*fNumberOfEmcClusters) ;
1030 (*emcRecPoints)[fNumberOfEmcClusters] = new AliPHOSEmcRecPoint("") ;
1031 emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(fNumberOfEmcClusters) ) ;
1032 fNumberOfEmcClusters++ ;
1033 emcRP->SetNExMax((Int_t)nPar/3) ;
1035 else{//create new entries in fCpvRecPoints
1036 if(fNumberOfCpvClusters >= cpvRecPoints->GetSize())
1037 cpvRecPoints->Expand(2*fNumberOfCpvClusters) ;
1039 (*cpvRecPoints)[fNumberOfCpvClusters] = new AliPHOSCpvRecPoint("") ;
1040 emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( cpvRecPoints->At(fNumberOfCpvClusters) ) ;
1041 fNumberOfCpvClusters++ ;
1045 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
1046 digit = dynamic_cast<AliPHOSDigit*>( digits->At( emcDigits[iDigit] ) ) ;
1047 geom->AbsToRelNumbering(digit->GetId(), relid) ;
1048 geom->RelPosInModule(relid, xDigit, zDigit) ;
1049 // ratio = epar * ShowerShape(xDigit - xpar,zDigit - zpar,vIncid) / efit[iDigit] ;
1050 ratio = epar * ShowerShape(xDigit - xpar,zDigit - zpar) / efit[iDigit] ;
1051 eDigit = emcEnergies[iDigit] * ratio ;
1052 emcRP->AddDigit( *digit, eDigit ) ;
1056 delete[] fitparameters ;
1061 //_____________________________________________________________________________
1062 void AliPHOSClusterizerv1::UnfoldingChiSquare(Int_t & nPar, Double_t * Grad, Double_t & fret, Double_t * x, Int_t iflag)
1064 // Calculates the Chi square for the cluster unfolding minimization
1065 // Number of parameters, Gradient, Chi squared, parameters, what to do
1067 TList * toMinuit = dynamic_cast<TList*>( gMinuit->GetObjectFit() ) ;
1069 AliPHOSEmcRecPoint * emcRP = dynamic_cast<AliPHOSEmcRecPoint*>( toMinuit->At(0) ) ;
1070 TClonesArray * digits = dynamic_cast<TClonesArray*>( toMinuit->At(1) ) ;
1071 // TVector3 * vtx = dynamic_cast<TVector3*>(toMinuit->At(2)) ; //Vertex position
1073 // AliPHOSEmcRecPoint * emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( gMinuit->GetObjectFit() ) ; // EmcRecPoint to fit
1075 Int_t * emcDigits = emcRP->GetDigitsList() ;
1077 Int_t nOdigits = emcRP->GetDigitsMultiplicity() ;
1079 Float_t * emcEnergies = emcRP->GetEnergiesList() ;
1081 const AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
1087 for(iparam = 0 ; iparam < nPar ; iparam++)
1088 Grad[iparam] = 0 ; // Will evaluate gradient
1092 AliPHOSDigit * digit ;
1095 for( iDigit = 0 ; iDigit < nOdigits ; iDigit++) {
1097 digit = dynamic_cast<AliPHOSDigit*>( digits->At( emcDigits[iDigit] ) );
1103 geom->AbsToRelNumbering(digit->GetId(), relid) ;
1105 geom->RelPosInModule(relid, xDigit, zDigit) ;
1107 if(iflag == 2){ // calculate gradient
1110 while(iParam < nPar ){
1111 Double_t dx = (xDigit - x[iParam]) ;
1113 Double_t dz = (zDigit - x[iParam]) ;
1115 // geom->GetIncidentVector(*vtx,emcRP->GetPHOSMod(),x[iParam-2],x[iParam-1],vInc) ;
1116 // efit += x[iParam] * ShowerShape(dx,dz,vInc) ;
1117 efit += x[iParam] * ShowerShape(dx,dz) ;
1120 Double_t sum = 2. * (efit - emcEnergies[iDigit]) / emcEnergies[iDigit] ; // Here we assume, that sigma = sqrt(E)
1122 while(iParam < nPar ){
1123 Double_t xpar = x[iParam] ;
1124 Double_t zpar = x[iParam+1] ;
1125 Double_t epar = x[iParam+2] ;
1126 // geom->GetIncidentVector(*vtx,emcRP->GetPHOSMod(),xpar,zpar,vInc) ;
1127 Double_t dr = TMath::Sqrt( (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) );
1128 // Double_t shape = sum * ShowerShape(xDigit - xpar,zDigit - zpar,vInc) ;
1129 Double_t shape = sum * ShowerShape(xDigit - xpar,zDigit - zpar) ;
1130 //DP: No incident angle dependence in gradient yet!!!!!!
1131 Double_t r4 = dr*dr*dr*dr ;
1132 Double_t r295 = TMath::Power(dr,2.95) ;
1133 Double_t deriv =-4. * dr*dr * ( 2.32 / ( (2.32 + 0.26 * r4) * (2.32 + 0.26 * r4) ) +
1134 0.0316 * (1. + 0.0171 * r295) / ( ( 1. + 0.0652 * r295) * (1. + 0.0652 * r295) ) ) ;
1136 Grad[iParam] += epar * shape * deriv * (xpar - xDigit) ; // Derivative over x
1138 Grad[iParam] += epar * shape * deriv * (zpar - zDigit) ; // Derivative over z
1140 Grad[iParam] += shape ; // Derivative over energy
1147 while(iparam < nPar ){
1148 Double_t xpar = x[iparam] ;
1149 Double_t zpar = x[iparam+1] ;
1150 Double_t epar = x[iparam+2] ;
1152 // geom->GetIncidentVector(*vtx,emcRP->GetPHOSMod(),xpar,zpar,vInc) ;
1153 // efit += epar * ShowerShape(xDigit - xpar,zDigit - zpar,vInc) ;
1154 efit += epar * ShowerShape(xDigit - xpar,zDigit - zpar) ;
1157 fret += (efit-emcEnergies[iDigit])*(efit-emcEnergies[iDigit])/emcEnergies[iDigit] ;
1158 // Here we assume, that sigma = sqrt(E)
1163 //____________________________________________________________________________
1164 void AliPHOSClusterizerv1::Print(const Option_t *)const
1166 // Print clusterizer parameters
1169 TString taskName(GetName()) ;
1170 taskName.ReplaceAll(Version(), "") ;
1172 if( strcmp(GetName(), "") !=0 ) {
1174 message = "\n--------------- %s %s -----------\n" ;
1175 message += "Clusterizing digits from the file: %s\n" ;
1176 message += " Branch: %s\n" ;
1177 message += " EMC Clustering threshold = %f\n" ;
1178 message += " EMC Local Maximum cut = %f\n" ;
1179 message += " EMC Logarothmic weight = %f\n" ;
1180 message += " CPV Clustering threshold = %f\n" ;
1181 message += " CPV Local Maximum cut = %f\n" ;
1182 message += " CPV Logarothmic weight = %f\n" ;
1184 message += " Unfolding on\n" ;
1186 message += " Unfolding off\n" ;
1188 message += "------------------------------------------------------------------" ;
1191 message = " AliPHOSClusterizerv1 not initialized " ;
1193 AliInfo(Form("%s, %s %s %s %s %s %s %s %s %s %s", message.Data(),
1198 fEmcClusteringThreshold,
1201 fCpvClusteringThreshold,
1205 //____________________________________________________________________________
1206 //void AliPHOSClusterizerv1::GetVertex(void)
1207 //{ //Extracts vertex posisition
1215 // if(gAlice && gAlice->GetMCApp() && gAlice->Generator()){
1217 // gAlice->Generator()->GetOrigin(x,y,z) ;
1218 // fVtx.SetXYZ(x,y,z) ;
1223 // fVtx[0]=fVtx[1]=fVtx[2]=0. ;
1226 //____________________________________________________________________________
1227 void AliPHOSClusterizerv1::PrintRecPoints(Option_t * option)
1229 // Prints list of RecPoints produced at the current pass of AliPHOSClusterizer
1231 AliPHOSGetter * gime = AliPHOSGetter::Instance();
1233 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
1234 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
1236 AliInfo(Form("\nevent %d \n Found %d EMC RecPoints and %d CPV RecPoints",
1237 gAlice->GetEvNumber(),
1238 emcRecPoints->GetEntriesFast(),
1239 cpvRecPoints->GetEntriesFast() )) ;
1241 fRecPointsInRun += emcRecPoints->GetEntriesFast() ;
1242 fRecPointsInRun += cpvRecPoints->GetEntriesFast() ;
1245 if(strstr(option,"all")) {
1246 printf("\n EMC clusters \n") ;
1247 printf("Index Ene(MeV) Multi Module X Y Z Lambdas_1 Lambda_2 # of prim Primaries list\n") ;
1249 for (index = 0 ; index < emcRecPoints->GetEntries() ; index++) {
1250 AliPHOSEmcRecPoint * rp = (AliPHOSEmcRecPoint * )emcRecPoints->At(index) ;
1252 rp->GetLocalPosition(locpos);
1254 rp->GetElipsAxis(lambda);
1257 primaries = rp->GetPrimaries(nprimaries);
1258 printf("\n%6d %8.2f %3d %2d %4.1f %4.1f %4.1f %4f %4f %2d : ",
1259 rp->GetIndexInList(), rp->GetEnergy(), rp->GetMultiplicity(), rp->GetPHOSMod(),
1260 locpos.X(), locpos.Y(), locpos.Z(), lambda[0], lambda[1], nprimaries) ;
1262 for (Int_t iprimary=0; iprimary<nprimaries; iprimary++) {
1263 printf("%d ", primaries[iprimary] ) ;
1268 //Now plot CPV recPoints
1269 printf("\n CPV clusters \n") ;
1270 printf("Index Ene(MeV) Module X Y Z \n") ;
1271 for (index = 0 ; index < cpvRecPoints->GetEntries() ; index++) {
1272 AliPHOSCpvRecPoint * rp = (AliPHOSCpvRecPoint * )cpvRecPoints->At(index) ;
1275 rp->GetLocalPosition(locpos);
1277 printf("\n%6d %8.2f %2d %4.1f %4.1f %4.1f \n",
1278 rp->GetIndexInList(), rp->GetEnergy(), rp->GetPHOSMod(),
1279 locpos.X(), locpos.Y(), locpos.Z()) ;
1285 //____________________________________________________________________________
1286 void AliPHOSClusterizerv1::SetDistancesToBadChannels()
1288 //For each EMC rec. point set the distance to the nearest bad crystal.
1289 //Author: Boris Polichtchouk
1291 if(!fCalibData->GetNumOfEmcBadChannels()) return;
1292 AliInfo(Form("%d bad channel(s) found.\n",fCalibData->GetNumOfEmcBadChannels()));
1294 AliPHOSGetter* gime = AliPHOSGetter::Instance();
1295 AliPHOSGeometry* geom = gime->PHOSGeometry();
1297 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
1300 fCalibData->EmcBadChannelIds(badIds);
1302 AliPHOSEmcRecPoint* rp;
1305 TVector3 gposRecPoint; // global (in ALICE frame) position of rec. point
1306 TVector3 gposBadChannel; // global position of bad crystal
1309 Float_t dist,minDist;
1311 for(Int_t iRP=0; iRP<emcRecPoints->GetEntries(); iRP++){
1312 rp = (AliPHOSEmcRecPoint*)emcRecPoints->At(iRP);
1315 for(Int_t iBad=0; iBad<fCalibData->GetNumOfEmcBadChannels(); iBad++) {
1316 rp->GetGlobalPosition(gposRecPoint,gmat);
1317 geom->RelPosInAlice(badIds[iBad],gposBadChannel);
1318 AliDebug(2,Form("BC position:[%.3f,%.3f,%.3f], RP position:[%.3f,%.3f,%.3f]. E=%.3f\n",
1319 gposBadChannel.X(),gposBadChannel.Y(),gposBadChannel.Z(),
1320 gposRecPoint.X(),gposRecPoint.Y(),gposRecPoint.Z(),rp->GetEnergy()));
1321 dR = gposBadChannel-gposRecPoint;
1323 if(dist<minDist) minDist = dist;
1326 rp->SetDistanceToBadCrystal(minDist);