Updated version.
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALDigit.cxx
CommitLineData
61e0abb5 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
090026bf 16/* $Id$ */
61e0abb5 17
18//_________________________________________________________________________
ffa6d63b 19// EMCAL digit:
20// A Digit is the sum of the energy lost in an EMCAL Tower
21// It also stores information on Primary, and enterring particle
22// tracknumbers Digits are created using AliEMCALSDigitizer, followed
23// by AliEMCALDigitizer
61e0abb5 24//
ffa6d63b 25//*-- Author: Sahal Yacoob (LBL)
26// based on : AliPHOSDigit
814ad4bf 27//__________________________________________________________________________
61e0abb5 28
29// --- ROOT system ---
090026bf 30#include <Riostream.h>
31#include <TMath.h>
61e0abb5 32
33// --- Standard library ---
34
61e0abb5 35// --- AliRoot header files ---
36
37#include "AliEMCALDigit.h"
814ad4bf 38#include "AliEMCALGeometry.h"
61e0abb5 39
40ClassImp(AliEMCALDigit)
41
42//____________________________________________________________________________
514da33c 43AliEMCALDigit::AliEMCALDigit() :
829ba234 44AliDigitNew(),
45 fAmpFloat(0.),
46 fNSamples(0),
47 fSamples(0x0),
48 fNSamplesHG(0),
49 fSamplesHG(0x0),
514da33c 50 fNprimary(0),
51 fNMaxPrimary(5),
52 fPrimary(0x0),
af5bdd85 53 fDEPrimary(0x0),
514da33c 54 fNiparent(0),
55 fNMaxiparent(5),
56 fIparent(0x0),
af5bdd85 57 fDEParent(0x0),
514da33c 58 fMaxIter(0),
59 fTime(0.),
829ba234 60 fTimeR(0.),
61 fChi2(0.),
62 fNDF(0),
f4a4dc82 63 fDigitType(kUnknown)
514da33c 64
61e0abb5 65{
66 // default ctor
67
af5bdd85 68 // Need to initialise for reading old files
f4a4dc82 69 fPrimary = new Int_t[fNMaxPrimary] ;
af5bdd85 70 fDEPrimary = new Float_t[fNMaxPrimary] ;
f4a4dc82 71 fIparent = new Int_t[fNMaxiparent] ;
72 fDEParent = new Float_t[fNMaxiparent] ;
af5bdd85 73 for ( Int_t i = 0; i < fNMaxPrimary ; i++) {
f4a4dc82 74 fPrimary[i] = -1 ;
af5bdd85 75 fDEPrimary[i] = 0 ;
76 }
77
0ae8ae77 78 for ( Int_t i = 0; i < fNMaxiparent ; i++) {
f4a4dc82 79 fIparent[i] = -1 ;
af5bdd85 80 fDEParent[i] = 0 ;
81 }
61e0abb5 82}
83
84//____________________________________________________________________________
2cd0ffda 85AliEMCALDigit::AliEMCALDigit(Int_t primary, Int_t iparent, Int_t id, Float_t digEnergy, Float_t time, Int_t type, Int_t index, Float_t chi2, Int_t ndf, Float_t dE)
18a21c7c 86 : AliDigitNew(),
829ba234 87 fAmpFloat(digEnergy),
88 fNSamples(0),
f4a4dc82 89 fSamples(0x0),
829ba234 90 fNSamplesHG(0),
91 fSamplesHG(0x0),
18a21c7c 92 fNprimary(0),
93 fNMaxPrimary(25),
94 fPrimary(0x0),
af5bdd85 95 fDEPrimary(0x0),
18a21c7c 96 fNiparent(0),
97 fNMaxiparent(150),
98 fIparent(0x0),
af5bdd85 99 fDEParent(0x0),
18a21c7c 100 fMaxIter(5),
101 fTime(time),
829ba234 102 fTimeR(time),
2cd0ffda 103 fChi2(chi2),
104 fNDF(ndf),
f4a4dc82 105 fDigitType(type)
61e0abb5 106{
107 // ctor with all data
108
514da33c 109 // data memebrs of the base class (AliNewDigit)
829ba234 110 fAmp = 0;
514da33c 111 fId = id ;
112 fIndexInList = index ;
113
829ba234 114 // data member
f4a4dc82 115 fPrimary = new Int_t[fNMaxPrimary] ;
af5bdd85 116 fDEPrimary = new Float_t[fNMaxPrimary] ;
f4a4dc82 117 fIparent = new Int_t[fNMaxiparent] ;
118 fDEParent = new Float_t[fNMaxiparent] ;
61e0abb5 119 if( primary != -1){
120 fNprimary = 1 ;
7b62cd84 121 fPrimary[0] = primary ;
af5bdd85 122 fDEPrimary[0] = dE ;
61e0abb5 123 fNiparent = 1 ;
124 fIparent[0] = iparent ;
af5bdd85 125 fDEParent[0] = dE ;
126 }
61e0abb5 127 else{ //If the contribution of this primary smaller than fDigitThreshold (AliEMCALv1)
128 fNprimary = 0 ;
129 fPrimary[0] = -1 ;
af5bdd85 130 fDEPrimary[0] = 0 ;
61e0abb5 131 fNiparent = 0 ;
af5bdd85 132 fIparent[0] = -1 ;
133 fDEParent[0] = 0 ;
61e0abb5 134 }
135 Int_t i ;
af5bdd85 136 for ( i = 1; i < fNMaxPrimary ; i++) {
61e0abb5 137 fPrimary[i] = -1 ;
af5bdd85 138 fDEPrimary[i] = 0 ;
139 }
61e0abb5 140
af5bdd85 141 for ( i = 1; i< fNMaxiparent ; i++) {
f807c3bd 142 fIparent[i] = -1 ;
af5bdd85 143 fDEParent[i] = 0 ;
144 }
61e0abb5 145}
146
147//____________________________________________________________________________
18a21c7c 148AliEMCALDigit::AliEMCALDigit(const AliEMCALDigit & digit)
149 : AliDigitNew(digit),
f4a4dc82 150 fAmpFloat(digit.fAmpFloat),
151 fNSamples(digit.fNSamples),
152 fSamples(0x0),
829ba234 153 fNSamplesHG(digit.fNSamplesHG),
154 fSamplesHG(0x0),
18a21c7c 155 fNprimary(digit.fNprimary),
156 fNMaxPrimary(digit.fNMaxPrimary),
157 fPrimary(0x0),
af5bdd85 158 fDEPrimary(0x0),
18a21c7c 159 fNiparent(digit.fNiparent),
160 fNMaxiparent(digit.fNMaxiparent),
161 fIparent(0x0),
af5bdd85 162 fDEParent(0x0),
18a21c7c 163 fMaxIter(digit.fMaxIter),
164 fTime(digit.fTime),
829ba234 165 fTimeR(digit.fTimeR),
166 fChi2(digit.fChi2),
167 fNDF(digit.fNDF),
f4a4dc82 168 fDigitType(digit.fDigitType)
61e0abb5 169{
170 // copy ctor
171
514da33c 172 // data memebrs of the base class (AliNewDigit)
173 fAmp = digit.fAmp ;
174 fId = digit.fId;
175 fIndexInList = digit.fIndexInList ;
61e0abb5 176
829ba234 177 // data members
84f6f119 178 if(fNSamples){
179 fSamples = new Int_t[fNSamples];
180 for (Int_t i=0; i < digit.fNSamples; i++) fSamples[i] = digit.fSamples[i];
181 }
182 else fNSamples = 0;
183
184 if(fNSamplesHG){
185 fSamplesHG = new Int_t[fNSamplesHG];
186 for (Int_t i=0; i < digit.fNSamplesHG; i++) fSamplesHG[i] = digit.fSamplesHG[i];
af5bdd85 187 }
84f6f119 188 else fNSamplesHG = 0;
189
190 if(fNMaxPrimary){
191 fPrimary = new Int_t [fNMaxPrimary] ;
192 fDEPrimary = new Float_t[fNMaxPrimary] ;
193 for ( Int_t i = 0; i < fNMaxPrimary ; i++) {
194 fPrimary[i] = digit.fPrimary[i] ;
195 fDEPrimary[i] = digit.fDEPrimary[i] ;
196 }
197 }
198 else{
199 fPrimary = 0 ;
200 fDEPrimary = 0 ;
201
202 }
203 if(fNMaxiparent){
204 fIparent = new Int_t [fNMaxiparent] ;
205 fDEParent = new Float_t[fNMaxiparent] ;
206 for (Int_t j = 0; j< fNMaxiparent ; j++) {
af5bdd85 207 fIparent[j] = digit.fIparent[j] ;
84f6f119 208 fDEParent[j] = digit.fDEParent[j] ;
209 }
210 }
211 else {
212 fIparent = 0 ;
213 fDEParent = 0 ;
af5bdd85 214 }
61e0abb5 215}
216
217//____________________________________________________________________________
218AliEMCALDigit::~AliEMCALDigit()
219{
220 // Delete array of primiries if any
88d764f0 221 delete [] fPrimary ;
af5bdd85 222 delete [] fDEPrimary ;
88d764f0 223 delete [] fIparent ;
af5bdd85 224 delete [] fDEParent ;
84f6f119 225 delete [] fSamples;
226 delete [] fSamplesHG;
829ba234 227
61e0abb5 228}
229
230//____________________________________________________________________________
231Int_t AliEMCALDigit::Compare(const TObject * obj) const
232{
233 // Compares two digits with respect to its Id
234 // to sort according increasing Id
235
236 Int_t rv ;
237
238 AliEMCALDigit * digit = (AliEMCALDigit *)obj ;
239
240 Int_t iddiff = fId - digit->GetId() ;
241
242 if ( iddiff > 0 )
243 rv = 1 ;
244 else if ( iddiff < 0 )
245 rv = -1 ;
246 else
247 rv = 0 ;
248
249 return rv ;
250
251}
252
253//____________________________________________________________________________
88cb7938 254Float_t AliEMCALDigit::GetEta() const
14ce0a6e 255{
256 //return pseudorapidity for this digit
257 // should be change in EMCALGeometry - 19-nov-04
814ad4bf 258 Float_t eta=-10., phi=-10.;
563aa66c 259 Int_t id = GetId();
5dee926e 260 const AliEMCALGeometry *g = AliEMCALGeometry::GetInstance();
563aa66c 261 g->EtaPhiFromIndex(id,eta,phi);
814ad4bf 262 return eta ;
263}
264
265//____________________________________________________________________________
88cb7938 266Float_t AliEMCALDigit::GetPhi() const
14ce0a6e 267{
268 //return phi coordinate of digit
269 // should be change in EMCALGeometry - 19-nov-04
814ad4bf 270 Float_t eta=-10., phi=-10.;
563aa66c 271 Int_t id = GetId();
5dee926e 272 const AliEMCALGeometry *g = AliEMCALGeometry::GetInstance();
563aa66c 273 g->EtaPhiFromIndex(id,eta,phi);
814ad4bf 274 return phi ;
275}
276
277//____________________________________________________________________________
829ba234 278Bool_t AliEMCALDigit::GetFALTROSample(const Int_t iSample, Int_t& timeBin, Int_t& amp) const
279{
280 //Get FALTRO sample in time bin iSample
f4a4dc82 281 if (iSample >= fNSamples || iSample < 0 || fDigitType==kTrigger) return kFALSE;
829ba234 282
283 amp = fSamples[iSample] & 0xFFF;
284 timeBin = (fSamples[iSample] >> 12) & 0xFF;
285
286 return kTRUE;
287}
288//____________________________________________________________________________
289Bool_t AliEMCALDigit::GetALTROSampleLG(const Int_t iSample, Int_t& timeBin, Int_t& amp) const
290{
291 //Get Low Gain ALTRO sample in time bin iSample
f4a4dc82 292 if (iSample >= fNSamples || iSample < 0 || fDigitType==kLG) return kFALSE;
829ba234 293
294 amp = fSamples[iSample] & 0xFFF;
295 timeBin = (fSamples[iSample] >> 12) & 0xFF;
296
297 return kTRUE;
298}
299
300//____________________________________________________________________________
301void AliEMCALDigit::SetALTROSamplesLG(const Int_t nSamples, Int_t *samples)
302{
303 //Set array of ALTRO samples, Low Gain or FALTRO
304 fNSamples = nSamples;
305 fSamples = new Int_t[fNSamples];
306 for (Int_t i=0; i < fNSamples; i++) fSamples[i] = samples[i];
307}
308
309//____________________________________________________________________________
310void AliEMCALDigit::SetALTROSamplesHG(const Int_t nSamples, Int_t *samples)
311{
312 //Set array of ALTRO samples, High Gain.
313 fNSamplesHG = nSamples;
314 fSamplesHG = new Int_t[fNSamplesHG];
315 for (Int_t i=0; i < fNSamplesHG; i++) fSamplesHG[i] = samples[i];
316}
317
318
319//____________________________________________________________________________
320Bool_t AliEMCALDigit::GetALTROSampleHG(const Int_t iSample, Int_t& timeBin, Int_t& amp) const
321{
322 //Get High Gain ALTRO sample in time bin iSample
f4a4dc82 323 if (iSample >= fNSamplesHG || iSample < 0 || fDigitType==kHG) return kFALSE;
829ba234 324
325 amp = fSamplesHG[iSample] & 0xFFF;
326 timeBin = (fSamplesHG[iSample] >> 12) & 0xFF;
327
328 return kTRUE;
329}
330
331
332//____________________________________________________________________________
61e0abb5 333Int_t AliEMCALDigit::GetPrimary(Int_t index) const
334{
335 // retrieves the primary particle number given its index in the list
fdebddeb 336 if ( (index <= fNprimary) && (index > 0)){
af5bdd85 337 return fPrimary[index-1] ;
61e0abb5 338 }
339
af5bdd85 340 return -1 ;
341}
342
343//____________________________________________________________________________
344Float_t AliEMCALDigit::GetDEPrimary(Int_t index) const
345{
346 // retrieves the primary particle energy contribution
347 // given its index in the list
348 if ( (index <= fNprimary) && (index > 0)){
349 return fDEPrimary[index-1] ;
350 }
351
352 return 0 ;
61e0abb5 353
354}
355
356//____________________________________________________________________________
357Int_t AliEMCALDigit::GetIparent(Int_t index) const
358{
359 // retrieves the primary particle number given its index in the list
af5bdd85 360 if ( index <= fNiparent && index > 0){
361 return fIparent[index-1] ;
61e0abb5 362 }
363
af5bdd85 364 return -1 ;
61e0abb5 365
366}
367
61e0abb5 368//____________________________________________________________________________
af5bdd85 369Float_t AliEMCALDigit::GetDEParent(Int_t index) const
370{
371 // retrieves the parent particle energy contribution
372 // given its index in the list
373 if ( (index <= fNiparent) && (index > 0)){
374 return fDEParent[index-1] ;
375 }
376
377 return 0;
378}
379
380//____________________________________________________________________________
61e0abb5 381void AliEMCALDigit::ShiftPrimary(Int_t shift){
fdebddeb 382 //shifts primary number to BIG offset, to separate primary in different TreeK
61e0abb5 383 Int_t index ;
384 for(index = 0; index <fNprimary; index++ ){
385 fPrimary[index] = fPrimary[index]+ shift * 10000000 ;}
386 for(index =0; index <fNiparent; index++){
387 fIparent[index] = fIparent[index] + shift * 10000000 ;}
388}
389//____________________________________________________________________________
390Bool_t AliEMCALDigit::operator==(AliEMCALDigit const & digit) const
391{
392 // Two digits are equal if they have the same Id
393
394 if ( fId == digit.fId )
395 return kTRUE ;
396 else
397 return kFALSE ;
398}
399
400//____________________________________________________________________________
0a4cb131 401AliEMCALDigit AliEMCALDigit::operator+(const AliEMCALDigit &digit)
61e0abb5 402{
403 // Adds the amplitude of digits and completes the list of primary particles
404 // if amplitude is larger than
405
829ba234 406 fAmpFloat += digit.fAmpFloat ;
407 for (Int_t i=0; i < fNSamples ; i++) fSamples[i] += digit.fSamples[i];
408 for (Int_t i=0; i < fNSamplesHG; i++) fSamplesHG[i] += digit.fSamplesHG[i];
409
410 fAmp += digit.fAmp ;
814ad4bf 411 if(fTime > digit.fTime)
412 fTime = digit.fTime ;
3c80fef6 413 if (digit.fTimeR < fTimeR)
414 fTimeR = digit.fTimeR ;
7b62cd84 415
61e0abb5 416 Int_t max1 = fNprimary ;
417 Int_t max2 = fNiparent ;
418 Int_t index ;
7b62cd84 419 for (index = 0 ; index < digit.fNprimary ; index++){
af5bdd85 420 Bool_t newPrim = kTRUE ;
61e0abb5 421 Int_t old ;
af5bdd85 422 for ( old = 0 ; (old < max1) && newPrim; old++) { //already have this primary?
423 if(fPrimary[old] == digit.fPrimary[index]) {
424 newPrim = kFALSE;
425 fDEPrimary[old] += digit.fDEPrimary[index];
426 }
61e0abb5 427 }
af5bdd85 428 if (newPrim) {
429 if(max1<fNMaxPrimary){
430 fPrimary[max1] = digit.fPrimary[index] ;
431 fDEPrimary[max1] = digit.fDEPrimary[index] ;
432 fNprimary++ ;
433 max1++;
434 }
7b62cd84 435 if(fNprimary==fNMaxPrimary) {
af5bdd85 436
451bc3c5 437 TString mess = " NMaxPrimary = " ;
438 mess += fNMaxPrimary ;
439 mess += " is too small" ;
440 Fatal("AliEMCALDigit::Operator+ -->" , mess.Data()) ;
8704424d 441
61e0abb5 442 }
443 }
444 }
445
446 for (index = 0 ; index < digit.fNiparent ; index++){
af5bdd85 447 Bool_t newParent = kTRUE ;
61e0abb5 448 Int_t old ;
af5bdd85 449 for ( old = 0 ; (old < max2) && newParent; old++) { //already have this primary?
450 if(fIparent[old] == digit.fIparent[index]) {
451 newParent = kFALSE;
452 fDEParent[old] += digit.fDEParent[index];
453 }
61e0abb5 454 }
af5bdd85 455 if(newParent){
456 if(max2<fNMaxiparent) {
457 fIparent[max2] = digit.fIparent[index] ;
458 fDEParent[max2] = digit.fDEParent[index] ;
459 fNiparent++ ;
460 max2++;
461 }
7b62cd84 462 if(fNiparent==fNMaxiparent) {
af5bdd85 463
451bc3c5 464 TString mess = " NMaxiparent = " ;
465 mess += fNMaxiparent ;
466 mess += " is too small" ;
467 Fatal("AliEMCALDigit::Operator+ -->", mess.Data()) ;
8704424d 468
61e0abb5 469 }
470 }
471 }
472
473 return *this ;
474}
475
476//____________________________________________________________________________
0a4cb131 477AliEMCALDigit AliEMCALDigit::operator*(Float_t factor)
563aa66c 478{
479 // Multiplies the amplitude by a factor
480
829ba234 481 //Float_t tempo = static_cast<Float_t>(fAmp) ;
482 //tempo *= factor ;
483 //fAmp = static_cast<Int_t>(TMath::Floor(tempo)) ;
484
485 fAmpFloat *= factor;
486 for (Int_t i=0; i < fNSamples ; i++) fSamples[i] = Int_t(factor*fSamples[i]);
487 for (Int_t i=0; i < fNSamplesHG; i++) fSamplesHG[i] = Int_t(factor*fSamplesHG[i]);
488
af5bdd85 489 for(Int_t i=0; i < fNprimary; i++)
490 fDEPrimary[i] *= factor;
491 for(Int_t i=0; i < fNiparent; i++)
492 fDEParent[i] *= factor;
493
563aa66c 494 return *this ;
495}
496
497//____________________________________________________________________________
61e0abb5 498ostream& operator << ( ostream& out , const AliEMCALDigit & digit)
499{
500 // Prints the data of the digit
501
814ad4bf 502 out << "ID " << digit.fId << " Energy = " << digit.fAmp << " Time = " << digit.fTime << endl ;
61e0abb5 503 Int_t i,j ;
af5bdd85 504 for(i=0;i<digit.fNprimary;i++)
505 out << "Primary " << i+1 << " = " << digit.fPrimary[i]
506 << " : DE " << digit.fDEPrimary[i] << endl ;
61e0abb5 507
508 for(j=0;j<digit.fNiparent;j++)
af5bdd85 509 out << "Iparent " << j+1 << " = " << digit.fIparent[j]
510 << " : DE " << digit.fDEParent[j] << endl ;
511 out << "Position in list = " << digit.fIndexInList << endl ;
61e0abb5 512 return out ;
513}
514
829ba234 515//____________________________________________________________________________
516void AliEMCALDigit::Print(const Option_t* /*opt*/) const
517{
518 //Print
f4a4dc82 519 printf("===\nDigit id: %4d / Energy %2.3f ; Time %e ; Time samples %d ; Chi2 %2.3f, NDF %d, Type? %d \n",
520 fId, fAmpFloat,fTime, fNSamples, fChi2, fNDF, fDigitType);
521 if(fDigitType==kTrigger){
829ba234 522 printf("FALTRO: ");
523 for (Int_t i=0; i < GetNFALTROSamples(); i++)
524 {
525 Int_t timeBin, amp;
526 GetFALTROSample(i, timeBin, amp);
527 printf(" (%d,%d) ",timeBin,amp);
528 }
529 printf("\n");
530 }//trigger
531 else{
532 printf("ALTRO, Low Gain: ");
533 for (Int_t i=0; i < GetNALTROSamplesLG(); i++)
534 {
535 Int_t timeBin, amp;
536 GetALTROSampleLG(i, timeBin, amp);
537 printf(" (%d,%d) ",timeBin,amp);
538 }
539 printf("\n");
540 printf("ALTRO, High Gain: ");
541 for (Int_t i=0; i < GetNALTROSamplesHG(); i++)
542 {
543 Int_t timeBin, amp;
544 GetALTROSampleHG(i, timeBin, amp);
545 printf(" (%d,%d) ",timeBin,amp);
546 }
547 printf("\n");
548 }//trigger
549
550}
551
552
61e0abb5 553