Changeset 8072
- Timestamp:
- 10/16/06 18:02:31 (18 years ago)
- Location:
- trunk/MagicSoft/Mars
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/Changelog
r8071 r8072 19 19 -*-*- END OF LINE -*-*- 20 20 21 2006/10/16 Thomas Bretz 22 23 * mextralgo/MExtralgoDigitalFilter.[h,cc]: 24 - Changed the extraction algorithm such that extraction of signal 25 and time is iterated and should be as consistent as possible 26 at the end of the algorithm. 27 - changed the final offset in the calculation of the arrival time 28 to match as best as it can so far. 29 - Updates to the still preliminary calculation of the weights 30 31 32 21 33 2006/10/15 Thomas Bretz 22 34 … … 26 38 27 39 * star.cc, ganymed.c, callisto.cc: 28 - implemented an error if the resource file doe n't exist40 - implemented an error if the resource file doesn't exist 29 41 (returns 0xfe) 30 42 -
trunk/MagicSoft/Mars/mextralgo/MExtralgoDigitalFilter.cc
r7942 r8072 33 33 using namespace std; 34 34 35 Float_t MExtralgoDigitalFilter::ExtractNoise(Int_t iter, Int_t windowsize) const 36 { 37 Double_t sum, dummy; 38 Eval(sum, dummy, windowsize, 0, iter-fWeightsPerBin/2); 39 return sum; 40 } 41 42 void MExtralgoDigitalFilter::Extract(Int_t windowsize, Float_t timeshift) 35 Float_t MExtralgoDigitalFilter::ExtractNoise(Int_t iter) const 36 { 37 return Eval(fWeightsAmp, 0, iter-fWeightsPerBin/2); 38 } 39 40 #include <iostream> 41 void MExtralgoDigitalFilter::Extract() 43 42 { 44 43 fSignal = 0; // default is: no pulse found … … 49 48 // FIXME: How to handle saturation? 50 49 51 Float_t maxamp = -FLT_MAX; 52 Float_t maxtime = 0; 53 Int_t maxp = -1; 50 Double_t maxamp = -FLT_MAX; 51 Int_t maxp = -1; 54 52 55 53 // 56 54 // Calculate the sum of the first fWindowSize slices 57 55 // 58 for (Int_t i=0; i<fNum-windowsize+1; i++) 59 { 60 Double_t sumamp, sumtime; 61 Eval(sumamp, sumtime, windowsize, i); 62 56 57 // For the case of an even numberof weights/bin there is 58 // no central bin.So we create an artificial central bin. 59 for (Int_t i=0; i<fNum-fWindowSize+1; i++) 60 { 61 const Double_t sumamp = Eval(fWeightsAmp, i); 63 62 if (sumamp>maxamp) 64 63 { 65 maxamp = sumamp; 66 maxtime = sumtime; 67 maxp = i; 68 } 69 } 70 64 maxamp = sumamp; 65 maxp = i; 66 } 67 } 71 68 // The number of available slices were smaller than the 72 69 // extraction window size of the extractor … … 84 81 return; 85 82 86 // This is the time offset from the extraction position 87 const Float_t time = maxtime/maxamp; 83 Int_t frac = 0; 84 const Int_t shift = AlignExtractionWindow(maxp, frac, maxamp); 85 86 // For safety we do another iteration if we have 87 // shifted the extraction window 88 if (TMath::Abs(shift)>0) 89 AlignExtractionWindow(maxp, frac); 90 91 // Now we have found the "final" position: extract time and charge 92 const Double_t sumamp = Eval(fWeightsAmp, maxp, frac); 93 94 fSignal = sumamp; 95 if (sumamp == 0) 96 return; 97 98 const Double_t sumtime = Eval(fWeightsTime, maxp, frac); 88 99 89 100 // This is used to align the weights to bins between 90 101 // -0.5/fWeightsPerBin and 0.5/fWeightsPerBin instead of 91 102 // 0 and 1./fWeightsPerBin 92 const Float_t halfres = 0.5/fWeightsPerBin; 93 94 // move the extractor by an offset number of slices 95 // determined by the extracted time 96 const Int_t integ = TMath::FloorNint(time+halfres+0.5); 97 maxp -= integ; 98 99 // Convert the residual fraction of one slice into an 100 // offset position in the extraction weights 101 Int_t frac = TMath::FloorNint((time+halfres-integ)*fWeightsPerBin); 102 103 // Align maxp into available range 104 if (maxp < 0) 105 { 106 maxp = 0; 107 frac = -fWeightsPerBin/2; // Assume peak at the beginning of the first slice 108 } 109 if (maxp+windowsize > fNum) 110 { 111 maxp = fNum-windowsize; 112 frac = fWeightsPerBin/2-1; // Assume peak at the end of the last slice 113 } 114 115 Double_t sumamp, sumtime; 116 Eval(sumamp, sumtime, windowsize, maxp, frac); 117 118 fSignal = sumamp; 119 if (sumamp == 0) 120 return; 103 const Double_t binoffset = TMath::Even(fWeightsPerBin) ? 0.5 : 0; 104 105 fTime = maxp /*- 0.5*/ - Double_t(frac+binoffset)/fWeightsPerBin; 106 107 // To let the lowest value which can be safely extracted be>0: 108 // Take also a possible offset from timefineadjust into account 109 // Sould it be: fTime += fWindowSize/2; ??? 110 fTime += 0.5 + 0.5/fWeightsPerBin; 111 // In the ideal case the would never get <0 112 // But timefineadjust can be >0.05 (in 60% of the cases) 113 114 // Define in each extractor a lowest and highest extracted value! 121 115 122 116 // here, the first high-gain slice is already included 123 117 // in the fTimeShiftHiGain this shifts the time to the 124 118 // start of the rising edge 125 fTime = maxp - Float_t(frac)/fWeightsPerBin + timeshift; 119 120 // This is from MExtractTimeAndChargeDigitalFilter 121 // fTime += 0.5 + 1./fWeightsPerBin; 122 123 // Now there is a difference between the rising edge and 124 // the extracted time. This must be applied after 125 // the randomization in case of wrog values 126 126 127 127 const Float_t timefineadjust = sumtime/sumamp; 128 128 129 129 // FIXME: Is 3 a good value? 130 if (TMath::Abs(timefineadjust)*fWeightsPerBin < 3.) 130 //if (TMath::Abs(timefineadjust)*fWeightsPerBin < 3.) 131 // fTime -= timefineadjust; 132 133 // if (TMath::FloorNint(timefineadjust+0.5)==0) 134 135 //if (TMath::Abs(timefineadjust) < 0.2) 131 136 fTime -= timefineadjust; 132 137 } 138 139 #include <TH1.h> 140 #include <TH2.h> 141 #include <TMatrixD.h> 142 #include <TArrayF.h> 143 #include <iostream> 144 #include <TSpline.h> 145 #include <TProfile.h> 146 147 Bool_t MExtralgoDigitalFilter::CalculateWeights(TH1 &shape, const TH2 &autocorr, TArrayF &weightsamp, TArrayF &weightstime, Int_t wpb) 148 { 149 const Int_t weightsperbin = wpb<=0?shape.GetNbinsX()/autocorr.GetNbinsX():wpb; 150 151 if (wpb<=0 && weightsperbin*autocorr.GetNbinsX()!=shape.GetNbinsX()) 152 { 153 cout << "ERROR - Number of bins mismatch..." << endl; 154 cout << " Shape: " << shape.GetNbinsX() << endl; 155 cout << " ACorr: " << autocorr.GetNbinsX() << endl; 156 return kFALSE; 157 } 158 159 const TAxis &axe = *shape.GetXaxis(); 160 161 const Int_t first = axe.GetFirst()/weightsperbin; 162 const Int_t last = axe.GetLast() /weightsperbin; 163 164 const Int_t width = last-first; 165 166 cout << "Range: " << first << " <= bin < " << last << endl; 167 cout << "Window: " << width << endl; 168 cout << "W/Bin: " << weightsperbin << endl; 169 170 // --------------------------------------------- 171 172 const Float_t sum = shape.Integral(first*weightsperbin, last*weightsperbin-1)/weightsperbin; 173 shape.Scale(1./sum); 174 175 cout << "Sum: " << sum << endl; 176 177 // TGraph gr(&shape); 178 // TSpline5 val("Signal", &gr); 179 180 // FIXME: DELETE!!! 181 TH1 &derivative = *static_cast<TH1*>(shape.Clone()); 182 derivative.Reset(); 183 184 for (int i=0; i<derivative.GetNbinsX(); i++) 185 { 186 // const Float_t x = derivative.GetBinCenter(i+1); 187 // derivative.SetBinContent(i+1, val.Derivative(x)); 188 189 const Float_t binm = shape.GetBinContent(i+1-1); 190 const Float_t binp = shape.GetBinContent(i+1+1); 191 192 const Float_t der = (binp-binm)/2./shape.GetBinWidth(1); 193 194 derivative.SetBinContent(i+1, der); 195 196 if (derivative.InheritsFrom(TProfile::Class())) 197 static_cast<TProfile&>(derivative).SetBinEntries(i+1,1); 198 } 199 200 // --------------------------------------------- 201 202 TMatrixD B(width, width); 203 for (Int_t i=0; i<width; i++) 204 for (Int_t j=0; j<width; j++) 205 B[i][j]=autocorr.GetBinContent(i+1/*first*/, j+1/*first*/); 206 207 const TMatrixD Binv(TMatrixD::kInverted, B); 208 209 // --------------------------------------------- 210 211 weightsamp.Set(width*weightsperbin); 212 weightstime.Set(width*weightsperbin); 213 214 for (Int_t i=0; i<weightsperbin; i++) 215 { 216 TMatrixD g(width, 1); 217 TMatrixD d(width, 1); 218 219 for (Int_t bin=0; bin<width; bin++) 220 { 221 const Int_t idx = weightsperbin*(bin+first) + i; 222 223 g[bin][0]=shape.GetBinContent(idx+1); 224 d[bin][0]=derivative.GetBinContent(idx+1); 225 } 226 227 const TMatrixD gT(TMatrixD::kTransposed, g); 228 const TMatrixD dT(TMatrixD::kTransposed, d); 229 230 const TMatrixD denom = (gT*(Binv*g))*(dT*(Binv*d)) - (dT*(Binv*g))*(dT*(Binv*g)); 231 232 if (denom[0][0]==0) 233 { 234 cout << "ERROR - Division by zero: denom[0][0]==0 for i=" << i << "." << endl; 235 return kFALSE; 236 } 237 238 const TMatrixD w_amp = (dT*(Binv*d))*(gT*Binv) - (gT*(Binv*d))*(dT*Binv); 239 const TMatrixD w_time = (gT*(Binv*g))*(dT*Binv) - (gT*(Binv*d))*(gT*Binv); 240 241 for (Int_t bin=0; bin<width; bin++) 242 { 243 const Int_t idx = weightsperbin*bin + i; 244 245 weightsamp[idx] = w_amp [0][bin]/denom[0][0]; 246 weightstime[idx] = w_time[0][bin]/denom[0][0]; 247 } 248 } 249 250 return kTRUE; 251 } 252 253 void MExtralgoDigitalFilter::CalculateWeights2(TH1F &shape, const TH2F &autocorr, TArrayF &weightsamp, TArrayF &weightstime, Int_t wpb) 254 { 255 const Int_t weightsperbin = wpb<=0?shape.GetNbinsX()/autocorr.GetNbinsX():wpb; 256 257 if (wpb<=0 && weightsperbin*autocorr.GetNbinsX()!=shape.GetNbinsX()) 258 { 259 cout << "ERROR - Number of bins mismatch..." << endl; 260 cout << " Shape: " << shape.GetNbinsX() << endl; 261 cout << " ACorr: " << autocorr.GetNbinsX() << endl; 262 return; 263 } 264 265 const TAxis &axe = *shape.GetXaxis(); 266 267 const Int_t first = axe.GetFirst()/weightsperbin; 268 const Int_t last = axe.GetLast() /weightsperbin; 269 270 const Int_t width = last-first; 271 272 cout << "Range: " << first << " <= bin < " << last << endl; 273 cout << "Window: " << width << endl; 274 cout << "W/Bin: " << weightsperbin << endl; 275 276 // --------------------------------------------- 277 278 const Float_t sum = shape.Integral(first*weightsperbin, last*weightsperbin-1)/weightsperbin; 279 shape.Scale(1./sum); 280 281 TGraph gr(&shape); 282 TSpline5 val("Signal", &gr); 283 284 TH1F derivative(shape); 285 derivative.Reset(); 286 287 for (int i=0; i<derivative.GetNbinsX(); i++) 288 { 289 const Float_t x = derivative.GetBinCenter(i+1); 290 derivative.SetBinContent(i+1, val.Derivative(x)); 291 292 /* 293 const Float_t binm = shape.GetBinContent(i+1-1); 294 const Float_t binp = shape.GetBinContent(i+1+1); 295 296 const Float_t der = (binp-binm)/2./shape.GetBinWidth(1); 297 298 derivative.SetBinContent(i+1, der); 299 */ 300 } 301 302 // --------------------------------------------- 303 304 TMatrixD B(width, width); 305 for (Int_t i=0; i<width; i++) 306 for (Int_t j=0; j<width; j++) 307 B[i][j]=autocorr.GetBinContent(i+first, j+first); 308 B.Invert(); 309 310 // --------------------------------------------- 311 312 weightsamp.Set(width*weightsperbin); 313 weightstime.Set(width*weightsperbin); 314 315 for (Int_t i=0; i<weightsperbin; i++) 316 { 317 TMatrixD g(width, 1); 318 TMatrixD d(width, 1); 319 320 for (Int_t bin=0; bin<width; bin++) 321 { 322 const Int_t idx = weightsperbin*(bin+first) + i; 323 324 g[bin][0]=shape.GetBinContent(idx+1); 325 d[bin][0]=derivative.GetBinContent(idx+1); 326 } 327 328 const TMatrixD gT(TMatrixD::kTransposed, g); 329 const TMatrixD dT(TMatrixD::kTransposed, d); 330 331 const TMatrixD denom = (gT*(B*g))*(dT*(B*d)) - (dT*(B*g))*(dT*(B*g)); 332 333 const TMatrixD w_amp = (dT*(B*d))*(gT*B) - (gT*(B*d))*(dT*B); 334 const TMatrixD w_time = (gT*(B*g))*(dT*B) - (gT*(B*d))*(gT*B); 335 336 for (Int_t bin=0; bin<width; bin++) 337 { 338 const Int_t idx = weightsperbin*bin + i; 339 340 weightsamp[idx] = w_amp [0][bin]/denom[0][0]; 341 weightstime[idx] = w_time[0][bin]/denom[0][0]; 342 } 343 } 344 } 345 /* 346 Int_t start = fBinningResolutionHiGain*(fSignalStartBinHiGain + 1); 347 for (Int_t i = -fBinningResolutionHiGain/2+1; i<=fBinningResolutionHiGain/2; i++) 348 { 349 // i = -4...5 350 for (Int_t count=0; count < fWindowSizeHiGain; count++) 351 { 352 // count=0: pos=10*(start+0) + 10 + i 353 // count=1: pos=10*(start+1) + 10 + i 354 // count=2: pos=10*(start+2) + 10 + i 355 // count=3: pos=10*(start+3) + 10 + i 356 } 357 358 for (Int_t count=0; count < fWindowSizeHiGain; count++) 359 { 360 // count=0: pos = 10*0 + 5 +i-1 361 // count=1: pos = 10*1 + 5 +i-1 362 // count=2: pos = 10*2 + 5 +i-1 363 // count=3: pos = 10*3 + 5 +i-1 364 } 365 } 366 367 Int_t start = fBinningResolutionLoGain*fSignalStartBinLoGain + fBinningResolutionLoGain/2; 368 for (Int_t i = -fBinningResolutionLoGain/2+1; i<=fBinningResolutionLoGain/2; i++) 369 { 370 // i=-4..5 371 for (Int_t count=0; count < fWindowSizeLoGain; count++) 372 { 373 // count=0: pos = 10*(start+0) + 5 + i 374 // count=1: pos = 10*(start+1) + 5 + i 375 // count=2: pos = 10*(start+2) + 5 + i 376 // count=3: pos = 10*(start+3) + 5 + i 377 } 378 379 for (Int_t count=0; count < fWindowSizeLoGain; count++) 380 { 381 // count=0: pos = 10*0 + 5 +i-1 382 // count=1: pos = 10*1 + 5 +i-1 383 // count=2: pos = 10*2 + 5 +i-1 384 // count=3: pos = 10*3 + 5 +i-1 385 } 386 } 387 */ -
trunk/MagicSoft/Mars/mextralgo/MExtralgoDigitalFilter.h
r7942 r8072 5 5 #include <TROOT.h> 6 6 #endif 7 8 class TH1; 9 class TH2; 10 class TH1F; 11 class TH2F; 12 class TArrayF; 7 13 8 14 class MExtralgoDigitalFilter … … 13 19 Int_t fNum; 14 20 15 Float_t *fWeightsAmp;16 Float_t *fWeightsTime;21 Float_t const *fWeightsAmp; 22 Float_t const *fWeightsTime; 17 23 18 Int_t fWeightsPerBin; // Number of weights per data bin 24 const Int_t fWeightsPerBin; // Number of weights per data bin 25 const Int_t fWindowSize; 19 26 20 27 // Result … … 24 31 Float_t fSignalDev; 25 32 26 inline void Eval(Double_t &sumamp, Double_t &sumtime, const Int_t windowsize, const Int_t startv, const Int_t startw=0) const 33 // Weights: Weights to evaluate 34 // Startv: Index of first bin of data 35 // startw: Offset on the weights 36 inline Double_t Eval(Float_t const *weights, const Int_t startv, const Int_t startw=0) const 27 37 { 28 38 // … … 30 40 // and multiply the entries with the corresponding weights 31 41 // 32 sumamp = 0; 33 sumtime = 0; 42 Double_t sum = 0; 34 43 35 44 // Shift the start of the weight to the center of sample 0 36 Float_t const *w a = fWeightsAmp + fWeightsPerBin/2+ startw;37 Float_t const *wt = fWeightsTime + fWeightsPerBin/2 + startw; 45 Float_t const *w = weights + startw; 46 38 47 Float_t *const beg = fVal+startv; 48 for (Float_t const *pex=beg; pex<beg+fWindowSize; pex++) 49 { 50 sum += *w * *pex; 51 w += fWeightsPerBin; 52 } 53 return sum; 54 } 39 55 40 for (Float_t const *pex=beg; pex<beg+windowsize; pex++) 56 inline void AlignIntoLimits(Int_t &maxp, Int_t &frac) const 57 { 58 // Align maxp into available range (TO BE CHECKED) 59 if (maxp < 0) 41 60 { 42 sumamp += *wa * *pex; 43 sumtime += *wt * *pex; 44 45 // Step forward by one bin 46 wa += fWeightsPerBin; 47 wt += fWeightsPerBin; 61 maxp = 0; 62 frac = fWeightsPerBin/2-1; // Assume peak at the end of the last slice 63 } 64 if (maxp > fNum-fWindowSize) 65 { 66 maxp = fNum-fWindowSize; 67 frac = -fWeightsPerBin/2; // Assume peak at the beginning of the first slice 48 68 } 49 69 } 50 70 71 inline Int_t AlignExtractionWindow(Int_t &maxp, Int_t &frac, const Double_t ampsum) 72 { 73 // Align extraction window to signal position 74 75 const Double_t timesum = Eval(fWeightsTime, maxp, frac); 76 77 // Because fWeightsPerBin/2 doesn't correspond to the center 78 // of a bin the time-values extracted are slightly positive. 79 // They are roughly between -0.45 and 0.55 80 const Double_t binoffset = TMath::Even(fWeightsPerBin) ? 0.5 : 0; 81 82 // This is the time offset from the extraction position 83 Double_t tmoffset = (frac+binoffset)/fWeightsPerBin + timesum/ampsum; 84 85 // Convert the residual fraction of one slice into an 86 // offset position in the extraction weights 87 const Int_t integ = TMath::FloorNint(tmoffset+0.5); 88 89 /* 90 if (integ>0) 91 tmoffset=0.49-0.05; 92 if (integ<0) 93 tmoffset=-0.49-0.05; 94 integ=0; 95 */ 96 97 // move the extractor by an offset number of slices 98 // determined by the extracted time 99 maxp -= integ; 100 101 frac = TMath::FloorNint((tmoffset-integ)*fWeightsPerBin); 102 103 // Align maxp into available range (TO BE CHECKED) 104 AlignIntoLimits(maxp, frac); 105 106 return integ; 107 } 108 109 inline void AlignExtractionWindow(Int_t &maxp, Int_t &frac) 110 { 111 const Double_t amp = Eval(fWeightsAmp, maxp, frac); 112 if (amp!=0) 113 AlignExtractionWindow(maxp, frac, amp); 114 } 115 51 116 public: 52 MExtralgoDigitalFilter(Float_t *val, Int_t n, Float_t *wa, Float_t *wt) 53 : fVal(val), fNum(n), 54 fWeightsAmp(wa), fWeightsTime(wt), fTime(0), fTimeDev(-1), fSignal(0), fSignalDev(-1) 117 MExtralgoDigitalFilter(Int_t res, Int_t windowsize, Float_t *wa, Float_t *wt) 118 : fVal(0), fNum(0), fWeightsAmp(wa+res/2), fWeightsTime(wt+res/2), 119 fWeightsPerBin(res), fWindowSize(windowsize), 120 fTime(0), fTimeDev(-1), fSignal(0), fSignalDev(-1) 55 121 { 56 122 } 57 123 58 void Set WeightsPerBin(Int_t res) { fWeightsPerBin=res; }124 void SetData(Int_t n, Float_t *val) { fNum=n; fVal=val; } 59 125 60 126 Float_t GetTime() const { return fTime; } … … 67 133 void GetTime(Float_t &sig, Float_t &dsig) const { sig=fTime; dsig=fTimeDev; } 68 134 69 Float_t ExtractNoise(Int_t iter, Int_t windowsize) const; 70 void Extract(Int_t windowsize, Float_t timeshift); 135 Float_t ExtractNoise(Int_t iter) const; 136 void Extract(); 137 138 static Bool_t CalculateWeights(TH1 &shape, const TH2 &autocorr, TArrayF &wa, TArrayF &wt, Int_t wpb=-1); 139 static void CalculateWeights2(TH1F &shape, const TH2F &autocorr, TArrayF &wa, TArrayF &wt, Int_t wpb=-1); 71 140 }; 72 141
Note:
See TracChangeset
for help on using the changeset viewer.