- Timestamp:
- 10/11/04 21:08:37 (20 years ago)
- Location:
- trunk/MagicSoft/Mars
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/Changelog
r5219 r5221 26 26 in MPedCalcFromLoGain. 27 27 28 * msignal/MExtractTimeAndChargeSpline.[h,cc] 29 - fixed class documentation and some last bugs. 28 30 29 31 2004/10/08: Markus Meyer and Keiichi Mase -
trunk/MagicSoft/Mars/msignal/MExtractTimeAndChargeSpline.cc
r5215 r5221 15 15 ! * 16 16 ! 17 ! Author(s): Markus Gaug 0 5/2004 <mailto:markus@ifae.es>17 ! Author(s): Markus Gaug 09/2004 <mailto:markus@ifae.es> 18 18 ! 19 19 ! Copyright: MAGIC Software Development, 2002-2004 … … 26 26 // MExtractTimeAndChargeSpline 27 27 // 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. 30 37 // 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: 36 40 // 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 // 42 144 ////////////////////////////////////////////////////////////////////////////// 43 145 #include "MExtractTimeAndChargeSpline.h" … … 60 162 const Byte_t MExtractTimeAndChargeSpline::fgLoGainFirst = 3; 61 163 const Byte_t MExtractTimeAndChargeSpline::fgLoGainLast = 14; 62 const Float_t MExtractTimeAndChargeSpline::fgResolution = 0.0 01;164 const Float_t MExtractTimeAndChargeSpline::fgResolution = 0.01; 63 165 const Float_t MExtractTimeAndChargeSpline::fgRiseTime = 2.0; 64 166 const Float_t MExtractTimeAndChargeSpline::fgFallTime = 4.0; … … 89 191 SetFallTime(); 90 192 193 SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast); 194 91 195 SetTimeType(); 92 196 SetChargeType(); 93 197 94 SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast);95 96 fNumHiGainSamples = 1.;97 fNumLoGainSamples = 1.;98 fSqrtHiGainSamples = 1.;99 fSqrtLoGainSamples = 1.;100 101 198 } 102 199 … … 119 216 } 120 217 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 // 225 void 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 // 243 void 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 // 260 void 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 121 286 // -------------------------------------------------------------------------- 122 287 // … … 275 440 if (sat || maxpos < 2) 276 441 { 277 time = Is TimeType(kMaximum)442 time = IsExtractionType(kMaximum) 278 443 ? (Float_t)(fHiGainFirst + maxpos) 279 444 : (Float_t)(fHiGainFirst + maxpos - 1); 445 sum = IsExtractionType(kAmplitude) 446 ? fAbMax : 0.; 280 447 return; 281 448 } … … 295 462 296 463 fHiGainSecondDeriv[range-1] = 0.; 464 297 465 for (Int_t k=range-2;k>=0;k--) 298 466 fHiGainSecondDeriv[k] = (fHiGainSecondDeriv[k]*fHiGainSecondDeriv[k+1] + fHiGainFirstDeriv[k])/6.; … … 338 506 339 507 // 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 342 509 // 343 510 if (fAbMaxPos > upper-0.1) … … 379 546 // Try a better precision. 380 547 // 381 const Float_t up = fAbMaxPos+step-0.0 55;382 const Float_t lo = fAbMaxPos-step+0.0 55;548 const Float_t up = fAbMaxPos+step-0.035; 549 const Float_t lo = fAbMaxPos-step+0.035; 383 550 const Float_t maxpossave = fAbMaxPos; 384 551 … … 387 554 b = x - lower; 388 555 389 step = 0.02 ; // step size of 42ps556 step = 0.025; // step size of 83 ps 390 557 391 558 while (x<up) … … 410 577 411 578 // 412 // Second, try from time down to time-0.2 in steps of 0.0 4.579 // Second, try from time down to time-0.2 in steps of 0.025. 413 580 // 414 581 x = maxpossave; … … 416 583 // 417 584 // 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.02and maxpos585 // maxpos and maxpos+0.025, then we have to look between maxpos-0.025 and maxpos 419 586 // which requires new setting of klocont and khicont 420 587 // … … 450 617 } 451 618 452 if (Is TimeType(kMaximum))619 if (IsExtractionType(kMaximum)) 453 620 { 454 621 time = (Float_t)fHiGainFirst + fAbMaxPos; 455 dtime = 0.02 ;622 dtime = 0.025; 456 623 } 457 624 else … … 482 649 Bool_t back = kFALSE; 483 650 484 Int_t maxcnt = 1000;651 Int_t maxcnt = 50; 485 652 Int_t cnt = 0; 486 653 … … 524 691 } 525 692 526 if (Is ChargeType(kAmplitude))693 if (IsExtractionType(kAmplitude)) 527 694 { 528 695 sum = fAbMax; … … 530 697 } 531 698 532 if (Is ChargeType(kIntegral))699 if (IsExtractionType(kIntegral)) 533 700 { 534 701 // … … 544 711 } 545 712 713 if (lastslice > range) 714 lastslice = range; 715 546 716 Int_t i = startslice; 547 717 sum = 0.5*fHiGainSignal[i]; 548 718 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 // 549 723 for (i=startslice+1; i<lastslice; i++) 550 724 sum += fHiGainSignal[i] + 1.5*fHiGainSecondDeriv[i]; … … 611 785 if (sat || maxpos < 2) 612 786 { 613 time = Is TimeType(kMaximum)787 time = IsExtractionType(kMaximum) 614 788 ? (Float_t)(fLoGainFirst + maxpos) 615 789 : (Float_t)(fLoGainFirst + maxpos - 1); … … 786 960 } 787 961 788 if (Is TimeType(kMaximum))962 if (IsExtractionType(kMaximum)) 789 963 { 790 964 time = (Float_t)fLoGainFirst + fAbMaxPos; … … 860 1034 } 861 1035 862 if (Is ChargeType(kAmplitude))1036 if (IsExtractionType(kAmplitude)) 863 1037 { 864 1038 sum = fAbMax; … … 866 1040 } 867 1041 868 if (Is ChargeType(kIntegral))1042 if (IsExtractionType(kIntegral)) 869 1043 { 870 1044 // -
trunk/MagicSoft/Mars/msignal/MExtractTimeAndChargeSpline.h
r5213 r5221 35 35 Float_t fHalfMax; // Current half maximum of the spline 36 36 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 39 38 40 39 Int_t PreProcess(MParList *pList); … … 50 49 public: 51 50 52 enum TimeType_t { kMaximum, kHalfMaximum }; //! Possible time extraction types53 enum ChargeType_t { kAmplitude, kIntegral }; //! Possiblecharge extraction types51 enum ExtractionType_t { kMaximum, kHalfMaximum, 52 kAmplitude, kIntegral }; //! Possible time and charge extraction types 54 53 55 54 private: 56 55 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); } 59 57 60 58 public: … … 63 61 ~MExtractTimeAndChargeSpline(); 64 62 63 void SetRange ( Byte_t hifirst=0, Byte_t hilast=0, Byte_t lofirst=0, Byte_t lolast=0 ); 65 64 void SetResolution ( Float_t f=fgResolution ) { fResolution = f; } 66 65 void SetRiseTime ( Float_t f=fgRiseTime ) { fRiseTime = f; } 67 66 void SetFallTime ( Float_t f=fgFallTime ) { fFallTime = f; } 68 67 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); 71 70 72 71 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.