Add separate time calibration for PHOS low gain channel
[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 #include "AliLog.h"
51
52
53
54 ClassImp(AliPHOSDigit)
55
56 //____________________________________________________________________________
57 AliPHOSDigit::AliPHOSDigit() :
58   AliDigitNew(),
59   fIsLG(0),
60   fNprimary(0),  
61   fPrimary(0x0),
62   fEnergy(0.),
63   fTime(0.),
64   fTimeR(0.),
65   fNSamplesHG(0),
66   fNSamplesLG(0),
67   fSamplesHG(0),
68   fSamplesLG(0)
69 {
70   // default ctor 
71 }
72
73 //____________________________________________________________________________
74 AliPHOSDigit::AliPHOSDigit(Int_t primary, Int_t id, Int_t digEnergy, Float_t time, Int_t index) :
75   fIsLG(0),
76   fNprimary(0),
77   fPrimary(0),
78   fEnergy(0.f),
79   fTime(0.f),
80   fTimeR(0.f),
81   fNSamplesHG(0),
82   fNSamplesLG(0),
83   fSamplesHG(0),
84   fSamplesLG(0)
85 {  
86   // ctor with all data 
87
88   fAmp         = digEnergy ;
89   fEnergy      = 0 ;
90   fTime        = time ;
91   fTimeR       = fTime ;
92   fId          = id ;
93   fIndexInList = index ; 
94
95   if( primary != -1){
96     fNprimary    = 1 ; 
97     fPrimary = new Int_t[fNprimary] ;
98     fPrimary[0]  = primary ;
99   }
100   else{  //If the contribution of this primary smaller than fDigitThreshold (AliPHOSv1)
101     fNprimary = 0 ; 
102     fPrimary  = 0 ;
103   }
104 }
105
106 //____________________________________________________________________________
107 AliPHOSDigit::AliPHOSDigit(Int_t primary, Int_t id, Float_t energy, Float_t time, Int_t index) :
108   fIsLG(0),
109   fNprimary(0),
110   fPrimary(0),
111   fEnergy(0.f),
112   fTime(0.f),
113   fTimeR(0.f),
114   fNSamplesHG(0),
115   fNSamplesLG(0),
116   fSamplesHG(0),
117   fSamplesLG(0)
118 {  
119   // ctor with all data 
120
121   fAmp         = 0 ;
122   fEnergy      = energy ;
123   fTime        = time ;
124   fTimeR       = fTime ;
125   fId          = id ;
126   fIndexInList = index ; 
127   if( primary != -1){
128     fNprimary    = 1 ; 
129     fPrimary = new Int_t[fNprimary] ;
130     fPrimary[0]  = primary ;
131   }
132   else{  //If the contribution of this primary smaller than fDigitThreshold (AliPHOSv1)
133     fNprimary = 0 ; 
134     fPrimary  = 0 ;
135   }
136 }
137
138 //____________________________________________________________________________
139 AliPHOSDigit::AliPHOSDigit(const AliPHOSDigit & digit) : 
140   AliDigitNew(digit),
141   fNprimary(digit.fNprimary),
142   fIsLG(digit.fIsLG),
143   fPrimary(0),
144   fEnergy(digit.fEnergy),
145   fTime(digit.fTime),
146   fTimeR(digit.fTimeR),
147   fNSamplesHG(0),
148   fNSamplesLG(0),
149   fSamplesHG(0),
150   fSamplesLG(0)
151 {
152   // copy ctor
153   if(fNprimary){
154     fPrimary = new Int_t[fNprimary] ;
155     for (Int_t i = 0; i < fNprimary ; i++)
156        fPrimary[i]  = digit.fPrimary[i] ;
157   }
158   else
159     fPrimary = 0 ;
160   fAmp         = digit.fAmp ;
161   fId          = digit.fId;
162   fIndexInList = digit.fIndexInList ; 
163 }
164
165 //____________________________________________________________________________
166 AliPHOSDigit & AliPHOSDigit::operator = (const AliPHOSDigit &)
167 {
168   Fatal("operator =", "not implemented");
169   return *this;
170 }
171 //____________________________________________________________________________
172 AliPHOSDigit::~AliPHOSDigit() 
173 {
174   // Delete array of primaries if any
175   if (fPrimary)   delete [] fPrimary  ;
176   // Delete arrays of ALTRO samples if any
177   if (fSamplesHG) delete [] fSamplesHG;
178   if (fSamplesLG) delete [] fSamplesLG;
179 }
180
181 //____________________________________________________________________________
182 Int_t AliPHOSDigit::Compare(const TObject * obj) const
183 {
184   // Compares two digits with respect to its Id
185   // to sort according increasing Id
186
187   Int_t rv ;
188
189   AliPHOSDigit * digit = (AliPHOSDigit *)obj ; 
190
191   Int_t iddiff = fId - digit->GetId() ; 
192
193   if ( iddiff > 0 ) 
194     rv = 1 ;
195   else if ( iddiff < 0 )
196     rv = -1 ; 
197   else
198     rv = 0 ;
199   
200   return rv ; 
201
202 }
203
204 //____________________________________________________________________________
205 Int_t AliPHOSDigit::GetPrimary(Int_t index) const
206 {
207   // retrieves the primary particle number given its index in the list 
208   Int_t rv = -1 ;
209   if ( index <= fNprimary && index > 0){
210     rv = fPrimary[index-1] ;
211   } 
212
213   return rv ; 
214   
215 }
216
217 //____________________________________________________________________________
218 void AliPHOSDigit::SetALTROSamplesHG(Int_t nSamplesHG, Int_t *samplesHG)
219 {
220   fNSamplesHG = nSamplesHG;
221   if (fSamplesHG) delete [] fSamplesHG;
222   fSamplesHG = new UShort_t[fNSamplesHG];
223   UShort_t i;
224   for (i=0; i<fNSamplesHG; i++) {
225     fSamplesHG[i] = samplesHG[i];
226   }
227 }
228 //____________________________________________________________________________
229 void AliPHOSDigit::SetALTROSamplesLG(Int_t nSamplesLG, Int_t *samplesLG)
230 {
231   fNSamplesLG = nSamplesLG;
232   if (fSamplesLG) delete [] fSamplesLG;
233   fSamplesLG = new UShort_t[fNSamplesLG];
234   UShort_t i;
235   for (i=0; i<fNSamplesLG; i++) {
236     fSamplesLG[i] = samplesLG[i];
237   }
238 }
239 //____________________________________________________________________________
240 void AliPHOSDigit::Print(const Option_t *) const
241 {
242   // Print the digit together with list of primaries
243   TString line = Form("PHOS digit: E=%.3f, Id=%d, Time=%.3e, TimeR=%.3e, NPrim=%d, nHG=%d, nLG=%d \n",
244                       fEnergy,fId,fTime,fTimeR,fNprimary,fNSamplesHG,fNSamplesLG);
245   line += "\tList of primaries: ";
246   for (Int_t index = 0; index <fNprimary; index ++ )
247     line += Form(" %d ",fPrimary[index]); 
248   line += "\n";
249   line += "\tSamples HG: ";
250   for (Int_t i = 0; i <fNSamplesHG; i++)
251     line += Form(" %d ",fSamplesHG[i]); 
252   line += "\n";
253   line += "\tSamples LG: ";
254   for (Int_t i = 0; i <fNSamplesLG; i++)
255     line += Form(" %d ",fSamplesLG[i]); 
256   line += "\n";
257   AliDebug(2,line);
258 }
259 //____________________________________________________________________________
260 void AliPHOSDigit::ShiftPrimary(Int_t shift)
261 {
262   //shifts primary number to BIG offset, to separate primary in different TreeK
263   for(Int_t index = 0; index <fNprimary; index ++ ){
264     fPrimary[index]+= shift ;
265   } 
266 }
267 //____________________________________________________________________________
268 Bool_t AliPHOSDigit::operator==(AliPHOSDigit const & digit) const 
269 {
270   // Two digits are equal if they have the same Id
271   
272   if ( fId == digit.fId ) 
273     return kTRUE ;
274   else 
275     return kFALSE ;
276 }
277  
278 //____________________________________________________________________________
279 AliPHOSDigit& AliPHOSDigit::operator+=(AliPHOSDigit const & digit) 
280 {
281
282   // Adds the amplitude of digits and completes the list of primary particles
283   if(digit.fNprimary>0){
284      Int_t *tmp = new Int_t[fNprimary+digit.fNprimary] ;
285      if(fAmp < digit.fAmp || fEnergy < digit.fEnergy){//most energetic primary in second digit => first primaries in list from second digit
286         for (Int_t index = 0 ; index < digit.fNprimary ; index++)
287            tmp[index]=(digit.fPrimary)[index] ;
288         for (Int_t index = 0 ; index < fNprimary ; index++)
289            tmp[index+digit.fNprimary]=fPrimary[index] ;
290      }
291      else{ //add new primaries to the end
292         for (Int_t index = 0 ; index < fNprimary ; index++)
293            tmp[index]=fPrimary[index] ;
294         for (Int_t index = 0 ; index < digit.fNprimary ; index++)
295            tmp[index+fNprimary]=(digit.fPrimary)[index] ;
296      }
297      if(fPrimary)
298        delete []fPrimary ;
299      fPrimary = tmp ;
300    }
301    fNprimary+=digit.fNprimary ;
302    fAmp     += digit.fAmp ;
303    fEnergy  += digit.fEnergy ;
304    if(fTime > digit.fTime)
305       fTime = digit.fTime ;
306    fTimeR = fTime ; 
307
308    // Add high-gain ALTRO samples
309    UShort_t i;
310    if (digit.fNSamplesHG > fNSamplesHG) {
311      UShort_t newNSamplesHG = digit.fNSamplesHG;
312      UShort_t *newSamplesHG = new UShort_t[newNSamplesHG];
313      for (i=0; i<newNSamplesHG; i++) {
314        if (i<fNSamplesHG)
315          newSamplesHG[i] = TMath::Max(1023,fSamplesHG[i] + (digit.fSamplesHG)[i]);
316        else
317          newSamplesHG[i] = (digit.fSamplesHG)[i];
318      }
319      delete [] fSamplesHG;
320      fSamplesHG = new UShort_t[newNSamplesHG];
321      for (i=0; i<newNSamplesHG; i++) {
322        fSamplesHG[i] = newSamplesHG[i];
323      }
324      delete [] newSamplesHG;
325    }
326    else {
327      for (i=0; i<fNSamplesHG; i++)
328        fSamplesHG[i] = TMath::Max(1023,fSamplesHG[i] + (digit.fSamplesHG)[i]);
329    }
330
331    // Add low-gain ALTRO samples
332    if (digit.fNSamplesLG > fNSamplesLG) {
333      UShort_t newNSamplesLG = digit.fNSamplesLG;
334      UShort_t *newSamplesLG = new UShort_t[newNSamplesLG];
335      for (i=0; i<newNSamplesLG; i++) {
336        if (i<fNSamplesLG)
337          newSamplesLG[i] = TMath::Max(1023,fSamplesLG[i] + (digit.fSamplesLG)[i]);
338        else
339          newSamplesLG[i] = (digit.fSamplesLG)[i];
340      }
341      delete [] fSamplesLG;
342      fSamplesLG = new UShort_t[newNSamplesLG];
343      for (i=0; i<newNSamplesLG; i++) {
344        fSamplesLG[i] = newSamplesLG[i];
345      }
346      delete [] newSamplesLG;
347    }
348    else {
349      for (i=0; i<fNSamplesLG; i++)
350        fSamplesLG[i] = TMath::Max(1023,fSamplesLG[i] + (digit.fSamplesLG)[i]);
351    }
352    
353    //If at least one digit in LG, then sum also
354    fIsLG=fIsLG||digit.fIsLG ;
355
356    return *this ;
357 }
358 //____________________________________________________________________________
359 AliPHOSDigit& AliPHOSDigit::operator *= (Float_t factor) 
360 {
361   // Multiplies the amplitude by a factor
362   
363   Float_t tempo = static_cast<Float_t>(fAmp) ; 
364   tempo *= factor ; 
365   fAmp = static_cast<Int_t>(TMath::Ceil(tempo)) ; 
366   return *this ;
367 }
368
369 //____________________________________________________________________________
370 ostream& operator << ( ostream& out , const AliPHOSDigit & digit)
371 {
372   // Prints the data of the digit
373   
374 //   out << "ID " << digit.fId << " Energy = " << digit.fAmp << " Time = " << digit.fTime << endl ; 
375 //   Int_t i ;
376 //   for(i=0;i<digit.fNprimary;i++)
377 //     out << "Primary " << i+1 << " = " << digit.fPrimary[i] << endl ;
378 //   out << "Position in list = " << digit.fIndexInList << endl ; 
379   digit.Warning("operator <<", "Implement differently") ; 
380   return out ;
381 }
382
383