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

Last change on this file since 2880 was 2880, checked in by gaug, 21 years ago
*** empty log message ***
File size: 18.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// 4)
38//
39/////////////////////////////////////////////////////////////////////////////
40#include "MCalibrationCam.h"
41#include "MCalibrationPix.h"
42#include "MHCalibrationPixel.h"
43#include "MCalibrationBlindPix.h"
44#include "MCalibrationConfig.h"
45
46#include <TClonesArray.h>
47
48#include "MLog.h"
49#include "MLogManip.h"
50
51#include "TCanvas.h"
52
53#include "MGeomCam.h"
54
55ClassImp(MCalibrationCam);
56
57using namespace std;
58// --------------------------------------------------------------------------
59//
60// Default constructor.
61//
62// Creates a TClonesArray of MCalibrationPix containers, initialized to 1 entry
63// Later, a call to MCalibrationCam::InitSize(Int_t size) has to be performed
64//
65// Creates an MCalibrationBlindPix container
66// Creates an MCalibrationPINDiode container
67//
68MCalibrationCam::MCalibrationCam(const char *name, const char *title)
69 : fNumPhotInsidePlexiglassAvailable(kFALSE),
70 fMeanPhotInsidePlexiglass(-1.),
71 fMeanPhotErrInsidePlexiglass(-1.),
72 fNumPhotOutsidePlexiglassAvailable(kFALSE),
73 fMeanPhotOutsidePlexiglass(-1.),
74 fMeanPhotErrOutsidePlexiglass(-1.),
75 fOffsets(NULL),
76 fSlopes(NULL),
77 fOffvsSlope(NULL),
78 fNumExcludedPixels(0)
79
80{
81 fName = name ? name : "MCalibrationCam";
82 fTitle = title ? title : "Storage container for the Calibration Information in the camera";
83
84 fPixels = new TClonesArray("MCalibrationPix",1);
85 fBlindPixel = new MCalibrationBlindPix();
86 fPINDiode = new MCalibrationPINDiode();
87
88}
89
90// --------------------------------------------------------------------------
91//
92// Delete the TClonesArray of MCalibrationPix containers
93// Delete the MCalibrationPINDiode and the MCalibrationBlindPix
94//
95// Delete the histograms if they exist
96//
97MCalibrationCam::~MCalibrationCam()
98{
99
100 //
101 // delete fPixels should delete all Objects stored inside
102 //
103 delete fPixels;
104 delete fBlindPixel;
105 delete fPINDiode;
106
107 if (fOffsets)
108 delete fOffsets;
109 if (fSlopes)
110 delete fSlopes;
111 if (fOffvsSlope)
112 delete fOffvsSlope;
113
114}
115
116// -------------------------------------------------------------------
117//
118// This function simply allocates memory via the ROOT command:
119// (TObject**) TStorage::ReAlloc(fCont, newSize * sizeof(TObject*),
120// fSize * sizeof(TObject*));
121// newSize corresponds to size in our case
122// fSize is the old size (in most cases: 1)
123//
124void MCalibrationCam::InitSize(Int_t size)
125{
126
127 //
128 // check if we have already initialized to size
129 //
130 if (CheckBounds(size))
131 return;
132
133 fPixels->ExpandCreate(size);
134
135}
136
137// --------------------------------------------------------------------------
138//
139// This function returns the current size of the TClonesArray
140// independently if the MCalibrationPix is filled with values or not.
141//
142// It is the size of the array fPixels.
143//
144Int_t MCalibrationCam::GetSize() const
145{
146 return fPixels->GetEntriesFast();
147}
148
149// --------------------------------------------------------------------------
150//
151// Check if position i is inside the current bounds of the TClonesArray
152//
153Bool_t MCalibrationCam::CheckBounds(Int_t i) const
154{
155 return i < fPixels->GetEntriesFast();
156}
157
158
159// --------------------------------------------------------------------------
160//
161// Get i-th pixel (pixel number)
162//
163MCalibrationPix &MCalibrationCam::operator[](Int_t i)
164{
165
166 if (!CheckBounds(i))
167 return *static_cast<MCalibrationPix*>(NULL);
168
169 return *static_cast<MCalibrationPix*>(fPixels->UncheckedAt(i));
170}
171
172// --------------------------------------------------------------------------
173//
174// Get i-th pixel (pixel number)
175//
176MCalibrationPix &MCalibrationCam::operator[](Int_t i) const
177{
178
179 if (!CheckBounds(i))
180 return *static_cast<MCalibrationPix*>(NULL);
181
182 return *static_cast<MCalibrationPix*>(fPixels->UncheckedAt(i));
183}
184
185
186// --------------------------------------------------------------------------
187//
188// Return true if pixel is inside bounds of the TClonesArray fPixels
189//
190Bool_t MCalibrationCam::IsPixelUsed(Int_t idx) const
191{
192 if (!CheckBounds(idx))
193 return kFALSE;
194
195 return kTRUE;
196}
197
198// --------------------------------------------------------------------------
199//
200// Return true if pixel has already been fitted once (independent of the result)
201//
202Bool_t MCalibrationCam::IsPixelFitted(Int_t idx) const
203{
204
205 if (!CheckBounds(idx))
206 return kFALSE;
207
208 return (*this)[idx].IsFitted();
209}
210
211
212// --------------------------------------
213//
214void MCalibrationCam::Clear(Option_t *o)
215{
216 fPixels->ForEach(TObject, Clear)();
217}
218
219// --------------------------------------------------------------------------
220//
221// Sets the user ranges of all histograms such that
222// empty bins at the edges are not used. Additionally, it rebins the
223// histograms such that in total, 50 bins are used.
224//
225void MCalibrationCam::CutEdges()
226{
227
228 fBlindPixel->GetHist()->CutAllEdges();
229 fPINDiode->GetHist()->CutAllEdges();
230
231 TIter Next(fPixels);
232 MCalibrationPix *pix;
233 while ((pix=(MCalibrationPix*)Next()))
234 {
235 pix->GetHist()->CutAllEdges();
236 }
237
238 return;
239}
240
241// --------------------------------------------------------------------------
242//
243// Print first the well fitted pixels
244// and then the ones which are not FitValid
245//
246void MCalibrationCam::Print(Option_t *o) const
247{
248
249 *fLog << all << GetDescriptor() << ":" << endl;
250 int id = 0;
251
252 *fLog << all << "Succesfully calibrated pixels:" << endl;
253 *fLog << all << endl;
254
255 TIter Next(fPixels);
256 MCalibrationPix *pix;
257 while ((pix=(MCalibrationPix*)Next()))
258 {
259
260 if (pix->IsFitValid() && !pix->IsExcluded())
261 {
262
263 Float_t rsigma = pix->GetRSigmaSquare();
264 if (rsigma > 0.)
265 rsigma = TMath::Sqrt(rsigma);
266
267 *fLog << all << pix->GetPixId() << " Pedestals: " << pix->GetPed() << " +- "
268 << pix->GetPedRms() << " Reduced Charge: " << pix->GetCharge() << " +- "
269 << pix->GetSigmaCharge() << " Reduced Sigma: " << rsigma
270 << " Nr Phe's: " << pix->GetPheFFactorMethod() << endl;
271 id++;
272 }
273 }
274
275 *fLog << all << id << " succesful pixels :-))" << endl;
276 id = 0;
277
278 *fLog << all << endl;
279 *fLog << all << "Pixels with errors:" << endl;
280 *fLog << all << endl;
281
282 TIter Next2(fPixels);
283 while ((pix=(MCalibrationPix*)Next2()))
284 {
285
286 if (!pix->IsFitValid() && !pix->IsExcluded())
287 {
288
289 Float_t rsigma = pix->GetRSigmaSquare();
290 if (rsigma > 0.)
291 rsigma = TMath::Sqrt(rsigma);
292
293 *fLog << all << pix->GetPixId() << " Pedestals: " << pix->GetPed() << " +- "
294 << pix->GetPedRms() << " Reduced Charge: " << pix->GetCharge() << " +- "
295 << pix->GetSigmaCharge() << " Reduced Sigma: " << rsigma << endl;
296 id++;
297 }
298 }
299 *fLog << all << id << " pixels with errors :-((" << endl;
300
301 *fLog << all << endl;
302 *fLog << all << "Excluded pixels:" << endl;
303 *fLog << all << endl;
304
305 TIter Next3(fPixels);
306 while ((pix=(MCalibrationPix*)Next3()))
307 if (pix->IsExcluded())
308 *fLog << all << pix->GetPixId() << endl;
309
310 *fLog << all << fNumExcludedPixels << " excluded pixels " << endl;
311
312}
313
314// The types are as follows:
315//
316// 0: Fitted Charge
317// 1: Error of fitted Charge
318// 2: Sigma of fitted Charge
319// 3: Error of Sigma of fitted Charge
320// 4: Returned probability of Gauss fit to Charge distribution
321// 5: Mean arrival time
322// 6: Sigma of the arrival time
323// 7: Chi-square of the Gauss fit to the arrival times
324// 8: Pedestal
325// 9: Pedestal RMS
326// 10: Reduced Sigma Square
327// 11: Number of Photo-electrons after the F-Factor method
328// 12: Error on the Number of Photo-electrons after the F-Factor method
329// 13: Mean conversion factor after the F-Factor method
330// 14: Error on the conversion factor after the F-Factor method
331// 15: Number of Photons after the Blind Pixel method
332// 16: Mean conversion factor after the Blind Pixel method
333//
334Bool_t MCalibrationCam::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const
335{
336
337 if (idx > GetSize())
338 return kFALSE;
339
340 if (!(*this)[idx].IsFitValid())
341 {
342 val = -1.;
343 return kFALSE;
344 }
345
346 switch (type)
347 {
348 case 0:
349 val = (*this)[idx].GetCharge();
350 break;
351 case 1:
352 val = (*this)[idx].GetErrCharge();
353 break;
354 case 2:
355 val = (*this)[idx].GetSigmaCharge();
356 break;
357 case 3:
358 val = (*this)[idx].GetErrSigmaCharge();
359 break;
360 case 4:
361 val = (*this)[idx].GetChargeProb();
362 break;
363 case 5:
364 val = (*this)[idx].GetTime();
365 break;
366 case 6:
367 val = (*this)[idx].GetSigmaTime();
368 break;
369 case 7:
370 val = (*this)[idx].GetTimeChiSquare();
371 break;
372 case 8:
373 val = (*this)[idx].GetPed();
374 break;
375 case 9:
376 val = (*this)[idx].GetPedRms();
377 break;
378 case 10:
379 if ((*this)[idx].GetRSigmaSquare() > 0.)
380 val = TMath::Sqrt((*this)[idx].GetRSigmaSquare());
381 else
382 val = -1.;
383 break;
384 case 11:
385 val = (*this)[idx].GetPheFFactorMethod();
386 break;
387 case 12:
388 val = (*this)[idx].GetPheFFactorMethodError();
389 break;
390 case 13:
391 val = (*this)[idx].GetMeanConversionFFactorMethod();
392 break;
393 case 14:
394 val = (*this)[idx].GetErrorConversionFFactorMethod();
395 break;
396 case 15:
397 if (idx < 397)
398 val = (double)fMeanPhotInsidePlexiglass;
399 else
400 val = (double)fMeanPhotInsidePlexiglass*gkCalibrationOutervsInnerPixelArea;
401 break;
402 case 16:
403 if (idx < 397)
404 val = (*this)[idx].GetMeanConversionBlindPixelMethod();
405 else
406 val = (*this)[idx].GetMeanConversionBlindPixelMethod()*gkCalibrationOutervsInnerPixelArea;
407 break;
408 case 17:
409 if ( (*this)[idx].GetRSigmaSquare() > 0. && (*this)[idx].GetCharge() > 0. )
410 val = TMath::Sqrt((*this)[idx].GetRSigmaSquare()) / (*this)[idx].GetCharge();
411 else
412 val = -1.;
413 break;
414 default:
415 return kFALSE;
416 }
417 return val!=-1.;
418}
419
420// --------------------------------------------------------------------------
421//
422// What MHCamera needs in order to draw an individual pixel in the camera
423//
424void MCalibrationCam::DrawPixelContent(Int_t idx) const
425{
426 (*this)[idx].Draw();
427}
428
429
430// --------------------------------------------------------------------------
431//
432//
433//
434Bool_t MCalibrationCam::CalcNumPhotInsidePlexiglass()
435{
436
437 if (!fBlindPixel->IsFitOK())
438 return kFALSE;
439
440 const Float_t mean = fBlindPixel->GetLambda();
441 const Float_t merr = fBlindPixel->GetErrLambda();
442
443 switch (fColor)
444 {
445 case kECGreen:
446 fMeanPhotInsidePlexiglass = (mean / gkCalibrationBlindPixelQEGreen) // real photons
447 *TMath::Power(10,gkCalibrationBlindPixelAttGreen) // correct for absorption
448 * gkCalibrationInnerPixelArea; // correct for area
449
450
451 break;
452 case kECBlue:
453 fMeanPhotInsidePlexiglass = (mean / gkCalibrationBlindPixelQEBlue )
454 *TMath::Power(10,gkCalibrationBlindPixelAttBlue)
455 * gkCalibrationInnerPixelArea;
456 break;
457 case kECUV:
458 fMeanPhotInsidePlexiglass = (mean / gkCalibrationBlindPixelQEUV )
459 *TMath::Power(10,gkCalibrationBlindPixelAttUV)
460 * gkCalibrationInnerPixelArea;
461 break;
462 case kECCT1:
463 default:
464 fMeanPhotInsidePlexiglass = (mean / gkCalibrationBlindPixelQECT1 )
465 *TMath::Power(10,gkCalibrationBlindPixelAttCT1)
466 * gkCalibrationInnerPixelArea;
467 break;
468 }
469
470 fNumPhotInsidePlexiglassAvailable = kTRUE;
471
472 *fLog << inf << endl;
473 *fLog << inf << mean << " Mean number of Photons for an Inner Pixel (inside Plexiglass): "
474 << fMeanPhotInsidePlexiglass << endl;
475 *fLog << inf << endl;
476
477 TIter Next(fPixels);
478 MCalibrationPix *pix;
479 while ((pix=(MCalibrationPix*)Next()))
480 {
481 if((pix->GetCharge() > 0.) && (fMeanPhotInsidePlexiglass > 0.))
482 {
483
484 Float_t conversion = fMeanPhotInsidePlexiglass/pix->GetCharge();
485 Float_t conversionerr = 0.;
486 Float_t conversionsigma = 0.;
487 pix->SetConversionBlindPixelMethod(conversion, conversionerr, conversionsigma);
488
489 if (conversionerr/conversion < 0.1)
490 pix->SetBlindPixelMethodValid();
491 }
492 }
493 return kTRUE;
494}
495
496
497Bool_t MCalibrationCam::CalcNumPhotOutsidePlexiglass()
498{
499
500 if (!fPINDiode->IsFitOK())
501 return kFALSE;
502
503 const Float_t mean = fPINDiode->GetMean();
504 const Float_t merr = fPINDiode->GetMeanError();
505
506 switch (fColor)
507 {
508 case kECGreen:
509 fMeanPhotOutsidePlexiglass = (mean / gkCalibrationPINDiodeQEGreen) // real photons
510 * gkCalibrationInnerPixelvsPINDiodeArea; // correct for area
511 break;
512 case kECBlue:
513 fMeanPhotOutsidePlexiglass = (mean / gkCalibrationPINDiodeQEBlue )
514 * gkCalibrationInnerPixelvsPINDiodeArea;
515 break;
516 case kECUV:
517 fMeanPhotOutsidePlexiglass = (mean / gkCalibrationPINDiodeQEUV )
518 * gkCalibrationInnerPixelvsPINDiodeArea;
519 break;
520 case kECCT1:
521 default:
522 fMeanPhotOutsidePlexiglass = (mean / gkCalibrationPINDiodeQECT1 )
523 * gkCalibrationInnerPixelvsPINDiodeArea;
524 break;
525 }
526
527 fNumPhotOutsidePlexiglassAvailable = kTRUE;
528
529 *fLog << inf << endl;
530 *fLog << inf << mean << " Mean number of Photons for an Inner Pixel (outside Plexiglass): "
531 << fMeanPhotOutsidePlexiglass << endl;
532 *fLog << inf << endl;
533
534 TIter Next(fPixels);
535 MCalibrationPix *pix;
536 while ((pix=(MCalibrationPix*)Next()))
537 {
538
539 if((pix->GetCharge() > 0.) && (fMeanPhotInsidePlexiglass > 0.))
540 pix->SetConversionPINDiodeMethod(fMeanPhotOutsidePlexiglass/pix->GetCharge(), 0., 0.);
541 }
542 return kTRUE;
543}
544
545
546
547Bool_t MCalibrationCam::GetConversionFactorBlindPixel(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
548{
549
550 if (ipx < 0 || !IsPixelFitted(ipx))
551 return kFALSE;
552
553 if (!fNumPhotInsidePlexiglassAvailable)
554 if (!CalcNumPhotInsidePlexiglass())
555 return kFALSE;
556
557 mean = (*this)[ipx].GetMeanConversionBlindPixelMethod();
558 err = (*this)[ipx].GetErrorConversionBlindPixelMethod();
559 sigma = (*this)[ipx].GetSigmaConversionBlindPixelMethod();
560
561 return kTRUE;
562}
563
564
565Bool_t MCalibrationCam::GetConversionFactorFFactor(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
566{
567
568 if (ipx < 0 || !IsPixelFitted(ipx))
569 return kFALSE;
570
571 Float_t conv = (*this)[ipx].GetMeanConversionFFactorMethod();
572
573 if (conv < 0.)
574 return kFALSE;
575
576 mean = conv;
577 err = (*this)[ipx].GetErrorConversionFFactorMethod();
578 sigma = (*this)[ipx].GetSigmaConversionFFactorMethod();
579
580 return kTRUE;
581}
582
583
584//-----------------------------------------------------------------------------------
585//
586// Calculates the conversion factor between the integral of FADCs slices
587// (as defined in the signal extractor MExtractSignal.cc)
588// and the number of photons reaching the plexiglass for one Inner Pixel
589//
590// FIXME: The PINDiode is still not working and so is the code
591//
592Bool_t MCalibrationCam::GetConversionFactorPINDiode(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
593{
594
595 if (ipx < 0 || !IsPixelFitted(ipx))
596 return kFALSE;
597
598 return kFALSE;
599
600}
601
602//-----------------------------------------------------------------------------------
603//
604// Calculates the best combination of the three used methods possible
605// between the integral of FADCs slices
606// (as defined in the signal extractor MExtractSignal.cc)
607// and the number of photons reaching one Inner Pixel.
608// The procedure is not yet defined.
609//
610// FIXME: The PINDiode is still not working and so is the code
611//
612Bool_t MCalibrationCam::GetConversionFactorCombined(Int_t ipx, Float_t &mean, Float_t &err, Float_t &sigma)
613{
614
615 if (ipx < 0 || !IsPixelFitted(ipx))
616 return kFALSE;
617
618 return kFALSE;
619
620}
621
622
623void MCalibrationCam::DrawHiLoFits()
624{
625
626 if (!fOffsets)
627 fOffsets = new TH1D("pp","Offsets of the HiGain LoGain Fit",100,-600.,400.);
628 if (!fSlopes)
629 fSlopes = new TH1D("mm","Slopes of the HiGain LoGain Fit",100,-2.,2.);
630 if (!fOffvsSlope)
631 fOffvsSlope = new TH2D("aa","Slopes vs Offsets of the HiGain LoGain Fit",100,-600.,400.,100,-2.,2.);
632
633 TIter Next(fPixels);
634 MCalibrationPix *pix;
635 MHCalibrationPixel *hist;
636 while ((pix=(MCalibrationPix*)Next()))
637 {
638 hist = pix->GetHist();
639 hist->FitHiGainvsLoGain();
640 fOffsets->Fill(hist->GetOffset(),1.);
641 fSlopes->Fill(hist->GetSlope(),1.);
642 fOffvsSlope->Fill(hist->GetOffset(),hist->GetSlope(),1.);
643 }
644
645 TCanvas *c1 = new TCanvas();
646
647 c1->Divide(1,3);
648 c1->cd(1);
649 fOffsets->Draw();
650 gPad->Modified();
651 gPad->Update();
652
653 c1->cd(2);
654 fSlopes->Draw();
655 gPad->Modified();
656 gPad->Update();
657
658 c1->cd(3);
659 fOffvsSlope->Draw("col1");
660 gPad->Modified();
661 gPad->Update();
662}
663
Note: See TracBrowser for help on using the repository browser.