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

Last change on this file since 4541 was 4541, checked in by gaug, 20 years ago
*** empty log message ***
File size: 62.2 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Markus Gaug 02/2004 <mailto:markus@ifae.es>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MCalibrationChargeCalc
28//
29// Task to calculate the calibration conversion factors and quantum efficiencies
30// from the fit results to the summed FADC slice distributions delivered by
31// MCalibrationChargeCam, MCalibrationChargePix, MCalibrationChargeBlindPix and
32// MCalibrationChargePINDiode, calculated and filled by MHCalibrationChargeCam,
33// MHCalibrationChargePix, MHCalibrationChargeBlindPix and MHCalibrationChargePINDiode.
34//
35// PreProcess(): Initialize pointers to MCalibrationChargeCam, MCalibrationChargeBlindPix
36// MCalibrationChargePINDiode and MCalibrationQECam
37//
38// Initialize pulser light wavelength
39//
40// ReInit(): MCalibrationCam::InitSize(NumPixels) is called from MGeomApply (which allocates
41// memory in a TClonesArray of type MCalibrationChargePix)
42// Initializes pointer to MBadPixelsCam
43//
44// Process(): Nothing to be done, histograms getting filled by MHCalibrationChargeCam
45//
46// PostProcess(): - FinalizePedestals()
47// - FinalizeCharges()
48// - FinalizeFFactorMethod()
49// - FinalizeBadPixels()
50// - FinalizeBlindPixel()
51// - FinalizePINDiode()
52// - FinalizeFFactorQECam()
53// - FinalizeBlindPixelQECam()
54// - FinalizePINDiodeQECam()
55//
56// Input Containers:
57// MCalibrationChargeCam
58// MCalibrationChargeBlindPix
59// MCalibrationChargePINDiode
60// MCalibrationQECam
61// MPedestalCam
62// MBadPixelsCam
63// MGeomCam
64// MTime
65//
66// Output Containers:
67// MCalibrationChargeCam
68// MCalibrationChargeBlindPix
69// MCalibrationChargePINDiode
70// MCalibrationQECam
71// MBadPixelsCam
72//
73//
74// Preliminary description of the calibration in photons (email from 12/02/04)
75//
76// Why calibrating in photons:
77// ===========================
78//
79// At the Barcelona meeting in 2002, we decided to calibrate the camera in
80// photons. This for the following reasons:
81//
82// * The physical quantity arriving at the camera are photons. This is
83// the direct physical information from the air shower. The photons
84// have a flux and a spectrum.
85//
86// * The photon fluxes depend mostly on the shower energy (with
87// corrections deriving from the observation conditions), while the photon
88// spectra depend mostly on the observation conditions: zenith angle,
89// quality of the air, also the impact parameter of the shower.
90//
91// * The photomultiplier, in turn, has different response properties
92// (quantum efficiencies) for photons of different colour. (Moreover,
93// different pixels have slightly different quantum efficiencies).
94// The resulting number of photo-electrons is then amplified (linearly)
95// with respect to the photo-electron flux.
96//
97// * In the ideal case, one would like to disentagle the effects
98// of the observation conditions from the primary particle energy (which
99// one likes to measure). To do so, one needs:
100//
101// 1) A reliable calibration relating the FADC counts to the photo-electron
102// flux -> This is accomplished with the F-Factor method.
103//
104// 2) A reliable calibration of the wavelength-dependent quantum efficiency
105// -> This is accomplished with the combination of the three methods,
106// together with QE-measurements performed by David in order to do
107// the interpolation.
108//
109// 3) A reliable calibration of the observation conditions. This means:
110// - Tracing the atmospheric conditions -> LIDAR
111// - Tracing the observation zenith angle -> Drive System
112//
113// 4) Some knowlegde about the impact parameter:
114// - This is the only part which cannot be accomplished well with a
115// single telescope. We would thus need to convolute the spectrum
116// over the distribution of impact parameters.
117//
118//
119// How an ideal calibration would look like:
120// =========================================
121//
122// We know from the combined PIN-Diode and Blind-Pixel Method the response of
123// each pixel to well-measured light fluxes in three representative
124// wavelengths (green, blue, UV). We also know the response to these light
125// fluxes in photo-electrons. Thus, we can derive:
126//
127// - conversion factors to photo-electrons
128// - conversion factors to photons in three wavelengths.
129//
130// Together with David's measurements and some MC-simulation, we should be
131// able to derive tables for typical Cherenkov-photon spectra - convoluted
132// with the impact parameters and depending on the athmospheric conditions
133// and the zenith angle (the "outer parameters").
134//
135// From these tables we can create "calibration tables" containing some
136// effective quantum efficiency depending on these outer parameters and which
137// are different for each pixel.
138//
139// In an ideal MCalibrate, one would thus have to convert first the FADC
140// slices to Photo-electrons and then, depending on the outer parameters,
141// look up the effective quantum efficiency and get the mean number of
142// photons which is then used for the further analysis.
143//
144// How the (first) MAGIC calibration should look like:
145// ===================================================
146//
147// For the moment, we have only one reliable calibration method, although
148// with very large systematic errors. This is the F-Factor method. Knowing
149// that the light is uniform over the whole camera (which I would not at all
150// guarantee in the case of the CT1 pulser), one could in principle already
151// perform a relative calibration of the quantum efficiencies in the UV.
152// However, the spread in QE at UV is about 10-15% (according to the plot
153// that Abelardo sent around last time. The spread in photo-electrons is 15%
154// for the inner pixels, but much larger (40%) for the outer ones.
155//
156// I'm not sure if we can already say that we have measured the relative
157// difference in quantum efficiency for the inner pixels and produce a first
158// QE-table for each pixel. To so, I would rather check in other wavelengths
159// (which we can do in about one-two weeks when the optical transmission of
160// the calibration trigger is installed).
161//
162// Thus, for the moment being, I would join Thomas proposal to calibrate in
163// photo-electrons and apply one stupid average quantum efficiency for all
164// pixels. This keeping in mind that we will have much preciser information
165// in about one to two weeks.
166//
167//
168// What MCalibrate should calculate and what should be stored:
169// ===========================================================
170//
171// It is clear that in the end, MCerPhotEvt will store photons.
172// MCalibrationCam stores the conversionfactors to photo-electrons and also
173// some tables of how to apply the conversion to photons, given the outer
174// parameters. This is not yet implemented and not even discussed.
175//
176// To start, I would suggest that we define the "average quantum efficiency"
177// (maybe something like 25+-3%) and apply them equally to all
178// photo-electrons. Later, this average factor can be easily replaced by a
179// pixel-dependent factor and later by a (pixel-dependent) table.
180//
181//
182//
183//////////////////////////////////////////////////////////////////////////////
184#include "MCalibrationChargeCalc.h"
185
186#include <TSystem.h>
187#include <TH1.h>
188#include <TF1.h>
189
190#include "MLog.h"
191#include "MLogManip.h"
192
193#include "MParList.h"
194
195#include "MRawRunHeader.h"
196#include "MRawEvtPixelIter.h"
197
198#include "MGeomCam.h"
199#include "MGeomPix.h"
200#include "MHCamera.h"
201
202#include "MPedestalCam.h"
203#include "MPedestalPix.h"
204
205#include "MCalibrationChargeCam.h"
206#include "MCalibrationChargePix.h"
207#include "MCalibrationChargePINDiode.h"
208#include "MCalibrationChargeBlindPix.h"
209#include "MCalibrationChargeBlindCam.h"
210
211#include "MExtractedSignalCam.h"
212#include "MExtractedSignalPix.h"
213#include "MExtractedSignalBlindPixel.h"
214#include "MExtractedSignalPINDiode.h"
215
216#include "MBadPixelsCam.h"
217#include "MBadPixelsPix.h"
218
219#include "MCalibrationQECam.h"
220#include "MCalibrationQEPix.h"
221
222#include "MCalibrationCam.h"
223
224ClassImp(MCalibrationChargeCalc);
225
226using namespace std;
227
228const Float_t MCalibrationChargeCalc::fgChargeLimit = 2.5;
229const Float_t MCalibrationChargeCalc::fgChargeErrLimit = 0.;
230const Float_t MCalibrationChargeCalc::fgChargeRelErrLimit = 1.;
231const Float_t MCalibrationChargeCalc::fgLambdaErrLimit = 0.2;
232const Float_t MCalibrationChargeCalc::fgLambdaCheckLimit = 0.5;
233const Float_t MCalibrationChargeCalc::fgPheErrLimit = 3.5;
234const Float_t MCalibrationChargeCalc::fgFFactorErrLimit = 4.5;
235// --------------------------------------------------------------------------
236//
237// Default constructor.
238//
239// Sets the pointer to fQECam and fGeom to NULL
240//
241// Calls AddToBranchList for:
242// - MRawEvtData.fHiGainPixId
243// - MRawEvtData.fLoGainPixId
244// - MRawEvtData.fHiGainFadcSamples
245// - MRawEvtData.fLoGainFadcSamples
246//
247// Initializes:
248// - fChargeLimit to fgChargeLimit
249// - fChargeErrLimit to fgChargeErrLimit
250// - fChargeRelErrLimit to fgChargeRelErrLimit
251// - fFFactorErrLimit to fgFFactorErrLimit
252// - fLambdaCheckLimit to fgLambdaCheckLimit
253// - fLambdaErrLimit to fgLambdaErrLimit
254// - fPheErrLimit to fgPheErrLimit
255// - fPulserColor to MCalibrationCam::kCT1
256// - fOutputPath to "."
257// - fOutputFile to "ChargeCalibStat.txt"
258// - flag debug to kFALSE
259//
260// Calls:
261// - Clear()
262//
263MCalibrationChargeCalc::MCalibrationChargeCalc(const char *name, const char *title)
264 : fQECam(NULL), fGeom(NULL)
265{
266
267 fName = name ? name : "MCalibrationChargeCalc";
268 fTitle = title ? title : "Task to calculate the calibration constants and MCalibrationCam ";
269
270 AddToBranchList("MRawEvtData.fHiGainPixId");
271 AddToBranchList("MRawEvtData.fLoGainPixId");
272 AddToBranchList("MRawEvtData.fHiGainFadcSamples");
273 AddToBranchList("MRawEvtData.fLoGainFadcSamples");
274
275 SetChargeLimit ();
276 SetChargeErrLimit ();
277 SetChargeRelErrLimit ();
278 SetFFactorErrLimit ();
279 SetLambdaCheckLimit ();
280 SetLambdaErrLimit ();
281 SetPheErrLimit ();
282 SetOutputPath ();
283 SetOutputFile ();
284 SetDebug ( kFALSE );
285
286 Clear();
287
288}
289
290// --------------------------------------------------------------------------
291//
292// Sets:
293// - all variables to 0.,
294// - all flags to kFALSE
295// - all pointers to NULL
296// - the pulser colour to kNONE
297// - fBlindPixelFlags to 0
298// - fPINDiodeFlags to 0
299//
300void MCalibrationChargeCalc::Clear(const Option_t *o)
301{
302
303 fNumHiGainSamples = 0.;
304 fNumLoGainSamples = 0.;
305 fSqrtHiGainSamples = 0.;
306 fSqrtLoGainSamples = 0.;
307 fNumInnerFFactorMethodUsed = 0;
308
309 fBadPixels = NULL;
310 fCam = NULL;
311 fBlindPixel = NULL;
312 fBlindCam = NULL;
313 fPINDiode = NULL;
314 fPedestals = NULL;
315
316 SetPulserColor ( MCalibrationCam::kNONE );
317
318 fBlindPixelFlags.Set(0);
319 fPINDiodeFlags .Set(0);
320 fResultFlags .Set(0);
321}
322
323
324// -----------------------------------------------------------------------------------
325//
326// The following container are searched for and execution aborted if not in MParList:
327// - MPedestalCam
328//
329// The following containers are searched and created if they were not found:
330//
331// - MCalibrationQECam
332// - MBadPixelsCam
333//
334Int_t MCalibrationChargeCalc::PreProcess(MParList *pList)
335{
336
337 //
338 // Containers that have to be there.
339 //
340 fPedestals = (MPedestalCam*)pList->FindObject("MPedestalCam");
341 if (!fPedestals)
342 {
343 *fLog << err << "MPedestalCam not found... aborting" << endl;
344 return kFALSE;
345 }
346
347 //
348 // Containers that are created in case that they are not there.
349 //
350 fQECam = (MCalibrationQECam*)pList->FindCreateObj("MCalibrationQECam");
351 if (!fQECam)
352 {
353 *fLog << err << "Cannot find nor create MCalibrationQECam... aborting" << endl;
354 return kFALSE;
355 }
356
357 fBadPixels = (MBadPixelsCam*)pList->FindCreateObj("MBadPixelsCam");
358 if (!fBadPixels)
359 {
360 *fLog << err << "Could not find or create MBadPixelsCam ... aborting." << endl;
361 return kFALSE;
362 }
363
364
365 //
366 // Check the pulser colour --> FIXME: this solution is only valid until the arrival of the DM's
367 //
368 if (fPulserColor == MCalibrationCam::kNONE)
369 {
370 *fLog << endl;
371 *fLog << err << GetDescriptor()
372 << ": No Pulser colour has been chosen. Since the installation of the IFAE pulser box,"
373 << " you HAVE to provide the LEDs colour, otherwise there is no calibration. " << endl;
374 *fLog << "See e.g. the macro calibration.C " << endl;
375 return kFALSE;
376 }
377
378 return kTRUE;
379}
380
381
382// --------------------------------------------------------------------------
383//
384// Search for the following input containers and abort if not existing:
385// - MGeomCam
386// - MCalibrationChargeCam
387//
388// Search for the following input containers and give a warning if not existing:
389// - MCalibrationChargeBlindPix
390// - MCalibrationChargePINDiode
391//
392// It retrieves the following variables from MCalibrationChargeCam:
393//
394// - fNumHiGainSamples
395// - fNumLoGainSamples
396//
397// It defines the PixId of every pixel in:
398//
399// - MCalibrationChargeCam
400// - MCalibrationQECam
401//
402// It sets all pixels in excluded which have the flag fBadBixelsPix::IsBad() set in:
403//
404// - MCalibrationChargePix
405// - MCalibrationQEPix
406//
407// Sets the pulser colour and tests if it has not changed w.r.t. fPulserColor in:
408//
409// - MCalibrationChargeCam
410// - MCalibrationChargeBlindPix (if existing)
411// - MCalibrationChargePINDiode (if existing)
412//
413Bool_t MCalibrationChargeCalc::ReInit(MParList *pList )
414{
415
416 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
417 if (!fGeom)
418 {
419 *fLog << err << "No MGeomCam found... aborting." << endl;
420 return kFALSE;
421 }
422
423 fCam = (MCalibrationChargeCam*)pList->FindObject("MCalibrationChargeCam");
424 if (!fCam)
425 {
426 *fLog << err << "Cannot find MCalibrationChargeCam... aborting" << endl;
427 *fLog << err << "Maybe you forget to call an MFillH for the MHCalibrationChargeCam before..." << endl;
428 return kFALSE;
429 }
430
431 //
432 // Optional Containers
433 //
434 fBlindPixel = (MCalibrationChargeBlindPix*)pList->FindObject("MCalibrationChargeBlindPix");
435 if (!fBlindPixel)
436 {
437 fBlindCam = (MCalibrationChargeBlindCam*)pList->FindObject("MCalibrationChargeBlindCam");
438 if (!fBlindCam)
439 {
440 *fLog << endl;
441 *fLog << warn << GetDescriptor()
442 << ": MCalibrationChargeBlindPix nor MCalibrationChargeBlindCam "
443 << " found... no Blind Pixel method! " << endl;
444 }
445 }
446
447 fPINDiode = (MCalibrationChargePINDiode*)pList->FindObject("MCalibrationChargePINDiode");
448 if (!fPINDiode)
449 {
450 *fLog << endl;
451 *fLog << warn << GetDescriptor()
452 << ": MCalibrationChargePINDiode not found... no PIN Diode method! " << endl;
453 }
454
455
456 //
457 // Initialize the pulser colours
458 //
459 if (fCam->GetPulserColor() == MCalibrationCam::kNONE)
460 {
461 fCam->SetPulserColor( fPulserColor );
462
463 if (fBlindPixel)
464 fBlindPixel->SetColor( fPulserColor );
465
466 if (fBlindCam)
467 fBlindCam->SetColor( fPulserColor );
468
469 if (fPINDiode)
470 fPINDiode->SetColor( fPulserColor );
471 }
472
473 if (fPulserColor != fCam->GetPulserColor())
474 {
475 *fLog << err << GetDescriptor()
476 << ": Pulser colour has changed w.r.t. last file in MCalibrationChargeCam" << endl;
477 *fLog << err << "This feature is not yet implemented, sorry ... aborting " << endl;
478 return kFALSE;
479 }
480
481 if (fBlindPixel)
482 if (fPulserColor != fBlindPixel->GetColor())
483 {
484 *fLog << err << GetDescriptor()
485 << ": Pulser colour has changed w.r.t. last file in MCalibrationChargeBlindPix." << endl;
486 *fLog << err << "This feature is not yet implemented, sorry ... aborting " << endl;
487 return kFALSE;
488 }
489
490 if (fBlindCam)
491 if (fPulserColor != fBlindCam->GetColor())
492 {
493 *fLog << err << GetDescriptor()
494 << ": Pulser colour has changed w.r.t. last file in MCalibrationChargeBlindCam." << endl;
495 *fLog << err << "This feature is not yet implemented, sorry ... aborting " << endl;
496 return kFALSE;
497 }
498
499 if (fPINDiode)
500 if (fPulserColor != fPINDiode->GetColor())
501 {
502 *fLog << err << GetDescriptor()
503 << ": Pulser colour has changed w.r.t. last file in MCalibrationChargePINDiode." << endl;
504 *fLog << err << "This feature is not yet implemented, sorry ... aborting " << endl;
505 return kFALSE;
506 }
507
508
509 fNumHiGainSamples = fCam->GetNumHiGainFADCSlices();
510 fNumLoGainSamples = fCam->GetNumLoGainFADCSlices();
511
512 fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
513 fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples);
514
515 UInt_t npixels = fGeom->GetNumPixels();
516
517 for (UInt_t i=0; i<npixels; i++)
518 {
519
520 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam) [i];
521 MCalibrationQEPix &pqe = (MCalibrationQEPix&) (*fQECam)[i];
522 MBadPixelsPix &bad = (*fBadPixels)[i];
523
524 pix.SetPixId(i);
525 pqe.SetPixId(i);
526
527 if (bad.IsBad())
528 {
529 pix.SetExcluded();
530 pqe.SetExcluded();
531 continue;
532 }
533
534 if (IsDebug())
535 pix.SetDebug();
536 }
537
538 return kTRUE;
539}
540
541// ----------------------------------------------------------------------------------
542//
543// Nothing to be done in Process, but have a look at MHCalibrationChargeCam, instead
544//
545Int_t MCalibrationChargeCalc::Process()
546{
547 return kTRUE;
548}
549
550// -----------------------------------------------------------------------
551//
552// Return if number of executions is null.
553//
554// First loop over pixels, average areas and sectors, call:
555// - FinalizePedestals()
556// - FinalizeCharges()
557// for every entry. Count number of valid pixels in loop and return kFALSE
558// if there are none (the "Michele check").
559//
560// Call FinalizeBadPixels()
561//
562// Call FinalizeFFactorMethod() (second and third loop over pixels and areas)
563//
564// Call FinalizeBlindPixel()
565// Call FinalizePINDiode()
566//
567// Call FinalizeFFactorQECam() (fourth loop over pixels and areas)
568// Call FinalizeBlindPixelQECam() (fifth loop over pixels and areas)
569// Call FinalizePINDiodeQECam() (sixth loop over pixels and areas)
570//
571// Call FinalizeUnsuitablePixels()
572//
573// Call MParContainer::SetReadyToSave() for fCam, fQECam, fBadPixels and
574// fBlindPixel and fPINDiode if they exist
575//
576// Print out some statistics
577//
578Int_t MCalibrationChargeCalc::PostProcess()
579{
580
581 if (GetNumExecutions()==0)
582 return kFALSE;
583
584 if (fPINDiode)
585 if (!fPINDiode->IsValid())
586 {
587 *fLog << warn << GetDescriptor()
588 << ": MCalibrationChargePINDiode is declared not valid... no PIN Diode method! " << endl;
589 fPINDiode = NULL;
590 }
591
592 if (fBlindPixel)
593 if (!fBlindPixel->IsValid())
594 {
595 *fLog << warn << GetDescriptor()
596 << ": MCalibrationChargeBlindPix is declared not valid... no Blind Pixel method! " << endl;
597 fBlindPixel = NULL;
598 }
599
600 if (fBlindCam)
601 if (!fBlindCam->IsValid())
602 {
603 *fLog << warn << GetDescriptor()
604 << ": MCalibrationChargeBlindCam is declared not valid... no Blind Pixel method! " << endl;
605 fBlindCam = NULL;
606 }
607
608 //
609 // First loop over pixels, call FinalizePedestals and FinalizeCharges
610 //
611 Int_t nvalid = 0;
612
613 for (Int_t pixid=0; pixid<fPedestals->GetSize(); pixid++)
614 {
615
616 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[pixid];
617 //
618 // Check if the pixel has been excluded from the fits
619 //
620 if (pix.IsExcluded())
621 continue;
622
623 MPedestalPix &ped = (*fPedestals)[pixid];
624 MBadPixelsPix &bad = (*fBadPixels)[pixid];
625 const Int_t aidx = (*fGeom)[pixid].GetAidx();
626
627 FinalizePedestals(ped,pix,aidx);
628
629 if (FinalizeCharges(pix,bad))
630 nvalid++;
631 }
632
633 //
634 // The Michele check ...
635 //
636 if (nvalid == 0)
637 {
638 *fLog << err << GetDescriptor() << ": All pixels have non-valid calibration. "
639 << "Did you forget to fill the histograms "
640 << "(filling MHCalibrationChargeCam from MExtractedSignalCam using MFillH) ? " << endl;
641 *fLog << err << GetDescriptor() << ": Or, maybe, you have used a pedestal run "
642 << "instead of a calibration run " << endl;
643 return kFALSE;
644 }
645
646 for (UInt_t aidx=0; aidx<fGeom->GetNumAreas(); aidx++)
647 {
648
649 const MPedestalPix &ped = fPedestals->GetAverageArea(aidx);
650 MCalibrationChargePix &pix = (MCalibrationChargePix&)fCam->GetAverageArea(aidx);
651
652 FinalizePedestals(ped,pix,aidx);
653 FinalizeCharges(pix, fCam->GetAverageBadArea(aidx));
654 }
655
656 for (UInt_t sector=0; sector<fGeom->GetNumSectors(); sector++)
657 {
658
659 const MPedestalPix &ped = fPedestals->GetAverageSector(sector);
660
661 MCalibrationChargePix &pix = (MCalibrationChargePix&)fCam->GetAverageSector(sector);
662 FinalizePedestals(ped,pix, 0);
663 FinalizeCharges(pix, fCam->GetAverageBadSector(sector));
664 }
665
666 //
667 // Finalize Bad Pixels
668 //
669 FinalizeBadPixels();
670
671 //
672 // Finalize F-Factor method
673 //
674 if (!FinalizeFFactorMethod())
675 {
676 *fLog << warn << "Could not calculate the photons flux from the F-Factor method " << endl;
677 fCam->SetFFactorMethodValid(kFALSE);
678 return kFALSE;
679 }
680 else
681 fCam->SetFFactorMethodValid(kTRUE);
682
683 //
684 // Finalize Blind Pixel
685 //
686 if (FinalizeBlindPixel())
687 fQECam->SetBlindPixelMethodValid(kTRUE);
688 else
689 fQECam->SetBlindPixelMethodValid(kFALSE);
690
691 //
692 // Finalize PIN Diode
693 //
694 if (FinalizePINDiode())
695 fQECam->SetPINDiodeMethodValid(kTRUE);
696 else
697 fQECam->SetPINDiodeMethodValid(kFALSE);
698
699 //
700 // Finalize QE Cam
701 //
702 FinalizeFFactorQECam();
703 FinalizeBlindPixelQECam();
704 FinalizePINDiodeQECam();
705
706 //
707 // Re-direct the output to an ascii-file from now on:
708 //
709 MLog asciilog;
710 asciilog.SetOutputFile(GetOutputFile(),kTRUE);
711 SetLogStream(&asciilog);
712 //
713 // Finalize calibration statistics
714 //
715 FinalizeUnsuitablePixels();
716
717 fCam ->SetReadyToSave();
718 fQECam ->SetReadyToSave();
719 fBadPixels->SetReadyToSave();
720
721 if (fBlindPixel)
722 fBlindPixel->SetReadyToSave();
723 if (fBlindCam)
724 fBlindCam->SetReadyToSave();
725 if (fPINDiode)
726 fPINDiode->SetReadyToSave();
727
728 *fLog << inf << endl;
729 *fLog << GetDescriptor() << ": Fatal errors statistics:" << endl;
730
731 PrintUncalibrated(MBadPixelsPix::kChargeIsPedestal,
732 Form("%s%2.1f%s","Signal less than ",fChargeLimit," Pedestal RMS: "));
733 PrintUncalibrated(MBadPixelsPix::kChargeRelErrNotValid,
734 Form("%s%2.1f%s","Signal Error bigger than ",fChargeRelErrLimit," times Mean Signal: "));
735 PrintUncalibrated(MBadPixelsPix::kChargeSigmaNotValid,
736 "Signal Sigma smaller than Pedestal RMS: ");
737 PrintUncalibrated(MBadPixelsPix::kLoGainSaturation,
738 "Pixels with Low Gain Saturation: ");
739 PrintUncalibrated(MBadPixelsPix::kMeanTimeInFirstBin,
740 Form("%s%2.1f%s","Mean Abs. Arr. Time in First ",1.," Bin(s): "));
741 PrintUncalibrated(MBadPixelsPix::kMeanTimeInLast2Bins,
742 Form("%s%2.1f%s","Mean Abs. Arr. Time in Last ",2.," Bin(s): "));
743 PrintUncalibrated(MBadPixelsPix::kDeviatingNumPhes,
744 "Pixels with deviating number of phes: ");
745 PrintUncalibrated(MBadPixelsPix::kDeviatingFFactor,
746 "Pixels with deviating F-Factor: ");
747
748 *fLog << inf << endl;
749 *fLog << GetDescriptor() << ": Unreliable errors statistics:" << endl;
750
751 PrintUncalibrated(MBadPixelsPix::kHiGainOscillating,
752 "Pixels with changing Hi Gain signal over time: ");
753 PrintUncalibrated(MBadPixelsPix::kLoGainOscillating,
754 "Pixels with changing Lo Gain signal over time: ");
755 PrintUncalibrated(MBadPixelsPix::kHiGainNotFitted,
756 "Pixels with unsuccesful Gauss fit to the Hi Gain: ");
757 PrintUncalibrated(MBadPixelsPix::kLoGainNotFitted,
758 "Pixels with unsuccesful Gauss fit to the Lo Gain: ");
759
760 SetLogStream(&gLog);
761
762 return kTRUE;
763}
764
765// ----------------------------------------------------------------------------------
766//
767// Retrieves pedestal and pedestal RMS from MPedestalPix
768// Retrieves total entries from MPedestalCam
769// Sets pedestal*fNumHiGainSamples and pedestal*fNumLoGainSamples in MCalibrationChargePix
770// Sets pedRMS *fSqrtHiGainSamples and pedRMS *fSqrtLoGainSamples in MCalibrationChargePix
771//
772// If the flag MCalibrationPix::IsHiGainSaturation() is set, call also:
773// - MCalibrationChargePix::CalcLoGainPedestal()
774//
775void MCalibrationChargeCalc::FinalizePedestals(const MPedestalPix &ped, MCalibrationChargePix &cal, const Int_t aidx)
776{
777
778 //
779 // get the pedestals
780 //
781 const Float_t pedes = ped.GetPedestal();
782 const Float_t prms = ped.GetPedestalRms();
783 const Float_t num = TMath::Sqrt((Float_t)fPedestals->GetTotalEntries());
784
785
786 //
787 // set them in the calibration camera
788 //
789 if (cal.IsHiGainSaturation())
790 {
791 cal.SetPedestal(pedes* fNumLoGainSamples,
792 prms * fSqrtLoGainSamples,
793 prms * fNumLoGainSamples / num);
794 cal.CalcLoGainPedestal((Float_t)fNumLoGainSamples, aidx);
795 }
796 else
797 {
798 cal.SetPedestal(pedes* fNumHiGainSamples,
799 prms * fSqrtHiGainSamples,
800 prms * fNumHiGainSamples / num);
801 }
802
803}
804
805// ----------------------------------------------------------------------------------------------------
806//
807// Check fit results validity. Bad Pixels flags are set if:
808//
809// 1) Pixel has a mean smaller than fChargeLimit*PedRMS ( Flag: MBadPixelsPix::kChargeIsPedestal)
810// 2) Pixel has a mean error smaller than fChargeErrLimit ( Flag: MBadPixelsPix::kChargeErrNotValid)
811// 3) Pixel has mean smaller than fChargeRelVarLimit times its mean error
812// ( Flag: MBadPixelsPix::kChargeRelErrNotValid)
813// 4) Pixel has a sigma bigger than its Pedestal RMS ( Flag: MBadPixelsPix::kChargeSigmaNotValid )
814//
815// Further returns if flags: MBadPixelsPix::kUnsuitableRun is set
816//
817// Calls MCalibrationChargePix::CalcReducedSigma() and sets flag: MBadPixelsPix::kChargeIsPedestal
818// if not succesful.
819//
820// Calls MCalibrationChargePix::CalcFFactorMethod() and sets flag: MBadPixelsPix::kDeviatingNumPhes)
821// if not succesful.
822//
823Bool_t MCalibrationChargeCalc::FinalizeCharges(MCalibrationChargePix &cal, MBadPixelsPix &bad)
824{
825
826 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
827 return kFALSE;
828
829 if (cal.GetMean() < fChargeLimit*cal.GetPedRms())
830 {
831 *fLog << warn << GetDescriptor() << ": Fitted Charge: " << cal.GetMean() << " is smaller than "
832 << fChargeLimit << " Pedestal RMS: " << cal.GetPedRms() << " in Pixel " << cal.GetPixId() << endl;
833 bad.SetUncalibrated( MBadPixelsPix::kChargeIsPedestal);
834 }
835
836 if (cal.GetMean() < fChargeRelErrLimit*cal.GetMeanErr())
837 {
838 *fLog << warn << GetDescriptor() << ": Fitted Charge: " << cal.GetMean() << " is smaller than "
839 << fChargeRelErrLimit << "* its error: " << cal.GetMeanErr()
840 << " in Pixel " << cal.GetPixId() << endl;
841 bad.SetUncalibrated( MBadPixelsPix::kChargeRelErrNotValid );
842 }
843
844 if (cal.GetSigma() < cal.GetPedRms())
845 {
846 *fLog << warn << GetDescriptor() << ": Sigma of Fitted Charge: " << cal.GetSigma()
847 << " smaller than Pedestal RMS: " << cal.GetPedRms() << " in Pixel " << cal.GetPixId() << endl;
848 bad.SetUncalibrated( MBadPixelsPix::kChargeSigmaNotValid );
849 }
850
851 if (!cal.CalcReducedSigma())
852 {
853 *fLog << warn << GetDescriptor()
854 << ": Could not calculate reduced sigmas of pixel: " << cal.GetPixId() << endl;
855 bad.SetUncalibrated(MBadPixelsPix::kChargeIsPedestal);
856 return kFALSE;
857 }
858
859 if (!cal.CalcFFactorMethod())
860 {
861 *fLog << warn << GetDescriptor()
862 << ": Could not calculate F-Factor of pixel: " << cal.GetPixId() << endl;
863 bad.SetUncalibrated(MBadPixelsPix::kDeviatingNumPhes);
864 return kFALSE;
865 }
866
867 return kTRUE;
868}
869
870
871
872// -----------------------------------------------------------------------------------
873//
874// Sets pixel to MBadPixelsPix::kUnsuitableRun, if one of the following flags is set:
875// - MBadPixelsPix::kChargeIsPedestal
876// - MBadPixelsPix::kChargeRelErrNotValid
877// - MBadPixelsPix::kChargeSigmaNotValid
878// - MBadPixelsPix::kMeanTimeInFirstBin
879// - MBadPixelsPix::kMeanTimeInLast2Bins
880// - MBadPixelsPix::kDeviatingNumPhes
881//
882// - Call MCalibrationPix::SetExcluded() for the bad pixels
883//
884void MCalibrationChargeCalc::FinalizeBadPixels()
885{
886
887 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
888 {
889
890 MBadPixelsPix &bad = (*fBadPixels)[i];
891 MCalibrationPix &pix = (*fCam)[i];
892
893 if (bad.IsUncalibrated( MBadPixelsPix::kChargeIsPedestal))
894 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
895
896 if (bad.IsUncalibrated( MBadPixelsPix::kChargeErrNotValid ))
897 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
898
899 if (bad.IsUncalibrated( MBadPixelsPix::kChargeRelErrNotValid ))
900 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
901
902 if (bad.IsUncalibrated( MBadPixelsPix::kChargeSigmaNotValid ))
903 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
904
905 if (bad.IsUncalibrated( MBadPixelsPix::kMeanTimeInFirstBin ))
906 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
907
908 if (bad.IsUncalibrated( MBadPixelsPix::kMeanTimeInLast2Bins ))
909 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
910
911 if (bad.IsUncalibrated( MBadPixelsPix::kDeviatingNumPhes ))
912 bad.SetUnsuitable( MBadPixelsPix::kUnsuitableRun );
913
914 if (bad.IsUnsuitable( MBadPixelsPix::kUnsuitableRun ))
915 pix.SetExcluded();
916
917 }
918}
919
920// ------------------------------------------------------------------------
921//
922//
923// First loop: Calculate a mean and mean RMS of photo-electrons per area index
924// Include only pixels which are not MBadPixelsPix::kUnsuitableRun or
925// MBadPixelsPix::kUnreliableRun (see FinalizeBadPixels()) and set
926// MCalibrationChargePix::SetFFactorMethodValid(kFALSE) in that case.
927//
928// Second loop: Get weighted mean number of photo-electrons and its RMS including
929// only pixels with flag MCalibrationChargePix::IsFFactorMethodValid()
930// and further exclude those deviating by more than fPheErrLimit mean
931// sigmas from the mean (obtained in first loop). Set
932// MBadPixelsPix::kDeviatingNumPhes if excluded.
933//
934// Set weighted mean and variance of photo-electrons per area index in:
935// average area pixels of MCalibrationChargeCam (obtained from:
936// MCalibrationChargeCam::GetAverageArea() )
937//
938// Set weighted mean and variance of photo-electrons per sector in:
939// average sector pixels of MCalibrationChargeCam (obtained from:
940// MCalibrationChargeCam::GetAverageSector() )
941//
942Bool_t MCalibrationChargeCalc::FinalizeFFactorMethod()
943{
944
945 const UInt_t npixels = fGeom->GetNumPixels();
946 const UInt_t nareas = fGeom->GetNumAreas();
947 const UInt_t nsectors = fGeom->GetNumSectors();
948
949 Float_t lowlim [nareas];
950 Float_t upplim [nareas];
951 Float_t areavars [nareas];
952 Float_t areaweights [nareas], sectorweights [nsectors];
953 Float_t areaphes [nareas], sectorphes [nsectors];
954 Int_t numareavalid[nareas], numsectorvalid[nsectors];
955
956 memset(lowlim ,0, nareas * sizeof(Float_t));
957 memset(upplim ,0, nareas * sizeof(Float_t));
958 memset(areaphes ,0, nareas * sizeof(Float_t));
959 memset(areavars ,0, nareas * sizeof(Float_t));
960 memset(areaweights ,0, nareas * sizeof(Float_t));
961 memset(numareavalid ,0, nareas * sizeof(Int_t ));
962 memset(sectorweights ,0, nsectors * sizeof(Float_t));
963 memset(sectorphes ,0, nsectors * sizeof(Float_t));
964 memset(numsectorvalid,0, nsectors * sizeof(Int_t ));
965
966 //
967 // First loop: Get mean number of photo-electrons and the RMS
968 // The loop is only to recognize later pixels with very deviating numbers
969 //
970 MHCamera camphes(*fGeom,"Camphes","Phes in Camera");
971
972 for (UInt_t i=0; i<npixels; i++)
973 {
974
975 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam) [i];
976 MBadPixelsPix &bad = (*fBadPixels)[i];
977
978 if (!pix.IsFFactorMethodValid())
979 continue;
980
981 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
982 {
983 pix.SetFFactorMethodValid(kFALSE);
984 continue;
985 }
986
987 // if (bad.IsUnsuitable(MBadPixelsPix::kUnreliableRun))
988 // continue;
989
990 const Float_t nphe = pix.GetPheFFactorMethod();
991 const Int_t aidx = (*fGeom)[i].GetAidx();
992
993 camphes.Fill(i,nphe);
994 camphes.SetUsed(i);
995
996 areaphes [aidx] += nphe;
997 areavars [aidx] += nphe*nphe;
998 numareavalid[aidx] ++;
999 }
1000
1001 for (UInt_t i=0; i<nareas; i++)
1002 {
1003 if (numareavalid[i] == 0)
1004 {
1005 *fLog << warn << GetDescriptor() << ": No pixels with valid number of photo-electrons found "
1006 << "in area index: " << i << endl;
1007 continue;
1008 }
1009
1010 areavars[i] = (areavars[i] - areaphes[i]*areaphes[i]/numareavalid[i]) / (numareavalid[i]-1.);
1011 areaphes[i] = areaphes[i] / numareavalid[i];
1012
1013 if (areavars[i] < 0.)
1014 {
1015 *fLog << warn << GetDescriptor() << ": No pixels with valid variance of photo-electrons found "
1016 << "in area index: " << i << endl;
1017 continue;
1018 }
1019
1020 lowlim [i] = areaphes[i] - fPheErrLimit*TMath::Sqrt(areavars[i]);
1021 upplim [i] = areaphes[i] + fPheErrLimit*TMath::Sqrt(areavars[i]);
1022
1023 TArrayI area(1);
1024 area[0] = i;
1025
1026 TH1D *hist = camphes.ProjectionS(TArrayI(),area,"_py",100);
1027 hist->Fit("gaus","Q");
1028 const Float_t mean = hist->GetFunction("gaus")->GetParameter(1);
1029 const Float_t sigma = hist->GetFunction("gaus")->GetParameter(2);
1030 const Int_t ndf = hist->GetFunction("gaus")->GetNDF();
1031
1032 if (ndf < 2)
1033 {
1034 *fLog << warn << GetDescriptor() << ": Cannot use a Gauss fit to the number of photo-electrons "
1035 << "in the camera with area index: " << i << endl;
1036 *fLog << warn << GetDescriptor() << ": Number of dof.: " << ndf << " is smaller than 2 " << endl;
1037 *fLog << warn << GetDescriptor() << ": Will use the simple mean and rms " << endl;
1038 delete hist;
1039 continue;
1040 }
1041
1042 const Double_t prob = hist->GetFunction("gaus")->GetProb();
1043
1044 if (prob < 0.001)
1045 {
1046 *fLog << warn << GetDescriptor() << ": Cannot use a Gauss fit to the number of photo-electrons "
1047 << "in the camera with area index: " << i << endl;
1048 *fLog << warn << GetDescriptor() << ": Fit probability " << prob
1049 << " is smaller than 0.001 " << endl;
1050 *fLog << warn << GetDescriptor() << ": Will use the simple mean and rms " << endl;
1051 delete hist;
1052 continue;
1053 }
1054
1055 *fLog << inf << endl;
1056 *fLog << inf << GetDescriptor() << ": Mean Number of photo-electrons "
1057 << "in the camera with area index: " << i << ": "
1058 << Form("%4.2f%s%4.2f",mean,"+-",sigma) << endl;
1059 *fLog << inf << endl;
1060
1061 lowlim [i] = mean - fPheErrLimit*sigma;
1062 upplim [i] = mean + fPheErrLimit*sigma;
1063
1064 delete hist;
1065 }
1066
1067 memset(numareavalid,0,nareas*sizeof(Int_t));
1068 memset(areaphes ,0,nareas*sizeof(Float_t));
1069 memset(areavars ,0,nareas*sizeof(Float_t));
1070
1071 //
1072 // Second loop: Get mean number of photo-electrons and its RMS excluding
1073 // pixels deviating by more than fPheErrLimit sigma.
1074 // Set the conversion factor FADC counts to photo-electrons
1075 //
1076 for (UInt_t i=0; i<npixels; i++)
1077 {
1078
1079 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1080
1081 if (!pix.IsFFactorMethodValid())
1082 continue;
1083
1084 const Float_t nvar = pix.GetPheFFactorMethodVar();
1085
1086 if (nvar <= 0.)
1087 {
1088 pix.SetFFactorMethodValid(kFALSE);
1089 continue;
1090 }
1091
1092 MBadPixelsPix &bad = (*fBadPixels)[i];
1093
1094 const Int_t aidx = (*fGeom)[i].GetAidx();
1095 const Int_t sector = (*fGeom)[i].GetSector();
1096 const Float_t nphe = pix.GetPheFFactorMethod();
1097
1098 if ( nphe < lowlim[aidx] || nphe > upplim[aidx] )
1099 {
1100 *fLog << warn << GetDescriptor() << ": Deviating number of photo-electrons: "
1101 << Form("%4.2f",nphe) << " out of accepted limits: ["
1102 << Form("%4.2f%s%4.2f",lowlim[aidx],",",upplim[aidx]) << "] in pixel " << i << endl;
1103 bad.SetUncalibrated( MBadPixelsPix::kDeviatingNumPhes );
1104 bad.SetUnsuitable ( MBadPixelsPix::kUnsuitableRun );
1105 pix.SetFFactorMethodValid(kFALSE);
1106 continue;
1107 }
1108
1109 // const Float_t weight = 1./nvar;
1110 // areaweights [aidx] += weight;
1111 // areaphes [aidx] += weight*nphe;
1112 areaweights [aidx] += nphe*nphe;
1113 areaphes [aidx] += nphe;
1114 numareavalid [aidx] ++;
1115
1116 if (aidx == 0)
1117 fNumInnerFFactorMethodUsed++;
1118 // sectorweights [sector] += weight;
1119 // sectorphes [sector] += weight*nphe;
1120 sectorweights [sector] += nphe*nphe;
1121 sectorphes [sector] += nphe;
1122 numsectorvalid[sector] ++;
1123 }
1124
1125 for (UInt_t aidx=0; aidx<nareas; aidx++)
1126 {
1127
1128 MCalibrationChargePix &apix = (MCalibrationChargePix&)fCam->GetAverageArea(aidx);
1129
1130 areaweights[aidx] -= areaphes[aidx]*areaphes[aidx]/numareavalid[aidx];
1131 areaphes[aidx] /= numareavalid[aidx];
1132 areaweights[aidx] /= numareavalid[aidx]-1.;
1133
1134 if (areaweights[aidx] <= 0. || areaphes[aidx] <= 0.)
1135 {
1136 *fLog << warn << " Mean number of phe's from area index " << aidx << " cannot be calculated: "
1137 << " Mean number of phes: " << areaphes[aidx]
1138 << " Variance: " << areaweights[aidx] << endl;
1139 apix.SetFFactorMethodValid(kFALSE);
1140 continue;
1141 }
1142
1143 *fLog << inf << "Replacing number photo-electrons of average area idx " << aidx << ": "
1144 << Form("%5.3f%s%5.3f",apix.GetPheFFactorMethod()," +- ",apix.GetPheFFactorMethodErr()) << endl;
1145 *fLog << inf << " by average number of photo-electrons from area idx " << aidx << ": "
1146 << Form("%5.3f%s%5.3f",areaphes[aidx]," +- ",TMath::Sqrt(areaweights[aidx])) << endl;
1147
1148 // apix.SetPheFFactorMethod ( areaphes[aidx]/ areaweights[aidx] );
1149 // apix.SetPheFFactorMethodVar( 1. / areaweights[aidx] );
1150 apix.SetPheFFactorMethod ( areaphes[aidx] );
1151 apix.SetPheFFactorMethodVar( areaweights[aidx] / numareavalid[aidx] );
1152 apix.SetFFactorMethodValid ( kTRUE );
1153
1154 }
1155
1156 for (UInt_t sector=0; sector<nsectors; sector++)
1157 {
1158
1159 sectorweights[sector] -= sectorphes[sector]*sectorphes[sector]/numsectorvalid[sector];
1160 sectorphes[sector] /= numsectorvalid[sector];
1161 sectorweights[sector] /= numsectorvalid[sector]-1.;
1162
1163 MCalibrationChargePix &spix = (MCalibrationChargePix&)fCam->GetAverageSector(sector);
1164
1165 if (sectorweights[sector] <= 0. || sectorphes[sector] <= 0.)
1166 {
1167 *fLog << warn << " Mean number of phe's from sector " << sector << " cannot be calculated: "
1168 << " Mean number of phes: " << sectorphes[sector]
1169 << " Variance: " << sectorweights[sector] << endl;
1170 spix.SetFFactorMethodValid(kFALSE);
1171 continue;
1172 }
1173
1174 *fLog << inf << "Replacing number photo-electrons of average sector " << sector << ": "
1175 << Form("%5.3f%s%5.3f",spix.GetPheFFactorMethod()," +- ",spix.GetPheFFactorMethodErr()) << endl;
1176 *fLog << inf << " by average number photo-electrons from sector " << sector << ": "
1177 << Form("%5.3f%s%5.3f",sectorphes[sector]," +- ",TMath::Sqrt(sectorweights[sector])) << endl;
1178
1179 // spix.SetPheFFactorMethod ( sectorphes[sector]/ sectorweights[sector] );
1180 // spix.SetPheFFactorMethodVar( 1. / sectorweights[sector] );
1181 spix.SetPheFFactorMethod ( sectorphes[sector] );
1182 spix.SetPheFFactorMethodVar( sectorweights[sector] / numsectorvalid[sector]);
1183 spix.SetFFactorMethodValid ( kTRUE );
1184
1185 }
1186
1187 return kTRUE;
1188}
1189
1190
1191// ------------------------------------------------------------------------
1192//
1193// Returns kFALSE if pointer to MCalibrationChargeBlindPix is NULL
1194//
1195// The check returns kFALSE if:
1196//
1197// 1) fLambda and fLambdaCheck are separated relatively to each other by more than fLambdaCheckLimit
1198// 2) BlindPixel has an fLambdaErr greater than fLambdaErrLimit
1199//
1200// Calls:
1201// - MCalibrationChargeBlindPix::CalcFluxInsidePlexiglass()
1202//
1203Bool_t MCalibrationChargeCalc::FinalizeBlindPixel()
1204{
1205
1206 if (!fBlindPixel)
1207 return kFALSE;
1208
1209 const Float_t lambda = fBlindPixel->GetLambda();
1210 const Float_t lambdaerr = fBlindPixel->GetLambdaErr();
1211 const Float_t lambdacheck = fBlindPixel->GetLambdaCheck();
1212
1213 if (2.*(lambdacheck-lambda)/(lambdacheck+lambda) > fLambdaCheckLimit)
1214 {
1215 *fLog << warn << GetDescriptor()
1216 << Form("%s%4.2f%s%4.2f%s%4.2f%s",": Lambda: ",lambda," and Lambda-Check: ",
1217 lambdacheck," differ by more than ",fLambdaCheckLimit," in the Blind Pixel ")
1218 << endl;
1219 return kFALSE;
1220 }
1221
1222 if (lambdaerr > fLambdaErrLimit)
1223 {
1224 *fLog << warn << GetDescriptor()
1225 << Form("%s%4.2f%s%4.2f%s",": Error of Fitted Lambda: ",lambdaerr," is greater than ",
1226 fLambdaErrLimit," in Blind Pixel ") << endl;
1227 return kFALSE;
1228 }
1229
1230 if (!fBlindPixel->CalcFluxInsidePlexiglass())
1231 {
1232 *fLog << warn << "Could not calculate the flux of photons from the Blind Pixel, "
1233 << "will skip Blind Pixel Calibration " << endl;
1234 return kFALSE;
1235 }
1236
1237 return kTRUE;
1238}
1239
1240// ------------------------------------------------------------------------
1241//
1242// Returns kFALSE if pointer to MCalibrationChargePINDiode is NULL
1243//
1244// The check returns kFALSE if:
1245//
1246// 1) PINDiode has a fitted charge smaller than fChargeLimit*PedRMS
1247// 2) PINDiode has a fit error smaller than fChargeErrLimit
1248// 3) PINDiode has a fitted charge smaller its fChargeRelErrLimit times its charge error
1249// 4) PINDiode has a charge sigma smaller than its Pedestal RMS
1250//
1251// Calls:
1252// - MCalibrationChargePINDiode::CalcFluxOutsidePlexiglass()
1253//
1254Bool_t MCalibrationChargeCalc::FinalizePINDiode()
1255{
1256
1257 if (!fPINDiode)
1258 return kFALSE;
1259
1260 if (fPINDiode->GetMean() < fChargeLimit*fPINDiode->GetPedRms())
1261 {
1262 *fLog << warn << GetDescriptor() << ": Fitted Charge is smaller than "
1263 << fChargeLimit << " Pedestal RMS in PINDiode " << endl;
1264 return kFALSE;
1265 }
1266
1267 if (fPINDiode->GetMeanErr() < fChargeErrLimit)
1268 {
1269 *fLog << warn << GetDescriptor() << ": Error of Fitted Charge is smaller than "
1270 << fChargeErrLimit << " in PINDiode " << endl;
1271 return kFALSE;
1272 }
1273
1274 if (fPINDiode->GetMean() < fChargeRelErrLimit*fPINDiode->GetMeanErr())
1275 {
1276 *fLog << warn << GetDescriptor() << ": Fitted Charge is smaller than "
1277 << fChargeRelErrLimit << "* its error in PINDiode " << endl;
1278 return kFALSE;
1279 }
1280
1281 if (fPINDiode->GetSigma() < fPINDiode->GetPedRms())
1282 {
1283 *fLog << warn << GetDescriptor()
1284 << ": Sigma of Fitted Charge smaller than Pedestal RMS in PINDiode " << endl;
1285 return kFALSE;
1286 }
1287
1288
1289 if (!fPINDiode->CalcFluxOutsidePlexiglass())
1290 {
1291 *fLog << warn << "Could not calculate the flux of photons from the PIN Diode, "
1292 << "will skip PIN Diode Calibration " << endl;
1293 return kFALSE;
1294 }
1295
1296 return kTRUE;
1297}
1298
1299// ------------------------------------------------------------------------
1300//
1301// Calculate the average number of photons outside the plexiglass with the
1302// formula:
1303//
1304// av.Num.photons(area index) = av.Num.Phes(area index)
1305// / MCalibrationQEPix::GetDefaultQE(fPulserColor)
1306// / MCalibrationQEPix::GetPMTCollectionEff()
1307// / MCalibrationQEPix::GetLightGuidesEff(fPulserColor)
1308// / MCalibrationQECam::GetPlexiglassQE()
1309//
1310// Calculate the variance on the average number of photons assuming that the error on the
1311// Quantum efficiency is reduced by the number of used inner pixels, but the rest of the
1312// values keeps it ordinary error since it is systematic.
1313//
1314// Loop over pixels:
1315//
1316// - Continue, if not MCalibrationChargePix::IsFFactorMethodValid() and set:
1317// MCalibrationQEPix::SetFFactorMethodValid(kFALSE,fPulserColor)
1318//
1319// - Call MCalibrationChargePix::CalcMeanFFactor(av.Num.photons) and set:
1320// MCalibrationQEPix::SetFFactorMethodValid(kFALSE,fPulserColor) if not succesful
1321//
1322// - Calculate the quantum efficiency with the formula:
1323//
1324// QE = ( Num.Phes / av.Num.photons ) * MGeomCam::GetPixRatio()
1325//
1326// - Set QE in MCalibrationQEPix::SetQEFFactor ( QE, fPulserColor );
1327//
1328// - Set Variance of QE in MCalibrationQEPix::SetQEFFactorVar ( Variance, fPulserColor );
1329// - Set bit MCalibrationQEPix::SetFFactorMethodValid(kTRUE,fPulserColor)
1330//
1331// - Call MCalibrationQEPix::UpdateFFactorMethod()
1332//
1333void MCalibrationChargeCalc::FinalizeFFactorQECam()
1334{
1335
1336 if (fNumInnerFFactorMethodUsed < 2)
1337 {
1338 *fLog << warn << GetDescriptor()
1339 << ": Could not calculate F-Factor Method: Less than 2 inner pixels valid! " << endl;
1340 return;
1341 }
1342
1343 MCalibrationChargePix &avpix = (MCalibrationChargePix&)fCam->GetAverageArea(0);
1344 MCalibrationQEPix &qepix = (MCalibrationQEPix&) fQECam->GetAverageArea(0);
1345
1346 const Float_t avphotons = avpix.GetPheFFactorMethod()
1347 / qepix.GetDefaultQE(fPulserColor)
1348 / qepix.GetPMTCollectionEff()
1349 / qepix.GetLightGuidesEff(fPulserColor)
1350 / fQECam->GetPlexiglassQE();
1351
1352 const Float_t avphotrelvar = avpix.GetPheFFactorMethodRelVar()
1353 + qepix.GetDefaultQERelVar(fPulserColor) / fNumInnerFFactorMethodUsed
1354 + qepix.GetPMTCollectionEffRelVar()
1355 + qepix.GetLightGuidesEffRelVar(fPulserColor)
1356 + fQECam->GetPlexiglassQERelVar();
1357
1358 const UInt_t nareas = fGeom->GetNumAreas();
1359
1360 //
1361 // Set the results in the MCalibrationChargeCam
1362 //
1363 fCam->SetNumPhotonsFFactorMethod (avphotons);
1364 if (avphotrelvar > 0.)
1365 fCam->SetNumPhotonsFFactorMethodErr(TMath::Sqrt( avphotrelvar * avphotons * avphotons));
1366
1367 Float_t lowlim [nareas];
1368 Float_t upplim [nareas];
1369 Float_t avffactorphotons [nareas];
1370 Float_t avffactorphotvar [nareas];
1371 Int_t numffactor [nareas];
1372
1373 memset(lowlim ,0, nareas * sizeof(Float_t));
1374 memset(upplim ,0, nareas * sizeof(Float_t));
1375 memset(avffactorphotons,0, nareas * sizeof(Float_t));
1376 memset(avffactorphotvar,0, nareas * sizeof(Float_t));
1377 memset(numffactor ,0, nareas * sizeof(Int_t));
1378
1379 const UInt_t npixels = fGeom->GetNumPixels();
1380
1381 MHCamera camffactor(*fGeom,"Camffactor","F-Factor in Camera");
1382
1383 for (UInt_t i=0; i<npixels; i++)
1384 {
1385
1386 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1387 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1388 MBadPixelsPix &bad = (*fBadPixels)[i];
1389
1390 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
1391 continue;
1392
1393 const Float_t photons = avphotons / fGeom->GetPixRatio(i);
1394 const Float_t qe = pix.GetPheFFactorMethod() / photons ;
1395
1396 if (!pix.CalcMeanFFactor( photons , avphotrelvar ))
1397 {
1398 (*fBadPixels)[i].SetUncalibrated( MBadPixelsPix::kDeviatingNumPhes );
1399 continue;
1400 }
1401
1402 const Float_t qerelvar = avphotrelvar + pix.GetPheFFactorMethodRelVar();
1403
1404 qepix.SetQEFFactor ( qe , fPulserColor );
1405 qepix.SetQEFFactorVar ( qerelvar*qe*qe, fPulserColor );
1406 qepix.SetFFactorMethodValid( kTRUE , fPulserColor );
1407
1408 if (!qepix.UpdateFFactorMethod())
1409 *fLog << warn << GetDescriptor()
1410 << ": Cannot update Quantum efficiencies with the F-Factor Method" << endl;
1411
1412 const Int_t aidx = (*fGeom)[i].GetAidx();
1413 const Float_t ffactor = pix.GetMeanFFactorFADC2Phot();
1414
1415 camffactor.Fill(i,ffactor);
1416 camffactor.SetUsed(i);
1417
1418 avffactorphotons[aidx] += ffactor;
1419 avffactorphotvar[aidx] += ffactor*ffactor;
1420 numffactor[aidx]++;
1421 }
1422
1423 for (UInt_t i=0; i<nareas; i++)
1424 {
1425
1426 if (numffactor[i] == 0)
1427 {
1428 *fLog << warn << GetDescriptor() << ": No pixels with valid total F-Factor found "
1429 << "in area index: " << i << endl;
1430 continue;
1431 }
1432
1433 avffactorphotvar[i] = (avffactorphotvar[i] - avffactorphotons[i]*avffactorphotons[i]/numffactor[i]) / (numffactor[i]-1.);
1434 avffactorphotons[i] = avffactorphotons[i] / numffactor[i];
1435
1436 if (avffactorphotvar[i] < 0.)
1437 {
1438 *fLog << warn << GetDescriptor() << ": No pixels with valid variance of total F-Factor found "
1439 << "in area index: " << i << endl;
1440 continue;
1441 }
1442
1443 lowlim [i] = 1.1; // Lowest known F-Factor of a PMT
1444 upplim [i] = avffactorphotons[i] + fFFactorErrLimit*TMath::Sqrt(avffactorphotvar[i]);
1445
1446 TArrayI area(1);
1447 area[0] = i;
1448
1449 TH1D *hist = camffactor.ProjectionS(TArrayI(),area,"_py",100);
1450 hist->Fit("gaus","Q");
1451 const Float_t mean = hist->GetFunction("gaus")->GetParameter(1);
1452 const Float_t sigma = hist->GetFunction("gaus")->GetParameter(2);
1453 const Int_t ndf = hist->GetFunction("gaus")->GetNDF();
1454
1455 if (ndf < 2)
1456 {
1457 *fLog << warn << GetDescriptor() << ": Cannot use a Gauss fit to the F-Factor "
1458 << "in the camera with area index: " << i << endl;
1459 *fLog << warn << GetDescriptor() << ": Number of dof.: " << ndf << " is smaller than 2 " << endl;
1460 *fLog << warn << GetDescriptor() << ": Will use the simple mean and rms " << endl;
1461 delete hist;
1462 continue;
1463 }
1464
1465 const Double_t prob = hist->GetFunction("gaus")->GetProb();
1466
1467 if (prob < 0.001)
1468 {
1469 *fLog << warn << GetDescriptor() << ": Cannot use a Gauss fit to the F-Factor "
1470 << "in the camera with area index: " << i << endl;
1471 *fLog << warn << GetDescriptor() << ": Fit probability " << prob
1472 << " is smaller than 0.001 " << endl;
1473 *fLog << warn << GetDescriptor() << ": Will use the simple mean and rms " << endl;
1474 delete hist;
1475 continue;
1476 }
1477
1478 *fLog << inf << endl;
1479 *fLog << inf << GetDescriptor() << ": Mean F-Factor "
1480 << "in the camera with area index: " << i << ": "
1481 << Form("%4.2f%s%4.2f",mean,"+-",sigma) << endl;
1482 *fLog << inf << endl;
1483
1484 lowlim [i] = mean - fFFactorErrLimit*sigma;
1485 upplim [i] = mean + fFFactorErrLimit*sigma;
1486
1487 delete hist;
1488 }
1489
1490 for (UInt_t i=0; i<npixels; i++)
1491 {
1492
1493 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1494 MBadPixelsPix &bad = (*fBadPixels)[i];
1495
1496 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
1497 continue;
1498
1499 const Float_t ffactor = pix.GetMeanFFactorFADC2Phot();
1500 const Int_t aidx = (*fGeom)[i].GetAidx();
1501
1502 if ( ffactor < lowlim[aidx] || ffactor > upplim[aidx] )
1503 {
1504 *fLog << warn << GetDescriptor() << ": Deviating F-Factor: "
1505 << Form("%4.2f",ffactor) << " out of accepted limits: ["
1506 << Form("%4.2f%s%4.2f",lowlim[aidx],",",upplim[aidx]) << "] in pixel " << i << endl;
1507 bad.SetUncalibrated( MBadPixelsPix::kDeviatingFFactor );
1508 bad.SetUnsuitable ( MBadPixelsPix::kUnsuitableRun );
1509 }
1510 }
1511
1512 for (UInt_t i=0; i<npixels; i++)
1513 {
1514
1515 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1516 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1517 MBadPixelsPix &bad = (*fBadPixels)[i];
1518
1519 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
1520 {
1521 qepix.SetFFactorMethodValid(kFALSE,fPulserColor);
1522 pix.SetFFactorMethodValid(kFALSE);
1523 pix.SetExcluded();
1524 continue;
1525 }
1526 }
1527}
1528
1529
1530// ------------------------------------------------------------------------
1531//
1532// Loop over pixels:
1533//
1534// - Continue, if not MCalibrationChargeBlindPix::IsFluxInsidePlexiglassAvailable() and set:
1535// MCalibrationQEPix::SetBlindPixelMethodValid(kFALSE,fPulserColor)
1536//
1537// - Calculate the quantum efficiency with the formula:
1538//
1539// QE = Num.Phes / MCalibrationChargeBlindPix::GetFluxInsidePlexiglass()
1540// / MGeomPix::GetA() * MCalibrationQECam::GetPlexiglassQE()
1541//
1542// - Set QE in MCalibrationQEPix::SetQEBlindPixel ( QE, fPulserColor );
1543// - Set Variance of QE in MCalibrationQEPix::SetQEBlindPixelVar ( Variance, fPulserColor );
1544// - Set bit MCalibrationQEPix::SetBlindPixelMethodValid(kTRUE,fPulserColor)
1545//
1546// - Call MCalibrationQEPix::UpdateBlindPixelMethod()
1547//
1548void MCalibrationChargeCalc::FinalizeBlindPixelQECam()
1549{
1550
1551 const UInt_t npixels = fGeom->GetNumPixels();
1552
1553 //
1554 // Set the results in the MCalibrationChargeCam
1555 //
1556 if (fBlindPixel)
1557 {
1558 if (fBlindPixel->IsFluxInsidePlexiglassAvailable())
1559 {
1560
1561 const Float_t photons = fBlindPixel->GetFluxInsidePlexiglass() * (*fGeom)[0].GetA()
1562 / fQECam->GetPlexiglassQE();
1563 fCam->SetNumPhotonsBlindPixelMethod(photons);
1564
1565 const Float_t photrelvar = fBlindPixel->GetFluxInsidePlexiglassRelVar()
1566 + fQECam->GetPlexiglassQERelVar();
1567 if (photrelvar > 0.)
1568 fCam->SetNumPhotonsBlindPixelMethodErr(TMath::Sqrt( photrelvar * photons * photons));
1569 }
1570 }
1571 //
1572 // With the knowledge of the overall photon flux, calculate the
1573 // quantum efficiencies after the Blind Pixel and PIN Diode method
1574 //
1575 for (UInt_t i=0; i<npixels; i++)
1576 {
1577
1578 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1579
1580 if (!fBlindPixel)
1581 {
1582 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1583 continue;
1584 }
1585
1586 if (!fBlindPixel->IsFluxInsidePlexiglassAvailable())
1587 {
1588 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1589 continue;
1590 }
1591
1592 MBadPixelsPix &bad = (*fBadPixels)[i];
1593 if (bad.IsUnsuitable (MBadPixelsPix::kUnsuitableRun))
1594 {
1595 qepix.SetBlindPixelMethodValid(kFALSE, fPulserColor);
1596 continue;
1597 }
1598
1599 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1600 MGeomPix &geo = (*fGeom)[i];
1601
1602 const Float_t qe = pix.GetPheFFactorMethod()
1603 / fBlindPixel->GetFluxInsidePlexiglass()
1604 / geo.GetA()
1605 * fQECam->GetPlexiglassQE();
1606
1607 const Float_t qerelvar = fBlindPixel->GetFluxInsidePlexiglassRelVar()
1608 + fQECam->GetPlexiglassQERelVar()
1609 + pix.GetPheFFactorMethodRelVar();
1610
1611 qepix.SetQEBlindPixel ( qe , fPulserColor );
1612 qepix.SetQEBlindPixelVar ( qerelvar*qe*qe, fPulserColor );
1613 qepix.SetBlindPixelMethodValid( kTRUE , fPulserColor );
1614
1615 if (!qepix.UpdateBlindPixelMethod())
1616 *fLog << warn << GetDescriptor()
1617 << ": Cannot update Quantum efficiencies with the Blind Pixel Method" << endl;
1618 }
1619}
1620
1621// ------------------------------------------------------------------------
1622//
1623// Loop over pixels:
1624//
1625// - Continue, if not MCalibrationChargePINDiode::IsFluxOutsidePlexiglassAvailable() and set:
1626// MCalibrationQEPix::SetPINDiodeMethodValid(kFALSE,fPulserColor)
1627//
1628// - Calculate the quantum efficiency with the formula:
1629//
1630// QE = Num.Phes / MCalibrationChargePINDiode::GetFluxOutsidePlexiglass() / MGeomPix::GetA()
1631//
1632// - Set QE in MCalibrationQEPix::SetQEPINDiode ( QE, fPulserColor );
1633// - Set Variance of QE in MCalibrationQEPix::SetQEPINDiodeVar ( Variance, fPulserColor );
1634// - Set bit MCalibrationQEPix::SetPINDiodeMethodValid(kTRUE,fPulserColor)
1635//
1636// - Call MCalibrationQEPix::UpdatePINDiodeMethod()
1637//
1638void MCalibrationChargeCalc::FinalizePINDiodeQECam()
1639{
1640
1641 const UInt_t npixels = fGeom->GetNumPixels();
1642
1643 //
1644 // With the knowledge of the overall photon flux, calculate the
1645 // quantum efficiencies after the PIN Diode method
1646 //
1647 for (UInt_t i=0; i<npixels; i++)
1648 {
1649
1650 MCalibrationQEPix &qepix = (MCalibrationQEPix&) (*fQECam)[i];
1651
1652 if (!fPINDiode)
1653 {
1654 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1655 continue;
1656 }
1657
1658 if (!fPINDiode->IsFluxOutsidePlexiglassAvailable())
1659 {
1660 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1661 continue;
1662 }
1663
1664 MBadPixelsPix &bad = (*fBadPixels)[i];
1665
1666 if (!bad.IsUnsuitable (MBadPixelsPix::kUnsuitableRun))
1667 {
1668 qepix.SetPINDiodeMethodValid(kFALSE, fPulserColor);
1669 continue;
1670 }
1671
1672 MCalibrationChargePix &pix = (MCalibrationChargePix&)(*fCam)[i];
1673 MGeomPix &geo = (*fGeom)[i];
1674
1675 const Float_t qe = pix.GetPheFFactorMethod()
1676 / fPINDiode->GetFluxOutsidePlexiglass()
1677 / geo.GetA();
1678
1679 const Float_t qerelvar = fPINDiode->GetFluxOutsidePlexiglassRelVar() + pix.GetPheFFactorMethodRelVar();
1680
1681 qepix.SetQEPINDiode ( qe , fPulserColor );
1682 qepix.SetQEPINDiodeVar ( qerelvar*qe*qe, fPulserColor );
1683 qepix.SetPINDiodeMethodValid( kTRUE , fPulserColor );
1684
1685 if (!qepix.UpdatePINDiodeMethod())
1686 *fLog << warn << GetDescriptor()
1687 << ": Cannot update Quantum efficiencies with the PIN Diode Method" << endl;
1688 }
1689}
1690
1691// -----------------------------------------------------------------------------------------------
1692//
1693// - Print out statistics about BadPixels of type UnsuitableType_t
1694// - store numbers of bad pixels of each type in fCam
1695//
1696void MCalibrationChargeCalc::FinalizeUnsuitablePixels()
1697{
1698
1699 *fLog << inf << endl;
1700 *fLog << GetDescriptor() << ": Charge Calibration status:" << endl;
1701 *fLog << dec << setfill(' ');
1702
1703 const Int_t nareas = fGeom->GetNumAreas();
1704
1705 Int_t counts[nareas];
1706 memset(counts,0,nareas*sizeof(Int_t));
1707
1708 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1709 {
1710 MBadPixelsPix &bad = (*fBadPixels)[i];
1711 if (!bad.IsBad())
1712 {
1713 const Int_t aidx = (*fGeom)[i].GetAidx();
1714 counts[aidx]++;
1715 }
1716 }
1717
1718 if (fGeom->InheritsFrom("MGeomCamMagic"))
1719 *fLog << " " << setw(7) << "Successfully calibrated Pixels: "
1720 << Form("%s%3i%s%3i","Inner: ",counts[0]," Outer: ",counts[1]) << endl;
1721
1722 memset(counts,0,nareas*sizeof(Int_t));
1723
1724 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1725 {
1726 MBadPixelsPix &bad = (*fBadPixels)[i];
1727 if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
1728 {
1729 const Int_t aidx = (*fGeom)[i].GetAidx();
1730 counts[aidx]++;
1731 }
1732 }
1733
1734 for (Int_t aidx=0; aidx<nareas; aidx++)
1735 fCam->SetNumUnsuitable(counts[aidx], aidx);
1736
1737 if (fGeom->InheritsFrom("MGeomCamMagic"))
1738 *fLog << " " << setw(7) << "Uncalibrated Pixels: "
1739 << Form("%s%3i%s%3i","Inner: ",counts[0]," Outer: ",counts[1]) << endl;
1740
1741 memset(counts,0,nareas*sizeof(Int_t));
1742
1743 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1744 {
1745 MBadPixelsPix &bad = (*fBadPixels)[i];
1746 if (bad.IsUnsuitable(MBadPixelsPix::kUnreliableRun))
1747 {
1748 const Int_t aidx = (*fGeom)[i].GetAidx();
1749 counts[aidx]++;
1750 }
1751 }
1752
1753 for (Int_t aidx=0; aidx<nareas; aidx++)
1754 fCam->SetNumUnreliable(counts[aidx], aidx);
1755
1756 *fLog << " " << setw(7) << "Unreliable Pixels: "
1757 << Form("%s%3i%s%3i","Inner: ",counts[0]," Outer: ",counts[1]) << endl;
1758
1759}
1760
1761// -----------------------------------------------------------------------------------------------
1762//
1763// Print out statistics about BadPixels of type UncalibratedType_t
1764//
1765void MCalibrationChargeCalc::PrintUncalibrated(MBadPixelsPix::UncalibratedType_t typ, const char *text) const
1766{
1767
1768 UInt_t countinner = 0;
1769 UInt_t countouter = 0;
1770
1771 for (Int_t i=0; i<fBadPixels->GetSize(); i++)
1772 {
1773 MBadPixelsPix &bad = (*fBadPixels)[i];
1774 if (bad.IsUncalibrated(typ))
1775 {
1776 if (fGeom->GetPixRatio(i) == 1.)
1777 countinner++;
1778 else
1779 countouter++;
1780 }
1781 }
1782
1783 *fLog << " " << setw(7) << text
1784 << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
1785}
1786
1787// --------------------------------------------------------------------------
1788//
1789// Set the path for output file
1790//
1791void MCalibrationChargeCalc::SetOutputPath(TString path)
1792{
1793 fOutputPath = path;
1794 if (fOutputPath.EndsWith("/"))
1795 fOutputPath = fOutputPath(0, fOutputPath.Length()-1);
1796}
1797
1798void MCalibrationChargeCalc::SetOutputFile(TString file)
1799{
1800 fOutputFile = file;
1801}
1802
1803// --------------------------------------------------------------------------
1804//
1805// Get the output file
1806//
1807const char* MCalibrationChargeCalc::GetOutputFile()
1808{
1809 return Form("%s/%s", (const char*)fOutputPath, (const char*)fOutputFile);
1810}
Note: See TracBrowser for help on using the repository browser.