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

Last change on this file since 5559 was 5558, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 15.8 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// MPedCalcLoGain
34//
35// This task derives from MExtractPedestal.
36// It calculates the pedestals using the low gain slices, whenever the difference
37// between the highest and the lowest slice in the high gain
38// slices is below a given threshold (SetMaxHiGainVar). In this case the receiver
39// boards do not switch to lo gain and the so called lo gain slices are actually
40// high gain slices.
41//
42// MPedCalcLoGain also fills the ABoffset in MPedestalPix which allows to correct
43// the 150 MHz clock noise.
44//
45// This task takes a pedestal run file and fills MPedestalCam during
46// the Process() with the pedestal and rms computed in an event basis.
47// In the PostProcess() MPedestalCam is finally filled with the pedestal
48// mean and rms computed in a run basis.
49// More than one run (file) can be merged
50//
51// MPedCalcPedRun applies the following formula (1):
52//
53// Pedestal per slice = sum(x_i) / n / slices
54// PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / 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 MPedCalcFromLoGain)
80// 2) The fitted mean pedestal per slice (from MHPedestalCam)
81// 3) The calculated pedestal RMS per slice (from MPedCalcFromLoGain)
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// The plots have been produced on run 20123. You can reproduce them using
94// the macro pedestalstudies.C
95//
96// Usage of this class:
97// ====================
98//
99//
100// fCheckWinFirst = fgCheckWinFirst = 0
101// fCheckWinLast = fgCheckWinLast = 29
102// fExtractWinFirst = fgExtractWinFirst = 15
103// fExtractWinSize = fgExtractWinSize = 6
104// fMaxSignalVar = fgMaxSignalVar = 40;
105//
106// Call:
107// SetCheckRange(fCheckWinFirst,fCheckWinLast);
108// to set the Window in which a signal is searched
109//
110// SetExtractWindow(fExtractWinFirst,fExtractWinSize);
111// to set the Window from which a signal is extracted
112//
113// SetMaxSignalVar(fMaxSignalVar);
114// set the maximum allowed difference between maximum and minimal signal in CheckWindow
115//
116// Variables:
117// fgCheckWinFirst; First FADC slice to check for signal (currently set to: 0)
118// fgCheckWinLast: Last FADC slice to check for signal (currently set to: 29)
119// fgExtractWinFirst: First FADC slice to be used for pedestal extraction (currently set to: 15)
120// fgExtractWinSize: Window size in slices used for pedestal extraction (currently set to: 6)
121// fgMaxSignalVar: The maximum difference between the highest and lowest slice
122// in the check window allowed in order to use event
123//
124// Input Containers:
125// MRawEvtData
126// MRawRunHeader
127// MGeomCam
128//
129// Output Containers:
130// MPedestalCam
131//
132// See also: MPedestalCam, MPedestalPix, MHPedestalCam, MExtractor
133//
134/////////////////////////////////////////////////////////////////////////////
135#include "MPedCalcFromLoGain.h"
136
137#include "MParList.h"
138
139#include "MLog.h"
140#include "MLogManip.h"
141
142#include "MRawRunHeader.h"
143#include "MRawEvtPixelIter.h"
144#include "MRawEvtData.h"
145
146#include "MPedestalPix.h"
147#include "MPedestalCam.h"
148
149#include "MGeomPix.h"
150#include "MGeomCam.h"
151
152#include "MExtractPedestal.h"
153#include "MExtractTimeAndCharge.h"
154
155ClassImp(MPedCalcFromLoGain);
156
157using namespace std;
158
159const UShort_t MPedCalcFromLoGain::fgCheckWinFirst = 0;
160const UShort_t MPedCalcFromLoGain::fgCheckWinLast = 29;
161const UShort_t MPedCalcFromLoGain::fgExtractWinFirst = 15;
162const UShort_t MPedCalcFromLoGain::fgExtractWinSize = 6;
163const UShort_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//
177MPedCalcFromLoGain::MPedCalcFromLoGain(const char *name, const char *title)
178{
179 fName = name ? name : "MPedCalcFromLoGain";
180 fTitle = title ? title : "Task to calculate pedestals from lo-gains";
181
182 SetCheckRange(fgCheckWinFirst, fgCheckWinLast);
183 SetExtractWindow(fgExtractWinFirst, fgExtractWinSize);
184
185 SetMaxSignalVar(fgMaxSignalVar);
186}
187
188void MPedCalcFromLoGain::ResetArrays()
189{
190 MExtractPedestal::ResetArrays();
191
192 fNumEventsUsed.Reset();
193 fTotalCounter.Reset();
194}
195
196// --------------------------------------------------------------------------
197//
198// SetCheckRange:
199//
200// Exits, if the first argument is smaller than 0
201// Exits, if the the last argument is smaller than the first
202//
203Bool_t MPedCalcFromLoGain::SetCheckRange(UShort_t chfirst, UShort_t chlast)
204{
205
206 Bool_t rc = kTRUE;
207
208 if (chlast<=chfirst)
209 {
210 *fLog << warn << GetDescriptor();
211 *fLog << " - WARNING: Last slice in SetCheckRange smaller than first slice... set to first+2" << endl;
212 chlast = chfirst+1;
213 rc = kFALSE;
214 }
215
216 fCheckWinFirst = chfirst;
217 fCheckWinLast = chlast;
218
219 return rc;
220}
221
222// ---------------------------------------------------------------------------------
223//
224// Checks:
225// - if the number of available slices
226// (fRunHeader->GetNumSamplesHiGain()+(Int_t)fRunHeader->GetNumSamplesLoGain()-1)
227// is smaller than the number of used slices
228// (fExtractWinSize+ fExtractWinFirst-1) or
229// fCheckWinLast
230//
231Bool_t MPedCalcFromLoGain::ReInit(MParList *pList)
232{
233 const UShort_t hisamples = fRunHeader->GetNumSamplesHiGain();
234 const UShort_t losamples = fRunHeader->GetNumSamplesLoGain();
235
236 fSlices.Set(hisamples+losamples);
237
238 UShort_t lastavailable = hisamples+losamples-1;
239
240 if (fExtractor)
241 lastavailable = losamples-1;
242
243 // If the size is not yet set, set the size
244 if (fSumx.GetSize()==0)
245 {
246 const Int_t npixels = fPedestalsOut->GetSize();
247 fNumEventsUsed.Set(npixels);
248 fTotalCounter.Set(npixels);
249 }
250
251 if (fExtractWinLast > lastavailable) //changed to override check
252 {
253 const UShort_t diff = fExtractWinLast - lastavailable;
254 *fLog << warn << GetDescriptor();
255 *fLog << " - WARNING: Selected Extract Window ranges out of range...adjusting to last available slice ";
256 *fLog << lastavailable << endl;
257
258 fExtractWinLast -= diff;
259 fExtractWinSize -= diff;
260 }
261
262 lastavailable = hisamples + losamples -1;
263
264 if (fCheckWinLast > lastavailable) //changed to override check
265 {
266 *fLog << warn << GetDescriptor();
267 *fLog << " - WARNING: Last Check Window slice out of range...adjusting to last available slice ";
268 *fLog << lastavailable << endl;
269
270 fCheckWinLast = lastavailable;
271 }
272
273 return MExtractPedestal::ReInit(pList);
274}
275
276// --------------------------------------------------------------------------
277//
278// Fill the MPedestalCam container with the signal mean and rms for the event.
279// Store the measured signal in arrays fSumx and fSumx2 so that we can
280// calculate the overall mean and rms in the PostProcess()
281//
282Int_t MPedCalcFromLoGain::Process()
283{
284 // This is the workaround to put hi- and lo-gains together
285 const Int_t nhigain = fRunHeader->GetNumSamplesHiGain();
286 const Int_t nlogain = fRunHeader->GetNumSamplesLoGain();
287
288 Byte_t *slices = fSlices.GetArray();
289
290 // Real Process
291 MRawEvtPixelIter pixel(fRawEvt);
292
293 while (pixel.Next())
294 {
295 // This is the fast workaround to put hi- and lo-gains together
296 memcpy(slices, pixel.GetHiGainSamples(), nhigain);
297 memcpy(slices+nhigain, pixel.GetLoGainSamples(), nlogain);
298
299 // Start 'real' work
300 const UInt_t idx = pixel.GetPixelId();
301
302 const UInt_t aidx = (*fGeom)[idx].GetAidx();
303 const UInt_t sector = (*fGeom)[idx].GetSector();
304
305 UShort_t max = 0;
306 UShort_t min = (UShort_t)-1;
307
308 // Find the maximum and minimum signal per slice in the high gain window
309 for (Byte_t *slice=slices+fCheckWinFirst; slice<=slices+fCheckWinLast; slice++)
310 {
311 if (*slice > max)
312 max = *slice;
313 if (*slice < min)
314 min = *slice;
315 }
316
317 // If the maximum in the high gain window is smaller than
318 if (max-min>=fMaxSignalVar || max>=250)
319 continue;
320
321 Float_t sum = 0.;
322 UInt_t sumi = 0;
323
324 //extract pedestal
325 if (fExtractor)
326 CalcExtractor(pixel, sum, (*fPedestalsIn)[idx]);
327 else
328 {
329 for(Byte_t *slice=slices+fExtractWinFirst; slice<=slices+fExtractWinLast; slice++)
330 sumi += *slice;
331 sum = (Float_t)sumi;
332 }
333
334 const Float_t sqrsum = sum*sum;
335
336 fSumx[idx] += sum;
337 fSumx2[idx] += sqrsum;
338 fAreaSumx[aidx] += sum;
339 fAreaSumx2[aidx] += sqrsum;
340 fSectorSumx[sector] += sum;
341 fSectorSumx2[sector] += sqrsum;
342
343 fNumEventsUsed[idx] ++;
344 fAreaFilled [aidx] ++;
345 fSectorFilled [sector]++;
346
347 if (!fExtractor)
348 {
349 //
350 // Calculate the amplitude of the 150MHz "AB" noise
351 //
352 const UShort_t abFlag = (fExtractWinFirst + pixel.HasABFlag()) & 0x1;
353
354 for (Byte_t *slice=slices+fExtractWinFirst; slice<=slices+fExtractWinLast; slice+=2)
355 {
356 const UShort_t ab0 = *(slice + abFlag);
357 const UShort_t ab1 = *(slice - abFlag + 1);
358
359 fSumAB0[idx] += ab0;
360 fSumAB1[idx] += ab1;
361 fAreaSumAB0[aidx] += ab0;
362 fAreaSumAB1[aidx] += ab1;
363 fSectorSumAB0[aidx] += ab0;
364 fSectorSumAB1[aidx] += ab1;
365 }
366 }
367
368 if (!fPedestalUpdate || (UInt_t)fNumEventsUsed[idx]<fNumEventsDump)
369 continue;
370
371 CalcPixResults(fNumEventsDump, idx);
372 fTotalCounter[idx]++;
373
374 fNumEventsUsed[idx]=0;
375 fSumx[idx]=0;
376 fSumx2[idx]=0;
377 fSumAB0[idx]=0;
378 fSumAB1[idx]=0;
379 }
380
381 if (!(GetNumExecutions() % fNumAreasDump))
382 CalcAreaResult();
383
384 if (!(GetNumExecutions() % fNumSectorsDump))
385 CalcSectorResult();
386
387 if (fPedestalUpdate)
388 fPedestalsOut->SetReadyToSave();
389
390 return kTRUE;
391}
392
393// --------------------------------------------------------------------------
394//
395// Loop over the sector indices to get the averaged pedestal per sector
396//
397void MPedCalcFromLoGain::CalcSectorResult()
398{
399 for (UInt_t sector=0; sector<fSectorFilled.GetSize(); sector++)
400 if (fSectorValid[sector]>0)
401 CalcSectorResults(fSectorFilled[sector], fSectorValid[sector], sector);
402}
403
404// --------------------------------------------------------------------------
405//
406// Loop over the (two) area indices to get the averaged pedestal per aidx
407//
408void MPedCalcFromLoGain::CalcAreaResult()
409{
410 for (UInt_t aidx=0; aidx<fAreaFilled.GetSize(); aidx++)
411 if (fAreaValid[aidx]>0)
412 CalcAreaResults(fAreaFilled[aidx], fAreaValid[aidx], aidx);
413
414}
415
416void MPedCalcFromLoGain::CalcExtractor(const MRawEvtPixelIter &pixel, Float_t &sum, MPedestalPix &ped)
417{
418 Byte_t sat = 0;
419 Byte_t *logain = pixel.GetLoGainSamples() + fExtractWinFirst;
420
421 const Bool_t logainabflag = (pixel.HasABFlag() + pixel.GetNumHiGainSamples()) & 0x1;
422
423 Float_t dummy;
424 fExtractor->FindTimeAndChargeHiGain(logain,logain,sum,dummy,dummy,dummy,sat,ped,logainabflag);
425}
426
427
428// --------------------------------------------------------------------------
429//
430// Compute signal mean and rms in the whole run and store it in MPedestalCam
431//
432Int_t MPedCalcFromLoGain::PostProcess()
433{
434 // Compute pedestals and rms from the whole run
435 if (fPedestalUpdate)
436 return kTRUE;
437
438 *fLog << flush << inf << "Calculating Pedestals..." << flush;
439
440 const Int_t npix = fGeom->GetNumPixels();
441 for (Int_t idx=0; idx<npix; idx++)
442 {
443 const ULong_t n = fNumEventsUsed[idx];
444 if (n>1)
445 {
446 CalcPixResults(n, idx);
447 fTotalCounter[idx]++;
448 }
449 }
450
451 CalcAreaResult();
452 CalcSectorResult();
453
454 fPedestalsOut->SetReadyToSave();
455
456 return MExtractPedestal::PostProcess();
457}
458
459
460// --------------------------------------------------------------------------
461//
462// The following resources are available:
463// FirstCheckWindowSlice: 0
464// LastCheckWindowSlice: 29
465// MaxSignalVar: 40
466//
467Int_t MPedCalcFromLoGain::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
468{
469 Bool_t rc=kFALSE;
470
471 // Find resources for CheckWindow
472 Int_t fs = fCheckWinFirst;
473 Int_t ls = fCheckWinLast;
474 if (IsEnvDefined(env, prefix, "CheckWinFirst", print))
475 {
476 fs = GetEnvValue(env, prefix, "CheckWinFirst", fs);
477 rc = kTRUE;
478 }
479 if (IsEnvDefined(env, prefix, "CheckWinLast", print))
480 {
481 ls = GetEnvValue(env, prefix, "CheckWinLast", ls);
482 rc = kTRUE;
483 }
484
485 SetCheckRange(fs,ls);
486
487 // find resource for maximum signal variation
488 if (IsEnvDefined(env, prefix, "MaxSignalVar", print))
489 {
490 SetMaxSignalVar(GetEnvValue(env, prefix, "MaxSignalVar", fMaxSignalVar));
491 rc = kTRUE;
492 }
493
494 return MExtractPedestal::ReadEnv(env,prefix,print) ? kTRUE : rc;
495}
496
497void MPedCalcFromLoGain::Print(Option_t *o) const
498{
499 MExtractPedestal::Print(o);
500
501 *fLog << "CheckWindow from slice " << fCheckWinFirst << " to " << fCheckWinLast << " incl." << endl;
502 *fLog << "Max. allowed signal variation: " << fMaxSignalVar << endl;
503 *fLog << endl;
504}
Note: See TracBrowser for help on using the repository browser.