ROOT logo
/**************************************************************************
 * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved.      *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// This class extracts the signal parameters (energy, time, quality)
// from ALTRO samples. Energy is in ADC counts, time is in time bin units.
// A coarse algorithm takes the energy as the maximum
// sample, time is the first sample index, and the quality is the number
// of bunches in the signal.
// 
//     AliPHOSRawFitterv0 *fitterv0=new AliPHOSRawFitterv0();
//     fitterv0->SetChannelGeo(module,cellX,cellZ,caloFlag);
//     fitterv0->SetCalibData(fgCalibData) ;
//     fitterv0->Eval(sig,sigStart,sigLength);
//     Double_t amplitude = fitterv0.GetEnergy();
//     Double_t time      = fitterv0.GetTime();
//     Bool_t   isLowGain = fitterv0.GetCaloFlag()==0;

// Author: Yuri Kharlov

// --- ROOT system ---
#include "TArrayI.h"
#include "TMath.h"
#include "TObject.h"

// --- AliRoot header files ---
#include "AliPHOSRawFitterv0.h"
#include "AliPHOSCalibData.h"
#include "AliLog.h"

ClassImp(AliPHOSRawFitterv0)

//-----------------------------------------------------------------------------
AliPHOSRawFitterv0::AliPHOSRawFitterv0():
  TObject(),
  fModule(0),
  fCellX(0),
  fCellZ(0),
  fCaloFlag(0),
  fNBunches(0),
  fPedSubtract(kFALSE),
  fEnergy(-111),
  fTime(-111),
  fQuality(0.),
  fPedestalRMS(0.),
  fAmpOffset(0),
  fAmpThreshold(0),
  fOverflow(kFALSE),
  fCalibData(0)
{
  //Default constructor
}

//-----------------------------------------------------------------------------
AliPHOSRawFitterv0::~AliPHOSRawFitterv0()
{
  //Destructor
}

//-----------------------------------------------------------------------------
AliPHOSRawFitterv0::AliPHOSRawFitterv0(const AliPHOSRawFitterv0 &phosFitter ):
  TObject(),
  fModule      (phosFitter.fModule),
  fCellX       (phosFitter.fCellX),
  fCellZ       (phosFitter.fCellZ),
  fCaloFlag    (phosFitter.fCaloFlag),
  fNBunches    (phosFitter.fNBunches),
  fPedSubtract (phosFitter.fPedSubtract),
  fEnergy      (phosFitter.fEnergy),
  fTime        (phosFitter.fTime),
  fQuality     (phosFitter.fQuality),
  fPedestalRMS (phosFitter.fPedestalRMS),
  fAmpOffset   (phosFitter.fAmpOffset),
  fAmpThreshold(phosFitter.fAmpThreshold),
  fOverflow    (phosFitter.fOverflow),
  fCalibData   (phosFitter.fCalibData)
{
  //Copy constructor
}

//-----------------------------------------------------------------------------
AliPHOSRawFitterv0& AliPHOSRawFitterv0::operator = (const AliPHOSRawFitterv0 &phosFitter)
{
  //Assignment operator.

  if(this != &phosFitter) {
    fModule       = phosFitter.fModule;
    fCellX        = phosFitter.fCellX;
    fCellZ        = phosFitter.fCellZ;
    fCaloFlag     = phosFitter.fCaloFlag;
    fNBunches     = phosFitter.fNBunches;
    fPedSubtract  = phosFitter.fPedSubtract;
    fEnergy       = phosFitter.fEnergy;
    fTime         = phosFitter.fTime;
    fQuality      = phosFitter.fQuality;
    fPedestalRMS  = phosFitter.fPedestalRMS;
    fAmpOffset    = phosFitter.fAmpOffset;
    fAmpThreshold = phosFitter.fAmpThreshold;
    fOverflow     = phosFitter.fOverflow;
    fCalibData    = phosFitter.fCalibData;
  }

  return *this;
}

//-----------------------------------------------------------------------------

void AliPHOSRawFitterv0::SetChannelGeo(const Int_t module, const Int_t cellX,
				     const Int_t cellZ,  const Int_t caloFlag)
{
  // Set geometry address of the channel
  // (for a case if fitting parameters are different for different channels)
  
  fModule   = module;
  fCellX    = cellX;
  fCellZ    = cellZ;
  fCaloFlag = caloFlag;
}
//-----------------------------------------------------------------------------

Bool_t AliPHOSRawFitterv0::Eval(const UShort_t *signal, Int_t sigStart, Int_t sigLength)
{
  // Calculate signal parameters (energy, time, quality) from array of samples
  // Energy is a maximum sample minus pedestal 9
  // Time is the first time bin
  // Signal overflows is there are at least 3 samples of the same amplitude above 900

  fOverflow= kFALSE ;
  fEnergy  = 0;
  if (fNBunches > 1) {
    fQuality = 1000;
    return kTRUE;
  }
  
  const Float_t kBaseLine   = 1.0;
  const Int_t   kPreSamples = 10;

  Float_t  pedMean   = 0;
  Float_t  pedRMS    = 0;
  Int_t    nPed      = 0;
  UShort_t maxSample = 0;
  Int_t    nMax      = 0;

  for (Int_t i=0; i<sigLength; i++) {
    if (i>sigLength-kPreSamples) { //inverse signal time order
      nPed++;
      pedMean += signal[i];
      pedRMS  += signal[i]*signal[i] ;
    }
    if(signal[i] >  maxSample){ maxSample = signal[i]; nMax=0;}
    if(signal[i] == maxSample) nMax++;

  }
  
  
  fEnergy = (Double_t)maxSample;
  if (maxSample > 900 && nMax > 2) fOverflow = kTRUE;

  Double_t pedestal = 0 ;
  if (fPedSubtract) {
    if (nPed > 0) {
      fPedestalRMS=(pedRMS - pedMean*pedMean/nPed)/nPed ;
      if(fPedestalRMS > 0.) 
	fPedestalRMS = TMath::Sqrt(fPedestalRMS) ;
      pedestal = (Double_t)(pedMean/nPed);
    }
    else
      return kFALSE;
  }
  else {
    //take pedestals from DB
    pedestal = (Double_t) fAmpOffset ;
    if (fCalibData) {
      Float_t truePed       = fCalibData->GetADCpedestalEmc(fModule, fCellZ, fCellX) ;
      Int_t   altroSettings = fCalibData->GetAltroOffsetEmc(fModule, fCellZ, fCellX) ;
      pedestal += truePed - altroSettings ;
    }
    else{
      AliDebug(2,Form("Pedestal and offset are not read from OCDB. Use 0 for their values.")) ;
    }
  }
  fEnergy-=pedestal ;
  if (fEnergy < kBaseLine) fEnergy = 0;

  //Evaluate time
  fTime = sigStart-sigLength-3; 
  const Int_t nLine= 6 ;        //Parameters of fitting
  const Float_t eMinTOF = 10. ; //Choosed from beam-test and cosmic analyis
  const Float_t kAmp=0.35 ;     //Result slightly depends on them, so no getters
  // Avoid too low peak:
  if(fEnergy < eMinTOF){
     return kTRUE;
  }

  // Find index posK (kLevel is a level of "timestamp" point Tk):
  Int_t posK =sigLength-1 ; //last point before crossing k-level
  Double_t levelK = pedestal + kAmp*fEnergy;
  while(signal[posK] <= levelK && posK>=0){
     posK-- ;
  }
  posK++ ;

  if(posK == 0 || posK==sigLength-1){
    return kTRUE; 
  }

  // Find crosing point by solving linear equation (least squares method)
  Int_t np = 0;
  Int_t iup=posK-1 ;
  Int_t idn=posK ;
  Double_t sx = 0., sy = 0., sxx = 0., sxy = 0.;
  Double_t x,y ;

  while(np<nLine){
    //point above crossing point
    if(iup>=0){
      x = sigLength-iup-1;
      y = signal[iup];
      sx += x;
      sy += y;
      sxx += (x*x);
      sxy += (x*y);
      np++ ;
      iup-- ;
    }
    //Point below crossing point
    if(idn<sigLength){
      if(signal[idn]<pedestal){
        idn=sigLength-1 ; //do not scan further
	idn++ ;
        continue ;
      }
      x = sigLength-idn-1;
      y = signal[idn];
      sx += x;
      sy += y;
      sxx += (x*x);
      sxy += (x*y);
      np++;
      idn++ ;
    }
    if(idn>=sigLength && iup<0){
      break ; //can not fit futher
    }
  }

  Double_t det = np*sxx - sx*sx;
  if(det == 0){
    return kTRUE;
  }
  if(np == 0){
    return kFALSE;
  }
  Double_t c1 = (np*sxy - sx*sy)/det;  //slope
  Double_t c0 = (sy-c1*sx)/np; //offset
  if(c1 == 0){
    return kTRUE;
  }

  // Find where the line cross kLevel:
  fTime += (levelK - c0)/c1-5. ; //5: mean offset between k-Level and start times
  return kTRUE;

}
 AliPHOSRawFitterv0.cxx:1
 AliPHOSRawFitterv0.cxx:2
 AliPHOSRawFitterv0.cxx:3
 AliPHOSRawFitterv0.cxx:4
 AliPHOSRawFitterv0.cxx:5
 AliPHOSRawFitterv0.cxx:6
 AliPHOSRawFitterv0.cxx:7
 AliPHOSRawFitterv0.cxx:8
 AliPHOSRawFitterv0.cxx:9
 AliPHOSRawFitterv0.cxx:10
 AliPHOSRawFitterv0.cxx:11
 AliPHOSRawFitterv0.cxx:12
 AliPHOSRawFitterv0.cxx:13
 AliPHOSRawFitterv0.cxx:14
 AliPHOSRawFitterv0.cxx:15
 AliPHOSRawFitterv0.cxx:16
 AliPHOSRawFitterv0.cxx:17
 AliPHOSRawFitterv0.cxx:18
 AliPHOSRawFitterv0.cxx:19
 AliPHOSRawFitterv0.cxx:20
 AliPHOSRawFitterv0.cxx:21
 AliPHOSRawFitterv0.cxx:22
 AliPHOSRawFitterv0.cxx:23
 AliPHOSRawFitterv0.cxx:24
 AliPHOSRawFitterv0.cxx:25
 AliPHOSRawFitterv0.cxx:26
 AliPHOSRawFitterv0.cxx:27
 AliPHOSRawFitterv0.cxx:28
 AliPHOSRawFitterv0.cxx:29
 AliPHOSRawFitterv0.cxx:30
 AliPHOSRawFitterv0.cxx:31
 AliPHOSRawFitterv0.cxx:32
 AliPHOSRawFitterv0.cxx:33
 AliPHOSRawFitterv0.cxx:34
 AliPHOSRawFitterv0.cxx:35
 AliPHOSRawFitterv0.cxx:36
 AliPHOSRawFitterv0.cxx:37
 AliPHOSRawFitterv0.cxx:38
 AliPHOSRawFitterv0.cxx:39
 AliPHOSRawFitterv0.cxx:40
 AliPHOSRawFitterv0.cxx:41
 AliPHOSRawFitterv0.cxx:42
 AliPHOSRawFitterv0.cxx:43
 AliPHOSRawFitterv0.cxx:44
 AliPHOSRawFitterv0.cxx:45
 AliPHOSRawFitterv0.cxx:46
 AliPHOSRawFitterv0.cxx:47
 AliPHOSRawFitterv0.cxx:48
 AliPHOSRawFitterv0.cxx:49
 AliPHOSRawFitterv0.cxx:50
 AliPHOSRawFitterv0.cxx:51
 AliPHOSRawFitterv0.cxx:52
 AliPHOSRawFitterv0.cxx:53
 AliPHOSRawFitterv0.cxx:54
 AliPHOSRawFitterv0.cxx:55
 AliPHOSRawFitterv0.cxx:56
 AliPHOSRawFitterv0.cxx:57
 AliPHOSRawFitterv0.cxx:58
 AliPHOSRawFitterv0.cxx:59
 AliPHOSRawFitterv0.cxx:60
 AliPHOSRawFitterv0.cxx:61
 AliPHOSRawFitterv0.cxx:62
 AliPHOSRawFitterv0.cxx:63
 AliPHOSRawFitterv0.cxx:64
 AliPHOSRawFitterv0.cxx:65
 AliPHOSRawFitterv0.cxx:66
 AliPHOSRawFitterv0.cxx:67
 AliPHOSRawFitterv0.cxx:68
 AliPHOSRawFitterv0.cxx:69
 AliPHOSRawFitterv0.cxx:70
 AliPHOSRawFitterv0.cxx:71
 AliPHOSRawFitterv0.cxx:72
 AliPHOSRawFitterv0.cxx:73
 AliPHOSRawFitterv0.cxx:74
 AliPHOSRawFitterv0.cxx:75
 AliPHOSRawFitterv0.cxx:76
 AliPHOSRawFitterv0.cxx:77
 AliPHOSRawFitterv0.cxx:78
 AliPHOSRawFitterv0.cxx:79
 AliPHOSRawFitterv0.cxx:80
 AliPHOSRawFitterv0.cxx:81
 AliPHOSRawFitterv0.cxx:82
 AliPHOSRawFitterv0.cxx:83
 AliPHOSRawFitterv0.cxx:84
 AliPHOSRawFitterv0.cxx:85
 AliPHOSRawFitterv0.cxx:86
 AliPHOSRawFitterv0.cxx:87
 AliPHOSRawFitterv0.cxx:88
 AliPHOSRawFitterv0.cxx:89
 AliPHOSRawFitterv0.cxx:90
 AliPHOSRawFitterv0.cxx:91
 AliPHOSRawFitterv0.cxx:92
 AliPHOSRawFitterv0.cxx:93
 AliPHOSRawFitterv0.cxx:94
 AliPHOSRawFitterv0.cxx:95
 AliPHOSRawFitterv0.cxx:96
 AliPHOSRawFitterv0.cxx:97
 AliPHOSRawFitterv0.cxx:98
 AliPHOSRawFitterv0.cxx:99
 AliPHOSRawFitterv0.cxx:100
 AliPHOSRawFitterv0.cxx:101
 AliPHOSRawFitterv0.cxx:102
 AliPHOSRawFitterv0.cxx:103
 AliPHOSRawFitterv0.cxx:104
 AliPHOSRawFitterv0.cxx:105
 AliPHOSRawFitterv0.cxx:106
 AliPHOSRawFitterv0.cxx:107
 AliPHOSRawFitterv0.cxx:108
 AliPHOSRawFitterv0.cxx:109
 AliPHOSRawFitterv0.cxx:110
 AliPHOSRawFitterv0.cxx:111
 AliPHOSRawFitterv0.cxx:112
 AliPHOSRawFitterv0.cxx:113
 AliPHOSRawFitterv0.cxx:114
 AliPHOSRawFitterv0.cxx:115
 AliPHOSRawFitterv0.cxx:116
 AliPHOSRawFitterv0.cxx:117
 AliPHOSRawFitterv0.cxx:118
 AliPHOSRawFitterv0.cxx:119
 AliPHOSRawFitterv0.cxx:120
 AliPHOSRawFitterv0.cxx:121
 AliPHOSRawFitterv0.cxx:122
 AliPHOSRawFitterv0.cxx:123
 AliPHOSRawFitterv0.cxx:124
 AliPHOSRawFitterv0.cxx:125
 AliPHOSRawFitterv0.cxx:126
 AliPHOSRawFitterv0.cxx:127
 AliPHOSRawFitterv0.cxx:128
 AliPHOSRawFitterv0.cxx:129
 AliPHOSRawFitterv0.cxx:130
 AliPHOSRawFitterv0.cxx:131
 AliPHOSRawFitterv0.cxx:132
 AliPHOSRawFitterv0.cxx:133
 AliPHOSRawFitterv0.cxx:134
 AliPHOSRawFitterv0.cxx:135
 AliPHOSRawFitterv0.cxx:136
 AliPHOSRawFitterv0.cxx:137
 AliPHOSRawFitterv0.cxx:138
 AliPHOSRawFitterv0.cxx:139
 AliPHOSRawFitterv0.cxx:140
 AliPHOSRawFitterv0.cxx:141
 AliPHOSRawFitterv0.cxx:142
 AliPHOSRawFitterv0.cxx:143
 AliPHOSRawFitterv0.cxx:144
 AliPHOSRawFitterv0.cxx:145
 AliPHOSRawFitterv0.cxx:146
 AliPHOSRawFitterv0.cxx:147
 AliPHOSRawFitterv0.cxx:148
 AliPHOSRawFitterv0.cxx:149
 AliPHOSRawFitterv0.cxx:150
 AliPHOSRawFitterv0.cxx:151
 AliPHOSRawFitterv0.cxx:152
 AliPHOSRawFitterv0.cxx:153
 AliPHOSRawFitterv0.cxx:154
 AliPHOSRawFitterv0.cxx:155
 AliPHOSRawFitterv0.cxx:156
 AliPHOSRawFitterv0.cxx:157
 AliPHOSRawFitterv0.cxx:158
 AliPHOSRawFitterv0.cxx:159
 AliPHOSRawFitterv0.cxx:160
 AliPHOSRawFitterv0.cxx:161
 AliPHOSRawFitterv0.cxx:162
 AliPHOSRawFitterv0.cxx:163
 AliPHOSRawFitterv0.cxx:164
 AliPHOSRawFitterv0.cxx:165
 AliPHOSRawFitterv0.cxx:166
 AliPHOSRawFitterv0.cxx:167
 AliPHOSRawFitterv0.cxx:168
 AliPHOSRawFitterv0.cxx:169
 AliPHOSRawFitterv0.cxx:170
 AliPHOSRawFitterv0.cxx:171
 AliPHOSRawFitterv0.cxx:172
 AliPHOSRawFitterv0.cxx:173
 AliPHOSRawFitterv0.cxx:174
 AliPHOSRawFitterv0.cxx:175
 AliPHOSRawFitterv0.cxx:176
 AliPHOSRawFitterv0.cxx:177
 AliPHOSRawFitterv0.cxx:178
 AliPHOSRawFitterv0.cxx:179
 AliPHOSRawFitterv0.cxx:180
 AliPHOSRawFitterv0.cxx:181
 AliPHOSRawFitterv0.cxx:182
 AliPHOSRawFitterv0.cxx:183
 AliPHOSRawFitterv0.cxx:184
 AliPHOSRawFitterv0.cxx:185
 AliPHOSRawFitterv0.cxx:186
 AliPHOSRawFitterv0.cxx:187
 AliPHOSRawFitterv0.cxx:188
 AliPHOSRawFitterv0.cxx:189
 AliPHOSRawFitterv0.cxx:190
 AliPHOSRawFitterv0.cxx:191
 AliPHOSRawFitterv0.cxx:192
 AliPHOSRawFitterv0.cxx:193
 AliPHOSRawFitterv0.cxx:194
 AliPHOSRawFitterv0.cxx:195
 AliPHOSRawFitterv0.cxx:196
 AliPHOSRawFitterv0.cxx:197
 AliPHOSRawFitterv0.cxx:198
 AliPHOSRawFitterv0.cxx:199
 AliPHOSRawFitterv0.cxx:200
 AliPHOSRawFitterv0.cxx:201
 AliPHOSRawFitterv0.cxx:202
 AliPHOSRawFitterv0.cxx:203
 AliPHOSRawFitterv0.cxx:204
 AliPHOSRawFitterv0.cxx:205
 AliPHOSRawFitterv0.cxx:206
 AliPHOSRawFitterv0.cxx:207
 AliPHOSRawFitterv0.cxx:208
 AliPHOSRawFitterv0.cxx:209
 AliPHOSRawFitterv0.cxx:210
 AliPHOSRawFitterv0.cxx:211
 AliPHOSRawFitterv0.cxx:212
 AliPHOSRawFitterv0.cxx:213
 AliPHOSRawFitterv0.cxx:214
 AliPHOSRawFitterv0.cxx:215
 AliPHOSRawFitterv0.cxx:216
 AliPHOSRawFitterv0.cxx:217
 AliPHOSRawFitterv0.cxx:218
 AliPHOSRawFitterv0.cxx:219
 AliPHOSRawFitterv0.cxx:220
 AliPHOSRawFitterv0.cxx:221
 AliPHOSRawFitterv0.cxx:222
 AliPHOSRawFitterv0.cxx:223
 AliPHOSRawFitterv0.cxx:224
 AliPHOSRawFitterv0.cxx:225
 AliPHOSRawFitterv0.cxx:226
 AliPHOSRawFitterv0.cxx:227
 AliPHOSRawFitterv0.cxx:228
 AliPHOSRawFitterv0.cxx:229
 AliPHOSRawFitterv0.cxx:230
 AliPHOSRawFitterv0.cxx:231
 AliPHOSRawFitterv0.cxx:232
 AliPHOSRawFitterv0.cxx:233
 AliPHOSRawFitterv0.cxx:234
 AliPHOSRawFitterv0.cxx:235
 AliPHOSRawFitterv0.cxx:236
 AliPHOSRawFitterv0.cxx:237
 AliPHOSRawFitterv0.cxx:238
 AliPHOSRawFitterv0.cxx:239
 AliPHOSRawFitterv0.cxx:240
 AliPHOSRawFitterv0.cxx:241
 AliPHOSRawFitterv0.cxx:242
 AliPHOSRawFitterv0.cxx:243
 AliPHOSRawFitterv0.cxx:244
 AliPHOSRawFitterv0.cxx:245
 AliPHOSRawFitterv0.cxx:246
 AliPHOSRawFitterv0.cxx:247
 AliPHOSRawFitterv0.cxx:248
 AliPHOSRawFitterv0.cxx:249
 AliPHOSRawFitterv0.cxx:250
 AliPHOSRawFitterv0.cxx:251
 AliPHOSRawFitterv0.cxx:252
 AliPHOSRawFitterv0.cxx:253
 AliPHOSRawFitterv0.cxx:254
 AliPHOSRawFitterv0.cxx:255
 AliPHOSRawFitterv0.cxx:256
 AliPHOSRawFitterv0.cxx:257
 AliPHOSRawFitterv0.cxx:258
 AliPHOSRawFitterv0.cxx:259
 AliPHOSRawFitterv0.cxx:260
 AliPHOSRawFitterv0.cxx:261
 AliPHOSRawFitterv0.cxx:262
 AliPHOSRawFitterv0.cxx:263
 AliPHOSRawFitterv0.cxx:264
 AliPHOSRawFitterv0.cxx:265
 AliPHOSRawFitterv0.cxx:266
 AliPHOSRawFitterv0.cxx:267
 AliPHOSRawFitterv0.cxx:268
 AliPHOSRawFitterv0.cxx:269
 AliPHOSRawFitterv0.cxx:270
 AliPHOSRawFitterv0.cxx:271
 AliPHOSRawFitterv0.cxx:272
 AliPHOSRawFitterv0.cxx:273
 AliPHOSRawFitterv0.cxx:274
 AliPHOSRawFitterv0.cxx:275
 AliPHOSRawFitterv0.cxx:276
 AliPHOSRawFitterv0.cxx:277