source: trunk/Mars/mpedestal/MExtractPedestal.cc@ 17302

Last change on this file since 17302 was 10166, checked in by tbretz, 14 years ago
Removed the old obsolete cvs header line.
File size: 35.1 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): Markus Gaug 01/2004 <mailto:markus@ifae.es>
19! Author(s): Thomas Bretz 01/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
20!
21! Copyright: MAGIC Software Development, 2000-2007
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MExtractPedestal
29//
30// Pedestal Extractor base class
31//
32// Input Containers:
33// MRawEvtData
34// MRawRunHeader
35// MRawEvtHeader
36// MGeomCam
37// MPedestalCam
38//
39// Output Containers:
40// MPedestalCam
41//
42// This class should be used for pedestal extractors with the following facilities:
43// a) Standardized calculation of AB-noise, mean pedestals and RMS
44// b) Standardized treatment of area- and sector averaged pedestals values
45// c) Possibility to use a signal extractor to be applied on the pedestals
46// d) Possibility to handle two MPedestalCams: one for the signal extractor and
47// a second to be filled during the pedestal calculating process.
48//
49// ad a): Every calculated value is referred to one FADC slice (e.g. Mean pedestal per slice),
50// RMS per slice.
51// MExtractPedestal applies the following formula (1):
52//
53// Pedestal per slice = sum(x_i) / n / slices
54// PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / slices )
55// AB-Offset per slice = (sumAB0 - sumAB1) / n / slices
56//
57// where x_i is the sum of "slices" FADC slices and sum means the sum over all
58// events. "n" is the number of events, "slices" is the number of summed FADC samples.
59//
60// Note that the slice-to-slice fluctuations are not Gaussian, but Poissonian, thus
61// asymmetric and they are correlated.
62//
63// It is important to know that the Pedestal per slice and PedRMS per slice depend
64// on the number of used FADC slices, as seen in the following plots:
65//
66//Begin_Html
67/*
68<img src="images/PedestalStudyInner.gif">
69*/
70//End_Html
71//
72//Begin_Html
73/*
74<img src="images/PedestalStudyOuter.gif">
75*/
76//End_Html
77//
78// The plots show the inner and outer pixels, respectivly and have the following meaning:
79//
80// 1) The calculated mean pedestal per slice (from MPedCalcPedRun)
81// 2) The fitted mean pedestal per slice (from MHPedestalCam)
82// 3) The calculated pedestal RMS per slice (from MPedCalcPedRun)
83// 4) The fitted sigma of the pedestal distribution per slice
84// (from MHPedestalCam)
85// 5) The relative difference between calculation and histogram fit
86// for the mean
87// 6) The relative difference between calculation and histogram fit
88// for the sigma or RMS, respectively.
89//
90// The calculated means do not change significantly except for the case of 2 slices,
91// however the RMS changes from 5.7 per slice in the case of 2 extracted slices
92// to 8.3 per slice in the case of 26 extracted slices. This change is very significant.
93//
94// ad b) Every calculated value is referred to one FADC slice and one (averaged) pixel,
95// (e.g. Mean Pedestal per area index per slice per pixel, etc. )
96//
97// MExtractPedestal applies the following formula (2):
98//
99// Averaged Pedestal per slice = sum(x_i) / n / slices / n_pix
100// PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / slices / n_pix )
101// AB-Offset per slice = (sumAB0 - sumAB1) / n / slices / n_pix
102//
103// where x_i is the sum of "slices" FADC slices and sum means the sum over all
104// events and all concerned pixels.
105// "n" is the number of events, "slices" is the number of summed FADC samples and
106// "n_pix" is the number of pixels belonging to the specific area index or camera sector.
107//
108// Calculating these averaged event-by-event values is very important to trace coherent
109// fluctuations. An example is given in the following plots:
110//
111//Begin_Html
112/*
113<img src="images/PedestalOscillations.gif">
114*/
115//End_Html
116//
117// The plots show the extracted pedestals of the inner pixels (obtained
118// with MHPedestalCam), averaged on an event-by-event basis from
119// run 13428 with switched off camera LV.
120// The meaning of the four plots is:
121//
122// 1) The distribution of the averaged pedestals
123// 2) The averaged pedestals vs. time.
124// One can see clearly the oscillation pattern
125// 3) The fourier transform of the averaged pedestals vs. time.
126// One can see clearly a peak at a certain frequency
127// 4) The projection of the fourier components with the non-exponential
128// (and therefore significant) outlier.
129//
130// ad c) Many signal extractors, especially those using a sliding window
131// have biases and their resolutions for zero-signals do not agree
132// with the pedestal RMS. For the F-Factor method in the calibration
133// and the image cleaning, however, both have to be known and measured.
134//
135// For this reason, a signal extractor can be handed over to the
136// pedestal extractor and applied on the pedestal events with the
137// function SetExtractor().
138// The results will get stored in an MPedestalCam.
139//
140// Note that only extractors deriving from MExtractTimeAndCharge
141// can be used.
142//
143// ad d) The signal extractors themselves need a pedestal to be subtracted
144// from the FADC slices.
145// If the user wishes that the pededestals do not get overwritten by
146// the results from the signal extractor, a different named MPedestalCam
147// can be created with the function: SetNamePedestalOut().
148//
149// See also: MPedestalCam, MPedestalPix, MPedCalcPedRun, MPedCalcFromLoGain
150//
151/////////////////////////////////////////////////////////////////////////////
152#include "MExtractPedestal.h"
153
154#include "MParList.h"
155
156#include "MLog.h"
157#include "MLogManip.h"
158
159#include "MRawRunHeader.h"
160#include "MRawEvtHeader.h"
161#include "MRawEvtPixelIter.h"
162
163#include "MPedestalPix.h"
164#include "MPedestalCam.h"
165
166#include "MGeom.h"
167#include "MGeomCam.h"
168
169#include "MExtractTimeAndCharge.h"
170#include "MPedestalSubtractedEvt.h"
171
172ClassImp(MExtractPedestal);
173
174using namespace std;
175
176const TString MExtractPedestal::fgNamePedestalCam = "MPedestalCam";
177const TString MExtractPedestal::fgNameRawEvtData = "MRawEvtData";
178
179const UShort_t MExtractPedestal::fgCheckWinFirst = 0;
180const UShort_t MExtractPedestal::fgCheckWinLast = 29;
181const UShort_t MExtractPedestal::fgMaxSignalVar = 40;
182const UShort_t MExtractPedestal::fgMaxSignalAbs = 250;
183
184// --------------------------------------------------------------------------
185//
186// Default constructor:
187//
188// Sets:
189// - all pointers to NULL
190//
191// Calls:
192// - Clear()
193//
194MExtractPedestal::MExtractPedestal(const char *name, const char *title)
195 : fGeom(NULL), fPedestalsInter(NULL),
196 fPedestalsOut(NULL), fExtractor(NULL), fSignal(0),
197 fExtractWinFirst(0), fExtractWinSize(0), fUseSpecialPixels(kFALSE),
198 fCounter(0)
199{
200 fName = name ? name : "MExtractPedestal";
201 fTitle = title ? title : "Base class to calculate pedestals";
202
203 SetIntermediateStorage( kFALSE );
204 SetRandomCalculation ( kTRUE );
205
206 SetNamePedestalCamOut();
207 SetNamePedestalCamInter();
208 SetNameRawEvtData();
209
210 SetCheckRange(fgCheckWinFirst, fgCheckWinLast);
211 SetMaxSignalVar(fgMaxSignalVar);
212 SetMaxSignalAbs(fgMaxSignalAbs);
213
214 Clear();
215}
216
217// --------------------------------------------------------------------------
218//
219// Call reset() of all Arays
220//
221void MExtractPedestal::ResetArrays()
222{
223 // Reset contents of arrays.
224 fSumx.Reset();
225 fSumx2.Reset();
226 fSumAB0.Reset();
227 fSumAB1.Reset();
228 fAreaSumx.Reset();
229 fAreaSumx2.Reset();
230 fAreaSumAB0.Reset();
231 fAreaSumAB1.Reset();
232 fAreaFilled.Reset();
233 fAreaValid.Reset();
234 fSectorSumx.Reset();
235 fSectorSumx2.Reset();
236 fSectorSumAB0.Reset();
237 fSectorSumAB1.Reset();
238 fSectorFilled.Reset();
239 fSectorValid.Reset();
240 fNumEventsUsed.Reset();
241}
242
243// --------------------------------------------------------------------------
244//
245// Resets Arrays:
246//
247// Sets:
248// - fRawEvt to NULL
249// - fRunHeader to NULL
250//
251void MExtractPedestal::Clear(const Option_t *o)
252{
253
254 fRawEvt = NULL;
255 fRunHeader = NULL;
256
257 // If the size is yet set, set the size
258 if (fSumx.GetSize()>0)
259 ResetArrays();
260
261}
262
263// --------------------------------------------------------------------------
264//
265// Checks:
266// - if a window is odd
267//
268Bool_t MExtractPedestal::SetExtractWindow(UShort_t windowf, UShort_t windows)
269{
270 Bool_t rc = kTRUE;
271
272 if (windows==0)
273 {
274 *fLog << warn << GetDescriptor();
275 *fLog << " - WARNING: Window size in SetExtractWindow has to be > 0... adjusting to 2!" << endl;
276 windows = 2;
277 rc = kFALSE;
278 }
279
280 fExtractWinSize = windows;
281 fExtractWinFirst = windowf;
282 fExtractWinLast = fExtractWinFirst+fExtractWinSize-1;
283
284 return rc;
285}
286
287// --------------------------------------------------------------------------
288//
289// SetCheckRange:
290//
291// Exits, if the first argument is smaller than 0
292// Exits, if the the last argument is smaller than the first
293//
294Bool_t MExtractPedestal::SetCheckRange(UShort_t chfirst, UShort_t chlast)
295{
296
297 Bool_t rc = kTRUE;
298
299 if (chlast<=chfirst)
300 {
301 *fLog << warn << GetDescriptor();
302 *fLog << " - WARNING: Last slice in SetCheckRange smaller than first slice... set to first+2" << endl;
303 chlast = chfirst+1;
304 rc = kFALSE;
305 }
306
307 fCheckWinFirst = chfirst;
308 fCheckWinLast = chlast;
309
310 return rc;
311}
312
313Bool_t MExtractPedestal::SetRangeFromExtractor(const MExtractor &ext, Bool_t logain)
314{
315 const Bool_t haslogains = ext.GetLoGainFirst()!=0 && ext.GetLoGainLast()!=0;
316
317 Bool_t rc1 = kTRUE;
318 if (!haslogains)
319 {
320 // We assume that in case without lo-gains we
321 // deal with pedestal events only
322 rc1 = SetCheckRange(ext.GetHiGainFirst(), ext.GetHiGainLast());
323 }
324
325 const Int_t f = logain && haslogains ? ext.GetLoGainFirst() : ext.GetHiGainFirst();
326 const Int_t l = logain && haslogains ? ext.GetLoGainLast() : ext.GetHiGainLast();
327
328 const Int_t w = (l-f+1);
329
330 // Setup to use the hi-gain extraction window in the lo-gain
331 // range (the start of the lo-gain range is added automatically
332 // by MPedCalcFromLoGain)
333 const Bool_t rc2 = SetExtractWindow(f, w);
334
335 return rc1 && rc2;
336}
337
338// --------------------------------------------------------------------------
339//
340// Check (and if neccesary: correct) the extraction and check ranges.
341//
342void MExtractPedestal::CheckExtractionWindow(UInt_t offset)
343{
344 *fLog << inf;
345 *fLog << "Requested CheckWindow is [" << fCheckWinFirst << "," << fCheckWinLast << "]." <<endl;
346 *fLog << "Requested ExtractWindow is [" << fExtractWinFirst+offset << "," << fExtractWinLast+offset << "]." <<endl;
347
348 // fSignal->GetNumSamples() not yet initialized!!!
349 const UInt_t num = fRunHeader->GetNumSamplesHiGain()+fRunHeader->GetNumSamplesLoGain();
350
351 // Check upper bound for check window
352 if (fCheckWinLast >= num)
353 {
354 *fLog << inf << "CheckWindow [" << fCheckWinFirst << "," << fCheckWinLast;
355 *fLog << "] out of range [0," << num-1 << "]... ";
356 *fLog << "reset upper edge to " << num-1 << "." << endl;
357
358 fCheckWinLast = num-1;
359 }
360
361 // Now check lower bound for check window
362 if (fCheckWinFirst>fCheckWinLast)
363 {
364 *fLog << err << "CheckWindow first slice " << fCheckWinFirst;
365 *fLog << " greater than last slice " << fCheckWinLast;
366 *fLog << "... reset to 0." << endl;
367
368 fCheckWinFirst = 0;
369 }
370
371 // check upper bound for extaction window
372 if (fExtractWinLast+offset >= num)
373 {
374 *fLog << inf << "ExtractWindow [" << fExtractWinFirst+offset << "," << fExtractWinLast+offset;
375 *fLog << "] out of range [0," << num-1 << "]... ";
376 *fLog << "reset upper edge to " << num-1 << "." << endl;
377
378 fExtractWinLast = num-offset-1;
379 }
380
381 // Now check lower bound for check window
382 if (fExtractWinFirst>fExtractWinLast)
383 {
384 *fLog << err << "ExtractWindow first slice " << fExtractWinFirst+offset;
385 *fLog << " greater than last slice " << fExtractWinLast+offset;
386 *fLog << "... reset to 0." << endl;
387
388 fExtractWinFirst = 0;
389 }
390
391 // Calculate window size for extraction window
392 fExtractWinSize = fExtractWinLast-fExtractWinFirst+1;
393
394 // Check if use tries to do a fundamental pedestal extraction
395 // with an odd number of slices
396 if (fExtractor || TMath::Even(fExtractWinSize))
397 return;
398
399 // Make sure the number of extracted slices is even
400 fExtractWinLast += offset+fExtractWinLast==num-1 ? -1 : +1;
401
402 *fLog << inf << "ExtractionWindow odd... set to [";
403 *fLog << fExtractWinFirst+offset << "," << fExtractWinLast+offset << "]" << endl;
404
405 fExtractWinSize = fExtractWinLast-fExtractWinFirst+1;
406}
407
408// --------------------------------------------------------------------------
409//
410// Look for the following input containers:
411//
412// - MRawEvtData
413// - MRawRunHeader
414// - MRawEvtHeader
415// - MGeomCam
416//
417// The following output containers are also searched and created if
418// they were not found:
419//
420// - MPedestalCam with the name fPedContainerName
421//
422Int_t MExtractPedestal::PreProcess(MParList *pList)
423{
424
425 Clear();
426
427 fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber(fNameRawEvtData));
428 if (!fRawEvt)
429 {
430 *fLog << err << AddSerialNumber(fNameRawEvtData) << " not found... aborting." << endl;
431 return kFALSE;
432 }
433
434 fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
435 if (!fRunHeader)
436 {
437 *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl;
438 return kFALSE;
439 }
440
441 fGeom = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
442 if (!fGeom)
443 {
444 *fLog << err << AddSerialNumber("MGeomCam") << " not found... aborting." << endl;
445 return kFALSE;
446 }
447
448 fSignal = (MPedestalSubtractedEvt*)pList->FindObject(AddSerialNumber("MPedestalSubtractedEvt"));
449 if (!fSignal)
450 {
451 *fLog << err << AddSerialNumber("MPedestalSubtractedEvt") << " not found... aborting." << endl;
452 return kFALSE;
453 }
454
455 if (!fPedestalsInter && fIntermediateStorage)
456 {
457 fPedestalsInter = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamInter));
458 if (!fPedestalsInter)
459 return kFALSE;
460 }
461
462 if (!fPedestalsOut)
463 {
464 fPedestalsOut = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamOut));
465 if (!fPedestalsOut)
466 return kFALSE;
467 }
468
469 fCounter = 0;
470
471 return fExtractor ? fExtractor->CallPreProcess(pList) : kTRUE;
472}
473
474//-----------------------------------------------------------------------
475//
476// Call Calc(). If fExtractor!=NULL enclose the call in setting the
477// NoiseCalculation to fRandomCalculation
478//
479Int_t MExtractPedestal::Process()
480{
481 //
482 // Necessary check for extraction of special pixels
483 // together with data which does not yet have them
484 //
485 if (fSumx.GetSize()==0)
486 return kTRUE;
487
488 if (fExtractor)
489 fExtractor->SetNoiseCalculation(fRandomCalculation);
490
491 Calc();
492
493 if (fExtractor)
494 fExtractor->SetNoiseCalculation(kFALSE);
495
496 fPedestalsOut->SetNumEvents(fCounter);
497
498 return kTRUE;
499}
500
501// ---------------------------------------------------------------------------------
502//
503// Sets the size (from MPedestalCam::GetSize() ) and resets the following arrays:
504// - fSumx
505// - fSumx2
506// - fSumAB0
507// - fSumAB1
508// - fAreaSumx
509// - fAreaSumx2
510// - fAreaSumAB0
511// - fAreaSumAB1
512// - fAreaFilled
513// - fAreaValid
514// - fSectorSumx
515// - fSectorSumx2
516// - fSectorSumAB0
517// - fSectorSumAB1
518// - fSectorFilled
519// - fSectorValid
520//
521Bool_t MExtractPedestal::ReInit(MParList *pList)
522{
523 // Necessary check for special pixels which might not yet have existed
524 if (!fRawEvt)
525 {
526 if (fRunHeader->GetFormatVersion() > 3)
527 return kTRUE;
528
529 *fLog << err << "ERROR - " << fNameRawEvtData << " [MRawEvtData] has not ";
530 *fLog << "been found and format version > 3... abort." << endl;
531 return kFALSE;
532 }
533
534 // If the size is not yet set, set the size
535 if (fSumx.GetSize()==0)
536 {
537 // Initialize the normal pixels (size of MPedestalCam already set by MGeomApply)
538 const Int_t npixels = fPedestalsOut->GetSize();
539
540 fSumx. Set(npixels);
541 fSumx2. Set(npixels);
542 fSumAB0.Set(npixels);
543 fSumAB1.Set(npixels);
544
545 fNumEventsUsed.Set(npixels);
546
547 if (fUseSpecialPixels)
548 {
549 // Initialize size of MPedestalCam in case of special pixels (not done by MGeomApply)
550 const UShort_t nspecial = fRunHeader->GetNumSpecialPixels();
551 if (nspecial == 0)
552 {
553 *fLog << warn << "WARNING - Number of special pixels is 0." << endl;
554 return kTRUE;
555 }
556
557 fPedestalsOut->InitSize((UInt_t)nspecial);
558 }
559 else
560 {
561 // Initialize the averaged areas and sectors (do not exist for special pixels)
562 const Int_t areas = fPedestalsOut->GetNumAverageArea();
563 const Int_t sectors = fPedestalsOut->GetNumAverageSector();
564
565 fAreaSumx. Set(areas);
566 fAreaSumx2. Set(areas);
567 fAreaSumAB0.Set(areas);
568 fAreaSumAB1.Set(areas);
569 fAreaFilled.Set(areas);
570 fAreaValid .Set(areas);
571
572 fSectorSumx. Set(sectors);
573 fSectorSumx2. Set(sectors);
574 fSectorSumAB0.Set(sectors);
575 fSectorSumAB1.Set(sectors);
576 fSectorFilled.Set(sectors);
577 fSectorValid .Set(sectors);
578
579 for (Int_t i=0; i<npixels; i++)
580 {
581 const UInt_t aidx = (*fGeom)[i].GetAidx();
582 const UInt_t sector = (*fGeom)[i].GetSector();
583
584 fAreaValid [aidx] ++;
585 fSectorValid[sector]++;
586 }
587 }
588 }
589
590 if (fExtractor)
591 {
592 *fLog << all << fExtractor->ClassName() << "... " << flush;
593 if (!fExtractor->ReInit(pList))
594 return kFALSE;
595
596 SetRangeFromExtractor(*fExtractor);
597
598 // fSignal->GetNumSamples() not yet initialized!!!
599 const UInt_t num = fRunHeader->GetNumSamples();
600 if (fExtractWinLast >= num)
601 {
602 *fLog << err;
603 *fLog << "ERROR - Selected fExtractWinLast " << fExtractWinLast;
604 *fLog << " out of range (>=" << num<< ")." << endl;
605 return kFALSE;
606 }
607 }
608 else
609 if (fRunHeader->GetNumSamplesLoGain()==0 && (fCheckWinFirst!=0 || fCheckWinLast!=0))
610 {
611 *fLog << inf << "Data has no lo-gains... resetting check window to extraction window." << endl;
612 SetCheckRange(fExtractWinFirst, fExtractWinLast);
613 }
614
615 //CheckExtractionWindow();
616
617 return kTRUE;
618}
619
620// ---------------------------------------------------------------------------------
621//
622// PostProcess the extractor if available
623//
624Int_t MExtractPedestal::PostProcess()
625{
626 return fExtractor ? fExtractor->CallPostProcess() : kTRUE;
627}
628
629// ---------------------------------------------------------------------------------
630//
631// Check whether the signal variation between fCheckWinFirst and fCheckWinLast
632// exceeds fMaxSignalVar or the signal is greater than fMaxSignalAbs
633//
634Bool_t MExtractPedestal::CheckVariation(UInt_t idx) const
635{
636 // This is the fast workaround to put hi- and lo-gains together
637 USample_t *slices = fSignal->GetSamplesRaw(idx);
638
639 // Start 'real' work
640 USample_t max = 0;
641 USample_t min = (USample_t)-1;
642
643 // Find the maximum and minimum signal per slice in the high gain window
644 for (USample_t *slice=slices+fCheckWinFirst; slice<=slices+fCheckWinLast; slice++)
645 {
646 if (*slice > max)
647 max = *slice;
648 if (*slice < min)
649 min = *slice;
650 }
651
652 max /= fRunHeader->GetScale();
653 min /= fRunHeader->GetScale();
654
655 // If the maximum in the high gain window is smaller than
656 return max-min<fMaxSignalVar && max<fMaxSignalAbs;
657}
658
659// ---------------------------------------------------------------------------------
660//
661// Invoke the hi-gain extraction starting at fExtractWinFirst+offset
662// for fExtractWinLast-fExtractWinFirst+1 slices. If Noise calculation
663// is set it is up to the signal extractor to do the right thing.
664//
665// Returns the extracted signal.
666//
667Float_t MExtractPedestal::CalcExtractor(const MRawEvtPixelIter &pixel, Int_t offset) const
668{
669 // Use the same extraction window as for signal extraction
670 const Int_t first = fExtractWinFirst;
671 const Int_t last = fExtractWinLast;
672
673 const Int_t start = first+offset;
674
675 const Int_t range = last-first+1;
676
677 // This check is already done in CheckExtractionWindow
678 // if (range>pixel.GetNumSamples()-start)
679 // range = pixel.GetNumSamples()-start;
680
681 const Int_t idx = pixel.GetPixelId();
682
683 // Do some handling if maxpos is last slice?
684 const Int_t maxposhi = fRandomCalculation ? 0 : fSignal->GetMaxPos(idx, start, start+range-1);
685
686 const Float_t *sig = fSignal->GetSamples(idx);
687
688 // The pedestal is extracted with the hi-gain extractor (eg. digital
689 // filter weights) but from the lo-gains
690 Float_t dummy[3];
691 Float_t sum = 0;
692 fExtractor->FindTimeAndChargeHiGain2(sig+start, range, sum,
693 dummy[0], dummy[1], dummy[2],
694 0, maxposhi);
695
696 return sum;
697}
698
699// ---------------------------------------------------------------------------------
700//
701// Sum slices from fExtractWinFirst to fExtractWinLast. The total sum is
702// returned. ab0 and ab1 will contain the total sum splitted by the
703// AB-flag. If the AB-flag is invalid ab0=ab1=0 is returned.
704//
705UInt_t MExtractPedestal::CalcSums(const MRawEvtPixelIter &pixel, Int_t offset, UInt_t &ab0, UInt_t &ab1) const
706{
707 const Int_t first = fExtractWinFirst+offset;
708
709 USample_t *ptr = fSignal->GetSamplesRaw(pixel.GetPixelId())+first;
710 USample_t *end = ptr + fExtractWinSize;
711
712 Int_t abflag = pixel.HasABFlag() + first;
713
714 UInt_t ab[2] = { 0, 0 };
715 while (ptr<end)
716 ab[abflag++ & 0x1] += *ptr++;
717
718 // This check if for old data without AB-Flag in the data
719 const Bool_t valid = pixel.IsABFlagValid();
720
721 ab0 = valid ? ab[0] : 0;
722 ab1 = valid ? ab[1] : 0;
723
724 return ab[0]+ab[1];
725}
726
727// ---------------------------------------------------------------------------------
728//
729// Check for the variation of the pixel. Return kFALSE if this pixel
730// should not be used.
731// Calculate the pedestal either with the extractor or by summing slices.
732// And update all arrays.
733//
734Bool_t MExtractPedestal::CalcPixel(const MRawEvtPixelIter &pixel, Int_t offset, UInt_t usespecialpixels)
735{
736 const UInt_t idx = pixel.GetPixelId();
737 if (!CheckVariation(idx))
738 return kFALSE;
739
740 //extract pedestal
741 UInt_t ab[2];
742 const Float_t sum = fExtractor ?
743 CalcExtractor(pixel, offset) :
744 CalcSums(pixel, offset, ab[0], ab[1]);
745
746 if (fIntermediateStorage)
747 (*fPedestalsInter)[idx].Set(sum, 0, 0, fNumEventsUsed[idx]);
748
749 const Double_t sqrsum = sum*sum;
750
751 fSumx[idx] += sum;
752 fSumx2[idx] += sqrsum;
753
754 fNumEventsUsed[idx]++;
755
756 if (!fExtractor && pixel.IsABFlagValid())
757 {
758 fSumAB0[idx] += ab[0];
759 fSumAB1[idx] += ab[1];
760 }
761
762 if (usespecialpixels)
763 return kTRUE;
764
765 const UInt_t aidx = (*fGeom)[idx].GetAidx();
766 const UInt_t sector = (*fGeom)[idx].GetSector();
767
768 fAreaFilled[aidx]++;
769 fSectorFilled[sector]++;
770
771 fAreaSumx[aidx] += sum;
772 fAreaSumx2[aidx] += sqrsum;
773 fSectorSumx[sector] += sum;
774 fSectorSumx2[sector] += sqrsum;
775
776 if (!fExtractor && pixel.IsABFlagValid())
777 {
778 fAreaSumAB0[aidx] += ab[0];
779 fAreaSumAB1[aidx] += ab[1];
780 fSectorSumAB0[aidx] += ab[0];
781 fSectorSumAB1[aidx] += ab[1];
782 }
783
784 return kTRUE;
785}
786
787// ---------------------------------------------------------------------------------
788//
789// Calculates for pixel "idx":
790//
791// Ped per slice = sum / n / fExtractWinSize;
792// RMS per slice = sqrt { (sum2 - sum*sum/n) / (n-1) / fExtractWinSize }
793// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / n / fExtractWinSize;
794//
795// Stores the results in MPedestalCam[pixid]
796//
797void MExtractPedestal::CalcPixResults(const UInt_t pixid)
798{
799 const UInt_t nevts = fNumEventsUsed[pixid];
800 if (nevts<2)
801 return;
802
803 const Double_t sum = fSumx[pixid];
804 const Double_t sum2 = fSumx2[pixid];
805
806 // 1. Calculate the mean of the sums:
807 Double_t ped = sum/nevts;
808
809 // 2. Calculate the Variance of the sums:
810 Double_t var = (sum2-sum*sum/nevts)/(nevts-1.);
811
812 // 3. Calculate the amplitude of the 150MHz "AB" noise
813 Double_t abOffs = (fSumAB0[pixid] - fSumAB1[pixid]) / nevts;
814
815 // 4. Scale the mean, variance and AB-noise to the number of slices:
816 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
817 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
818 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
819 // The pedestal extracted with the extractor is divided by
820 // the number of hi-gain samples because the calibration
821 // multiplies by this number
822
823 // scale to 256
824 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale();
825
826 ped /= scale;
827 abOffs /= scale;
828
829 // 5. Calculate the RMS from the Variance:
830 const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale;
831
832 // abOffs contains only half of the signal as ped.
833 // Therefor abOffs is not the full, but the half amplitude
834 (*fPedestalsOut)[pixid].Set(ped, rms, abOffs, nevts);
835}
836
837// ---------------------------------------------------------------------------------
838//
839// Calculates for area idx "aidx" with "napix" valid pixels:
840//
841// Ped per slice = sum / nevts / fExtractWinSize / napix;
842// RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / napix }
843// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / napix;
844//
845// Stores the results in MPedestalCam::GetAverageArea(aidx)
846//
847void MExtractPedestal::CalcAreaResults(const UInt_t aidx)
848{
849 const UInt_t nevts = fAreaFilled[aidx];
850 if (nevts<2)
851 return;
852
853 const UInt_t napix = fAreaValid[aidx];
854 if (napix<1)
855 return;
856
857 const Double_t sum = fAreaSumx[aidx];
858 const Double_t sum2 = fAreaSumx2[aidx];
859
860 // 1. Calculate the mean of the sums:
861 Double_t ped = sum/nevts;
862
863 // 2. Calculate the Variance of the sums:
864 Double_t var = (sum2/napix-sum*sum/nevts)/(nevts-1.);
865
866 // 3. Calculate the amplitude of the 150MHz "AB" noise
867 Double_t abOffs = (fAreaSumAB0[aidx] - fAreaSumAB1[aidx]) / nevts;
868
869 // 4. Scale the mean, variance and AB-noise to the number of slices:
870 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
871 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
872 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
873 // The pedestal extracted with the extractor is divided by
874 // the number of hi-gain samples because the calibration
875 // multiplies by this number
876
877 // scale to 256
878 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale();
879
880 // 5. Scale the mean, variance and AB-noise to the number of pixels:
881 ped /= napix*scale;
882 abOffs /= napix*scale;
883
884 // 6. Calculate the RMS from the Variance:
885 const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale;
886
887 // abOffs contains only half of the signal as ped.
888 // Therefor abOffs is not the full, but the half amplitude
889 fPedestalsOut->GetAverageArea(aidx).Set(ped, rms, abOffs, nevts);
890}
891
892// ---------------------------------------------------------------------------------
893//
894// Calculates for sector idx "sector" with "nspix" valid pixels:
895//
896// Ped per slice = sum / nevts / fExtractWinSize / nspix;
897// RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / nspix }
898// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / nspix;
899//
900// Stores the results in MPedestalCam::GetAverageSector(sector)
901//
902void MExtractPedestal::CalcSectorResults(const UInt_t sector)
903{
904 const UInt_t nevts = fSectorFilled[sector];
905 if (nevts<2)
906 return;
907
908 const UInt_t nspix = fSectorValid[sector];
909 if (nspix<1)
910 return;
911
912 const Double_t sum = fSectorSumx[sector];
913 const Double_t sum2 = fSectorSumx2[sector];
914
915 // 1. Calculate the mean of the sums:
916 Double_t ped = sum/nevts;
917
918 // 2. Calculate the Variance of the sums:
919 Double_t var = (sum2/nspix-sum*sum/nevts)/(nevts-1.);
920
921 // 3. Calculate the amplitude of the 150MHz "AB" noise
922 Double_t abOffs = (fSectorSumAB0[sector] - fSectorSumAB1[sector]) / nevts;
923
924 // 4. Scale the mean, variance and AB-noise to the number of slices:
925 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
926 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
927 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
928 // The pedestal extracted with the extractor is divided by
929 // the number of hi-gain samples because the calibration
930 // multiplies by this number
931
932 // scale to 256
933 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale();
934
935 // 5. Scale the mean, variance and AB-noise to the number of pixels:
936 ped /= nspix*scale;
937 abOffs /= nspix*scale;
938
939 // 6. Calculate the RMS from the Variance:
940 const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale;
941
942 // abOffs contains only half of the signal as ped.
943 // Therefor abOffs is not the full, but the half amplitude
944 fPedestalsOut->GetAverageSector(sector).Set(ped, rms, abOffs, nevts);
945}
946
947// --------------------------------------------------------------------------
948//
949// Loop over the pixels to get the averaged pedestal
950//
951void MExtractPedestal::CalcPixResult()
952{
953 for (UInt_t idx=0; idx<fNumEventsUsed.GetSize(); idx++)
954 CalcPixResults(idx);
955}
956
957// --------------------------------------------------------------------------
958//
959// Loop over the sector indices to get the averaged pedestal per sector
960//
961void MExtractPedestal::CalcSectorResult()
962{
963 for (UInt_t sector=0; sector<fSectorFilled.GetSize(); sector++)
964 CalcSectorResults(sector);
965}
966
967// --------------------------------------------------------------------------
968//
969// Loop over the (two) area indices to get the averaged pedestal per aidx
970//
971void MExtractPedestal::CalcAreaResult()
972{
973 for (UInt_t aidx=0; aidx<fAreaFilled.GetSize(); aidx++)
974 CalcAreaResults(aidx);
975}
976
977//-----------------------------------------------------------------------
978//
979void MExtractPedestal::Print(Option_t *o) const
980{
981 *fLog << GetDescriptor() << ":" << endl;
982 *fLog << "Name of interm. MPedestalCam: " << (fPedestalsInter?fPedestalsInter->GetName():fNamePedestalCamInter.Data()) << " (" << fPedestalsInter << ")" << endl;
983 *fLog << "Name of output MPedestalCam: " << (fPedestalsOut?fPedestalsOut->GetName():fNamePedestalCamOut.Data()) << " (" << fPedestalsOut << ")" << endl;
984 *fLog << "Intermediate Storage is " << (fIntermediateStorage?"on":"off") << endl;
985 *fLog << "Special pixel mode " << (fUseSpecialPixels?"on":"off") << endl;
986 if (fExtractor)
987 {
988 *fLog << "Extractor used: " << fExtractor->ClassName() << " (";
989 *fLog << (fRandomCalculation?"":"non-") << "random)" << endl;
990 }
991 *fLog << "ExtractWindow from slice " << fExtractWinFirst << " to " << fExtractWinLast << " incl." << endl;
992 *fLog << "CheckWindow from slice " << fCheckWinFirst << " to " << fCheckWinLast << " incl." << endl;
993 *fLog << "Max.allowed signal variation: " << fMaxSignalVar << endl;
994 *fLog << "Max.allowed signal absolute: " << fMaxSignalAbs << endl;
995}
996
997// --------------------------------------------------------------------------
998//
999// The following resources are available:
1000// ExtractWindowFirst: 15
1001// ExtractWindowSize: 6
1002// PedestalUpdate: yes
1003// RandomCalculation: yes
1004//
1005Int_t MExtractPedestal::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
1006{
1007 Bool_t rc=kFALSE;
1008
1009 // find resource for fUseSpecialPixels
1010 if (IsEnvDefined(env, prefix, "UseSpecialPixels", print))
1011 {
1012 SetUseSpecialPixels(GetEnvValue(env, prefix, "UseSpecialPixels", fUseSpecialPixels));
1013 rc = kTRUE;
1014 }
1015
1016 if (IsEnvDefined(env, prefix, "IntermediateStorage", print))
1017 {
1018 SetIntermediateStorage(GetEnvValue(env, prefix, "IntermediateStorage", fIntermediateStorage));
1019 rc = kTRUE;
1020 }
1021
1022 // find resource for random calculation
1023 if (IsEnvDefined(env, prefix, "RandomCalculation", print))
1024 {
1025 SetRandomCalculation(GetEnvValue(env, prefix, "RandomCalculation", fRandomCalculation));
1026 rc = kTRUE;
1027 }
1028
1029 // Find resources for ExtractWindow
1030 Int_t ef = fExtractWinFirst;
1031 Int_t es = fExtractWinSize;
1032 if (IsEnvDefined(env, prefix, "ExtractWinFirst", print))
1033 {
1034 ef = GetEnvValue(env, prefix, "ExtractWinFirst", ef);
1035 rc = kTRUE;
1036 }
1037 if (IsEnvDefined(env, prefix, "ExtractWinSize", print))
1038 {
1039 es = GetEnvValue(env, prefix, "ExtractWinSize", es);
1040 rc = kTRUE;
1041 }
1042
1043 SetExtractWindow(ef,es);
1044
1045 // Find resources for CheckWindow
1046 Int_t cfs = fCheckWinFirst;
1047 Int_t cls = fCheckWinLast;
1048 if (IsEnvDefined(env, prefix, "CheckWinFirst", print))
1049 {
1050 cfs = GetEnvValue(env, prefix, "CheckWinFirst", cfs);
1051 rc = kTRUE;
1052 }
1053 if (IsEnvDefined(env, prefix, "CheckWinLast", print))
1054 {
1055 cls = GetEnvValue(env, prefix, "CheckWinLast", cls);
1056 rc = kTRUE;
1057 }
1058
1059 SetCheckRange(cfs,cls);
1060
1061 // find resource for maximum signal variation
1062 if (IsEnvDefined(env, prefix, "MaxSignalVar", print))
1063 {
1064 SetMaxSignalVar(GetEnvValue(env, prefix, "MaxSignalVar", fMaxSignalVar));
1065 rc = kTRUE;
1066 }
1067
1068 if (IsEnvDefined(env, prefix, "MaxSignalAbs", print))
1069 {
1070 SetMaxSignalAbs(GetEnvValue(env, prefix, "MaxSignalAbs", fMaxSignalAbs));
1071 rc = kTRUE;
1072 }
1073
1074 // find resource for MPedestalCam
1075 if (IsEnvDefined(env, prefix, "NamePedestalCamInter", print))
1076 {
1077 SetNamePedestalCamInter(GetEnvValue(env, prefix, "NamePedestalCamInter", fNamePedestalCamInter));
1078 rc = kTRUE;
1079 }
1080
1081 if (IsEnvDefined(env, prefix, "NamePedestalCamOut", print))
1082 {
1083 SetNamePedestalCamOut(GetEnvValue(env, prefix, "NamePedestalCamOut", fNamePedestalCamOut));
1084 rc = kTRUE;
1085 }
1086
1087 return rc;
1088}
Note: See TracBrowser for help on using the repository browser.