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