ALTRO samples are added to AliPHOSDigit for per-sample event merging.
[u/mrichter/AliRoot.git] / PHOS / AliPHOSDigit.cxx
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
16 /* $Id$ */
17
18 /* History of cvs commits:
19  *
20  * $Log$
21  * Revision 1.39  2006/04/22 15:04:24  hristov
22  * Effective C++ initialization of data members in the default constructor
23  *
24  * Revision 1.38  2006/04/22 10:30:17  hristov
25  * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
26  *
27  * Revision 1.37  2005/05/28 14:19:04  schutz
28  * Compilation warnings fixed by T.P.
29  *
30  */
31
32 //_________________________________________________________________________
33 //  PHOS digit: Id
34 //              energy
35 //              3 identifiers for the primary particle(s) at the origine of the digit
36 //  The digits are made in FinishEvent() by summing all the hits in a single PHOS crystal or PPSD gas cell
37 //
38 //*-- Author: Laurent Aphecetche & Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
39
40
41 // --- ROOT system ---
42
43 #include "TMath.h"
44
45 // --- Standard library ---
46
47 // --- AliRoot header files ---
48
49 #include "AliPHOSDigit.h"
50
51
52
53
54 ClassImp(AliPHOSDigit)
55
56 //____________________________________________________________________________
57 AliPHOSDigit::AliPHOSDigit() :
58   AliDigitNew(),
59   fNprimary(0),  
60   fPrimary(0x0),
61   fEnergy(0.),
62   fTime(0.),
63   fTimeR(0.),
64   fNSamplesHG(0),
65   fNSamplesLG(0),
66   fSamplesHG(0),
67   fSamplesLG(0)
68 {
69   // default ctor 
70 }
71
72 //____________________________________________________________________________
73 AliPHOSDigit::AliPHOSDigit(Int_t primary, Int_t id, Int_t digEnergy, Float_t time, Int_t index) :
74   fNprimary(0),
75   fPrimary(0),
76   fEnergy(0.f),
77   fTime(0.f),
78   fTimeR(0.f),
79   fNSamplesHG(0),
80   fNSamplesLG(0),
81   fSamplesHG(0),
82   fSamplesLG(0)
83 {  
84   // ctor with all data 
85
86   fAmp         = digEnergy ;
87   fEnergy      = 0 ;
88   fTime        = time ;
89   fTimeR       = fTime ;
90   fId          = id ;
91   fIndexInList = index ; 
92   if( primary != -1){
93     fNprimary    = 1 ; 
94     fPrimary = new Int_t[fNprimary] ;
95     fPrimary[0]  = primary ;
96   }
97   else{  //If the contribution of this primary smaller than fDigitThreshold (AliPHOSv1)
98     fNprimary = 0 ; 
99     fPrimary  = 0 ;
100   }
101 }
102
103 //____________________________________________________________________________
104 AliPHOSDigit::AliPHOSDigit(Int_t primary, Int_t id, Float_t energy, Float_t time, Int_t index) :
105   fNprimary(0),
106   fPrimary(0),
107   fEnergy(0.f),
108   fTime(0.f),
109   fTimeR(0.f),
110   fNSamplesHG(0),
111   fNSamplesLG(0),
112   fSamplesHG(0),
113   fSamplesLG(0)
114 {  
115   // ctor with all data 
116
117   fAmp         = 0 ;
118   fEnergy      = energy ;
119   fTime        = time ;
120   fTimeR       = fTime ;
121   fId          = id ;
122   fIndexInList = index ; 
123   if( primary != -1){
124     fNprimary    = 1 ; 
125     fPrimary = new Int_t[fNprimary] ;
126     fPrimary[0]  = primary ;
127   }
128   else{  //If the contribution of this primary smaller than fDigitThreshold (AliPHOSv1)
129     fNprimary = 0 ; 
130     fPrimary  = 0 ;
131   }
132 }
133
134 //____________________________________________________________________________
135 AliPHOSDigit::AliPHOSDigit(const AliPHOSDigit & digit) : 
136   AliDigitNew(digit),
137   fNprimary(digit.fNprimary),
138   fPrimary(0),
139   fEnergy(digit.fEnergy),
140   fTime(digit.fTime),
141   fTimeR(digit.fTimeR),
142   fNSamplesHG(0),
143   fNSamplesLG(0),
144   fSamplesHG(0),
145   fSamplesLG(0)
146 {
147   // copy ctor
148   if(fNprimary){
149     fPrimary = new Int_t[fNprimary] ;
150     for (Int_t i = 0; i < fNprimary ; i++)
151        fPrimary[i]  = digit.fPrimary[i] ;
152   }
153   else
154     fPrimary = 0 ;
155   fAmp         = digit.fAmp ;
156   fId          = digit.fId;
157   fIndexInList = digit.fIndexInList ; 
158 }
159
160 //____________________________________________________________________________
161 AliPHOSDigit::~AliPHOSDigit() 
162 {
163   // Delete array of primaries if any
164   if (fPrimary)   delete [] fPrimary  ;
165   // Delete arrays of ALTRO samples if any
166   if (fSamplesHG) delete [] fSamplesHG;
167   if (fSamplesLG) delete [] fSamplesLG;
168 }
169
170 //____________________________________________________________________________
171 Int_t AliPHOSDigit::Compare(const TObject * obj) const
172 {
173   // Compares two digits with respect to its Id
174   // to sort according increasing Id
175
176   Int_t rv ;
177
178   AliPHOSDigit * digit = (AliPHOSDigit *)obj ; 
179
180   Int_t iddiff = fId - digit->GetId() ; 
181
182   if ( iddiff > 0 ) 
183     rv = 1 ;
184   else if ( iddiff < 0 )
185     rv = -1 ; 
186   else
187     rv = 0 ;
188   
189   return rv ; 
190
191 }
192
193 //____________________________________________________________________________
194 Int_t AliPHOSDigit::GetPrimary(Int_t index) const
195 {
196   // retrieves the primary particle number given its index in the list 
197   Int_t rv = -1 ;
198   if ( index <= fNprimary && index > 0){
199     rv = fPrimary[index-1] ;
200   } 
201
202   return rv ; 
203   
204 }
205
206 //____________________________________________________________________________
207 void AliPHOSDigit::SetALTROSamplesHG(Int_t nSamplesHG, Int_t *samplesHG)
208 {
209   fNSamplesHG = nSamplesHG;
210   fSamplesHG = new UShort_t[fNSamplesHG];
211   UShort_t i;
212   for (i=0; i<fNSamplesHG; i++) {
213     fSamplesHG[i] = samplesHG[i];
214   }
215 }
216 //____________________________________________________________________________
217 void AliPHOSDigit::SetALTROSamplesLG(Int_t nSamplesLG, Int_t *samplesLG)
218 {
219   fNSamplesLG = nSamplesLG;
220   fSamplesLG = new UShort_t[fNSamplesLG];
221   UShort_t i;
222   for (i=0; i<fNSamplesLG; i++) {
223     fSamplesLG[i] = samplesLG[i];
224   }
225 }
226 //____________________________________________________________________________
227 void AliPHOSDigit::Print(const Option_t *) const
228 {
229   // Print the digit together with list of primaries
230   printf("PHOS digit: E=%.3f, Id=%d, Time=%.3e, TimeR=%.3e, NPrim=%d, nHG=%d, nLG=%d \n",
231          fEnergy,fId,fTime,fTimeR,fNprimary,fNSamplesHG,fNSamplesLG);
232   printf("\tList of primaries: ");
233   for (Int_t index = 0; index <fNprimary; index ++ )
234     printf(" %d ",fPrimary[index]); 
235   printf("\n") ;
236   printf("\tHG samples: 0x%x: ",fSamplesHG);
237   for (Int_t i = 0; i <fNSamplesHG; i++)
238     printf(" %d ",fSamplesHG[i]); 
239   printf("\n") ;
240   printf("\tLG samples: 0x%x: ",fSamplesLG);
241   for (Int_t i = 0; i <fNSamplesLG; i++)
242     printf(" %d ",fSamplesLG[i]); 
243   printf("\n") ;
244 }
245 //____________________________________________________________________________
246 void AliPHOSDigit::ShiftPrimary(Int_t shift)
247 {
248   //shifts primary number to BIG offset, to separate primary in different TreeK
249   for(Int_t index = 0; index <fNprimary; index ++ ){
250     fPrimary[index]+= shift ;
251   } 
252 }
253 //____________________________________________________________________________
254 Bool_t AliPHOSDigit::operator==(AliPHOSDigit const & digit) const 
255 {
256   // Two digits are equal if they have the same Id
257   
258   if ( fId == digit.fId ) 
259     return kTRUE ;
260   else 
261     return kFALSE ;
262 }
263  
264 //____________________________________________________________________________
265 AliPHOSDigit& AliPHOSDigit::operator+=(AliPHOSDigit const & digit) 
266 {
267
268   // Adds the amplitude of digits and completes the list of primary particles
269   if(digit.fNprimary>0){
270      Int_t *tmp = new Int_t[fNprimary+digit.fNprimary] ;
271      if(fAmp < digit.fAmp || fEnergy < digit.fEnergy){//most energetic primary in second digit => first primaries in list from second digit
272         for (Int_t index = 0 ; index < digit.fNprimary ; index++)
273            tmp[index]=(digit.fPrimary)[index] ;
274         for (Int_t index = 0 ; index < fNprimary ; index++)
275            tmp[index+digit.fNprimary]=fPrimary[index] ;
276      }
277      else{ //add new primaries to the end
278         for (Int_t index = 0 ; index < fNprimary ; index++)
279            tmp[index]=fPrimary[index] ;
280         for (Int_t index = 0 ; index < digit.fNprimary ; index++)
281            tmp[index+fNprimary]=(digit.fPrimary)[index] ;
282      }
283      if(fPrimary)
284        delete []fPrimary ;
285      fPrimary = tmp ;
286    }
287    fNprimary+=digit.fNprimary ;
288    fAmp     += digit.fAmp ;
289    fEnergy  += digit.fEnergy ;
290    if(fTime > digit.fTime)
291       fTime = digit.fTime ;
292    fTimeR = fTime ; 
293
294    // Add high-gain ALTRO samples
295    UShort_t i;
296    if (digit.fNSamplesHG > fNSamplesHG) {
297      UShort_t newNSamplesHG = digit.fNSamplesHG;
298      UShort_t *newSamplesHG = new UShort_t[newNSamplesHG];
299      for (i=0; i<newNSamplesHG; i++) {
300        if (i<fNSamplesHG)
301          newSamplesHG[i] = TMath::Max(1023,fSamplesHG[i] + (digit.fSamplesHG)[i]);
302        else
303          newSamplesHG[i] = (digit.fSamplesHG)[i];
304      }
305      delete [] fSamplesHG;
306      fSamplesHG = new UShort_t[newNSamplesHG];
307      for (i=0; i<newNSamplesHG; i++) {
308        fSamplesHG[i] = newSamplesHG[i];
309      }
310      delete [] newSamplesHG;
311    }
312    else {
313      for (i=0; i<fNSamplesHG; i++)
314        fSamplesHG[i] = TMath::Max(1023,fSamplesHG[i] + (digit.fSamplesHG)[i]);
315    }
316
317    // Add low-gain ALTRO samples
318    if (digit.fNSamplesLG > fNSamplesLG) {
319      UShort_t newNSamplesLG = digit.fNSamplesLG;
320      UShort_t *newSamplesLG = new UShort_t[newNSamplesLG];
321      for (i=0; i<newNSamplesLG; i++) {
322        if (i<fNSamplesLG)
323          newSamplesLG[i] = TMath::Max(1023,fSamplesLG[i] + (digit.fSamplesLG)[i]);
324        else
325          newSamplesLG[i] = (digit.fSamplesLG)[i];
326      }
327      delete [] fSamplesLG;
328      fSamplesLG = new UShort_t[newNSamplesLG];
329      for (i=0; i<newNSamplesLG; i++) {
330        fSamplesLG[i] = newSamplesLG[i];
331      }
332      delete [] newSamplesLG;
333    }
334    else {
335      for (i=0; i<fNSamplesLG; i++)
336        fSamplesLG[i] = TMath::Max(1023,fSamplesLG[i] + (digit.fSamplesLG)[i]);
337    }
338
339    return *this ;
340 }
341 //____________________________________________________________________________
342 AliPHOSDigit& AliPHOSDigit::operator *= (Float_t factor) 
343 {
344   // Multiplies the amplitude by a factor
345   
346   Float_t tempo = static_cast<Float_t>(fAmp) ; 
347   tempo *= factor ; 
348   fAmp = static_cast<Int_t>(TMath::Ceil(tempo)) ; 
349   return *this ;
350 }
351
352 //____________________________________________________________________________
353 ostream& operator << ( ostream& out , const AliPHOSDigit & digit)
354 {
355   // Prints the data of the digit
356   
357 //   out << "ID " << digit.fId << " Energy = " << digit.fAmp << " Time = " << digit.fTime << endl ; 
358 //   Int_t i ;
359 //   for(i=0;i<digit.fNprimary;i++)
360 //     out << "Primary " << i+1 << " = " << digit.fPrimary[i] << endl ;
361 //   out << "Position in list = " << digit.fIndexInList << endl ; 
362   digit.Warning("operator <<", "Implement differently") ; 
363   return out ;
364 }
365
366