]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PHOS/AliPHOSClusterizerv1.cxx
moving AliTPCClusterHistograms to dep library
[u/mrichter/AliRoot.git] / PHOS / AliPHOSClusterizerv1.cxx
CommitLineData
d15a28e7 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
b2a60966 16/* $Id$ */
17
702ab87e 18/* History of cvs commits:
19 *
20 * $Log$
e1afea68 21 * Revision 1.97 2006/08/29 11:41:19 kharlov
22 * Missing implementation of ctors and = operator are added
23 *
f1133801 24 * Revision 1.96 2006/08/25 16:56:30 kharlov
25 * Compliance with Effective C++
26 *
0378398c 27 * Revision 1.95 2006/08/11 12:36:26 cvetan
28 * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root)
29 *
52c5f046 30 * Revision 1.94 2006/08/07 12:27:49 hristov
31 * Removing obsolete code which affected the event numbering scheme
32 *
4d4750bd 33 * Revision 1.93 2006/08/01 12:20:17 cvetan
34 * 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
35 *
f5eaa851 36 * Revision 1.92 2006/04/29 20:26:46 hristov
37 * Separate EMC and CPV calibration (Yu.Kharlov)
38 *
e95226ae 39 * Revision 1.91 2006/04/22 10:30:17 hristov
40 * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
41 *
27a73a5d 42 * Revision 1.90 2006/04/11 15:22:59 hristov
43 * run number in query set to -1: forces AliCDBManager to use its run number (A.Colla)
44 *
28871337 45 * Revision 1.89 2006/03/13 14:05:42 kharlov
46 * Calibration objects for EMC and CPV
47 *
fc6706cb 48 * Revision 1.88 2006/01/11 08:54:52 hristov
49 * Additional protection in case no calibration entry was found
50 *
e521c5a0 51 * Revision 1.87 2005/11/22 08:46:43 kharlov
52 * Updated to new CDB (Boris Polichtchouk)
53 *
ef629623 54 * Revision 1.86 2005/11/14 21:52:43 hristov
55 * Coding conventions
56 *
fdf65bb5 57 * Revision 1.85 2005/09/27 16:08:08 hristov
58 * New version of CDB storage framework (A.Colla)
59 *
9e1ceb13 60 * Revision 1.84 2005/09/21 10:02:47 kharlov
61 * Reading calibration from CDB (Boris Polichtchouk)
62 *
8d6d4fb5 63 * Revision 1.82 2005/09/02 15:43:13 kharlov
64 * Add comments in GetCalibrationParameters and Calibrate
65 *
5c149aeb 66 * Revision 1.81 2005/09/02 14:32:07 kharlov
67 * Calibration of raw data
68 *
44ae287e 69 * Revision 1.80 2005/08/24 15:31:36 kharlov
70 * Setting raw digits flag
71 *
9735c615 72 * Revision 1.79 2005/07/25 15:53:53 kharlov
73 * Read raw data
74 *
3cf4f75f 75 * Revision 1.78 2005/05/28 14:19:04 schutz
76 * Compilation warnings fixed by T.P.
77 *
702ab87e 78 */
79
9a1398dd 80//*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (SUBATECH & Kurchatov Institute)
d15a28e7 81//////////////////////////////////////////////////////////////////////////////
9a1398dd 82// Clusterization class. Performs clusterization (collects neighbouring active cells) and
a4e98857 83// unfolds the clusters having several local maxima.
84// Results are stored in TreeR#, branches PHOSEmcRP (EMC recPoints),
9a1398dd 85// PHOSCpvRP (CPV RecPoints) and AliPHOSClusterizer (Clusterizer with all
f035f6ce 86// parameters including input digits branch title, thresholds etc.)
a4e98857 87// This TTask is normally called from Reconstructioner, but can as well be used in
88// standalone mode.
89// Use Case:
fc12304f 90// root [0] AliPHOSClusterizerv1 * cl = new AliPHOSClusterizerv1("galice.root", "recpointsname", "digitsname")
a4e98857 91// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
fc12304f 92// // reads gAlice from header file "galice.root", uses digits stored in the branch names "digitsname" (default = "Default")
93// // and saves recpoints in branch named "recpointsname" (default = "digitsname")
a4e98857 94// root [1] cl->ExecuteTask()
9a1398dd 95// //finds RecPoints in all events stored in galice.root
a4e98857 96// root [2] cl->SetDigitsBranch("digits2")
f035f6ce 97// //sets another title for Digitis (input) branch
a4e98857 98// root [3] cl->SetRecPointsBranch("recp2")
f035f6ce 99// //sets another title four output branches
a4e98857 100// root [4] cl->SetEmcLocalMaxCut(0.03)
9a1398dd 101// //set clusterization parameters
a4e98857 102// root [5] cl->ExecuteTask("deb all time")
9a1398dd 103// //once more finds RecPoints options are
104// // deb - print number of found rec points
105// // deb all - print number of found RecPoints and some their characteristics
106// // time - print benchmarking results
ed4205d8 107
d15a28e7 108// --- ROOT system ---
109
110#include "TMath.h"
9a1398dd 111#include "TMinuit.h"
112#include "TTree.h"
9a1398dd 113#include "TBenchmark.h"
d15a28e7 114
115// --- Standard library ---
116
d15a28e7 117// --- AliRoot header files ---
351dd634 118#include "AliLog.h"
88cb7938 119#include "AliPHOSGetter.h"
e957fea8 120#include "AliPHOSGeometry.h"
d15a28e7 121#include "AliPHOSClusterizerv1.h"
88cb7938 122#include "AliPHOSEmcRecPoint.h"
9a1398dd 123#include "AliPHOSCpvRecPoint.h"
d15a28e7 124#include "AliPHOSDigit.h"
9a1398dd 125#include "AliPHOSDigitizer.h"
ba898748 126#include "AliPHOSCalibrationDB.h"
9e1ceb13 127#include "AliCDBManager.h"
eaa5012b 128#include "AliCDBStorage.h"
fdf65bb5 129#include "AliCDBEntry.h"
d15a28e7 130
131ClassImp(AliPHOSClusterizerv1)
f035f6ce 132
d15a28e7 133//____________________________________________________________________________
0378398c 134AliPHOSClusterizerv1::AliPHOSClusterizerv1() :
135 AliPHOSClusterizer(),
136 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
137 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
138 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
139 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
140 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
141 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
142 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
143 fIsOldRCUFormat(0)
d15a28e7 144{
f035f6ce 145 // default ctor (to be used mainly by Streamer)
f035f6ce 146
8d0f3f77 147 InitParameters() ;
92f521a9 148 fDefaultInit = kTRUE ;
9a1398dd 149}
7b7c1533 150
9a1398dd 151//____________________________________________________________________________
0378398c 152AliPHOSClusterizerv1::AliPHOSClusterizerv1(const TString alirunFileName, const TString eventFolderName) :
153 AliPHOSClusterizer(alirunFileName, eventFolderName),
154 fDefaultInit(0), fEmcCrystals(0), fToUnfold(0),
155 fWrite(0), fNumberOfEmcClusters(0), fNumberOfCpvClusters(0),
156 fCalibData(0), fADCchanelEmc(0), fADCpedestalEmc(0),
157 fADCchanelCpv(0), fADCpedestalCpv(0), fEmcClusteringThreshold(0),
158 fCpvClusteringThreshold(0), fEmcMinE(0), fCpvMinE(0),
159 fEmcLocMaxCut(0), fW0(0), fCpvLocMaxCut(0),
160 fW0CPV(0), fRecPointsInRun(0), fEmcTimeGate(0),
161 fIsOldRCUFormat(0)
9a1398dd 162{
a4e98857 163 // ctor with the indication of the file where header Tree and digits Tree are stored
9a1398dd 164
8d0f3f77 165 InitParameters() ;
2bd5457f 166 Init() ;
92f521a9 167 fDefaultInit = kFALSE ;
9a1398dd 168}
fc12304f 169
f1133801 170//____________________________________________________________________________
171AliPHOSClusterizerv1::AliPHOSClusterizerv1(const AliPHOSClusterizerv1 & obj) :
172 AliPHOSClusterizer(obj),
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),
180 fIsOldRCUFormat(0)
181{
182 // Copy constructor
183}
9688c1dd 184//____________________________________________________________________________
185 AliPHOSClusterizerv1::~AliPHOSClusterizerv1()
186{
0bc3b8ed 187 // dtor
188
9688c1dd 189}
fc12304f 190//____________________________________________________________________________
191const TString AliPHOSClusterizerv1::BranchName() const
192{
88cb7938 193 return GetName();
fc12304f 194}
195
9a1398dd 196//____________________________________________________________________________
e95226ae 197Float_t AliPHOSClusterizerv1::CalibrateEMC(Float_t amp, Int_t absId)
88cb7938 198{
e95226ae 199 // Convert EMC measured amplitude into real energy.
5c149aeb 200 // Calibration parameters are taken from calibration data base for raw data,
201 // or from digitizer parameters for simulated data.
202
44ae287e 203 if(fCalibData){
204 Int_t relId[4];
205 AliPHOSGetter *gime = AliPHOSGetter::Instance();
206 gime->PHOSGeometry()->AbsToRelNumbering(absId,relId) ;
207 Int_t module = relId[0];
8d6d4fb5 208 Int_t column = relId[3];
eaa5012b 209 Int_t row = relId[2];
e95226ae 210 if(absId <= fEmcCrystals) { // this is EMC
44ae287e 211 fADCchanelEmc = fCalibData->GetADCchannelEmc (module,column,row);
e95226ae 212 return amp*fADCchanelEmc ;
44ae287e 213 }
e95226ae 214 }
215 else{ //simulation
216 if(absId <= fEmcCrystals) // this is EMC
217 return fADCpedestalEmc + amp*fADCchanelEmc ;
218 }
219 return 0;
220}
221
222//____________________________________________________________________________
223Float_t AliPHOSClusterizerv1::CalibrateCPV(Int_t amp, Int_t absId)
224{
225 // Convert digitized CPV amplitude into charge.
226 // Calibration parameters are taken from calibration data base for raw data,
227 // or from digitizer parameters for simulated data.
228
229 if(fCalibData){
230 Int_t relId[4];
231 AliPHOSGetter *gime = AliPHOSGetter::Instance();
232 gime->PHOSGeometry()->AbsToRelNumbering(absId,relId) ;
233 Int_t module = relId[0];
234 Int_t column = relId[3];
235 Int_t row = relId[2];
236 if(absId > fEmcCrystals) { // this is CPV
fc6706cb 237 fADCchanelCpv = fCalibData->GetADCchannelCpv (module,column,row);
238 fADCpedestalCpv = fCalibData->GetADCpedestalCpv(module,column,row);
239 return fADCpedestalCpv + amp*fADCchanelCpv ;
240 }
ba898748 241 }
242 else{ //simulation
e95226ae 243 if(absId > fEmcCrystals) // this is CPV
ba898748 244 return fADCpedestalCpv+ amp*fADCchanelCpv ;
245 }
e95226ae 246 return 0;
3758d9fc 247}
548f0134 248
3758d9fc 249//____________________________________________________________________________
eabde521 250void AliPHOSClusterizerv1::Exec(Option_t *option)
a4e98857 251{
eabde521 252 // Steering method to perform clusterization for events
253 // in the range from fFirstEvent to fLastEvent.
254 // This range is optionally set by SetEventRange().
255 // if fLastEvent=-1 (by default), then process events until the end.
9a1398dd 256
257 if(strstr(option,"tim"))
7d493c2c 258 gBenchmark->Start("PHOSClusterizer");
9a1398dd 259
eabde521 260 if(strstr(option,"print")) {
88cb7938 261 Print() ;
eabde521 262 return ;
263 }
bed9e3fb 264
eaa5012b 265 GetCalibrationParameters() ;
266
ba898748 267 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
9735c615 268 if (fRawReader == 0)
269 gime->SetRawDigits(kFALSE);
270 else
271 gime->SetRawDigits(kTRUE);
88cb7938 272
9cae45af 273 if (fLastEvent == -1)
274 fLastEvent = gime->MaxEvent() - 1 ;
275 else
fb43ada4 276 fLastEvent = TMath::Min(fFirstEvent, gime->MaxEvent()); // one event at the time
eabde521 277 Int_t nEvents = fLastEvent - fFirstEvent + 1;
ba898748 278
9cae45af 279 Int_t ievent ;
9cae45af 280 for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
3cf4f75f 281 if (fRawReader == 0)
282 gime->Event(ievent ,"D"); // Read digits from simulated data
f5eaa851 283 else {
284 gime->Event(fRawReader,"W",fIsOldRCUFormat); // Read digits from raw data
285 }
548f0134 286 fNumberOfEmcClusters = fNumberOfCpvClusters = 0 ;
9a1398dd 287
88cb7938 288 MakeClusters() ;
e1afea68 289
290 AliDebug(2,Form(" ---- Printing clusters (%d) of event %d.\n",
291 gime->EmcRecPoints()->GetEntries(),ievent));
292 if(AliLog::GetGlobalDebugLevel()>1)
293 gime->EmcRecPoints()->Print();
88cb7938 294
fc12304f 295 if(fToUnfold)
296 MakeUnfolding() ;
7b7c1533 297
88cb7938 298 WriteRecPoints();
7b7c1533 299
94de8339 300 if(strstr(option,"deb"))
301 PrintRecPoints(option) ;
302
88cb7938 303 //increment the total number of recpoints per run
fbf811ec 304 fRecPointsInRun += gime->EmcRecPoints()->GetEntriesFast() ;
305 fRecPointsInRun += gime->CpvRecPoints()->GetEntriesFast() ;
27a73a5d 306 }
88cb7938 307
ba898748 308 if(fWrite) //do not unload in "on flight" mode
309 Unload();
9a1398dd 310
311 if(strstr(option,"tim")){
312 gBenchmark->Stop("PHOSClusterizer");
351dd634 313 AliInfo(Form("took %f seconds for Clusterizing %f seconds per event \n",
21cd0c07 314 gBenchmark->GetCpuTime("PHOSClusterizer"),
351dd634 315 gBenchmark->GetCpuTime("PHOSClusterizer")/nEvents )) ;
88cb7938 316 }
9a1398dd 317}
318
319//____________________________________________________________________________
a0636361 320Bool_t AliPHOSClusterizerv1::FindFit(AliPHOSEmcRecPoint * emcRP, AliPHOSDigit ** maxAt, Float_t * maxAtEnergy,
d1de15f5 321 Int_t nPar, Float_t * fitparameters) const
9a1398dd 322{
323 // Calls TMinuit to fit the energy distribution of a cluster with several maxima
a4e98857 324 // The initial values for fitting procedure are set equal to the positions of local maxima.
f035f6ce 325 // Cluster will be fitted as a superposition of nPar/3 electromagnetic showers
9a1398dd 326
88cb7938 327
328 AliPHOSGetter * gime = AliPHOSGetter::Instance();
329 TClonesArray * digits = gime->Digits();
7b7c1533 330
331
9a1398dd 332 gMinuit->mncler(); // Reset Minuit's list of paramters
333 gMinuit->SetPrintLevel(-1) ; // No Printout
334 gMinuit->SetFCN(AliPHOSClusterizerv1::UnfoldingChiSquare) ;
335 // To set the address of the minimization function
336
337 TList * toMinuit = new TList();
338 toMinuit->AddAt(emcRP,0) ;
7b7c1533 339 toMinuit->AddAt(digits,1) ;
9a1398dd 340
341 gMinuit->SetObjectFit(toMinuit) ; // To tranfer pointer to UnfoldingChiSquare
342
343 // filling initial values for fit parameters
344 AliPHOSDigit * digit ;
345
346 Int_t ierflg = 0;
347 Int_t index = 0 ;
348 Int_t nDigits = (Int_t) nPar / 3 ;
349
350 Int_t iDigit ;
351
7b7c1533 352 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
9a1398dd 353
354 for(iDigit = 0; iDigit < nDigits; iDigit++){
a0636361 355 digit = maxAt[iDigit];
9a1398dd 356
357 Int_t relid[4] ;
7b7c1533 358 Float_t x = 0.;
359 Float_t z = 0.;
360 geom->AbsToRelNumbering(digit->GetId(), relid) ;
361 geom->RelPosInModule(relid, x, z) ;
9a1398dd 362
363 Float_t energy = maxAtEnergy[iDigit] ;
364
365 gMinuit->mnparm(index, "x", x, 0.1, 0, 0, ierflg) ;
366 index++ ;
367 if(ierflg != 0){
21cd0c07 368 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : x = %f\n", x ) ;
9a1398dd 369 return kFALSE;
370 }
371 gMinuit->mnparm(index, "z", z, 0.1, 0, 0, ierflg) ;
372 index++ ;
373 if(ierflg != 0){
21cd0c07 374 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : z =%f\n", z ) ;
9a1398dd 375 return kFALSE;
376 }
377 gMinuit->mnparm(index, "Energy", energy , 0.05*energy, 0., 4.*energy, ierflg) ;
378 index++ ;
379 if(ierflg != 0){
21cd0c07 380 Warning("FindFit", "PHOS Unfolding unable to set initial value for fit procedure : energy = %f\n", energy ) ;
9a1398dd 381 return kFALSE;
382 }
383 }
384
385 Double_t p0 = 0.1 ; // "Tolerance" Evaluation stops when EDM = 0.0001*p0 ; The number of function call slightly
386 // depends on it.
387 Double_t p1 = 1.0 ;
388 Double_t p2 = 0.0 ;
389
390 gMinuit->mnexcm("SET STR", &p2, 0, ierflg) ; // force TMinuit to reduce function calls
391 gMinuit->mnexcm("SET GRA", &p1, 1, ierflg) ; // force TMinuit to use my gradient
392 gMinuit->SetMaxIterations(5);
393 gMinuit->mnexcm("SET NOW", &p2 , 0, ierflg) ; // No Warnings
394
395 gMinuit->mnexcm("MIGRAD", &p0, 0, ierflg) ; // minimize
396
397 if(ierflg == 4){ // Minimum not found
21cd0c07 398 Warning("FindFit", "PHOS Unfolding fit not converged, cluster abandoned\n" );
9a1398dd 399 return kFALSE ;
400 }
401 for(index = 0; index < nPar; index++){
402 Double_t err ;
403 Double_t val ;
404 gMinuit->GetParameter(index, val, err) ; // Returns value and error of parameter index
405 fitparameters[index] = val ;
406 }
407
408 delete toMinuit ;
409 return kTRUE;
c3c187e5 410
d15a28e7 411}
412
3758d9fc 413//____________________________________________________________________________
414void AliPHOSClusterizerv1::GetCalibrationParameters()
415{
5c149aeb 416 // Set calibration parameters:
eaa5012b 417 // if calibration database exists, they are read from database,
418 // otherwise, they are taken from digitizer.
5c149aeb 419 //
ef629623 420 // It is a user responsilibity to open CDB before reconstruction, for example:
421 // AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage("local://CalibDB");
fbf811ec 422
88cb7938 423 AliPHOSGetter * gime = AliPHOSGetter::Instance();
28871337 424 // fCalibData = new AliPHOSCalibData(gAlice->GetRunNumber()); //original
425
426 fCalibData = new AliPHOSCalibData(-1); //use AliCDBManager's run number
9e1ceb13 427
eaa5012b 428 if(!fCalibData)
429 {
430 if ( !gime->Digitizer() )
431 gime->LoadDigitizer();
432 AliPHOSDigitizer * dig = gime->Digitizer();
433 fADCchanelEmc = dig->GetEMCchannel() ;
434 fADCpedestalEmc = dig->GetEMCpedestal();
ba898748 435
eaa5012b 436 fADCchanelCpv = dig->GetCPVchannel() ;
437 fADCpedestalCpv = dig->GetCPVpedestal() ;
438 }
3758d9fc 439}
548f0134 440
d15a28e7 441//____________________________________________________________________________
a4e98857 442void AliPHOSClusterizerv1::Init()
443{
2bd5457f 444 // Make all memory allocations which can not be done in default constructor.
445 // Attach the Clusterizer task to the list of PHOS tasks
ba898748 446
447 AliPHOSGetter* gime = AliPHOSGetter::Instance() ;
448 if(!gime)
449 gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName.Data());
fbf811ec 450
88cb7938 451 AliPHOSGeometry * geom = gime->PHOSGeometry();
ba898748 452
3758d9fc 453 fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ;
454
7b7c1533 455 if(!gMinuit)
88cb7938 456 gMinuit = new TMinuit(100);
fbf811ec 457
ba898748 458 if ( !gime->Clusterizer() ) {
88cb7938 459 gime->PostClusterizer(this);
ba898748 460 }
9a1398dd 461}
7b7c1533 462
8d0f3f77 463//____________________________________________________________________________
464void AliPHOSClusterizerv1::InitParameters()
465{
466
467 fNumberOfCpvClusters = 0 ;
468 fNumberOfEmcClusters = 0 ;
469
470 fCpvClusteringThreshold = 0.0;
471 fEmcClusteringThreshold = 0.2;
472
473 fEmcLocMaxCut = 0.03 ;
474 fCpvLocMaxCut = 0.03 ;
ba898748 475
476 fEmcMinE = 0.01 ;
477 fCpvMinE = 0.0 ;
478
8d0f3f77 479 fW0 = 4.5 ;
480 fW0CPV = 4.0 ;
481
482 fEmcTimeGate = 1.e-8 ;
483
484 fToUnfold = kTRUE ;
88cb7938 485
8d0f3f77 486 fRecPointsInRun = 0 ;
c2cd5471 487
ba898748 488 fWrite = kTRUE ;
489
44ae287e 490 fCalibData = 0 ;
ae911977 491
eabde521 492 SetEventRange(0,-1) ;
f5eaa851 493
494 fIsOldRCUFormat = kFALSE;
8d0f3f77 495}
496
9a1398dd 497//____________________________________________________________________________
498Int_t AliPHOSClusterizerv1::AreNeighbours(AliPHOSDigit * d1, AliPHOSDigit * d2)const
d15a28e7 499{
b2a60966 500 // Gives the neighbourness of two digits = 0 are not neighbour but continue searching
501 // = 1 are neighbour
502 // = 2 are not neighbour but do not continue searching
a4e98857 503 // neighbours are defined as digits having at least a common vertex
b2a60966 504 // The order of d1 and d2 is important: first (d1) should be a digit already in a cluster
505 // which is compared to a digit (d2) not yet in a cluster
506
88cb7938 507 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
7b7c1533 508
d15a28e7 509 Int_t rv = 0 ;
510
d15a28e7 511 Int_t relid1[4] ;
7b7c1533 512 geom->AbsToRelNumbering(d1->GetId(), relid1) ;
d15a28e7 513
514 Int_t relid2[4] ;
7b7c1533 515 geom->AbsToRelNumbering(d2->GetId(), relid2) ;
d15a28e7 516
9688c1dd 517 if ( (relid1[0] == relid2[0]) && (relid1[1]==relid2[1]) ) { // inside the same PHOS module
92862013 518 Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;
519 Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;
d15a28e7 520
92862013 521 if (( coldiff <= 1 ) && ( rowdiff <= 1 )){
9688c1dd 522 if((relid1[1] != 0) || (TMath::Abs(d1->GetTime() - d2->GetTime() ) < fEmcTimeGate))
d15a28e7 523 rv = 1 ;
524 }
525 else {
526 if((relid2[2] > relid1[2]) && (relid2[3] > relid1[3]+1))
88cb7938 527 rv = 2; // Difference in row numbers is too large to look further
d15a28e7 528 }
529
530 }
531 else {
532
9688c1dd 533 if( (relid1[0] < relid2[0]) || (relid1[1] != relid2[1]) )
d15a28e7 534 rv=2 ;
535
536 }
d72dfbc3 537
d15a28e7 538 return rv ;
539}
ba898748 540//____________________________________________________________________________
e95226ae 541void AliPHOSClusterizerv1::CleanDigits(TClonesArray * digits)
542{
543 // Remove digits with amplitudes below threshold
544
ba898748 545 for(Int_t i=0; i<digits->GetEntriesFast(); i++){
546 AliPHOSDigit * digit = static_cast<AliPHOSDigit*>(digits->At(i)) ;
e95226ae 547 if ( (IsInEmc(digit) && CalibrateEMC(digit->GetEnergy(),digit->GetId()) < fEmcMinE) ||
548 (IsInCpv(digit) && CalibrateCPV(digit->GetAmp() ,digit->GetId()) < fCpvMinE) )
ba898748 549 digits->RemoveAt(i) ;
550 }
551 digits->Compress() ;
552 for (Int_t i = 0 ; i < digits->GetEntriesFast() ; i++) {
553 AliPHOSDigit *digit = static_cast<AliPHOSDigit*>( digits->At(i) ) ;
554 digit->SetIndexInList(i) ;
555 }
d15a28e7 556
ba898748 557}
d15a28e7 558//____________________________________________________________________________
9a1398dd 559Bool_t AliPHOSClusterizerv1::IsInEmc(AliPHOSDigit * digit) const
d15a28e7 560{
b2a60966 561 // Tells if (true) or not (false) the digit is in a PHOS-EMC module
562
9f616d61 563 Bool_t rv = kFALSE ;
88cb7938 564 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
d15a28e7 565
2b629790 566 Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
d15a28e7 567
2b629790 568 if(digit->GetId() <= nEMC ) rv = kTRUE;
ed4205d8 569
570 return rv ;
571}
572
ed4205d8 573//____________________________________________________________________________
9a1398dd 574Bool_t AliPHOSClusterizerv1::IsInCpv(AliPHOSDigit * digit) const
ed4205d8 575{
fad3e5b9 576 // Tells if (true) or not (false) the digit is in a PHOS-CPV module
ed4205d8 577
578 Bool_t rv = kFALSE ;
88cb7938 579
580 AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
ed4205d8 581
2b629790 582 Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ();
ed4205d8 583
2b629790 584 if(digit->GetId() > nEMC ) rv = kTRUE;
d15a28e7 585
586 return rv ;
587}
9a1398dd 588
589//____________________________________________________________________________
88cb7938 590void AliPHOSClusterizerv1::Unload()
591{
592 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
593 gime->PhosLoader()->UnloadDigits() ;
594 gime->PhosLoader()->UnloadRecPoints() ;
595}
596
597//____________________________________________________________________________
598void AliPHOSClusterizerv1::WriteRecPoints()
a4e98857 599{
7b7c1533 600
601 // Creates new branches with given title
a4e98857 602 // fills and writes into TreeR.
88cb7938 603
604 AliPHOSGetter * gime = AliPHOSGetter::Instance();
605
fbf811ec 606 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
607 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
608 TClonesArray * digits = gime->Digits() ;
ba898748 609
610
9a1398dd 611 Int_t index ;
ba898748 612 //Evaluate position, dispersion and other RecPoint properties..
613 Int_t nEmc = emcRecPoints->GetEntriesFast();
614 for(index = 0; index < nEmc; index++){
615 AliPHOSEmcRecPoint * rp = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) );
616 rp->Purify(fEmcMinE) ;
617 if(rp->GetMultiplicity()>0.) //If this RP is not empty
618 rp->EvalAll(fW0,digits) ;
619 else{
620 emcRecPoints->RemoveAt(index) ;
621 delete rp ;
622 }
623 }
624 emcRecPoints->Compress() ;
7b7c1533 625 emcRecPoints->Sort() ;
ba898748 626 // emcRecPoints->Expand(emcRecPoints->GetEntriesFast()) ;
627 for(index = 0; index < emcRecPoints->GetEntries(); index++){
88cb7938 628 dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) )->SetIndexInList(index) ;
ba898748 629 }
fbf811ec 630
9a1398dd 631 //Now the same for CPV
ba898748 632 for(index = 0; index < cpvRecPoints->GetEntries(); index++){
633 AliPHOSCpvRecPoint * rp = dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(index) );
634 rp->EvalAll(fW0CPV,digits) ;
635 }
7b7c1533 636 cpvRecPoints->Sort() ;
fbf811ec 637
7b7c1533 638 for(index = 0; index < cpvRecPoints->GetEntries(); index++)
2bb500e5 639 dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(index) )->SetIndexInList(index) ;
fbf811ec 640
7b7c1533 641 cpvRecPoints->Expand(cpvRecPoints->GetEntriesFast()) ;
9a1398dd 642
ba898748 643 if(fWrite){ //We write TreeR
644 TTree * treeR = gime->TreeR();
9a1398dd 645
ba898748 646 Int_t bufferSize = 32000 ;
647 Int_t splitlevel = 0 ;
9a1398dd 648
ba898748 649 //First EMC
650 TBranch * emcBranch = treeR->Branch("PHOSEmcRP","TObjArray",&emcRecPoints,bufferSize,splitlevel);
651 emcBranch->SetTitle(BranchName());
652
653 //Now CPV branch
654 TBranch * cpvBranch = treeR->Branch("PHOSCpvRP","TObjArray",&cpvRecPoints,bufferSize,splitlevel);
655 cpvBranch->SetTitle(BranchName());
656
657 emcBranch ->Fill() ;
658 cpvBranch ->Fill() ;
659
660 gime->WriteRecPoints("OVERWRITE");
661 gime->WriteClusterizer("OVERWRITE");
662 }
9a1398dd 663}
664
665//____________________________________________________________________________
666void AliPHOSClusterizerv1::MakeClusters()
667{
668 // Steering method to construct the clusters stored in a list of Reconstructed Points
669 // A cluster is defined as a list of neighbour digits
d15a28e7 670
88cb7938 671
672 AliPHOSGetter * gime = AliPHOSGetter::Instance();
673
674 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
675 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
7b7c1533 676
7d493c2c 677 emcRecPoints->Delete() ;
678 cpvRecPoints->Delete() ;
7b7c1533 679
fbf811ec 680 TClonesArray * digits = gime->Digits() ;
88cb7938 681
ba898748 682 //Remove digits below threshold
683 CleanDigits(digits) ;
684
88cb7938 685 TClonesArray * digitsC = static_cast<TClonesArray*>( digits->Clone() ) ;
7b7c1533 686
d15a28e7 687 // Clusterization starts
9a1398dd 688
7b7c1533 689 TIter nextdigit(digitsC) ;
d15a28e7 690 AliPHOSDigit * digit ;
92862013 691 Bool_t notremoved = kTRUE ;
6ad0bfa0 692
88cb7938 693 while ( (digit = dynamic_cast<AliPHOSDigit *>( nextdigit()) ) ) { // scan over the list of digitsC
694
695
9a1398dd 696 AliPHOSRecPoint * clu = 0 ;
c161df70 697
d1de15f5 698 TArrayI clusterdigitslist(1500) ;
d15a28e7 699 Int_t index ;
f2bc1b87 700
e95226ae 701 if (( IsInEmc (digit) &&
702 CalibrateEMC(digit->GetEnergy(),digit->GetId()) > fEmcClusteringThreshold ) ||
703 ( IsInCpv (digit) &&
704 CalibrateCPV(digit->GetAmp() ,digit->GetId()) > fCpvClusteringThreshold ) ) {
d15a28e7 705 Int_t iDigitInCluster = 0 ;
7b7c1533 706
6ad0bfa0 707 if ( IsInEmc(digit) ) {
88cb7938 708 // start a new EMC RecPoint
709 if(fNumberOfEmcClusters >= emcRecPoints->GetSize())
710 emcRecPoints->Expand(2*fNumberOfEmcClusters+1) ;
711
712 emcRecPoints->AddAt(new AliPHOSEmcRecPoint(""), fNumberOfEmcClusters) ;
713 clu = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(fNumberOfEmcClusters) ) ;
e95226ae 714 fNumberOfEmcClusters++ ;
715 clu->AddDigit(*digit, CalibrateEMC(digit->GetEnergy(),digit->GetId())) ;
716 clusterdigitslist[iDigitInCluster] = digit->GetIndexInList() ;
717 iDigitInCluster++ ;
88cb7938 718 digitsC->Remove(digit) ;
ca77b032 719
d72dfbc3 720 } else {
88cb7938 721
722 // start a new CPV cluster
723 if(fNumberOfCpvClusters >= cpvRecPoints->GetSize())
724 cpvRecPoints->Expand(2*fNumberOfCpvClusters+1);
725
726 cpvRecPoints->AddAt(new AliPHOSCpvRecPoint(""), fNumberOfCpvClusters) ;
727
728 clu = dynamic_cast<AliPHOSCpvRecPoint *>( cpvRecPoints->At(fNumberOfCpvClusters) ) ;
729 fNumberOfCpvClusters++ ;
e95226ae 730 clu->AddDigit(*digit, CalibrateCPV(digit->GetAmp(),digit->GetId()) ) ;
88cb7938 731 clusterdigitslist[iDigitInCluster] = digit->GetIndexInList() ;
732 iDigitInCluster++ ;
733 digitsC->Remove(digit) ;
d15a28e7 734 nextdigit.Reset() ;
88cb7938 735
736 // Here we remove remaining EMC digits, which cannot make a cluster
737
92862013 738 if( notremoved ) {
88cb7938 739 while( ( digit = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) {
9f616d61 740 if( IsInEmc(digit) )
88cb7938 741 digitsC->Remove(digit) ;
d15a28e7 742 else
88cb7938 743 break ;
744 }
745 notremoved = kFALSE ;
746 }
747
d15a28e7 748 } // else
749
750 nextdigit.Reset() ;
fad3e5b9 751
d15a28e7 752 AliPHOSDigit * digitN ;
753 index = 0 ;
9f616d61 754 while (index < iDigitInCluster){ // scan over digits already in cluster
88cb7938 755 digit = dynamic_cast<AliPHOSDigit*>( digits->At(clusterdigitslist[index]) ) ;
756 index++ ;
757 while ( (digitN = dynamic_cast<AliPHOSDigit *>( nextdigit() ) ) ) { // scan over the reduced list of digits
758 Int_t ineb = AreNeighbours(digit, digitN); // call (digit,digitN) in THAT oder !!!!!
d15a28e7 759 switch (ineb ) {
9f616d61 760 case 0 : // not a neighbour
88cb7938 761 break ;
762 case 1 : // are neighbours
e95226ae 763 if (IsInEmc (digitN))
764 clu->AddDigit(*digitN, CalibrateEMC( digitN->GetEnergy(), digitN->GetId() ) );
765 else
766 clu->AddDigit(*digitN, CalibrateCPV( digitN->GetAmp() , digitN->GetId() ) );
767
88cb7938 768 clusterdigitslist[iDigitInCluster] = digitN->GetIndexInList() ;
769 iDigitInCluster++ ;
770 digitsC->Remove(digitN) ;
771 break ;
9f616d61 772 case 2 : // too far from each other
88cb7938 773 goto endofloop;
774 } // switch
775
776 } // while digitN
777
d15a28e7 778 endofloop: ;
88cb7938 779 nextdigit.Reset() ;
780
d15a28e7 781 } // loop over cluster
ad8cfaf4 782
ad8cfaf4 783 } // energy theshold
ad8cfaf4 784
31aa6d6c 785
d15a28e7 786 } // while digit
787
7b7c1533 788 delete digitsC ;
9688c1dd 789
9a1398dd 790}
791
792//____________________________________________________________________________
a4e98857 793void AliPHOSClusterizerv1::MakeUnfolding()
794{
795 // Unfolds clusters using the shape of an ElectroMagnetic shower
9688c1dd 796 // Performs unfolding of all EMC/CPV clusters
9a1398dd 797
88cb7938 798 AliPHOSGetter * gime = AliPHOSGetter::Instance();
fc12304f 799
7b7c1533 800 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
88cb7938 801
802 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
803 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
fbf811ec 804 TClonesArray * digits = gime->Digits() ;
7b7c1533 805
a4e98857 806 // Unfold first EMC clusters
9a1398dd 807 if(fNumberOfEmcClusters > 0){
808
7b7c1533 809 Int_t nModulesToUnfold = geom->GetNModules() ;
9a1398dd 810
811 Int_t numberofNotUnfolded = fNumberOfEmcClusters ;
812 Int_t index ;
813 for(index = 0 ; index < numberofNotUnfolded ; index++){
814
88cb7938 815 AliPHOSEmcRecPoint * emcRecPoint = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(index) ) ;
9a1398dd 816 if(emcRecPoint->GetPHOSMod()> nModulesToUnfold)
88cb7938 817 break ;
9a1398dd 818
819 Int_t nMultipl = emcRecPoint->GetMultiplicity() ;
a0636361 820 AliPHOSDigit ** maxAt = new AliPHOSDigit*[nMultipl] ;
9a1398dd 821 Float_t * maxAtEnergy = new Float_t[nMultipl] ;
7b7c1533 822 Int_t nMax = emcRecPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy,fEmcLocMaxCut,digits) ;
9a1398dd 823
824 if( nMax > 1 ) { // if cluster is very flat (no pronounced maximum) then nMax = 0
88cb7938 825 UnfoldCluster(emcRecPoint, nMax, maxAt, maxAtEnergy) ;
826 emcRecPoints->Remove(emcRecPoint);
827 emcRecPoints->Compress() ;
828 index-- ;
829 fNumberOfEmcClusters -- ;
830 numberofNotUnfolded-- ;
9a1398dd 831 }
c6bf27f2 832 else{
833 emcRecPoint->SetNExMax(1) ; //Only one local maximum
834 }
9a1398dd 835
836 delete[] maxAt ;
837 delete[] maxAtEnergy ;
838 }
839 }
a4e98857 840 // Unfolding of EMC clusters finished
9a1398dd 841
842
a4e98857 843 // Unfold now CPV clusters
9a1398dd 844 if(fNumberOfCpvClusters > 0){
845
9688c1dd 846 Int_t nModulesToUnfold = geom->GetNModules() ;
9a1398dd 847
848 Int_t numberofCpvNotUnfolded = fNumberOfCpvClusters ;
849 Int_t index ;
850 for(index = 0 ; index < numberofCpvNotUnfolded ; index++){
851
88cb7938 852 AliPHOSRecPoint * recPoint = dynamic_cast<AliPHOSRecPoint *>( cpvRecPoints->At(index) ) ;
9a1398dd 853
854 if(recPoint->GetPHOSMod()> nModulesToUnfold)
88cb7938 855 break ;
9a1398dd 856
88cb7938 857 AliPHOSEmcRecPoint * emcRecPoint = dynamic_cast<AliPHOSEmcRecPoint*>(recPoint) ;
9a1398dd 858
859 Int_t nMultipl = emcRecPoint->GetMultiplicity() ;
a0636361 860 AliPHOSDigit ** maxAt = new AliPHOSDigit*[nMultipl] ;
9a1398dd 861 Float_t * maxAtEnergy = new Float_t[nMultipl] ;
7b7c1533 862 Int_t nMax = emcRecPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy,fCpvLocMaxCut,digits) ;
9a1398dd 863
864 if( nMax > 1 ) { // if cluster is very flat (no pronounced maximum) then nMax = 0
88cb7938 865 UnfoldCluster(emcRecPoint, nMax, maxAt, maxAtEnergy) ;
866 cpvRecPoints->Remove(emcRecPoint);
867 cpvRecPoints->Compress() ;
868 index-- ;
869 numberofCpvNotUnfolded-- ;
870 fNumberOfCpvClusters-- ;
9a1398dd 871 }
872
873 delete[] maxAt ;
874 delete[] maxAtEnergy ;
875 }
876 }
877 //Unfolding of Cpv clusters finished
878
879}
880
9a1398dd 881//____________________________________________________________________________
882Double_t AliPHOSClusterizerv1::ShowerShape(Double_t r)
883{
884 // Shape of the shower (see PHOS TDR)
a4e98857 885 // If you change this function, change also the gradient evaluation in ChiSquare()
9a1398dd 886
887 Double_t r4 = r*r*r*r ;
888 Double_t r295 = TMath::Power(r, 2.95) ;
889 Double_t shape = TMath::Exp( -r4 * (1. / (2.32 + 0.26 * r4) + 0.0316 / (1 + 0.0652 * r295) ) ) ;
890 return shape ;
891}
892
893//____________________________________________________________________________
894void AliPHOSClusterizerv1::UnfoldCluster(AliPHOSEmcRecPoint * iniEmc,
88cb7938 895 Int_t nMax,
896 AliPHOSDigit ** maxAt,
897 Float_t * maxAtEnergy)
9a1398dd 898{
899 // Performs the unfolding of a cluster with nMax overlapping showers
900
88cb7938 901 AliPHOSGetter * gime = AliPHOSGetter::Instance();
fc12304f 902
7b7c1533 903 const AliPHOSGeometry * geom = gime->PHOSGeometry() ;
88cb7938 904
fbf811ec 905 const TClonesArray * digits = gime->Digits() ;
906 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
907 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
7b7c1533 908
9a1398dd 909 Int_t nPar = 3 * nMax ;
910 Float_t * fitparameters = new Float_t[nPar] ;
911
912 Bool_t rv = FindFit(iniEmc, maxAt, maxAtEnergy, nPar, fitparameters) ;
913 if( !rv ) {
88cb7938 914 // Fit failed, return and remove cluster
c6bf27f2 915 iniEmc->SetNExMax(-1) ;
9a1398dd 916 delete[] fitparameters ;
917 return ;
918 }
919
920 // create ufolded rec points and fill them with new energy lists
921 // First calculate energy deposited in each sell in accordance with fit (without fluctuations): efit[]
922 // and later correct this number in acordance with actual energy deposition
923
924 Int_t nDigits = iniEmc->GetMultiplicity() ;
925 Float_t * efit = new Float_t[nDigits] ;
7b7c1533 926 Float_t xDigit=0.,zDigit=0.,distance=0. ;
927 Float_t xpar=0.,zpar=0.,epar=0. ;
9a1398dd 928 Int_t relid[4] ;
7b7c1533 929 AliPHOSDigit * digit = 0 ;
9a1398dd 930 Int_t * emcDigits = iniEmc->GetDigitsList() ;
931
932 Int_t iparam ;
933 Int_t iDigit ;
934 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
88cb7938 935 digit = dynamic_cast<AliPHOSDigit*>( digits->At(emcDigits[iDigit] ) ) ;
7b7c1533 936 geom->AbsToRelNumbering(digit->GetId(), relid) ;
937 geom->RelPosInModule(relid, xDigit, zDigit) ;
9a1398dd 938 efit[iDigit] = 0;
939
940 iparam = 0 ;
941 while(iparam < nPar ){
942 xpar = fitparameters[iparam] ;
943 zpar = fitparameters[iparam+1] ;
944 epar = fitparameters[iparam+2] ;
945 iparam += 3 ;
946 distance = (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) ;
947 distance = TMath::Sqrt(distance) ;
948 efit[iDigit] += epar * ShowerShape(distance) ;
949 }
950 }
951
952
953 // Now create new RecPoints and fill energy lists with efit corrected to fluctuations
954 // so that energy deposited in each cell is distributed betwin new clusters proportionally
955 // to its contribution to efit
956
957 Float_t * emcEnergies = iniEmc->GetEnergiesList() ;
958 Float_t ratio ;
959
960 iparam = 0 ;
961 while(iparam < nPar ){
962 xpar = fitparameters[iparam] ;
963 zpar = fitparameters[iparam+1] ;
964 epar = fitparameters[iparam+2] ;
965 iparam += 3 ;
966
7b7c1533 967 AliPHOSEmcRecPoint * emcRP = 0 ;
9a1398dd 968
969 if(iniEmc->IsEmc()){ //create new entries in fEmcRecPoints...
970
7b7c1533 971 if(fNumberOfEmcClusters >= emcRecPoints->GetSize())
88cb7938 972 emcRecPoints->Expand(2*fNumberOfEmcClusters) ;
9a1398dd 973
73a68ccb 974 (*emcRecPoints)[fNumberOfEmcClusters] = new AliPHOSEmcRecPoint("") ;
88cb7938 975 emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( emcRecPoints->At(fNumberOfEmcClusters) ) ;
9a1398dd 976 fNumberOfEmcClusters++ ;
c6bf27f2 977 emcRP->SetNExMax((Int_t)nPar/3) ;
9a1398dd 978 }
979 else{//create new entries in fCpvRecPoints
7b7c1533 980 if(fNumberOfCpvClusters >= cpvRecPoints->GetSize())
88cb7938 981 cpvRecPoints->Expand(2*fNumberOfCpvClusters) ;
9a1398dd 982
73a68ccb 983 (*cpvRecPoints)[fNumberOfCpvClusters] = new AliPHOSCpvRecPoint("") ;
88cb7938 984 emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( cpvRecPoints->At(fNumberOfCpvClusters) ) ;
9a1398dd 985 fNumberOfCpvClusters++ ;
986 }
987
988 Float_t eDigit ;
989 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
88cb7938 990 digit = dynamic_cast<AliPHOSDigit*>( digits->At( emcDigits[iDigit] ) ) ;
7b7c1533 991 geom->AbsToRelNumbering(digit->GetId(), relid) ;
992 geom->RelPosInModule(relid, xDigit, zDigit) ;
9a1398dd 993 distance = (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) ;
994 distance = TMath::Sqrt(distance) ;
995 ratio = epar * ShowerShape(distance) / efit[iDigit] ;
996 eDigit = emcEnergies[iDigit] * ratio ;
997 emcRP->AddDigit( *digit, eDigit ) ;
88cb7938 998 }
9a1398dd 999 }
1000
1001 delete[] fitparameters ;
1002 delete[] efit ;
1003
1004}
1005
1006//_____________________________________________________________________________
1007void AliPHOSClusterizerv1::UnfoldingChiSquare(Int_t & nPar, Double_t * Grad, Double_t & fret, Double_t * x, Int_t iflag)
1008{
a4e98857 1009 // Calculates the Chi square for the cluster unfolding minimization
9a1398dd 1010 // Number of parameters, Gradient, Chi squared, parameters, what to do
1011
88cb7938 1012 TList * toMinuit = dynamic_cast<TList*>( gMinuit->GetObjectFit() ) ;
9a1398dd 1013
88cb7938 1014 AliPHOSEmcRecPoint * emcRP = dynamic_cast<AliPHOSEmcRecPoint*>( toMinuit->At(0) ) ;
1015 TClonesArray * digits = dynamic_cast<TClonesArray*>( toMinuit->At(1) ) ;
9a1398dd 1016
1017
1018
88cb7938 1019 // AliPHOSEmcRecPoint * emcRP = dynamic_cast<AliPHOSEmcRecPoint *>( gMinuit->GetObjectFit() ) ; // EmcRecPoint to fit
9a1398dd 1020
1021 Int_t * emcDigits = emcRP->GetDigitsList() ;
1022
7b7c1533 1023 Int_t nOdigits = emcRP->GetDigitsMultiplicity() ;
9a1398dd 1024
1025 Float_t * emcEnergies = emcRP->GetEnergiesList() ;
88cb7938 1026
1027 const AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
9a1398dd 1028 fret = 0. ;
1029 Int_t iparam ;
1030
1031 if(iflag == 2)
1032 for(iparam = 0 ; iparam < nPar ; iparam++)
1033 Grad[iparam] = 0 ; // Will evaluate gradient
1034
1035 Double_t efit ;
1036
1037 AliPHOSDigit * digit ;
1038 Int_t iDigit ;
1039
7b7c1533 1040 for( iDigit = 0 ; iDigit < nOdigits ; iDigit++) {
9a1398dd 1041
88cb7938 1042 digit = dynamic_cast<AliPHOSDigit*>( digits->At( emcDigits[iDigit] ) );
9a1398dd 1043
1044 Int_t relid[4] ;
1045 Float_t xDigit ;
1046 Float_t zDigit ;
1047
1048 geom->AbsToRelNumbering(digit->GetId(), relid) ;
1049
1050 geom->RelPosInModule(relid, xDigit, zDigit) ;
1051
1052 if(iflag == 2){ // calculate gradient
1053 Int_t iParam = 0 ;
1054 efit = 0 ;
1055 while(iParam < nPar ){
88cb7938 1056 Double_t distance = (xDigit - x[iParam]) * (xDigit - x[iParam]) ;
1057 iParam++ ;
1058 distance += (zDigit - x[iParam]) * (zDigit - x[iParam]) ;
1059 distance = TMath::Sqrt( distance ) ;
1060 iParam++ ;
1061 efit += x[iParam] * ShowerShape(distance) ;
1062 iParam++ ;
9a1398dd 1063 }
88cb7938 1064 Double_t sum = 2. * (efit - emcEnergies[iDigit]) / emcEnergies[iDigit] ; // Here we assume, that sigma = sqrt(E)
9a1398dd 1065 iParam = 0 ;
1066 while(iParam < nPar ){
88cb7938 1067 Double_t xpar = x[iParam] ;
1068 Double_t zpar = x[iParam+1] ;
1069 Double_t epar = x[iParam+2] ;
1070 Double_t dr = TMath::Sqrt( (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) );
1071 Double_t shape = sum * ShowerShape(dr) ;
1072 Double_t r4 = dr*dr*dr*dr ;
1073 Double_t r295 = TMath::Power(dr,2.95) ;
1074 Double_t deriv =-4. * dr*dr * ( 2.32 / ( (2.32 + 0.26 * r4) * (2.32 + 0.26 * r4) ) +
1075 0.0316 * (1. + 0.0171 * r295) / ( ( 1. + 0.0652 * r295) * (1. + 0.0652 * r295) ) ) ;
1076
1077 Grad[iParam] += epar * shape * deriv * (xpar - xDigit) ; // Derivative over x
1078 iParam++ ;
1079 Grad[iParam] += epar * shape * deriv * (zpar - zDigit) ; // Derivative over z
1080 iParam++ ;
1081 Grad[iParam] += shape ; // Derivative over energy
1082 iParam++ ;
9a1398dd 1083 }
1084 }
1085 efit = 0;
1086 iparam = 0 ;
1087
1088 while(iparam < nPar ){
1089 Double_t xpar = x[iparam] ;
1090 Double_t zpar = x[iparam+1] ;
1091 Double_t epar = x[iparam+2] ;
1092 iparam += 3 ;
1093 Double_t distance = (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) ;
1094 distance = TMath::Sqrt(distance) ;
1095 efit += epar * ShowerShape(distance) ;
1096 }
1097
88cb7938 1098 fret += (efit-emcEnergies[iDigit])*(efit-emcEnergies[iDigit])/emcEnergies[iDigit] ;
9a1398dd 1099 // Here we assume, that sigma = sqrt(E)
1100 }
83974468 1101
d15a28e7 1102}
1103
1104//____________________________________________________________________________
702ab87e 1105void AliPHOSClusterizerv1::Print(const Option_t *)const
d15a28e7 1106{
d1de15f5 1107 // Print clusterizer parameters
1108
21cd0c07 1109 TString message ;
1110 TString taskName(GetName()) ;
1111 taskName.ReplaceAll(Version(), "") ;
1112
1113 if( strcmp(GetName(), "") !=0 ) {
9a1398dd 1114 // Print parameters
21cd0c07 1115 message = "\n--------------- %s %s -----------\n" ;
1116 message += "Clusterizing digits from the file: %s\n" ;
1117 message += " Branch: %s\n" ;
1118 message += " EMC Clustering threshold = %f\n" ;
1119 message += " EMC Local Maximum cut = %f\n" ;
1120 message += " EMC Logarothmic weight = %f\n" ;
1121 message += " CPV Clustering threshold = %f\n" ;
1122 message += " CPV Local Maximum cut = %f\n" ;
1123 message += " CPV Logarothmic weight = %f\n" ;
9a1398dd 1124 if(fToUnfold)
21cd0c07 1125 message += " Unfolding on\n" ;
9a1398dd 1126 else
21cd0c07 1127 message += " Unfolding off\n" ;
9a1398dd 1128
21cd0c07 1129 message += "------------------------------------------------------------------" ;
9a1398dd 1130 }
21cd0c07 1131 else
1132 message = " AliPHOSClusterizerv1 not initialized " ;
1133
351dd634 1134 AliInfo(Form("%s, %s %s %s %s %s %s %s %s %s %s", message.Data(),
21cd0c07 1135 taskName.Data(),
1136 GetTitle(),
1137 taskName.Data(),
1138 GetName(),
1139 fEmcClusteringThreshold,
1140 fEmcLocMaxCut,
1141 fW0,
1142 fCpvClusteringThreshold,
1143 fCpvLocMaxCut,
351dd634 1144 fW0CPV )) ;
9a1398dd 1145}
21cd0c07 1146
1147
9a1398dd 1148//____________________________________________________________________________
a4e98857 1149void AliPHOSClusterizerv1::PrintRecPoints(Option_t * option)
1150{
1151 // Prints list of RecPoints produced at the current pass of AliPHOSClusterizer
9a1398dd 1152
88cb7938 1153 AliPHOSGetter * gime = AliPHOSGetter::Instance();
1154
1155 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
1156 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
7b7c1533 1157
351dd634 1158 AliInfo(Form("\nevent %d \n Found %d EMC RecPoints and %d CPV RecPoints",
1159 gAlice->GetEvNumber(),
1160 emcRecPoints->GetEntriesFast(),
1161 cpvRecPoints->GetEntriesFast() )) ;
88cb7938 1162
1163 fRecPointsInRun += emcRecPoints->GetEntriesFast() ;
1164 fRecPointsInRun += cpvRecPoints->GetEntriesFast() ;
1165
11f9c5ff 1166
9a1398dd 1167 if(strstr(option,"all")) {
709e117a 1168 printf("\n EMC clusters \n") ;
1169 printf("Index Ene(MeV) Multi Module X Y Z Lambdas_1 Lambda_2 # of prim Primaries list\n") ;
9a1398dd 1170 Int_t index ;
7b7c1533 1171 for (index = 0 ; index < emcRecPoints->GetEntries() ; index++) {
1172 AliPHOSEmcRecPoint * rp = (AliPHOSEmcRecPoint * )emcRecPoints->At(index) ;
9a1398dd 1173 TVector3 locpos;
1174 rp->GetLocalPosition(locpos);
9a1398dd 1175 Float_t lambda[2];
1176 rp->GetElipsAxis(lambda);
9a1398dd 1177 Int_t * primaries;
1178 Int_t nprimaries;
1179 primaries = rp->GetPrimaries(nprimaries);
709e117a 1180 printf("\n%6d %8.2f %3d %2d %4.1f %4.1f %4.1f %4f %4f %2d : ",
11f9c5ff 1181 rp->GetIndexInList(), rp->GetEnergy(), rp->GetMultiplicity(), rp->GetPHOSMod(),
1182 locpos.X(), locpos.Y(), locpos.Z(), lambda[0], lambda[1], nprimaries) ;
3bf72d32 1183
21cd0c07 1184 for (Int_t iprimary=0; iprimary<nprimaries; iprimary++) {
709e117a 1185 printf("%d ", primaries[iprimary] ) ;
21cd0c07 1186 }
709e117a 1187 printf("\n") ;
1188 }
1189
1190 //Now plot CPV recPoints
1191 printf("\n CPV clusters \n") ;
1192 printf("Index Ene(MeV) Module X Y Z \n") ;
1193 for (index = 0 ; index < cpvRecPoints->GetEntries() ; index++) {
2bb500e5 1194 AliPHOSCpvRecPoint * rp = (AliPHOSCpvRecPoint * )cpvRecPoints->At(index) ;
1195
1196 TVector3 locpos;
1197 rp->GetLocalPosition(locpos);
1198
1199 printf("\n%6d %8.2f %2d %4.1f %4.1f %4.1f \n",
1200 rp->GetIndexInList(), rp->GetEnergy(), rp->GetPHOSMod(),
1201 locpos.X(), locpos.Y(), locpos.Z()) ;
88cb7938 1202 }
9a1398dd 1203 }
d15a28e7 1204}
9a1398dd 1205