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

Last change on this file since 5676 was 5570, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 20.6 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!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MExtractPedestal
28//
29// Pedestal Extractor base class
30//
31// Input Containers:
32// MRawEvtData
33// MRawRunHeader
34// MRawEvtHeader
35// MGeomCam
36// MPedestalCam
37//
38// Output Containers:
39// MPedestalCam
40//
41// This class should be used for pedestal extractors with the following facilities:
42// a) Standardized calculation of AB-noise, mean pedestals and RMS
43// b) Standardized treatment of area- and sector averaged pedestals values
44// c) Possibility to use a signal extractor to be applied on the pedestals
45// d) Possibility to handle two MPedestalCams: one for the signal extractor and
46// a second to be filled during the pedestal calculating process.
47//
48// ad a): Every calculated value is referred to one FADC slice (e.g. Mean pedestal per slice),
49// RMS per slice.
50// MExtractPedestal applies the following formula (1):
51//
52// Pedestal per slice = sum(x_i) / n / slices
53// PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / slices )
54// AB-Offset per slice = (sumAB0 - sumAB1) / n / slices
55//
56// where x_i is the sum of "slices" FADC slices and sum means the sum over all
57// events. "n" is the number of events, "slices" is the number of summed FADC samples.
58//
59// Note that the slice-to-slice fluctuations are not Gaussian, but Poissonian, thus
60// asymmetric and they are correlated.
61//
62// It is important to know that the Pedestal per slice and PedRMS per slice depend
63// on the number of used FADC slices, as seen in the following plots:
64//
65//Begin_Html
66/*
67<img src="images/PedestalStudyInner.gif">
68*/
69//End_Html
70//
71//Begin_Html
72/*
73<img src="images/PedestalStudyOuter.gif">
74*/
75//End_Html
76//
77// The plots show the inner and outer pixels, respectivly and have the following meaning:
78//
79// 1) The calculated mean pedestal per slice (from MPedCalcPedRun)
80// 2) The fitted mean pedestal per slice (from MHPedestalCam)
81// 3) The calculated pedestal RMS per slice (from MPedCalcPedRun)
82// 4) The fitted sigma of the pedestal distribution per slice
83// (from MHPedestalCam)
84// 5) The relative difference between calculation and histogram fit
85// for the mean
86// 6) The relative difference between calculation and histogram fit
87// for the sigma or RMS, respectively.
88//
89// The calculated means do not change significantly except for the case of 2 slices,
90// however the RMS changes from 5.7 per slice in the case of 2 extracted slices
91// to 8.3 per slice in the case of 26 extracted slices. This change is very significant.
92//
93// ad b) Every calculated value is referred to one FADC slice and one (averaged) pixel,
94// (e.g. Mean Pedestal per area index per slice per pixel, etc. )
95//
96// MExtractPedestal applies the following formula (2):
97//
98// Averaged Pedestal per slice = sum(x_i) / n / slices / n_pix
99// PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / slices / n_pix )
100// AB-Offset per slice = (sumAB0 - sumAB1) / n / slices / n_pix
101//
102// where x_i is the sum of "slices" FADC slices and sum means the sum over all
103// events and all concerned pixels.
104// "n" is the number of events, "slices" is the number of summed FADC samples and
105// "n_pix" is the number of pixels belonging to the specific area index or camera sector.
106//
107// Calculating these averaged event-by-event values is very important to trace coherent
108// fluctuations. An example is given in the following plots:
109//
110//Begin_Html
111/*
112<img src="images/PedestalOscillations.gif">
113*/
114//End_Html
115//
116// The plots show the extracted pedestals of the inner pixels (obtained
117// with MHPedestalCam), averaged on an event-by-event basis from
118// run 13428 with switched off camera LV.
119// The meaning of the four plots is:
120//
121// 1) The distribution of the averaged pedestals
122// 2) The averaged pedestals vs. time.
123// One can see clearly the oscillation pattern
124// 3) The fourier transform of the averaged pedestals vs. time.
125// One can see clearly a peak at a certain frequency
126// 4) The projection of the fourier components with the non-exponential
127// (and therefore significant) outlier.
128//
129// ad c) Many signal extractors, especially those using a sliding window
130// have biases and their resolutions for zero-signals do not agree
131// with the pedestal RMS. For the F-Factor method in the calibration
132// and the image cleaning, however, both have to be known and measured.
133//
134// For this reason, a signal extractor can be handed over to the
135// pedestal extractor and applied on the pedestal events with the
136// function SetExtractor().
137// The results will get stored in an MPedestalCam.
138//
139// Note that only extractors deriving from MExtractTimeAndCharge
140// can be used.
141//
142// ad d) The signal extractors themselves need a pedestal to be subtracted
143// from the FADC slices.
144// If the user wishes that the pededestals do not get overwritten by
145// the results from the signal extractor, a different named MPedestalCam
146// can be created with the function: SetNamePedestalOut().
147//
148// See also: MPedestalCam, MPedestalPix, MPedCalcPedRun, MPedCalcFromLoGain
149//
150/////////////////////////////////////////////////////////////////////////////
151#include "MExtractPedestal.h"
152
153#include "MParList.h"
154
155#include "MLog.h"
156#include "MLogManip.h"
157
158#include "MRawRunHeader.h"
159#include "MRawEvtHeader.h"
160#include "MRawEvtPixelIter.h"
161#include "MRawEvtData.h"
162
163#include "MPedestalPix.h"
164#include "MPedestalCam.h"
165
166#include "MGeomPix.h"
167#include "MGeomCam.h"
168
169#include "MTaskEnv.h"
170#include "MExtractTimeAndCharge.h"
171
172ClassImp(MExtractPedestal);
173
174using namespace std;
175
176const TString MExtractPedestal::fgNamePedestalCam = "MPedestalCam";
177
178// --------------------------------------------------------------------------
179//
180// Default constructor:
181//
182// Sets:
183// - all pointers to NULL
184//
185// Calls:
186// - AddToBranchList("fHiGainPixId");
187// - AddToBranchList("fHiGainFadcSamples");
188// - Clear()
189//
190MExtractPedestal::MExtractPedestal(const char *name, const char *title)
191 : fGeom(NULL), fPedestalsIn(NULL), fPedestalsOut(NULL), fExtractor(NULL),
192 fExtractWinFirst(0), fExtractWinSize(0)
193{
194 fName = name ? name : "MExtractPedestal";
195 fTitle = title ? title : "Base class to calculate pedestals";
196
197 AddToBranchList("fHiGainPixId");
198 AddToBranchList("fLoGainPixId");
199 AddToBranchList("fHiGainFadcSamples");
200 AddToBranchList("fLoGainFadcSamples");
201
202 SetPedestalUpdate(kTRUE);
203
204 SetNamePedestalCamIn();
205 SetNamePedestalCamOut();
206 SetNumEventsDump();
207 SetNumAreasDump();
208 SetNumSectorsDump();
209
210 Clear();
211}
212
213void MExtractPedestal::ResetArrays()
214{
215 // Reset contents of arrays.
216 fSumx.Reset();
217 fSumx2.Reset();
218 fSumAB0.Reset();
219 fSumAB1.Reset();
220 fAreaSumx.Reset();
221 fAreaSumx2.Reset();
222 fAreaSumAB0.Reset();
223 fAreaSumAB1.Reset();
224 fAreaFilled.Reset();
225 fAreaValid.Reset();
226 fSectorSumx.Reset();
227 fSectorSumx2.Reset();
228 fSectorSumAB0.Reset();
229 fSectorSumAB1.Reset();
230 fSectorFilled.Reset();
231 fSectorValid.Reset();
232
233}
234
235// --------------------------------------------------------------------------
236//
237// Resets Arrays:
238//
239// Sets:
240// - fRawEvt to NULL
241// - fRunHeader to NULL
242// - fEvtHeader to NULL
243// - fPedestalsIn to NULL
244// - fPedestalsOut to NULL
245//
246void MExtractPedestal::Clear(const Option_t *o)
247{
248
249 fRawEvt = NULL;
250 fRunHeader = NULL;
251 fEvtHeader = NULL;
252
253 // If the size is yet set, set the size
254 if (fSumx.GetSize()>0)
255 ResetArrays();
256
257}
258
259// --------------------------------------------------------------------------
260//
261// Checks:
262// - if a window is odd
263//
264Bool_t MExtractPedestal::SetExtractWindow(UShort_t windowf, UShort_t windows)
265{
266
267 Bool_t rc = kTRUE;
268
269 const Int_t odd = windows & 0x1;
270
271 if (odd)
272 {
273 *fLog << warn << GetDescriptor();
274 *fLog << " - WARNING: Window size in SetExtraxtWindow has to be even... ";
275 *fLog << " raising from " << windows << " to ";
276 windows += 1;
277 *fLog << windows << "!" << endl;
278 rc = kFALSE;
279 }
280
281 if (windows==0)
282 {
283 *fLog << warn << GetDescriptor();
284 *fLog << " - WARNING: Window size in SetExtraxtWindow has to be > 0... adjusting to 2!" << endl;
285 windows = 2;
286 rc = kFALSE;
287 }
288
289 fExtractWinSize = windows;
290 fExtractWinFirst = windowf;
291 fExtractWinLast = fExtractWinFirst+fExtractWinSize-1;
292
293 return rc;
294}
295
296// --------------------------------------------------------------------------
297//
298// Look for the following input containers:
299//
300// - MRawEvtData
301// - MRawRunHeader
302// - MRawEvtHeader
303// - MGeomCam
304//
305// The following output containers are also searched and created if
306// they were not found:
307//
308// - MPedestalCam with the name fPedContainerName
309//
310Int_t MExtractPedestal::PreProcess(MParList *pList)
311{
312
313 Clear();
314
315 fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber("MRawEvtData"));
316 if (!fRawEvt)
317 {
318 *fLog << err << AddSerialNumber("MRawEvtData") << " not found... aborting." << endl;
319 return kFALSE;
320 }
321
322 fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
323 if (!fRunHeader)
324 {
325 *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl;
326 return kFALSE;
327 }
328
329 fEvtHeader = (MRawEvtHeader*)pList->FindObject(AddSerialNumber("MRawEvtHeader"));
330 if (!fEvtHeader)
331 {
332 *fLog << err << AddSerialNumber("MRawEvtHeader") << " not found... aborting." << endl;
333 return kFALSE;
334 }
335
336 fGeom = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
337 if (!fGeom)
338 {
339 *fLog << err << AddSerialNumber("MGeomCam") << " not found... aborting." << endl;
340 return kFALSE;
341 }
342
343 if (fExtractor && !fPedestalsIn)
344 {
345 fPedestalsIn = (MPedestalCam*)pList->FindObject(AddSerialNumber(fNamePedestalCamIn), "MPedestalCam");
346 if (!fPedestalsIn)
347 {
348 *fLog << err << AddSerialNumber(fNamePedestalCamIn) << " not found... aborting." << endl;
349 return kFALSE;
350 }
351 }
352
353 if (!fPedestalsOut)
354 {
355 fPedestalsOut = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamOut));
356 if (!fPedestalsOut)
357 return kFALSE;
358 }
359
360 *fLog << inf;
361 Print();
362
363 return kTRUE;
364}
365
366// ---------------------------------------------------------------------------------
367//
368// Sets the size (from MPedestalCam::GetSize() ) and resets the following arrays:
369// - fSumx
370// - fSumx2
371// - fSumAB0
372// - fSumAB1
373// - fAreaSumx
374// - fAreaSumx2
375// - fAreaSumAB0
376// - fAreaSumAB1
377// - fAreaFilled
378// - fAreaValid
379// - fSectorSumx
380// - fSectorSumx2
381// - fSectorSumAB0
382// - fSectorSumAB1
383// - fSectorFilled
384// - fSectorValid
385//
386Bool_t MExtractPedestal::ReInit(MParList *pList)
387{
388 // If the size is not yet set, set the size
389 if (fSumx.GetSize()==0)
390 {
391 const Int_t npixels = fPedestalsOut->GetSize();
392 const Int_t areas = fPedestalsOut->GetNumAverageArea();
393 const Int_t sectors = fPedestalsOut->GetNumAverageSector();
394
395 fSumx. Set(npixels);
396 fSumx2. Set(npixels);
397 fSumAB0.Set(npixels);
398 fSumAB1.Set(npixels);
399
400 fAreaSumx. Set(areas);
401 fAreaSumx2. Set(areas);
402 fAreaSumAB0.Set(areas);
403 fAreaSumAB1.Set(areas);
404 fAreaFilled.Set(areas);
405 fAreaValid .Set(areas);
406
407 fSectorSumx. Set(sectors);
408 fSectorSumx2. Set(sectors);
409 fSectorSumAB0.Set(sectors);
410 fSectorSumAB1.Set(sectors);
411 fSectorFilled.Set(sectors);
412 fSectorValid .Set(sectors);
413
414 for (Int_t i=0; i<npixels; i++)
415 {
416 const UInt_t aidx = (*fGeom)[i].GetAidx();
417 const UInt_t sector = (*fGeom)[i].GetSector();
418
419 fAreaValid [aidx] ++;
420 fSectorValid[sector]++;
421 }
422 }
423
424 if (fExtractor)
425 {
426 if (!fExtractor->InitArrays())
427 return kFALSE;
428
429 SetExtractWindow(fExtractor->GetHiGainFirst(), (Int_t)TMath::Nint(fExtractor->GetNumHiGainSamples()));
430 }
431
432 return kTRUE;
433}
434
435Int_t MExtractPedestal::PostProcess()
436{
437 fPedestalsIn = NULL;
438 return kTRUE;
439}
440
441
442// --------------------------------------------------------------------------
443//
444// The following resources are available:
445// ExtractWindowFirst: 15
446// ExtractWindowSize: 6
447// NumEventsDump: 500
448// PedestalUpdate: yes
449//
450Int_t MExtractPedestal::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
451{
452 Bool_t rc=kFALSE;
453
454 // find resource for numeventsdump
455 if (IsEnvDefined(env, prefix, "NumEventsDump", print))
456 {
457 SetNumEventsDump(GetEnvValue(env, prefix, "NumEventsDump", (Int_t)fNumEventsDump));
458 rc = kTRUE;
459 }
460
461 // find resource for numeventsdump
462 if (IsEnvDefined(env, prefix, "NumAreasDump", print))
463 {
464 SetNumAreasDump(GetEnvValue(env, prefix, "NumAreasDump", (Int_t)fNumAreasDump));
465 rc = kTRUE;
466 }
467
468 // find resource for numeventsdump
469 if (IsEnvDefined(env, prefix, "NumSectorsDump", print))
470 {
471 SetNumSectorsDump(GetEnvValue(env, prefix, "NumSectorsDump", (Int_t)fNumSectorsDump));
472 rc = kTRUE;
473 }
474
475 // find resource for pedestal update
476 if (IsEnvDefined(env, prefix, "PedestalUpdate", print))
477 {
478 SetPedestalUpdate(GetEnvValue(env, prefix, "PedestalUpdate", fPedestalUpdate));
479 rc = kTRUE;
480 }
481
482 // Find resources for ExtractWindow
483 Int_t ef = fExtractWinFirst;
484 Int_t es = fExtractWinSize;
485 if (IsEnvDefined(env, prefix, "ExtractWinFirst", print))
486 {
487 ef = GetEnvValue(env, prefix, "ExtractWinFirst", ef);
488 rc = kTRUE;
489 }
490 if (IsEnvDefined(env, prefix, "ExtractWinSize", print))
491 {
492 es = GetEnvValue(env, prefix, "ExtractWinSize", es);
493 rc = kTRUE;
494 }
495
496 SetExtractWindow(ef,es);
497
498 // find resource for MPedestalCam
499 if (IsEnvDefined(env, prefix, "NamePedestalCamIn", print))
500 {
501 SetNamePedestalCamIn(GetEnvValue(env, prefix, "NamePedestalCamIn", fNamePedestalCamIn));
502 rc = kTRUE;
503 }
504
505 if (IsEnvDefined(env, prefix, "NamePedestalCamOut", print))
506 {
507 SetNamePedestalCamOut(GetEnvValue(env, prefix, "NamePedestalCamOut", fNamePedestalCamOut));
508 rc = kTRUE;
509 }
510
511 return rc;
512}
513
514// ---------------------------------------------------------------------------------
515//
516// Calculates for pixel "idx":
517//
518// Ped per slice = sum / n / fExtractWinSize;
519// RMS per slice = sqrt { (sum2 - sum*sum/n) / (n-1) / fExtractWinSize }
520// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / n / fExtractWinSize;
521//
522// Stores the results in MPedestalCam[pixid]
523//
524void MExtractPedestal::CalcPixResults(const UInt_t nevts, const UInt_t pixid)
525{
526 const Float_t sum = fSumx[pixid];
527 const Float_t sum2 = fSumx2[pixid];
528
529 // 1. Calculate the mean of the sums:
530 Float_t ped = sum/nevts;
531
532 // 2. Calculate the Variance of the sums:
533 Float_t var = (sum2-sum*sum/nevts)/(nevts-1.);
534
535 // 3. Calculate the amplitude of the 150MHz "AB" noise
536 Float_t abOffs = (fSumAB0[pixid] - fSumAB1[pixid]) / nevts;
537
538 // 4. Scale the mean, variance and AB-noise to the number of slices:
539 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
540 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
541 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
542
543 // 5. Calculate the RMS from the Variance:
544 const Float_t rms = var<0 ? 0 : TMath::Sqrt(var);
545
546 (*fPedestalsOut)[pixid].Set(ped, rms, abOffs, nevts);
547}
548
549// ---------------------------------------------------------------------------------
550//
551// Calculates for area idx "aidx" with "napix" valid pixels:
552//
553// Ped per slice = sum / nevts / fExtractWinSize / napix;
554// RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / napix }
555// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / napix;
556//
557// Stores the results in MPedestalCam::GetAverageArea(aidx)
558//
559void MExtractPedestal::CalcAreaResults(const UInt_t nevts, const UInt_t napix, const UInt_t aidx)
560{
561 const Float_t sum = fAreaSumx[aidx];
562 const Float_t sum2 = fAreaSumx2[aidx];
563
564 // 1. Calculate the mean of the sums:
565 Float_t ped = sum/nevts;
566
567 // 2. Calculate the Variance of the sums:
568 Float_t var = (sum2-sum*sum/nevts)/(nevts-1.);
569
570 // 3. Calculate the amplitude of the 150MHz "AB" noise
571 Float_t abOffs = (fAreaSumAB0[aidx] - fAreaSumAB1[aidx]) / nevts;
572
573 // 4. Scale the mean, variance and AB-noise to the number of slices:
574 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
575 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
576 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
577
578 // 5. Scale the mean, variance and AB-noise to the number of pixels:
579 ped /= napix;
580 var /= napix;
581 abOffs /= napix;
582
583 // 6. Calculate the RMS from the Variance:
584 const Float_t rms = var<0 ? 0 : TMath::Sqrt(var);
585
586 fPedestalsOut->GetAverageArea(aidx).Set(ped, rms, abOffs, nevts);
587}
588
589// ---------------------------------------------------------------------------------
590//
591// Calculates for sector idx "sector" with "nspix" valid pixels:
592//
593// Ped per slice = sum / nevts / fExtractWinSize / nspix;
594// RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / nspix }
595// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / nspix;
596//
597// Stores the results in MPedestalCam::GetAverageSector(sector)
598//
599void MExtractPedestal::CalcSectorResults(const UInt_t nevts, const UInt_t nspix, const UInt_t sector)
600{
601 const Float_t sum = fSectorSumx[sector];
602 const Float_t sum2 = fSectorSumx2[sector];
603
604 // 1. Calculate the mean of the sums:
605 Float_t ped = sum/nevts;
606
607 // 2. Calculate the Variance of the sums:
608 Float_t var = (sum2-sum*sum/nevts)/(nevts-1.);
609
610 // 3. Calculate the amplitude of the 150MHz "AB" noise
611 Float_t abOffs = (fSectorSumAB0[sector] - fSectorSumAB1[sector]) / nevts;
612
613 // 4. Scale the mean, variance and AB-noise to the number of slices:
614 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
615 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
616 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
617
618 // 5. Scale the mean, variance and AB-noise to the number of pixels:
619 ped /= nspix;
620 var /= nspix;
621 abOffs /= nspix;
622
623 // 6. Calculate the RMS from the Variance:
624 const Float_t rms = var<0 ? 0 : TMath::Sqrt(var);
625
626 fPedestalsOut->GetAverageSector(sector).Set(ped, rms, abOffs, nevts);
627}
628
629void MExtractPedestal::Print(Option_t *o) const
630{
631 *fLog << GetDescriptor() << ":" << endl;
632 *fLog << "Name of input MPedestalCam: " << (fPedestalsIn?fPedestalsIn->GetName():fNamePedestalCamIn.Data()) << " (" << fPedestalsIn << ")" << endl;
633 *fLog << "Name of output MPedestalCam: " << (fPedestalsOut?fPedestalsOut->GetName():fNamePedestalCamOut.Data()) << " (" << fPedestalsOut << ")" << endl;
634 *fLog << "Pedestal Update is " << (fPedestalUpdate?"on":"off") << endl;
635 if (fPedestalUpdate)
636 {
637 *fLog << "Num evts for pedestal calc: " << fNumEventsDump << endl;
638 *fLog << "Num evts for avg.areas calc: " << fNumAreasDump << endl;
639 *fLog << "Num evts for avg.sector calc: " << fNumSectorsDump << endl;
640 }
641 if (fExtractor)
642 *fLog << "Extractor used: " << fExtractor->ClassName() << endl;
643 *fLog << "ExtractWindow from slice " << fExtractWinFirst << " to " << fExtractWinLast << " incl." << endl;
644}
Note: See TracBrowser for help on using the repository browser.