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.111 2007/08/08 12:11:28 kharlov
22 * Protection against uninitialized fQADM
24 * Revision 1.110 2007/08/07 14:16:00 kharlov
25 * Quality assurance added (Yves Schutz)
27 * Revision 1.109 2007/07/24 17:20:35 policheh
28 * Usage of RecoParam objects instead of hardcoded parameters in reconstruction.
29 * (See $ALICE_ROOT/PHOS/macros/BeamTest2006/RawReconstruction.C).
31 * Revision 1.108 2007/06/18 07:00:51 kharlov
32 * Bug fix for attempt to use AliPHOSEmcRecPoint after its deletion
34 * Revision 1.107 2007/05/25 14:12:26 policheh
35 * Local to tracking CS transformation added for CPV rec. points
37 * Revision 1.106 2007/05/24 13:01:22 policheh
38 * Local to tracking CS transformation invoked for each EMC rec.point
40 * Revision 1.105 2007/05/02 13:41:22 kharlov
41 * Mode protection against absence of calib.data from AliPHOSCalibData to AliPHOSClusterizerv1::GetCalibrationParameters()
43 * Revision 1.104 2007/04/27 16:55:53 kharlov
44 * Calibration stops if PHOS CDB objects do not exist
46 * Revision 1.103 2007/04/11 11:55:45 policheh
47 * SetDistancesToBadChannels() added.
49 * Revision 1.102 2007/03/28 19:18:15 kharlov
50 * RecPoints recalculation in TSM removed
52 * Revision 1.101 2007/03/06 06:51:27 kharlov
53 * Calculation of cluster properties dep. on vertex posponed to TrackSegmentMaker
55 * Revision 1.100 2007/01/10 11:07:26 kharlov
56 * Raw digits writing to file (B.Polichtchouk)
58 * Revision 1.99 2006/11/07 16:49:51 kharlov
59 * Corrections for next event switch in case of raw data (B.Polichtchouk)
61 * Revision 1.98 2006/10/27 17:14:27 kharlov
62 * Introduce AliDebug and AliLog (B.Polichtchouk)
64 * Revision 1.97 2006/08/29 11:41:19 kharlov
65 * Missing implementation of ctors and = operator are added
67 * Revision 1.96 2006/08/25 16:56:30 kharlov
68 * Compliance with Effective C++
70 * Revision 1.95 2006/08/11 12:36:26 cvetan
71 * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root)
73 * Revision 1.94 2006/08/07 12:27:49 hristov
74 * Removing obsolete code which affected the event numbering scheme
76 * Revision 1.93 2006/08/01 12:20:17 cvetan
77 * 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
79 * Revision 1.92 2006/04/29 20:26:46 hristov
80 * Separate EMC and CPV calibration (Yu.Kharlov)
82 * Revision 1.91 2006/04/22 10:30:17 hristov
83 * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
85 * Revision 1.90 2006/04/11 15:22:59 hristov
86 * run number in query set to -1: forces AliCDBManager to use its run number (A.Colla)
88 * Revision 1.89 2006/03/13 14:05:42 kharlov
89 * Calibration objects for EMC and CPV
91 * Revision 1.88 2006/01/11 08:54:52 hristov
92 * Additional protection in case no calibration entry was found
94 * Revision 1.87 2005/11/22 08:46:43 kharlov
95 * Updated to new CDB (Boris Polichtchouk)
97 * Revision 1.86 2005/11/14 21:52:43 hristov
100 * Revision 1.85 2005/09/27 16:08:08 hristov
101 * New version of CDB storage framework (A.Colla)
103 * Revision 1.84 2005/09/21 10:02:47 kharlov
104 * Reading calibration from CDB (Boris Polichtchouk)
106 * Revision 1.82 2005/09/02 15:43:13 kharlov
107 * Add comments in GetCalibrationParameters and Calibrate
109 * Revision 1.81 2005/09/02 14:32:07 kharlov
110 * Calibration of raw data
112 * Revision 1.80 2005/08/24 15:31:36 kharlov
113 * Setting raw digits flag
115 * Revision 1.79 2005/07/25 15:53:53 kharlov
118 * Revision 1.78 2005/05/28 14:19:04 schutz
119 * Compilation warnings fixed by T.P.
123 //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (SUBATECH & Kurchatov Institute)
124 //////////////////////////////////////////////////////////////////////////////
125 // Clusterization class. Performs clusterization (collects neighbouring active cells) and
126 // unfolds the clusters having several local maxima.
127 // Results are stored in TreeR#, branches PHOSEmcRP (EMC recPoints),
128 // PHOSCpvRP (CPV RecPoints) and AliPHOSClusterizer (Clusterizer with all
129 // parameters including input digits branch title, thresholds etc.)
130 // This TTask is normally called from Reconstructioner, but can as well be used in
133 // root [0] AliPHOSClusterizerv1 * cl = new AliPHOSClusterizerv1("galice.root", "recpointsname", "digitsname")
134 // Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
135 // // reads gAlice from header file "galice.root", uses digits stored in the branch names "digitsname" (default = "Default")
136 // // and saves recpoints in branch named "recpointsname" (default = "digitsname")
137 // root [1] cl->ExecuteTask()
138 // //finds RecPoints in all events stored in galice.root
139 // root [2] cl->SetDigitsBranch("digits2")
140 // //sets another title for Digitis (input) branch
141 // root [3] cl->SetRecPointsBranch("recp2")
142 // //sets another title four output branches
143 // root [4] cl->SetEmcLocalMaxCut(0.03)
144 // //set clusterization parameters
145 // root [5] cl->ExecuteTask("deb all time")
146 // //once more finds RecPoints options are
147 // // deb - print number of found rec points
148 // // deb all - print number of found RecPoints and some their characteristics
149 // // time - print benchmarking results
151 // --- ROOT system ---
156 #include "TBenchmark.h"
158 // --- Standard library ---
160 // --- AliRoot header files ---
162 #include "AliRunLoader.h"
163 #include "AliGenerator.h"
164 #include "AliPHOSGetter.h"
165 #include "AliPHOSGeometry.h"
166 #include "AliPHOSClusterizerv1.h"
167 #include "AliPHOSEmcRecPoint.h"
168 #include "AliPHOSCpvRecPoint.h"
169 #include "AliPHOSDigit.h"
170 #include "AliPHOSDigitizer.h"
171 #include "AliPHOSCalibrationDB.h"
172 #include "AliCDBManager.h"
173 #include "AliCDBStorage.h"
174 #include "AliCDBEntry.h"
175 #include "AliPHOSReconstructor.h"
176 #include "AliPHOSRecoParam.h"
177 #include "AliPHOSQualAssDataMaker.h"
179 ClassImp(AliPHOSClusterizerv1)
181 //____________________________________________________________________________
182 AliPHOSClusterizerv1::AliPHOSClusterizerv1() :
183 AliPHOSClusterizer(),
184 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
185 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
186 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
187 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
188 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
189 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
190 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
191 fIsOldRCUFormat(0), fEventCounter(0)
193 // default ctor (to be used mainly by Streamer)
196 fDefaultInit = kTRUE ;
199 //____________________________________________________________________________
200 AliPHOSClusterizerv1::AliPHOSClusterizerv1(const TString alirunFileName, const TString eventFolderName) :
201 AliPHOSClusterizer(alirunFileName, eventFolderName),
202 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
203 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
204 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
205 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
206 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
207 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
208 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
209 fIsOldRCUFormat(0), fEventCounter(0)
211 // ctor with the indication of the file where header Tree and digits Tree are stored
215 fDefaultInit = kFALSE ;
218 //____________________________________________________________________________
219 AliPHOSClusterizerv1::AliPHOSClusterizerv1(const AliPHOSClusterizerv1 & obj) :
220 AliPHOSClusterizer(obj),
221 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
222 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
223 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
224 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
225 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
226 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
227 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
228 fIsOldRCUFormat(0), fEventCounter(0)
232 //____________________________________________________________________________
233 AliPHOSClusterizerv1::~AliPHOSClusterizerv1()
238 //____________________________________________________________________________
239 const TString AliPHOSClusterizerv1::BranchName() const
244 //____________________________________________________________________________
245 Float_t AliPHOSClusterizerv1::CalibrateEMC(Float_t amp, Int_t absId)
247 // Convert EMC measured amplitude into real energy.
248 // Calibration parameters are taken from calibration data base for raw data,
249 // or from digitizer parameters for simulated data.
253 AliPHOSGetter *gime = AliPHOSGetter::Instance();
254 gime->PHOSGeometry()->AbsToRelNumbering(absId,relId) ;
255 Int_t module = relId[0];
256 Int_t column = relId[3];
257 Int_t row = relId[2];
258 if(absId <= fEmcCrystals) { // this is EMC
259 fADCchanelEmc = fCalibData->GetADCchannelEmc (module,column,row);
260 return amp*fADCchanelEmc ;
264 if(absId <= fEmcCrystals) // this is EMC
265 return fADCpedestalEmc + amp*fADCchanelEmc ;
270 //____________________________________________________________________________
271 Float_t AliPHOSClusterizerv1::CalibrateCPV(Int_t amp, Int_t absId)
273 // Convert digitized CPV amplitude into charge.
274 // Calibration parameters are taken from calibration data base for raw data,
275 // or from digitizer parameters for simulated data.
279 AliPHOSGetter *gime = AliPHOSGetter::Instance();
280 gime->PHOSGeometry()->AbsToRelNumbering(absId,relId) ;
281 Int_t module = relId[0];
282 Int_t column = relId[3];
283 Int_t row = relId[2];
284 if(absId > fEmcCrystals) { // this is CPV
285 fADCchanelCpv = fCalibData->GetADCchannelCpv (module,column,row);
286 fADCpedestalCpv = fCalibData->GetADCpedestalCpv(module,column,row);
287 return fADCpedestalCpv + amp*fADCchanelCpv ;
291 if(absId > fEmcCrystals) // this is CPV
292 return fADCpedestalCpv+ amp*fADCchanelCpv ;
297 //____________________________________________________________________________
298 void AliPHOSClusterizerv1::Exec(Option_t *option)
300 // Steering method to perform clusterization for events
301 // in the range from fFirstEvent to fLastEvent.
302 // This range is optionally set by SetEventRange().
303 // if fLastEvent=-1 (by default), then process events until the end.
305 if(strstr(option,"tim"))
306 gBenchmark->Start("PHOSClusterizer");
308 if(strstr(option,"print")) {
313 GetCalibrationParameters() ;
315 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
317 gime->SetRawDigits(kFALSE);
319 gime->SetRawDigits(kTRUE);
321 if (fLastEvent == -1)
322 fLastEvent = gime->MaxEvent() - 1 ;
324 fLastEvent = TMath::Min(fFirstEvent, gime->MaxEvent()); // one event at the time
325 Int_t nEvents = fLastEvent - fFirstEvent + 1;
328 for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
331 gime->Event(ievent ,"D"); // Read digits from simulated data
333 AliRunLoader * rl = AliRunLoader::GetRunLoader(gime->PhosLoader()->GetTitle());
334 rl->GetEvent(ievent);
335 gime->Event(fRawReader,"W",fIsOldRCUFormat); // Read digits from raw data
337 fNumberOfEmcClusters = fNumberOfCpvClusters = 0 ;
341 AliDebug(2,Form(" ---- Printing clusters (%d) of event %d.\n",
342 gime->EmcRecPoints()->GetEntries(),ievent));
343 if(AliLog::GetGlobalDebugLevel()>1)
344 gime->EmcRecPoints()->Print();
349 //makes the quality assurance data
350 if (GetQualAssDataMaker()) {
351 GetQualAssDataMaker()->SetData(gime->EmcRecPoints()) ;
352 GetQualAssDataMaker()->Exec(AliQualAss::kRECPOINTS) ;
353 GetQualAssDataMaker()->SetData(gime->CpvRecPoints()) ;
354 GetQualAssDataMaker()->Exec(AliQualAss::kRECPOINTS) ;
359 if(strstr(option,"deb"))
360 PrintRecPoints(option) ;
362 //increment the total number of recpoints per run
363 fRecPointsInRun += gime->EmcRecPoints()->GetEntriesFast() ;
364 fRecPointsInRun += gime->CpvRecPoints()->GetEntriesFast() ;
367 //Write the quality assurance data only after the last event
368 if (GetQualAssDataMaker() && fEventCounter == gime->MaxEvent())
369 GetQualAssDataMaker()->Finish(AliQualAss::kRECPOINTS) ;
371 if(fWrite) //do not unload in "on flight" mode
374 if(strstr(option,"tim")){
375 gBenchmark->Stop("PHOSClusterizer");
376 AliInfo(Form("took %f seconds for Clusterizing %f seconds per event \n",
377 gBenchmark->GetCpuTime("PHOSClusterizer"),
378 gBenchmark->GetCpuTime("PHOSClusterizer")/nEvents )) ;
382 //____________________________________________________________________________
383 Bool_t AliPHOSClusterizerv1::FindFit(AliPHOSEmcRecPoint * emcRP, AliPHOSDigit ** maxAt, Float_t * maxAtEnergy,
384 Int_t nPar, Float_t * fitparameters) const
386 // Calls TMinuit to fit the energy distribution of a cluster with several maxima
387 // The initial values for fitting procedure are set equal to the positions of local maxima.
388 // Cluster will be fitted as a superposition of nPar/3 electromagnetic showers
391 AliPHOSGetter * gime = AliPHOSGetter::Instance();
392 TClonesArray * digits = gime->Digits();
394 gMinuit->mncler(); // Reset Minuit's list of paramters
395 gMinuit->SetPrintLevel(-1) ; // No Printout
396 gMinuit->SetFCN(AliPHOSClusterizerv1::UnfoldingChiSquare) ;
397 // To set the address of the minimization function
399 TList * toMinuit = new TList();
400 toMinuit->AddAt(emcRP,0) ;
401 toMinuit->AddAt(digits,1) ;
403 gMinuit->SetObjectFit(toMinuit) ; // To tranfer pointer to UnfoldingChiSquare
405 // filling initial values for fit parameters
406 AliPHOSDigit * digit ;
410 Int_t nDigits = (Int_t) nPar / 3 ;
414 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
416 for(iDigit = 0; iDigit < nDigits; iDigit++){
417 digit = maxAt[iDigit];
422 geom->AbsToRelNumbering(digit->GetId(), relid) ;
423 geom->RelPosInModule(relid, x, z) ;
425 Float_t energy = maxAtEnergy[iDigit] ;
427 gMinuit->mnparm(index, "x", x, 0.1, 0, 0, ierflg) ;
430 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : x = %f\n", x ) ;
433 gMinuit->mnparm(index, "z", z, 0.1, 0, 0, ierflg) ;
436 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : z =%f\n", z ) ;
439 gMinuit->mnparm(index, "Energy", energy , 0.05*energy, 0., 4.*energy, ierflg) ;
442 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : energy = %f\n", energy ) ;
447 Double_t p0 = 0.1 ; // "Tolerance" Evaluation stops when EDM = 0.0001*p0 ; The number of function call slightly
452 gMinuit->mnexcm("SET STR", &p2, 0, ierflg) ; // force TMinuit to reduce function calls
453 gMinuit->mnexcm("SET GRA", &p1, 1, ierflg) ; // force TMinuit to use my gradient
454 gMinuit->SetMaxIterations(5);
455 gMinuit->mnexcm("SET NOW", &p2 , 0, ierflg) ; // No Warnings
457 gMinuit->mnexcm("MIGRAD", &p0, 0, ierflg) ; // minimize
459 if(ierflg == 4){ // Minimum not found
460 Warning("FindFit", "PHOS Unfolding fit not converged, cluster abandoned\n" );
463 for(index = 0; index < nPar; index++){
466 gMinuit->GetParameter(index, val, err) ; // Returns value and error of parameter index
467 fitparameters[index] = val ;
475 //____________________________________________________________________________
476 void AliPHOSClusterizerv1::GetCalibrationParameters()
478 // Set calibration parameters:
479 // if calibration database exists, they are read from database,
480 // otherwise, reconstruction stops in the constructor of AliPHOSCalibData
482 // It is a user responsilibity to open CDB before reconstruction, for example:
483 // AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage("local://CalibDB");
485 fCalibData = new AliPHOSCalibData(-1); //use AliCDBManager's run number
486 if (fCalibData->GetCalibDataEmc() == 0)
487 AliFatal("Calibration parameters for PHOS EMC not found. Stop reconstruction.\n");
488 if (fCalibData->GetCalibDataCpv() == 0)
489 AliFatal("Calibration parameters for PHOS CPV not found. Stop reconstruction.\n");
493 //____________________________________________________________________________
494 void AliPHOSClusterizerv1::Init()
496 // Make all memory allocations which can not be done in default constructor.
497 // Attach the Clusterizer task to the list of PHOS tasks
499 AliPHOSGetter* gime = AliPHOSGetter::Instance() ;
501 gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName.Data());
503 AliPHOSGeometry * geom = gime->PHOSGeometry();
505 fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ;
508 gMinuit = new TMinuit(100);
510 if ( !gime->Clusterizer() ) {
511 gime->PostClusterizer(this);
515 //____________________________________________________________________________
516 void AliPHOSClusterizerv1::InitParameters()
519 fNumberOfCpvClusters = 0 ;
520 fNumberOfEmcClusters = 0 ;
522 const AliPHOSRecoParam* parEmc = AliPHOSReconstructor::GetRecoParamEmc();
523 if(!parEmc) AliFatal("Reconstruction parameters for EMC not set!");
525 const AliPHOSRecoParam* parCpv = AliPHOSReconstructor::GetRecoParamCpv();
526 if(!parCpv) AliFatal("Reconstruction parameters for CPV not set!");
528 fCpvClusteringThreshold = parCpv->GetClusteringThreshold();
529 fEmcClusteringThreshold = parEmc->GetClusteringThreshold();
531 fEmcLocMaxCut = parEmc->GetLocalMaxCut();
532 fCpvLocMaxCut = parCpv->GetLocalMaxCut();
534 fEmcMinE = parEmc->GetMinE();
535 fCpvMinE = parCpv->GetMinE();
537 fW0 = parEmc->GetLogWeight();
538 fW0CPV = parCpv->GetLogWeight();
540 fEmcTimeGate = 1.e-8 ;
544 fRecPointsInRun = 0 ;
550 SetEventRange(0,-1) ;
552 fIsOldRCUFormat = kFALSE;
555 //____________________________________________________________________________
556 Int_t AliPHOSClusterizerv1::AreNeighbours(AliPHOSDigit * d1, AliPHOSDigit * d2)const
558 // Gives the neighbourness of two digits = 0 are not neighbour but continue searching
560 // = 2 are not neighbour but do not continue searching
561 // neighbours are defined as digits having at least a common vertex
562 // The order of d1 and d2 is important: first (d1) should be a digit already in a cluster
563 // which is compared to a digit (d2) not yet in a cluster
565 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
570 geom->AbsToRelNumbering(d1->GetId(), relid1) ;
573 geom->AbsToRelNumbering(d2->GetId(), relid2) ;
575 if ( (relid1[0] == relid2[0]) && (relid1[1]==relid2[1]) ) { // inside the same PHOS module
576 Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;
577 Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;
579 if (( coldiff <= 1 ) && ( rowdiff <= 1 )){
580 if((relid1[1] != 0) || (TMath::Abs(d1->GetTime() - d2->GetTime() ) < fEmcTimeGate))
584 if((relid2[2] > relid1[2]) && (relid2[3] > relid1[3]+1))
585 rv = 2; // Difference in row numbers is too large to look further
591 if( (relid1[0] < relid2[0]) || (relid1[1] != relid2[1]) )
598 //____________________________________________________________________________
599 void AliPHOSClusterizerv1::CleanDigits(TClonesArray * digits)
601 // Remove digits with amplitudes below threshold
603 for(Int_t i=0; i<digits->GetEntriesFast(); i++){
604 AliPHOSDigit * digit = static_cast<AliPHOSDigit*>(digits->At(i)) ;
605 if ( (IsInEmc(digit) && CalibrateEMC(digit->GetEnergy(),digit->GetId()) < fEmcMinE) ||
606 (IsInCpv(digit) && CalibrateCPV(digit->GetAmp() ,digit->GetId()) < fCpvMinE) )
607 digits->RemoveAt(i) ;
610 for (Int_t i = 0 ; i < digits->GetEntriesFast() ; i++) {
611 AliPHOSDigit *digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
612 digit->SetIndexInList(i) ;
615 //Overwrite digits tree
616 AliPHOSGetter* gime = AliPHOSGetter::Instance();
617 TTree * treeD = gime->TreeD();
618 treeD->Branch("PHOS", &digits);
620 gime->WriteDigits("OVERWRITE");
621 gime->PhosLoader()->UnloadDigits() ;
623 //____________________________________________________________________________
624 Bool_t AliPHOSClusterizerv1::IsInEmc(AliPHOSDigit * digit) const
626 // Tells if (true) or not (false) the digit is in a PHOS-EMC module
629 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
631 Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
633 if(digit->GetId() <= nEMC ) rv = kTRUE;
638 //____________________________________________________________________________
639 Bool_t AliPHOSClusterizerv1::IsInCpv(AliPHOSDigit * digit) const
641 // Tells if (true) or not (false) the digit is in a PHOS-CPV module
645 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
647 Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
649 if(digit->GetId() > nEMC ) rv = kTRUE;
654 //____________________________________________________________________________
655 void AliPHOSClusterizerv1::Unload()
657 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
658 gime->PhosLoader()->UnloadDigits() ;
659 gime->PhosLoader()->UnloadRecPoints() ;
662 //____________________________________________________________________________
663 void AliPHOSClusterizerv1::WriteRecPoints()
666 // Creates new branches with given title
667 // fills and writes into TreeR.
669 AliPHOSGetter * gime = AliPHOSGetter::Instance();
671 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
672 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
673 TClonesArray * digits = gime->Digits() ;
676 //Evaluate position, dispersion and other RecPoint properties..
677 Int_t nEmc = emcRecPoints->GetEntriesFast();
678 for(index = 0; index < nEmc; index++){
679 AliPHOSEmcRecPoint * rp =
680 dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) );
681 rp->Purify(fEmcMinE) ;
682 if(rp->GetMultiplicity()==0){
683 emcRecPoints->RemoveAt(index) ;
688 // No vertex is available now, calculate corrections in PID
689 rp->EvalAll(fW0,digits) ;
690 TVector3 fakeVtx(0.,0.,0.) ;
691 rp->EvalAll(fW0,fakeVtx,digits) ;
692 rp->EvalLocal2TrackingCSTransform();
694 emcRecPoints->Compress() ;
695 // emcRecPoints->Sort() ; //Can not sort until position is calculated!
696 // emcRecPoints->Expand(emcRecPoints->GetEntriesFast()) ;
697 for(index = 0; index < emcRecPoints->GetEntries(); index++){
698 dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) )->SetIndexInList(index) ;
701 //For each rec.point set the distance to the nearest bad crystal (BVP)
702 SetDistancesToBadChannels();
704 //Now the same for CPV
705 for(index = 0; index < cpvRecPoints->GetEntries(); index++){
706 AliPHOSCpvRecPoint * rp = dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(index) );
707 rp->EvalAll(fW0CPV,digits) ;
708 rp->EvalLocal2TrackingCSTransform();
710 // cpvRecPoints->Sort() ;
712 for(index = 0; index < cpvRecPoints->GetEntries(); index++)
713 dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(index) )->SetIndexInList(index) ;
715 cpvRecPoints->Expand(cpvRecPoints->GetEntriesFast()) ;
717 if(fWrite){ //We write TreeR
718 TTree * treeR = gime->TreeR();
720 Int_t bufferSize = 32000 ;
721 Int_t splitlevel = 0 ;
724 TBranch * emcBranch = treeR->Branch("PHOSEmcRP","TObjArray",&emcRecPoints,bufferSize,splitlevel);
725 emcBranch->SetTitle(BranchName());
728 TBranch * cpvBranch = treeR->Branch("PHOSCpvRP","TObjArray",&cpvRecPoints,bufferSize,splitlevel);
729 cpvBranch->SetTitle(BranchName());
734 gime->WriteRecPoints("OVERWRITE");
735 gime->WriteClusterizer("OVERWRITE");
739 //____________________________________________________________________________
740 void AliPHOSClusterizerv1::MakeClusters()
742 // Steering method to construct the clusters stored in a list of Reconstructed Points
743 // A cluster is defined as a list of neighbour digits
746 AliPHOSGetter * gime = AliPHOSGetter::Instance();
748 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
749 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
751 emcRecPoints->Delete() ;
752 cpvRecPoints->Delete() ;
754 TClonesArray * digits = gime->Digits() ;
756 //Remove digits below threshold
757 CleanDigits(digits) ;
759 TClonesArray * digitsC = static_cast<TClonesArray*>( digits->Clone() ) ;
761 // Clusterization starts
763 TIter nextdigit(digitsC) ;
764 AliPHOSDigit * digit ;
765 Bool_t notremoved = kTRUE ;
767 while ( (digit = dynamic_cast<AliPHOSDigit *>( nextdigit()) ) ) { // scan over the list of digitsC
770 AliPHOSRecPoint * clu = 0 ;
772 TArrayI clusterdigitslist(1500) ;
775 if (( IsInEmc (digit) &&
776 CalibrateEMC(digit->GetEnergy(),digit->GetId()) > fEmcClusteringThreshold ) ||
778 CalibrateCPV(digit->GetAmp() ,digit->GetId()) > fCpvClusteringThreshold ) ) {
779 Int_t iDigitInCluster = 0 ;
781 if ( IsInEmc(digit) ) {
782 // start a new EMC RecPoint
783 if(fNumberOfEmcClusters >= emcRecPoints->GetSize())
784 emcRecPoints->Expand(2*fNumberOfEmcClusters+1) ;
786 emcRecPoints->AddAt(new AliPHOSEmcRecPoint(""), fNumberOfEmcClusters) ;
787 clu = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(fNumberOfEmcClusters) ) ;
788 fNumberOfEmcClusters++ ;
789 clu->AddDigit(*digit, CalibrateEMC(digit->GetEnergy(),digit->GetId())) ;
790 clusterdigitslist[iDigitInCluster] = digit->GetIndexInList() ;
792 digitsC->Remove(digit) ;
796 // start a new CPV cluster
797 if(fNumberOfCpvClusters >= cpvRecPoints->GetSize())
798 cpvRecPoints->Expand(2*fNumberOfCpvClusters+1);
800 cpvRecPoints->AddAt(new AliPHOSCpvRecPoint(""), fNumberOfCpvClusters) ;
802 clu = dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(fNumberOfCpvClusters) ) ;
803 fNumberOfCpvClusters++ ;
804 clu->AddDigit(*digit, CalibrateCPV(digit->GetAmp(),digit->GetId()) ) ;
805 clusterdigitslist[iDigitInCluster] = digit->GetIndexInList() ;
807 digitsC->Remove(digit) ;
810 // Here we remove remaining EMC digits, which cannot make a cluster
813 while( ( digit = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) {
815 digitsC->Remove(digit) ;
819 notremoved = kFALSE ;
826 AliPHOSDigit * digitN ;
828 while (index < iDigitInCluster){ // scan over digits already in cluster
829 digit = dynamic_cast<AliPHOSDigit*>( digits->At(clusterdigitslist[index]) ) ;
831 while ( (digitN = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) { // scan over the reduced list of digits
832 Int_t ineb = AreNeighbours(digit, digitN); // call (digit,digitN) in THAT oder !!!!!
834 case 0 : // not a neighbour
836 case 1 : // are neighbours
837 if (IsInEmc (digitN))
838 clu->AddDigit(*digitN, CalibrateEMC( digitN->GetEnergy(), digitN->GetId() ) );
840 clu->AddDigit(*digitN, CalibrateCPV( digitN->GetAmp() , digitN->GetId() ) );
842 clusterdigitslist[iDigitInCluster] = digitN->GetIndexInList() ;
844 digitsC->Remove(digitN) ;
846 case 2 : // too far from each other
855 } // loop over cluster
866 //____________________________________________________________________________
867 void AliPHOSClusterizerv1::MakeUnfolding()
869 // Unfolds clusters using the shape of an ElectroMagnetic shower
870 // Performs unfolding of all EMC/CPV clusters
872 AliPHOSGetter * gime = AliPHOSGetter::Instance();
874 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
876 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
877 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
878 TClonesArray * digits = gime->Digits() ;
880 // Unfold first EMC clusters
881 if(fNumberOfEmcClusters > 0){
883 Int_t nModulesToUnfold = geom->GetNModules() ;
885 Int_t numberofNotUnfolded = fNumberOfEmcClusters ;
887 for(index = 0 ; index < numberofNotUnfolded ; index++){
889 AliPHOSEmcRecPoint * emcRecPoint = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) ) ;
890 if(emcRecPoint->GetPHOSMod()> nModulesToUnfold)
893 Int_t nMultipl = emcRecPoint->GetMultiplicity() ;
894 AliPHOSDigit ** maxAt = new AliPHOSDigit*[nMultipl] ;
895 Float_t * maxAtEnergy = new Float_t[nMultipl] ;
896 Int_t nMax = emcRecPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy,fEmcLocMaxCut,digits) ;
898 if( nMax > 1 ) { // if cluster is very flat (no pronounced maximum) then nMax = 0
899 UnfoldCluster(emcRecPoint, nMax, maxAt, maxAtEnergy) ;
900 emcRecPoints->Remove(emcRecPoint);
901 emcRecPoints->Compress() ;
903 fNumberOfEmcClusters -- ;
904 numberofNotUnfolded-- ;
907 emcRecPoint->SetNExMax(1) ; //Only one local maximum
911 delete[] maxAtEnergy ;
914 // Unfolding of EMC clusters finished
917 // Unfold now CPV clusters
918 if(fNumberOfCpvClusters > 0){
920 Int_t nModulesToUnfold = geom->GetNModules() ;
922 Int_t numberofCpvNotUnfolded = fNumberOfCpvClusters ;
924 for(index = 0 ; index < numberofCpvNotUnfolded ; index++){
926 AliPHOSRecPoint * recPoint = dynamic_cast<AliPHOSRecPoint *>( cpvRecPoints->At(index) ) ;
928 if(recPoint->GetPHOSMod()> nModulesToUnfold)
931 AliPHOSEmcRecPoint * emcRecPoint = dynamic_cast<AliPHOSEmcRecPoint*>(recPoint) ;
933 Int_t nMultipl = emcRecPoint->GetMultiplicity() ;
934 AliPHOSDigit ** maxAt = new AliPHOSDigit*[nMultipl] ;
935 Float_t * maxAtEnergy = new Float_t[nMultipl] ;
936 Int_t nMax = emcRecPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy,fCpvLocMaxCut,digits) ;
938 if( nMax > 1 ) { // if cluster is very flat (no pronounced maximum) then nMax = 0
939 UnfoldCluster(emcRecPoint, nMax, maxAt, maxAtEnergy) ;
940 cpvRecPoints->Remove(emcRecPoint);
941 cpvRecPoints->Compress() ;
943 numberofCpvNotUnfolded-- ;
944 fNumberOfCpvClusters-- ;
948 delete[] maxAtEnergy ;
951 //Unfolding of Cpv clusters finished
955 //____________________________________________________________________________
956 Double_t AliPHOSClusterizerv1::ShowerShape(Double_t x, Double_t z)
958 // Shape of the shower (see PHOS TDR)
959 // If you change this function, change also the gradient evaluation in ChiSquare()
961 //for the moment we neglect dependence on the incident angle.
963 Double_t r2 = x*x + z*z ;
964 Double_t r4 = r2*r2 ;
965 Double_t r295 = TMath::Power(r2, 2.95/2.) ;
966 Double_t shape = TMath::Exp( -r4 * (1. / (2.32 + 0.26 * r4) + 0.0316 / (1 + 0.0652 * r295) ) ) ;
970 //____________________________________________________________________________
971 void AliPHOSClusterizerv1::UnfoldCluster(AliPHOSEmcRecPoint * iniEmc,
973 AliPHOSDigit ** maxAt,
974 Float_t * maxAtEnergy)
976 // Performs the unfolding of a cluster with nMax overlapping showers
978 AliPHOSGetter * gime = AliPHOSGetter::Instance();
980 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
982 const TClonesArray * digits = gime->Digits() ;
983 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
984 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
986 Int_t nPar = 3 * nMax ;
987 Float_t * fitparameters = new Float_t[nPar] ;
989 Bool_t rv = FindFit(iniEmc, maxAt, maxAtEnergy, nPar, fitparameters) ;
991 // Fit failed, return and remove cluster
992 iniEmc->SetNExMax(-1) ;
993 delete[] fitparameters ;
997 // create ufolded rec points and fill them with new energy lists
998 // First calculate energy deposited in each sell in accordance with fit (without fluctuations): efit[]
999 // and later correct this number in acordance with actual energy deposition
1001 Int_t nDigits = iniEmc->GetMultiplicity() ;
1002 Float_t * efit = new Float_t[nDigits] ;
1003 Float_t xDigit=0.,zDigit=0. ;
1004 Float_t xpar=0.,zpar=0.,epar=0. ;
1006 AliPHOSDigit * digit = 0 ;
1007 Int_t * emcDigits = iniEmc->GetDigitsList() ;
1013 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
1014 digit = dynamic_cast<AliPHOSDigit*>( digits->At(emcDigits[iDigit] ) ) ;
1015 geom->AbsToRelNumbering(digit->GetId(), relid) ;
1016 geom->RelPosInModule(relid, xDigit, zDigit) ;
1020 while(iparam < nPar ){
1021 xpar = fitparameters[iparam] ;
1022 zpar = fitparameters[iparam+1] ;
1023 epar = fitparameters[iparam+2] ;
1025 // geom->GetIncidentVector(fVtx,relid[0],xpar,zpar,vIncid) ;
1026 // efit[iDigit] += epar * ShowerShape(xDigit - xpar,zDigit - zpar,vIncid) ;
1027 efit[iDigit] += epar * ShowerShape(xDigit - xpar,zDigit - zpar) ;
1032 // Now create new RecPoints and fill energy lists with efit corrected to fluctuations
1033 // so that energy deposited in each cell is distributed betwin new clusters proportionally
1034 // to its contribution to efit
1036 Float_t * emcEnergies = iniEmc->GetEnergiesList() ;
1040 while(iparam < nPar ){
1041 xpar = fitparameters[iparam] ;
1042 zpar = fitparameters[iparam+1] ;
1043 epar = fitparameters[iparam+2] ;
1045 // geom->GetIncidentVector(fVtx,iniEmc->GetPHOSMod(),xpar,zpar,vIncid) ;
1047 AliPHOSEmcRecPoint * emcRP = 0 ;
1049 if(iniEmc->IsEmc()){ //create new entries in fEmcRecPoints...
1051 if(fNumberOfEmcClusters >= emcRecPoints->GetSize())
1052 emcRecPoints->Expand(2*fNumberOfEmcClusters) ;
1054 (*emcRecPoints)[fNumberOfEmcClusters] = new AliPHOSEmcRecPoint("") ;
1055 emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(fNumberOfEmcClusters) ) ;
1056 fNumberOfEmcClusters++ ;
1057 emcRP->SetNExMax((Int_t)nPar/3) ;
1059 else{//create new entries in fCpvRecPoints
1060 if(fNumberOfCpvClusters >= cpvRecPoints->GetSize())
1061 cpvRecPoints->Expand(2*fNumberOfCpvClusters) ;
1063 (*cpvRecPoints)[fNumberOfCpvClusters] = new AliPHOSCpvRecPoint("") ;
1064 emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( cpvRecPoints->At(fNumberOfCpvClusters) ) ;
1065 fNumberOfCpvClusters++ ;
1069 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
1070 digit = dynamic_cast<AliPHOSDigit*>( digits->At( emcDigits[iDigit] ) ) ;
1071 geom->AbsToRelNumbering(digit->GetId(), relid) ;
1072 geom->RelPosInModule(relid, xDigit, zDigit) ;
1073 // ratio = epar * ShowerShape(xDigit - xpar,zDigit - zpar,vIncid) / efit[iDigit] ;
1074 ratio = epar * ShowerShape(xDigit - xpar,zDigit - zpar) / efit[iDigit] ;
1075 eDigit = emcEnergies[iDigit] * ratio ;
1076 emcRP->AddDigit( *digit, eDigit ) ;
1080 delete[] fitparameters ;
1085 //_____________________________________________________________________________
1086 void AliPHOSClusterizerv1::UnfoldingChiSquare(Int_t & nPar, Double_t * Grad, Double_t & fret, Double_t * x, Int_t iflag)
1088 // Calculates the Chi square for the cluster unfolding minimization
1089 // Number of parameters, Gradient, Chi squared, parameters, what to do
1091 TList * toMinuit = dynamic_cast<TList*>( gMinuit->GetObjectFit() ) ;
1093 AliPHOSEmcRecPoint * emcRP = dynamic_cast<AliPHOSEmcRecPoint*>( toMinuit->At(0) ) ;
1094 TClonesArray * digits = dynamic_cast<TClonesArray*>( toMinuit->At(1) ) ;
1095 // TVector3 * vtx = dynamic_cast<TVector3*>(toMinuit->At(2)) ; //Vertex position
1097 // AliPHOSEmcRecPoint * emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( gMinuit->GetObjectFit() ) ; // EmcRecPoint to fit
1099 Int_t * emcDigits = emcRP->GetDigitsList() ;
1101 Int_t nOdigits = emcRP->GetDigitsMultiplicity() ;
1103 Float_t * emcEnergies = emcRP->GetEnergiesList() ;
1105 const AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
1111 for(iparam = 0 ; iparam < nPar ; iparam++)
1112 Grad[iparam] = 0 ; // Will evaluate gradient
1116 AliPHOSDigit * digit ;
1119 for( iDigit = 0 ; iDigit < nOdigits ; iDigit++) {
1121 digit = dynamic_cast<AliPHOSDigit*>( digits->At( emcDigits[iDigit] ) );
1127 geom->AbsToRelNumbering(digit->GetId(), relid) ;
1129 geom->RelPosInModule(relid, xDigit, zDigit) ;
1131 if(iflag == 2){ // calculate gradient
1134 while(iParam < nPar ){
1135 Double_t dx = (xDigit - x[iParam]) ;
1137 Double_t dz = (zDigit - x[iParam]) ;
1139 // geom->GetIncidentVector(*vtx,emcRP->GetPHOSMod(),x[iParam-2],x[iParam-1],vInc) ;
1140 // efit += x[iParam] * ShowerShape(dx,dz,vInc) ;
1141 efit += x[iParam] * ShowerShape(dx,dz) ;
1144 Double_t sum = 2. * (efit - emcEnergies[iDigit]) / emcEnergies[iDigit] ; // Here we assume, that sigma = sqrt(E)
1146 while(iParam < nPar ){
1147 Double_t xpar = x[iParam] ;
1148 Double_t zpar = x[iParam+1] ;
1149 Double_t epar = x[iParam+2] ;
1150 // geom->GetIncidentVector(*vtx,emcRP->GetPHOSMod(),xpar,zpar,vInc) ;
1151 Double_t dr = TMath::Sqrt( (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) );
1152 // Double_t shape = sum * ShowerShape(xDigit - xpar,zDigit - zpar,vInc) ;
1153 Double_t shape = sum * ShowerShape(xDigit - xpar,zDigit - zpar) ;
1154 //DP: No incident angle dependence in gradient yet!!!!!!
1155 Double_t r4 = dr*dr*dr*dr ;
1156 Double_t r295 = TMath::Power(dr,2.95) ;
1157 Double_t deriv =-4. * dr*dr * ( 2.32 / ( (2.32 + 0.26 * r4) * (2.32 + 0.26 * r4) ) +
1158 0.0316 * (1. + 0.0171 * r295) / ( ( 1. + 0.0652 * r295) * (1. + 0.0652 * r295) ) ) ;
1160 Grad[iParam] += epar * shape * deriv * (xpar - xDigit) ; // Derivative over x
1162 Grad[iParam] += epar * shape * deriv * (zpar - zDigit) ; // Derivative over z
1164 Grad[iParam] += shape ; // Derivative over energy
1171 while(iparam < nPar ){
1172 Double_t xpar = x[iparam] ;
1173 Double_t zpar = x[iparam+1] ;
1174 Double_t epar = x[iparam+2] ;
1176 // geom->GetIncidentVector(*vtx,emcRP->GetPHOSMod(),xpar,zpar,vInc) ;
1177 // efit += epar * ShowerShape(xDigit - xpar,zDigit - zpar,vInc) ;
1178 efit += epar * ShowerShape(xDigit - xpar,zDigit - zpar) ;
1181 fret += (efit-emcEnergies[iDigit])*(efit-emcEnergies[iDigit])/emcEnergies[iDigit] ;
1182 // Here we assume, that sigma = sqrt(E)
1187 //____________________________________________________________________________
1188 void AliPHOSClusterizerv1::Print(const Option_t *)const
1190 // Print clusterizer parameters
1193 TString taskName(GetName()) ;
1194 taskName.ReplaceAll(Version(), "") ;
1196 if( strcmp(GetName(), "") !=0 ) {
1198 message = "\n--------------- %s %s -----------\n" ;
1199 message += "Clusterizing digits from the file: %s\n" ;
1200 message += " Branch: %s\n" ;
1201 message += " EMC Clustering threshold = %f\n" ;
1202 message += " EMC Local Maximum cut = %f\n" ;
1203 message += " EMC Logarothmic weight = %f\n" ;
1204 message += " CPV Clustering threshold = %f\n" ;
1205 message += " CPV Local Maximum cut = %f\n" ;
1206 message += " CPV Logarothmic weight = %f\n" ;
1208 message += " Unfolding on\n" ;
1210 message += " Unfolding off\n" ;
1212 message += "------------------------------------------------------------------" ;
1215 message = " AliPHOSClusterizerv1 not initialized " ;
1217 AliInfo(Form("%s, %s %s %s %s %s %s %s %s %s %s", message.Data(),
1222 fEmcClusteringThreshold,
1225 fCpvClusteringThreshold,
1229 //____________________________________________________________________________
1230 //void AliPHOSClusterizerv1::GetVertex(void)
1231 //{ //Extracts vertex posisition
1239 // if(gAlice && gAlice->GetMCApp() && gAlice->Generator()){
1241 // gAlice->Generator()->GetOrigin(x,y,z) ;
1242 // fVtx.SetXYZ(x,y,z) ;
1247 // fVtx[0]=fVtx[1]=fVtx[2]=0. ;
1250 //____________________________________________________________________________
1251 void AliPHOSClusterizerv1::PrintRecPoints(Option_t * option)
1253 // Prints list of RecPoints produced at the current pass of AliPHOSClusterizer
1255 AliPHOSGetter * gime = AliPHOSGetter::Instance();
1257 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
1258 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
1260 AliInfo(Form("\nevent %d \n Found %d EMC RecPoints and %d CPV RecPoints",
1261 gAlice->GetEvNumber(),
1262 emcRecPoints->GetEntriesFast(),
1263 cpvRecPoints->GetEntriesFast() )) ;
1265 fRecPointsInRun += emcRecPoints->GetEntriesFast() ;
1266 fRecPointsInRun += cpvRecPoints->GetEntriesFast() ;
1269 if(strstr(option,"all")) {
1270 printf("\n EMC clusters \n") ;
1271 printf("Index Ene(MeV) Multi Module X Y Z Lambdas_1 Lambda_2 # of prim Primaries list\n") ;
1273 for (index = 0 ; index < emcRecPoints->GetEntries() ; index++) {
1274 AliPHOSEmcRecPoint * rp = (AliPHOSEmcRecPoint * )emcRecPoints->At(index) ;
1276 rp->GetLocalPosition(locpos);
1278 rp->GetElipsAxis(lambda);
1281 primaries = rp->GetPrimaries(nprimaries);
1282 printf("\n%6d %8.2f %3d %2d %4.1f %4.1f %4.1f %4f %4f %2d : ",
1283 rp->GetIndexInList(), rp->GetEnergy(), rp->GetMultiplicity(), rp->GetPHOSMod(),
1284 locpos.X(), locpos.Y(), locpos.Z(), lambda[0], lambda[1], nprimaries) ;
1286 for (Int_t iprimary=0; iprimary<nprimaries; iprimary++) {
1287 printf("%d ", primaries[iprimary] ) ;
1292 //Now plot CPV recPoints
1293 printf("\n CPV clusters \n") ;
1294 printf("Index Ene(MeV) Module X Y Z \n") ;
1295 for (index = 0 ; index < cpvRecPoints->GetEntries() ; index++) {
1296 AliPHOSCpvRecPoint * rp = (AliPHOSCpvRecPoint * )cpvRecPoints->At(index) ;
1299 rp->GetLocalPosition(locpos);
1301 printf("\n%6d %8.2f %2d %4.1f %4.1f %4.1f \n",
1302 rp->GetIndexInList(), rp->GetEnergy(), rp->GetPHOSMod(),
1303 locpos.X(), locpos.Y(), locpos.Z()) ;
1309 //____________________________________________________________________________
1310 void AliPHOSClusterizerv1::SetDistancesToBadChannels()
1312 //For each EMC rec. point set the distance to the nearest bad crystal.
1313 //Author: Boris Polichtchouk
1315 if(!fCalibData->GetNumOfEmcBadChannels()) return;
1316 AliInfo(Form("%d bad channel(s) found.\n",fCalibData->GetNumOfEmcBadChannels()));
1318 AliPHOSGetter* gime = AliPHOSGetter::Instance();
1319 AliPHOSGeometry* geom = gime->PHOSGeometry();
1321 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
1324 fCalibData->EmcBadChannelIds(badIds);
1326 AliPHOSEmcRecPoint* rp;
1329 TVector3 gposRecPoint; // global (in ALICE frame) position of rec. point
1330 TVector3 gposBadChannel; // global position of bad crystal
1333 Float_t dist,minDist;
1335 for(Int_t iRP=0; iRP<emcRecPoints->GetEntries(); iRP++){
1336 rp = (AliPHOSEmcRecPoint*)emcRecPoints->At(iRP);
1339 for(Int_t iBad=0; iBad<fCalibData->GetNumOfEmcBadChannels(); iBad++) {
1340 rp->GetGlobalPosition(gposRecPoint,gmat);
1341 geom->RelPosInAlice(badIds[iBad],gposBadChannel);
1342 AliDebug(2,Form("BC position:[%.3f,%.3f,%.3f], RP position:[%.3f,%.3f,%.3f]. E=%.3f\n",
1343 gposBadChannel.X(),gposBadChannel.Y(),gposBadChannel.Z(),
1344 gposRecPoint.X(),gposRecPoint.Y(),gposRecPoint.Z(),rp->GetEnergy()));
1345 dR = gposBadChannel-gposRecPoint;
1347 if(dist<minDist) minDist = dist;
1350 rp->SetDistanceToBadCrystal(minDist);