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

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