LCOV - code coverage report
Current view: top level - EMCAL/EMCALraw - AliCaloRawAnalyzer.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 95 153 62.1 %
Date: 2016-06-14 17:26:59 Functions: 10 16 62.5 %

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

Generated by: LCOV version 1.11