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

Last change on this file since 8582 was 8582, checked in by tbretz, 17 years ago
*** empty log message ***
File size: 34.1 KB
Line 
1/* ======================================================================== *\
2! $Name: not supported by cvs2svn $:$Id: MExtractPedestal.cc,v 1.33 2007-06-19 09:25:39 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{
201 fName = name ? name : "MExtractPedestal";
202 fTitle = title ? title : "Base class to calculate pedestals";
203
204 SetIntermediateStorage( kFALSE );
205 SetRandomCalculation ( kTRUE );
206
207 SetNamePedestalCamOut();
208 SetNamePedestalCamInter();
209 SetNameRawEvtData();
210
211 SetCheckRange(fgCheckWinFirst, fgCheckWinLast);
212 SetMaxSignalVar(fgMaxSignalVar);
213 SetMaxSignalAbs(fgMaxSignalAbs);
214
215 Clear();
216}
217
218// --------------------------------------------------------------------------
219//
220// Call reset() of all Arays
221//
222void MExtractPedestal::ResetArrays()
223{
224 // Reset contents of arrays.
225 fSumx.Reset();
226 fSumx2.Reset();
227 fSumAB0.Reset();
228 fSumAB1.Reset();
229 fAreaSumx.Reset();
230 fAreaSumx2.Reset();
231 fAreaSumAB0.Reset();
232 fAreaSumAB1.Reset();
233 fAreaFilled.Reset();
234 fAreaValid.Reset();
235 fSectorSumx.Reset();
236 fSectorSumx2.Reset();
237 fSectorSumAB0.Reset();
238 fSectorSumAB1.Reset();
239 fSectorFilled.Reset();
240 fSectorValid.Reset();
241 fNumEventsUsed.Reset();
242}
243
244// --------------------------------------------------------------------------
245//
246// Resets Arrays:
247//
248// Sets:
249// - fRawEvt to NULL
250// - fRunHeader to NULL
251//
252void MExtractPedestal::Clear(const Option_t *o)
253{
254
255 fRawEvt = NULL;
256 fRunHeader = NULL;
257
258 // If the size is yet set, set the size
259 if (fSumx.GetSize()>0)
260 ResetArrays();
261
262}
263
264// --------------------------------------------------------------------------
265//
266// Checks:
267// - if a window is odd
268//
269Bool_t MExtractPedestal::SetExtractWindow(UShort_t windowf, UShort_t windows)
270{
271 Bool_t rc = kTRUE;
272
273 if (windows==0)
274 {
275 *fLog << warn << GetDescriptor();
276 *fLog << " - WARNING: Window size in SetExtractWindow has to be > 0... adjusting to 2!" << endl;
277 windows = 2;
278 rc = kFALSE;
279 }
280
281 fExtractWinSize = windows;
282 fExtractWinFirst = windowf;
283 fExtractWinLast = fExtractWinFirst+fExtractWinSize-1;
284
285 return rc;
286}
287
288// --------------------------------------------------------------------------
289//
290// SetCheckRange:
291//
292// Exits, if the first argument is smaller than 0
293// Exits, if the the last argument is smaller than the first
294//
295Bool_t MExtractPedestal::SetCheckRange(UShort_t chfirst, UShort_t chlast)
296{
297
298 Bool_t rc = kTRUE;
299
300 if (chlast<=chfirst)
301 {
302 *fLog << warn << GetDescriptor();
303 *fLog << " - WARNING: Last slice in SetCheckRange smaller than first slice... set to first+2" << endl;
304 chlast = chfirst+1;
305 rc = kFALSE;
306 }
307
308 fCheckWinFirst = chfirst;
309 fCheckWinLast = chlast;
310
311 return rc;
312}
313
314Bool_t MExtractPedestal::SetRangeFromExtractor(const MExtractor &ext, Bool_t logain)
315{
316 const Bool_t haslogains = ext.GetLoGainFirst()!=0 && ext.GetLoGainLast()!=0;
317
318 Bool_t rc1 = kTRUE;
319 if (!haslogains)
320 {
321 // We assume that in case without lo-gains we
322 // deal with pedestal events only
323 rc1 = SetCheckRange(ext.GetHiGainFirst(), ext.GetHiGainLast());
324 }
325
326 const Int_t f = logain && haslogains ? ext.GetLoGainFirst() : ext.GetHiGainFirst();
327 const Int_t l = logain && haslogains ? ext.GetLoGainLast() : ext.GetHiGainLast();
328
329 const Int_t w = (l-f+1);
330
331 // Setup to use the hi-gain extraction window in the lo-gain
332 // range (the start of the lo-gain range is added automatically
333 // by MPedCalcFromLoGain)
334 const Bool_t rc2 = SetExtractWindow(f, w);
335
336 return rc1 && rc2;
337}
338
339// --------------------------------------------------------------------------
340//
341// Check (and if neccesary: correct) the extraction and check ranges.
342//
343void MExtractPedestal::CheckExtractionWindow(UInt_t offset)
344{
345 *fLog << inf;
346 *fLog << "Requested CheckWindow is [" << fCheckWinFirst << "," << fCheckWinLast << "]." <<endl;
347 *fLog << "Requested ExtractWindow is [" << fExtractWinFirst+offset << "," << fExtractWinLast+offset << "]." <<endl;
348
349 // fSignal->GetNumSamples() not yet initialized!!!
350 const UInt_t num = fRunHeader->GetNumSamplesHiGain()+fRunHeader->GetNumSamplesLoGain();
351
352 if (fCheckWinLast >= num)
353 {
354 *fLog << "CheckWindow [" << fCheckWinFirst << "," << fCheckWinLast;
355 *fLog << "] out of range [0," << num-1 << "]... ";
356 *fLog << "reset upper edge." << endl;
357
358 fCheckWinLast = num-1;
359 }
360
361 if (offset+fExtractWinLast >= num)
362 {
363 *fLog << "ExtractWindow [" << fExtractWinFirst+offset << "," << fExtractWinLast+offset;
364 *fLog << "] out of range [0," << num-1 << "]... ";
365 *fLog << "reset upper edge." << endl;
366
367 fExtractWinLast = num-offset-1;
368 }
369
370 fExtractWinSize = fExtractWinLast-fExtractWinFirst+1;
371
372 if (fExtractor || TMath::Even(fExtractWinSize))
373 return;
374
375 fExtractWinLast += offset+fExtractWinLast==num-1 ? -1 : +1;
376
377 *fLog << "ExtractionWindow odd... set to [";
378 *fLog << fExtractWinFirst+offset << "," << fExtractWinLast+offset << "]" << endl;
379
380 fExtractWinSize = fExtractWinLast-fExtractWinFirst+1;
381}
382
383// --------------------------------------------------------------------------
384//
385// Look for the following input containers:
386//
387// - MRawEvtData
388// - MRawRunHeader
389// - MRawEvtHeader
390// - MGeomCam
391//
392// The following output containers are also searched and created if
393// they were not found:
394//
395// - MPedestalCam with the name fPedContainerName
396//
397Int_t MExtractPedestal::PreProcess(MParList *pList)
398{
399
400 Clear();
401
402 fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber(fNameRawEvtData));
403 if (!fRawEvt)
404 {
405 *fLog << err << AddSerialNumber(fNameRawEvtData) << " not found... aborting." << endl;
406 return kFALSE;
407 }
408
409 fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
410 if (!fRunHeader)
411 {
412 *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl;
413 return kFALSE;
414 }
415
416 fGeom = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
417 if (!fGeom)
418 {
419 *fLog << err << AddSerialNumber("MGeomCam") << " not found... aborting." << endl;
420 return kFALSE;
421 }
422
423 fSignal = (MPedestalSubtractedEvt*)pList->FindObject(AddSerialNumber("MPedestalSubtractedEvt"));
424 if (!fSignal)
425 {
426 *fLog << err << AddSerialNumber("MPedestalSubtractedEvt") << " not found... aborting." << endl;
427 return kFALSE;
428 }
429
430 if (!fPedestalsInter && fIntermediateStorage)
431 {
432 fPedestalsInter = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamInter));
433 if (!fPedestalsInter)
434 return kFALSE;
435 }
436
437 if (!fPedestalsOut)
438 {
439 fPedestalsOut = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamOut));
440 if (!fPedestalsOut)
441 return kFALSE;
442 }
443
444 return fExtractor ? fExtractor->CallPreProcess(pList) : kTRUE;
445}
446
447//-----------------------------------------------------------------------
448//
449// Call Calc(). If fExtractor!=NULL enclose the call in setting the
450// NoiseCalculation to fRandomCalculation
451//
452Int_t MExtractPedestal::Process()
453{
454 //
455 // Necessary check for extraction of special pixels
456 // together with data which does not yet have them
457 //
458 if (fSumx.GetSize()==0)
459 return kTRUE;
460
461 if (fExtractor)
462 fExtractor->SetNoiseCalculation(fRandomCalculation);
463
464 const Int_t rc = Calc();
465
466 if (fExtractor)
467 fExtractor->SetNoiseCalculation(kFALSE);
468
469 return rc;
470}
471
472// ---------------------------------------------------------------------------------
473//
474// Sets the size (from MPedestalCam::GetSize() ) and resets the following arrays:
475// - fSumx
476// - fSumx2
477// - fSumAB0
478// - fSumAB1
479// - fAreaSumx
480// - fAreaSumx2
481// - fAreaSumAB0
482// - fAreaSumAB1
483// - fAreaFilled
484// - fAreaValid
485// - fSectorSumx
486// - fSectorSumx2
487// - fSectorSumAB0
488// - fSectorSumAB1
489// - fSectorFilled
490// - fSectorValid
491//
492Bool_t MExtractPedestal::ReInit(MParList *pList)
493{
494 // Necessary check for special pixels which might not yet have existed
495 if (!fRawEvt)
496 {
497 if (fRunHeader->GetFormatVersion() > 3)
498 return kTRUE;
499
500 *fLog << err << "ERROR - " << fNameRawEvtData << " [MRawEvtData] has not ";
501 *fLog << "been found and format version > 3... abort." << endl;
502 return kFALSE;
503 }
504
505 // If the size is not yet set, set the size
506 if (fSumx.GetSize()==0)
507 {
508 // Initialize the normal pixels (size of MPedestalCam already set by MGeomApply)
509 const Int_t npixels = fPedestalsOut->GetSize();
510
511 fSumx. Set(npixels);
512 fSumx2. Set(npixels);
513 fSumAB0.Set(npixels);
514 fSumAB1.Set(npixels);
515
516 fNumEventsUsed.Set(npixels);
517
518 if (fUseSpecialPixels)
519 {
520 // Initialize size of MPedestalCam in case of special pixels (not done by MGeomApply)
521 const UShort_t nspecial = fRunHeader->GetNumSpecialPixels();
522 if (nspecial == 0)
523 {
524 *fLog << warn << "WARNING - Number of special pixels is 0." << endl;
525 return kTRUE;
526 }
527
528 fPedestalsOut->InitSize((UInt_t)nspecial);
529 }
530 else
531 {
532 // Initialize the averaged areas and sectors (do not exist for special pixels)
533 const Int_t areas = fPedestalsOut->GetNumAverageArea();
534 const Int_t sectors = fPedestalsOut->GetNumAverageSector();
535
536 fAreaSumx. Set(areas);
537 fAreaSumx2. Set(areas);
538 fAreaSumAB0.Set(areas);
539 fAreaSumAB1.Set(areas);
540 fAreaFilled.Set(areas);
541 fAreaValid .Set(areas);
542
543 fSectorSumx. Set(sectors);
544 fSectorSumx2. Set(sectors);
545 fSectorSumAB0.Set(sectors);
546 fSectorSumAB1.Set(sectors);
547 fSectorFilled.Set(sectors);
548 fSectorValid .Set(sectors);
549
550 for (Int_t i=0; i<npixels; i++)
551 {
552 const UInt_t aidx = (*fGeom)[i].GetAidx();
553 const UInt_t sector = (*fGeom)[i].GetSector();
554
555 fAreaValid [aidx] ++;
556 fSectorValid[sector]++;
557 }
558 }
559 }
560
561 if (fExtractor)
562 {
563 if (!fExtractor->ReInit(pList))
564 return kFALSE;
565
566 SetRangeFromExtractor(*fExtractor);
567
568 // fSignal->GetNumSamples() not yet initialized!!!
569 const UInt_t num = fRunHeader->GetNumSamples();
570 if (fExtractWinLast >= num)
571 {
572 *fLog << err;
573 *fLog << "ERROR - Selected fExtractWinLast " << fExtractWinLast;
574 *fLog << " out of range (>=" << num<< ")." << endl;
575 return kFALSE;
576 }
577 }
578 else
579 if (fRunHeader->GetNumSamplesLoGain()==0 && (fCheckWinFirst!=0 || fCheckWinLast!=0))
580 {
581 *fLog << inf << "Data has no lo-gains... resetting check window to extraction window." << endl;
582 SetCheckRange(fExtractWinFirst, fExtractWinLast);
583 }
584
585 //CheckExtractionWindow();
586
587 return kTRUE;
588}
589
590// ---------------------------------------------------------------------------------
591//
592// PostProcess the extractor if available
593//
594Int_t MExtractPedestal::PostProcess()
595{
596 return fExtractor ? fExtractor->CallPostProcess() : kTRUE;
597}
598
599// ---------------------------------------------------------------------------------
600//
601// Check whether the signal variation between fCheckWinFirst and fCheckWinLast
602// exceeds fMaxSignalVar or the signal is greater than fMaxSignalAbs
603//
604Bool_t MExtractPedestal::CheckVariation(UInt_t idx) const
605{
606 // This is the fast workaround to put hi- and lo-gains together
607 USample_t *slices = fSignal->GetSamplesRaw(idx);
608
609 // Start 'real' work
610 USample_t max = 0;
611 USample_t min = (USample_t)-1;
612
613 // Find the maximum and minimum signal per slice in the high gain window
614 for (USample_t *slice=slices+fCheckWinFirst; slice<=slices+fCheckWinLast; slice++)
615 {
616 if (*slice > max)
617 max = *slice;
618 if (*slice < min)
619 min = *slice;
620 }
621
622 max /= fRunHeader->GetScale();
623 min /= fRunHeader->GetScale();
624
625 // If the maximum in the high gain window is smaller than
626 return max-min<fMaxSignalVar && max<fMaxSignalAbs;
627}
628
629// ---------------------------------------------------------------------------------
630//
631// Invoke the hi-gain extraction starting at fExtractWinFirst+offset
632// for fExtractWinLast-fExtractWinFirst+1 slices. If Noise calculation
633// is set it is up to the signal extractor to do the right thing.
634//
635// Returns the extracted signal.
636//
637Float_t MExtractPedestal::CalcExtractor(const MRawEvtPixelIter &pixel, Int_t offset) const
638{
639 // Use the same extraction window as for signal extraction
640 const Int_t first = fExtractWinFirst;
641 const Int_t last = fExtractWinLast;
642
643 const Int_t start = first+offset;
644
645 const Int_t range = last-first+1;
646
647 // This check is already done in CheckExtractionWindow
648 // if (range>pixel.GetNumSamples()-start)
649 // range = pixel.GetNumSamples()-start;
650
651 const Int_t idx = pixel.GetPixelId();
652
653 // Do some handling if maxpos is last slice?
654 const Int_t maxposhi = fRandomCalculation ? 0 : fSignal->GetMaxPos(idx, start, start+range-1);
655
656 const Float_t *sig = fSignal->GetSamples(idx);
657
658 // The pedestal is extracted with the hi-gain extractor (eg. digital
659 // filter weights) but from the lo-gains
660 Float_t dummy[3];
661 Float_t sum = 0;
662 fExtractor->FindTimeAndChargeHiGain2(sig+start, range, sum,
663 dummy[0], dummy[1], dummy[2],
664 0, maxposhi);
665
666 return sum;
667}
668
669// ---------------------------------------------------------------------------------
670//
671// Sum slices from fExtractWinFirst to fExtractWinLast. The total sum is
672// returned. ab0 and ab1 will contain the total sum splitted by the
673// AB-flag. If the AB-flag is invalid ab0=ab1=0 is returned.
674//
675UInt_t MExtractPedestal::CalcSums(const MRawEvtPixelIter &pixel, Int_t offset, UInt_t &ab0, UInt_t &ab1) const
676{
677 const Int_t first = fExtractWinFirst+offset;
678
679 USample_t *ptr = fSignal->GetSamplesRaw(pixel.GetPixelId())+first;
680 USample_t *end = ptr + fExtractWinSize;
681
682 Int_t abflag = pixel.HasABFlag() + first;
683
684 UInt_t ab[2] = { 0, 0 };
685 while (ptr<end)
686 ab[abflag++ & 0x1] += *ptr++;
687
688 // This check if for old data without AB-Flag in the data
689 const Bool_t valid = pixel.IsABFlagValid();
690
691 ab0 = valid ? ab[0] : 0;
692 ab1 = valid ? ab[1] : 0;
693
694 return ab[0]+ab[1];
695}
696
697// ---------------------------------------------------------------------------------
698//
699// Check for the variation of the pixel. Return kFALSE if this pixel
700// should not be used.
701// Calculate the pedestal either with the extractor or by summing slices.
702// And update all arrays.
703//
704Bool_t MExtractPedestal::CalcPixel(const MRawEvtPixelIter &pixel, Int_t offset, UInt_t usespecialpixels)
705{
706 const UInt_t idx = pixel.GetPixelId();
707 if (!CheckVariation(idx))
708 return kFALSE;
709
710 //extract pedestal
711 UInt_t ab[2];
712 const Float_t sum = fExtractor ?
713 CalcExtractor(pixel, offset) :
714 CalcSums(pixel, offset, ab[0], ab[1]);
715
716 fNumEventsUsed[idx]++;
717
718 if (fIntermediateStorage)
719 (*fPedestalsInter)[idx].Set(sum, 0, 0, fNumEventsUsed[idx]);
720
721 const Float_t sqrsum = sum*sum;
722
723 fSumx[idx] += sum;
724 fSumx2[idx] += sqrsum;
725
726 if (!fExtractor && pixel.IsABFlagValid())
727 {
728 fSumAB0[idx] += ab[0];
729 fSumAB1[idx] += ab[1];
730 }
731
732 if (usespecialpixels)
733 return kTRUE;
734
735 const UInt_t aidx = (*fGeom)[idx].GetAidx();
736 const UInt_t sector = (*fGeom)[idx].GetSector();
737
738 fAreaFilled[aidx]++;
739 fSectorFilled[sector]++;
740
741 fAreaSumx[aidx] += sum;
742 fAreaSumx2[aidx] += sqrsum;
743 fSectorSumx[sector] += sum;
744 fSectorSumx2[sector] += sqrsum;
745
746 if (!fExtractor && pixel.IsABFlagValid())
747 {
748 fAreaSumAB0[aidx] += ab[0];
749 fAreaSumAB1[aidx] += ab[1];
750 fSectorSumAB0[aidx] += ab[0];
751 fSectorSumAB1[aidx] += ab[1];
752 }
753
754 return kTRUE;
755}
756
757// ---------------------------------------------------------------------------------
758//
759// Calculates for pixel "idx":
760//
761// Ped per slice = sum / n / fExtractWinSize;
762// RMS per slice = sqrt { (sum2 - sum*sum/n) / (n-1) / fExtractWinSize }
763// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / n / fExtractWinSize;
764//
765// Stores the results in MPedestalCam[pixid]
766//
767void MExtractPedestal::CalcPixResults(const UInt_t pixid)
768{
769 const UInt_t nevts = fNumEventsUsed[pixid];
770 if (nevts<2)
771 return;
772
773 const Double_t sum = fSumx[pixid];
774 const Double_t sum2 = fSumx2[pixid];
775
776 // 1. Calculate the mean of the sums:
777 Double_t ped = sum/nevts;
778
779 // 2. Calculate the Variance of the sums:
780 Double_t var = (sum2-sum*sum/nevts)/(nevts-1.);
781
782 // 3. Calculate the amplitude of the 150MHz "AB" noise
783 Double_t abOffs = (fSumAB0[pixid] - fSumAB1[pixid]) / nevts;
784
785 // 4. Scale the mean, variance and AB-noise to the number of slices:
786 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
787 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
788 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
789 // The pedestal extracted with the extractor is divided by
790 // the number of hi-gain samples because the calibration
791 // multiplies by this number
792
793 // scale to 256
794 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale();
795
796 ped /= scale;
797 abOffs /= scale;
798
799 // 5. Calculate the RMS from the Variance:
800 const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale;
801
802 // abOffs contains only half of the signal as ped.
803 // Therefor abOffs is not the full, but the half amplitude
804 (*fPedestalsOut)[pixid].Set(ped, rms, abOffs, nevts);
805}
806
807// ---------------------------------------------------------------------------------
808//
809// Calculates for area idx "aidx" with "napix" valid pixels:
810//
811// Ped per slice = sum / nevts / fExtractWinSize / napix;
812// RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / napix }
813// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / napix;
814//
815// Stores the results in MPedestalCam::GetAverageArea(aidx)
816//
817void MExtractPedestal::CalcAreaResults(const UInt_t aidx)
818{
819 const UInt_t nevts = fAreaFilled[aidx];
820 if (nevts<2)
821 return;
822
823 const UInt_t napix = fAreaValid[aidx];
824 if (napix<1)
825 return;
826
827 const Double_t sum = fAreaSumx[aidx];
828 const Double_t sum2 = fAreaSumx2[aidx];
829
830 // 1. Calculate the mean of the sums:
831 Double_t ped = sum/nevts;
832
833 // 2. Calculate the Variance of the sums:
834 Double_t var = (sum2/napix-sum*sum/nevts)/(nevts-1.);
835
836 // 3. Calculate the amplitude of the 150MHz "AB" noise
837 Double_t abOffs = (fAreaSumAB0[aidx] - fAreaSumAB1[aidx]) / nevts;
838
839 // 4. Scale the mean, variance and AB-noise to the number of slices:
840 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
841 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
842 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
843 // The pedestal extracted with the extractor is divided by
844 // the number of hi-gain samples because the calibration
845 // multiplies by this number
846
847 // scale to 256
848 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale();
849
850 // 5. Scale the mean, variance and AB-noise to the number of pixels:
851 ped /= napix*scale;
852 abOffs /= napix*scale;
853
854 // 6. Calculate the RMS from the Variance:
855 const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale;
856
857 // abOffs contains only half of the signal as ped.
858 // Therefor abOffs is not the full, but the half amplitude
859 fPedestalsOut->GetAverageArea(aidx).Set(ped, rms, abOffs, nevts);
860}
861
862// ---------------------------------------------------------------------------------
863//
864// Calculates for sector idx "sector" with "nspix" valid pixels:
865//
866// Ped per slice = sum / nevts / fExtractWinSize / nspix;
867// RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / nspix }
868// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / nspix;
869//
870// Stores the results in MPedestalCam::GetAverageSector(sector)
871//
872void MExtractPedestal::CalcSectorResults(const UInt_t sector)
873{
874 const UInt_t nevts = fSectorFilled[sector];
875 if (nevts<2)
876 return;
877
878 const UInt_t nspix = fSectorValid[sector];
879 if (nspix<1)
880 return;
881
882 const Double_t sum = fSectorSumx[sector];
883 const Double_t sum2 = fSectorSumx2[sector];
884
885 // 1. Calculate the mean of the sums:
886 Double_t ped = sum/nevts;
887
888 // 2. Calculate the Variance of the sums:
889 Double_t var = (sum2/nspix-sum*sum/nevts)/(nevts-1.);
890
891 // 3. Calculate the amplitude of the 150MHz "AB" noise
892 Double_t abOffs = (fSectorSumAB0[sector] - fSectorSumAB1[sector]) / nevts;
893
894 // 4. Scale the mean, variance and AB-noise to the number of slices:
895 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
896 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
897 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
898 // The pedestal extracted with the extractor is divided by
899 // the number of hi-gain samples because the calibration
900 // multiplies by this number
901
902 // scale to 256
903 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale();
904
905 // 5. Scale the mean, variance and AB-noise to the number of pixels:
906 ped /= nspix*scale;
907 abOffs /= nspix*scale;
908
909 // 6. Calculate the RMS from the Variance:
910 const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale;
911
912 // abOffs contains only half of the signal as ped.
913 // Therefor abOffs is not the full, but the half amplitude
914 fPedestalsOut->GetAverageSector(sector).Set(ped, rms, abOffs, nevts);
915}
916
917// --------------------------------------------------------------------------
918//
919// Loop over the pixels to get the averaged pedestal
920//
921void MExtractPedestal::CalcPixResult()
922{
923 for (UInt_t idx=0; idx<fNumEventsUsed.GetSize(); idx++)
924 CalcPixResults(idx);
925}
926
927// --------------------------------------------------------------------------
928//
929// Loop over the sector indices to get the averaged pedestal per sector
930//
931void MExtractPedestal::CalcSectorResult()
932{
933 for (UInt_t sector=0; sector<fSectorFilled.GetSize(); sector++)
934 CalcSectorResults(sector);
935}
936
937// --------------------------------------------------------------------------
938//
939// Loop over the (two) area indices to get the averaged pedestal per aidx
940//
941void MExtractPedestal::CalcAreaResult()
942{
943 for (UInt_t aidx=0; aidx<fAreaFilled.GetSize(); aidx++)
944 CalcAreaResults(aidx);
945}
946
947//-----------------------------------------------------------------------
948//
949void MExtractPedestal::Print(Option_t *o) const
950{
951 *fLog << GetDescriptor() << ":" << endl;
952 *fLog << "Name of interm. MPedestalCam: " << (fPedestalsInter?fPedestalsInter->GetName():fNamePedestalCamInter.Data()) << " (" << fPedestalsInter << ")" << endl;
953 *fLog << "Name of output MPedestalCam: " << (fPedestalsOut?fPedestalsOut->GetName():fNamePedestalCamOut.Data()) << " (" << fPedestalsOut << ")" << endl;
954 *fLog << "Intermediate Storage is " << (fIntermediateStorage?"on":"off") << endl;
955 *fLog << "Special pixel mode " << (fUseSpecialPixels?"on":"off") << endl;
956 if (fExtractor)
957 {
958 *fLog << "Extractor used: " << fExtractor->ClassName() << " (";
959 *fLog << (fRandomCalculation?"":"non-") << "random)" << endl;
960 }
961 *fLog << "ExtractWindow from slice " << fExtractWinFirst << " to " << fExtractWinLast << " incl." << endl;
962 *fLog << "CheckWindow from slice " << fCheckWinFirst << " to " << fCheckWinLast << " incl." << endl;
963 *fLog << "Max.allowed signal variation: " << fMaxSignalVar << endl;
964 *fLog << "Max.allowed signal absolute: " << fMaxSignalAbs << endl;
965}
966
967// --------------------------------------------------------------------------
968//
969// The following resources are available:
970// ExtractWindowFirst: 15
971// ExtractWindowSize: 6
972// PedestalUpdate: yes
973// RandomCalculation: yes
974//
975Int_t MExtractPedestal::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
976{
977 Bool_t rc=kFALSE;
978
979 // find resource for fUseSpecialPixels
980 if (IsEnvDefined(env, prefix, "UseSpecialPixels", print))
981 {
982 SetUseSpecialPixels(GetEnvValue(env, prefix, "UseSpecialPixels", fUseSpecialPixels));
983 rc = kTRUE;
984 }
985
986 if (IsEnvDefined(env, prefix, "IntermediateStorage", print))
987 {
988 SetIntermediateStorage(GetEnvValue(env, prefix, "IntermediateStorage", fIntermediateStorage));
989 rc = kTRUE;
990 }
991
992 // find resource for random calculation
993 if (IsEnvDefined(env, prefix, "RandomCalculation", print))
994 {
995 SetRandomCalculation(GetEnvValue(env, prefix, "RandomCalculation", fRandomCalculation));
996 rc = kTRUE;
997 }
998
999 // Find resources for ExtractWindow
1000 Int_t ef = fExtractWinFirst;
1001 Int_t es = fExtractWinSize;
1002 if (IsEnvDefined(env, prefix, "ExtractWinFirst", print))
1003 {
1004 ef = GetEnvValue(env, prefix, "ExtractWinFirst", ef);
1005 rc = kTRUE;
1006 }
1007 if (IsEnvDefined(env, prefix, "ExtractWinSize", print))
1008 {
1009 es = GetEnvValue(env, prefix, "ExtractWinSize", es);
1010 rc = kTRUE;
1011 }
1012
1013 SetExtractWindow(ef,es);
1014
1015 // Find resources for CheckWindow
1016 Int_t cfs = fCheckWinFirst;
1017 Int_t cls = fCheckWinLast;
1018 if (IsEnvDefined(env, prefix, "CheckWinFirst", print))
1019 {
1020 cfs = GetEnvValue(env, prefix, "CheckWinFirst", cfs);
1021 rc = kTRUE;
1022 }
1023 if (IsEnvDefined(env, prefix, "CheckWinLast", print))
1024 {
1025 cls = GetEnvValue(env, prefix, "CheckWinLast", cls);
1026 rc = kTRUE;
1027 }
1028
1029 SetCheckRange(cfs,cls);
1030
1031 // find resource for maximum signal variation
1032 if (IsEnvDefined(env, prefix, "MaxSignalVar", print))
1033 {
1034 SetMaxSignalVar(GetEnvValue(env, prefix, "MaxSignalVar", fMaxSignalVar));
1035 rc = kTRUE;
1036 }
1037
1038 if (IsEnvDefined(env, prefix, "MaxSignalAbs", print))
1039 {
1040 SetMaxSignalAbs(GetEnvValue(env, prefix, "MaxSignalAbs", fMaxSignalAbs));
1041 rc = kTRUE;
1042 }
1043
1044 // find resource for MPedestalCam
1045 if (IsEnvDefined(env, prefix, "NamePedestalCamInter", print))
1046 {
1047 SetNamePedestalCamInter(GetEnvValue(env, prefix, "NamePedestalCamInter", fNamePedestalCamInter));
1048 rc = kTRUE;
1049 }
1050
1051 if (IsEnvDefined(env, prefix, "NamePedestalCamOut", print))
1052 {
1053 SetNamePedestalCamOut(GetEnvValue(env, prefix, "NamePedestalCamOut", fNamePedestalCamOut));
1054 rc = kTRUE;
1055 }
1056
1057 return rc;
1058}
Note: See TracBrowser for help on using the repository browser.