]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EMCAL/AliCaloRawAnalyzer.cxx
Move data member fFixTau from AliCaloRawAnalyzerFitter to the mother class
[u/mrichter/AliRoot.git] / EMCAL / AliCaloRawAnalyzer.cxx
CommitLineData
168c7b3c 1// -*- mode: c++ -*-
d655d7dd 2/**************************************************************************
3 * This file is property of and copyright by *
4 * the Relativistic Heavy Ion Group (RHIG), Yale University, US, 2009 *
5 * *
e37e3c84 6 * Primary Author: Per Thomas Hille <perthomas.hille@yale.edu> *
d655d7dd 7 * *
8 * Contributors are mentioned in the code where appropriate. *
9 * Please report bugs to p.t.hille@fys.uio.no *
10 * *
11 * Permission to use, copy, modify and distribute this software and its *
12 * documentation strictly for non-commercial purposes is hereby granted *
13 * without fee, provided that the above copyright notice appears in all *
14 * copies and that both the copyright notice and this permission notice *
15 * appear in the supporting documentation. The authors make no claims *
16 * about the suitability of this software for any purpose. It is *
17 * provided "as is" without express or implied warranty. *
18 **************************************************************************/
19
20
21// Base class for extraction
22// of signal amplitude and peak position
57839add 23// From CALO Calorimeter RAW data (from the RCU)
d655d7dd 24// Contains some utilities for preparing / selecting
25// Signals suitable for signal extraction
26// By derived classes
27
28#include "AliLog.h"
57839add 29#include "AliCaloRawAnalyzer.h"
30#include "AliCaloBunchInfo.h"
31#include "AliCaloFitResults.h"
32#include "TMath.h"
d655d7dd 33#include <iostream>
34using namespace std;
35
ce95bae9 36ClassImp(AliCaloRawAnalyzer)
48a2e3eb 37
38AliCaloRawAnalyzer::AliCaloRawAnalyzer(const char *name, const char *nameshort) : TObject(),
168c7b3c 39 fMinTimeIndex(-1),
40 fMaxTimeIndex(-1),
41 fFitArrayCut(5),
42 fAmpCut(4),
43 fNsampleCut(5),
44 fOverflowCut(950),
45 fNsamplePed(3),
46 fIsZerosupressed( false ),
47 fVerbose( false ),
92d9f317 48 fAlgo(Algo::kNONE),
92d9f317 49 fL1Phase(0),
50 fAmp(0),
396baaf6 51 fTof(0),
0eb3189c 52 fTau( EMCAL::TAU ),
53 fFixTau( true )
d655d7dd 54{
0eb3189c 55 // Ctor
56
57 snprintf(fName, 256, "%s", name);
576a5057 58 snprintf(fNameShort,256, "%s", nameshort);
70e652a6 59
92d9f317 60 for(int i=0; i < ALTROMAXSAMPLES; i++ )
d655d7dd 61 {
62 fReversed[i] = 0;
63 }
64}
65
d655d7dd 66
67void
57839add 68AliCaloRawAnalyzer::SetTimeConstraint(const int min, const int max )
d655d7dd 69{
70 //Require that the bin if the maximum ADC value is between min and max (timebin)
92d9f317 71 if( ( min > max ) || min > ALTROMAXSAMPLES || max > ALTROMAXSAMPLES )
d655d7dd 72 {
73 AliWarning( Form( "Attempt to set Invalid time bin range (Min , Max) = (%d, %d), Ingored", min, max ) );
74 }
75 else
76 {
77 fMinTimeIndex = min;
78 fMaxTimeIndex = max;
79 }
80}
81
82
83UShort_t
9dfd5c8d 84AliCaloRawAnalyzer::Max(const UShort_t *data, const int length ) const
d655d7dd 85{
86 //------------
87 UShort_t tmpmax = data[0];
88
89 for(int i=0; i < length; i++)
90 {
91 if( tmpmax < data[i] )
92 {
93 tmpmax = data[i];
94 }
95 }
96 return tmpmax;
97}
98
99
100void
9dfd5c8d 101AliCaloRawAnalyzer::SelectSubarray( const Double_t *data, const int length, const short maxindex,int *const first, int *const last, const int cut) const
d655d7dd 102{
103 //Selection of subset of data from one bunch that will be used for fitting or
104 //Peak finding. Go to the left and right of index of the maximum time bin
e7acbc37 105 //Until the ADC value is less that fFitArrayCut, or derivative changes sign (data jump)
d655d7dd 106 int tmpfirst = maxindex;
107 int tmplast = maxindex;
92d9f317 108 Double_t prevFirst = data[maxindex];
109 Double_t prevLast = data[maxindex];
947c8e28 110 bool firstJump = false;
111 bool lastJump = false;
112
92d9f317 113 while( (tmpfirst >= 0) && (data[tmpfirst] >= cut ) && (!firstJump) )
d655d7dd 114 {
947c8e28 115 // jump check:
116 if (tmpfirst != maxindex) { // neighbor to maxindex can share peak with maxindex
92d9f317 117 if ( data[tmpfirst] >= prevFirst) {
947c8e28 118 firstJump = true;
119 }
120 }
92d9f317 121 prevFirst = data[tmpfirst];
d655d7dd 122 tmpfirst -- ;
123 }
124
92d9f317 125 while( (tmplast < length) && (data[tmplast] >= cut ) && (!lastJump) )
d655d7dd 126 {
947c8e28 127 // jump check:
128 if (tmplast != maxindex) { // neighbor to maxindex can share peak with maxindex
92d9f317 129 if ( data[tmplast] >= prevLast) {
947c8e28 130 lastJump = true;
131 }
132 }
92d9f317 133 prevLast = data[tmplast];
d655d7dd 134 tmplast ++;
135 }
f57baa2d 136
947c8e28 137 // we keep one pre- or post- sample if we can (as in online)
138 // check though if we ended up on a 'jump', or out of bounds: if so, back up
139 if (firstJump || tmpfirst<0) tmpfirst ++;
140 if (lastJump || tmplast>=length) tmplast --;
141
142 *first = tmpfirst;
143 *last = tmplast;
e7acbc37 144 return;
d655d7dd 145}
146
147
148
149Float_t
57839add 150AliCaloRawAnalyzer::ReverseAndSubtractPed( const AliCaloBunchInfo *bunch, const UInt_t /*altrocfg1*/, const UInt_t /*altrocfg2*/, double *outarray ) const
d655d7dd 151{
152 //Time sample comes in reversed order, revers them back
153 //Subtract the baseline based on content of altrocfg1 and altrocfg2.
154 Int_t length = bunch->GetLength();
155 const UShort_t *sig = bunch->GetData();
156
57839add 157 double ped = EvaluatePedestal( sig , length);
158
159 for( int i=0; i < length; i++ )
160 {
161 outarray[i] = sig[length -i -1] - ped;
162 }
163
164 return ped;
165}
166
167
168
169Float_t
170AliCaloRawAnalyzer::EvaluatePedestal(const UShort_t * const data, const int /*length*/ ) const
171{
172 // double ped = 0;
d655d7dd 173 double tmp = 0;
174
175 if( fIsZerosupressed == false )
176 {
f57baa2d 177 for(int i=0; i < fNsamplePed; i++ )
d655d7dd 178 {
57839add 179 tmp += data[i];
d655d7dd 180 }
f57baa2d 181 }
e37e3c84 182
f57baa2d 183 return tmp/fNsamplePed;
184 }
d655d7dd 185
186
187short
9dfd5c8d 188AliCaloRawAnalyzer::Max( const AliCaloBunchInfo *const bunch , int *const maxindex ) const
d655d7dd 189{
190 //comment
191 short tmpmax = -1;
192 int tmpindex = -1;
193 const UShort_t *sig = bunch->GetData();
194
195 for(int i=0; i < bunch->GetLength(); i++ )
196 {
197 if( sig[i] > tmpmax )
198 {
199 tmpmax = sig[i];
200 tmpindex = i;
201 }
202 }
203
204 if(maxindex != 0 )
205 {
48a2e3eb 206 // *maxindex = bunch->GetLength() -1 - tmpindex + bunch->GetStartBin();
207 *maxindex = bunch->GetLength() -1 - tmpindex + bunch->GetStartBin();
d655d7dd 208 }
209
210 return tmpmax;
211}
212
213
507751ce 214bool
215AliCaloRawAnalyzer::CheckBunchEdgesForMax( const AliCaloBunchInfo *const bunch ) const
216{
217 // a bunch is considered invalid if the maximum is in the first or last time-bin
218 short tmpmax = -1;
219 int tmpindex = -1;
220 const UShort_t *sig = bunch->GetData();
221
222 for(int i=0; i < bunch->GetLength(); i++ )
223 {
224 if( sig[i] > tmpmax )
225 {
226 tmpmax = sig[i];
227 tmpindex = i;
228 }
229 }
230
231 bool bunchOK = true;
232 if (tmpindex == 0 || tmpindex == (bunch->GetLength()-1) )
233 {
234 bunchOK = false;
235 }
236
237 return bunchOK;
238}
239
240
d655d7dd 241int
9dfd5c8d 242AliCaloRawAnalyzer::SelectBunch( const vector<AliCaloBunchInfo> &bunchvector, short *const maxampbin, short *const maxamplitude )
d655d7dd 243{
244 //We select the bunch with the highest amplitude unless any time constraints is set
245 short max = -1;
246 short bunchindex = -1;
247 short maxall = -1;
248 int indx = -1;
249
250 for(unsigned int i=0; i < bunchvector.size(); i++ )
251 {
48a2e3eb 252 max = Max( &bunchvector.at(i), &indx ); // CRAP PTH, bug fix, trouble if more than one bunches
92d9f317 253 if( IsInTimeRange( indx, fMaxTimeIndex, fMinTimeIndex) )
d655d7dd 254 {
255 if( max > maxall )
256 {
257 maxall = max;
258 bunchindex = i;
48a2e3eb 259 *maxampbin = indx;
260 *maxamplitude = max;
d655d7dd 261 }
262 }
263 }
264
507751ce 265 if (bunchindex >= 0) {
266 bool bunchOK = CheckBunchEdgesForMax( &bunchvector.at(bunchindex) );
267 if (! bunchOK) {
268 bunchindex = -1;
269 }
270 }
271
d655d7dd 272 return bunchindex;
273}
274
275
276bool
9dfd5c8d 277AliCaloRawAnalyzer::IsInTimeRange( const int maxindex, const int maxtindx, const int mintindx ) const
d655d7dd 278{
279 // Ckeck if the index of the max ADC vaue is consistent with trigger.
92d9f317 280 if( ( mintindx < 0 && maxtindx < 0) ||maxtindx < 0 )
d655d7dd 281 {
282 return true;
283 }
92d9f317 284 return ( maxindex < maxtindx ) && ( maxindex > mintindx ) ? true : false;
d655d7dd 285}
286
287
288void
f67ce0df 289AliCaloRawAnalyzer::PrintBunches( const vector<AliCaloBunchInfo> &bvctr )
d655d7dd 290{
291 //comment
292 cout << __FILE__ << __LINE__<< "*************** Printing Bunches *******************" << endl;
293 cout << __FILE__ << __LINE__<< "*** There are " << bvctr.size() << ", bunches" << endl;
294
295 for(unsigned int i=0; i < bvctr.size() ; i++ )
296 {
297 PrintBunch( bvctr.at(i) );
298 cout << " bunch = " << i << endl;
299 }
300 cout << __FILE__ << __LINE__<< "*************** Done ... *******************" << endl;
301}
302
303
304void
f67ce0df 305AliCaloRawAnalyzer::PrintBunch( const AliCaloBunchInfo &bunch )
d655d7dd 306{
307 //comment
308 cout << __FILE__ << ":" << __LINE__ << endl;
309 cout << __FILE__ << __LINE__ << ", startimebin = " << bunch.GetStartBin() << ", length =" << bunch.GetLength() << endl;
310 const UShort_t *sig = bunch.GetData();
311
312 for ( Int_t j = 0; j < bunch.GetLength(); j++)
313 {
314 printf("%d\t", sig[j] );
315 }
316 cout << endl;
317}
318
48a2e3eb 319
947c8e28 320Double_t
321AliCaloRawAnalyzer::CalculateChi2(const Double_t amp, const Double_t time,
322 const Int_t first, const Int_t last,
323 const Double_t adcErr,
9dfd5c8d 324 const Double_t tau) const
947c8e28 325{
326 // Input:
327 // amp - max amplitude;
328 // time - time of max amplitude;
329 // first, last - sample array indices to be used
330 // adcErr - nominal error of amplitude measurement (one value for all channels)
331 // if adcErr<0 that mean adcErr=1.
332 // tau - filter time response (in timebin units)
333 // Output:
334 // chi2 - chi2
335
336 if (first == last || first<0 ) { // signal consists of single sample, chi2 estimate (0) not too well defined..
337 // or, first is negative, the indices are not valid
168c7b3c 338 return Ret::kDummy;
947c8e28 339 }
340
341 int nsamples = last - first + 1;
2cd0ffda 342 // printf(" AliCaloRawAnalyzer::CalculateChi2 : first %i last %i : nsamples %i : amp %3.2f time %3.2f \n", first, last, nsamples, amp, time);
947c8e28 343
344 Int_t x = 0;
345 Double_t chi2 = 0;
346 Double_t dy = 0.0, xx = 0.0, f=0.0;
347
348 for (Int_t i=0; i<nsamples; i++) {
349 x = first + i; // timebin
350 xx = (x - time + tau) / tau; // help variable
351 f = 0;
352 if (xx > 0) {
353 f = amp * xx*xx * TMath::Exp(2 * (1 - xx )) ;
354 }
355 dy = fReversed[x] - f;
356 chi2 += dy*dy;
2cd0ffda 357 // printf(" AliCaloRawAnalyzer::CalculateChi2 : %i : y %f -> f %f : dy %f \n", i, fReversed[first+i], f, dy);
947c8e28 358 }
359
360 if (adcErr>0.0) { // weight chi2
361 chi2 /= (adcErr*adcErr);
362 }
363 return chi2;
364}
365
366
367void
368AliCaloRawAnalyzer::CalculateMeanAndRMS(const Int_t first, const Int_t last,
369 Double_t & mean, Double_t & rms)
370{
371 // Input:
372 // first, last - sample array indices to be used
373 // Output:
374 // mean and RMS of samples
375 //
376 // To possibly be used to differentiate good signals from bad before fitting
377 //
168c7b3c 378 mean = Ret::kDummy;
379 rms = Ret::kDummy;
947c8e28 380
381 if (first == last || first<0 ) { // signal consists of single sample, chi2 estimate (0) not too well defined..
382 // or, first is negative, the indices are not valid
383 return;
384 }
385
386 int nsamples = last - first + 1;
387 // printf(" AliCaloRawAnalyzer::CalculateMeanAndRMS : first %i last %i : nsamples %i \n", first, last, nsamples);
388
389 int x = 0;
390 Double_t sampleSum = 0; // sum of samples
391 Double_t squaredSampleSum = 0; // sum of samples squared
392
393 for (Int_t i=0; i<nsamples; i++) {
394 x = first + i;
395 sampleSum += fReversed[x];
396 squaredSampleSum += (fReversed[x] * fReversed[x]);
397 }
398
399 mean = sampleSum / nsamples;
400 Double_t squaredMean = squaredSampleSum / nsamples;
401 // The variance (rms squared) is equal to the mean of the squares minus the square of the mean..
402 rms = sqrt(squaredMean - mean*mean);
403
404 return;
405}
406
168c7b3c 407
408
57839add 409int
92d9f317 410AliCaloRawAnalyzer::PreFitEvaluateSamples( const vector<AliCaloBunchInfo> &bunchvector, const UInt_t altrocfg1,
411 const UInt_t altrocfg2, Int_t & index, Float_t & maxf, short & maxamp,
412 short & maxrev, Float_t & ped, int & first, int & last,const int acut )
57839add 413{ // method to do the selection of what should possibly be fitted
414 int nsamples = 0;
f57baa2d 415 short maxampindex = 0;
57839add 416 index = SelectBunch( bunchvector, &maxampindex, &maxamp ); // select the bunch with the highest amplitude unless any time constraints is set
417
418
92d9f317 419 if( index >= 0 && maxamp >= acut ) // something valid was found, and non-zero amplitude
57839add 420 {
421 // use more convenient numbering and possibly subtract pedestal
422 ped = ReverseAndSubtractPed( &(bunchvector.at(index)), altrocfg1, altrocfg2, fReversed );
423 maxf = TMath::MaxElement( bunchvector.at(index).GetLength(), fReversed );
424
92d9f317 425 if ( maxf >= acut ) // possibly significant signal
57839add 426 {
427 // select array around max to possibly be used in fit
f57baa2d 428 maxrev = maxampindex - bunchvector.at(index).GetStartBin();
92d9f317 429 SelectSubarray( fReversed, bunchvector.at(index).GetLength(), maxrev, &first, &last, acut );
57839add 430
431 // sanity check: maximum should not be in first or last bin
432 // if we should do a fit
92d9f317 433 if (first!=maxrev && last!=maxrev)
434 {
435 // calculate how many samples we have
436 nsamples = last - first + 1;
437 }
57839add 438 }
439 }
440
441 return nsamples;
442}
443