source: trunk/MagicSoft/Mars/mextralgo/MExtralgoDigitalFilter.cc@ 8179

Last change on this file since 8179 was 8165, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 13.7 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Hendrik Bartko, 09/2004 <mailto:hbartko@mppmu.mpg.de>
19! Author(s): Thomas Bretz, 08/2006 <mailto:tbretz@astro.uni-wuerzburg.de>
20!
21! Copyright: MAGIC Software Development, 2000-2006
22!
23!
24\* ======================================================================== */
25
26//////////////////////////////////////////////////////////////////////////////
27//
28// MExtralgoDigitalFilter
29//
30//////////////////////////////////////////////////////////////////////////////
31#include "MExtralgoDigitalFilter.h"
32
33using namespace std;
34
35Float_t MExtralgoDigitalFilter::ExtractNoise(Int_t iter) const
36{
37 return Eval(fWeightsAmp, 0, iter-fWeightsPerBin/2);
38}
39
40// -----------------------------------------------------------------------------
41//
42// Calculates the chi2 of the fit, once the weights have been iterated.
43// Argument: time, obtained after a call to EvalDigitalFilterHiGain
44//
45Float_t MExtralgoDigitalFilter::GetChisq(const Int_t maxp, const Int_t frac, const Float_t sum) const
46{
47 /*
48 TMatrix g (windowh,1);
49 TMatrix gt(windowh,1);
50 TMatrix y (windowh,1);
51
52 const Float_t etau = fFineAdjustHi*sumhi;
53 const Float_t t_fine = TMath::Abs(fFineAdjustHi)< 1./fBinningResolutionHiGain ? -fFineAdjustHi : 0.;
54
55 // if (t_fine==0.)
56 // return -1.;
57
58 if (fDebug)
59 gLog << all << " fMaxPHi: " << fMaxPHi << " fIterPHi " << fIterPHi << " t_fine: " << t_fine << endl;
60
61 //
62 // Slide with a window of size windowh over the sample
63 // and calculate the arrays by interpolating the pulse shape using the
64 // fine-tuned time information.
65 //
66 for (Int_t sample=0; sample &lt; windowh; sample++)
67 {
68 const Int_t idx = fArrBinningResHalfHiGain[sample] + fIterPHi;
69 const Int_t ids = fMaxPHi + sample;
70
71 y [sample][0] = fHiGainSignalDF[ids];
72 g [sample][0] = t_fine >= 0
73 ? (fPulseShapeHiGain[idx] + t_fine*(fPulseShapeHiGain[idx+1] -fPulseShapeHiGain[idx]) )*sumhi
74 : (fPulseShapeHiGain[idx] + t_fine*(fPulseShapeHiGain[idx] -fPulseShapeHiGain[idx-1]))*sumhi;
75 gt[sample][0] = t_fine >= 0
76 ? (fPulseShapeDotHiGain[idx] + t_fine*(fPulseShapeDotHiGain[idx+1]-fPulseShapeDotHiGain[idx]) )*etau
77 : (fPulseShapeDotHiGain[idx] + t_fine*(fPulseShapeDotHiGain[idx] -fPulseShapeDotHiGain[idx-1]) )*etau;
78 }
79
80 TMatrix second = y - g - gt;
81 TMatrix first(TMatrix::kTransposed,second);
82 TMatrix chisq = first * ((*fBHiInv)*second);
83
84 return chisq[0][0]/(windowh-2);
85 */
86/*
87
88 TMatrix S(fWindowSize, 1); // Signal (start==start of window)
89 for (int i=0; i<fWindowSize; i++)
90 S[i][0] = fVal[i+maxp];
91
92 TMatrix g(fWindowSize, 1);
93 //TMatrix gT(fWindowSize, 1);
94
95 for (int i=0; i<fWindowSize; i++)
96 {
97 Int_t idx = fWeightsPerBin*i + frac;
98
99 // FIXME: Maybe we could do an interpolation on time-fineadj?
100 //Float_t slope = fPulseShapeHiGain[idx+1] -fPulseShapeHiGain[idx];
101 //Float_t slopet = fPulseShapeDotHiGain[idx+1]-fPulseShapeDotHiGain[idx];
102
103 g[i][0] = fPulseShapeHiGain[idx] *sumhi;
104 //gT[i][0] = fPulseShapeHiGainDot[idx]*tau;
105 }
106
107 TMatrix Ainv; // Autocorrelation Matrix (inverted)
108
109 TMatrix m = S - g;// - gT;
110 TMatrix mT(TMatrix::kTransposed, m);
111
112 TMatrix chisq = mT * (Ainv*m);
113
114 return chisq[0][0]/(fWindowSize-2);
115 */
116
117 Double_t sumc = 0;
118
119 TMatrix d(fWindowSize, 1); // Signal (start==start of window)
120 for (int i=0; i<fWindowSize; i++)
121 {
122 d[i][0] = fVal[i+maxp]/sum - fPulseShape[fWeightsPerBin*i + frac];
123 sumc += d[i][0]*d[i][0];
124 }
125
126/*
127 TMatrix Ainv; // Autocorrelation Matrix (inverted)
128
129 TMatrix dT(TMatrix::kTransposed, d);
130
131 TMatrix chisq = dT * (*fAinv*d);
132 */
133 return sumc;//chisq[0][0]/(fWindowSize-2);
134}
135
136#include <iostream>
137void MExtralgoDigitalFilter::Extract(Int_t maxpos)
138{
139 fSignal = 0; // default is: no pulse found
140 fTime = -1; // default is: out if range (--> random)
141 fSignalDev = 0; // default is: valid
142 fTimeDev = 0; // default is: valid
143
144 // FIXME: How to handle saturation?
145
146 Double_t maxamp = -FLT_MAX;
147 Int_t maxp = -1;
148
149 //
150 // Calculate the sum of the first fWindowSize slices
151 //
152 // For the case of an even number of weights/bin there is
153 // no central bin.So we create an artificial central bin.
154 for (Int_t i=0; i<fNum-fWindowSize+1; i++)
155 {
156 const Double_t sumamp = Eval(fWeightsAmp, i);
157 if (sumamp>maxamp)
158 {
159 maxamp = sumamp;
160 maxp = i;
161 }
162 }
163
164 /*
165 // This could be for a fast but less accurate extraction....
166 maxamp = Eval(fWeightsAmp, maxpos-fWindowSize/2);
167 maxp = maxpos-fWindowSize/2;
168 */
169
170 // The number of available slices were smaller than the
171 // extraction window size of the extractor
172 if (maxp<0)
173 {
174 fSignalDev = -1; // means: is invalid
175 fTimeDev = -1; // means: is invalid
176 return;
177 }
178
179 // For some reason (by chance or because all slices contain 0)
180 // maxamp is 0. This means the signal is zero and no arrival
181 // time can be extracted (but both informations are valid)
182 if (maxamp==0)
183 return;
184
185 Int_t frac = 0;
186 const Int_t shift = AlignExtractionWindow(maxp, frac, maxamp);
187
188 // For safety we do another iteration if we have
189 // shifted the extraction window
190 if (TMath::Abs(shift)>0)
191 AlignExtractionWindow(maxp, frac);
192
193 // Now we have found the "final" position: extract time and charge
194 const Double_t sumamp = Eval(fWeightsAmp, maxp, frac);
195
196 fSignal = sumamp;
197 if (sumamp == 0)
198 return;
199
200 const Double_t sumtime = Eval(fWeightsTime, maxp, frac);
201
202 // This is used to align the weights to bins between
203 // -0.5/fWeightsPerBin and 0.5/fWeightsPerBin instead of
204 // 0 and 1./fWeightsPerBin
205 const Double_t binoffset = TMath::Even(fWeightsPerBin) ? 0.5 : 0;
206
207 fTime = maxp /*- 0.5*/ - Double_t(frac+binoffset)/fWeightsPerBin;
208
209 // To let the lowest value which can be safely extracted be>0:
210 // Take also a possible offset from timefineadjust into account
211 // Sould it be: fTime += fWindowSize/2; ???
212
213 // HERE we should add the distance from the beginning of the
214 // extraction window to the leading edge!
215 fTime += 0.5 + 0.5/fWeightsPerBin;
216 // Define in each extractor a lowest and highest extracted value!
217
218 const Float_t timefineadjust = sumtime/sumamp;
219
220 //if (TMath::Abs(timefineadjust) < 0.2)
221 fTime -= timefineadjust;
222}
223
224
225#include <TH1.h>
226#include <TH2.h>
227#include <TMatrixD.h>
228#include <TArrayF.h>
229#include <iostream>
230#include <TSpline.h>
231#include <TProfile.h>
232
233Int_t MExtralgoDigitalFilter::CalculateWeights(TH1 &shape, const TH2 &autocorr, TArrayF &weightsamp, TArrayF &weightstime, Int_t wpb)
234{
235 const Int_t weightsperbin = wpb<=0?shape.GetNbinsX()/autocorr.GetNbinsX():wpb;
236
237 if (wpb<=0 && weightsperbin*autocorr.GetNbinsX()!=shape.GetNbinsX())
238 {
239 cout << "ERROR - Number of bins mismatch..." << endl;
240 cout << " Shape: " << shape.GetNbinsX() << endl;
241 cout << " ACorr: " << autocorr.GetNbinsX() << endl;
242 return -1;
243 }
244
245 const TAxis &axe = *shape.GetXaxis();
246
247 const Int_t first = axe.GetFirst()/weightsperbin;
248 const Int_t last = axe.GetLast() /weightsperbin;
249
250 const Int_t width = last-first;
251
252 cout << "Range: " << first << " <= bin < " << last << endl;
253 cout << "Window: " << width << endl;
254 cout << "W/Bin: " << weightsperbin << endl;
255
256 // ---------------------------------------------
257
258 const Float_t sum = shape.Integral(first*weightsperbin, last*weightsperbin-1)/weightsperbin;
259 shape.Scale(1./sum);
260
261 cout << "Sum: " << sum << endl;
262
263// TGraph gr(&shape);
264// TSpline5 val("Signal", &gr);
265
266 // FIXME: DELETE!!!
267 TH1 &derivative = *static_cast<TH1*>(shape.Clone());
268 derivative.SetDirectory(0);
269 derivative.Reset();
270
271 for (int i=0; i<derivative.GetNbinsX(); i++)
272 {
273// const Float_t x = derivative.GetBinCenter(i+1);
274// derivative.SetBinContent(i+1, val.Derivative(x));
275
276 const Float_t binm = shape.GetBinContent(i+1-1);
277 const Float_t binp = shape.GetBinContent(i+1+1);
278
279 const Float_t der = (binp-binm)/2./shape.GetBinWidth(1);
280
281 derivative.SetBinContent(i+1, der);
282
283 if (derivative.InheritsFrom(TProfile::Class()))
284 static_cast<TProfile&>(derivative).SetBinEntries(i+1,1);
285 }
286
287 // ---------------------------------------------
288
289 TMatrixD B(width, width);
290 for (Int_t i=0; i<width; i++)
291 for (Int_t j=0; j<width; j++)
292 B[i][j]=autocorr.GetBinContent(i+1/*first*/, j+1/*first*/);
293
294 const TMatrixD Binv(TMatrixD::kInverted, B);
295
296 // ---------------------------------------------
297
298 weightsamp.Set(width*weightsperbin);
299 weightstime.Set(width*weightsperbin);
300
301 for (Int_t i=0; i<weightsperbin; i++)
302 {
303 TMatrixD g(width, 1);
304 TMatrixD d(width, 1);
305
306 for (Int_t bin=0; bin<width; bin++)
307 {
308 const Int_t idx = weightsperbin*(bin+first) + i;
309
310 g[bin][0]=shape.GetBinContent(idx+1);
311 d[bin][0]=derivative.GetBinContent(idx+1);
312 }
313
314 const TMatrixD gT(TMatrixD::kTransposed, g);
315 const TMatrixD dT(TMatrixD::kTransposed, d);
316
317 const TMatrixD denom = (gT*(Binv*g))*(dT*(Binv*d)) - (dT*(Binv*g))*(dT*(Binv*g));
318
319 if (denom[0][0]==0)
320 {
321 cout << "ERROR - Division by zero: denom[0][0]==0 for i=" << i << "." << endl;
322 return -1;
323 }
324
325 const TMatrixD w_amp = (dT*(Binv*d))*(gT*Binv) - (gT*(Binv*d))*(dT*Binv);
326 const TMatrixD w_time = (gT*(Binv*g))*(dT*Binv) - (gT*(Binv*d))*(gT*Binv);
327
328 for (Int_t bin=0; bin<width; bin++)
329 {
330 const Int_t idx = weightsperbin*bin + i;
331
332 weightsamp[idx] = w_amp [0][bin]/denom[0][0];
333 weightstime[idx] = w_time[0][bin]/denom[0][0];
334 }
335 }
336
337 return first*weightsperbin;
338}
339
340Int_t MExtralgoDigitalFilter::CalculateWeights2(TH1 &shape, const TH2 &autocorr, TArrayF &weightsamp, TArrayF &weightstime, Int_t wpb)
341{
342 const Int_t weightsperbin = wpb<=0?shape.GetNbinsX()/autocorr.GetNbinsX():wpb;
343
344 if (wpb<=0 && weightsperbin*autocorr.GetNbinsX()!=shape.GetNbinsX())
345 {
346 cout << "ERROR - Number of bins mismatch..." << endl;
347 cout << " Shape: " << shape.GetNbinsX() << endl;
348 cout << " ACorr: " << autocorr.GetNbinsX() << endl;
349 return -1;
350 }
351
352 const TAxis &axe = *shape.GetXaxis();
353
354 const Int_t first = axe.GetFirst()/weightsperbin;
355 const Int_t last = axe.GetLast() /weightsperbin;
356
357 const Int_t width = last-first;
358
359 cout << "Range: " << first << " <= bin < " << last << endl;
360 cout << "Window: " << width << endl;
361 cout << "W/Bin: " << weightsperbin << endl;
362
363 // ---------------------------------------------
364
365 const Float_t sum = shape.Integral(first*weightsperbin, last*weightsperbin-1)/weightsperbin;
366 shape.Scale(1./sum);
367
368 TGraph gr(&shape);
369 TSpline5 val("Signal", &gr);
370
371 // FIXME: DELETE!!!
372 TH1 &derivative = *static_cast<TH1*>(shape.Clone());
373 derivative.SetDirectory(0);
374 derivative.Reset();
375
376 for (int i=0; i<derivative.GetNbinsX(); i++)
377 {
378 const Float_t x = derivative.GetBinCenter(i+1);
379 derivative.SetBinContent(i+1, val.Derivative(x));
380
381 /*
382 const Float_t binm = shape.GetBinContent(i+1-1);
383 const Float_t binp = shape.GetBinContent(i+1+1);
384
385 const Float_t der = (binp-binm)/2./shape.GetBinWidth(1);
386
387 derivative.SetBinContent(i+1, der);
388 */
389 }
390
391 // ---------------------------------------------
392
393 TMatrixD B(width, width);
394 for (Int_t i=0; i<width; i++)
395 for (Int_t j=0; j<width; j++)
396 B[i][j]=autocorr.GetBinContent(i+first, j+first);
397 B.Invert();
398
399 // ---------------------------------------------
400
401 weightsamp.Set(width*weightsperbin);
402 weightstime.Set(width*weightsperbin);
403
404 for (Int_t i=0; i<weightsperbin; i++)
405 {
406 TMatrixD g(width, 1);
407 TMatrixD d(width, 1);
408
409 for (Int_t bin=0; bin<width; bin++)
410 {
411 const Int_t idx = weightsperbin*(bin+first) + i;
412
413 g[bin][0]=shape.GetBinContent(idx+1);
414 d[bin][0]=derivative.GetBinContent(idx+1);
415 }
416
417 const TMatrixD gT(TMatrixD::kTransposed, g);
418 const TMatrixD dT(TMatrixD::kTransposed, d);
419
420 const TMatrixD denom = (gT*(B*g))*(dT*(B*d)) - (dT*(B*g))*(dT*(B*g));
421
422 if (denom[0][0]==0)
423 {
424 cout << "ERROR - Division by zero: denom[0][0]==0 for i=" << i << "." << endl;
425 return -1;
426 }
427
428 const TMatrixD w_amp = (dT*(B*d))*(gT*B) - (gT*(B*d))*(dT*B);
429 const TMatrixD w_time = (gT*(B*g))*(dT*B) - (gT*(B*d))*(gT*B);
430
431 for (Int_t bin=0; bin<width; bin++)
432 {
433 const Int_t idx = weightsperbin*bin + i;
434
435 weightsamp[idx] = w_amp [0][bin]/denom[0][0];
436 weightstime[idx] = w_time[0][bin]/denom[0][0];
437 }
438 }
439 return first*weightsperbin;
440}
Note: See TracBrowser for help on using the repository browser.