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

Last change on this file since 3681 was 3681, checked in by gaug, 21 years ago
*** empty log message ***
File size: 46.5 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 "MRawRunHeader.h"
188#include "MRawEvtPixelIter.h"
189
190#include "MGeomCam.h"
191#include "MGeomPix.h"
192
193#include "MPedestalCam.h"
194#include "MPedestalPix.h"
195
196#include "MCalibrationChargeCam.h"
197#include "MCalibrationChargePix.h"
198#include "MCalibrationChargePINDiode.h"
199#include "MCalibrationChargeBlindPix.h"
200
201#include "MExtractedSignalCam.h"
202#include "MExtractedSignalPix.h"
203#include "MExtractedSignalBlindPixel.h"
204#include "MExtractedSignalPINDiode.h"
205
206#include "MBadPixelsCam.h"
207#include "MBadPixelsPix.h"
208
209#include "MCalibrationQECam.h"
210#include "MCalibrationQEPix.h"
211
212#include "MCalibrationCam.h"
213
214ClassImp(MCalibrationChargeCalc);
215
216using namespace std;
217
218const Float_t MCalibrationChargeCalc::fgChargeLimit = 3.;
219const Float_t MCalibrationChargeCalc::fgChargeErrLimit = 0.;
220const Float_t MCalibrationChargeCalc::fgChargeRelErrLimit = 1.;
221const Float_t MCalibrationChargeCalc::fgLambdaErrLimit = 0.2;
222const Float_t MCalibrationChargeCalc::fgLambdaCheckLimit = 0.2;
223const Float_t MCalibrationChargeCalc::fgPheErrLimit = 5.;
224const Float_t MCalibrationChargeCalc::fgTimeLowerLimit = 1.;
225const Float_t MCalibrationChargeCalc::fgTimeUpperLimit = 2.;
226// --------------------------------------------------------------------------
227//
228// Default constructor.
229//
230// Sets all pointers to NULL
231//
232// Calls AddToBranchList for:
233// - MRawEvtData.fHiGainPixId
234// - MRawEvtData.fLoGainPixId
235// - MRawEvtData.fHiGainFadcSamples
236// - MRawEvtData.fLoGainFadcSamples
237//
238// Initializes:
239// - fChargeLimit to fgChargeLimit
240// - fChargeErrLimit to fgChargeErrLimit
241// - fChargeRelErrLimit to fgChargeRelErrLimit
242// - fLambdaCheckLimit to fgLambdaCheckLimit
243// - fLambdaErrLimit to fgLambdaErrLimit
244// - fTimeLowerLimit to fgTimeLowerLimit
245// - fTimeUpperLimit to fgTimeUpperLimit
246// - fPheErrLimit to fgPheErrLimit
247// - fPulserColor to MCalibrationCam::kCT1
248//
249// Calls:
250// - Clear()
251//
252MCalibrationChargeCalc::MCalibrationChargeCalc(const char *name, const char *title)
253 : fPedestals(NULL), fCam(NULL), fQECam(NULL),
254 fRawEvt(NULL), fRunHeader(NULL), fGeom(NULL),
255 fBadPixels(NULL), fEvtTime(NULL),
256 fSignals(NULL), fSigBlind(NULL), fSigPIN(NULL),
257 fPINDiode(NULL), fBlindPixel(NULL)
258{
259
260 fName = name ? name : "MCalibrationChargeCalc";
261 fTitle = title ? title : "Task to calculate the calibration constants and MCalibrationCam ";
262
263 AddToBranchList("MRawEvtData.fHiGainPixId");
264 AddToBranchList("MRawEvtData.fLoGainPixId");
265 AddToBranchList("MRawEvtData.fHiGainFadcSamples");
266 AddToBranchList("MRawEvtData.fLoGainFadcSamples");
267
268 SetChargeLimit();
269 SetChargeErrLimit();
270 SetChargeRelErrLimit();
271 SetLambdaCheckLimit();
272 SetLambdaErrLimit();
273 SetPheErrLimit();
274 SetPulserColor(MCalibrationCam::kCT1);
275 SetTimeLowerLimit();
276 SetTimeUpperLimit();
277
278 Clear();
279
280}
281
282void MCalibrationChargeCalc::Clear(const Option_t *o)
283{
284
285 SETBIT(fFlags, kUseQualityChecks);
286 SETBIT(fFlags, kHiLoGainCalibration);
287
288 fNumHiGainSamples = 0.;
289 fNumLoGainSamples = 0.;
290 fSqrtHiGainSamples = 0.;
291 fSqrtLoGainSamples = 0.;
292 fConversionHiLo = 0 ;
293 SkipQualityChecks ( kFALSE );
294 SkipHiLoGainCalibration( kFALSE );
295}
296
297
298// --------------------------------------------------------------------------
299//
300// The PreProcess searches for the following input containers:
301// - MRawEvtData
302// - MPedestalCam
303// - MExtractedSignalCam
304// - MExtractedSignalBlindPixel
305// - MExtractedSignalPINDiode
306//
307// The following output containers are also searched and created if
308// they were not found:
309//
310// - MCalibrationChargeCam
311// - MCalibrationQECam
312//
313// The following output containers are only searched, but not created
314//
315// - MTime
316//
317// Sets the pulser colour in MCalibrationChargeCam
318//
319Int_t MCalibrationChargeCalc::PreProcess(MParList *pList)
320{
321
322 fRawEvt = (MRawEvtData*)pList->FindObject("MRawEvtData");
323 if (!fRawEvt)
324 {
325 *fLog << err << "MRawEvtData not found... aborting." << endl;
326 return kFALSE;
327 }
328
329 fPedestals = (MPedestalCam*)pList->FindObject("MPedestalCam");
330 if (!fPedestals)
331 {
332 *fLog << err << "MPedestalCam not found... aborting" << endl;
333 return kFALSE;
334 }
335
336 fSignals = (MExtractedSignalCam*)pList->FindObject("MExtractedSignalCam");
337 if (!fSignals)
338 {
339 *fLog << err << "MExtractedSignalCam not found... aborting" << endl;
340 return kFALSE;
341 }
342
343 fSigBlind = (MExtractedSignalBlindPixel*)pList->FindObject("MExtractedSignalBlindPixel");
344 if (!fSigBlind)
345 *fLog << warn << "MExtractedSignalBlindPixel not found... no blind pixel method! " << endl;
346 else
347 {
348 fBlindPixel = (MCalibrationChargeBlindPix*)pList->FindCreateObj("MCalibrationChargeBlindPix");
349 if (!fBlindPixel)
350 {
351 *fLog << err << "Cannot find nor create MCalibrationChargeBlindPix... aborting" << endl;
352 return kFALSE;
353 }
354 fBlindPixel->SetColor( fPulserColor );
355 }
356
357 fSigPIN = (MExtractedSignalPINDiode*)pList->FindObject("MExtractedSignalPINDiode");
358 if (!fSigPIN)
359 *fLog << warn << "MExtractedSignalPINDiode not found... no PIN Diode method! " << endl;
360 else
361 {
362 fPINDiode = (MCalibrationChargePINDiode*)pList->FindCreateObj("MCalibrationChargePINDiode");
363 if (!fPINDiode)
364 {
365 *fLog << err << "Cannot find nor create MCalibrationChargePINDiode... aborting" << endl;
366 return kFALSE;
367 }
368 fPINDiode->SetColor( fPulserColor );
369 }
370
371 fCam = (MCalibrationChargeCam*)pList->FindCreateObj("MCalibrationChargeCam");
372 if (!fCam)
373 {
374 *fLog << err << "Cannot find nor create MCalibrationChargeCam... aborting" << endl;
375 return kFALSE;
376 }
377
378 fCam->SetPulserColor( fPulserColor );
379
380 fQECam = (MCalibrationQECam*)pList->FindCreateObj("MCalibrationQECam");
381 if (!fQECam)
382 {
383 *fLog << err << "Cannot find nor create MCalibrationQECam... aborting" << endl;
384 return kFALSE;
385 }
386
387 fEvtTime = (MTime*)pList->FindObject("MTime");
388
389 return kTRUE;
390}
391
392
393// --------------------------------------------------------------------------
394//
395// The ReInit searches for the following input containers:
396// - MRawRunHeader
397// - MGeomCam
398// - MBadPixelsCam
399//
400// It retrieves the following variables from MExtractedSignalCam:
401//
402// fNumHiGainSamples
403// fNumLoGainSamples
404//
405// fFirstUsedSliceHiGain
406// fLastUsedSliceHiGain
407// fFirstUsedSliceLoGain
408// fLastUsedSliceLoGain
409//
410// It defines the PixId of every pixel in MCalibrationChargeCam and MCalibrationQECam
411// It sets all pixels excluded which have the flag fBadBixelsPix::IsBad() set.
412//
413Bool_t MCalibrationChargeCalc::ReInit(MParList *pList )
414{
415
416 fRunHeader = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
417 if (!fRunHeader)
418 {
419 *fLog << err << "MRawRunHeader not found... aborting." << endl;
420 return kFALSE;
421 }
422
423 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
424 if (!fGeom)
425 {
426 *fLog << err << "No MGeomCam found... aborting." << endl;
427 return kFALSE;
428 }
429
430 fBadPixels = (MBadPixelsCam*)pList->FindCreateObj("MBadPixelsCam");
431 if (!fBadPixels)
432 {
433 *fLog << err << "Could not find or create MBadPixelsCam ... aborting." << endl;
434 return kFALSE;
435 }
436
437 fNumHiGainSamples = fSignals->GetNumUsedHiGainFADCSlices();
438 fNumLoGainSamples = fSignals->GetNumUsedLoGainFADCSlices();
439 fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
440 fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples);
441
442 UInt_t npixels = fGeom->GetNumPixels();
443
444 for (UInt_t i=0; i<npixels; i++)
445 {
446
447 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam) [i];
448 MCalibrationQEPix &pqe = (MCalibrationQEPix&) (*fQECam)[i];
449 MBadPixelsPix &bad = (*fBadPixels)[i];
450
451 pix.SetPixId(i);
452 pqe.SetPixId(i);
453
454 if (bad.IsBad())
455 {
456 pix.SetExcluded();
457 pqe.SetExcluded();
458 continue;
459 }
460
461 }
462
463 return kTRUE;
464}
465
466
467// ----------------------------------------------------------------------------------
468//
469// Nothing to be done in Process, but have a look at MHCalibrationChargeCam, instead
470//
471Int_t MCalibrationChargeCalc::Process()
472{
473 return kTRUE;
474}
475
476// ----------------------------------------------------------------------------------
477//
478// Finalize pedestals:
479//
480// - Retrieve pedestal and pedestal RMS from MPedestalPix
481// - Retrieve total entries from MPedestalCam
482// - Sum up pedestal and pedestalRMS for the average pixel
483// - Set pedestal*number of used samples in MCalibrationChargePix
484// - Set pedestal RMS * sqrt of number of used samples in MCalibrationChargePix
485//
486//
487void MCalibrationChargeCalc::FinalizePedestals(const MPedestalPix &ped, MCalibrationChargePix &cal,
488 Float_t &avped, Float_t &avrms)
489{
490
491 //
492 // get the pedestals
493 //
494 const Float_t pedes = ped.GetPedestal();
495 const Float_t prms = ped.GetPedestalRms();
496 const Float_t num = TMath::Sqrt((Float_t)fPedestals->GetTotalEntries());
497
498 //
499 // Calculate the average pedestal
500 //
501 avped += pedes;
502 avrms += prms;
503
504 //
505 // set them in the calibration camera
506 //
507 if (cal.IsHiGainSaturation())
508 {
509 cal.SetPedestal(pedes* fNumLoGainSamples,
510 prms * fSqrtLoGainSamples,
511 prms * fNumLoGainSamples / num);
512 cal.CalcLoGainPedestal((Float_t)fNumLoGainSamples);
513 }
514 else
515 {
516 cal.SetPedestal(pedes* fNumHiGainSamples,
517 prms * fSqrtHiGainSamples,
518 prms * fNumHiGainSamples / num);
519 }
520
521}
522
523void MCalibrationChargeCalc::FinalizeAvPedestals(MCalibrationChargePix &cal,
524 Float_t avped, Float_t avrms, Int_t avnum)
525{
526
527 //
528 // set the pedestans in the calibration camera
529 //
530 if (cal.IsHiGainSaturation())
531 {
532 cal.SetPedestal(avped/avnum * fNumLoGainSamples,
533 avrms/avnum * fSqrtLoGainSamples,
534 avrms/avnum * fSqrtLoGainSamples/avnum);
535 cal.CalcLoGainPedestal((Float_t)fNumLoGainSamples);
536 }
537 else
538 {
539 cal.SetPedestal(avped/avnum * fNumHiGainSamples,
540 avrms/avnum * fSqrtHiGainSamples,
541 avrms/avnum * fSqrtHiGainSamples/avnum);
542 }
543}
544
545// ---------------------------------------------------------------------
546//
547// Finalize charges per pixel:
548// - Check chage validity
549// - Check absolute time validity
550// - Calculate the reduced sigma
551// - Calculate the number of photo-electrons
552//
553Bool_t MCalibrationChargeCalc::FinalizeCharges(MCalibrationChargePix &cal, MBadPixelsPix &bad)
554{
555
556 //
557 // The check return kTRUE if:
558 //
559 // 1) Pixel has a fitted charge greater than fChargeLimit*PedRMS
560 // 2) Pixel has a fit error greater than fChargeVarLimit
561 // 3) Pixel has a fitted charge greater its fChargeRelVarLimit times its charge error
562 // 4) Pixel has a charge sigma bigger than its Pedestal RMS
563 //
564 if (cal.GetMean() < fChargeLimit*cal.GetPedRms())
565 {
566 *fLog << warn << GetDescriptor() << ": Fitted Charge: " << cal.GetMean() << " is smaller than "
567 << fChargeLimit << " Pedestal RMS: " << cal.GetPedRms() << " in Pixel " << cal.GetPixId() << endl;
568 bad.SetUncalibrated( MBadPixelsPix::kChargeIsPedestal);
569 }
570
571 if (cal.GetMeanErr() < fChargeErrLimit)
572 {
573 *fLog << warn << GetDescriptor() << ": Sigma of Fitted Charge: " << cal.GetMeanErr()
574 << " is smaller than " << fChargeErrLimit << " in Pixel " << cal.GetPixId() << endl;
575 bad.SetUncalibrated( MBadPixelsPix::kChargeErrNotValid );
576 }
577
578 if (cal.GetMean() < fChargeRelErrLimit*cal.GetMeanErr())
579 {
580 *fLog << warn << GetDescriptor() << ": Fitted Charge: " << cal.GetMean() << " is smaller than "
581 << fChargeRelErrLimit << "* its error: " << cal.GetMeanErr()
582 << " in Pixel " << cal.GetPixId() << endl;
583 bad.SetUncalibrated( MBadPixelsPix::kChargeRelErrNotValid );
584 }
585
586 if (cal.GetSigma() < cal.GetPedRms())
587 {
588 *fLog << warn << GetDescriptor() << ": Sigma of Fitted Charge: " << cal.GetSigma()
589 << " smaller than Pedestal RMS: " << cal.GetPedRms() << " in Pixel " << cal.GetPixId() << endl;
590 bad.SetUncalibrated( MBadPixelsPix::kChargeSigmaNotValid );
591 }
592
593 //
594 // The check returns kTRUE if:
595 //
596 // The mean arrival time is at least fTimeLowerLimit slices from the lower edge
597 // and fUpperLimit slices from the upper edge
598 //
599 const Byte_t loweredge = cal.IsHiGainSaturation() ? fSignals->GetFirstUsedSliceLoGain()
600 : fSignals->GetFirstUsedSliceHiGain();
601 const Byte_t upperedge = cal.IsHiGainSaturation() ? fSignals->GetLastUsedSliceLoGain()
602 : fSignals->GetLastUsedSliceHiGain();
603
604 const Float_t lowerlimit = (Float_t)loweredge + fTimeLowerLimit;
605 const Float_t upperlimit = (Float_t)upperedge + fTimeUpperLimit;
606
607 if ( cal.GetAbsTimeMean() < lowerlimit)
608 {
609 *fLog << warn << GetDescriptor() << ": Mean ArrivalTime in first " << fTimeLowerLimit
610 << " extraction bin of the Pixel " << cal.GetPixId() << endl;
611 *fLog << cal.GetAbsTimeMean() << " " << lowerlimit << endl;
612 bad.SetUncalibrated( MBadPixelsPix::kMeanTimeInFirstBin );
613 }
614
615 if ( cal.GetAbsTimeMean() > upperlimit )
616 {
617 *fLog << warn << GetDescriptor() << ": Mean ArrivalTime in last " << fTimeUpperLimit
618 << " two extraction bins of the Pixel " << cal.GetPixId() << endl;
619 *fLog << cal.GetAbsTimeMean() << " " << upperlimit << endl;
620 bad.SetUncalibrated( MBadPixelsPix::kMeanTimeInLast2Bins );
621 }
622
623 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
624 return kFALSE;
625
626 if (!cal.CalcReducedSigma())
627 {
628 *fLog << warn << GetDescriptor()
629 << ": Could not calculate reduced sigmas of pixel: " << cal.GetPixId() << endl;
630 bad.SetUncalibrated(MBadPixelsPix::kChargeIsPedestal);
631 return kFALSE;
632 }
633
634 if (!cal.CalcFFactorMethod())
635 {
636 *fLog << warn << GetDescriptor()
637 << ": Could not calculate F-Factor of pixel: " << cal.GetPixId() << endl;
638 bad.SetUncalibrated(MBadPixelsPix::kDeviatingNumPhes);
639 return kFALSE;
640 }
641 return kTRUE;
642}
643
644// ------------------------------------------------------------------------
645//
646// Returns kFALSE if pointer to MExtractedSignalPINDiode is NULL
647// Returns kFALSE if pointer to MCalibrationChargePINDiode is NULL
648//
649// The check returns kFALSE if:
650//
651// 1) PINDiode has a fitted charge smaller than fChargeLimit*PedRMS
652// 2) PINDiode has a fit error smaller than fChargeErrLimit
653// 3) PINDiode has a fitted charge smaller its fChargeRelErrLimit times its charge error
654// 4) PINDiode has a charge sigma smaller than its Pedestal RMS
655// 5) The mean arrival time is in fTimeLowerLimit slices from the lower edge
656// and fUpperLimit slices from the upper edge
657//
658// Calls:
659// - MCalibrationChargePINDiode::CalcFluxOutsidePlexiglass()
660//
661Bool_t MCalibrationChargeCalc::FinalizePINDiode()
662{
663
664 if (!fSigPIN)
665 return kFALSE;
666
667 if (!fPINDiode)
668 return kFALSE;
669
670 if (fPINDiode->GetMean() < fChargeLimit*fPINDiode->GetPedRms())
671 {
672 *fLog << warn << GetDescriptor() << ": Fitted Charge is smaller than "
673 << fChargeLimit << " Pedestal RMS in PINDiode " << endl;
674 return kFALSE;
675 }
676
677 if (fPINDiode->GetMeanErr() < fChargeErrLimit)
678 {
679 *fLog << warn << GetDescriptor() << ": Error of Fitted Charge is smaller than "
680 << fChargeErrLimit << " in PINDiode " << endl;
681 return kFALSE;
682 }
683
684 if (fPINDiode->GetMean() < fChargeRelErrLimit*fPINDiode->GetMeanErr())
685 {
686 *fLog << warn << GetDescriptor() << ": Fitted Charge is smaller than "
687 << fChargeRelErrLimit << "* its error in PINDiode " << endl;
688 return kFALSE;
689 }
690
691 if (fPINDiode->GetSigma() < fPINDiode->GetPedRms())
692 {
693 *fLog << warn << GetDescriptor() << ": Sigma of Fitted Charge smaller than Pedestal RMS in PINDiode " << endl;
694 return kFALSE;
695 }
696
697 const Byte_t loweredge = fSigPIN->GetFirstUsedSlice();
698 const Byte_t upperedge = fSigPIN->GetLastUsedSlice();
699 const Float_t lowerlimit = (Float_t)loweredge + fTimeLowerLimit;
700 const Float_t upperlimit = (Float_t)upperedge + fTimeUpperLimit;
701
702 if (fPINDiode->GetAbsTimeMean() < lowerlimit)
703 {
704 *fLog << warn << GetDescriptor() << ": Mean ArrivalTime in first " << fTimeLowerLimit
705 << " extraction bin in PIN Diode " << endl;
706 *fLog << fPINDiode->GetAbsTimeMean() << " " << lowerlimit << endl;
707 return kFALSE;
708 }
709
710 if ( fPINDiode->GetAbsTimeMean() > upperlimit )
711 {
712 *fLog << warn << GetDescriptor() << ": Mean ArrivalTime in last " << fTimeUpperLimit
713 << " two extraction bins in PIN Diode " << endl;
714 *fLog << fPINDiode->GetAbsTimeMean() << " " << upperlimit << endl;
715 return kFALSE;
716 }
717
718 if (!fPINDiode->CalcFluxOutsidePlexiglass())
719 {
720 *fLog << warn << "Could not calculate the flux of photons from the PIN Diode, "
721 << "will skip PIN Diode Calibration " << endl;
722 return kFALSE;
723 }
724
725 return kTRUE;
726}
727
728// ------------------------------------------------------------------------
729//
730// Returns kFALSE if pointer to MExtractedSignalBlindPixel is NULL
731// Returns kFALSE if pointer to MCalibrationChargeBlindPix is NULL
732//
733// The check returns kFALSE if:
734//
735// 1) fLambda and fLambdaCheck are separated relatively to each other by more than fLambdaCheckLimit
736// 2) BlindPixel has an fLambdaErr greater than fLambdaErrLimit
737//
738// Calls:
739// - MCalibrationChargeBlindPix::CalcFluxInsidePlexiglass()
740//
741Bool_t MCalibrationChargeCalc::FinalizeBlindPixel()
742{
743
744 if (!fSigBlind)
745 return kFALSE;
746
747 if (!fBlindPixel)
748 return kFALSE;
749
750 const Float_t lambda = fBlindPixel->GetLambda();
751 const Float_t lambdaerr = fBlindPixel->GetLambdaErr();
752 const Float_t lambdacheck = fBlindPixel->GetLambdaCheck();
753
754 if (2.*(lambdacheck-lambda)/(lambdacheck+lambda) < fLambdaCheckLimit)
755 {
756 *fLog << warn << GetDescriptor() << ": Lambda and Lambda-Check differ by more than "
757 << fLambdaCheckLimit << " in the Blind Pixel " << endl;
758 return kFALSE;
759 }
760
761 if (lambdaerr < fLambdaErrLimit)
762 {
763 *fLog << warn << GetDescriptor() << ": Error of Fitted Lambda is greater than "
764 << fLambdaErrLimit << " in Blind Pixel " << endl;
765 return kFALSE;
766 }
767
768 if (!fBlindPixel->CalcFluxInsidePlexiglass())
769 {
770 *fLog << warn << "Could not calculate the flux of photons from the Blind Pixel, "
771 << "will skip Blind Pixel Calibration " << endl;
772 return kFALSE;
773 }
774
775 return kTRUE;
776}
777
778// ------------------------------------------------------------------------
779//
780//
781Bool_t MCalibrationChargeCalc::FinalizeFFactorMethod()
782{
783
784 const UInt_t npixels = fGeom->GetNumPixels();
785 const UInt_t nareas = fGeom->GetNumAreas();
786 const UInt_t nsectors = fGeom->GetNumSectors();
787
788 Float_t lowlim [nareas];
789 Float_t upplim [nareas];
790 Float_t areavars [nareas];
791 Float_t areaweights [nareas], sectorweights [nsectors];
792 Float_t areaphes [nareas], sectorphes [nsectors];
793 Int_t numareavalid[nareas], numsectorvalid[nsectors];
794
795 memset(lowlim ,0, nareas * sizeof(Float_t));
796 memset(upplim ,0, nareas * sizeof(Float_t));
797 memset(areaphes ,0, nareas * sizeof(Float_t));
798 memset(areavars ,0, nareas * sizeof(Float_t));
799 memset(areaweights ,0, nareas * sizeof(Float_t));
800 memset(numareavalid ,0, nareas * sizeof(Int_t ));
801 memset(sectorweights ,0, nsectors * sizeof(Float_t));
802 memset(sectorphes ,0, nsectors * sizeof(Float_t));
803 memset(numsectorvalid,0, nsectors * sizeof(Int_t ));
804
805 //
806 // First loop: Get mean number of photo-electrons and the RMS
807 // The loop is only to recognize later pixels with very deviating numbers
808 //
809 for (UInt_t i=0; i<npixels; i++)
810 {
811
812 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam) [i];
813 MBadPixelsPix &bad = (*fBadPixels)[i];
814
815 if (!pix.IsFFactorMethodValid())
816 continue;
817
818 if (!bad.IsCalibrationResultOK())
819 {
820 pix.SetFFactorMethodValid(kFALSE);
821 continue;
822 }
823
824 const Float_t nphe = pix.GetPheFFactorMethod();
825 const Float_t nvar = pix.GetPheFFactorMethodVar();
826 const Int_t aidx = (*fGeom)[i].GetAidx();
827
828 if (nvar > 0.)
829 {
830 areaphes [aidx] += nphe;
831 areavars [aidx] += nvar;
832 numareavalid[aidx] ++;
833 }
834 }
835
836 for (UInt_t i=0; i<nareas; i++)
837 {
838 if (numareavalid[i] == 0)
839 {
840 *fLog << warn << GetDescriptor() << ": No pixels with valid number of photo-electrons found "
841 << "in area index: " << i << endl;
842 continue;
843 }
844
845 areaphes[i] = areaphes[i] / numareavalid[i];
846 areavars[i] = areavars[i] / numareavalid[i];
847 lowlim [i] = areaphes[i] - fPheErrLimit*TMath::Sqrt(areavars[i]);
848 upplim [i] = areaphes[i] + fPheErrLimit*TMath::Sqrt(areavars[i]);
849 }
850
851 memset(numareavalid,0,nareas*sizeof(Int_t));
852 memset(areaphes ,0,nareas*sizeof(Int_t));
853 memset(areavars ,0,nareas*sizeof(Int_t));
854
855 //
856 // Second loop: Get weighted mean number of photo-electrons and its RMS excluding
857 // pixels deviating by more than fPheErrLimit sigma.
858 // Set the conversion factor FADC counts to photo-electrons
859 //
860 for (UInt_t i=0; i<npixels; i++)
861 {
862
863 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
864
865 if (!pix.IsFFactorMethodValid())
866 continue;
867
868 const Float_t nvar = pix.GetPheFFactorMethodVar();
869
870 if (nvar <= 0.)
871 {
872 pix.SetFFactorMethodValid(kFALSE);
873 continue;
874 }
875
876 MBadPixelsPix &bad = (*fBadPixels)[i];
877
878 const Int_t aidx = (*fGeom)[i].GetAidx();
879 const Int_t sector = (*fGeom)[i].GetSector();
880 const Float_t nphe = pix.GetPheFFactorMethod();
881
882 if ( nphe < lowlim[aidx] || nphe > upplim[aidx] )
883 {
884 *fLog << warn << GetDescriptor() << ": Deviating number of photo-electrons: "
885 << Form("%4.2f",nphe) << " out of accepted limits: ["
886 << Form("%4.2f%s%4.2f",lowlim[aidx],",",upplim[aidx]) << "] in pixel " << i << endl;
887 bad.SetUncalibrated( MBadPixelsPix::kDeviatingNumPhes );
888 bad.SetUnsuitable ( MBadPixelsPix::kUnreliableRun );
889 continue;
890 }
891
892 const Float_t weight = 1./nvar;
893
894 areaweights [aidx] += weight;
895 areaphes [aidx] += weight*nphe;
896 numareavalid [aidx] ++;
897 sectorweights [sector] += weight;
898 sectorphes [sector] += weight*nphe;
899 numsectorvalid[sector] ++;
900 }
901
902 for (UInt_t aidx=0; aidx<nareas; aidx++)
903 {
904
905 MCalibrationChargePix &apix = (MCalibrationChargePix&)fCam->GetAverageArea(aidx);
906
907 if (areaweights[aidx] <= 0. || areaphes[aidx] <= 0.)
908 {
909 *fLog << warn << " Mean number of phe's from area index " << aidx << " cannot be calculated: "
910 << " Sum of weights: " << areaweights[aidx]
911 << " Sum of weighted phes: " << areaphes[aidx] << endl;
912 apix.SetFFactorMethodValid(kFALSE);
913 continue;
914 }
915
916 *fLog << inf << "Replacing number photo-electrons of average area idx " << aidx << ": "
917 << Form("%5.3f%s%5.3f",apix.GetPheFFactorMethod()," +- ",apix.GetPheFFactorMethodErr()) << endl;
918 *fLog << inf << " by average number of photo-electrons from area idx " << aidx << ": "
919 << Form("%5.3f%s%5.3f",areaphes[aidx] / areaweights[aidx]," +- ",
920 TMath::Sqrt(1./areaweights[aidx])) << endl;
921
922 apix.SetPheFFactorMethod ( areaphes[aidx]/ areaweights[aidx] );
923 apix.SetPheFFactorMethodVar( 1. / areaweights[aidx] );
924 apix.SetFFactorMethodValid ( kTRUE );
925
926 }
927
928 for (UInt_t sector=0; sector<nsectors; sector++)
929 {
930
931 MCalibrationChargePix &spix = (MCalibrationChargePix&)fCam->GetAverageSector(sector);
932
933 if (sectorweights[sector] <= 0. || sectorphes[sector] <= 0.)
934 {
935 *fLog << warn << " Mean number of phe's from sector " << sector << " cannot be calculated: "
936 << " Sum of weights: " << sectorweights[sector]
937 << " Sum of weighted phes: " << sectorphes[sector] << endl;
938 spix.SetFFactorMethodValid(kFALSE);
939 continue;
940 }
941
942 *fLog << inf << "Replacing number photo-electrons of average sector " << sector << ": "
943 << Form("%5.3f%s%5.3f",spix.GetPheFFactorMethod()," +- ",spix.GetPheFFactorMethodErr()) << endl;
944 *fLog << inf << " by average number photo-electrons from sector " << sector << ": "
945 << Form("%5.3f%s%5.3f",sectorphes[sector]/ sectorweights[sector]," +- ",
946 TMath::Sqrt(1./sectorweights[sector])) << endl;
947
948 spix.SetPheFFactorMethod ( sectorphes[sector]/ sectorweights[sector] );
949 spix.SetPheFFactorMethodVar( 1. / sectorweights[sector] );
950 spix.SetFFactorMethodValid ( kTRUE );
951
952 }
953
954 return kTRUE;
955}
956
957
958// ----------------------------------------------------------------------
959//
960// Sets all pixels to MBadPixelsPix::kUnsuitableRun, if following flags are set:
961// - MBadPixelsPix::kChargeIsPedestal
962// - MBadPixelsPix::kChargeErrNotValid
963// - MBadPixelsPix::kChargeRelErrNotValid
964// - MBadPixelsPix::kChargeSigmaNotValid
965// - MBadPixelsPix::kMeanTimeInFirstBin
966// - MBadPixelsPix::kMeanTimeInLast2Bins
967//
968// Sets all pixels to MBadPixelsPix::kUnreliableRun, if following flags are set:
969// - MBadPixelsPix::kDeviatingNumPhes
970//
971void MCalibrationChargeCalc::FinalizeBadPixels()
972{
973
974 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
975 {
976
977 MBadPixelsPix &bad = (*fBadPixels)[i];
978
979 if (bad.IsUncalibrated( MBadPixelsPix::kChargeIsPedestal))
980 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
981
982 if (bad.IsUncalibrated( MBadPixelsPix::kChargeErrNotValid ))
983 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
984
985 if (bad.IsUncalibrated( MBadPixelsPix::kChargeRelErrNotValid ))
986 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
987
988 if (bad.IsUncalibrated( MBadPixelsPix::kChargeSigmaNotValid ))
989 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
990
991 if (bad.IsUncalibrated( MBadPixelsPix::kMeanTimeInFirstBin ))
992 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
993
994 if (bad.IsUncalibrated( MBadPixelsPix::kMeanTimeInLast2Bins ))
995 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
996
997 if (bad.IsUncalibrated( MBadPixelsPix::kDeviatingNumPhes ))
998 bad.SetUnsuitable( MBadPixelsPix::kUnreliableRun );
999 }
1000}
1001
1002// ------------------------------------------------------------------------
1003//
1004//
1005void MCalibrationChargeCalc::FinalizeFFactorQECam()
1006{
1007
1008 MCalibrationChargePix &avpix = (MCalibrationChargePix&)fCam->GetAverageArea(0);
1009 MCalibrationQEPix &qepix = (MCalibrationQEPix&) fQECam->GetAverageArea(0);
1010
1011 const Float_t avphotonflux = avpix.GetPheFFactorMethod()
1012 / qepix.GetQEFFactor(fPulserColor)
1013 / fQECam->GetPlexiglassQE();
1014
1015 const Float_t avfluxrelvar = avpix.GetPheFFactorMethodRelVar()
1016 + qepix.GetQEFFactorRelVar(fPulserColor)
1017 + fQECam->GetPlexiglassQERelVar();
1018
1019 const UInt_t npixels = fGeom->GetNumPixels();
1020
1021 for (UInt_t i=0; i<npixels; i++)
1022 {
1023
1024 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1025 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1026
1027 if (!pix.IsFFactorMethodValid())
1028 {
1029 qepix.SetFFactorMethodValid(kFALSE,fPulserColor);
1030 continue;
1031 }
1032
1033 const Float_t photons = avphotonflux / fGeom->GetPixRatio(i);
1034 const Float_t qe = pix.GetPheFFactorMethod() / photons ;
1035
1036 if (!pix.CalcMeanFFactor( photons , avfluxrelvar ))
1037 {
1038 pix.SetFFactorMethodValid(kFALSE);
1039 qepix.SetFFactorMethodValid(kFALSE, fPulserColor);
1040 (*fBadPixels)[i].SetUncalibrated( MBadPixelsPix::kDeviatingNumPhes );
1041 }
1042
1043 const Float_t qerelvar = avfluxrelvar + pix.GetPheFFactorMethodRelVar();
1044
1045 qepix.SetQEFFactor ( qe , fPulserColor );
1046 qepix.SetQEFFactorVar ( qerelvar*qe*qe, fPulserColor );
1047 qepix.UpdateFFactorMethod();
1048 }
1049}
1050
1051// ------------------------------------------------------------------------
1052//
1053//
1054void MCalibrationChargeCalc::FinalizeBlindPixelQECam()
1055{
1056
1057 const UInt_t npixels = fGeom->GetNumPixels();
1058
1059 //
1060 // With the knowledge of the overall photon flux, calculate the
1061 // quantum efficiencies after the Blind Pixel and PIN Diode method
1062 //
1063 for (UInt_t i=0; i<npixels; i++)
1064 {
1065
1066 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1067
1068 if (!fBlindPixel)
1069 {
1070 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1071 continue;
1072 }
1073
1074 if (!fBlindPixel->IsFluxInsidePlexiglassAvailable())
1075 {
1076 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1077 continue;
1078 }
1079
1080 MBadPixelsPix &bad = (*fBadPixels)[i];
1081
1082 if (!bad.IsUnsuitable (MBadPixelsPix::kUnsuitableRun))
1083 {
1084 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1085 continue;
1086 }
1087
1088 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1089 MGeomPix &geo = (*fGeom)[i];
1090
1091 const Float_t conv = fBlindPixel->GetFluxInsidePlexiglass()
1092 * geo.GetA()
1093 / fQECam->GetPlexiglassQE()
1094 / pix.GetPheFFactorMethod();
1095
1096 const Float_t convrelvar = fBlindPixel->GetFluxInsidePlexiglassRelVar()
1097 + fQECam->GetPlexiglassQERelVar()
1098 + pix.GetPheFFactorMethodRelVar();
1099
1100 qepix.SetQEBlindPixel ( conv , fPulserColor );
1101 qepix.SetQEBlindPixelVar ( convrelvar * conv * conv, fPulserColor );
1102 qepix.UpdateBlindPixelMethod();
1103 }
1104}
1105
1106// ------------------------------------------------------------------------
1107//
1108//
1109void MCalibrationChargeCalc::FinalizePINDiodeQECam()
1110{
1111
1112 const UInt_t npixels = fGeom->GetNumPixels();
1113
1114 //
1115 // With the knowledge of the overall photon flux, calculate the
1116 // quantum efficiencies after the PIN Diode method
1117 //
1118 for (UInt_t i=0; i<npixels; i++)
1119 {
1120
1121 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1122
1123 if (!fPINDiode)
1124 {
1125 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1126 continue;
1127 }
1128
1129 if (!fPINDiode->IsFluxOutsidePlexiglassAvailable())
1130 {
1131 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1132 continue;
1133 }
1134
1135 MBadPixelsPix &bad = (*fBadPixels)[i];
1136
1137 if (!bad.IsUnsuitable (MBadPixelsPix::kUnsuitableRun))
1138 {
1139 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1140 continue;
1141 }
1142
1143 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1144 MGeomPix &geo = (*fGeom)[i];
1145
1146 const Float_t conv = fPINDiode->GetFluxOutsidePlexiglass() * geo.GetA() / pix.GetPheFFactorMethod();
1147 const Float_t convrelvar = fPINDiode->GetFluxOutsidePlexiglassRelVar() + pix.GetPheFFactorMethodRelVar();
1148
1149 qepix.SetQEPINDiode ( conv , fPulserColor );
1150 qepix.SetQEPINDiodeVar ( convrelvar * conv * conv, fPulserColor );
1151 qepix.UpdateBlindPixelMethod();
1152 }
1153}
1154
1155
1156// -----------------------------------------------------------------------
1157//
1158// - Finalize the pedestals
1159// - Do the quality checks
1160// - Calculate the reduced sigma
1161// - Calculate the F-Factor Method
1162//
1163Int_t MCalibrationChargeCalc::PostProcess()
1164{
1165
1166 if (GetNumExecutions()==0)
1167 return kFALSE;
1168
1169 //
1170 // loop over the pedestal events and check if we have calibration
1171 //
1172 Int_t nvalid = 0;
1173 Float_t avinnerped = 0.;
1174 Float_t avinnerprms = 0.;
1175 Int_t avinnernum = 0;
1176 Float_t avouterped = 0.;
1177 Float_t avouterprms = 0.;
1178 Int_t avouternum = 0;
1179
1180 for (Int_t pixid=0; pixid<fPedestals->GetSize(); pixid++)
1181 {
1182
1183 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[pixid];
1184 //
1185 // Check if the pixel has been excluded from the fits
1186 //
1187 if (pix.IsExcluded())
1188 continue;
1189
1190 MPedestalPix &ped = (*fPedestals)[pixid];
1191 MBadPixelsPix &bad = (*fBadPixels)[pixid];
1192
1193 if (fGeom->GetPixRatio(pixid) == 1.)
1194 {
1195 FinalizePedestals(ped,pix,avinnerped,avinnerprms);
1196 avinnernum++;
1197 }
1198 else
1199 {
1200 FinalizePedestals(ped,pix,avouterped,avouterprms);
1201 avouternum++;
1202 }
1203
1204 if (FinalizeCharges(pix,bad))
1205 nvalid++;
1206 }
1207
1208 //
1209 // The Michele check ...
1210 //
1211 if (nvalid == 0)
1212 {
1213 *fLog << err << GetDescriptor() << ": All pixels have non-valid calibration. "
1214 << "Did you forget to fill the histograms "
1215 << "(filling MHCalibrationChargeCam from MExtractedSignalCam using MFillH) ? " << endl;
1216 *fLog << err << GetDescriptor() << ": Or, maybe, you have used a pedestal run "
1217 << "instead of a calibration run " << endl;
1218 return kFALSE;
1219 }
1220
1221 for (UInt_t aidx=0; aidx<fGeom->GetNumAreas(); aidx++)
1222 {
1223
1224 FinalizeAvPedestals((MCalibrationChargePix&)fCam->GetAverageArea(aidx),
1225 avinnerped, avinnerprms,avinnernum);
1226 FinalizeCharges((MCalibrationChargePix&)fCam->GetAverageArea(aidx),
1227 fCam->GetAverageBadArea(aidx));
1228 }
1229
1230 for (UInt_t sector=0; sector<fGeom->GetNumSectors(); sector++)
1231 {
1232
1233 FinalizeAvPedestals((MCalibrationChargePix&)fCam->GetAverageSector(sector),
1234 avinnerped, avinnerprms,avinnernum);
1235 FinalizeCharges((MCalibrationChargePix&)fCam->GetAverageSector(sector),
1236 fCam->GetAverageBadSector(sector));
1237 }
1238
1239 //
1240 // Finalize Bad Pixels
1241 //
1242 FinalizeBadPixels();
1243
1244 //
1245 // Finalize F-Factor method
1246 //
1247 if (!FinalizeFFactorMethod())
1248 {
1249 *fLog << warn << "Could not calculate the photons flux from the F-Factor method " << endl;
1250 fCam->SetFFactorMethodValid(kFALSE);
1251 return kFALSE;
1252 }
1253 else
1254 fCam->SetFFactorMethodValid(kTRUE);
1255
1256 //
1257 // Finalize Blind Pixel
1258 //
1259 if (FinalizeBlindPixel())
1260 fQECam->SetBlindPixelMethodValid(kTRUE);
1261 else
1262 fQECam->SetBlindPixelMethodValid(kFALSE);
1263
1264 //
1265 // Finalize PIN Diode
1266 //
1267 if (FinalizePINDiode())
1268 fQECam->SetPINDiodeMethodValid(kTRUE);
1269 else
1270 fQECam->SetPINDiodeMethodValid(kFALSE);
1271
1272 //
1273 // Finalize QE Cam
1274 //
1275 FinalizeFFactorQECam();
1276 FinalizeBlindPixelQECam();
1277 FinalizePINDiodeQECam();
1278
1279 fCam ->SetReadyToSave();
1280 fQECam ->SetReadyToSave();
1281 fBadPixels->SetReadyToSave();
1282
1283 *fLog << inf << endl;
1284 *fLog << GetDescriptor() << ": Calibration statistics:" << endl;
1285 *fLog << dec << setfill(' ');
1286
1287 UInt_t countinner = 0;
1288 UInt_t countouter = 0;
1289 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1290 {
1291 MBadPixelsPix &bad = (*fBadPixels)[i];
1292 if (bad.IsOK())
1293 {
1294 if (fGeom->GetPixRatio(i) == 1.)
1295 countinner++;
1296 else
1297 countouter++;
1298 }
1299 }
1300
1301 *fLog << " " << setw(7) << "Successfully calibrated Pixels: "
1302 << "Inner: " << countinner << " Outer: " << countouter << endl;
1303
1304 PrintUnsuitable(MBadPixelsPix::kUnsuitableRun, "Bad Pixels: ");
1305 PrintUnsuitable(MBadPixelsPix::kUnreliableRun, "Unreliable Pixels: ");
1306
1307 *fLog << inf << endl;
1308 *fLog << GetDescriptor() << ": Errors statistics:" << endl;
1309
1310 PrintUncalibrated(MBadPixelsPix::kChargeIsPedestal,
1311 Form("%s%2.1f%s","Signal less than ",fChargeLimit," Pedestal RMS: "));
1312 PrintUncalibrated(MBadPixelsPix::kChargeErrNotValid,
1313 Form("%s%2.1f%s","Signal Error smaller than ",fChargeErrLimit,": "));
1314 PrintUncalibrated(MBadPixelsPix::kChargeRelErrNotValid,
1315 Form("%s%2.1f%s","Signal Error bigger than ",fChargeRelErrLimit," times Mean Signal: "));
1316 PrintUncalibrated(MBadPixelsPix::kChargeSigmaNotValid,
1317 "Signal Sigma smaller than Pedestal RMS: ");
1318 PrintUncalibrated(MBadPixelsPix::kLoGainSaturation,
1319 "Pixels with Low Gain Saturation: ");
1320 PrintUncalibrated(MBadPixelsPix::kMeanTimeInFirstBin,
1321 Form("%s%2.1f%s","Mean Abs. Arr. Time in First ",fTimeLowerLimit," Bin(s): "));
1322 PrintUncalibrated(MBadPixelsPix::kMeanTimeInLast2Bins,
1323 Form("%s%2.1f%s","Mean Abs. Arr. Time in Last ",fTimeUpperLimit," Bin(s): "));
1324 PrintUncalibrated(MBadPixelsPix::kHiGainOscillating,
1325 "Pixels with changing Hi Gain signal over time: ");
1326 PrintUncalibrated(MBadPixelsPix::kLoGainOscillating,
1327 "Pixels with changing Lo Gain signal over time: ");
1328 PrintUncalibrated(MBadPixelsPix::kDeviatingNumPhes,
1329 "Pixels with deviating number of phes: ");
1330 PrintUncalibrated(MBadPixelsPix::kHiGainNotFitted,
1331 "Pixels with unsuccesful Gauss fit to the Hi Gain: ");
1332 PrintUncalibrated(MBadPixelsPix::kLoGainNotFitted,
1333 "Pixels with unsuccesful Gauss fit to the Lo Gain: ");
1334
1335 return kTRUE;
1336}
1337
1338void MCalibrationChargeCalc::PrintUnsuitable(MBadPixelsPix::UnsuitableType_t typ, const char *text) const
1339{
1340
1341 UInt_t countinner = 0;
1342 UInt_t countouter = 0;
1343 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1344 {
1345 MBadPixelsPix &bad = (*fBadPixels)[i];
1346 if (bad.IsUnsuitable(typ))
1347 {
1348 if (fGeom->GetPixRatio(i) == 1.)
1349 countinner++;
1350 else
1351 countouter++;
1352 }
1353 }
1354
1355 *fLog << " " << setw(7) << text
1356 << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
1357}
1358
1359void MCalibrationChargeCalc::PrintUncalibrated(MBadPixelsPix::UncalibratedType_t typ, const char *text) const
1360{
1361
1362 UInt_t countinner = 0;
1363 UInt_t countouter = 0;
1364 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1365 {
1366 MBadPixelsPix &bad = (*fBadPixels)[i];
1367 if (bad.IsUncalibrated(typ))
1368 {
1369 if (fGeom->GetPixRatio(i) == 1.)
1370 countinner++;
1371 else
1372 countouter++;
1373 }
1374 }
1375
1376 *fLog << " " << setw(7) << text
1377 << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
1378}
1379
Note: See TracBrowser for help on using the repository browser.