source: trunk/MagicSoft/Mars/mpedestal/MExtractPedestal.cc@ 9338

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