]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PHOS/AliPHOSEmcRecPoint.cxx
New class AliPHOSCpvPreprocessor.
[u/mrichter/AliRoot.git] / PHOS / AliPHOSEmcRecPoint.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$
25779c68 21 * Revision 1.59 2007/10/18 15:12:22 kharlov
22 * Moved MakePrimary to EMCRecPoint to rpduce correct order of primaries
23 *
c307c629 24 * Revision 1.58 2007/04/16 09:03:37 kharlov
25 * Incedent angle correction fixed
26 *
753b19cd 27 * Revision 1.57 2007/04/05 10:18:58 policheh
28 * Introduced distance to nearest bad crystal.
29 *
dce76bbb 30 * Revision 1.56 2007/03/06 06:47:28 kharlov
31 * DP:Possibility to use actual vertex position added
32 *
91daaf24 33 * Revision 1.55 2007/01/19 20:31:19 kharlov
34 * Improved formatting for Print()
35 *
6f766ada 36 * Revision 1.54 2006/08/28 10:01:56 kharlov
37 * Effective C++ warnings fixed (Timur Pocheptsov)
38 *
3663622c 39 * Revision 1.53 2005/12/20 14:28:47 hristov
40 * Additional protection
41 *
f33a3764 42 * Revision 1.52 2005/05/28 14:19:04 schutz
43 * Compilation warnings fixed by T.P.
44 *
702ab87e 45 */
46
d15a28e7 47//_________________________________________________________________________
b2a60966 48// RecPoint implementation for PHOS-EMC
49// An EmcRecPoint is a cluster of digits
baef0810 50//*--
b2a60966 51//*-- Author: Dmitri Peressounko (RRC KI & SUBATECH)
52
d15a28e7 53
54// --- ROOT system ---
9f616d61 55#include "TH2.h"
d15a28e7 56#include "TMath.h"
9f616d61 57#include "TCanvas.h"
55fe9d13 58#include "TGraph.h"
d15a28e7 59
60// --- Standard library ---
61
d15a28e7 62// --- AliRoot header files ---
351dd634 63#include "AliLog.h"
e957fea8 64#include "AliPHOSLoader.h"
88cb7938 65#include "AliGenerator.h"
d15a28e7 66#include "AliPHOSGeometry.h"
e957fea8 67#include "AliPHOSDigit.h"
d15a28e7 68#include "AliPHOSEmcRecPoint.h"
e957fea8 69
d15a28e7 70ClassImp(AliPHOSEmcRecPoint)
71
72//____________________________________________________________________________
3663622c 73AliPHOSEmcRecPoint::AliPHOSEmcRecPoint() :
74 AliPHOSRecPoint(),
75 fCoreEnergy(0.), fDispersion(0.),
76 fEnergyList(0), fTime(-1.), fNExMax(0),
77 fM2x(0.), fM2z(0.), fM3x(0.), fM4z(0.),
dce76bbb 78 fPhixe(0.), fDistToBadCrystal(-1),fDebug(0)
d15a28e7 79{
80 // ctor
d15a28e7 81 fMulDigit = 0 ;
82 fAmp = 0. ;
a6eedfad 83 fLocPos.SetX(1000000.) ; //Local position should be evaluated
83974468 84}
85
73a68ccb 86//____________________________________________________________________________
3663622c 87AliPHOSEmcRecPoint::AliPHOSEmcRecPoint(const char * opt) :
88 AliPHOSRecPoint(opt),
89 fCoreEnergy(0.), fDispersion(0.),
90 fEnergyList(0), fTime(-1.), fNExMax(0),
91 fM2x(0.), fM2z(0.), fM3x(0.), fM4z(0.),
dce76bbb 92 fPhixe(0.), fDistToBadCrystal(-1), fDebug(0)
73a68ccb 93{
94 // ctor
73a68ccb 95 fMulDigit = 0 ;
96 fAmp = 0. ;
73a68ccb 97 fLocPos.SetX(1000000.) ; //Local position should be evaluated
73a68ccb 98}
99
55fe9d13 100//____________________________________________________________________________
3663622c 101AliPHOSEmcRecPoint::AliPHOSEmcRecPoint(const AliPHOSEmcRecPoint & rp) :
102 AliPHOSRecPoint(rp),
103 fCoreEnergy(rp.fCoreEnergy), fDispersion(rp.fDispersion),
104 fEnergyList(0), fTime(rp.fTime), fNExMax(rp.fNExMax),
105 fM2x(rp.fM2x), fM2z(rp.fM2z), fM3x(rp.fM3x), fM4z(rp.fM4z),
dce76bbb 106 fPhixe(rp.fPhixe), fDistToBadCrystal(rp.fDistToBadCrystal), fDebug(rp.fDebug)
55fe9d13 107{
108 // cpy ctor
55fe9d13 109 fMulDigit = rp.fMulDigit ;
110 fAmp = rp.fAmp ;
25779c68 111 if (rp.fMulDigit>0) fEnergyList = new Float_t[rp.fMulDigit] ;
112 for(Int_t index = 0 ; index < fMulDigit ; index++)
55fe9d13 113 fEnergyList[index] = rp.fEnergyList[index] ;
55fe9d13 114}
115
83974468 116//____________________________________________________________________________
117AliPHOSEmcRecPoint::~AliPHOSEmcRecPoint()
118{
88714635 119 // dtor
83974468 120 if ( fEnergyList )
121 delete[] fEnergyList ;
d15a28e7 122}
123
d15a28e7 124//____________________________________________________________________________
83974468 125void AliPHOSEmcRecPoint::AddDigit(AliPHOSDigit & digit, Float_t Energy)
d15a28e7 126{
b2a60966 127 // Adds a digit to the RecPoint
a4e98857 128 // and accumulates the total amplitude and the multiplicity
d15a28e7 129
7932f811 130 if(fEnergyList == 0)
131 fEnergyList = new Float_t[fMaxDigit];
132
d15a28e7 133 if ( fMulDigit >= fMaxDigit ) { // increase the size of the lists
9f616d61 134 fMaxDigit*=2 ;
0fbb8738 135 Int_t * tempo = new Int_t[fMaxDigit];
136 Float_t * tempoE = new Float_t[fMaxDigit];
9f616d61 137
138 Int_t index ;
d15a28e7 139 for ( index = 0 ; index < fMulDigit ; index++ ){
83974468 140 tempo[index] = fDigitsList[index] ;
d15a28e7 141 tempoE[index] = fEnergyList[index] ;
142 }
143
9f616d61 144 delete [] fDigitsList ;
0fbb8738 145 fDigitsList = new Int_t[fMaxDigit];
9f616d61 146
147 delete [] fEnergyList ;
0fbb8738 148 fEnergyList = new Float_t[fMaxDigit];
9f616d61 149
150 for ( index = 0 ; index < fMulDigit ; index++ ){
151 fDigitsList[index] = tempo[index] ;
152 fEnergyList[index] = tempoE[index] ;
153 }
154
155 delete [] tempo ;
156 delete [] tempoE ;
157 } // if
d15a28e7 158
83974468 159 fDigitsList[fMulDigit] = digit.GetIndexInList() ;
160 fEnergyList[fMulDigit] = Energy ;
161 fMulDigit++ ;
d15a28e7 162 fAmp += Energy ;
7932f811 163
164 EvalPHOSMod(&digit) ;
d15a28e7 165}
166
167//____________________________________________________________________________
ad8cfaf4 168Bool_t AliPHOSEmcRecPoint::AreNeighbours(AliPHOSDigit * digit1, AliPHOSDigit * digit2 ) const
d15a28e7 169{
a4e98857 170 // Tells if (true) or not (false) two digits are neighbors
d15a28e7 171
172 Bool_t aren = kFALSE ;
173
686b771f 174 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance() ;
7b7c1533 175
d15a28e7 176 Int_t relid1[4] ;
92862013 177 phosgeom->AbsToRelNumbering(digit1->GetId(), relid1) ;
d15a28e7 178
179 Int_t relid2[4] ;
92862013 180 phosgeom->AbsToRelNumbering(digit2->GetId(), relid2) ;
d15a28e7 181
92862013 182 Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;
183 Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;
d15a28e7 184
92862013 185 if (( coldiff <= 1 ) && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0))
d15a28e7 186 aren = kTRUE ;
187
188 return aren ;
189}
190
191//____________________________________________________________________________
2a941f4e 192Int_t AliPHOSEmcRecPoint::Compare(const TObject * obj) const
d15a28e7 193{
b2a60966 194 // Compares two RecPoints according to their position in the PHOS modules
686b771f 195
196 const Float_t delta = 1 ; //Width of "Sorting row". If you changibg this
7932f811 197 //value (what is senseless) change as vell delta in
198 //AliPHOSTrackSegmentMakerv* and other RecPoints...
d15a28e7 199 Int_t rv ;
200
201 AliPHOSEmcRecPoint * clu = (AliPHOSEmcRecPoint *)obj ;
202
203
ad8cfaf4 204 Int_t phosmod1 = GetPHOSMod() ;
92862013 205 Int_t phosmod2 = clu->GetPHOSMod() ;
d15a28e7 206
92862013 207 TVector3 locpos1;
7932f811 208 GetLocalPosition(locpos1) ;
92862013 209 TVector3 locpos2;
210 clu->GetLocalPosition(locpos2) ;
d15a28e7 211
92862013 212 if(phosmod1 == phosmod2 ) {
7932f811 213 Int_t rowdif = (Int_t)TMath::Ceil(locpos1.X()/delta)-(Int_t)TMath::Ceil(locpos2.X()/delta) ;
d15a28e7 214 if (rowdif> 0)
7932f811 215 rv = 1 ;
d15a28e7 216 else if(rowdif < 0)
7932f811 217 rv = -1 ;
92862013 218 else if(locpos1.Z()>locpos2.Z())
d15a28e7 219 rv = -1 ;
220 else
221 rv = 1 ;
222 }
223
224 else {
92862013 225 if(phosmod1 < phosmod2 )
d15a28e7 226 rv = -1 ;
227 else
228 rv = 1 ;
229 }
230
231 return rv ;
232}
9f616d61 233//______________________________________________________________________________
702ab87e 234void AliPHOSEmcRecPoint::ExecuteEvent(Int_t event, Int_t, Int_t) /*const*/
9f616d61 235{
9f616d61 236
9688c1dd 237 // Execute action corresponding to one event
238 // This member function is called when a AliPHOSRecPoint is clicked with the locator
239 //
240 // If Left button is clicked on AliPHOSRecPoint, the digits are switched on
241 // and switched off when the mouse button is released.
242
88cb7938 243
686b771f 244 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance();
83974468 245
9688c1dd 246 static TGraph * digitgraph = 0 ;
83974468 247
9688c1dd 248 if (!gPad->IsEditable()) return;
83974468 249
9688c1dd 250 TH2F * histo = 0 ;
251 TCanvas * histocanvas ;
252
88cb7938 253
254 //try to get run loader from default event folder
e191bb57 255 AliRunLoader* rn = AliRunLoader::GetRunLoader(AliConfig::GetDefaultEventFolderName());
88cb7938 256 if (rn == 0x0)
257 {
351dd634 258 AliError(Form("Cannot find Run Loader in Default Event Folder"));
88cb7938 259 return;
260 }
261 AliPHOSLoader* gime = dynamic_cast<AliPHOSLoader*>(rn->GetLoader("PHOSLoader"));
262 if (gime == 0x0)
263 {
351dd634 264 AliError(Form("Cannot find PHOS Loader from Run Loader"));
88cb7938 265 return;
266 }
267
268
afa51c4e 269 const TClonesArray * digits = gime->Digits() ;
9688c1dd 270
271 switch (event) {
83974468 272
9688c1dd 273 case kButton1Down: {
274 AliPHOSDigit * digit ;
275 Int_t iDigit;
276 Int_t relid[4] ;
83974468 277
9688c1dd 278 const Int_t kMulDigit = AliPHOSEmcRecPoint::GetDigitsMultiplicity() ;
279 Float_t * xi = new Float_t[kMulDigit] ;
280 Float_t * zi = new Float_t[kMulDigit] ;
83974468 281
9688c1dd 282 // create the histogram for the single cluster
283 // 1. gets histogram boundaries
284 Float_t ximax = -999. ;
285 Float_t zimax = -999. ;
286 Float_t ximin = 999. ;
287 Float_t zimin = 999. ;
83974468 288
9688c1dd 289 for(iDigit=0; iDigit<kMulDigit; iDigit++) {
290 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
291 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
292 phosgeom->RelPosInModule(relid, xi[iDigit], zi[iDigit]);
293 if ( xi[iDigit] > ximax )
294 ximax = xi[iDigit] ;
295 if ( xi[iDigit] < ximin )
296 ximin = xi[iDigit] ;
297 if ( zi[iDigit] > zimax )
298 zimax = zi[iDigit] ;
299 if ( zi[iDigit] < zimin )
300 zimin = zi[iDigit] ;
301 }
302 ximax += phosgeom->GetCrystalSize(0) / 2. ;
303 zimax += phosgeom->GetCrystalSize(2) / 2. ;
304 ximin -= phosgeom->GetCrystalSize(0) / 2. ;
305 zimin -= phosgeom->GetCrystalSize(2) / 2. ;
306 Int_t xdim = (int)( (ximax - ximin ) / phosgeom->GetCrystalSize(0) + 0.5 ) ;
307 Int_t zdim = (int)( (zimax - zimin ) / phosgeom->GetCrystalSize(2) + 0.5 ) ;
83974468 308
9688c1dd 309 // 2. gets the histogram title
83974468 310
9688c1dd 311 Text_t title[100] ;
312 sprintf(title,"Energy=%1.2f GeV ; Digits ; %d ", GetEnergy(), GetDigitsMultiplicity()) ;
83974468 313
9688c1dd 314 if (!histo) {
315 delete histo ;
316 histo = 0 ;
317 }
318 histo = new TH2F("cluster3D", title, xdim, ximin, ximax, zdim, zimin, zimax) ;
83974468 319
9688c1dd 320 Float_t x, z ;
321 for(iDigit=0; iDigit<kMulDigit; iDigit++) {
322 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
323 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
324 phosgeom->RelPosInModule(relid, x, z);
325 histo->Fill(x, z, fEnergyList[iDigit] ) ;
326 }
83974468 327
9688c1dd 328 if (!digitgraph) {
329 digitgraph = new TGraph(kMulDigit,xi,zi);
330 digitgraph-> SetMarkerStyle(5) ;
331 digitgraph-> SetMarkerSize(1.) ;
332 digitgraph-> SetMarkerColor(1) ;
333 digitgraph-> Paint("P") ;
334 }
83974468 335
9688c1dd 336 // Print() ;
337 histocanvas = new TCanvas("cluster", "a single cluster", 600, 500) ;
338 histocanvas->Draw() ;
339 histo->Draw("lego1") ;
83974468 340
9688c1dd 341 delete[] xi ;
342 delete[] zi ;
83974468 343
9688c1dd 344 break;
345 }
83974468 346
9688c1dd 347 case kButton1Up:
348 if (digitgraph) {
349 delete digitgraph ;
350 digitgraph = 0 ;
351 }
352 break;
9f616d61 353
9688c1dd 354 }
9f616d61 355}
356
d15a28e7 357//____________________________________________________________________________
91daaf24 358void AliPHOSEmcRecPoint::EvalDispersion(Float_t logWeight,TClonesArray * digits, TVector3 &vInc)
d15a28e7 359{
b2a60966 360 // Calculates the dispersion of the shower at the origine of the RecPoint
91daaf24 361 //DP: should we correct dispersion for non-perpendicular hit????????
362
e5b16749 363 Float_t d = 0. ;
364 Float_t wtot = 0. ;
d15a28e7 365
d084d50d 366 Float_t x = 0.;
367 Float_t z = 0.;
d15a28e7 368
369 AliPHOSDigit * digit ;
7b7c1533 370
686b771f 371 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance();
e5b16749 372
373 // Calculates the center of gravity in the local PHOS-module coordinates
374
d15a28e7 375 Int_t iDigit;
e5b16749 376
377 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
378 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
379 Int_t relid[4] ;
380 Float_t xi ;
381 Float_t zi ;
382 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
383 phosgeom->RelPosInModule(relid, xi, zi);
f33a3764 384 if (fAmp>0 && fEnergyList[iDigit]>0) {
385 Float_t w = TMath::Max( 0., logWeight + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ;
386 x += xi * w ;
387 z += zi * w ;
388 wtot += w ;
389 }
390 else
391 AliError(Form("Wrong energy %f and/or amplitude %f\n", fEnergyList[iDigit], fAmp));
e5b16749 392 }
f33a3764 393 if (wtot>0) {
394 x /= wtot ;
395 z /= wtot ;
396 }
397 else
398 AliError(Form("Wrong weight %f\n", wtot));
e5b16749 399
400
401// Calculates the dispersion in coordinates
402 wtot = 0.;
88714635 403 for(iDigit=0; iDigit < fMulDigit; iDigit++) {
7932f811 404 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
d15a28e7 405 Int_t relid[4] ;
406 Float_t xi ;
407 Float_t zi ;
92862013 408 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
409 phosgeom->RelPosInModule(relid, xi, zi);
f33a3764 410 if (fAmp>0 && fEnergyList[iDigit]>0) {
411 Float_t w = TMath::Max(0.,logWeight+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ;
412 d += w*((xi-x)*(xi-x) + (zi-z)*(zi-z) ) ;
413 wtot+=w ;
414 }
415 else
416 AliError(Form("Wrong energy %f and/or amplitude %f\n", fEnergyList[iDigit], fAmp));
d15a28e7 417 }
e5b16749 418
7932f811 419
f33a3764 420 if (wtot>0) {
421 d /= wtot ;
422 }
423 else
424 AliError(Form("Wrong weight %f\n", wtot));
d15a28e7 425
f33a3764 426 fDispersion = 0;
427 if (d>=0)
428 fDispersion = TMath::Sqrt(d) ;
91daaf24 429
c63c49e9 430
d15a28e7 431}
fad3e5b9 432//______________________________________________________________________________
e5b16749 433void AliPHOSEmcRecPoint::EvalCoreEnergy(Float_t logWeight, TClonesArray * digits)
fad3e5b9 434{
a4e98857 435 // This function calculates energy in the core,
436 // i.e. within a radius rad = 3cm around the center. Beyond this radius
437 // in accordance with shower profile the energy deposition
fad3e5b9 438 // should be less than 2%
91daaf24 439//DP: non-perpendicular incidence??????????????
fad3e5b9 440
fad3e5b9 441 Float_t coreRadius = 3 ;
442
e5b16749 443 Float_t x = 0 ;
444 Float_t z = 0 ;
fad3e5b9 445
446 AliPHOSDigit * digit ;
7b7c1533 447
686b771f 448 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance();
88cb7938 449
fad3e5b9 450 Int_t iDigit;
e5b16749 451
452// Calculates the center of gravity in the local PHOS-module coordinates
453 Float_t wtot = 0;
454 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
455 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
456 Int_t relid[4] ;
457 Float_t xi ;
458 Float_t zi ;
459 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
460 phosgeom->RelPosInModule(relid, xi, zi);
f33a3764 461 if (fAmp>0 && fEnergyList[iDigit]>0) {
462 Float_t w = TMath::Max( 0., logWeight + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ;
463 x += xi * w ;
464 z += zi * w ;
465 wtot += w ;
466 }
467 else
468 AliError(Form("Wrong energy %f and/or amplitude %f\n", fEnergyList[iDigit], fAmp));
e5b16749 469 }
f33a3764 470 if (wtot>0) {
471 x /= wtot ;
472 z /= wtot ;
473 }
474 else
475 AliError(Form("Wrong weight %f\n", wtot));
e5b16749 476
477
fad3e5b9 478 for(iDigit=0; iDigit < fMulDigit; iDigit++) {
7932f811 479 digit = (AliPHOSDigit *) ( digits->At(fDigitsList[iDigit]) ) ;
fad3e5b9 480 Int_t relid[4] ;
481 Float_t xi ;
482 Float_t zi ;
483 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
484 phosgeom->RelPosInModule(relid, xi, zi);
485 Float_t distance = TMath::Sqrt((xi-x)*(xi-x)+(zi-z)*(zi-z)) ;
486 if(distance < coreRadius)
7932f811 487 fCoreEnergy += fEnergyList[iDigit] ;
fad3e5b9 488 }
489
91daaf24 490
fad3e5b9 491}
d15a28e7 492
493//____________________________________________________________________________
91daaf24 494void AliPHOSEmcRecPoint::EvalElipsAxis(Float_t logWeight,TClonesArray * digits, TVector3 &vInc)
d15a28e7 495{
b2a60966 496 // Calculates the axis of the shower ellipsoid
83974468 497
e8dbb96e 498 Double_t wtot = 0. ;
499 Double_t x = 0.;
500 Double_t z = 0.;
501 Double_t dxx = 0.;
502 Double_t dzz = 0.;
503 Double_t dxz = 0.;
d15a28e7 504
505 AliPHOSDigit * digit ;
7b7c1533 506
686b771f 507 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance();
7b7c1533 508
d15a28e7 509 Int_t iDigit;
510
e5b16749 511
d15a28e7 512 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
7932f811 513 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
d15a28e7 514 Int_t relid[4] ;
515 Float_t xi ;
516 Float_t zi ;
92862013 517 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
518 phosgeom->RelPosInModule(relid, xi, zi);
f33a3764 519 if (fAmp>0 && fEnergyList[iDigit]>0) {
520 Double_t w = TMath::Max(0.,logWeight+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ;
521 dxx += w * xi * xi ;
522 x += w * xi ;
523 dzz += w * zi * zi ;
524 z += w * zi ;
525 dxz += w * xi * zi ;
526 wtot += w ;
527 }
528 else
529 AliError(Form("Wrong energy %f and/or amplitude %f\n", fEnergyList[iDigit], fAmp));
d15a28e7 530 }
f33a3764 531 if (wtot>0) {
532 dxx /= wtot ;
533 x /= wtot ;
534 dxx -= x * x ;
535 dzz /= wtot ;
536 z /= wtot ;
537 dzz -= z * z ;
538 dxz /= wtot ;
539 dxz -= x * z ;
d15a28e7 540
69183710 541// //Apply correction due to non-perpendicular incidence
542// Double_t CosX ;
543// Double_t CosZ ;
88cb7938 544// AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
7b7c1533 545// AliPHOSGeometry * phosgeom = (AliPHOSGeometry*)gime->PHOSGeometry();
91daaf24 546// Double_t DistanceToIP= (Double_t ) phosgeom->GetIPtoCrystalSurface() ;
69183710 547
548// CosX = DistanceToIP/TMath::Sqrt(DistanceToIP*DistanceToIP+x*x) ;
549// CosZ = DistanceToIP/TMath::Sqrt(DistanceToIP*DistanceToIP+z*z) ;
550
551// dxx = dxx/(CosX*CosX) ;
552// dzz = dzz/(CosZ*CosZ) ;
553// dxz = dxz/(CosX*CosZ) ;
554
555
f33a3764 556 fLambda[0] = 0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
557 if(fLambda[0] > 0)
558 fLambda[0] = TMath::Sqrt(fLambda[0]) ;
e8dbb96e 559
f33a3764 560 fLambda[1] = 0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
561 if(fLambda[1] > 0) //To avoid exception if numerical errors lead to negative lambda.
562 fLambda[1] = TMath::Sqrt(fLambda[1]) ;
563 else
564 fLambda[1]= 0. ;
565 }
566 else {
567 AliError(Form("Wrong weight %f\n", wtot));
568 fLambda[0]=fLambda[1]=0.;
569 }
d15a28e7 570}
571
ce2a9a95 572//____________________________________________________________________________
91daaf24 573void AliPHOSEmcRecPoint::EvalMoments(Float_t logWeight,TClonesArray * digits, TVector3 &vInc)
ce2a9a95 574{
575 // Calculate the shower moments in the eigen reference system
576 // M2x, M2z, M3x, M4z
577 // Calculate the angle between the shower position vector and the eigen vector
578
579 Double_t wtot = 0. ;
580 Double_t x = 0.;
581 Double_t z = 0.;
582 Double_t dxx = 0.;
583 Double_t dzz = 0.;
584 Double_t dxz = 0.;
585 Double_t lambda0=0, lambda1=0;
586
587 AliPHOSDigit * digit ;
588
686b771f 589 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance() ;
ce2a9a95 590
591 Int_t iDigit;
592
593 // 1) Find covariance matrix elements:
594 // || dxx dxz ||
595 // || dxz dzz ||
596
597 Float_t xi ;
598 Float_t zi ;
599 Int_t relid[4] ;
600 Double_t w;
601 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
602 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
603 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
604 phosgeom->RelPosInModule(relid, xi, zi);
f33a3764 605 if (fAmp>0 && fEnergyList[iDigit]>0) {
606 w = TMath::Max(0.,logWeight+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ;
607 x += w * xi ;
608 z += w * zi ;
609 dxx += w * xi * xi ;
610 dzz += w * zi * zi ;
611 dxz += w * xi * zi ;
612 wtot += w ;
613 }
614 else
615 AliError(Form("Wrong energy %f and/or amplitude %f\n", fEnergyList[iDigit], fAmp));
616
ce2a9a95 617 }
f33a3764 618 if (wtot>0) {
619 x /= wtot ;
620 z /= wtot ;
621 dxx /= wtot ;
622 dzz /= wtot ;
623 dxz /= wtot ;
624 dxx -= x * x ;
625 dzz -= z * z ;
626 dxz -= x * z ;
ce2a9a95 627
628 // 2) Find covariance matrix eigen values lambda0 and lambda1
629
f33a3764 630 lambda0 = 0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
631 lambda1 = 0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ) ;
632 }
633 else {
634 AliError(Form("Wrong weight %f\n", wtot));
635 lambda0=lambda1=0.;
636 }
ce2a9a95 637
638 // 3) Find covariance matrix eigen vectors e0 and e1
639
640 TVector2 e0,e1;
641 if (dxz != 0)
642 e0.Set(1.,(lambda0-dxx)/dxz);
643 else
644 e0.Set(0.,1.);
645
646 e0 = e0.Unit();
647 e1.Set(-e0.Y(),e0.X());
648
649 // 4) Rotate cluster tensor from (x,z) to (e0,e1) system
650 // and calculate moments M3x and M4z
651
652 Float_t cosPhi = e0.X();
653 Float_t sinPhi = e0.Y();
654
655 Float_t xiPHOS ;
656 Float_t ziPHOS ;
657 Double_t dx3, dz3, dz4;
658 wtot = 0.;
659 x = 0.;
660 z = 0.;
661 dxx = 0.;
662 dzz = 0.;
663 dxz = 0.;
664 dx3 = 0.;
665 dz3 = 0.;
666 dz4 = 0.;
667 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
668 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
669 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
670 phosgeom->RelPosInModule(relid, xiPHOS, ziPHOS);
671 xi = xiPHOS*cosPhi + ziPHOS*sinPhi;
672 zi = ziPHOS*cosPhi - xiPHOS*sinPhi;
f33a3764 673 if (fAmp>0 && fEnergyList[iDigit]>0) {
674 w = TMath::Max(0.,logWeight+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ;
675 x += w * xi ;
676 z += w * zi ;
677 dxx += w * xi * xi ;
678 dzz += w * zi * zi ;
679 dxz += w * xi * zi ;
680 dx3 += w * xi * xi * xi;
681 dz3 += w * zi * zi * zi ;
682 dz4 += w * zi * zi * zi * zi ;
683 wtot += w ;
684 }
685 else
686 AliError(Form("Wrong energy %f and/or amplitude %f\n", fEnergyList[iDigit], fAmp));
ce2a9a95 687 }
f33a3764 688 if (wtot>0) {
689 x /= wtot ;
690 z /= wtot ;
691 dxx /= wtot ;
692 dzz /= wtot ;
693 dxz /= wtot ;
694 dx3 /= wtot ;
695 dz3 /= wtot ;
696 dz4 /= wtot ;
697 dx3 += -3*dxx*x + 2*x*x*x;
698 dz4 += -4*dz3*z + 6*dzz*z*z -3*z*z*z*z;
699 dxx -= x * x ;
700 dzz -= z * z ;
701 dxz -= x * z ;
702 }
703 else
704 AliError(Form("Wrong weight %f\n", wtot));
ce2a9a95 705
706 // 5) Find an angle between cluster center vector and eigen vector e0
707
f33a3764 708 Float_t phi = 0;
709 if ( (x*x+z*z) > 0 )
710 phi = TMath::ACos ((x*e0.X() + z*e0.Y()) / sqrt(x*x + z*z));
ce2a9a95 711
712 fM2x = lambda0;
713 fM2z = lambda1;
714 fM3x = dx3;
715 fM4z = dz4;
716 fPhixe = phi;
717
718}
c307c629 719//______________________________________________________________________________
720void AliPHOSEmcRecPoint::EvalPrimaries(TClonesArray * digits)
721{
722 // Constructs the list of primary particles (tracks) which have contributed to this RecPoint
723
724 AliPHOSDigit * digit ;
725 Int_t * tempo = new Int_t[fMaxTrack] ;
726
727 //First find digit with maximal energy deposition and copy its primaries
728 Float_t emax=0.;
729 Int_t imaxDigit=0;
730 for(Int_t id=0; id<GetDigitsMultiplicity(); id++){
731 if(emax<fEnergyList[id])
732 imaxDigit=id ;
733 }
734 digit = dynamic_cast<AliPHOSDigit *>(digits->At( fDigitsList[imaxDigit] )) ;
735 Int_t nprimaries = digit->GetNprimary() ;
736 if ( nprimaries > fMaxTrack ) {
737 fMulTrack = - 1 ;
738 Error("EvalPrimaries", "GetNprimaries ERROR > increase fMaxTrack" ) ;
739 nprimaries = fMaxTrack; //skip the rest
740 }
741 for(fMulTrack=1; fMulTrack<=nprimaries ; fMulTrack++){
742 tempo[fMulTrack-1] = digit->GetPrimary(fMulTrack) ;
743 }
744
745 //Now add other digits contributions
746 for (Int_t index = 0 ; index < GetDigitsMultiplicity() ; index++ ) { // all digits
747 if(index==imaxDigit) //already in
748 continue ;
749 digit = dynamic_cast<AliPHOSDigit *>(digits->At( fDigitsList[index] )) ;
750 nprimaries = digit->GetNprimary() ;
751 for(Int_t ipr=0; ipr<nprimaries; ipr++){
752 Int_t iprimary = digit->GetPrimary(ipr+1) ;
753 Bool_t notIn=1 ;
754 for(Int_t kndex = 0 ; (kndex < fMulTrack)&& notIn ; kndex++ ) { //check if not already stored
755 if(iprimary == tempo[kndex]){
756 notIn = kFALSE ;
757 }
758 }
759 if(notIn){
760 if(fMulTrack<fMaxTrack){
761 tempo[fMulTrack]=iprimary ;
762 fMulTrack++ ;
763 }
764 else{
765 Error("EvalPrimaries", "GetNprimaries ERROR > increase fMaxTrack!!!" ) ;
766 break ;
767 }
768 }
769 }
770 } // all digits
771
772 if(fMulTrack > 0){
773 if(fTracksList)delete [] fTracksList;
774 fTracksList = new Int_t[fMulTrack] ;
775 }
776 for(Int_t index = 0; index < fMulTrack; index++)
777 fTracksList[index] = tempo[index] ;
778
779 delete [] tempo ;
780
781}
782
b2a60966 783//____________________________________________________________________________
7932f811 784void AliPHOSEmcRecPoint::EvalAll(Float_t logWeight, TClonesArray * digits )
ad8cfaf4 785{
e5b16749 786 EvalCoreEnergy(logWeight, digits);
a6eedfad 787 EvalTime(digits) ;
c307c629 788 EvalPrimaries(digits) ;
e957fea8 789 AliPHOSRecPoint::EvalAll(digits) ;
ad8cfaf4 790}
791//____________________________________________________________________________
91daaf24 792void AliPHOSEmcRecPoint::EvalAll(Float_t logWeight, TVector3 &vtx, TClonesArray * digits )
793{
794 // Evaluates all shower parameters
795 TVector3 vInc ;
796 EvalLocalPosition(logWeight, vtx, digits,vInc) ;
797 EvalElipsAxis(logWeight, digits, vInc) ; //they are evaluated with momenta
798 EvalMoments(logWeight, digits, vInc) ;
799 EvalDispersion(logWeight, digits, vInc) ;
800}
801//____________________________________________________________________________
802void AliPHOSEmcRecPoint::EvalLocalPosition(Float_t logWeight, TVector3 &vtx, TClonesArray * digits, TVector3 &vInc)
b2a60966 803{
804 // Calculates the center of gravity in the local PHOS-module coordinates
b2a60966 805 Float_t wtot = 0. ;
806
807 Int_t relid[4] ;
808
809 Float_t x = 0. ;
810 Float_t z = 0. ;
811
812 AliPHOSDigit * digit ;
813
686b771f 814 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance() ;
b2a60966 815
816 Int_t iDigit;
817
b2a60966 818 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
7932f811 819 digit = (AliPHOSDigit *) digits->At(fDigitsList[iDigit]) ;
b2a60966 820
821 Float_t xi ;
822 Float_t zi ;
823 phosgeom->AbsToRelNumbering(digit->GetId(), relid) ;
824 phosgeom->RelPosInModule(relid, xi, zi);
f33a3764 825 if (fAmp>0 && fEnergyList[iDigit]>0) {
826 Float_t w = TMath::Max( 0., logWeight + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ;
827 x += xi * w ;
828 z += zi * w ;
829 wtot += w ;
830 }
831 else
832 AliError(Form("Wrong energy %f and/or amplitude %f\n", fEnergyList[iDigit], fAmp));
9ce1a8d9 833 }
f33a3764 834 if (wtot>0) {
835 x /= wtot ;
836 z /= wtot ;
837 }
838 else
839 AliError(Form("Wrong weight %f\n", wtot));
ad8cfaf4 840
841 // Correction for the depth of the shower starting point (TDR p 127)
842 Float_t para = 0.925 ;
843 Float_t parb = 6.52 ;
844
91daaf24 845 phosgeom->GetIncidentVector(vtx,GetPHOSMod(),x,z,vInc) ;
1b799736 846
f33a3764 847 Float_t depthx = 0.;
848 Float_t depthz = 0.;
91daaf24 849 if (fAmp>0&&vInc.Y()!=0.) {
753b19cd 850 depthx = ( para * TMath::Log(fAmp) + parb ) * vInc.X()/TMath::Abs(vInc.Y()) ;
851 depthz = ( para * TMath::Log(fAmp) + parb ) * vInc.Z()/TMath::Abs(vInc.Y()) ;
f33a3764 852 }
853 else
854 AliError(Form("Wrong amplitude %f\n", fAmp));
ad8cfaf4 855
856 fLocPos.SetX(x - depthx) ;
b2a60966 857 fLocPos.SetY(0.) ;
ad8cfaf4 858 fLocPos.SetZ(z - depthz) ;
b2a60966 859
a6eedfad 860 fLocPosM = 0 ;
b2a60966 861}
862
d15a28e7 863//____________________________________________________________________________
ad8cfaf4 864Float_t AliPHOSEmcRecPoint::GetMaximalEnergy(void) const
d15a28e7 865{
b2a60966 866 // Finds the maximum energy in the cluster
867
d15a28e7 868 Float_t menergy = 0. ;
869
870 Int_t iDigit;
871
872 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
873
874 if(fEnergyList[iDigit] > menergy)
875 menergy = fEnergyList[iDigit] ;
876 }
877 return menergy ;
878}
879
880//____________________________________________________________________________
fc7e2f43 881Int_t AliPHOSEmcRecPoint::GetMultiplicityAtLevel(Float_t H) const
d15a28e7 882{
b2a60966 883 // Calculates the multiplicity of digits with energy larger than H*energy
884
d15a28e7 885 Int_t multipl = 0 ;
886 Int_t iDigit ;
887 for(iDigit=0; iDigit<fMulDigit; iDigit++) {
888
889 if(fEnergyList[iDigit] > H * fAmp)
890 multipl++ ;
891 }
892 return multipl ;
893}
894
895//____________________________________________________________________________
a0636361 896Int_t AliPHOSEmcRecPoint::GetNumberOfLocalMax( AliPHOSDigit ** maxAt, Float_t * maxAtEnergy,
7932f811 897 Float_t locMaxCut,TClonesArray * digits) const
d15a28e7 898{
b2a60966 899 // Calculates the number of local maxima in the cluster using fLocalMaxCut as the minimum
a4e98857 900 // energy difference between two local maxima
b2a60966 901
d15a28e7 902 AliPHOSDigit * digit ;
903 AliPHOSDigit * digitN ;
904
905
906 Int_t iDigitN ;
907 Int_t iDigit ;
908
7932f811 909 for(iDigit = 0; iDigit < fMulDigit; iDigit++)
a0636361 910 maxAt[iDigit] = (AliPHOSDigit*) digits->At(fDigitsList[iDigit]) ;
7932f811 911
d15a28e7 912
6ad0bfa0 913 for(iDigit = 0 ; iDigit < fMulDigit; iDigit++) {
a0636361 914 if(maxAt[iDigit]) {
915 digit = maxAt[iDigit] ;
83974468 916
6ad0bfa0 917 for(iDigitN = 0; iDigitN < fMulDigit; iDigitN++) {
686b771f 918 if(iDigit == iDigitN)
919 continue ;
920
7932f811 921 digitN = (AliPHOSDigit *) digits->At(fDigitsList[iDigitN]) ;
d15a28e7 922
9f616d61 923 if ( AreNeighbours(digit, digitN) ) {
d15a28e7 924 if (fEnergyList[iDigit] > fEnergyList[iDigitN] ) {
a0636361 925 maxAt[iDigitN] = 0 ;
6ad0bfa0 926 // but may be digit too is not local max ?
7932f811 927 if(fEnergyList[iDigit] < fEnergyList[iDigitN] + locMaxCut)
a0636361 928 maxAt[iDigit] = 0 ;
d15a28e7 929 }
930 else {
a0636361 931 maxAt[iDigit] = 0 ;
6ad0bfa0 932 // but may be digitN too is not local max ?
7932f811 933 if(fEnergyList[iDigit] > fEnergyList[iDigitN] - locMaxCut)
a0636361 934 maxAt[iDigitN] = 0 ;
d15a28e7 935 }
936 } // if Areneighbours
937 } // while digitN
938 } // slot not empty
939 } // while digit
940
941 iDigitN = 0 ;
6ad0bfa0 942 for(iDigit = 0; iDigit < fMulDigit; iDigit++) {
a0636361 943 if(maxAt[iDigit]){
d15a28e7 944 maxAt[iDigitN] = maxAt[iDigit] ;
9f616d61 945 maxAtEnergy[iDigitN] = fEnergyList[iDigit] ;
946 iDigitN++ ;
d15a28e7 947 }
948 }
949 return iDigitN ;
950}
9688c1dd 951//____________________________________________________________________________
0bc3b8ed 952void AliPHOSEmcRecPoint::EvalTime(TClonesArray * digits)
953{
954 // Define a rec.point time as a time in the cell with the maximum energy
955
9688c1dd 956 Float_t maxE = 0;
957 Int_t maxAt = 0;
958 for(Int_t idig=0; idig < fMulDigit; idig++){
959 if(fEnergyList[idig] > maxE){
960 maxE = fEnergyList[idig] ;
961 maxAt = idig;
962 }
963 }
964 fTime = ((AliPHOSDigit*) digits->At(fDigitsList[maxAt]))->GetTime() ;
965
966}
d15a28e7 967//____________________________________________________________________________
092b50ba 968void AliPHOSEmcRecPoint::Purify(Float_t threshold){
969 //Removes digits below threshold
970
0fbb8738 971 Int_t * tempo = new Int_t[fMaxDigit];
972 Float_t * tempoE = new Float_t[fMaxDigit];
092b50ba 973
974 Int_t mult = 0 ;
975 for(Int_t iDigit=0;iDigit< fMulDigit ;iDigit++){
976 if(fEnergyList[iDigit] > threshold){
977 tempo[mult] = fDigitsList[iDigit] ;
978 tempoE[mult] = fEnergyList[iDigit] ;
979 mult++ ;
980 }
981 }
982
983 fMulDigit = mult ;
984 delete [] fDigitsList ;
985 delete [] fEnergyList ;
0fbb8738 986 fDigitsList = new Int_t[fMulDigit];
987 fEnergyList = new Float_t[fMulDigit];
092b50ba 988
0458aa58 989 fAmp = 0.; //Recalculate total energy
092b50ba 990 for(Int_t iDigit=0;iDigit< fMulDigit ;iDigit++){
0458aa58 991 fDigitsList[iDigit] = tempo[iDigit];
992 fEnergyList[iDigit] = tempoE[iDigit] ;
993 fAmp+=tempoE[iDigit];
092b50ba 994 }
995
996 delete [] tempo ;
997 delete [] tempoE ;
998
999}
1000//____________________________________________________________________________
a8c47ab6 1001void AliPHOSEmcRecPoint::Print(Option_t *) const
d15a28e7 1002{
b2a60966 1003 // Print the list of digits belonging to the cluster
1004
21cd0c07 1005 TString message ;
1006 message = "AliPHOSEmcRecPoint:\n" ;
6f766ada 1007 message += "Digit multiplicity = %d" ;
1008 message += ", cluster Energy = %f" ;
1009 message += ", number of primaries = %d" ;
1010 message += ", rec.point index = %d \n" ;
1011 printf(message.Data(), fMulDigit, fAmp, fMulTrack,GetIndexInList() ) ;
d15a28e7 1012
d15a28e7 1013 Int_t iDigit;
6f766ada 1014 printf(" digits ids = ") ;
7932f811 1015 for(iDigit=0; iDigit<fMulDigit; iDigit++)
53ad38d8 1016 printf(" %d ", fDigitsList[iDigit] ) ;
7932f811 1017
6f766ada 1018 printf("\n digit energies = ") ;
7932f811 1019 for(iDigit=0; iDigit<fMulDigit; iDigit++)
53ad38d8 1020 printf(" %f ", fEnergyList[iDigit] ) ;
6f766ada 1021
1022 printf("\n digit primaries ") ;
1023 if (fMulTrack<1) printf("... no primaries");
bc68d12c 1024 for(iDigit = 0;iDigit < fMulTrack; iDigit++)
53ad38d8 1025 printf(" %d ", fTracksList[iDigit]) ;
1026 printf("\n") ;
6f766ada 1027
d15a28e7 1028}
88714635 1029
7932f811 1030