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