source: trunk/MagicSoft/Mars/mpedestal/MPedCalcFromLoGain.cc@ 5357

Last change on this file since 5357 was 5356, checked in by gaug, 20 years ago
*** empty log message ***
File size: 18.7 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): Josep Flix 04/2001 <mailto:jflix@ifae.es>
19! Author(s): Thomas Bretz 05/2001 <mailto:tbretz@astro.uni-wuerzburg.de>
20! Author(s): Sebastian Commichau 12/2003
21! Author(s): Javier Rico 01/2004 <mailto:jrico@ifae.es>
22! Author(s): Markus Gaug 01/2004 <mailto:markus@ifae.es>
23! Author(s): Florian Goebel 06/2004 <mailto:fgoebel@mppmu.mpg.de>
24! Author(s): Nepomuk Otte 10/2004 <mailto:otte@mppmu.mpg.de>
25!
26! Copyright: MAGIC Software Development, 2000-2004
27!
28!
29\* ======================================================================== */
30
31/////////////////////////////////////////////////////////////////////////////
32//
33//
34//
35// MPedCalcLoGain
36//
37//
38// This task is devide form MPedCalcPedRun, described below. However, It
39// calculates the pedstals using the low gain slices, whenever the difference
40// between the highest and the lowest slice in the high gain
41// slices is below a given threshold (SetMaxHiGainVar). In this case the receiver
42// boards do not switch to lo gain and the so called lo gain slices are actually
43// high gain slices.
44//
45// MPedCalcLoGain also fills the ABoffset in MPedestalPix which allows to correct
46// the 150 MHz clock noise.
47//
48// This task takes a pedestal run file and fills MPedestalCam during
49// the Process() with the pedestal and rms computed in an event basis.
50// In the PostProcess() MPedestalCam is finally filled with the pedestal
51// mean and rms computed in a run basis.
52// More than one run (file) can be merged
53//
54// MPedCalcPedRun applies the following formula (1):
55//
56// Pedestal per slice = sum(x_i) / n / slices
57// PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / 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//
79// The plots show the inner and outer pixels, respectivly and have the following meaning:
80//
81// 1) The calculated mean pedestal per slice (from MPedCalcFromLoGain)
82// 2) The fitted mean pedestal per slice (from MHPedestalCam)
83// 3) The calculated pedestal RMS per slice (from MPedCalcFromLoGain)
84// 4) The fitted sigma of the pedestal distribution per slice
85// (from MHPedestalCam)
86// 5) The relative difference between calculation and histogram fit
87// for the mean
88// 6) The relative difference between calculation and histogram fit
89// for the sigma or RMS, respectively.
90//
91// The calculated means do not change significantly except for the case of 2 slices,
92// however the RMS changes from 5.7 per slice in the case of 2 extracted slices
93// to 8.3 per slice in the case of 26 extracted slices. This change is very significant.
94//
95// The plots have been produced on run 20123. You can reproduce them using
96// the macro pedestalstudies.C
97//
98// Usage of this class:
99// ====================
100//
101//
102// fCheckWinFirst = fgCheckWinFirst = 0
103// fHiGainLast = fgCheckWinLast = 29
104// fExtractWinFirst = fgExtractWinFirst = 0
105// fExtractWinSize = fgExtractWinSize = 6
106// fMaxSignalVar = fgMaxSignalVar = 40;
107//
108// Call:
109// SetCheckRange(fCheckWinFirst,fCheckWinLast);
110// to set the Window in which a signal is searched
111//
112// SetExtractWindow(fExtractWindFirst,fExtractWinSize);
113// to set the Window from which a signal is extracted
114//
115// SetMaxSignalVar(fMaxSignalVar);
116// set the maximum allowed difference between maximum and minimal signal in CheckWindow
117//
118// Variables:
119// fgCheckWinFirst; First FADC slice to check for signal (currently set to: 0)
120// fgCheckWinLast: Last FADC slice to check for signal (currently set to: 29)
121// fgExtractWinFirst: First FADC slice to be used for pedestal extraction (currently set to: 15)
122// fgExtractWinSize: Window size in slices used for pedestal extraction (currently set to: 6)
123// fgMaxSignalVar: The maximum difference between the highest and lowest slice
124// in the check window allowed in order to use event
125//
126// Input Containers:
127// MRawEvtData
128// MRawRunHeader
129// MGeomCam
130//
131// Output Containers:
132// MPedestalCam
133//
134// See also: MPedestalCam, MPedestalPix, MHPedestalCam, MExtractor
135//
136/////////////////////////////////////////////////////////////////////////////
137#include "MPedCalcFromLoGain.h"
138#include "MExtractor.h"
139
140#include "MParList.h"
141
142#include "MLog.h"
143#include "MLogManip.h"
144
145#include "MRawRunHeader.h"
146#include "MRawEvtPixelIter.h"
147#include "MRawEvtData.h"
148
149#include "MPedestalPix.h"
150#include "MPedestalCam.h"
151
152#include "MGeomPix.h"
153#include "MGeomCam.h"
154
155ClassImp(MPedCalcFromLoGain);
156
157using namespace std;
158
159const Int_t MPedCalcFromLoGain::fgCheckWinFirst = 0;
160const Int_t MPedCalcFromLoGain::fgCheckWinLast = 29;
161const Int_t MPedCalcFromLoGain::fgExtractWinFirst = 15;
162const Int_t MPedCalcFromLoGain::fgExtractWinSize = 6;
163const Int_t MPedCalcFromLoGain::fgMaxSignalVar = 40;
164
165// --------------------------------------------------------------------------
166//
167// Default constructor:
168//
169// Sets:
170// - all pointers to NULL
171//
172// Calls:
173// - AddToBranchList("fHiGainPixId");
174// - AddToBranchList("fHiGainFadcSamples");
175// - SetCheckRange(fgCheckWinFirst, fgCheckWinLast, fgExtractWinFirst, fgExtractWinSize)
176// - Clear()
177//
178MPedCalcFromLoGain::MPedCalcFromLoGain(const char *name, const char *title)
179 : fGeom(NULL), fPedContainerName("MPedestalCam")
180{
181
182 fName = name ? name : "MPedCalcFromLoGain";
183 fTitle = title ? title : "Task to calculate pedestals from pedestal runs raw data";
184
185 AddToBranchList("fHiGainPixId");
186 AddToBranchList("fHiGainFadcSamples");
187
188 SetCheckRange(fgCheckWinFirst, fgCheckWinLast);
189 SetExtractWindow(fgExtractWinFirst, fgExtractWinSize);
190
191 SetMaxSignalVar(fgMaxSignalVar);
192 SetPedestalUpdate(kTRUE);
193 Clear();
194
195}
196
197// --------------------------------------------------------------------------
198//
199// Sets:
200// - fRawEvt to NULL
201// - fRunHeader to NULL
202// - fPedestals to NULL
203//
204// Resets:
205// - fSumx
206// - fSumx2
207// - fSumAB0
208// - fSumAB1
209// - fNumEventsUsed
210// - fTotalCounter
211//
212void MPedCalcFromLoGain::Clear(const Option_t *o)
213{
214
215 fRawEvt = NULL;
216 fRunHeader = NULL;
217 fPedestals = NULL;
218
219 // If the size is yet set, set the size
220 if (fSumx.GetSize()>0)
221 {
222 // Reset contents of arrays.
223 fSumx.Reset();
224 fSumx2.Reset();
225 fSumAB0.Reset();
226 fSumAB1.Reset();
227 fNumEventsUsed.Reset();
228 fTotalCounter.Reset();
229 }
230}
231
232// --------------------------------------------------------------------------
233//
234// SetCheckRange:
235//
236// Exits, if the first argument is smaller than 0
237// Exits, if the the last argument is smaller than the first
238//
239void MPedCalcFromLoGain::SetCheckRange(Int_t chfirst, Int_t chlast)
240{
241
242 if(chfirst<0)
243 {
244 *fLog << warn << GetDescriptor()
245 << ": First slice in window to check for Signal <0, adjust:" << endl;
246 exit(-1);
247 }
248
249 if(chlast<=chfirst)
250 {
251 *fLog << warn << GetDescriptor()
252 << ": Last slice in Check window smaller than first slice in window, adjust:" << endl;
253 exit(-1);
254 }
255
256 fCheckWinFirst = chfirst;
257 fCheckWinLast = chlast;
258
259}
260
261// --------------------------------------------------------------------------
262//
263// Exits:
264// - if a window is odd
265//
266void MPedCalcFromLoGain::SetExtractWindow(Int_t windowf, Int_t windows)
267{
268
269 if(windowf<0)
270 {
271 *fLog << warn << GetDescriptor()
272 << Form(": First slice in Extract window has to be >0, adjust:")<< endl;
273 exit(-1);
274 }
275
276 Int_t odd = windows & 0x1;
277
278 if (odd||(windows==0))
279 {
280 *fLog << warn << GetDescriptor() << ": Extract window size has to be even and larger 0, adjust!"<< endl;
281 exit(-1);
282 }
283
284 fExtractWinSize = windows;
285 fExtractWinFirst = windowf;
286 fExtractWinLast = fExtractWinFirst+fExtractWinSize-1;
287
288/*
289 const Byte_t availhirange = (fHiGainLast-fHiGainFirst+1) & ~1;
290 const Byte_t availlorange = (fLoGainLast-fLoGainFirst+1) & ~1;
291
292 if (fWindowSizeHiGain > availhirange)
293 {
294 *fLog << warn;
295 *fLog << GetDescriptor() << ": HiGain window " << (int)fWindowSizeHiGain;
296 *fLog << " out of range [" << (int)fHiGainFirst;
297 *fLog << "," << (int)fHiGainLast << "]" << endl;
298 *fLog << "Will set window size to " << (int)availhirange << endl;
299 fWindowSizeHiGain = availhirange;
300 }
301
302 if (fWindowSizeLoGain > availlorange)
303 {
304 *fLog << warn;
305 *fLog << GetDescriptor() << ": LoGain window " << (int)fWindowSizeLoGain;
306 *fLog << " out of range [" << (int)fLoGainFirst;
307 *fLog << "," << (int)fLoGainLast << "]" << endl;
308 *fLog << "Will set window size to " << (int)availlorange << endl;
309 fWindowSizeLoGain = availlorange;
310 }
311*/
312}
313
314// --------------------------------------------------------------------------
315//
316// Look for the following input containers:
317//
318// - MRawEvtData
319// - MRawRunHeader
320// - MGeomCam
321//
322// The following output containers are also searched and created if
323// they were not found:
324//
325// - MPedestalCam with the name fPedContainerName
326//
327Int_t MPedCalcFromLoGain::PreProcess(MParList *pList)
328{
329
330 Clear();
331
332 fRawEvt = (MRawEvtData*)pList->FindObject("MRawEvtData");
333 if (!fRawEvt)
334 {
335 *fLog << err << "MRawEvtData not found... aborting." << endl;
336 return kFALSE;
337 }
338
339 fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
340 if (!fRunHeader)
341 {
342 *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl;
343 return kFALSE;
344 }
345
346 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
347 if (!fGeom)
348 {
349 *fLog << err << "MGeomCam not found... aborting." << endl;
350 return kFALSE;
351 }
352
353
354 fPedestals = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fPedContainerName));
355 if (!fPedestals)
356 return kFALSE;
357
358
359 *fLog << inf << "Parameters used for pedestal calculation:"<<endl;
360 *fLog << inf <<"CheckWindow: First slice: "<<fCheckWinFirst<<"; Last slice: "<<fCheckWinLast<<endl;
361 *fLog << inf <<"ExtractWindow: First slice: "<<fExtractWinFirst<<"; Last slice: "<<fExtractWinLast<<endl;
362 *fLog << inf <<"Max allowed signal variation: "<<fMaxSignalVar<<endl;
363 return kTRUE;
364}
365
366// ---------------------------------------------------------------------------------
367//
368// Checks:
369// - if the number of available slices
370// (fRunHeader->GetNumSamplesHiGain()+(Int_t)fRunHeader->GetNumSamplesLoGain()-1)
371// is smaller than the number of used slices
372// (fExtractWinSize+ fExtractWinFirst-1) or
373// fCheckWinLast
374//
375// Sets the size (from MPedestalCam::GetSize() ) and resets the following arrays:
376// - fSumx
377// - fSumx2
378// - fSumAB0
379// - fSumAB1
380// - fNumEventsUsed
381// - fTotalCounter
382//
383Bool_t MPedCalcFromLoGain::ReInit(MParList *pList)
384{
385
386 Int_t lastavailableslice = (Int_t)fRunHeader->GetNumSamplesHiGain()
387 +(Int_t)fRunHeader->GetNumSamplesLoGain()-1;
388 Int_t lastextractslice = fExtractWinSize+ fExtractWinFirst - 1;
389
390 if ( lastextractslice > lastavailableslice ) //changed to override check
391 {
392 *fLog << endl;
393 *fLog << warn << GetDescriptor()
394 << Form(": Selected Extract Window ranges out of the available limits adjust. Last available slice is %2i",
395 lastavailableslice) << endl;
396 return kFALSE;
397 }
398
399 if ( fCheckWinLast > lastavailableslice ) //changed to override check
400 {
401 *fLog << endl;
402 *fLog << warn << GetDescriptor()
403 << Form(": Last Check Window slice is out of the available limits adjust. Last available slice is %2i",
404 lastavailableslice) << endl;
405 return kFALSE;
406 }
407
408
409
410 // If the size is not yet set, set the size
411 if (fSumx.GetSize()==0)
412 {
413 const Int_t npixels = fPedestals->GetSize();
414
415 fSumx. Set(npixels);
416 fSumx2.Set(npixels);
417 fSumAB0.Set(npixels);
418 fSumAB1.Set(npixels);
419 fNumEventsUsed.Set(npixels);
420 fTotalCounter.Set(npixels);
421
422 // Reset contents of arrays.
423 fSumx.Reset();
424 fSumx2.Reset();
425 fSumAB0.Reset();
426 fSumAB1.Reset();
427 fNumEventsUsed.Reset();
428 fTotalCounter.Reset();
429 }
430
431 return kTRUE;
432}
433
434// ---------------------------------------------------------------------------------
435//
436// Calculates for pixel "idx":
437//
438// Ped per slice = sum / n / fExtractWinSize;
439// RMS per slice = sqrt { (sum2 - sum*sum/n) / (n-1) / fExtractWinSize }
440// ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / n / fExtractWinSize;
441//
442// Sets fTotalCounter up by 1.
443//
444void MPedCalcFromLoGain::Calc(ULong_t n, UInt_t idx)
445{
446
447 const ULong_t nsamplestot = n*fExtractWinSize;
448
449 const Float_t sum = fSumx.At(idx);
450 const Float_t sum2 = fSumx2.At(idx);
451 const Float_t ped = sum/nsamplestot;
452
453 // 1. Calculate the Variance of the sums:
454 Float_t var = (sum2-sum*sum/n)/(n-1.);
455
456 // 2. Scale the variance to the number of slices:
457 var /= (Float_t)(fExtractWinSize);
458
459 // 3. Calculate the RMS from the Variance:
460 const Float_t rms = var<0 ? 0 : TMath::Sqrt(var);
461
462 // 4. Calculate the amplitude of the 150MHz "AB" noise
463 const Float_t abOffs = (fSumAB0[idx] - fSumAB1[idx]) / nsamplestot;
464
465 (*fPedestals)[idx].Set(ped, rms, abOffs, n);
466
467 fTotalCounter[idx]++;
468}
469
470// ---------------------------------------------------------------------------------
471//
472// Returns the pointer to slice "slice".
473//
474UInt_t MPedCalcFromLoGain::GetSlice(MRawEvtPixelIter *pixel, UInt_t slice)
475{
476
477 const UInt_t nh = (Int_t)fRunHeader->GetNumSamplesHiGain();
478
479 Byte_t *ptr;
480
481 if(slice>=nh)
482 {
483 ptr = pixel->GetLoGainSamples();
484 ptr += slice - nh;
485 }
486 else
487 {
488 ptr = pixel->GetHiGainSamples();
489 ptr += slice;
490 }
491
492 return *ptr;
493}
494
495// --------------------------------------------------------------------------
496//
497// Fill the MPedestalCam container with the signal mean and rms for the event.
498// Store the measured signal in arrays fSumx and fSumx2 so that we can
499// calculate the overall mean and rms in the PostProcess()
500//
501Int_t MPedCalcFromLoGain::Process()
502{
503 MRawEvtPixelIter pixel(fRawEvt);
504
505 while (pixel.Next())
506 {
507
508 const UInt_t idx = pixel.GetPixelId();
509
510 Int_t max = 0;
511 Int_t min = 1025;
512
513 // Find the maximum and minimum signal per slice in the high gain window
514
515 for(Int_t slice=fCheckWinFirst; slice<=fCheckWinLast; slice++)
516 {
517
518 Int_t svalue = GetSlice(&pixel,slice);
519 if (svalue > max) {
520 max = svalue;
521 }
522 if (svalue < min) {
523 min = svalue;
524 }
525 }
526
527 // If the maximum in the high gain window is smaller than
528 if (max-min>=fMaxSignalVar || max>=250)
529 continue;
530
531 UInt_t sum = 0;
532 UInt_t sqr = 0;
533
534 //extract pedestal
535 for(Int_t slice=fExtractWinFirst; slice<=fExtractWinLast; slice++)
536 {
537 UInt_t svalue = GetSlice(&pixel,slice);
538 sum += svalue;
539 sqr += svalue*svalue;
540 }
541
542 const Float_t msum = (Float_t)sum;
543 const Float_t sqrsum = msum*msum;
544
545 fSumx[idx] += msum;
546 fSumx2[idx] += sqrsum;
547 fNumEventsUsed[idx]++;
548
549 // Calculate the amplitude of the 150MHz "AB" noise
550
551 Int_t abFlag = (fExtractWinFirst + pixel.HasABFlag()) & 0x1;
552
553 //cout << " MPedCalcFromLoGain: idx: " << idx << " abFlag: " << abFlag << endl;
554
555 for (Int_t islice=fExtractWinFirst; islice<=fExtractWinLast; islice+=2)
556 {
557 Int_t sliceAB0 = islice + abFlag;
558 Int_t sliceAB1 = islice - abFlag + 1;
559 fSumAB0[idx] += GetSlice(&pixel, sliceAB0);
560 fSumAB1[idx] += GetSlice(&pixel, sliceAB1);
561 }
562
563 if (!fPedestalUpdate || fNumEventsUsed[idx]<fNumEventsDump)
564 continue;
565
566 Calc(fNumEventsDump, idx);
567
568 fNumEventsUsed[idx]=0;
569 fSumx[idx]=0;
570 fSumx2[idx]=0;
571 fSumAB0[idx]=0;
572 fSumAB1[idx]=0;
573 }
574
575 if (fPedestalUpdate)
576 fPedestals->SetReadyToSave();
577
578 return kTRUE;
579}
580
581// --------------------------------------------------------------------------
582//
583// Compute signal mean and rms in the whole run and store it in MPedestalCam
584//
585Int_t MPedCalcFromLoGain::PostProcess()
586{
587 // Compute pedestals and rms from the whole run
588 if (fPedestalUpdate)
589 return kTRUE;
590
591 *fLog << flush << inf << "Calculating Pedestals..." << flush;
592
593 const Int_t npix = fGeom->GetNumPixels();
594 for (Int_t idx=0; idx<npix; idx++)
595 {
596 const ULong_t n = fNumEventsUsed[idx];
597 if (n>1)
598 Calc(n, idx);
599 }
600
601 fPedestals->SetReadyToSave();
602 return kTRUE;
603}
604
605
606Int_t MPedCalcFromLoGain::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
607{
608 if (MExtractor::ReadEnv(env, prefix, print)==kERROR)
609 return kERROR;
610
611 Bool_t rc=kFALSE;
612
613 Int_t lw = fExtractWinSize;
614 Int_t wf = fExtractWinFirst;
615
616 if (IsEnvDefined(env, prefix, "ExtractWindowSize", print))
617 {
618 lw = GetEnvValue(env, prefix, "ExtractWindowSize", lw);
619 wf = GetEnvValue(env, prefix, "ExtractWindowFirst", wf);
620 rc = kTRUE;
621
622 }
623 SetExtractWindow(wf,lw);
624
625 Int_t num = fNumEventsDump;
626 if (IsEnvDefined(env, prefix, "NumEventsDump", print))
627 {
628 num = GetEnvValue(env, prefix, "NumEventsDump", num);
629 rc = kTRUE;
630 }
631 SetNumEventsDump(num);
632
633 Byte_t max = fMaxSignalVar;
634 if (IsEnvDefined(env, prefix, "MaxSignalVar", print))
635 {
636 max = GetEnvValue(env, prefix, "MaxSignalVar", max);
637 rc = kTRUE;
638 }
639 SetMaxSignalVar(max);
640
641 Bool_t upd = fPedestalUpdate;
642 if (IsEnvDefined(env, prefix, "PedestalUpdate", print))
643 {
644 upd = GetEnvValue(env, prefix, "PedestalUpdate", upd);
645 rc = kTRUE;
646 }
647 SetPedestalUpdate(upd);
648
649 return rc;
650}
Note: See TracBrowser for help on using the repository browser.