]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - PHOS/AliPHOSRawFitterv0.cxx
Method added.
[u/mrichter/AliRoot.git] / PHOS / AliPHOSRawFitterv0.cxx
... / ...
CommitLineData
1/**************************************************************************
2 * Copyright(c) 2007, 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// This class extracts the signal parameters (energy, time, quality)
19// from ALTRO samples. Energy is in ADC counts, time is in time bin units.
20// A coarse algorithm takes the energy as the maximum
21// sample, time is the first sample index, and the quality is the number
22// of bunches in the signal.
23//
24// AliPHOSRawFitterv0 *fitterv0=new AliPHOSRawFitterv0();
25// fitterv0->SetChannelGeo(module,cellX,cellZ,caloFlag);
26// fitterv0->SetCalibData(fgCalibData) ;
27// fitterv0->Eval(sig,sigStart,sigLength);
28// Double_t amplitude = fitterv0.GetEnergy();
29// Double_t time = fitterv0.GetTime();
30// Bool_t isLowGain = fitterv0.GetCaloFlag()==0;
31
32// Author: Yuri Kharlov
33
34// --- ROOT system ---
35#include "TArrayI.h"
36#include "TMath.h"
37#include "TObject.h"
38
39// --- AliRoot header files ---
40#include "AliPHOSRawFitterv0.h"
41#include "AliPHOSCalibData.h"
42#include "AliLog.h"
43
44ClassImp(AliPHOSRawFitterv0)
45
46//-----------------------------------------------------------------------------
47AliPHOSRawFitterv0::AliPHOSRawFitterv0():
48 TObject(),
49 fModule(0),
50 fCellX(0),
51 fCellZ(0),
52 fCaloFlag(0),
53 fNBunches(0),
54 fPedSubtract(kFALSE),
55 fEnergy(-111),
56 fTime(-111),
57 fQuality(0.),
58 fPedestalRMS(0.),
59 fAmpOffset(0),
60 fAmpThreshold(0),
61 fOverflow(kFALSE),
62 fCalibData(0)
63{
64 //Default constructor
65}
66
67//-----------------------------------------------------------------------------
68AliPHOSRawFitterv0::~AliPHOSRawFitterv0()
69{
70 //Destructor
71}
72
73//-----------------------------------------------------------------------------
74AliPHOSRawFitterv0::AliPHOSRawFitterv0(const AliPHOSRawFitterv0 &phosFitter ):
75 TObject(),
76 fModule (phosFitter.fModule),
77 fCellX (phosFitter.fCellX),
78 fCellZ (phosFitter.fCellZ),
79 fCaloFlag (phosFitter.fCaloFlag),
80 fNBunches (phosFitter.fNBunches),
81 fPedSubtract (phosFitter.fPedSubtract),
82 fEnergy (phosFitter.fEnergy),
83 fTime (phosFitter.fTime),
84 fQuality (phosFitter.fQuality),
85 fPedestalRMS (phosFitter.fPedestalRMS),
86 fAmpOffset (phosFitter.fAmpOffset),
87 fAmpThreshold(phosFitter.fAmpThreshold),
88 fOverflow (phosFitter.fOverflow),
89 fCalibData (phosFitter.fCalibData)
90{
91 //Copy constructor
92}
93
94//-----------------------------------------------------------------------------
95AliPHOSRawFitterv0& AliPHOSRawFitterv0::operator = (const AliPHOSRawFitterv0 &phosFitter)
96{
97 //Assignment operator.
98
99 if(this != &phosFitter) {
100 fModule = phosFitter.fModule;
101 fCellX = phosFitter.fCellX;
102 fCellZ = phosFitter.fCellZ;
103 fCaloFlag = phosFitter.fCaloFlag;
104 fNBunches = phosFitter.fNBunches;
105 fPedSubtract = phosFitter.fPedSubtract;
106 fEnergy = phosFitter.fEnergy;
107 fTime = phosFitter.fTime;
108 fQuality = phosFitter.fQuality;
109 fPedestalRMS = phosFitter.fPedestalRMS;
110 fAmpOffset = phosFitter.fAmpOffset;
111 fAmpThreshold = phosFitter.fAmpThreshold;
112 fOverflow = phosFitter.fOverflow;
113 fCalibData = phosFitter.fCalibData;
114 }
115
116 return *this;
117}
118
119//-----------------------------------------------------------------------------
120
121void AliPHOSRawFitterv0::SetChannelGeo(const Int_t module, const Int_t cellX,
122 const Int_t cellZ, const Int_t caloFlag)
123{
124 // Set geometry address of the channel
125 // (for a case if fitting parameters are different for different channels)
126
127 fModule = module;
128 fCellX = cellX;
129 fCellZ = cellZ;
130 fCaloFlag = caloFlag;
131}
132//-----------------------------------------------------------------------------
133
134Bool_t AliPHOSRawFitterv0::Eval(const UShort_t *signal, Int_t sigStart, Int_t sigLength)
135{
136 // Calculate signal parameters (energy, time, quality) from array of samples
137 // Energy is a maximum sample minus pedestal 9
138 // Time is the first time bin
139 // Signal overflows is there are at least 3 samples of the same amplitude above 900
140
141 fEnergy = 0;
142 if (fNBunches > 1) {
143 fQuality = 1000;
144 return kTRUE;
145 }
146
147 const Float_t kBaseLine = 1.0;
148 const Int_t kPreSamples = 10;
149
150 Float_t pedMean = 0;
151 Float_t pedRMS = 0;
152 Int_t nPed = 0;
153 UShort_t maxSample = 0;
154 Int_t nMax = 0;
155
156 for (Int_t i=0; i<sigLength; i++) {
157 if (i>sigLength-kPreSamples) { //inverse signal time order
158 nPed++;
159 pedMean += signal[i];
160 pedRMS += signal[i]*signal[i] ;
161 }
162 if(signal[i] > maxSample){ maxSample = signal[i]; nMax=0;}
163 if(signal[i] == maxSample) nMax++;
164
165 }
166
167
168 fEnergy = (Double_t)maxSample;
169 if (maxSample > 900 && nMax > 2) fOverflow = kTRUE;
170
171 Double_t pedestal = 0 ;
172 if (fPedSubtract) {
173 if (nPed > 0) {
174 fPedestalRMS=(pedRMS - pedMean*pedMean/nPed)/nPed ;
175 if(fPedestalRMS > 0.)
176 fPedestalRMS = TMath::Sqrt(fPedestalRMS) ;
177 pedestal = (Double_t)(pedMean/nPed);
178 }
179 else
180 return kFALSE;
181 }
182 else {
183 //take pedestals from DB
184 pedestal = (Double_t) fAmpOffset ;
185 if (fCalibData) {
186 Float_t truePed = fCalibData->GetADCpedestalEmc(fModule, fCellZ, fCellX) ;
187 Int_t altroSettings = fCalibData->GetAltroOffsetEmc(fModule, fCellZ, fCellX) ;
188 pedestal += truePed - altroSettings ;
189 }
190 else{
191 AliDebug(2,Form("Pedestal and offset are not read from OCDB. Use 0 for their values.")) ;
192 }
193 }
194 fEnergy-=pedestal ;
195 if (fEnergy < kBaseLine) fEnergy = 0;
196
197 //Evaluate time
198 fTime = sigStart-sigLength-3;
199 const Int_t nLine= 6 ; //Parameters of fitting
200 const Float_t eMinTOF = 10. ; //Choosed from beam-test and cosmic analyis
201 const Float_t kAmp=0.35 ; //Result slightly depends on them, so no getters
202 // Avoid too low peak:
203 if(fEnergy < eMinTOF){
204 return kTRUE;
205 }
206
207 // Find index posK (kLevel is a level of "timestamp" point Tk):
208 Int_t posK =sigLength-1 ; //last point before crossing k-level
209 Double_t levelK = pedestal + kAmp*fEnergy;
210 while(signal[posK] <= levelK && posK>=0){
211 posK-- ;
212 }
213 posK++ ;
214
215 if(posK == 0 || posK==sigLength-1){
216 return kTRUE;
217 }
218
219 // Find crosing point by solving linear equation (least squares method)
220 Int_t np = 0;
221 Int_t iup=posK-1 ;
222 Int_t idn=posK ;
223 Double_t sx = 0., sy = 0., sxx = 0., sxy = 0.;
224 Double_t x,y ;
225
226 while(np<nLine){
227 //point above crossing point
228 if(iup>=0){
229 x = sigLength-iup-1;
230 y = signal[iup];
231 sx += x;
232 sy += y;
233 sxx += (x*x);
234 sxy += (x*y);
235 np++ ;
236 iup-- ;
237 }
238 //Point below crossing point
239 if(idn<sigLength){
240 if(signal[idn]<pedestal){
241 idn=sigLength-1 ; //do not scan further
242 idn++ ;
243 continue ;
244 }
245 x = sigLength-idn-1;
246 y = signal[idn];
247 sx += x;
248 sy += y;
249 sxx += (x*x);
250 sxy += (x*y);
251 np++;
252 idn++ ;
253 }
254 if(idn>=sigLength && iup<0){
255 break ; //can not fit futher
256 }
257 }
258
259 Double_t det = np*sxx - sx*sx;
260 if(det == 0){
261 return kTRUE;
262 }
263 Double_t c1 = (np*sxy - sx*sy)/det; //slope
264 Double_t c0 = (sy-c1*sx)/np; //offset
265 if(c1 == 0){
266 return kTRUE;
267 }
268
269 // Find where the line cross kLevel:
270 fTime += (levelK - c0)/c1-5. ; //5: mean offset between k-Level and start times
271 return kTRUE;
272
273}