source: trunk/MagicSoft/Mars/msignal/MExtractTimeAndChargeSlidingWindow.cc@ 6121

Last change on this file since 6121 was 6121, checked in by gaug, 20 years ago
*** empty log message ***
File size: 14.0 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 analyzing 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! Author(s): Markus Gaug, 09/2004 <mailto:markus@ifae.es>
18! Author(s): Hendrik Bartko, 01/2004 <mailto:hbartko@mppmu.mpg.de>
19!
20! Copyright: MAGIC Software Development, 2002-2005
21!
22!
23\* ======================================================================== */
24//////////////////////////////////////////////////////////////////////////////
25//
26// MExtractSlidingWindow
27//
28// Extracts the signal from a sliding window of size fHiGainWindowSize and
29// fLoGainWindowSize, respectively. The signal is the one which maximizes
30// the clock-noise and pedestal-corrected integral contents.
31//
32// The amplitude-weighted arrival time is calculated from the window with
33// the highest integral using the following formula:
34//
35// t = sum(s(i) * i) / sum(i)
36//
37// where i denotes the FADC slice index and s(i) the clock-noise and
38/// pedestal-corrected FADC value at slice index i. The sum runs over the
39// extraction window size.
40//
41// Call: SetRange(higainfirst, higainlast, logainfirst, logainlast)
42// to modify the ranges in which the window is allowed to move.
43//
44// Defaults are:
45//
46// fHiGainFirst = fgHiGainFirst = 0
47// fHiGainLast = fgHiGainLast = 14
48// fLoGainFirst = fgLoGainFirst = 2
49// fLoGainLast = fgLoGainLast = 14
50//
51// Call: SetWindowSize(windowhigain, windowlogain)
52// to modify the sliding window widths. Windows have to be an even number.
53// Odd numbers are possible since the clock-noise is corrected for.
54//
55// Defaults are:
56//
57// fHiGainWindowSize = 6
58// fLoGainWindowSize = 6
59//
60//////////////////////////////////////////////////////////////////////////////
61#include "MExtractTimeAndChargeSlidingWindow.h"
62
63#include "MPedestalPix.h"
64
65#include "MLog.h"
66#include "MLogManip.h"
67
68ClassImp(MExtractTimeAndChargeSlidingWindow);
69
70using namespace std;
71
72const Byte_t MExtractTimeAndChargeSlidingWindow::fgHiGainFirst = 2;
73const Byte_t MExtractTimeAndChargeSlidingWindow::fgHiGainLast = 16;
74const Byte_t MExtractTimeAndChargeSlidingWindow::fgLoGainFirst = 2;
75const Byte_t MExtractTimeAndChargeSlidingWindow::fgLoGainLast = 14;
76const Byte_t MExtractTimeAndChargeSlidingWindow::fgHiGainWindowSize = 6;
77const Byte_t MExtractTimeAndChargeSlidingWindow::fgLoGainWindowSize = 6;
78// --------------------------------------------------------------------------
79//
80// Default constructor.
81//
82// Calls:
83// - SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast)
84//
85// Initializes:
86// - fWindowSizeHiGain to fgHiGainWindowSize
87// - fWindowSizeLoGain to fgLoGainWindowSize
88//
89MExtractTimeAndChargeSlidingWindow::MExtractTimeAndChargeSlidingWindow(const char *name, const char *title)
90{
91
92 fName = name ? name : "MExtractTimeAndChargeSlidingWindow";
93 fTitle = title ? title : "Calculate arrival times and charges using a sliding window";
94
95 fWindowSizeHiGain = fgHiGainWindowSize;
96 fWindowSizeLoGain = fgLoGainWindowSize;
97
98 SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast);
99}
100
101//-------------------------------------------------------------------
102//
103// Set the ranges
104//
105// Calls:
106// - MExtractor::SetRange(hifirst,hilast,lofirst,lolast);
107// - SetWindowSize(fWindowSizeHiGain,fWindowSizeLoGain);
108//
109void MExtractTimeAndChargeSlidingWindow::SetRange(Byte_t hifirst, Byte_t hilast, Byte_t lofirst, Byte_t lolast)
110{
111
112 MExtractor::SetRange(hifirst, hilast, lofirst, lolast);
113
114 //
115 // Redo the checks if the window is still inside the ranges
116 //
117 SetWindowSize(fWindowSizeHiGain,fWindowSizeLoGain);
118
119}
120
121// -----------------------------------------------------------------------------------------
122//
123// Checks:
124// - if a window is bigger than the one defined by the ranges, set it to the available range
125// - if a window is smaller than 2, set it to 2
126//
127// Sets:
128// - fNumHiGainSamples to: (Float_t)fWindowSizeHiGain
129// - fNumLoGainSamples to: (Float_t)fWindowSizeLoGain
130// - fSqrtHiGainSamples to: TMath::Sqrt(fNumHiGainSamples)
131// - fSqrtLoGainSamples to: TMath::Sqrt(fNumLoGainSamples)
132//
133void MExtractTimeAndChargeSlidingWindow::SetWindowSize(Int_t windowh, Int_t windowl)
134{
135
136 fWindowSizeHiGain = windowh;
137 fWindowSizeLoGain = windowl;
138
139 const Int_t availhirange = (Int_t)(fHiGainLast-fHiGainFirst+1);
140
141 if (fWindowSizeHiGain > availhirange)
142 {
143 *fLog << warn << GetDescriptor()
144 << Form("%s%2i%s%2i%s%2i%s",": Hi Gain window size: ",(int)fWindowSizeHiGain,
145 " is bigger than available range: [",(int)fHiGainFirst,",",(int)fHiGainLast,"]") << endl;
146 *fLog << warn << GetDescriptor()
147 << ": Will set window size to: " << (int)availhirange << endl;
148 fWindowSizeHiGain = availhirange;
149 }
150
151 if (fWindowSizeHiGain<1)
152 {
153 fWindowSizeHiGain = 1;
154 *fLog << warn << GetDescriptor() << ": High Gain window size too small, set to one sample" << endl;
155 }
156
157 if (fLoGainLast != 0 && fWindowSizeLoGain != 0)
158 {
159 const Int_t availlorange = (Int_t)(fLoGainLast-fLoGainFirst+1);
160
161 if (fWindowSizeLoGain > availlorange)
162 {
163 *fLog << warn << GetDescriptor()
164 << Form("%s%2i%s%2i%s%2i%s",": Lo Gain window size: ",(int)fWindowSizeLoGain,
165 " is bigger than available range: [",(int)fLoGainFirst,",",(int)fLoGainLast,"]") << endl;
166 *fLog << warn << GetDescriptor()
167 << ": Will set window size to: " << (int)availlorange << endl;
168 fWindowSizeLoGain = availlorange;
169 }
170 }
171
172 fNumHiGainSamples = (Float_t)fWindowSizeHiGain;
173 fNumLoGainSamples = fLoGainLast ? (Float_t)fWindowSizeLoGain : 0.;
174
175 fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
176 fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples);
177
178}
179
180// --------------------------------------------------------------------------
181//
182// InitArrays
183//
184// Gets called in the ReInit() and initialized the arrays
185//
186Bool_t MExtractTimeAndChargeSlidingWindow::InitArrays()
187{
188 Int_t range = (Int_t)(fHiGainLast - fHiGainFirst + 1 + fHiLoLast);
189 fHiGainSignal.Set(range);
190 range = (Int_t)(fLoGainLast - fLoGainFirst + 1);
191 fLoGainSignal.Set(range);
192
193 return kTRUE;
194
195}
196
197// --------------------------------------------------------------------------
198//
199// Calculates the arrival time for each pixel
200//
201void MExtractTimeAndChargeSlidingWindow::FindTimeAndChargeHiGain(Byte_t *first, Byte_t *logain, Float_t &sum, Float_t &dsum,
202 Float_t &time, Float_t &dtime,
203 Byte_t &sat, const MPedestalPix &ped, const Bool_t abflag)
204{
205
206 Int_t range = fHiGainLast - fHiGainFirst + 1;
207 const Byte_t *end = first + range;
208 Byte_t *p = first;
209
210 Float_t max = 0; // highest integral content of all windows
211 Int_t count = 0;
212 sat = 0;
213
214 const Float_t pedes = ped.GetPedestal();
215 const Float_t ABoffs = ped.GetPedestalABoffset();
216
217 Float_t PedMean[2] = { pedes + ABoffs, pedes - ABoffs };
218
219 fMaxBinContent = 0;
220 //
221 // Check for saturation in all other slices
222 //
223 Int_t ids = fHiGainFirst;
224
225 while (p<first+fWindowSizeHiGain)
226 {
227
228 const Float_t signal = (Float_t)*p - PedMean[(ids++ + abflag) & 0x1];
229 sum += signal;
230 fHiGainSignal[count] = signal;
231
232 if (*p > fMaxBinContent)
233 fMaxBinContent = *p;
234
235 if (*p++ >= fSaturationLimit)
236 if (!sat)
237 sat = ids-2;
238
239 count++;
240 }
241
242 //
243 // Check for saturation in all other slices
244 //
245 while (p<end)
246 {
247 if (*p > fMaxBinContent)
248 fMaxBinContent = *p;
249
250 if (*p++ >= fSaturationLimit)
251 if (!sat)
252 sat = ids-2;
253 }
254
255 if (IsNoiseCalculation())
256 return;
257
258 //
259 // Calculate the i-th sum as
260 // sum_i+1 = sum_i + slice[i+8] - slice[i]
261 // This is fast and accurate (because we are using int's)
262 //
263 count = 0;
264 max = sum;
265 Int_t idx = 0; // idx of the first slice of the maximum window
266
267 for (p=first; p+fWindowSizeHiGain<end; p++)
268 {
269
270 const Float_t signal = (Float_t)*(p+fWindowSizeHiGain) - PedMean[(ids++ + abflag) & 0x1];
271 sum += signal - fHiGainSignal[count];
272 fHiGainSignal[count + fWindowSizeHiGain] = signal;
273
274 if (sum>max)
275 {
276 max = sum;
277 idx = count+1;
278 }
279 count++;
280 }
281
282 if (fHiLoLast != 0)
283 {
284
285 //
286 // overlap bins
287 //
288 Byte_t *l = logain;
289
290 while (p < end && l < logain+fHiLoLast)
291 {
292
293 const Float_t signal = (Float_t)*l - PedMean[(ids++ + abflag) & 0x1];
294 sum += signal - fHiGainSignal[count];
295 fHiGainSignal[count + fWindowSizeHiGain] = signal;
296
297 if (*l > fMaxBinContent)
298 fMaxBinContent = *logain;
299
300 if (*l++ >= fSaturationLimit)
301 if (!sat)
302 sat = ids-2;
303
304 if (sum>max)
305 {
306 max = sum;
307 idx = count+1;
308 }
309 count++;
310 p++;
311 }
312
313 if (fHiLoLast > (Byte_t)fWindowSizeHiGain)
314 {
315 while (l < logain + fHiLoLast)
316 {
317 const Float_t signal = (Float_t)*l - PedMean[(ids++ + abflag) & 0x1];
318 sum += signal - fHiGainSignal[count];
319 fHiGainSignal[count+fWindowSizeHiGain] = signal;
320
321 if (*l++ >= fSaturationLimit)
322 if (!sat)
323 sat = ids-2;
324
325 if (sum>max)
326 {
327 max = sum;
328 idx = count+1;
329 }
330 count++;
331 } /* while (l < logain + fHiLoLast) */
332 } /* if (fHiLoLast > fWindowSizeHiGain) */
333 } /* if (fHiLoLast != 0) */
334
335 //
336 // now calculate the time for the maximum window
337 //
338 Float_t timesignalsum = 0.;
339 Int_t timesquaredsum = 0;
340
341 for (Int_t i=idx; i<idx+fWindowSizeHiGain; i++)
342 {
343 timesignalsum += fHiGainSignal[i]*i;
344 timesquaredsum += i*i;
345 }
346
347 sum = max;
348
349 time = max > 0.1 ? timesignalsum / max + Float_t(fHiGainFirst) : 1.;
350 dtime = max > 0.1 ? ped.GetPedestalRms() / max * sqrt(timesquaredsum - fWindowSizeHiGain*time) : 1.;
351
352}
353
354
355// --------------------------------------------------------------------------
356//
357// Calculates the arrival time for each pixel
358//
359void MExtractTimeAndChargeSlidingWindow::FindTimeAndChargeLoGain(Byte_t *first, Float_t &sum, Float_t &dsum,
360 Float_t &time, Float_t &dtime,
361 Byte_t &sat, const MPedestalPix &ped, const Bool_t abflag)
362{
363
364 Int_t range = fLoGainLast - fLoGainFirst + 1;
365 const Byte_t *end = first + range;
366 Byte_t *p = first;
367
368 Float_t max = 0; // highest integral content of all windows
369 Int_t count = 0; // counter to recognize the AB-flag
370
371 Float_t pedes = ped.GetPedestal();
372 const Float_t ABoffs = ped.GetPedestalABoffset();
373
374 Float_t PedMean[2] = { pedes + ABoffs, pedes - ABoffs };
375 //
376 // Check for saturation in all other slices
377 //
378 Int_t ids = fLoGainFirst;
379
380 while (p<first+fWindowSizeLoGain)
381 {
382 const Float_t signal = (Float_t)*p - PedMean[(ids++ + abflag) & 0x1];
383 sum += signal;
384 fLoGainSignal[count] = signal;
385
386 if (*p++ >= fSaturationLimit)
387 sat++;
388
389 count++;
390 }
391
392 //
393 // Check for saturation in all other slices
394 //
395 while (p<end)
396 if (*p++ >= fSaturationLimit)
397 sat++;
398
399 if (IsNoiseCalculation())
400 return;
401
402 //
403 // Calculate the i-th sum as
404 // sum_i+1 = sum_i + slice[i+8] - slice[i]
405 // This is fast and accurate (because we are using int's)
406 //
407 count = 0;
408 max = sum;
409 Int_t idx = 0; // idx of the first slice of the maximum window
410
411 for (p=first; p+fWindowSizeLoGain<end; p++)
412 {
413
414 const Float_t signal = (Float_t)*(p+fWindowSizeLoGain) - PedMean[(ids++ + abflag) & 0x1];
415 sum += signal - fLoGainSignal[count];
416 fLoGainSignal[count + fWindowSizeLoGain] = signal;
417
418 if (sum>max)
419 {
420 max = sum;
421 idx = count+1;
422 }
423 count++;
424 }
425
426 //
427 // now calculate the time for the maximum window
428 //
429 Float_t timesignalsum = 0;
430 Int_t timesquaredsum = 0;
431
432 for (Int_t i=idx; i<idx+fWindowSizeLoGain; i++)
433 {
434 timesignalsum += fLoGainSignal[i]*i;
435 timesquaredsum += i*i;
436 }
437
438 sum = max;
439
440 time = max > 0.1 ? timesignalsum / max + Float_t(fLoGainFirst) : 1.;
441 dtime = max > 0.1 ? ped.GetPedestalRms() / max * sqrt(timesquaredsum - fWindowSizeLoGain*time) : 1.;
442}
443
444// --------------------------------------------------------------------------
445//
446// In addition to the resources of the base-class MExtractor:
447// MJPedestal.MExtractor.WindowSizeHiGain: 6
448// MJPedestal.MExtractor.WindowSizeLoGain: 6
449//
450Int_t MExtractTimeAndChargeSlidingWindow::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
451{
452
453 Byte_t hw = fWindowSizeHiGain;
454 Byte_t lw = fWindowSizeLoGain;
455
456 Bool_t rc = kFALSE;
457
458 if (IsEnvDefined(env, prefix, "HiGainWindowSize", print))
459 {
460 hw = GetEnvValue(env, prefix, "HiGainWindowSize", hw);
461 rc = kTRUE;
462 }
463 if (IsEnvDefined(env, prefix, "LoGainWindowSize", print))
464 {
465 lw = GetEnvValue(env, prefix, "LoGainWindowSize", lw);
466 rc = kTRUE;
467 }
468
469 if (rc)
470 SetWindowSize(hw, lw);
471
472 return MExtractTime::ReadEnv(env, prefix, print) ? kTRUE : rc;
473
474}
475
Note: See TracBrowser for help on using the repository browser.