source: trunk/MagicSoft/Mars/mpedestal/MPedCalcPedRun.cc@ 5502

Last change on this file since 5502 was 5487, checked in by gaug, 21 years ago
*** empty log message ***
File size: 13.2 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!
24! Copyright: MAGIC Software Development, 2000-2004
25!
26!
27\* ======================================================================== */
28/////////////////////////////////////////////////////////////////////////////
29//
30// MPedCalcPedRun
31//
32// This task takes a pedestal run file and fills MPedestalCam during
33// the Process() with the pedestal and rms computed in an event basis.
34// In the PostProcess() MPedestalCam is finally filled with the pedestal
35// mean and rms computed in a run basis.
36// More than one run (file) can be merged
37//
38// MPedCalcPedRun applies the following formula (1):
39//
40// Pedestal per slice = sum(x_i) / n / slices
41// PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / slices )
42//
43// where x_i is the sum of "slices" FADC slices and sum means the sum over all
44// events. "n" is the number of events, "slices" is the number of summed FADC samples.
45//
46// Note that the slice-to-slice fluctuations are not Gaussian, but Poissonian, thus
47// asymmetric and they are correlated.
48//
49// It is important to know that the Pedestal per slice and PedRMS per slice depend
50// on the number of used FADC slices, as seen in the following plots:
51//
52//Begin_Html
53/*
54<img src="images/PedestalStudyInner.gif">
55*/
56//End_Html
57//
58//Begin_Html
59/*
60<img src="images/PedestalStudyOuter.gif">
61*/
62//
63// The plots show the inner and outer pixels, respectivly and have the following meaning:
64//
65// 1) The calculated mean pedestal per slice (from MPedCalcPedRun)
66// 2) The fitted mean pedestal per slice (from MHPedestalCam)
67// 3) The calculated pedestal RMS per slice (from MPedCalcPedRun)
68// 4) The fitted sigma of the pedestal distribution per slice
69// (from MHPedestalCam)
70// 5) The relative difference between calculation and histogram fit
71// for the mean
72// 6) The relative difference between calculation and histogram fit
73// for the sigma or RMS, respectively.
74//
75// The calculated means do not change significantly except for the case of 2 slices,
76// however the RMS changes from 5.7 per slice in the case of 2 extracted slices
77// to 8.3 per slice in the case of 26 extracted slices. This change is very significant.
78//
79// The plots have been produced on run 20123. You can reproduce them using
80// the macro pedestalstudies.C
81//
82// Usage of this class:
83// ====================
84//
85// Call: SetRange(higainfirst, higainlast, logainfirst, logainlast)
86// to modify the ranges in which the window is allowed to move.
87// Defaults are:
88//
89// fHiGainFirst = fgHiGainFirst = 0
90// fHiGainLast = fgHiGainLast = 29
91// fLoGainFirst = fgLoGainFirst = 0
92// fLoGainLast = fgLoGainLast = 14
93//
94// Call: SetWindowSize(windowhigain, windowlogain)
95// to modify the sliding window widths. Windows have to be an even number.
96// In case of odd numbers, the window will be modified.
97//
98// Defaults are:
99//
100// fHiGainWindowSize = fgHiGainWindowSize = 14
101// fLoGainWindowSize = fgLoGainWindowSize = 0
102//
103//
104// ToDo:
105// - Take a setup file (ReadEnv-implementation) as input
106//
107//
108// Input Containers:
109// MRawEvtData
110// MRawRunHeader
111// MRawEvtHeader
112// MGeomCam
113//
114// Output Containers:
115// MPedestalCam
116//
117// See also: MPedestalCam, MPedestalPix, MHPedestalCam, MExtractor
118//
119/////////////////////////////////////////////////////////////////////////////
120#include "MPedCalcPedRun.h"
121#include "MExtractPedestal.h"
122
123#include "MExtractTimeAndCharge.h"
124
125#include "MParList.h"
126
127#include "MLog.h"
128#include "MLogManip.h"
129
130#include "MRawRunHeader.h"
131#include "MRawEvtHeader.h"
132#include "MRawEvtPixelIter.h"
133#include "MRawEvtData.h"
134
135#include "MPedestalPix.h"
136#include "MPedestalCam.h"
137
138#include "MGeomPix.h"
139#include "MGeomCam.h"
140
141#include "MStatusDisplay.h"
142
143ClassImp(MPedCalcPedRun);
144
145using namespace std;
146
147const UShort_t MPedCalcPedRun::fgExtractWinFirst = 0;
148const UShort_t MPedCalcPedRun::fgExtractWinSize = 6;
149const UInt_t MPedCalcPedRun::gkFirstRunWithFinalBits = 45589;
150// --------------------------------------------------------------------------
151//
152// Default constructor:
153//
154// Sets:
155// - all pointers to NULL
156// - fWindowSizeHiGain to fgHiGainWindowSize
157// - fWindowSizeLoGain to fgLoGainWindowSize
158//
159// Calls:
160// - AddToBranchList("fHiGainPixId");
161// - AddToBranchList("fHiGainFadcSamples");
162// - SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast)
163// - Clear()
164//
165MPedCalcPedRun::MPedCalcPedRun(const char *name, const char *title)
166{
167 fName = name ? name : "MPedCalcPedRun";
168 fTitle = title ? title : "Task to calculate pedestals from pedestal runs raw data";
169
170 AddToBranchList("fHiGainPixId");
171 AddToBranchList("fHiGainFadcSamples");
172
173 SetExtractWindow(fgExtractWinFirst, fgExtractWinSize);
174
175 Clear();
176
177 fFirstRun = kTRUE;
178 fSkip = kFALSE;
179 fOverlap = 0;
180 fUsedEvents = 0;
181}
182
183
184
185void MPedCalcPedRun::ResetArrays()
186{
187
188 MExtractPedestal::ResetArrays();
189 fUsedEvents = 0;
190}
191
192// --------------------------------------------------------------------------
193//
194// In case that the variables fExtractLast is greater than the number of
195// High-Gain FADC samples obtained from the run header, the flag
196// fOverlap is set to the difference and fExtractLast is set back by the
197// same number of slices.
198//
199// The run type is checked for "Pedestal" (run type: 1)
200// and the variable fSkip is set in that case
201//
202Bool_t MPedCalcPedRun::ReInit(MParList *pList)
203{
204
205 MExtractPedestal::ReInit(pList);
206
207 const UShort_t lastavailable = fRunHeader->GetNumSamplesHiGain()-1;
208
209 if (fExtractWinLast > lastavailable)
210 {
211 const UShort_t diff = fExtractWinLast - lastavailable;
212 *fLog << endl;
213 *fLog << warn << GetDescriptor()
214 << Form("%s%2i%s%2i%s%2i%s",": Selected ExtractWindow [",
215 fExtractWinFirst,",",fExtractWinLast,
216 "] ranges out of available limits: [0,",lastavailable,"].") << endl;
217 *fLog << warn << GetDescriptor()
218 << Form("%s%2i%s",": Will use ",diff," samples from the 'Low-Gain' slices for the pedestal extraction")
219 << endl;
220 fExtractWinLast -= diff;
221 fOverlap = diff;
222 }
223
224 const UShort_t runtype = fRunHeader->GetRunType();
225
226 switch (runtype)
227 {
228 case 1:
229 fFirstRun = kFALSE;
230 fSkip = kFALSE;
231 return kTRUE;
232 break;
233 default:
234 fSkip = kTRUE;
235 if (!fFirstRun)
236 {
237 *fLog << endl;
238 *fLog << inf << GetDescriptor() << " : Finalize pedestal calculations..." << flush;
239 CallPostProcess();
240 Reset();
241 }
242 return kTRUE;
243 break;
244 }
245
246 Print();
247
248 return kTRUE;
249}
250
251// --------------------------------------------------------------------------
252//
253// Return kTRUE (without doing anything) in case that the run type is not
254// equal to 1 (pedestal run)
255//
256// Fill the MPedestalCam container with the signal mean and rms for the event.
257// Store the measured signal in arrays fSumx and fSumx2 so that we can
258// calculate the overall mean and rms in the PostProcess()
259//
260Int_t MPedCalcPedRun::Process()
261{
262
263 if (fSkip && !IsPedBitSet())
264 return kTRUE;
265
266 /*
267 *fLog << err << dec << fEvtHeader->GetTriggerID() << endl;
268 for (Int_t i=16; i>= 0; i--)
269 *fLog << inf << (fEvtHeader->GetTriggerID() >> i & 1);
270 *fLog << endl;
271 *fLog << warn << hex << fEvtHeader->GetTriggerID() << endl;
272 */
273
274 fUsedEvents++;
275
276 MRawEvtPixelIter pixel(fRawEvt);
277
278 while (pixel.Next())
279 {
280 const UInt_t idx = pixel.GetPixelId();
281 const UInt_t aidx = (*fGeom)[idx].GetAidx();
282 const UInt_t sector = (*fGeom)[idx].GetSector();
283
284 Float_t sum = 0.;
285 UInt_t ab0 = 0;
286 UInt_t ab1 = 0;
287
288 if (fExtractor)
289 CalcExtractor( &pixel, sum, (*fPedestalsIn)[idx]);
290 else
291 CalcSums( &pixel, sum, ab0, ab1);
292
293 const Float_t msum = (Float_t)sum;
294
295 fSumx[idx] += msum;
296 fAreaSumx[aidx] += msum;
297 fSectorSumx[sector] += msum;
298
299 const Float_t sqrsum = msum*msum;
300 fSumx2[idx] += sqrsum;
301 fAreaSumx2[aidx] += sqrsum;
302 fSectorSumx2[sector] += sqrsum;
303
304 fSumAB0[idx] += ab0;
305 fSumAB1[idx] += ab1;
306
307 fAreaSumAB0[aidx] += ab0;
308 fAreaSumAB1[aidx] += ab1;
309
310 fSectorSumAB0[aidx] += ab0;
311 fSectorSumAB1[aidx] += ab1;
312 }
313
314 fPedestalsOut->SetReadyToSave();
315
316 return kTRUE;
317}
318
319
320
321void MPedCalcPedRun::CalcExtractor( MRawEvtPixelIter *pixel, Float_t &sum, MPedestalPix &ped)
322{
323
324 Byte_t sat = 0;
325 Byte_t *first = pixel->GetHiGainSamples() + fExtractWinFirst;
326 Byte_t *logain = pixel->GetLoGainSamples();
327 const Bool_t abflag = pixel->HasABFlag();
328 Float_t dummy;
329 fExtractor->FindTimeAndChargeHiGain(first,logain,sum,dummy,dummy,dummy,sat,ped,abflag);
330}
331
332
333void MPedCalcPedRun::CalcSums( MRawEvtPixelIter *pixel, Float_t &sum, UInt_t &ab0, UInt_t &ab1)
334{
335
336 Byte_t *higain = pixel->GetHiGainSamples() + fExtractWinFirst;
337 Byte_t *ptr = higain;
338 Byte_t *end = ptr + fExtractWinSize;
339
340 const Bool_t abflag = pixel->HasABFlag();
341
342 Int_t sumi = 0;
343
344 Int_t cnt = 0;
345 do
346 {
347 sumi += *ptr;
348 if (pixel->IsABFlagValid())
349 {
350 const Int_t abFlag = (fExtractWinFirst + abflag + cnt) & 0x1;
351 if (abFlag)
352 ab1 += *ptr;
353 else
354 ab0 += *ptr;
355
356 cnt++;
357 }
358 }
359 while (++ptr != end);
360
361 if (fOverlap != 0)
362 {
363 ptr = pixel->GetLoGainSamples();
364 end = ptr + fOverlap;
365
366 do
367 {
368 sumi += *ptr;
369 if (pixel->IsABFlagValid())
370 {
371 const Int_t abFlag = (fExtractWinFirst + abflag + cnt) & 0x1;
372 if (abFlag)
373 ab1 += *ptr;
374 else
375 ab0 += *ptr;
376
377 cnt++;
378 }
379 }
380 while (++ptr != end);
381 }
382
383 sum = (Float_t)sumi;
384
385}
386
387// --------------------------------------------------------------------------
388//
389// Compute signal mean and rms in the whole run and store it in MPedestalCam
390//
391Int_t MPedCalcPedRun::PostProcess()
392{
393
394 if (fUsedEvents == 0)
395 return kTRUE;
396
397 MRawEvtPixelIter pixel(fRawEvt);
398
399 while (pixel.Next())
400 {
401 const Int_t pixid = pixel.GetPixelId();
402 CalcPixResults(fUsedEvents,pixid);
403 }
404
405 //
406 // Loop over the (two) area indices to get the averaged pedestal per aidx
407 //
408 for (UInt_t aidx=0; aidx<fAreaValid.GetSize(); aidx++)
409 {
410 const Int_t napix = fAreaValid.At(aidx);
411 if (napix == 0)
412 continue;
413
414 CalcAreaResults(fUsedEvents,napix,aidx);
415 }
416
417 //
418 // Loop over the (six) sector indices to get the averaged pedestal per sector
419 //
420 for (UInt_t sector=0; sector<fSectorValid.GetSize(); sector++)
421 {
422 const Int_t nspix = fSectorValid.At(sector);
423 if (nspix == 0)
424 continue;
425
426 CalcSectorResults(fUsedEvents,nspix,sector);
427 }
428
429 fPedestalsOut->SetTotalEntries(fUsedEvents*fExtractWinSize);
430 fPedestalsOut->SetReadyToSave();
431
432 return kTRUE;
433}
434
435// -----------------------------------------------------------------------
436//
437// Analogue to the MTask::CallPostProcess, but without the manipulation
438// of the bit fIsPreProcessed. Needed in order to call PostProcess multiple
439// times in the intensity calibration.
440//
441Int_t MPedCalcPedRun::CallPostProcess()
442{
443
444 *fLog << all << fName << "... " << flush;
445 if (fDisplay)
446 fDisplay->SetStatusLine2(*this);
447
448 return PostProcess();
449}
450
451//-------------------------------------------------------------
452//
453// Return if the pedestal bit was set from the calibration trigger box.
454// The last but one bit is used for the "pedestal-bit".
455//
456// This bit is set since run gkFinalizationTriggerBit
457//
458Bool_t MPedCalcPedRun::IsPedBitSet()
459{
460 if (fRunHeader->GetRunNumber() < gkFirstRunWithFinalBits)
461 return kFALSE;
462
463 return (fEvtHeader->GetTriggerID() >> 3 & 1);
464}
465
466void MPedCalcPedRun::Print(Option_t *o) const
467{
468
469 MExtractPedestal::Print(o);
470
471 *fLog << "Number overlap low-gain slices: " << fOverlap << endl;
472 *fLog << "First run out of sequence: " << (fFirstRun?"yes":"no") << endl;
473 *fLog << "Skip this run: " << (fSkip?"yes":"no") << endl;
474 *fLog << "Number of used events so far: " << fUsedEvents << endl;
475 *fLog << endl;
476}
Note: See TracBrowser for help on using the repository browser.