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

Last change on this file since 5557 was 5521, checked in by gaug, 20 years ago
*** empty log message ***
File size: 20.4 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#include "MExtractTimeAndCharge.h"
153
154#include "MParList.h"
155
156#include "MLog.h"
157#include "MLogManip.h"
158
159#include "MRawRunHeader.h"
160#include "MRawEvtHeader.h"
161#include "MRawEvtPixelIter.h"
162#include "MRawEvtData.h"
163
164#include "MPedestalPix.h"
165#include "MPedestalCam.h"
166
167#include "MGeomPix.h"
168#include "MGeomCam.h"
169
170ClassImp(MExtractPedestal);
171
172using namespace std;
173
174const TString MExtractPedestal::fgNamePedestalCam = "MPedestalCam";
175// --------------------------------------------------------------------------
176//
177// Default constructor:
178//
179// Sets:
180// - all pointers to NULL
181//
182// Calls:
183// - AddToBranchList("fHiGainPixId");
184// - AddToBranchList("fHiGainFadcSamples");
185// - Clear()
186//
187MExtractPedestal::MExtractPedestal(const char *name, const char *title)
188 : fGeom(NULL), fPedestalsIn(NULL), fPedestalsOut(NULL), fExtractor(NULL),
189 fExtractWinFirst(0), fExtractWinSize(0)
190{
191
192 fName = name ? name : "MExtractPedestal";
193 fTitle = title ? title : "Base class to calculate pedestals";
194
195 AddToBranchList("fHiGainPixId");
196 AddToBranchList("fLoGainPixId");
197 AddToBranchList("fHiGainFadcSamples");
198 AddToBranchList("fLoGainFadcSamples");
199
200 SetPedestalUpdate(kTRUE);
201
202 SetNamePedestalCamIn();
203 SetNamePedestalCamOut();
204 SetNumEventsDump();
205 SetNumAreasDump();
206 SetNumSectorsDump();
207
208 Clear();
209}
210
211void MExtractPedestal::ResetArrays()
212{
213 // Reset contents of arrays.
214 fSumx.Reset();
215 fSumx2.Reset();
216 fSumAB0.Reset();
217 fSumAB1.Reset();
218 fAreaSumx.Reset();
219 fAreaSumx2.Reset();
220 fAreaSumAB0.Reset();
221 fAreaSumAB1.Reset();
222 fAreaFilled.Reset();
223 fAreaValid.Reset();
224 fSectorSumx.Reset();
225 fSectorSumx2.Reset();
226 fSectorSumAB0.Reset();
227 fSectorSumAB1.Reset();
228 fSectorFilled.Reset();
229 fSectorValid.Reset();
230
231}
232
233// --------------------------------------------------------------------------
234//
235// Resets Arrays:
236//
237// Sets:
238// - fRawEvt to NULL
239// - fRunHeader to NULL
240// - fEvtHeader to NULL
241// - fPedestalsIn to NULL
242// - fPedestalsOut to NULL
243//
244void MExtractPedestal::Clear(const Option_t *o)
245{
246
247 fRawEvt = NULL;
248 fRunHeader = NULL;
249 fEvtHeader = NULL;
250 fPedestalsIn = NULL;
251 fPedestalsOut = 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 " raising from " << windows << " to " << flush;
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 fPedestalsIn = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamIn.Data()));
344 if (!fPedestalsIn)
345 {
346 *fLog << err << fNamePedestalCamIn.Data() << " could not be found nor created... aborting" << endl;
347 return kFALSE;
348 }
349
350 fPedestalsOut = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamOut.Data()));
351 if (!fPedestalsOut)
352 {
353 *fLog << err << fNamePedestalCamOut.Data() << " could not be found nor created... aborting" << endl;
354 return kFALSE;
355 }
356
357 *fLog << inf;
358
359 return kTRUE;
360}
361
362// ---------------------------------------------------------------------------------
363//
364// Sets the size (from MPedestalCam::GetSize() ) and resets the following arrays:
365// - fSumx
366// - fSumx2
367// - fSumAB0
368// - fSumAB1
369// - fAreaSumx
370// - fAreaSumx2
371// - fAreaSumAB0
372// - fAreaSumAB1
373// - fAreaFilled
374// - fAreaValid
375// - fSectorSumx
376// - fSectorSumx2
377// - fSectorSumAB0
378// - fSectorSumAB1
379// - fSectorFilled
380// - fSectorValid
381//
382Bool_t MExtractPedestal::ReInit(MParList *pList)
383{
384
385 // If the size is not yet set, set the size
386 if (fSumx.GetSize()==0)
387 {
388 const Int_t npixels = fPedestalsOut->GetSize();
389 const Int_t areas = fPedestalsOut->GetAverageAreas();
390 const Int_t sectors = fPedestalsOut->GetAverageSectors();
391
392 fSumx. Set(npixels);
393 fSumx2. Set(npixels);
394 fSumAB0.Set(npixels);
395 fSumAB1.Set(npixels);
396
397 fAreaSumx. Set(areas);
398 fAreaSumx2. Set(areas);
399 fAreaSumAB0.Set(areas);
400 fAreaSumAB1.Set(areas);
401 fAreaFilled.Set(areas);
402 fAreaValid .Set(areas);
403
404 fSectorSumx. Set(sectors);
405 fSectorSumx2. Set(sectors);
406 fSectorSumAB0.Set(sectors);
407 fSectorSumAB1.Set(sectors);
408 fSectorFilled.Set(sectors);
409 fSectorValid .Set(sectors);
410
411 for (Int_t i=0; i<npixels; i++)
412 {
413 const UInt_t aidx = (*fGeom)[i].GetAidx();
414 const UInt_t sector = (*fGeom)[i].GetSector();
415
416 fAreaValid [aidx] ++;
417 fSectorValid[sector]++;
418 }
419 }
420
421 if (fExtractor)
422 {
423 if (!fExtractor->InitArrays())
424 return kFALSE;
425 SetExtractWindow(fExtractor->GetHiGainFirst(),(Int_t)fExtractor->GetNumHiGainSamples());
426 }
427
428 Print();
429
430 return kTRUE;
431}
432
433// --------------------------------------------------------------------------
434//
435// The following resources are available:
436// ExtractWindowFirst: 15
437// ExtractWindowSize: 6
438// NumEventsDump: 500
439// PedestalUpdate: yes
440//
441Int_t MExtractPedestal::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
442{
443
444 Bool_t rc=kFALSE;
445
446 // find resource for numeventsdump
447 if (IsEnvDefined(env, prefix, "NumEventsDump", print))
448 {
449 SetNumEventsDump(GetEnvValue(env, prefix, "NumEventsDump", (Int_t)fNumEventsDump));
450 rc = kTRUE;
451 }
452
453 // find resource for numeventsdump
454 if (IsEnvDefined(env, prefix, "NumAreasDump", print))
455 {
456 SetNumAreasDump(GetEnvValue(env, prefix, "NumAreasDump", (Int_t)fNumAreasDump));
457 rc = kTRUE;
458 }
459
460 // find resource for numeventsdump
461 if (IsEnvDefined(env, prefix, "NumSectorsDump", print))
462 {
463 SetNumSectorsDump(GetEnvValue(env, prefix, "NumSectorsDump", (Int_t)fNumSectorsDump));
464 rc = kTRUE;
465 }
466
467 // find resource for pedestal update
468 if (IsEnvDefined(env, prefix, "PedestalUpdate", print))
469 {
470 SetPedestalUpdate(GetEnvValue(env, prefix, "PedestalUpdate", fPedestalUpdate));
471 rc = kTRUE;
472 }
473
474 // Find resources for ExtractWindow
475 Int_t ef = fExtractWinFirst;
476 Int_t es = fExtractWinSize;
477 if (IsEnvDefined(env, prefix, "ExtractWinFirst", print))
478 {
479 ef = GetEnvValue(env, prefix, "ExtractWinFirst", ef);
480 rc = kTRUE;
481 }
482 if (IsEnvDefined(env, prefix, "ExtractWinSize", print))
483 {
484 es = GetEnvValue(env, prefix, "ExtractWinSize", es);
485 rc = kTRUE;
486 }
487
488 SetExtractWindow(ef,es);
489
490 // find resource for MPedestalCam
491 if (IsEnvDefined(env, prefix, "NamePedestalCamIn", print))
492 {
493 SetNamePedestalCamIn(GetEnvValue(env, prefix, "NamePedestalCamIn", fNamePedestalCamIn));
494 rc = kTRUE;
495 }
496
497 if (IsEnvDefined(env, prefix, "NamePedestalCamOut", print))
498 {
499 SetNamePedestalCamOut(GetEnvValue(env, prefix, "NamePedestalCamOut", fNamePedestalCamOut));
500 rc = kTRUE;
501 }
502
503 return rc;
504}
505
506// ---------------------------------------------------------------------------------
507//
508// Calculates for pixel "idx":
509//
510// Ped per slice = sum / n / fExtractWinSize;
511// RMS per slice = sqrt { (sum2 - sum*sum/n) / (n-1) / fExtractWinSize }
512// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / n / fExtractWinSize;
513//
514// Stores the results in MPedestalCam[pixid]
515//
516void MExtractPedestal::CalcPixResults(const UInt_t nevts, const UInt_t pixid)
517{
518
519 const Float_t sum = fSumx.At(pixid);
520 const Float_t sum2 = fSumx2.At(pixid);
521
522 // 1. Calculate the mean of the sums:
523 Float_t ped = sum/nevts;
524
525 // 2. Calculate the Variance of the sums:
526 Float_t var = (sum2-sum*sum/nevts)/(nevts-1.);
527
528 // 3. Calculate the amplitude of the 150MHz "AB" noise
529 Float_t abOffs = (fSumAB0[pixid] - fSumAB1[pixid]) / nevts;
530
531 // 4. Scale the mean, variance and AB-noise to the number of slices:
532 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
533 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
534 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
535
536 // 5. Calculate the RMS from the Variance:
537 const Float_t rms = var<0 ? 0 : TMath::Sqrt(var);
538
539 (*fPedestalsOut)[pixid].Set(ped, rms, abOffs, nevts);
540}
541
542// ---------------------------------------------------------------------------------
543//
544// Calculates for area idx "aidx" with "napix" valid pixels:
545//
546// Ped per slice = sum / nevts / fExtractWinSize / napix;
547// RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / napix }
548// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / napix;
549//
550// Stores the results in MPedestalCam::GetAverageArea(aidx)
551//
552void MExtractPedestal::CalcAreaResults(const UInt_t nevts, const UInt_t napix, const UInt_t aidx)
553{
554
555 const Float_t sum = fAreaSumx.At(aidx);
556 const Float_t sum2 = fAreaSumx2.At(aidx);
557
558 // 1. Calculate the mean of the sums:
559 Float_t ped = sum/nevts;
560 //
561 // 2. Calculate the Variance of the sums:
562 //
563 Float_t var = (sum2-sum*sum/nevts)/(nevts-1.);
564 //
565 // 3. Calculate the amplitude of the 150MHz "AB" noise
566 //
567 Float_t abOffs = (fAreaSumAB0[aidx] - fAreaSumAB1[aidx]) / nevts;
568 //
569 // 4. Scale the mean, variance and AB-noise to the number of slices:
570 //
571 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
572 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
573 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
574 //
575 // 5. Scale the mean, variance and AB-noise to the number of pixels:
576 //
577 ped /= napix;
578 var /= napix;
579 abOffs /= napix;
580 //
581 // 6. Calculate the RMS from the Variance:
582 //
583 const Float_t rms = var<0 ? 0 : TMath::Sqrt(var);
584
585 fPedestalsOut->GetAverageArea(aidx).Set(ped, rms,abOffs,nevts);
586
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
602 const Float_t sum = fSectorSumx.At(sector);
603 const Float_t sum2 = fSectorSumx2.At(sector);
604
605 // 1. Calculate the mean of the sums:
606 Float_t ped = sum/nevts;
607 //
608 // 2. Calculate the Variance of the sums:
609 //
610 Float_t var = (sum2-sum*sum/nevts)/(nevts-1.);
611 //
612 // 3. Calculate the amplitude of the 150MHz "AB" noise
613 //
614 Float_t abOffs = (fSectorSumAB0[sector] - fSectorSumAB1[sector]) / nevts;
615 //
616 // 4. Scale the mean, variance and AB-noise to the number of slices:
617 //
618 ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
619 var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
620 abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize;
621 //
622 // 5. Scale the mean, variance and AB-noise to the number of pixels:
623 //
624 ped /= nspix;
625 var /= nspix;
626 abOffs /= nspix;
627 //
628 // 6. Calculate the RMS from the Variance:
629 //
630 const Float_t rms = var<0 ? 0 : TMath::Sqrt(var);
631
632 fPedestalsOut->GetAverageSector(sector).Set(ped, rms,abOffs,nevts);
633}
634
635
636
637void MExtractPedestal::Print(Option_t *o) const
638{
639
640 *fLog << GetDescriptor() << ":" << endl;
641 *fLog << "Name of incoming MPedestalCam Container: " << fNamePedestalCamIn.Data() << endl;
642 *fLog << "Name of outgoing MPedestalCam Container: " << fNamePedestalCamOut.Data() << endl;
643 *fLog << "Number events for pedestal calculation: " << fNumEventsDump << endl;
644 *fLog << "Number events for av. areas calculation: " << fNumAreasDump << endl;
645 *fLog << "Number events for av. sector calculation: " << fNumSectorsDump << endl;
646 *fLog << "Pedestal Update is " << (fPedestalUpdate?"on":"off") << endl;
647 *fLog << "ExtractWindow from slice " << fExtractWinFirst << " to " << fExtractWinLast << " incl." << endl;
648}
Note: See TracBrowser for help on using the repository browser.