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

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