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

Last change on this file since 3678 was 3678, checked in by gaug, 20 years ago
*** empty log message ***
File size: 46.4 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 << GetDesriptor() << ": Sigma of Fitted Charge: " << cal.GetMeanErr() << " is smaller than "
574 << fChargeErrLimit << " in Pixel " << cal.GetPixId() << endl;
575 bad.SetUncalibrated( MBadPixelsPix::kChargeErrNotValid );
576 }
577
578 if (cal.GetMean() < fChargeRelErrLimit*cal.GetMeanErr())
579 {
580 *fLog << warn << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 << GetDesriptor() << ": 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 MCalibrationChargePix &avpix = (MCalibrationChargePix&)fCam->GetAverageArea(0);
955 MCalibrationQEPix &qepix = (MCalibrationQEPix&) fQECam->GetAverageArea(0);
956
957 const Float_t avphotonflux = avpix.GetPheFFactorMethod()
958 / qepix.GetQEFFactor(fPulserColor)
959 / fQECam->GetPlexiglassQE();
960
961 const Float_t avfluxrelvar = avpix.GetPheFFactorMethodRelVar()
962 + qepix.GetQEFFactorRelVar(fPulserColor)
963 + fQECam->GetPlexiglassQERelVar();
964 //
965 // Third loop: With the knowledge of the overall photon flux, calculate the total
966 // F-Factor of the whole readout per pixel and set the quantum efficiencies
967 // after the F-Factor method.
968 //
969 for (UInt_t i=0; i<npixels; i++)
970 {
971
972 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
973 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
974
975 if (!pix.IsFFactorMethodValid())
976 {
977 qepix.SetFFactorMethodValid(kFALSE,fPulserColor);
978 continue;
979 }
980
981 const Float_t photons = avphotonflux / fGeom->GetPixRatio(i);
982 const Float_t conv = photons / pix.GetPheFFactorMethod();
983
984 if (!pix.CalcMeanFFactor( photons , avfluxrelvar ))
985 {
986 pix.SetFFactorMethodValid(kFALSE);
987 qepix.SetFFactorMethodValid(kFALSE, fPulserColor);
988 (*fBadPixels)[i].SetUncalibrated( MBadPixelsPix::kDeviatingNumPhes );
989 }
990
991 const Float_t convrelvar = avfluxrelvar + pix.GetPheFFactorMethodRelVar();
992
993 qepix.SetQEFFactor ( conv , fPulserColor );
994 qepix.SetQEFFactorVar ( convrelvar * conv * conv, fPulserColor );
995 }
996
997
998 return kTRUE;
999}
1000
1001// ----------------------------------------------------------------------
1002//
1003// Sets all pixels to MBadPixelsPix::kUnsuitableRun, if following flags are set:
1004// - MBadPixelsPix::kChargeIsPedestal
1005// - MBadPixelsPix::kChargeErrNotValid
1006// - MBadPixelsPix::kChargeRelErrNotValid
1007// - MBadPixelsPix::kChargeSigmaNotValid
1008// - MBadPixelsPix::kMeanTimeInFirstBin
1009// - MBadPixelsPix::kMeanTimeInLast2Bins
1010//
1011// Sets all pixels to MBadPixelsPix::kUnreliableRun, if following flags are set:
1012// - MBadPixelsPix::kDeviatingNumPhes
1013//
1014void MCalibrationChargeCalc::FinalizeBadPixels()
1015{
1016
1017 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1018 {
1019
1020 MBadPixelsPix &bad = (*fBadPixels)[i];
1021
1022 if (bad.IsUncalibrated( MBadPixelsPix::kChargeIsPedestal))
1023 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
1024
1025 if (bad.IsUncalibrated( MBadPixelsPix::kChargeErrNotValid ))
1026 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
1027
1028 if (bad.IsUncalibrated( MBadPixelsPix::kChargeRelErrNotValid ))
1029 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
1030
1031 if (bad.IsUncalibrated( MBadPixelsPix::kChargeSigmaNotValid ))
1032 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
1033
1034 if (bad.IsUncalibrated( MBadPixelsPix::kMeanTimeInFirstBin ))
1035 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
1036
1037 if (bad.IsUncalibrated( MBadPixelsPix::kMeanTimeInLast2Bins ))
1038 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
1039
1040 if (bad.IsUncalibrated( MBadPixelsPix::kDeviatingNumPhes ))
1041 bad.SetUnsuitable( MBadPixelsPix::kUnreliableRun );
1042 }
1043}
1044
1045// ------------------------------------------------------------------------
1046//
1047//
1048void MCalibrationChargeCalc::FinalizeBlindPixelQECam()
1049{
1050
1051 const UInt_t npixels = fGeom->GetNumPixels();
1052
1053 //
1054 // With the knowledge of the overall photon flux, calculate the
1055 // quantum efficiencies after the Blind Pixel and PIN Diode method
1056 //
1057 for (UInt_t i=0; i<npixels; i++)
1058 {
1059
1060 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1061
1062 if (!fBlindPixel)
1063 {
1064 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1065 continue;
1066 }
1067
1068 if (!fBlindPixel->IsFluxInsidePlexiglassAvailable())
1069 {
1070 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1071 continue;
1072 }
1073
1074 MBadPixelsPix &bad = (*fBadPixels)[i];
1075
1076 if (!bad.IsUnsuitable (MBadPixelsPix::kUnsuitableRun))
1077 {
1078 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1079 continue;
1080 }
1081
1082 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1083 MGeomPix &geo = (*fGeom)[i];
1084
1085 const Float_t conv = fBlindPixel->GetFluxInsidePlexiglass()
1086 * geo.GetA()
1087 / fQECam->GetPlexiglassQE()
1088 / pix.GetPheFFactorMethod();
1089
1090 const Float_t convrelvar = fBlindPixel->GetFluxInsidePlexiglassRelVar()
1091 + fQECam->GetPlexiglassQERelVar()
1092 + pix.GetPheFFactorMethodRelVar();
1093
1094 qepix.SetQEBlindPixel ( conv , fPulserColor );
1095 qepix.SetQEBlindPixelVar ( convrelvar * conv * conv, fPulserColor );
1096 }
1097}
1098
1099// ------------------------------------------------------------------------
1100//
1101//
1102void MCalibrationChargeCalc::FinalizePINDiodeQECam()
1103{
1104
1105 const UInt_t npixels = fGeom->GetNumPixels();
1106
1107 //
1108 // With the knowledge of the overall photon flux, calculate the
1109 // quantum efficiencies after the PIN Diode method
1110 //
1111 for (UInt_t i=0; i<npixels; i++)
1112 {
1113
1114 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1115
1116 if (!fPINDiode)
1117 {
1118 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1119 continue;
1120 }
1121
1122 if (!fPINDiode->IsFluxOutsidePlexiglassAvailable())
1123 {
1124 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1125 continue;
1126 }
1127
1128 MBadPixelsPix &bad = (*fBadPixels)[i];
1129
1130 if (!bad.IsUnsuitable (MBadPixelsPix::kUnsuitableRun))
1131 {
1132 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1133 continue;
1134 }
1135
1136 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1137 MGeomPix &geo = (*fGeom)[i];
1138
1139 const Float_t conv = fPINDiode->GetFluxOutsidePlexiglass() * geo.GetA() / pix.GetPheFFactorMethod();
1140 const Float_t convrelvar = fPINDiode->GetFluxOutsidePlexiglassRelVar() + pix.GetPheFFactorMethodRelVar();
1141
1142 qepix.SetQEPINDiode ( conv , fPulserColor );
1143 qepix.SetQEPINDiodeVar ( convrelvar * conv * conv, fPulserColor );
1144 }
1145}
1146
1147
1148// -----------------------------------------------------------------------
1149//
1150// - Finalize the pedestals
1151// - Do the quality checks
1152// - Calculate the reduced sigma
1153// - Calculate the F-Factor Method
1154//
1155Int_t MCalibrationChargeCalc::PostProcess()
1156{
1157
1158 if (GetNumExecutions()==0)
1159 return kFALSE;
1160
1161 //
1162 // loop over the pedestal events and check if we have calibration
1163 //
1164 Int_t nvalid = 0;
1165 Float_t avinnerped = 0.;
1166 Float_t avinnerprms = 0.;
1167 Int_t avinnernum = 0;
1168 Float_t avouterped = 0.;
1169 Float_t avouterprms = 0.;
1170 Int_t avouternum = 0;
1171
1172 for (Int_t pixid=0; pixid<fPedestals->GetSize(); pixid++)
1173 {
1174
1175 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[pixid];
1176 //
1177 // Check if the pixel has been excluded from the fits
1178 //
1179 if (pix.IsExcluded())
1180 continue;
1181
1182 MPedestalPix &ped = (*fPedestals)[pixid];
1183 MBadPixelsPix &bad = (*fBadPixels)[pixid];
1184
1185 if (fGeom->GetPixRatio(pixid) == 1.)
1186 {
1187 FinalizePedestals(ped,pix,avinnerped,avinnerprms);
1188 avinnernum++;
1189 }
1190 else
1191 {
1192 FinalizePedestals(ped,pix,avouterped,avouterprms);
1193 avouternum++;
1194 }
1195
1196 if (FinalizeCharges(pix,bad))
1197 nvalid++;
1198 }
1199
1200 //
1201 // The Michele check ...
1202 //
1203 if (nvalid == 0)
1204 {
1205 *fLog << err << GetDescriptor() << ": All pixels have non-valid calibration. "
1206 << "Did you forget to fill the histograms "
1207 << "(filling MHCalibrationChargeCam from MExtractedSignalCam using MFillH) ? " << endl;
1208 *fLog << err << GetDescriptor() << ": Or, maybe, you have used a pedestal run "
1209 << "instead of a calibration run " << endl;
1210 return kFALSE;
1211 }
1212
1213 for (UInt_t aidx=0; aidx<fGeom->GetNumAreas(); aidx++)
1214 {
1215
1216 FinalizeAvPedestals((MCalibrationChargePix&)fCam->GetAverageArea(aidx),
1217 avinnerped, avinnerprms,avinnernum);
1218 FinalizeCharges((MCalibrationChargePix&)fCam->GetAverageArea(aidx),
1219 fCam->GetAverageBadArea(aidx));
1220 }
1221
1222 for (UInt_t sector=0; sector<fGeom->GetNumSectors(); sector++)
1223 {
1224
1225 FinalizeAvPedestals((MCalibrationChargePix&)fCam->GetAverageSector(sector),
1226 avinnerped, avinnerprms,avinnernum);
1227 FinalizeCharges((MCalibrationChargePix&)fCam->GetAverageSector(sector),
1228 fCam->GetAverageBadSector(sector));
1229 }
1230
1231 //
1232 // Finalize Bad Pixels
1233 //
1234 FinalizeBadPixels();
1235
1236 //
1237 // Finalize F-Factor method
1238 //
1239 if (!FinalizeFFactorMethod())
1240 {
1241 *fLog << warn << "Could not calculate the photons flux from the F-Factor method " << endl;
1242 fCam->SetFFactorMethodValid(kFALSE);
1243 return kFALSE;
1244 }
1245 else
1246 fCam->SetFFactorMethodValid(kTRUE);
1247
1248 //
1249 // Finalize Blind Pixel
1250 //
1251 if (FinalizeBlindPixel())
1252 fQECam->SetBlindPixelMethodValid(kTRUE);
1253 else
1254 fQECam->SetBlindPixelMethodValid(kFALSE);
1255
1256 //
1257 // Finalize PIN Diode
1258 //
1259 if (FinalizePINDiode())
1260 fQECam->SetPINDiodeMethodValid(kTRUE);
1261 else
1262 fQECam->SetPINDiodeMethodValid(kFALSE);
1263
1264 //
1265 // Finalize QE Cam
1266 //
1267 FinalizeBlindPixelQECam();
1268 FinalizePINDiodeQECam();
1269
1270 fCam ->SetReadyToSave();
1271 fQECam ->SetReadyToSave();
1272 fBadPixels->SetReadyToSave();
1273
1274 *fLog << inf << endl;
1275 *fLog << GetDescriptor() << ": Calibration statistics:" << endl;
1276 *fLog << dec << setfill(' ');
1277
1278 UInt_t countinner = 0;
1279 UInt_t countouter = 0;
1280 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1281 {
1282 MBadPixelsPix &bad = (*fBadPixels)[i];
1283 if (bad.IsOK())
1284 {
1285 if (fGeom->GetPixRatio(i) == 1.)
1286 countinner++;
1287 else
1288 countouter++;
1289 }
1290 }
1291
1292 *fLog << " " << setw(7) << "Successfully calibrated Pixels: "
1293 << "Inner: " << countinner << " Outer: " << countouter << endl;
1294
1295 PrintUnsuitable(MBadPixelsPix::kUnsuitableRun, "Bad Pixels: ");
1296 PrintUnsuitable(MBadPixelsPix::kUnreliableRun, "Unreliable Pixels: ");
1297
1298 *fLog << inf << endl;
1299 *fLog << GetDescriptor() << ": Errors statistics:" << endl;
1300
1301 PrintUncalibrated(MBadPixelsPix::kChargeIsPedestal,
1302 Form("%s%2.1f%s","Signal less than ",fChargeLimit," Pedestal RMS: "));
1303 PrintUncalibrated(MBadPixelsPix::kChargeErrNotValid,
1304 Form("%s%2.1f%s","Signal Error smaller than ",fChargeErrLimit,": "));
1305 PrintUncalibrated(MBadPixelsPix::kChargeRelErrNotValid,
1306 Form("%s%2.1f%s","Signal Error bigger than ",fChargeRelErrLimit," times Mean Signal: "));
1307 PrintUncalibrated(MBadPixelsPix::kChargeSigmaNotValid,
1308 "Signal Sigma smaller than Pedestal RMS: ");
1309 PrintUncalibrated(MBadPixelsPix::kLoGainSaturation,
1310 "Pixels with Low Gain Saturation: ");
1311 PrintUncalibrated(MBadPixelsPix::kMeanTimeInFirstBin,
1312 Form("%s%2.1f%s","Mean Abs. Arr. Time in First ",fTimeLowerLimit," Bin(s): "));
1313 PrintUncalibrated(MBadPixelsPix::kMeanTimeInLast2Bins,
1314 Form("%s%2.1f%s","Mean Abs. Arr. Time in Last ",fTimeUpperLimit," Bin(s): "));
1315 PrintUncalibrated(MBadPixelsPix::kHiGainOscillating,
1316 "Pixels with changing Hi Gain signal over time: ");
1317 PrintUncalibrated(MBadPixelsPix::kLoGainOscillating,
1318 "Pixels with changing Lo Gain signal over time: ");
1319 PrintUncalibrated(MBadPixelsPix::kDeviatingNumPhes,
1320 "Pixels with deviating number of phes: ");
1321 PrintUncalibrated(MBadPixelsPix::kHiGainNotFitted,
1322 "Pixels with unsuccesful Gauss fit to the Hi Gain: ");
1323 PrintUncalibrated(MBadPixelsPix::kLoGainNotFitted,
1324 "Pixels with unsuccesful Gauss fit to the Lo Gain: ");
1325
1326 return kTRUE;
1327}
1328
1329void MCalibrationChargeCalc::PrintUnsuitable(MBadPixelsPix::UnsuitableType_t typ, const char *text) const
1330{
1331
1332 UInt_t countinner = 0;
1333 UInt_t countouter = 0;
1334 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1335 {
1336 MBadPixelsPix &bad = (*fBadPixels)[i];
1337 if (bad.IsUnsuitable(typ))
1338 {
1339 if (fGeom->GetPixRatio(i) == 1.)
1340 countinner++;
1341 else
1342 countouter++;
1343 }
1344 }
1345
1346 *fLog << " " << setw(7) << text
1347 << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
1348}
1349
1350void MCalibrationChargeCalc::PrintUncalibrated(MBadPixelsPix::UncalibratedType_t typ, const char *text) const
1351{
1352
1353 UInt_t countinner = 0;
1354 UInt_t countouter = 0;
1355 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1356 {
1357 MBadPixelsPix &bad = (*fBadPixels)[i];
1358 if (bad.IsUncalibrated(typ))
1359 {
1360 if (fGeom->GetPixRatio(i) == 1.)
1361 countinner++;
1362 else
1363 countouter++;
1364 }
1365 }
1366
1367 *fLog << " " << setw(7) << text
1368 << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
1369}
1370
Note: See TracBrowser for help on using the repository browser.