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