source: trunk/MagicSoft/Mars/mcalib/MCalibrationCam.cc@ 3204

Last change on this file since 3204 was 3080, checked in by gaug, 21 years ago
*** empty log message ***
File size: 36.1 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!
19! Author(s): Markus Gaug 11/2003 <mailto:markus@ifae.es>
20!
21! Copyright: MAGIC Software Development, 2000-2001
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MCalibrationCam
29//
30// Hold the whole Calibration results of the camera:
31//
32// 1) MCalibrationCam initializes a TClonesArray whose elements are
33// pointers to MCalibrationPix Containers
34// 2) It initializes a pointer to an MCalibrationBlindPix container
35// 3) It initializes a pointer to an MCalibrationPINDiode container
36//
37//
38// The calculated values (types of GetPixelContent) are:
39//
40// Fitted values:
41// ==============
42//
43// 0: Fitted Charge
44// 1: Error of fitted Charge
45// 2: Sigma of fitted Charge
46// 3: Error of Sigma of fitted Charge
47//
48// Useful variables derived from the fit results:
49// =============================================
50//
51// 4: Returned probability of Gauss fit to Charge distribution
52// 5: Reduced Sigma of fitted Charge --> sqrt(sigma_Q^2 - PedRMS^2)
53// 6: Error Reduced Sigma of fitted Charge
54// 7: Reduced Sigma per Charge
55// 8: Error of Reduced Sigma per Charge
56//
57// Results of the different calibration methods:
58// =============================================
59//
60// 9: Number of Photo-electrons obtained with the F-Factor method
61// 10: Error on Number of Photo-electrons obtained with the F-Factor method
62// 11: Mean conversion factor obtained with the F-Factor method
63// 12: Error on the mean conversion factor obtained with the F-Factor method
64// 13: Overall F-Factor of the readout obtained with the F-Factor method
65// 14: Error on Overall F-Factor of the readout obtained with the F-Factor method
66// 15: Number of Photons inside Plexiglass obtained with the Blind Pixel method
67// 16: Error on Number of Photons inside Plexiglass obtained with the Blind Pixel method
68// 17: Mean conversion factor obtained with the Blind Pixel method
69// 18: Error on the mean conversion factor obtained with the Blind Pixel method
70// 19: Overall F-Factor of the readout obtained with the Blind Pixel method
71// 20: Error on Overall F-Factor of the readout obtained with the Blind Pixel method
72// 21: Number of Photons outside Plexiglass obtained with the PIN Diode method
73// 22: Error on Number of Photons outside Plexiglass obtained with the PIN Diode method
74// 23: Mean conversion factor obtained with the PIN Diode method
75// 24: Error on the mean conversion factor obtained with the PIN Diode method
76// 25: Overall F-Factor of the readout obtained with the PIN Diode method
77// 26: Error on Overall F-Factor of the readout obtained with the PIN Diode method
78//
79// Localized defects:
80// ==================
81//
82// 27: Excluded Pixels
83// 28: Pixels where the fit did not succeed --> results obtained only from the histograms
84// 29: Pixels with succeeded fit, but apparently wrong results
85// 30: Pixels with un-expected behavior in the fourier spectrum (e.g. oscillations)
86//
87// Other classifications of pixels:
88// ================================
89//
90// 31: Pixels with saturated Hi-Gain
91//
92// Classification of validity of the calibrations:
93// ===============================================
94//
95// 32: Pixels with valid calibration by the F-Factor-Method
96// 33: Pixels with valid calibration by the Blind Pixel-Method
97// 34: Pixels with valid calibration by the PIN Diode-Method
98//
99// Used Pedestals:
100// ===============
101//
102// 35: Mean Pedestal over the entire range of signal extraction
103// 36: Error on the Mean Pedestal over the entire range of signal extraction
104// 37: Pedestal RMS over the entire range of signal extraction
105// 38: Error on the Pedestal RMS over the entire range of signal extraction
106//
107// Calculated absolute arrival times (very low precision!):
108// ========================================================
109//
110// 39: Absolute Arrival time of the signal
111// 40: Error on the Absolute Arrival time of the signal
112// 41: RMS of the Absolute Arrival time of the signal
113// 42: Error on the RMS of the Absolute Arrival time of the signal
114//
115/////////////////////////////////////////////////////////////////////////////
116#include "MCalibrationCam.h"
117
118#include <TH2.h>
119#include <TCanvas.h>
120#include <TClonesArray.h>
121
122#include "MLog.h"
123#include "MLogManip.h"
124
125#include "MGeomCam.h"
126#include "MGeomPix.h"
127
128#include "MCalibrationPix.h"
129#include "MCalibrationConfig.h"
130#include "MCalibrationBlindPix.h"
131#include "MCalibrationPINDiode.h"
132
133#include "MHCalibrationPixel.h"
134
135ClassImp(MCalibrationCam);
136
137using namespace std;
138
139const Int_t MCalibrationCam::gkBlindPixelId = 559;
140const Int_t MCalibrationCam::gkPINDiodeId = 9999;
141const Float_t MCalibrationCam::gkBlindPixelArea = 100;
142const Float_t MCalibrationCam::gkPINDiodeArea = 100;
143
144// --------------------------------------------------------------------------
145//
146// Default constructor.
147//
148// Creates a TClonesArray of MCalibrationPix containers, initialized to 1 entry
149// Later, a call to MCalibrationCam::InitSize(Int_t size) has to be performed
150//
151// Creates an MCalibrationBlindPix container
152// Creates an MCalibrationPINDiode container
153//
154MCalibrationCam::MCalibrationCam(const char *name, const char *title)
155 : fOffsets(NULL),
156 fSlopes(NULL),
157 fOffvsSlope(NULL)
158{
159 fName = name ? name : "MCalibrationCam";
160 fTitle = title ? title : "Storage container for the Calibration Information in the camera";
161
162 fPixels = new TClonesArray("MCalibrationPix",1);
163 fBlindPixel = new MCalibrationBlindPix();
164 fPINDiode = new MCalibrationPINDiode();
165
166 Clear();
167}
168
169// --------------------------------------------------------------------------
170//
171// Delete the TClonesArray of MCalibrationPix containers
172// Delete the MCalibrationPINDiode and the MCalibrationBlindPix
173//
174// Delete the histograms if they exist
175//
176MCalibrationCam::~MCalibrationCam()
177{
178
179 //
180 // delete fPixels should delete all Objects stored inside
181 //
182 delete fPixels;
183 delete fBlindPixel;
184 delete fPINDiode;
185
186 if (fOffsets)
187 delete fOffsets;
188 if (fSlopes)
189 delete fSlopes;
190 if (fOffvsSlope)
191 delete fOffvsSlope;
192
193}
194
195// -------------------------------------------------------------------
196//
197// This function simply allocates memory via the ROOT command:
198// (TObject**) TStorage::ReAlloc(fCont, newSize * sizeof(TObject*),
199// fSize * sizeof(TObject*));
200// newSize corresponds to size in our case
201// fSize is the old size (in most cases: 1)
202//
203void MCalibrationCam::InitSize(const UInt_t i)
204{
205
206 //
207 // check if we have already initialized to size
208 //
209 if (CheckBounds(i))
210 return;
211
212 fPixels->ExpandCreate(i);
213
214}
215
216// --------------------------------------------------------------------------
217//
218// This function returns the current size of the TClonesArray
219// independently if the MCalibrationPix is filled with values or not.
220//
221// It is the size of the array fPixels.
222//
223Int_t MCalibrationCam::GetSize() const
224{
225 return fPixels->GetEntriesFast();
226}
227
228// --------------------------------------------------------------------------
229//
230// Check if position i is inside the current bounds of the TClonesArray
231//
232Bool_t MCalibrationCam::CheckBounds(Int_t i) const
233{
234 return i < GetSize();
235}
236
237
238// --------------------------------------------------------------------------
239//
240// Get i-th pixel (pixel number)
241//
242MCalibrationPix &MCalibrationCam::operator[](Int_t i)
243{
244 return *static_cast<MCalibrationPix*>(fPixels->UncheckedAt(i));
245}
246
247// --------------------------------------------------------------------------
248//
249// Get i-th pixel (pixel number)
250//
251MCalibrationPix &MCalibrationCam::operator[](Int_t i) const
252{
253 return *static_cast<MCalibrationPix*>(fPixels->UncheckedAt(i));
254}
255
256
257// --------------------------------------
258//
259void MCalibrationCam::Clear(Option_t *o)
260{
261
262 fPixels->ForEach(TObject, Clear)();
263 fBlindPixel->Clear();
264 fPINDiode->Clear();
265
266 fMeanFluxInsidePlexiglass = -1.;
267 fMeanFluxErrInsidePlexiglass = -1.;
268 fMeanFluxOutsidePlexiglass = -1.;
269 fMeanFluxErrOutsidePlexiglass = -1.;
270
271 fNumExcludedPixels = 0;
272
273 CLRBIT(fFlags,kBlindPixelMethodValid);
274 CLRBIT(fFlags,kPINDiodeMethodValid);
275 CLRBIT(fFlags,kFluxInsidePlexiglassAvailable);
276 CLRBIT(fFlags,kFluxOutsidePlexiglassAvailable);
277
278 return;
279}
280
281void MCalibrationCam::SetBlindPixelMethodValid(const Bool_t b)
282{
283
284 if (b)
285 SETBIT(fFlags, kBlindPixelMethodValid);
286 else
287 CLRBIT(fFlags, kBlindPixelMethodValid);
288
289}
290
291void MCalibrationCam::SetPINDiodeMethodValid(const Bool_t b)
292{
293
294 if (b)
295 SETBIT(fFlags, kPINDiodeMethodValid);
296 else
297 CLRBIT(fFlags, kPINDiodeMethodValid);
298
299
300}
301
302Bool_t MCalibrationCam::IsBlindPixelMethodValid() const
303{
304 return TESTBIT(fFlags,kBlindPixelMethodValid);
305}
306
307Bool_t MCalibrationCam::IsPINDiodeMethodValid() const
308{
309 return TESTBIT(fFlags,kPINDiodeMethodValid);
310}
311
312
313Bool_t MCalibrationCam::IsFluxInsidePlexiglassAvailable() const
314{
315 return TESTBIT(fFlags,kFluxInsidePlexiglassAvailable);
316}
317
318Bool_t MCalibrationCam::IsFluxOutsidePlexiglassAvailable() const
319{
320 return TESTBIT(fFlags,kFluxOutsidePlexiglassAvailable);
321}
322
323
324
325// --------------------------------------------------------------------------
326//
327// Print first the well fitted pixels
328// and then the ones which are not FitValid
329//
330void MCalibrationCam::Print(Option_t *o) const
331{
332
333 *fLog << all << GetDescriptor() << ":" << endl;
334 int id = 0;
335
336 *fLog << all << "Succesfully calibrated pixels:" << endl;
337 *fLog << all << endl;
338
339 TIter Next(fPixels);
340 MCalibrationPix *pix;
341 while ((pix=(MCalibrationPix*)Next()))
342 {
343
344 if (pix->IsChargeValid() && !pix->IsExcluded() && !pix->IsOscillating() && pix->IsFitted())
345 {
346
347 *fLog << all << pix->GetPixId() << " Pedestals: " << pix->GetPed() << " +- "
348 << pix->GetPedRms() << " Reduced Charge: " << pix->GetCharge() << " +- "
349 << pix->GetSigmaCharge() << " Reduced Sigma: " << pix->GetRSigmaCharge()
350 << " Nr Phe's: " << pix->GetPheFFactorMethod() << endl;
351 id++;
352 }
353 }
354
355 *fLog << all << id << " succesful pixels :-))" << endl;
356 id = 0;
357
358 *fLog << all << endl;
359 *fLog << all << "Pixels with errors:" << endl;
360 *fLog << all << endl;
361
362 TIter Next2(fPixels);
363 while ((pix=(MCalibrationPix*)Next2()))
364 {
365
366 if (!pix->IsChargeValid() && !pix->IsExcluded() && !pix->IsFitted())
367 {
368
369 *fLog << all << pix->GetPixId() << " Pedestals: " << pix->GetPed() << " +- "
370 << pix->GetPedRms() << " Reduced Charge: " << pix->GetCharge() << " +- "
371 << pix->GetSigmaCharge() << " Reduced Sigma: " << pix->GetRSigmaCharge() << endl;
372 id++;
373 }
374 }
375 *fLog << all << id << " pixels with errors :-((" << endl;
376
377 *fLog << all << endl;
378 *fLog << all << "Pixels with oscillations:" << endl;
379 *fLog << all << endl;
380
381 id = 0;
382
383 TIter Next3(fPixels);
384 while ((pix=(MCalibrationPix*)Next3()))
385 {
386
387 if (pix->IsOscillating() && !pix->IsExcluded())
388 {
389
390 *fLog << all << pix->GetPixId() << " Pedestals: " << pix->GetPed() << " +- "
391 << pix->GetPedRms() << " Reduced Charge: " << pix->GetCharge() << " +- "
392 << pix->GetSigmaCharge() << " Reduced Sigma: " << pix->GetRSigmaCharge() << endl;
393 id++;
394 }
395 }
396 *fLog << all << id << " Oscillating pixels :-((" << endl;
397
398
399 *fLog << all << endl;
400 *fLog << all << "Excluded pixels:" << endl;
401 *fLog << all << endl;
402
403 TIter Next4(fPixels);
404 while ((pix=(MCalibrationPix*)Next4()))
405 if (pix->IsExcluded())
406 *fLog << all << pix->GetPixId() << endl;
407
408 *fLog << all << fNumExcludedPixels << " excluded pixels " << endl;
409}
410
411// --------------------------------------------------------------------------
412//
413// Return true if pixel is inside bounds of the TClonesArray fPixels
414//
415Bool_t MCalibrationCam::IsPixelUsed(Int_t idx) const
416{
417 if (!CheckBounds(idx))
418 return kFALSE;
419
420 return kTRUE;
421}
422
423// --------------------------------------------------------------------------
424//
425// Return true if pixel has already been fitted once (independent of the result)
426//
427Bool_t MCalibrationCam::IsPixelFitted(Int_t idx) const
428{
429
430 if (!CheckBounds(idx))
431 return kFALSE;
432
433 return (*this)[idx].IsFitted();
434}
435
436// --------------------------------------------------------------------------
437//
438// Sets the user ranges of all histograms such that
439// empty bins at the edges are not used. Additionally, it rebins the
440// histograms such that in total, 50 bins are used.
441//
442void MCalibrationCam::CutEdges()
443{
444
445 fBlindPixel->GetHist()->CutAllEdges();
446 fPINDiode->GetHist()->CutAllEdges();
447
448 TIter Next(fPixels);
449 MCalibrationPix *pix;
450 while ((pix=(MCalibrationPix*)Next()))
451 {
452 pix->GetHist()->CutAllEdges();
453 }
454
455 return;
456}
457
458// --------------------------------------------------------------------------
459//
460// The types are as follows:
461//
462// Fitted values:
463// ==============
464//
465// 0: Fitted Charge
466// 1: Error of fitted Charge
467// 2: Sigma of fitted Charge
468// 3: Error of Sigma of fitted Charge
469//
470// Useful variables derived from the fit results:
471// =============================================
472//
473// 4: Returned probability of Gauss fit to Charge distribution
474// 5: Reduced Sigma of fitted Charge --> sqrt(sigma_Q^2 - PedRMS^2)
475// 6: Error Reduced Sigma of fitted Charge
476// 7: Reduced Sigma per Charge
477// 8: Error of Reduced Sigma per Charge
478//
479// Results of the different calibration methods:
480// =============================================
481//
482// 9: Number of Photo-electrons obtained with the F-Factor method
483// 10: Error on Number of Photo-electrons obtained with the F-Factor method
484// 11: Mean conversion factor obtained with the F-Factor method
485// 12: Error on the mean conversion factor obtained with the F-Factor method
486// 13: Overall F-Factor of the readout obtained with the F-Factor method
487// 14: Error on Overall F-Factor of the readout obtained with the F-Factor method
488// 15: Number of Photons inside Plexiglass obtained with the Blind Pixel method
489// 16: Error on Number of Photons inside Plexiglass obtained with the Blind Pixel method
490// 17: Mean conversion factor obtained with the Blind Pixel method
491// 18: Error on the mean conversion factor obtained with the Blind Pixel method
492// 19: Overall F-Factor of the readout obtained with the Blind Pixel method
493// 20: Error on Overall F-Factor of the readout obtained with the Blind Pixel method
494// 21: Number of Photons outside Plexiglass obtained with the PIN Diode method
495// 22: Error on Number of Photons outside Plexiglass obtained with the PIN Diode method
496// 23: Mean conversion factor obtained with the PIN Diode method
497// 24: Error on the mean conversion factor obtained with the PIN Diode method
498// 25: Overall F-Factor of the readout obtained with the PIN Diode method
499// 26: Error on Overall F-Factor of the readout obtained with the PIN Diode method
500//
501// Localized defects:
502// ==================
503//
504// 27: Excluded Pixels
505// 28: Pixels where the fit did not succeed --> results obtained only from the histograms
506// 29: Pixels with succeeded fit, but apparently wrong results
507// 30: Pixels with un-expected behavior in the fourier spectrum (e.g. oscillations)
508//
509// Other classifications of pixels:
510// ================================
511//
512// 31: Pixels with saturated Hi-Gain
513//
514// Classification of validity of the calibrations:
515// ===============================================
516//
517// 32: Pixels with valid calibration by the F-Factor-Method
518// 33: Pixels with valid calibration by the Blind Pixel-Method
519// 34: Pixels with valid calibration by the PIN Diode-Method
520//
521// Used Pedestals:
522// ===============
523//
524// 35: Mean Pedestal over the entire range of signal extraction
525// 36: Error on the Mean Pedestal over the entire range of signal extraction
526// 37: Pedestal RMS over the entire range of signal extraction
527// 38: Error on the Pedestal RMS over the entire range of signal extraction
528//
529// Calculated absolute arrival times (very low precision!):
530// ========================================================
531//
532// 39: Absolute Arrival time of the signal
533// 40: Error on the Absolute Arrival time of the signal
534// 41: RMS of the Absolute Arrival time of the signal
535// 42: Error on the RMS of the Absolute Arrival time of the signal
536//
537Bool_t MCalibrationCam::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const
538{
539
540 if (idx > GetSize())
541 return kFALSE;
542
543 Float_t area = cam[idx].GetA();
544
545 if (area == 0)
546 return kFALSE;
547
548 switch (type)
549 {
550 case 0:
551 if ((*this)[idx].IsExcluded())
552 return kFALSE;
553 val = (*this)[idx].GetCharge();
554 break;
555 case 1:
556 if ((*this)[idx].IsExcluded())
557 return kFALSE;
558 val = (*this)[idx].GetErrCharge();
559 break;
560 case 2:
561 if ((*this)[idx].IsExcluded())
562 return kFALSE;
563 val = (*this)[idx].GetSigmaCharge();
564 break;
565 case 3:
566 if ((*this)[idx].IsExcluded())
567 return kFALSE;
568 val = (*this)[idx].GetErrSigmaCharge();
569 break;
570 case 4:
571 if ((*this)[idx].IsExcluded())
572 return kFALSE;
573 val = (*this)[idx].GetChargeProb();
574 break;
575 case 5:
576 if ((*this)[idx].IsExcluded())
577 return kFALSE;
578 val = (*this)[idx].GetRSigmaCharge();
579 break;
580 case 6:
581 if ((*this)[idx].IsExcluded())
582 return kFALSE;
583 val = (*this)[idx].GetErrRSigmaCharge();
584 break;
585 case 7:
586 if ((*this)[idx].IsExcluded())
587 return kFALSE;
588 val = (*this)[idx].GetRSigmaCharge() / (*this)[idx].GetCharge();
589 break;
590 case 8:
591 if ((*this)[idx].IsExcluded())
592 return kFALSE;
593 // relative error RsigmaCharge square
594 val = (*this)[idx].GetErrRSigmaCharge()* (*this)[idx].GetErrRSigmaCharge()
595 / ((*this)[idx].GetRSigmaCharge() * (*this)[idx].GetRSigmaCharge() );
596 // relative error Charge square
597 val += (*this)[idx].GetErrCharge() * (*this)[idx].GetErrCharge()
598 / ((*this)[idx].GetCharge() * (*this)[idx].GetCharge() );
599 // calculate relative error out of squares
600 val = TMath::Sqrt(val) ;
601 // multiply with value to get absolute error
602 val *= (*this)[idx].GetRSigmaCharge() / (*this)[idx].GetCharge();
603 break;
604 case 9:
605 if ((*this)[idx].IsExcluded())
606 return kFALSE;
607 val = (*this)[idx].GetPheFFactorMethod();
608 break;
609 case 10:
610 if ((*this)[idx].IsExcluded())
611 return kFALSE;
612 val = (*this)[idx].GetPheFFactorMethodError();
613 break;
614 case 11:
615 if ((*this)[idx].IsExcluded())
616 return kFALSE;
617 val = (*this)[idx].GetMeanConversionFFactorMethod();
618 break;
619 case 12:
620 if ((*this)[idx].IsExcluded())
621 return kFALSE;
622 val = (*this)[idx].GetErrorConversionFFactorMethod();
623 break;
624 case 13:
625 if ((*this)[idx].IsExcluded())
626 return kFALSE;
627 val = (*this)[idx].GetTotalFFactorFFactorMethod();
628 break;
629 case 14:
630 if ((*this)[idx].IsExcluded())
631 return kFALSE;
632 val = (*this)[idx].GetTotalFFactorErrorFFactorMethod();
633 break;
634 case 15:
635 if ((*this)[idx].IsExcluded())
636 return kFALSE;
637 val = GetMeanFluxInsidePlexiglass()*area;
638 break;
639 case 16:
640 if ((*this)[idx].IsExcluded())
641 return kFALSE;
642 val = GetMeanFluxInsidePlexiglass()*area;
643 break;
644 case 17:
645 if ((*this)[idx].IsExcluded())
646 return kFALSE;
647 val = (*this)[idx].GetMeanConversionBlindPixelMethod();
648 break;
649 case 18:
650 if ((*this)[idx].IsExcluded())
651 return kFALSE;
652 val = (*this)[idx].GetErrorConversionBlindPixelMethod();
653 break;
654 case 19:
655 if ((*this)[idx].IsExcluded())
656 return kFALSE;
657 val = (*this)[idx].GetTotalFFactorBlindPixelMethod();
658 break;
659 case 20:
660 if ((*this)[idx].IsExcluded())
661 return kFALSE;
662 val = (*this)[idx].GetTotalFFactorErrorBlindPixelMethod();
663 break;
664 case 21:
665 if ((*this)[idx].IsExcluded())
666 return kFALSE;
667 val = GetMeanFluxOutsidePlexiglass()*area;
668 break;
669 case 22:
670 if ((*this)[idx].IsExcluded())
671 return kFALSE;
672 val = GetMeanFluxOutsidePlexiglass()*area;
673 break;
674 case 23:
675 if ((*this)[idx].IsExcluded())
676 return kFALSE;
677 val = (*this)[idx].GetMeanConversionPINDiodeMethod();
678 break;
679 case 24:
680 if ((*this)[idx].IsExcluded())
681 return kFALSE;
682 val = (*this)[idx].GetErrorConversionPINDiodeMethod();
683 break;
684 case 25:
685 if ((*this)[idx].IsExcluded())
686 return kFALSE;
687 val = (*this)[idx].GetTotalFFactorBlindPixelMethod();
688 break;
689 case 26:
690 if ((*this)[idx].IsExcluded())
691 return kFALSE;
692 val = (*this)[idx].GetTotalFFactorErrorBlindPixelMethod();
693 break;
694 case 27:
695 if ((*this)[idx].IsExcluded())
696 val = 1.;
697 else
698 return kFALSE;
699 break;
700 case 28:
701 if ((*this)[idx].IsExcluded())
702 return kFALSE;
703 if (!(*this)[idx].IsFitted())
704 val = 1;
705 else
706 return kFALSE;
707 break;
708 case 29:
709 if ((*this)[idx].IsExcluded())
710 return kFALSE;
711 if (!(*this)[idx].IsFitted())
712 return kFALSE;
713 if (!(*this)[idx].IsChargeValid())
714 val = 1;
715 else
716 return kFALSE;
717 break;
718 case 30:
719 if ((*this)[idx].IsExcluded())
720 return kFALSE;
721 if ((*this)[idx].IsOscillating())
722 val = 1;
723 else
724 return kFALSE;
725 break;
726 case 31:
727 if ((*this)[idx].IsExcluded())
728 return kFALSE;
729 if ((*this)[idx].IsHiGainSaturation())
730 val = 1;
731 else
732 return kFALSE;
733 break;
734 case 32:
735 if ((*this)[idx].IsExcluded())
736 return kFALSE;
737 if ((*this)[idx].IsFFactorMethodValid())
738 val = 1;
739 else
740 return kFALSE;
741 break;
742 case 33:
743 if ((*this)[idx].IsExcluded())
744 return kFALSE;
745 if ((*this)[idx].IsBlindPixelMethodValid())
746 val = 1;
747 else
748 return kFALSE;
749 break;
750 case 34:
751 if ((*this)[idx].IsExcluded())
752 return kFALSE;
753 if ((*this)[idx].IsPINDiodeMethodValid())
754 val = 1;
755 else
756 return kFALSE;
757 break;
758 case 35:
759 if ((*this)[idx].IsExcluded())
760 return kFALSE;
761 val = (*this)[idx].GetPed();
762 break;
763 case 36:
764 if ((*this)[idx].IsExcluded())
765 return kFALSE;
766 val = 1.;
767 // val = (*this)[idx].GetPedError();
768 break;
769 case 37:
770 if ((*this)[idx].IsExcluded())
771 return kFALSE;
772 val = (*this)[idx].GetPedRms();
773 break;
774 case 38:
775 if ((*this)[idx].IsExcluded())
776 return kFALSE;
777 val = 1.;
778 // val = (*this)[idx].GetPedRmsError();
779 break;
780 case 39:
781 if ((*this)[idx].IsExcluded())
782 return kFALSE;
783 val = (*this)[idx].GetAbsTimeMean();
784 break;
785 case 40:
786 if ((*this)[idx].IsExcluded())
787 return kFALSE;
788 val = (*this)[idx].GetAbsTimeMeanErr();
789 break;
790 case 41:
791 if ((*this)[idx].IsExcluded())
792 return kFALSE;
793 val = (*this)[idx].GetAbsTimeRms();
794 break;
795 case 42:
796 if ((*this)[idx].IsExcluded())
797 return kFALSE;
798 val = (*this)[idx].GetAbsTimeMeanErr()/TMath::Sqrt(2.);
799 break;
800 default:
801 return kFALSE;
802 }
803 return val!=-1.;
804}
805
806// --------------------------------------------------------------------------
807//
808// What MHCamera needs in order to draw an individual pixel in the camera
809//
810void MCalibrationCam::DrawPixelContent(Int_t idx) const
811{
812 (*this)[idx].Draw();
813}
814
815
816// --------------------------------------------------------------------------
817//
818//
819//
820Bool_t MCalibrationCam::CalcFluxInsidePlexiglass()
821{
822
823 if (!fBlindPixel->IsFitOK())
824 return kFALSE;
825
826 const Float_t mean = fBlindPixel->GetLambda();
827 const Float_t merr = fBlindPixel->GetErrLambda();
828
829 //
830 // Start calculation of number of photons
831 //
832 // The blind pixel has exactly 100 mm^2 area (with negligible error),
833 //
834 fMeanFluxInsidePlexiglass = mean*gkBlindPixelArea;
835
836 // Start calculation of number of photons relative Variance (!!)
837 fMeanFluxErrInsidePlexiglass = merr*merr/mean/mean;
838
839 switch (fColor)
840 {
841 case kECGreen:
842 fMeanFluxInsidePlexiglass /= gkCalibrationBlindPixelQEGreen;
843 fMeanFluxErrInsidePlexiglass += gkCalibrationBlindPixelQEGreenError*gkCalibrationBlindPixelQEGreenError
844 / gkCalibrationBlindPixelQEGreen / gkCalibrationBlindPixelQEGreen;
845
846 fMeanFluxInsidePlexiglass *= TMath::Power(10,gkCalibrationBlindPixelAttGreen); // correct for absorption
847 // attenuation has negligible error
848 break;
849 case kECBlue:
850 fMeanFluxInsidePlexiglass /= gkCalibrationBlindPixelQEBlue;
851 fMeanFluxErrInsidePlexiglass += gkCalibrationBlindPixelQEBlueError*gkCalibrationBlindPixelQEBlueError
852 / gkCalibrationBlindPixelQEBlue / gkCalibrationBlindPixelQEBlue;
853
854 fMeanFluxInsidePlexiglass *= TMath::Power(10,gkCalibrationBlindPixelAttBlue); // correct for absorption
855 // attenuation has negligible error
856 break;
857 case kECUV:
858 fMeanFluxInsidePlexiglass /= gkCalibrationBlindPixelQEUV;
859 fMeanFluxErrInsidePlexiglass += gkCalibrationBlindPixelQEUVError*gkCalibrationBlindPixelQEUVError
860 / gkCalibrationBlindPixelQEUV / gkCalibrationBlindPixelQEUV;
861
862 fMeanFluxInsidePlexiglass *= TMath::Power(10,gkCalibrationBlindPixelAttUV); // correct for absorption
863 // attenuation has negligible error
864 break;
865 case kECCT1:
866 default:
867 fMeanFluxInsidePlexiglass /= gkCalibrationBlindPixelQECT1;
868 fMeanFluxErrInsidePlexiglass += gkCalibrationBlindPixelQECT1Error*gkCalibrationBlindPixelQECT1Error
869 / gkCalibrationBlindPixelQECT1 / gkCalibrationBlindPixelQECT1;
870
871 fMeanFluxInsidePlexiglass *= TMath::Power(10,gkCalibrationBlindPixelAttCT1); // correct for absorption
872 // attenuation has negligible error
873 break;
874 }
875
876 *fLog << inf << endl;
877 *fLog << inf << " Photon flux [ph/mm^2] inside Plexiglass: "
878 << fMeanFluxInsidePlexiglass << endl;
879
880 if (fMeanFluxInsidePlexiglass > 0.)
881 SETBIT(fFlags,kFluxInsidePlexiglassAvailable);
882 else
883 {
884 CLRBIT(fFlags,kFluxInsidePlexiglassAvailable);
885 return kFALSE;
886 }
887
888 if (fMeanFluxErrInsidePlexiglass < 0.)
889 {
890 *fLog << warn << " Relative Variance on Photon flux inside Plexiglass: "
891 << fMeanFluxErrInsidePlexiglass << endl;
892 CLRBIT(fFlags,kFluxInsidePlexiglassAvailable);
893 return kFALSE;
894 }
895
896 // Finish calculation of errors -> convert from relative variance to absolute error
897 fMeanFluxErrInsidePlexiglass = TMath::Sqrt(fMeanFluxErrInsidePlexiglass);
898 fMeanFluxErrInsidePlexiglass *= fMeanFluxInsidePlexiglass;
899
900 *fLog << inf << " Error on photon flux [ph/mm^2] inside Plexiglass: "
901 << fMeanFluxErrInsidePlexiglass << endl;
902 *fLog << inf << endl;
903
904 TIter Next(fPixels);
905 MCalibrationPix *pix;
906 while ((pix=(MCalibrationPix*)Next()))
907 {
908
909 if(pix->IsChargeValid())
910 {
911
912 const Int_t idx = pix->GetPixId();
913
914 const Float_t charge = pix->GetCharge();
915 const Float_t area = (*fGeomCam)[idx].GetA();
916 const Float_t chargeerr = pix->GetErrCharge();
917
918 const Float_t nphot = fMeanFluxInsidePlexiglass*area;
919 const Float_t nphoterr = fMeanFluxErrInsidePlexiglass*area;
920 const Float_t conversion = nphot/charge;
921 Float_t conversionerr;
922
923 conversionerr = nphoterr/charge
924 * nphoterr/charge ;
925 conversionerr += chargeerr/charge
926 * chargeerr/charge
927 * conversion*conversion;
928 conversionerr = TMath::Sqrt(conversionerr);
929
930 const Float_t conversionsigma = 0.;
931
932 pix->SetConversionBlindPixelMethod(conversion, conversionerr, conversionsigma);
933
934 if (conversionerr/conversion < 0.1)
935 pix->SetBlindPixelMethodValid();
936 }
937 }
938 return kTRUE;
939}
940
941
942Bool_t MCalibrationCam::CalcFluxOutsidePlexiglass()
943{
944
945 if (!fPINDiode->IsChargeFitValid())
946 return kFALSE;
947
948 const Float_t mean = fPINDiode->GetCharge();
949 const Float_t merr = fPINDiode->GetErrCharge();
950
951 // Start calculation of number of photons per mm^2 on the camera
952 fMeanFluxOutsidePlexiglass = mean * gkPINDiodeArea;
953 // Correct for the distance between camera and PIN Diode and for different areas.
954 fMeanFluxOutsidePlexiglass *= gkCalibrationFluxCameravsPINDiode;
955
956 // Start calculation of number of photons relative Variance (!!)
957 fMeanFluxErrOutsidePlexiglass = merr*merr/mean/mean;
958 fMeanFluxErrOutsidePlexiglass += gkCalibrationFluxCameravsPINDiodeError*gkCalibrationFluxCameravsPINDiodeError
959 / gkCalibrationFluxCameravsPINDiode/gkCalibrationFluxCameravsPINDiode;
960
961 switch (fColor)
962 {
963 case kECGreen:
964 fMeanFluxOutsidePlexiglass /= gkCalibrationPINDiodeQEGreen;
965 fMeanFluxErrOutsidePlexiglass += gkCalibrationPINDiodeQEGreenError*gkCalibrationPINDiodeQEGreenError
966 / gkCalibrationPINDiodeQEGreen/gkCalibrationPINDiodeQEGreen;
967 break;
968 case kECBlue:
969 fMeanFluxOutsidePlexiglass /= gkCalibrationPINDiodeQEBlue;
970 fMeanFluxErrOutsidePlexiglass += gkCalibrationPINDiodeQEBlueError*gkCalibrationPINDiodeQEBlueError
971 / gkCalibrationPINDiodeQEBlue/gkCalibrationPINDiodeQEBlue;
972 break;
973 case kECUV:
974 fMeanFluxOutsidePlexiglass /= gkCalibrationPINDiodeQEUV;
975 fMeanFluxErrOutsidePlexiglass += gkCalibrationPINDiodeQEUVError*gkCalibrationPINDiodeQEUVError
976 / gkCalibrationPINDiodeQEUV/gkCalibrationPINDiodeQEUV;
977 break;
978 case kECCT1:
979 default:
980 fMeanFluxOutsidePlexiglass /= gkCalibrationPINDiodeQECT1;
981 fMeanFluxErrOutsidePlexiglass += gkCalibrationPINDiodeQECT1Error*gkCalibrationPINDiodeQECT1Error
982 / gkCalibrationPINDiodeQECT1/gkCalibrationPINDiodeQECT1;
983 break;
984 }
985
986
987 *fLog << inf << endl;
988 *fLog << inf << " Mean Photon flux [ph/mm^2] outside Plexiglass: "
989 << fMeanFluxOutsidePlexiglass << endl;
990
991 if (fMeanFluxOutsidePlexiglass > 0.)
992 SETBIT(fFlags,kFluxOutsidePlexiglassAvailable);
993 else
994 {
995 CLRBIT(fFlags,kFluxOutsidePlexiglassAvailable);
996 return kFALSE;
997 }
998
999 if (fMeanFluxErrOutsidePlexiglass < 0.)
1000 {
1001 *fLog << warn << "Relative Variance on Photon flux outside Plexiglass: "
1002 << fMeanFluxErrOutsidePlexiglass << endl;
1003 CLRBIT(fFlags,kFluxOutsidePlexiglassAvailable);
1004 return kFALSE;
1005 }
1006
1007 // Finish calculation of errors -> convert from relative variance to absolute error
1008 fMeanFluxErrOutsidePlexiglass = TMath::Sqrt(fMeanFluxErrOutsidePlexiglass);
1009 fMeanFluxErrOutsidePlexiglass *= fMeanFluxOutsidePlexiglass;
1010
1011 *fLog << inf << " Error on Photon flux [ph/mm^2] outside Plexiglass: "
1012 << fMeanFluxErrOutsidePlexiglass << endl;
1013 *fLog << inf << endl;
1014
1015 TIter Next(fPixels);
1016 MCalibrationPix *pix;
1017 while ((pix=(MCalibrationPix*)Next()))
1018 {
1019
1020 if (pix->IsChargeValid())
1021 {
1022
1023 const Int_t idx = pix->GetPixId();
1024
1025 const Float_t charge = pix->GetCharge();
1026 const Float_t area = (*fGeomCam)[idx].GetA();
1027 const Float_t chargeerr = pix->GetErrCharge();
1028
1029 const Float_t nphot = fMeanFluxOutsidePlexiglass*area;
1030 const Float_t nphoterr = fMeanFluxErrOutsidePlexiglass*area;
1031 const Float_t conversion = nphot/charge;
1032
1033 Float_t conversionerr;
1034
1035 conversionerr = nphoterr/charge
1036 * nphoterr/charge ;
1037 conversionerr += chargeerr/charge
1038 * chargeerr/charge
1039 * conversion*conversion;
1040 if (conversionerr > 0.)
1041 conversionerr = TMath::Sqrt(conversionerr);
1042
1043 const Float_t conversionsigma = 0.;
1044
1045 pix->SetConversionPINDiodeMethod(conversion, conversionerr, conversionsigma);
1046
1047 if (conversionerr/conversion < 0.1)
1048 pix->SetPINDiodeMethodValid();
1049
1050 }
1051 }
1052 return kTRUE;
1053}
1054
1055
1056
1057Bool_t MCalibrationCam::GetConversionFactorBlindPixel(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
1058{
1059
1060 if (ipx < 0 || !IsPixelFitted(ipx))
1061 return kFALSE;
1062
1063 if (!IsFluxInsidePlexiglassAvailable())
1064 if (!CalcFluxInsidePlexiglass())
1065 return kFALSE;
1066
1067 mean = (*this)[ipx].GetMeanConversionBlindPixelMethod();
1068 err = (*this)[ipx].GetErrorConversionBlindPixelMethod();
1069 sigma = (*this)[ipx].GetSigmaConversionBlindPixelMethod();
1070
1071 return kTRUE;
1072}
1073
1074
1075Bool_t MCalibrationCam::GetConversionFactorFFactor(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
1076{
1077
1078 if (ipx < 0 || !IsPixelFitted(ipx))
1079 return kFALSE;
1080
1081 Float_t conv = (*this)[ipx].GetMeanConversionFFactorMethod();
1082
1083 if (conv < 0.)
1084 return kFALSE;
1085
1086 mean = conv;
1087 err = (*this)[ipx].GetErrorConversionFFactorMethod();
1088 sigma = (*this)[ipx].GetSigmaConversionFFactorMethod();
1089
1090 return kTRUE;
1091}
1092
1093
1094//-----------------------------------------------------------------------------------
1095//
1096// Calculates the conversion factor between the integral of FADCs slices
1097// (as defined in the signal extractor MExtractSignal.cc)
1098// and the number of photons reaching the plexiglass for one Inner Pixel
1099//
1100// FIXME: The PINDiode is still not working and so is the code
1101//
1102Bool_t MCalibrationCam::GetConversionFactorPINDiode(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
1103{
1104
1105 if (ipx < 0 || !IsPixelFitted(ipx))
1106 return kFALSE;
1107
1108 if (!IsFluxOutsidePlexiglassAvailable())
1109 if (!CalcFluxOutsidePlexiglass())
1110 return kFALSE;
1111
1112 mean = (*this)[ipx].GetMeanConversionPINDiodeMethod();
1113 err = (*this)[ipx].GetErrorConversionPINDiodeMethod();
1114 sigma = (*this)[ipx].GetSigmaConversionPINDiodeMethod();
1115
1116 return kFALSE;
1117
1118}
1119
1120//-----------------------------------------------------------------------------------
1121//
1122// Calculates the best combination of the three used methods possible
1123// between the integral of FADCs slices
1124// (as defined in the signal extractor MExtractSignal.cc)
1125// and the number of photons reaching one Inner Pixel.
1126// The procedure is not yet defined.
1127//
1128// FIXME: The PINDiode is still not working and so is the code
1129//
1130Bool_t MCalibrationCam::GetConversionFactorCombined(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
1131{
1132
1133 if (ipx < 0 || !IsPixelFitted(ipx))
1134 return kFALSE;
1135
1136 return kFALSE;
1137
1138}
1139
1140
1141void MCalibrationCam::DrawHiLoFits()
1142{
1143
1144 if (!fOffsets)
1145 fOffsets = new TH1D("pp","Offsets of the HiGain LoGain Fit",100,-600.,400.);
1146 if (!fSlopes)
1147 fSlopes = new TH1D("mm","Slopes of the HiGain LoGain Fit",100,-2.,2.);
1148 if (!fOffvsSlope)
1149 fOffvsSlope = new TH2D("aa","Slopes vs Offsets of the HiGain LoGain Fit",100,-600.,400.,100,-2.,2.);
1150
1151 TIter Next(fPixels);
1152 MCalibrationPix *pix;
1153 MHCalibrationPixel *hist;
1154 while ((pix=(MCalibrationPix*)Next()))
1155 {
1156 hist = pix->GetHist();
1157 hist->FitHiGainvsLoGain();
1158 fOffsets->Fill(hist->GetOffset(),1.);
1159 fSlopes->Fill(hist->GetSlope(),1.);
1160 fOffvsSlope->Fill(hist->GetOffset(),hist->GetSlope(),1.);
1161 }
1162
1163 TCanvas *c1 = new TCanvas();
1164
1165 c1->Divide(1,3);
1166 c1->cd(1);
1167 fOffsets->Draw();
1168 gPad->Modified();
1169 gPad->Update();
1170
1171 c1->cd(2);
1172 fSlopes->Draw();
1173 gPad->Modified();
1174 gPad->Update();
1175
1176 c1->cd(3);
1177 fOffvsSlope->Draw("col1");
1178 gPad->Modified();
1179 gPad->Update();
1180}
1181
Note: See TracBrowser for help on using the repository browser.