source: trunk/MagicSoft/Mars/mcalib/MCalibrationChargeCalc.cc@ 3657

Last change on this file since 3657 was 3655, checked in by gaug, 22 years ago
*** empty log message ***
File size: 31.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): Markus Gaug 02/2004 <mailto:markus@ifae.es>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MCalibrationChargeCalc
28//
29// Task to calculate the calibration conversion factors from the FADC
30// time slices. The integrated time slices have to be delivered by an
31// MExtractedSignalCam. The pedestals by an MPedestalCam.
32//
33// The output container MCalibrationCam holds one entry of type MCalibrationChargePix
34// for every pixel. It is filled in the following way:
35//
36// ProProcess: Initialize MCalibrationCam
37// Initialize pulser light wavelength
38//
39// ReInit: MCalibrationCam::InitSize(NumPixels) is called from MGeomApply (which allocates
40// memory in a TClonesArray of type MCalibrationChargePix)
41// Initializes pointer to MBadPixelsCam
42//
43// Process: Nothing done by this class, histograms are filled by
44// MHCalibrationChargeCam
45//
46// PostProcess: Fit results from MHCalibrationChargeCam are retrieved
47// and used for the calculation of the reduced sigma,
48// the F-Factor method, the blind pixel method (photon flux
49// inside plexiglass) and
50// the PINDiode method (photon flux
51// outside plexiglass)
52//
53// Hi-Gain vs. Lo-Gain Calibration (very memory-intensive)
54// can be skipped with the command:
55// MalibrationCam::SkipHiLoGainCalibration()
56//
57// Input Containers:
58// MRawEvtData
59// MPedestalCam
60// MBadPixelsCam
61//
62// Output Containers:
63// MCalibrationCam
64// MCalibrationQECam
65// MBadPixelsCam
66//
67//
68// Preliminary description of the calibration in photons (email from 12/02/04)
69//
70// Why calibrating in photons:
71// ===========================
72//
73// At the Barcelona meeting in 2002, we decided to calibrate the camera in
74// photons. This for the following reasons:
75//
76// * The physical quantity arriving at the camera are photons. This is
77// the direct physical information from the air shower. The photons
78// have a flux and a spectrum.
79//
80// * The photon fluxes depend mostly on the shower energy (with
81// corrections deriving from the observation conditions), while the photon
82// spectra depend mostly on the observation conditions: zenith angle,
83// quality of the air, also the impact parameter of the shower.
84//
85// * The photomultiplier, in turn, has different response properties
86// (quantum efficiencies) for photons of different colour. (Moreover,
87// different pixels have slightly different quantum efficiencies).
88// The resulting number of photo-electrons is then amplified (linearly)
89// with respect to the photo-electron flux.
90//
91// * In the ideal case, one would like to disentagle the effects
92// of the observation conditions from the primary particle energy (which
93// one likes to measure). To do so, one needs:
94//
95// 1) A reliable calibration relating the FADC counts to the photo-electron
96// flux -> This is accomplished with the F-Factor method.
97//
98// 2) A reliable calibration of the wavelength-dependent quantum efficiency
99// -> This is accomplished with the combination of the three methods,
100// together with QE-measurements performed by David in order to do
101// the interpolation.
102//
103// 3) A reliable calibration of the observation conditions. This means:
104// - Tracing the atmospheric conditions -> LIDAR
105// - Tracing the observation zenith angle -> Drive System
106// 4) Some knowlegde about the impact parameter:
107// - This is the only part which cannot be accomplished well with a
108// single telescope. We would thus need to convolute the spectrum
109// over the distribution of impact parameters.
110//
111//
112// How an ideal calibration would look like:
113// =========================================
114//
115// We know from the combined PIN-Diode and Blind-Pixel Method the response of
116// each pixel to well-measured light fluxes in three representative
117// wavelengths (green, blue, UV). We also know the response to these light
118// fluxes in photo-electrons. Thus, we can derive:
119//
120// - conversion factors to photo-electrons
121// - conversion factors to photons in three wavelengths.
122//
123// Together with David's measurements and some MC-simulation, we should be
124// able to derive tables for typical Cherenkov-photon spectra - convoluted
125// with the impact parameters and depending on the athmospheric conditions
126// and the zenith angle (the "outer parameters").
127//
128// From these tables we can create "calibration tables" containing some
129// effective quantum efficiency depending on these outer parameters and which
130// are different for each pixel.
131//
132// In an ideal MCalibrate, one would thus have to convert first the FADC
133// slices to Photo-electrons and then, depending on the outer parameters,
134// look up the effective quantum efficiency and get the mean number of
135// photons which is then used for the further analysis.
136//
137// How the (first) MAGIC calibration should look like:
138// ===================================================
139//
140// For the moment, we have only one reliable calibration method, although
141// with very large systematic errors. This is the F-Factor method. Knowing
142// that the light is uniform over the whole camera (which I would not at all
143// guarantee in the case of the CT1 pulser), one could in principle already
144// perform a relative calibration of the quantum efficiencies in the UV.
145// However, the spread in QE at UV is about 10-15% (according to the plot
146// that Abelardo sent around last time. The spread in photo-electrons is 15%
147// for the inner pixels, but much larger (40%) for the outer ones.
148//
149// I'm not sure if we can already say that we have measured the relative
150// difference in quantum efficiency for the inner pixels and produce a first
151// QE-table for each pixel. To so, I would rather check in other wavelengths
152// (which we can do in about one-two weeks when the optical transmission of
153// the calibration trigger is installed).
154//
155// Thus, for the moment being, I would join Thomas proposal to calibrate in
156// photo-electrons and apply one stupid average quantum efficiency for all
157// pixels. This keeping in mind that we will have much preciser information
158// in about one to two weeks.
159//
160//
161// What MCalibrate should calculate and what should be stored:
162// ===========================================================
163//
164// It is clear that in the end, MCerPhotEvt will store photons.
165// MCalibrationCam stores the conversionfactors to photo-electrons and also
166// some tables of how to apply the conversion to photons, given the outer
167// parameters. This is not yet implemented and not even discussed.
168//
169// To start, I would suggest that we define the "average quantum efficiency"
170// (maybe something like 25+-3%) and apply them equally to all
171// photo-electrons. Later, this average factor can be easily replaced by a
172// pixel-dependent factor and later by a (pixel-dependent) table.
173//
174//
175//
176//////////////////////////////////////////////////////////////////////////////
177#include "MCalibrationChargeCalc.h"
178
179#include <TSystem.h>
180#include <TH1.h>
181
182#include "MLog.h"
183#include "MLogManip.h"
184
185#include "MParList.h"
186
187#include "MGeomCam.h"
188#include "MRawRunHeader.h"
189#include "MRawEvtPixelIter.h"
190
191#include "MPedestalCam.h"
192#include "MPedestalPix.h"
193
194#include "MCalibrationChargeCam.h"
195#include "MCalibrationChargePix.h"
196#include "MCalibrationChargePINDiode.h"
197#include "MCalibrationChargeBlindPix.h"
198
199#include "MExtractedSignalCam.h"
200#include "MExtractedSignalPix.h"
201#include "MExtractedSignalBlindPixel.h"
202#include "MExtractedSignalPINDiode.h"
203
204#include "MBadPixelsCam.h"
205#include "MBadPixelsPix.h"
206
207#include "MCalibrationQECam.h"
208#include "MCalibrationQEPix.h"
209
210
211ClassImp(MCalibrationChargeCalc);
212
213using namespace std;
214
215const Float_t MCalibrationChargeCalc::fgChargeLimit = 3.;
216const Float_t MCalibrationChargeCalc::fgChargeErrLimit = 0.;
217const Float_t MCalibrationChargeCalc::fgChargeRelErrLimit = 1.;
218const Float_t MCalibrationChargeCalc::fgTimeLowerLimit = 1.;
219const Float_t MCalibrationChargeCalc::fgTimeUpperLimit = 2.;
220// --------------------------------------------------------------------------
221//
222// Default constructor.
223//
224MCalibrationChargeCalc::MCalibrationChargeCalc(const char *name, const char *title)
225 : fPedestals(NULL), fCam(NULL), fQECam(NULL),
226 fRawEvt(NULL), fRunHeader(NULL), fGeom(NULL),
227 fBadPixels(NULL), fEvtTime(NULL),
228 fSignals(NULL), fSigBlind(NULL), fSigPIN(NULL),
229 fPINDiode(NULL), fBlindPixel(NULL)
230{
231
232 fName = name ? name : "MCalibrationChargeCalc";
233 fTitle = title ? title : "Task to calculate the calibration constants and MCalibrationCam ";
234
235 AddToBranchList("MRawEvtData.fHiGainPixId");
236 AddToBranchList("MRawEvtData.fLoGainPixId");
237 AddToBranchList("MRawEvtData.fHiGainFadcSamples");
238 AddToBranchList("MRawEvtData.fLoGainFadcSamples");
239
240 Clear();
241
242 SetChargeLimit();
243 SetChargeErrLimit();
244
245 SetChargeRelErrLimit();
246 SetTimeLowerLimit();
247 SetTimeUpperLimit();
248}
249
250void MCalibrationChargeCalc::Clear(const Option_t *o)
251{
252
253 SETBIT(fFlags, kUseQualityChecks);
254 SETBIT(fFlags, kHiLoGainCalibration);
255
256 fNumHiGainSamples = 0.;
257 fNumLoGainSamples = 0.;
258 fSqrtHiGainSamples = 0.;
259 fSqrtLoGainSamples = 0.;
260 fConversionHiLo = 0;
261 SkipQualityChecks ( kFALSE );
262 SkipHiLoGainCalibration( kFALSE );
263
264}
265
266
267// --------------------------------------------------------------------------
268//
269// The PreProcess searches for the following input containers:
270// - MRawEvtData
271// - MPedestalCam
272// - MExtractedSignalCam
273// - MExtractedSignalBlindPixel
274// - MExtractedSignalPINDiode
275//
276// The following output containers are also searched and created if
277// they were not found:
278//
279// - MCalibrationCam
280// - MCalibrationQECam
281//
282// The following output containers are only searched, but not created
283//
284// - MTime
285//
286Int_t MCalibrationChargeCalc::PreProcess(MParList *pList)
287{
288
289 fRawEvt = (MRawEvtData*)pList->FindObject("MRawEvtData");
290 if (!fRawEvt)
291 {
292 *fLog << err << "MRawEvtData not found... aborting." << endl;
293 return kFALSE;
294 }
295
296 fPedestals = (MPedestalCam*)pList->FindObject("MPedestalCam");
297 if (!fPedestals)
298 {
299 *fLog << err << "MPedestalCam not found... aborting" << endl;
300 return kFALSE;
301 }
302
303 fSignals = (MExtractedSignalCam*)pList->FindObject("MExtractedSignalCam");
304 if (!fSignals)
305 {
306 *fLog << err << "MExtractedSignalCam not found... aborting" << endl;
307 return kFALSE;
308 }
309
310 fSigBlind = (MExtractedSignalBlindPixel*)pList->FindObject("MExtractedSignalBlindPixel");
311 if (!fSigBlind)
312 *fLog << warn << "MExtractedSignalBlindPixel not found... no blind pixel method! " << endl;
313 else
314 {
315 fBlindPixel = (MCalibrationChargeBlindPix*)pList->FindCreateObj("MCalibrationChargeBlindPix");
316 if (!fBlindPixel)
317 {
318 *fLog << err << "Cannot find nor create MCalibrationChargeBlindPix... aborting" << endl;
319 return kFALSE;
320 }
321 }
322
323 fSigPIN = (MExtractedSignalPINDiode*)pList->FindObject("MExtractedSignalPINDiode");
324 if (!fSigPIN)
325 *fLog << warn << "MExtractedSignalPINDiode not found... no PIN Diode method! " << endl;
326 else
327 {
328 fPINDiode = (MCalibrationChargePINDiode*)pList->FindCreateObj("MCalibrationChargePINDiode");
329 if (!fPINDiode)
330 {
331 *fLog << err << "Cannot find nor create MCalibrationChargePINDiode... aborting" << endl;
332 return kFALSE;
333 }
334 }
335
336 fCam = (MCalibrationChargeCam*)pList->FindCreateObj("MCalibrationChargeCam");
337 if (!fCam)
338 {
339 *fLog << err << "Cannot find nor create MCalibrationChargeCam... aborting" << endl;
340 return kFALSE;
341 }
342
343 fQECam = (MCalibrationQECam*)pList->FindCreateObj("MCalibrationQECam");
344 if (!fQECam)
345 {
346 *fLog << err << "Cannot find nor create MCalibrationQECam... aborting" << endl;
347 return kFALSE;
348 }
349
350 fEvtTime = (MTime*)pList->FindObject("MTime");
351
352 return kTRUE;
353}
354
355
356// --------------------------------------------------------------------------
357//
358// The ReInit searches for the following input containers:
359// - MRawRunHeader
360// - MGeomCam
361// - MBadPixelsCam
362//
363// It retrieves the following variables from MExtractedSignalCam:
364//
365// fNumHiGainSamples
366// fNumLoGainSamples
367//
368// fFirstUsedSliceHiGain
369// fLastUsedSliceHiGain
370// fFirstUsedSliceLoGain
371// fLastUsedSliceLoGain
372//
373// It defines the PixId of every pixel in MCalibrationChargeCam and MCalibrationQECam
374// It sets all pixels excluded which have the flag fBadBixelsPix::IsBad() set.
375//
376Bool_t MCalibrationChargeCalc::ReInit(MParList *pList )
377{
378
379 fRunHeader = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
380 if (!fRunHeader)
381 {
382 *fLog << err << "MRawRunHeader not found... aborting." << endl;
383 return kFALSE;
384 }
385
386 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
387 if (!fGeom)
388 {
389 *fLog << err << "No MGeomCam found... aborting." << endl;
390 return kFALSE;
391 }
392
393 fBadPixels = (MBadPixelsCam*)pList->FindCreateObj("MBadPixelsCam");
394 if (!fBadPixels)
395 {
396 *fLog << err << "Could not find or create MBadPixelsCam ... aborting." << endl;
397 return kFALSE;
398 }
399
400 fNumHiGainSamples = fSignals->GetNumUsedHiGainFADCSlices();
401 fNumLoGainSamples = fSignals->GetNumUsedLoGainFADCSlices();
402 fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
403 fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples);
404
405 UInt_t npixels = fGeom->GetNumPixels();
406
407 for (UInt_t i=0; i<npixels; i++)
408 {
409
410 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam) [i];
411 MCalibrationQEPix &pqe = (MCalibrationQEPix&) (*fQECam)[i];
412 MBadPixelsPix &bad = (*fBadPixels)[i];
413
414 pix.SetPixId(i);
415 pqe.SetPixId(i);
416
417 if (bad.IsBad())
418 {
419 pix.SetExcluded();
420 pqe.SetExcluded();
421 continue;
422 }
423
424 }
425
426 return kTRUE;
427}
428
429
430Int_t MCalibrationChargeCalc::Process()
431{
432 return kTRUE;
433}
434
435// --------------------------------------------------------------------------
436//
437// Finalize pedestals:
438//
439// - Retrieve pedestal and pedestal RMS from MPedestalPix
440// - Retrieve total entries from MPedestalCam
441// - Sum up pedestal and pedestalRMS for the average pixel
442// - Set pedestal*number of used samples in MCalibrationChargePix
443// - Set pedestal RMS * sqrt of number of used samples in MCalibrationChargePix
444//
445//
446void MCalibrationChargeCalc::FinalizePedestals(const MPedestalPix &ped, MCalibrationChargePix &cal,
447 Float_t &avped, Float_t &avrms)
448{
449
450 //
451 // get the pedestals
452 //
453 const Float_t pedes = ped.GetPedestal();
454 const Float_t prms = ped.GetPedestalRms();
455 const Float_t num = TMath::Sqrt((Float_t)fPedestals->GetTotalEntries());
456
457 //
458 // Calculate the average pedestal
459 //
460 avped += pedes;
461 avrms += prms;
462
463 //
464 // set them in the calibration camera
465 //
466 if (cal.IsHiGainSaturation())
467 {
468 cal.SetPedestal(pedes* fNumLoGainSamples,
469 prms * fSqrtLoGainSamples,
470 prms * fNumLoGainSamples / num);
471 cal.CalcLoGainPedestal((Float_t)fNumLoGainSamples);
472 }
473 else
474 {
475 cal.SetPedestal(pedes* fNumHiGainSamples,
476 prms * fSqrtHiGainSamples,
477 prms * fNumHiGainSamples / num);
478 }
479
480}
481
482void MCalibrationChargeCalc::FinalizeAvPedestals(MCalibrationChargePix &cal,
483 Float_t avped, Float_t avrms, Int_t avnum)
484{
485
486 //
487 // set the pedestans in the calibration camera
488 //
489 if (cal.IsHiGainSaturation())
490 {
491 cal.SetPedestal(avped/avnum * fNumLoGainSamples,
492 avrms/avnum * fSqrtLoGainSamples,
493 avrms/avnum * fSqrtLoGainSamples/avnum);
494 cal.CalcLoGainPedestal((Float_t)fNumLoGainSamples);
495 }
496 else
497 {
498 cal.SetPedestal(avped/avnum * fNumHiGainSamples,
499 avrms/avnum * fSqrtHiGainSamples,
500 avrms/avnum * fSqrtHiGainSamples/avnum);
501 }
502}
503
504// ---------------------------------------------------------------------
505//
506// Finalize charges per pixel:
507// - Check chage validity
508// - Check absolute time validity
509// - Calculate the reduced sigma
510// - Calculate the number of photo-electrons
511//
512Bool_t MCalibrationChargeCalc::FinalizeCharges(MCalibrationChargePix &cal, MBadPixelsPix &bad)
513{
514
515 //
516 // The check return kTRUE if:
517 //
518 // 1) Pixel has a fitted charge greater than fChargeLimit*PedRMS
519 // 2) Pixel has a fit error greater than fChargeVarLimit
520 // 3) Pixel has a fitted charge greater its fChargeRelVarLimit times its charge error
521 // 4) Pixel has a charge sigma bigger than its Pedestal RMS
522 //
523 if (cal.GetMean() < fChargeLimit*cal.GetPedRms())
524 {
525 *fLog << warn << "WARNING: Fitted Charge: " << cal.GetMean() << " is smaller than "
526 << fChargeLimit << " Pedestal RMS: " << cal.GetPedRms() << " in Pixel " << cal.GetPixId() << endl;
527 bad.SetUncalibrated( MBadPixelsPix::kChargeIsPedestal);
528 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
529 }
530
531 if (cal.GetMeanErr() < fChargeErrLimit)
532 {
533 *fLog << warn << "WARNING: Sigma of Fitted Charge: " << cal.GetMeanErr() << " is smaller than "
534 << fChargeErrLimit << " in Pixel " << cal.GetPixId() << endl;
535 bad.SetUncalibrated( MBadPixelsPix::kChargeErrNotValid );
536 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
537 }
538
539 if (cal.GetMean() < fChargeRelErrLimit*cal.GetMeanErr())
540 {
541 *fLog << warn << "WARNING: Fitted Charge: " << cal.GetMean() << " is smaller than "
542 << fChargeRelErrLimit << "* its error: " << cal.GetMeanErr() << " in Pixel " << cal.GetPixId() << endl;
543 bad.SetUncalibrated( MBadPixelsPix::kChargeRelErrNotValid );
544 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
545 }
546
547 if (cal.GetSigma() < cal.GetPedRms())
548 {
549 *fLog << warn << "WARNING: Sigma of Fitted Charge: " << cal.GetSigma()
550 << " smaller than Pedestal RMS: " << cal.GetPedRms() << " in Pixel " << cal.GetPixId() << endl;
551 bad.SetUncalibrated( MBadPixelsPix::kChargeSigmaNotValid );
552 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
553 }
554
555 //
556 // The check returns kTRUE if:
557 //
558 // The mean arrival time is at least fTimeLowerLimit slices from the lower edge
559 // and fUpperLimit slices from the upper edge
560 //
561 const Byte_t loweredge = cal.IsHiGainSaturation() ? fSignals->GetFirstUsedSliceLoGain()
562 : fSignals->GetFirstUsedSliceHiGain();
563 const Byte_t upperedge = cal.IsHiGainSaturation() ? fSignals->GetLastUsedSliceLoGain()
564 : fSignals->GetLastUsedSliceHiGain();
565
566 const Float_t lowerlimit = (Float_t)loweredge + fTimeLowerLimit;
567 const Float_t upperlimit = (Float_t)upperedge + fTimeUpperLimit;
568
569 if ( cal.GetAbsTimeMean() < lowerlimit)
570 {
571 *fLog << warn << "WARNING: Mean ArrivalTime in first " << fTimeLowerLimit
572 << " extraction bin of the Pixel " << cal.GetPixId() << endl;
573 *fLog << cal.GetAbsTimeMean() << " " << lowerlimit << endl;
574 bad.SetUncalibrated( MBadPixelsPix::kMeanTimeInFirstBin );
575 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
576 }
577
578 if ( cal.GetAbsTimeMean() > upperlimit )
579 {
580 *fLog << warn << "WARNING: Mean ArrivalTime in last " << fTimeUpperLimit
581 << " two extraction bins of the Pixel " << cal.GetPixId() << endl;
582 *fLog << cal.GetAbsTimeMean() << " " << upperlimit << endl;
583 bad.SetUncalibrated( MBadPixelsPix::kMeanTimeInLast2Bins );
584 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
585 }
586
587 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
588 return kFALSE;
589
590 if (!cal.CalcReducedSigma())
591 {
592 *fLog << warn << GetDescriptor()
593 << ": Could not calculate reduced sigmas of pixel: " << cal.GetPixId() << endl;
594 bad.SetUnsuitable(MBadPixelsPix::kUnsuitableRun);
595 return kFALSE;
596 }
597
598 if (!cal.CalcFFactorMethod())
599 {
600 *fLog << warn << GetDescriptor()
601 << ": Could not calculate F-Factor of pixel: " << cal.GetPixId() << endl;
602 bad.SetUnsuitable(MBadPixelsPix::kUnsuitableRun);
603 return kFALSE;
604 }
605 return kTRUE;
606}
607
608// ------------------------------------------------------------------------
609//
610// Returns kFALSE if pointer to MExtractedSignalPINDiode is NULL
611// Returns kFALSE if pointer to MCalibrationChargePINDiode is NULL
612//
613// The check return kTRUE if:
614//
615// 1) PINDiode has a fitted charge greater than fChargeLimit*PedRMS
616// 2) PINDiode has a fit error greater than fChargeErrLimit
617// 3) PINDiode has a fitted charge greater its fChargeRelErrLimit times its charge error
618// 4) PINDiode has a charge sigma bigger than its Pedestal RMS
619// 5) The mean arrival time is at least fTimeLowerLimit slices from the lower edge
620// and fUpperLimit slices from the upper edge
621//
622Bool_t MCalibrationChargeCalc::FinalizePINDiode()
623{
624
625 if (!fSigPIN)
626 return kFALSE;
627
628 if (!fPINDiode)
629 return kFALSE;
630
631 if (fPINDiode->GetMean() < fChargeLimit*fPINDiode->GetPedRms())
632 {
633 *fLog << warn << "WARNING: Fitted Charge is smaller than "
634 << fChargeLimit << " Pedestal RMS in PINDiode " << endl;
635 return kFALSE;
636 }
637
638 if (fPINDiode->GetMeanErr() < fChargeErrLimit)
639 {
640 *fLog << warn << "WARNING: Error of Fitted Charge is smaller than "
641 << fChargeErrLimit << " in PINDiode " << endl;
642 return kFALSE;
643 }
644
645 if (fPINDiode->GetMean() < fChargeRelErrLimit*fPINDiode->GetMeanErr())
646 {
647 *fLog << warn << "WARNING: Fitted Charge is smaller than "
648 << fChargeRelErrLimit << "* its error in PINDiode " << endl;
649 return kFALSE;
650 }
651
652 if (fPINDiode->GetSigma() < fPINDiode->GetPedRms())
653 {
654 *fLog << warn << "WARNING: Sigma of Fitted Charge smaller than Pedestal RMS in PINDiode " << endl;
655 return kFALSE;
656 }
657
658 const Byte_t loweredge = fSigPIN->GetFirstUsedSlice();
659 const Byte_t upperedge = fSigPIN->GetLastUsedSlice();
660 const Float_t lowerlimit = (Float_t)loweredge + fTimeLowerLimit;
661 const Float_t upperlimit = (Float_t)upperedge + fTimeUpperLimit;
662
663 if (fPINDiode->GetAbsTimeMean() < lowerlimit)
664 {
665 *fLog << warn << "WARNING: Mean ArrivalTime in first " << fTimeLowerLimit
666 << " extraction bin in PIN Diode " << endl;
667 *fLog << fPINDiode->GetAbsTimeMean() << " " << lowerlimit << endl;
668 return kFALSE;
669 }
670
671 if ( fPINDiode->GetAbsTimeMean() > upperlimit )
672 {
673 *fLog << warn << "WARNING: Mean ArrivalTime in last " << fTimeUpperLimit
674 << " two extraction bins in PIN Diode " << endl;
675 *fLog << fPINDiode->GetAbsTimeMean() << " " << upperlimit << endl;
676 return kFALSE;
677 }
678
679 if (!fPINDiode->CalcFluxOutsidePlexiglass())
680 {
681 *fLog << warn << "Could not calculate the flux of photons from the PIN Diode, "
682 << "will skip PIN Diode Calibration " << endl;
683 return kFALSE;
684 }
685
686 return kTRUE;
687}
688
689
690// -----------------------------------------------------------------------
691//
692// - Finalize the pedestals
693// - Do the quality checks
694// - Calculate the reduced sigma
695// - Calculate the F-Factor Method
696//
697Int_t MCalibrationChargeCalc::PostProcess()
698{
699
700 if (GetNumExecutions()==0)
701 return kFALSE;
702
703 //
704 // loop over the pedestal events and check if we have calibration
705 //
706 Int_t nvalid = 0;
707 Float_t avinnerped = 0.;
708 Float_t avinnerprms = 0.;
709 Int_t avinnernum = 0;
710 Float_t avouterped = 0.;
711 Float_t avouterprms = 0.;
712 Int_t avouternum = 0;
713
714 for (Int_t pixid=0; pixid<fPedestals->GetSize(); pixid++)
715 {
716
717 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[pixid];
718 //
719 // Check if the pixel has been excluded from the fits
720 //
721 if (pix.IsExcluded())
722 continue;
723
724 MPedestalPix &ped = (*fPedestals)[pixid];
725 MBadPixelsPix &bad = (*fBadPixels)[pixid];
726
727 if (fGeom->GetPixRatio(pixid) == 1.)
728 {
729 FinalizePedestals(ped,pix,avinnerped,avinnerprms);
730 avinnernum++;
731 }
732 else
733 {
734 FinalizePedestals(ped,pix,avouterped,avouterprms);
735 avouternum++;
736 }
737
738 if (FinalizeCharges(pix,bad))
739 nvalid++;
740 }
741
742 //
743 // The Michele check ...
744 //
745 if (nvalid == 0)
746 {
747 *fLog << err << GetDescriptor() << ": All pixels have non-valid calibration. "
748 << "Did you forget to fill the histograms "
749 << "(filling MHCalibrationChargeCam from MExtractedSignalCam using MFillH) ? " << endl;
750 *fLog << err << GetDescriptor() << ": Or, maybe, you have used a pedestal run "
751 << "instead of a calibration run " << endl;
752 return kFALSE;
753 }
754
755 for (UInt_t aidx=0; aidx<fGeom->GetNumAreas(); aidx++)
756 {
757
758 FinalizeAvPedestals((MCalibrationChargePix&)fCam->GetAverageArea(aidx),
759 avinnerped, avinnerprms,avinnernum);
760 FinalizeCharges((MCalibrationChargePix&)fCam->GetAverageArea(aidx),
761 fCam->GetAverageBadArea(aidx));
762 }
763
764 for (UInt_t sector=0; sector<fGeom->GetNumSectors(); sector++)
765 {
766
767 FinalizeAvPedestals((MCalibrationChargePix&)fCam->GetAverageSector(sector),
768 avinnerped, avinnerprms,avinnernum);
769 FinalizeCharges((MCalibrationChargePix&)fCam->GetAverageSector(sector),
770 fCam->GetAverageBadSector(sector));
771 }
772
773 //
774 // F-Factor calibration
775 //
776 if (fCam->CalcMeanFluxPhotonsFFactorMethod(*fGeom, *fBadPixels))
777 {
778 fCam->ApplyFFactorCalibration(*fGeom,*fBadPixels);
779 fCam->SetFFactorMethodValid(kTRUE);
780 }
781 else
782 {
783 *fLog << warn << "Could not calculate the flux of photo-electrons from the F-Factor method, " << endl;
784 fCam->SetFFactorMethodValid(kFALSE);
785 }
786
787 //
788 // Blind Pixel calibration
789 //
790 if (!fBlindPixel->CheckChargeFitValidity())
791 {
792 *fLog << warn << "Could not calculate the flux of photons from the Blind Pixel, "
793 << "charge fit not valid " << endl;
794 fCam->SetBlindPixelMethodValid(kFALSE);
795 }
796 else
797 {
798 if (!fBlindPixel->CalcFluxInsidePlexiglass())
799 {
800 *fLog << warn << "Could not calculate the flux of photons from the Blind Pixel, "
801 << "will skip PIN Diode Calibration " << endl;
802 fCam->SetBlindPixelMethodValid(kFALSE);
803 }
804 else
805 {
806 fCam->SetBlindPixelMethodValid(kTRUE);
807 fCam->ApplyBlindPixelCalibration(*fGeom,*fBadPixels, *fBlindPixel);
808 }
809 }
810
811 //
812 // PIN Diode calibration
813 //
814 if (!FinalizePINDiode())
815 fCam->SetPINDiodeMethodValid(kFALSE);
816 else
817 {
818 fCam->SetPINDiodeMethodValid(kTRUE);
819 fCam->ApplyPINDiodeCalibration(*fGeom,*fBadPixels, *fPINDiode);
820 }
821
822 fCam->SetReadyToSave();
823
824 *fLog << inf << endl;
825 *fLog << GetDescriptor() << ": Calibration statistics:" << endl;
826 *fLog << dec << setfill(' ');
827
828 UInt_t countinner = 0;
829 UInt_t countouter = 0;
830 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
831 {
832 MBadPixelsPix &bad = (*fBadPixels)[i];
833 if (bad.IsOK())
834 {
835 if (fGeom->GetPixRatio(i) == 1.)
836 countinner++;
837 else
838 countouter++;
839 }
840 }
841
842 *fLog << " " << setw(7) << "Successfully calibrated Pixels: "
843 << "Inner: " << countinner << " Outer: " << countouter << endl;
844
845 PrintUnsuitable(MBadPixelsPix::kUnsuitableRun, "Bad Pixels: ");
846 PrintUnsuitable(MBadPixelsPix::kUnreliableRun, "Unreliable Pixels: ");
847
848 *fLog << inf << endl;
849 *fLog << GetDescriptor() << ": Errors statistics:" << endl;
850
851 PrintUncalibrated(MBadPixelsPix::kChargeIsPedestal,
852 Form("%s%2.1f%s","Signal less than ",fChargeLimit," Pedestal RMS: "));
853 PrintUncalibrated(MBadPixelsPix::kChargeErrNotValid,
854 Form("%s%2.1f%s","Signal Error smaller than ",fChargeErrLimit,": "));
855 PrintUncalibrated(MBadPixelsPix::kChargeRelErrNotValid,
856 Form("%s%2.1f%s","Signal Error bigger than ",fChargeRelErrLimit," times Mean Signal: "));
857 PrintUncalibrated(MBadPixelsPix::kChargeSigmaNotValid,
858 "Signal Sigma smaller than Pedestal RMS: ");
859 PrintUncalibrated(MBadPixelsPix::kLoGainSaturation,
860 "Pixels with Low Gain Saturation: ");
861 PrintUncalibrated(MBadPixelsPix::kMeanTimeInFirstBin,
862 Form("%s%2.1f%s","Mean Abs. Arr. Time in First ",fTimeLowerLimit," Bin(s): "));
863 PrintUncalibrated(MBadPixelsPix::kMeanTimeInLast2Bins,
864 Form("%s%2.1f%s","Mean Abs. Arr. Time in Last ",fTimeUpperLimit," Bin(s): "));
865 PrintUncalibrated(MBadPixelsPix::kHiGainOscillating,
866 "Pixels with changing Hi Gain signal over time: ");
867 PrintUncalibrated(MBadPixelsPix::kLoGainOscillating,
868 "Pixels with changing Lo Gain signal over time: ");
869 PrintUncalibrated(MBadPixelsPix::kDeviatingNumPhes,
870 "Pixels with deviating number of phes: ");
871 PrintUncalibrated(MBadPixelsPix::kHiGainNotFitted,
872 "Pixels with unsuccesful Gauss fit to the Hi Gain: ");
873 PrintUncalibrated(MBadPixelsPix::kLoGainNotFitted,
874 "Pixels with unsuccesful Gauss fit to the Lo Gain: ");
875
876 return kTRUE;
877}
878
879void MCalibrationChargeCalc::PrintUnsuitable(MBadPixelsPix::UnsuitableType_t typ, const char *text) const
880{
881
882 UInt_t countinner = 0;
883 UInt_t countouter = 0;
884 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
885 {
886 MBadPixelsPix &bad = (*fBadPixels)[i];
887 if (bad.IsUnsuitable(typ))
888 {
889 if (fGeom->GetPixRatio(i) == 1.)
890 countinner++;
891 else
892 countouter++;
893 }
894 }
895
896 *fLog << " " << setw(7) << text
897 << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
898}
899
900void MCalibrationChargeCalc::PrintUncalibrated(MBadPixelsPix::UncalibratedType_t typ, const char *text) const
901{
902
903 UInt_t countinner = 0;
904 UInt_t countouter = 0;
905 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
906 {
907 MBadPixelsPix &bad = (*fBadPixels)[i];
908 if (bad.IsUncalibrated(typ))
909 {
910 if (fGeom->GetPixRatio(i) == 1.)
911 countinner++;
912 else
913 countouter++;
914 }
915 }
916
917 *fLog << " " << setw(7) << text
918 << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
919}
920
Note: See TracBrowser for help on using the repository browser.