source: trunk/MagicSoft/Mars/msignal/MExtractFixedWindowPeakSearch.cc@ 5538

Last change on this file since 5538 was 5491, checked in by gaug, 20 years ago
*** empty log message ***
File size: 16.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): Abelardo Moralejo, 04/2004 <mailto:moralejo@pd.infn.it>
19! Author(s): Markus Gaug, 04/2004 <mailto:markus@ifae.es>
20!
21! Copyright: MAGIC Software Development, 2000-2004
22!
23!
24\* ======================================================================== */
25
26//////////////////////////////////////////////////////////////////////////////
27//
28// MExtractFixedWindowPeakSearch
29//
30// Calculate the signal integrating fWindowSize time slices, the same for
31// all pixels. The integrated slices change from event to event, since the
32// pulse positions in the FADC jump between events, but apparently in a
33// "coherent" fashion. We first loop over all pixels and find the one
34// which has the highest sum of fPeakSearchWindowSize (default: 4) consecutive
35// non-saturated high gain slices. The position of the peak in this pixel
36// determines the integration window position for all pixels of this event.
37// For the moment we neglect time delays between pixels (which are in most
38// cases small). The class is based on MExtractSlidingWindow.
39//
40// Call: SetRange(higainfirst, higainlast, logainfirst, logainlast)
41// to modify the ranges in which the window is allowed to move.
42// Defaults are:
43//
44// fHiGainFirst = fgHiGainFirst = 0
45// fHiGainLast = fgHiGainLast = 14
46// fLoGainFirst = fgLoGainFirst = 3
47// fLoGainLast = fgLoGainLast = 14
48//
49// Call: SetWindows(windowhigain, windowlogain,peaksearchwindow)
50// to modify the sliding window widths. Windows have to be an even number.
51// In case of odd numbers, the window will be modified.
52//
53// Defaults are:
54//
55// fHiGainWindowSize = fgHiGainWindowSize = 6
56// fLoGainWindowSize = fgLoGainWindowSize = 6
57// fPeakSearchWindowSize = fgPeakSearchWindowSize = 4
58// fLoGainPeakShift = fgLoGainPeakShift = 0
59//
60//////////////////////////////////////////////////////////////////////////////
61#include "MExtractFixedWindowPeakSearch.h"
62#include "MExtractor.h"
63
64#include "MLog.h"
65#include "MLogManip.h"
66
67#include "MRawEvtPixelIter.h"
68
69#include "MExtractedSignalCam.h"
70#include "MExtractedSignalPix.h"
71
72#include "MPedestalCam.h"
73#include "MPedestalPix.h"
74
75ClassImp(MExtractFixedWindowPeakSearch);
76
77using namespace std;
78
79const Byte_t MExtractFixedWindowPeakSearch::fgHiGainFirst = 0;
80const Byte_t MExtractFixedWindowPeakSearch::fgHiGainLast = 14;
81const Byte_t MExtractFixedWindowPeakSearch::fgLoGainFirst = 3;
82const Byte_t MExtractFixedWindowPeakSearch::fgLoGainLast = 14;
83const Byte_t MExtractFixedWindowPeakSearch::fgHiGainWindowSize = 6;
84const Byte_t MExtractFixedWindowPeakSearch::fgLoGainWindowSize = 6;
85const Byte_t MExtractFixedWindowPeakSearch::fgPeakSearchWindowSize = 4;
86const Byte_t MExtractFixedWindowPeakSearch::fgOffsetFromWindow = 1;
87const Byte_t MExtractFixedWindowPeakSearch::fgLoGainPeakShift = 1;
88// --------------------------------------------------------------------------
89//
90// Default constructor.
91//
92// Sets:
93// - fHiGainWindowSize to fgHiGainWindowSize
94// - fLoGainWindowSize to fgLoGainWindowSize
95// - fPeakSearchWindowSize to fgPeakSearchWindowSize
96// - fLoGainPeakShift to fgLoGainPeakShift
97//
98// Calls:
99// - SetOffsetFromWindow()
100// - SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast)
101//
102MExtractFixedWindowPeakSearch::MExtractFixedWindowPeakSearch(const char *name, const char *title)
103 : fHiGainWindowSize(fgHiGainWindowSize),
104 fLoGainWindowSize(fgLoGainWindowSize),
105 fPeakSearchWindowSize(fgPeakSearchWindowSize),
106 fLoGainPeakShift(fgLoGainPeakShift)
107{
108
109 fName = name ? name : "MExtractFixedWindowPeakSearch";
110 fTitle = title ? title : "Task to extract the signal from the FADC slices";
111
112 SetOffsetFromWindow();
113 SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast);
114}
115
116// --------------------------------------------------------------------------
117//
118// SetRange:
119//
120// Calls:
121// - MExtractor::SetRange(hifirst,hilast,lofirst,lolast);
122// - SetWindows(fHiGainWindowSize,fLoGainWindowSize,fPeakSearchWindowSize);
123//
124void MExtractFixedWindowPeakSearch::SetRange(Byte_t hifirst, Byte_t hilast, Byte_t lofirst, Byte_t lolast)
125{
126
127 MExtractor::SetRange(hifirst,hilast,lofirst,lolast);
128
129 //
130 // Redo the checks if the window is still inside the ranges
131 //
132 SetWindows(fHiGainWindowSize,fLoGainWindowSize,fPeakSearchWindowSize);
133
134}
135
136// --------------------------------------------------------------------------
137//
138// Checks:
139// - if a window is odd, subtract one
140// - if a window is bigger than the one defined by the ranges, set it to the available range
141// - if a window is smaller than 2, set it to 2
142//
143// Sets:
144// - fNumHiGainSamples to: (Float_t)fHiGainWindowSize
145// - fNumLoGainSamples to: (Float_t)fLoGainWindowSize
146// - fSqrtHiGainSamples to: TMath::Sqrt(fNumHiGainSamples)
147// - fSqrtLoGainSamples to: TMath::Sqrt(fNumLoGainSamples)
148//
149void MExtractFixedWindowPeakSearch::SetWindows(Byte_t windowh, Byte_t windowl, Byte_t peaksearchwindow)
150{
151
152 fHiGainWindowSize = windowh & ~1;
153 fLoGainWindowSize = windowl & ~1;
154 fPeakSearchWindowSize = peaksearchwindow & ~1;
155
156 if (fHiGainWindowSize != windowh)
157 *fLog << warn << GetDescriptor() << ": Hi Gain window size has to be even, set to: "
158 << int(fHiGainWindowSize) << " samples " << endl;
159
160 if (fLoGainWindowSize != windowl)
161 *fLog << warn << GetDescriptor() << ": Lo Gain window size has to be even, set to: "
162 << int(fLoGainWindowSize) << " samples " << endl;
163
164 if (fPeakSearchWindowSize != peaksearchwindow)
165 *fLog << warn << GetDescriptor() << ": Peak Search window size has to be even, set to: "
166 << int(fPeakSearchWindowSize) << " samples " << endl;
167
168 const Byte_t availhirange = (fHiGainLast-fHiGainFirst+1) & ~1;
169 const Byte_t availlorange = (fLoGainLast-fLoGainFirst+1) & ~1;
170
171 if (fHiGainWindowSize > availhirange)
172 {
173 *fLog << warn << GetDescriptor()
174 << Form("%s%2i%s%2i%s%2i%s",": Hi Gain window size: ",(int)fHiGainWindowSize,
175 " is bigger than available range: [",(int)fHiGainFirst,",",(int)fHiGainLast,"]") << endl;
176 *fLog << warn << GetDescriptor()
177 << ": Will set window size to: " << (int)availhirange << endl;
178 fHiGainWindowSize = availhirange;
179 }
180
181
182 if (fLoGainWindowSize > availlorange)
183 {
184 *fLog << warn << GetDescriptor()
185 << Form("%s%2i%s%2i%s%2i%s",": Lo Gain window size: ",(int)fLoGainWindowSize,
186 " is bigger than available range: [",(int)fLoGainFirst,",",(int)fLoGainLast,"]") << endl;
187 *fLog << warn << GetDescriptor()
188 << ": Will set window size to: " << (int)availlorange << endl;
189 fLoGainWindowSize = availlorange;
190 }
191
192 if (fHiGainWindowSize<2)
193 {
194 fHiGainWindowSize = 2;
195 *fLog << warn << GetDescriptor() << ": Hi Gain window size set to two samples" << endl;
196 }
197
198 if (fLoGainWindowSize<2)
199 {
200 fLoGainWindowSize = 2;
201 *fLog << warn << GetDescriptor() << ": Lo Gain window size set to two samples" << endl;
202 }
203
204 if (fPeakSearchWindowSize<2)
205 {
206 fPeakSearchWindowSize = 2;
207 *fLog << warn << GetDescriptor()
208 << ": Peak Search window size set to two samples" << endl;
209 }
210
211 fNumHiGainSamples = (Float_t)fHiGainWindowSize;
212 fNumLoGainSamples = (Float_t)fLoGainWindowSize;
213
214 fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
215 fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples);
216}
217
218
219// --------------------------------------------------------------------------
220//
221// The ReInit calls:
222// - MExtractor::ReInit()
223// - fSignals->SetUsedFADCSlices(fHiGainFirst, fHiGainLast+fHiLoLast, fNumHiGainSamples,
224// fLoGainFirst, fLoGainLast, fNumLoGainSamples);
225//
226Bool_t MExtractFixedWindowPeakSearch::ReInit(MParList *pList)
227{
228
229 MExtractor::ReInit(pList);
230
231 fSignals->SetUsedFADCSlices(fHiGainFirst, fHiGainLast+fHiLoLast, fNumHiGainSamples,
232 fLoGainFirst, fLoGainLast, fNumLoGainSamples);
233
234 *fLog << dec << endl;
235 *fLog << inf << "Taking " << fNumHiGainSamples
236 << " HiGain samples starting with slice " << (Int_t)fHiGainFirst
237 << " to " << (Int_t)(fHiGainLast+fHiLoLast) << " incl" << endl;
238 *fLog << inf << "Taking " << fNumLoGainSamples
239 << " LoGain samples starting with slice " << (Int_t)fLoGainFirst
240 << " to " << (Int_t)fLoGainLast << " incl" << endl;
241
242 return kTRUE;
243
244}
245
246// --------------------------------------------------------------------------
247//
248// FindPeak
249// Finds highest sum of "window" consecutive FADC slices in a pixel, and store
250// in "startslice" the first slice of the group which yields the maximum sum.
251// In "max" the value of the maximum sum is stored, in "sat" the number of
252// saturated slices.
253//
254void MExtractFixedWindowPeakSearch::FindPeak(Byte_t *ptr, Byte_t window, Byte_t &startslice, Int_t &max, Int_t &sat) const
255{
256
257 const Byte_t *end = ptr + fHiGainLast - fHiGainFirst + 1;
258
259 sat = 0;
260 startslice = 0;
261 Int_t sum=0;
262
263 //
264 // Calculate the sum of the first "window" slices
265 //
266 sat = 0;
267 Byte_t *p = ptr;
268
269 while (p<ptr+window)
270 {
271 sum += *p;
272 if (*p++ >= fSaturationLimit)
273 sat++;
274 }
275
276 //
277 // Check for saturation in all other slices
278 //
279 while (p<end)
280 if (*p++ >= fSaturationLimit)
281 sat++;
282
283 //
284 // Calculate the i-th sum of n as
285 // sum_i+1 = sum_i + slice[i+window] - slice[i]
286 // This is fast and accurate (because we are using int's)
287 //
288 max=sum;
289 for (p=ptr; p+window<end; p++)
290 {
291 sum += *(p+window) - *p;
292 if (sum > max)
293 {
294 max = sum;
295 startslice = p-ptr;
296 }
297 }
298
299 return;
300}
301
302// --------------------------------------------------------------------------
303//
304// FindSignalHiGain:
305//
306// - Loop from ptr to (ptr+fHiGainWindowSize)
307// - Sum up contents of *ptr
308// - If *ptr is greater than fSaturationLimit, raise sat by 1
309//
310void MExtractFixedWindowPeakSearch::FindSignalHiGain(Byte_t *ptr, Byte_t *logain, Float_t &sum, Byte_t &sat) const
311{
312
313 Byte_t *end = ptr + fHiGainWindowSize-fHiLoLast;
314
315 Int_t summ = 0;
316 //
317 // Calculate the sum of the "window" slices starting in ptr
318 //
319 while (ptr<end)
320 {
321 summ += *ptr;
322 if (*ptr++ >= fSaturationLimit)
323 sat++;
324 }
325
326 //
327 // If part of the "lo-Gain" slices are used,
328 // repeat steps one and two for the logain part until fHiLoLast
329 //
330 Byte_t *p = logain;
331 end = logain + fHiLoLast;
332 while (p<end)
333 {
334
335 summ += *p;
336 if (*p++ >= fSaturationLimit)
337 sat++;
338 }
339
340 sum = (Float_t)summ;
341 return;
342}
343
344// --------------------------------------------------------------------------
345//
346// FindSignalLoGain:
347//
348// - Loop from ptr to (ptr+fLoGainWindowSize)
349// - Sum up contents of *ptr
350// - If *ptr is greater than fSaturationLimit, raise sat by 1
351//
352void MExtractFixedWindowPeakSearch::FindSignalLoGain(Byte_t *ptr, Float_t &sum, Byte_t &sat) const
353{
354 //
355 // Calculate the sum of the "window" slices starting in ptr
356 //
357 Byte_t *p = ptr;
358 Int_t summ = 0;
359
360 while (p<ptr+fLoGainWindowSize)
361 {
362 summ += *p;
363 if (*p++ >= fSaturationLimit)
364 sat++;
365 }
366
367 sum = (Float_t)summ;
368 return;
369}
370
371// --------------------------------------------------------------------------
372//
373// Process
374// First find the pixel with highest sum of fPeakSearchWindowSize slices (default:4)
375// "startslice" will mark the slice at which the highest sum begins for that pixel.
376// Then define the beginning of the integration window for ALL pixels as the slice
377// before that: startslice-fOffsetFromWindow, unless of course startslice-fOffsetFromWindow<=0,
378// in which case we start at 0. We will also check that the integration window does not
379// go beyond the FADC limits.
380//
381Int_t MExtractFixedWindowPeakSearch::Process()
382{
383
384 MRawEvtPixelIter pixel(fRawEvt);
385
386 Int_t sat;
387 Int_t maxsumhi = -1000000;
388 Byte_t startslice;
389 Byte_t hiGainFirst = 0;
390 Byte_t loGainFirst = 0;
391 fHiLoLast = 0;
392
393 while (pixel.Next())
394 {
395 Int_t sumhi;
396 sat = 0;
397
398 FindPeak(pixel.GetHiGainSamples()+fHiGainFirst, fPeakSearchWindowSize, startslice, sumhi, sat);
399
400 if (sumhi > maxsumhi && sat == 0 )
401 {
402 maxsumhi = sumhi;
403 if ((startslice-fOffsetFromWindow) > 0)
404 hiGainFirst = fHiGainFirst + startslice - fOffsetFromWindow;
405 else
406 hiGainFirst = fHiGainFirst;
407 }
408 }
409
410
411 loGainFirst = ( hiGainFirst+fLoGainPeakShift > fLoGainFirst ) ?
412 hiGainFirst+fLoGainPeakShift : fLoGainFirst;
413
414 // Make sure we will not integrate beyond the hi gain limit:
415 if (hiGainFirst+fHiGainWindowSize > pixel.GetNumHiGainSamples())
416 fHiLoLast = hiGainFirst+fHiGainWindowSize - pixel.GetNumHiGainSamples();
417 // hiGainFirst = pixel.GetNumHiGainSamples()-fHiGainWindowSize;
418
419 // Make sure we will not integrate beyond the lo gain limit:
420 if (loGainFirst+fLoGainWindowSize > pixel.GetNumLoGainSamples())
421 loGainFirst = pixel.GetNumLoGainSamples()-fLoGainWindowSize;
422
423 pixel.Reset();
424 fSignals->Clear();
425
426 sat = 0;
427 while (pixel.Next())
428 {
429 //
430 // Find signal in hi- and lo-gain
431 //
432 Float_t sumhi=0.;
433 Byte_t sathi=0;
434
435 FindSignalHiGain(pixel.GetHiGainSamples()+hiGainFirst, pixel.GetLoGainSamples(), sumhi, sathi);
436
437 Float_t sumlo=0.;
438 Byte_t satlo=0;
439 if (pixel.HasLoGain())
440 {
441 FindSignalLoGain(pixel.GetLoGainSamples()+loGainFirst, sumlo, satlo);
442 if (satlo)
443 sat++;
444 }
445
446 //
447 // Take corresponding pedestal
448 //
449 const Int_t pixid = pixel.GetPixelId();
450
451 const MPedestalPix &ped = (*fPedestals)[pixid];
452 MExtractedSignalPix &pix = (*fSignals)[pixid];
453
454 const Float_t pedes = ped.GetPedestal();
455 const Float_t pedrms = ped.GetPedestalRms();
456 //
457 // Set extracted signal with pedestal substracted
458 //
459 pix.SetExtractedSignal(sumhi - pedes*fNumHiGainSamples, pedrms*fSqrtHiGainSamples,
460 sumlo - pedes*fNumLoGainSamples, pedrms*fSqrtLoGainSamples);
461
462 pix.SetGainSaturation(sathi, sathi, satlo);
463
464 // pix.SetNumHiGainSlices(fNumHiGainSamples);
465 // pix.SetNumLoGainSlices(fNumLoGainSamples);
466
467 } /* while (pixel.Next()) */
468
469
470 fSignals->SetReadyToSave();
471
472 return kTRUE;
473}
474
475// --------------------------------------------------------------------------
476//
477// In addition to the resources of the base-class MExtractor:
478// MJPedestal.MExtractor.WindowSizeHiGain: 6
479// MJPedestal.MExtractor.WindowSizeLoGain: 6
480// MJPedestal.MExtractor.PeakSearchWindow: 4
481// MJPedestal.MExtractor.OffsetFromWindow: 1
482// MJPedestal.MExtractor.LoGainPeakShift: 1
483//
484Int_t MExtractFixedWindowPeakSearch::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
485{
486 Byte_t hw = fHiGainWindowSize;
487 Byte_t lw = fLoGainWindowSize;
488 Byte_t pw = fPeakSearchWindowSize;
489
490 Bool_t rc = kFALSE;
491
492 if (IsEnvDefined(env, prefix, "PeakSearchWindow", print))
493 {
494 pw = GetEnvValue(env, prefix, "PeakSearchWindow", pw);
495 rc = kTRUE;
496 }
497 if (IsEnvDefined(env, prefix, "HiGainWindowSize", print))
498 {
499 hw = GetEnvValue(env, prefix, "HiGainWindowSize", hw);
500 rc = kTRUE;
501 }
502 if (IsEnvDefined(env, prefix, "LoGainWindowSize", print))
503 {
504 lw = GetEnvValue(env, prefix, "LoGainWindowSize", lw);
505 rc = kTRUE;
506 }
507
508 if (rc)
509 SetWindows(hw, lw, pw);
510
511
512 if (IsEnvDefined(env, prefix, "OffsetFromWindow", print))
513 {
514 SetOffsetFromWindow(GetEnvValue(env, prefix, "OffsetFromWindow", fOffsetFromWindow));
515 rc = kTRUE;
516 }
517
518 if (IsEnvDefined(env, prefix, "LoGainPeakShift", print))
519 {
520 SetLoGainPeakShift(GetEnvValue(env, prefix, "LoGainPeakShift", fLoGainPeakShift));
521 rc = kTRUE;
522 }
523
524 rc = MExtractor::ReadEnv(env, prefix, print) ? kTRUE : rc;
525
526 return rc;
527}
528
529void MExtractFixedWindowPeakSearch::Print(Option_t *o) const
530{
531 *fLog << all;
532 *fLog << GetDescriptor() << ":" << endl;
533 *fLog << " Windows: Hi-Gain=" << (int)fHiGainWindowSize << " Lo-Gain=" << (int)fLoGainWindowSize;
534 *fLog << " Peak-Search=" << (int)fPeakSearchWindowSize << endl;
535 *fLog << " Offset From Window: " << (int)fOffsetFromWindow << endl;
536 *fLog << " Lo-Gain peak Shift: " << (int)fLoGainPeakShift << endl;
537 MExtractor::Print(o);
538}
Note: See TracBrowser for help on using the repository browser.