Changeset 5221 for trunk


Ignore:
Timestamp:
10/11/04 21:08:37 (20 years ago)
Author:
gaug
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Mars
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/Changelog

    r5219 r5221  
    2626       in MPedCalcFromLoGain.
    2727
     28   * msignal/MExtractTimeAndChargeSpline.[h,cc]
     29     - fixed class documentation and some last bugs.
    2830
    2931 2004/10/08: Markus Meyer and Keiichi Mase
  • trunk/MagicSoft/Mars/msignal/MExtractTimeAndChargeSpline.cc

    r5215 r5221  
    1515! *
    1616!
    17 !   Author(s): Markus Gaug       05/2004 <mailto:markus@ifae.es>
     17!   Author(s): Markus Gaug       09/2004 <mailto:markus@ifae.es>
    1818!
    1919!   Copyright: MAGIC Software Development, 2002-2004
     
    2626//   MExtractTimeAndChargeSpline
    2727//
    28 //   Fast Spline extractor using a cubic spline algorithm of Numerical Recipes.
    29 //   It returns the integral below the interpolating spline.
     28//   Fast Spline extractor using a cubic spline algorithm, adapted from
     29//   Numerical Recipes in C++, 2nd edition, pp. 116-119.
     30//   
     31//   The coefficients "ya" are here denoted as "fHiGainSignal" and "fLoGainSignal"
     32//   which means the FADC value subtracted by the clock-noise corrected pedestal.
     33//
     34//   The coefficients "y2a" get immediately divided 6. and are called here
     35//   "fHiGainSecondDeriv" and "fLoGainSecondDeriv" although they are now not exactly
     36//   the second derivative coefficients any more.
    3037//
    31 //   Call: SetRange(fHiGainFirst, fHiGainLast, fLoGainFirst, fLoGainLast)
    32 //         to modify the ranges. Ranges have to be an even number. In case of odd
    33 //         ranges, the last slice will be reduced by one.
    34 //
    35 //  Defaults are:
     38//   The calculation of the cubic-spline interpolated value "y" on a point
     39//   "x" along the FADC-slices axis becomes:
    3640//
    37 //   fHiGainFirst =  fgHiGainFirst =  3
    38 //   fHiGainLast  =  fgHiGainLast  =  14
    39 //   fLoGainFirst =  fgLoGainFirst =  3
    40 //   fLoGainLast  =  fgLoGainLast  =  14
    41 //
     41//   y =    a*fHiGainSignal[klo] + b*fHiGainSignal[khi]
     42//       + (a*a*a-a)*fHiGainSecondDeriv[klo] + (b*b*b-b)*fHiGainSecondDeriv[khi]
     43//
     44//   with:
     45//   a = (khi - x)
     46//   b = (x - klo)
     47//
     48//   and "klo" being the lower bin edge FADC index and "khi" the upper bin edge FADC index.
     49//   fHiGainSignal[klo] and fHiGainSignal[khi] are the FADC values at "klo" and "khi".
     50//
     51//   An analogues formula is used for the low-gain values.
     52//
     53//   The coefficients fHiGainSecondDeriv and fLoGainSecondDeriv are calculated with the
     54//   following simplified algorithm:
     55//
     56//   for (Int_t i=1;i<range-1;i++) {
     57//       pp                   = fHiGainSecondDeriv[i-1] + 4.;
     58//       fHiGainFirstDeriv[i] = fHiGainSignal[i+1] - 2.*fHiGainSignal[i] + fHiGainSignal[i-1]
     59//       fHiGainFirstDeriv[i] = (6.0*fHiGainFirstDeriv[i]-fHiGainFirstDeriv[i-1])/pp;
     60//   }
     61//
     62//   for (Int_t k=range-2;k>=0;k--)
     63//       fHiGainSecondDeriv[k] = (fHiGainSecondDeriv[k]*fHiGainSecondDeriv[k+1] + fHiGainFirstDeriv[k])/6.;
     64//
     65//
     66//   This algorithm takes advantage of the fact that the x-values are all separated by exactly 1
     67//   which simplifies the Numerical Recipes algorithm.
     68//   (Note that the variables "fHiGainFirstDeriv" are not real first derivative coefficients.)
     69//
     70//
     71//   The algorithm to search the time proceeds as follows:
     72//
     73//   1) Calculate all fHiGainSignal from fHiGainFirst to fHiGainLast
     74//      (note that an "overlap" to the low-gain arrays is possible: i.e. fHiGainLast>14 in the case of
     75//      the MAGIC FADCs).
     76//   2) Remember the position of the slice with the highest content "fAbMax" at "fAbMaxPos".
     77//   3) If one or more slices are saturated or fAbMaxPos is less than 2 slices from fHiGainFirst,
     78//      return fAbMaxPos as time and fAbMax as charge (note that the pedestal is subtracted here).
     79//   4) Calculate all fHiGainSecondDeriv from the fHiGainSignal array
     80//   5) Search for the maximum, starting in interval fAbMaxPos-1 in steps of 0.2 till fAbMaxPos-0.2.
     81//      If no maximum is found, go to interval fAbMaxPos+1.
     82//      --> 4 function evaluations
     83//   6) Search for the absolute maximum from fAbMaxPos to fAbMaxPos+1 in steps of 0.2
     84//      --> 4 function  evaluations
     85//   7) Try a better precision searching from new max. position fAbMaxPos-0.2 to fAbMaxPos+0.2
     86//      in steps of 0.025 (83 psec. in the case of the MAGIC FADCs).
     87//      --> 14 function evaluations
     88//   8) If Time Extraction Type kMaximum has been chosen, the position of the found maximum is
     89//      returned, else:
     90//   9) The Half Maximum is calculated.
     91//  10) fHiGainSignal is called beginning from fAbMaxPos-1 backwards until a value smaller than fHalfMax
     92//      is found at "klo".
     93//  11) Then, the spline value between "klo" and "klo"+1 is halfed by means of bisection as long as
     94//      the difference between fHalfMax and spline evaluation is less than fResolution (default: 0.01).
     95//      --> maximum 12 interations.
     96//   
     97//  The algorithm to search the charge proceeds as follows:
     98//
     99//  1) If Charge Type: kAmplitude was chosen, return the Maximum of the spline, found during the
     100//     time search.
     101//  2) If Charge Type: kIntegral was chosen, sum the fHiGainSignal between:
     102//     (Int_t)(fAbMaxPos - fRiseTime) and
     103//     (Int_t)(fAbMaxPos + fFallTime)
     104//     (default: fRiseTime: 1.5, fFallTime: 4.5)
     105//  3) Sum only half the values of the edge slices
     106//  4) Sum 1.5*fHiGainSecondDeriv of the not-edge slices using the "natural cubic
     107//     spline with second derivatives set to 0. at the edges.
     108//     (Remember that fHiGainSecondDeriv had been divided by 6.)
     109//   
     110//  The values: fNumHiGainSamples and fNumLoGainSamples are set to:
     111//  1) If Charge Type: kAmplitude was chosen: 1.
     112//  2) If Charge Type: kIntegral was chosen: TMath::Floor(fRiseTime + fFallTime)
     113//
     114//  Call: SetRange(fHiGainFirst, fHiGainLast, fLoGainFirst, fLoGainLast)
     115//        to modify the ranges.
     116//
     117//        Defaults:
     118//        fHiGainFirst =  2
     119//        fHiGainLast  =  14
     120//        fLoGainFirst =  3
     121//        fLoGainLast  =  14
     122//
     123//  Call: SetResolution() to define the resolution of the half-maximum search.
     124//        Default: 0.01
     125//
     126//  Call: SetRiseTime() and SetFallTime() to define the integration ranges
     127//        for the case, the extraction type kIntegral has been chosen.
     128//
     129//  Call: - SetTimeType(MExtractTimeAndChargeSpline::kMaximum) for extraction
     130//          the position of the maximum (default)
     131//          --> needs 22 function evaluations
     132//        - SetTimeType(MExtractTimeAndChargeSpline::kHalfMaximum) for extraction
     133//          the position of the half maximum at the rising edge.
     134//          --> needs max. 34 function evaluations
     135//        - SetChargeType(MExtractTimeAndChargeSpline::kAmplitude) for the
     136//          computation of the amplitude at the maximum (default)
     137//          --> no further function evaluation needed
     138//        - SetChargeType(MExtractTimeAndChargeSpline::kIntegral) for the
     139//          computation of the integral beneith the spline between fRiseTime
     140//          from the position of the maximum to fFallTime after the position of
     141//          the maximum.
     142//          --> needs one more simple summation loop over 7 slices.
     143//       
    42144//////////////////////////////////////////////////////////////////////////////
    43145#include "MExtractTimeAndChargeSpline.h"
     
    60162const Byte_t  MExtractTimeAndChargeSpline::fgLoGainFirst  = 3;
    61163const Byte_t  MExtractTimeAndChargeSpline::fgLoGainLast   = 14;
    62 const Float_t MExtractTimeAndChargeSpline::fgResolution   = 0.001;
     164const Float_t MExtractTimeAndChargeSpline::fgResolution   = 0.01;
    63165const Float_t MExtractTimeAndChargeSpline::fgRiseTime     = 2.0;
    64166const Float_t MExtractTimeAndChargeSpline::fgFallTime     = 4.0;
     
    89191  SetFallTime();
    90192 
     193  SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast);
     194
    91195  SetTimeType();
    92196  SetChargeType();
    93197
    94   SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast);
    95 
    96   fNumHiGainSamples = 1.;
    97   fNumLoGainSamples = 1.;
    98   fSqrtHiGainSamples = 1.;
    99   fSqrtLoGainSamples = 1.;
    100  
    101198}
    102199
     
    119216}
    120217
     218//-------------------------------------------------------------------
     219//
     220// Set the ranges
     221// In order to set the fNum...Samples variables correctly for the case,
     222// the integral is computed, have to overwrite this function and make an
     223// explicit call to SetChargeType().
     224//
     225void MExtractTimeAndChargeSpline::SetRange(Byte_t hifirst, Byte_t hilast, Byte_t lofirst, Byte_t lolast)
     226{
     227
     228  MExtractor::SetRange(hifirst, hilast, lofirst, lolast);
     229
     230  if (IsExtractionType(kIntegral))
     231    SetChargeType(kIntegral);
     232 
     233}
     234
     235
     236//-------------------------------------------------------------------
     237//
     238// Set the Time Extraction type. Possible are:
     239// - kMaximum:     Search the maximum of the spline and return its position
     240// - kHalfMaximum: Search the half maximum left from the maximum and return
     241//                 its position
     242//
     243void MExtractTimeAndChargeSpline::SetTimeType( ExtractionType_t typ )
     244{
     245
     246  CLRBIT(fFlags,kMaximum);
     247  CLRBIT(fFlags,kHalfMaximum);
     248  SETBIT(fFlags,typ);
     249
     250}
     251
     252//-------------------------------------------------------------------
     253//
     254// Set the Charge Extraction type. Possible are:
     255// - kAmplitude: Search the value of the spline at the maximum
     256// - kIntegral:  Integral the spline from fHiGainFirst to fHiGainLast,   
     257//               by counting the edge bins only half and setting the
     258//               second derivative to zero, there.
     259//
     260void MExtractTimeAndChargeSpline::SetChargeType( ExtractionType_t typ )
     261{
     262
     263  CLRBIT(fFlags,kAmplitude);
     264  CLRBIT(fFlags,kIntegral );
     265
     266  SETBIT(fFlags,typ);
     267
     268  if (IsExtractionType(kAmplitude))
     269    {
     270      fNumHiGainSamples = 1.;
     271      fNumLoGainSamples = 1.;
     272      fSqrtHiGainSamples = 1.;
     273      fSqrtLoGainSamples = 1.;
     274    }
     275
     276  if (IsExtractionType(kIntegral))
     277    {
     278      fNumHiGainSamples  = TMath::Floor(fRiseTime + fFallTime);
     279      fNumLoGainSamples  = fNumHiGainSamples;
     280      fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
     281      fSqrtLoGainSamples = fSqrtHiGainSamples;
     282    }
     283}
     284
     285
    121286// --------------------------------------------------------------------------
    122287//
     
    275440  if (sat || maxpos < 2)
    276441    {
    277       time =  IsTimeType(kMaximum)
     442      time =  IsExtractionType(kMaximum)
    278443        ? (Float_t)(fHiGainFirst + maxpos)
    279444        : (Float_t)(fHiGainFirst + maxpos - 1);
     445      sum  =  IsExtractionType(kAmplitude)
     446        ? fAbMax : 0.;
    280447      return;
    281448    }
     
    295462
    296463  fHiGainSecondDeriv[range-1] = 0.;
     464
    297465  for (Int_t k=range-2;k>=0;k--)
    298466    fHiGainSecondDeriv[k] = (fHiGainSecondDeriv[k]*fHiGainSecondDeriv[k+1] + fHiGainFirstDeriv[k])/6.;
     
    338506
    339507  //
    340   // Test the possibility that the absolute maximum has not been found before the
    341   // maxpos and search from maxpos to maxpos+1 in steps of 0.2
     508  // Search for the absolute maximum from maxpos to maxpos+1 in steps of 0.2
    342509  //
    343510  if (fAbMaxPos > upper-0.1)
     
    379546  // Try a better precision.
    380547  //
    381   const Float_t up = fAbMaxPos+step-0.055;
    382   const Float_t lo = fAbMaxPos-step+0.055;
     548  const Float_t up = fAbMaxPos+step-0.035;
     549  const Float_t lo = fAbMaxPos-step+0.035;
    383550  const Float_t maxpossave = fAbMaxPos;
    384551 
     
    387554  b     = x - lower;
    388555 
    389   step  = 0.02; // step size of 42 ps
     556  step  = 0.025; // step size of 83 ps
    390557 
    391558  while (x<up)
     
    410577
    411578  //
    412   // Second, try from time down to time-0.2 in steps of 0.04.
     579  // Second, try from time down to time-0.2 in steps of 0.025.
    413580  //
    414581  x     = maxpossave;
     
    416583  //
    417584  // Test the possibility that the absolute maximum has not been found between
    418   // maxpos and maxpos+0.02, then we have to look between maxpos-0.02 and maxpos
     585  // maxpos and maxpos+0.025, then we have to look between maxpos-0.025 and maxpos
    419586  // which requires new setting of klocont and khicont
    420587  //
     
    450617    }
    451618
    452   if (IsTimeType(kMaximum))
     619  if (IsExtractionType(kMaximum))
    453620    {
    454621      time = (Float_t)fHiGainFirst + fAbMaxPos;
    455       dtime = 0.02;
     622      dtime = 0.025;
    456623    }
    457624  else
     
    482649      Bool_t back = kFALSE;
    483650     
    484       Int_t maxcnt = 1000;
     651      Int_t maxcnt = 50;
    485652      Int_t cnt    = 0;
    486653
     
    524691    }
    525692 
    526   if (IsChargeType(kAmplitude))
     693  if (IsExtractionType(kAmplitude))
    527694    {
    528695      sum = fAbMax;
     
    530697    }
    531698
    532   if (IsChargeType(kIntegral))
     699  if (IsExtractionType(kIntegral))
    533700    {
    534701      //
     
    544711        }
    545712
     713      if (lastslice > range)
     714        lastslice = range;
     715
    546716      Int_t i = startslice;
    547717      sum = 0.5*fHiGainSignal[i];
    548718     
     719      //
     720      // We sum 1.5 times the second deriv. coefficients because these had been
     721      // divided by 6. already. Usually, 0.25*fHiGainSecondDeriv should be added.
     722      //
    549723      for (i=startslice+1; i<lastslice; i++)
    550724        sum += fHiGainSignal[i] + 1.5*fHiGainSecondDeriv[i];
     
    611785  if (sat || maxpos < 2)
    612786    {
    613       time =  IsTimeType(kMaximum)
     787      time =  IsExtractionType(kMaximum)
    614788        ? (Float_t)(fLoGainFirst + maxpos)
    615789        : (Float_t)(fLoGainFirst + maxpos - 1);
     
    786960    }
    787961
    788   if (IsTimeType(kMaximum))
     962  if (IsExtractionType(kMaximum))
    789963    {
    790964      time = (Float_t)fLoGainFirst + fAbMaxPos;
     
    8601034    }
    8611035 
    862   if (IsChargeType(kAmplitude))
     1036  if (IsExtractionType(kAmplitude))
    8631037    {
    8641038      sum = fAbMax;
     
    8661040    }
    8671041
    868   if (IsChargeType(kIntegral))
     1042  if (IsExtractionType(kIntegral))
    8691043    {
    8701044      //
  • trunk/MagicSoft/Mars/msignal/MExtractTimeAndChargeSpline.h

    r5213 r5221  
    3535  Float_t fHalfMax;                      // Current half maximum of the spline
    3636
    37   Byte_t  fTimeFlags;                    // Flag to hold the time extraction type
    38   Byte_t  fChargeFlags;                  // Flag to hold the charge extraction type
     37  Byte_t  fFlags;                        // Bit-field to hold the time extraction types
    3938 
    4039  Int_t  PreProcess(MParList *pList);
     
    5049public:
    5150
    52   enum TimeType_t   { kMaximum,   kHalfMaximum };    //! Possible time   extraction types
    53   enum ChargeType_t { kAmplitude, kIntegral    };    //! Possible charge extraction types
     51  enum ExtractionType_t { kMaximum,   kHalfMaximum,
     52                          kAmplitude, kIntegral    };    //! Possible time and charge extraction types
    5453
    5554private:
    5655
    57   Bool_t IsTimeType  ( TimeType_t   typ )  { return TESTBIT(fTimeFlags  , typ); }
    58   Bool_t IsChargeType( ChargeType_t typ )  { return TESTBIT(fChargeFlags, typ); } 
     56  Bool_t IsExtractionType ( ExtractionType_t typ )  { return TESTBIT(fFlags, typ); }
    5957 
    6058public:
     
    6361  ~MExtractTimeAndChargeSpline(); 
    6462
     63  void SetRange    ( Byte_t hifirst=0, Byte_t hilast=0, Byte_t lofirst=0, Byte_t lolast=0 ); 
    6564  void SetResolution   ( Float_t f=fgResolution  )  { fResolution  = f;  }
    6665  void SetRiseTime     ( Float_t f=fgRiseTime    )  { fRiseTime    = f;  }
    6766  void SetFallTime     ( Float_t f=fgFallTime    )  { fFallTime    = f;  }
    6867
    69   void SetTimeType     ( TimeType_t typ=kMaximum    ) { fTimeFlags = 0;   SETBIT(fTimeFlags,typ);  }
    70   void SetChargeType   ( ChargeType_t typ=kAmplitude) { fChargeFlags = 0; SETBIT(fChargeFlags,typ);}
     68  void SetTimeType     ( ExtractionType_t typ=kMaximum );
     69  void SetChargeType   ( ExtractionType_t typ=kAmplitude);
    7170 
    7271  ClassDef(MExtractTimeAndChargeSpline, 0)   // Task to Extract Arrival Times and Charges using a Fast Cubic Spline
Note: See TracChangeset for help on using the changeset viewer.