source: trunk/MagicSoft/Mars/mjobs/MJCalibration.cc @ 8898

Last change on this file since 8898 was 8898, checked in by tbretz, 13 years ago
*** empty log message ***
File size: 65.7 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): Thomas Bretz, 1/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!   Author(s): Markus Gaug, 02/2004 <mailto:markus@ifae.es>
20!
21!   Copyright: MAGIC Software Development, 2000-2008
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28//  MJCalibration
29//
30//  Do one calibration loop over serious of runs with the same pulser
31//  colour and the same intensity. The following containers (rectangular) and
32//  tasks (ellipses) are called to produce an MCalibrationChargeCam and to
33//  update the MCalibrationQECam: (MCalibrate is not called from this class)
34//
35//Begin_Html
36/*
37<img src="images/CalibClasses.gif">
38*/
39//End_Html
40//
41// Different signal extractors can be set with the command SetExtractor()
42// Only extractors deriving from MExtractor can be set, default is MExtractSlidingWindow
43//
44// Different arrival time extractors can be set with the command SetTimeExtractor()
45// Only extractors deriving from MExtractTime can be set, default is MExtractTimeHighestIntegral
46//
47// At the end of the eventloop, plots and results are displayed, depending on
48// the flags set (see DisplayResult())
49//
50// If the flag SetFullDisplay() is set, all MHCameras will be displayed.
51// if the flag SetDataCheckDisplay() is set, only the most important ones are displayed
52// Otherwise, (default: SetNormalDisplay()), a good selection of plots is given
53//
54// The absolute light calibration devices Blind Pixel and PIN Diode can be switched on
55// and off with the commands:
56//
57// - SetUseBlindPixel(Bool_t )
58// - SetUsePINDiode(Bool_t )
59//
60// See also: MHCalibrationChargePix, MHCalibrationChargeCam, MHGausEvents
61//           MHCalibrationChargeBlindPix, MHCalibrationChargePINDiode
62//           MCalibrationChargePix, MCalibrationChargeCam, MCalibrationChargeCalc
63//           MCalibrationBlindPix, MCalibrationChargePINDiode,
64//           MCalibrationQECam, MBadPixelsPix, MBadPixelsCam
65//
66// If the flag RelTimeCalibration() is set, a calibration of the relative arrival
67// times is also performed. The following containers (rectangular) and
68// tasks (ellipses) are called to produce an MCalibrationRelTimeCam used by 
69// MCalibrateTime to correct timing offset between pixels: (MCalibrateTime is not
70// called from this class)
71//
72//Begin_Html
73/*
74<img src="images/RelTimeClasses.gif">
75*/
76//End_Html
77//
78// Different arrival time extractors can be set directly with the command
79// SetTimeExtractor(MExtractor *)
80//
81// Resource file entries are case sensitive!
82//
83// See also: MHCalibrationRelTimePix, MHCalibrationRelTimeCam, MHGausEvents
84//           MCalibrationRelTimePix, MCalibrationRelTimeCam
85//           MBadPixelsPix, MBadPixelsCam
86//
87/////////////////////////////////////////////////////////////////////////////
88#include "MJCalibration.h"
89
90#include <TFile.h>
91#include <TF1.h>
92#include <TStyle.h>
93#include <TCanvas.h>
94#include <TSystem.h>
95#include <TLine.h>
96#include <TLatex.h>
97#include <TLegend.h>
98#include <TRegexp.h>
99#include <TPaveText.h>
100#include <TPaveStats.h>
101#include <TEnv.h>
102
103#include "MLog.h"
104#include "MLogManip.h"
105
106#include "MEnv.h"
107#include "MRunIter.h"
108#include "MSequence.h"
109#include "MParList.h"
110#include "MTaskList.h"
111#include "MEvtLoop.h"
112
113#include "MHCamera.h"
114#include "MGeomCam.h"
115
116#include "MCalibrationPatternDecode.h"
117#include "MCalibrationCam.h"
118#include "MCalibrationQECam.h"
119#include "MCalibrationQEPix.h"
120#include "MCalibrationChargeCam.h"
121#include "MCalibrationChargePix.h"
122#include "MCalibrationChargePINDiode.h"
123#include "MCalibrationBlindPix.h"
124#include "MCalibrationBlindCam.h"
125#include "MCalibrationBlindCamOneOldStyle.h"
126#include "MCalibrationBlindCamTwoNewStyle.h"
127#include "MCalibrationBlindCamThreeNewStyle.h"
128#include "MCalibrationChargeCalc.h"
129#include "MCalibColorSet.h"
130#include "MCalibrationRelTimeCam.h"
131#include "MCalibrationRelTimeCalc.h"
132
133#include "MHGausEvents.h"
134#include "MHCalibrationCam.h"
135#include "MHCalibrationChargeCam.h"
136#include "MHCalibrationChargeBlindCam.h"
137#include "MHCalibrationChargePINDiode.h"
138#include "MHCalibrationRelTimeCam.h"
139#include "MHCalibrationPix.h"
140
141#include "MHCamEvent.h"
142
143#include "MReadMarsFile.h"
144#include "MPedCalcPedRun.h"
145#include "MRawFileRead.h"
146#include "MGeomApply.h"
147#include "MPedestalSubtract.h"
148#include "MTaskEnv.h"
149#include "MBadPixelsMerge.h"
150#include "MBadPixelsCam.h"
151#include "MExtractTime.h"
152#include "MExtractor.h"
153#include "MExtractPINDiode.h"
154#include "MExtractBlindPixel.h"
155#include "MExtractTimeAndChargeSpline.h"
156#include "MFCosmics.h"
157#include "MFTriggerPattern.h"
158#include "MContinue.h"
159#include "MFillH.h"
160
161#include "MTriggerPatternDecode.h"   
162
163#include "MArrivalTimeCam.h"
164
165#include "MStatusDisplay.h"
166
167ClassImp(MJCalibration);
168
169using namespace std;
170
171const Int_t MJCalibration::gkIFAEBoxInaugurationRun        = 20113;
172const Int_t MJCalibration::gkSecondBlindPixelInstallation  = 31693;
173const Int_t MJCalibration::gkSpecialPixelsContInstallation = 34057;
174const Int_t MJCalibration::gkThirdBlindPixelInstallation   = 43308;
175const TString MJCalibration::fgReferenceFile = "mjobs/calibrationref.rc";
176const TString MJCalibration::fgHiLoCalibFile = "resources/hilocalib.rc";
177
178// --------------------------------------------------------------------------
179//
180// Default constructor.
181//
182// - fExtractor to NULL, fTimeExtractor to NULL, fColor to kNONE,
183//   fDisplay to kNormalDisplay, kRelTimes to kFALSE, kataCheck to kFALSE, kDebug to kFALSE
184// - SetUseBlindPixel()
185// - SetUsePINDiode()
186//
187MJCalibration::MJCalibration(const char *name, const char *title) 
188    : fExtractor(NULL), fTimeExtractor(NULL), 
189      fColor(MCalibrationCam::kNONE), fDisplayType(kDataCheckDisplay),
190      fMinEvents(1000), fGeometry("MGeomCamMagic")
191{
192
193  fName  = name  ? name  : "MJCalibration";
194  fTitle = title ? title : "Tool to create the calibration constants for one calibration run";
195
196  //SetHiLoCalibration();
197  SetRelTimeCalibration();
198  SetDebug(kFALSE);
199
200  SetReferenceFile();
201  SetHiLoCalibFile();
202
203  fConvFADC2PheMin           = 0.;
204  fConvFADC2PheMax           = 1.5;
205  fConvFADC2PhotMin          = 0.; 
206  fConvFADC2PhotMax          = 10.; 
207  fQEMin                     = 0.;
208  fQEMax                     = 0.3;
209  fArrivalTimeMin            = 1.;
210  fArrivalTimeMax            = 10.;
211  fTimeOffsetMin             = -3.;
212  fTimeOffsetMax             =  3.;
213  fTimeResolutionMin         =  0.;
214  fTimeResolutionMax         =  1.;
215
216  fRefFADC2PheInner          = 0.14;
217  fRefFADC2PheOuter          = 0.4;
218  fRefConvFADC2PheInner      = 0.14;
219  fRefConvFADC2PheOuter      = 0.52;
220  fRefQEInner                = 0.18;
221  fRefQEOuter                = 0.12;
222  fRefArrivalTimeInner       = 4.5;
223  fRefArrivalTimeOuter       = 5.0;
224  fRefArrivalTimeRmsInner    = 0.5;
225  fRefArrivalTimeRmsOuter    = 0.5;
226  fRefTimeOffsetOuter        = 0.62;
227  fRefTimeResolutionInner    = 0.12;
228  fRefTimeResolutionOuter    = 0.09;
229
230}
231
232void MJCalibration::DrawTab(MParList &plist, const char *cont, const char *name, Option_t *opt)
233{
234    TObject *obj = plist.FindObject(cont);
235    if (!obj)
236        return;
237
238    fDisplay->AddTab(name);
239    obj->DrawClone(opt);
240}
241
242void MJCalibration::DrawBadPixel(TPaveText &pave, const MHCamera &h, Int_t n, Float_t f, const char *str) const
243{
244    Int_t cnt = 0;
245    for (UInt_t pix=0; pix<h.GetNumPixels(); pix++)
246        if (TMath::Nint(h.GetPixContent(pix)) == n)
247            cnt++;
248
249    const TString txt = Form(n<10?"  %d) %s%3i pixels":"%d) %s%3i pixels", n, str, cnt);
250
251    TText *p = pave.AddText(txt);
252    p->SetTextColor(gStyle->GetColorPalette(TMath::FloorNint((n-1)*f)));
253    p->SetTextAlign(12);
254}
255
256// --------------------------------------------------------------------------
257//
258// Display the results in MStatusDisplay:
259//
260// - Add "Calibration" to the MStatusDisplay title
261// - Retrieve the MGeomCam from MParList
262// - Initialize the following MHCamera's:
263//   1)  MCalibrationPix::GetMean()
264//   2)  MCalibrationPix::Sigma()
265//   3)  MCalibrationChargePix::GetRSigma()
266//   4)  MCalibrationChargePix::GetRSigmaPerCharge()
267//   5)  MCalibrationChargePix::GetPheFFactorMethod()
268//   6)  MCalibrationChargePix::GetMeanConvFADC2Phe()
269//   7)  MCalibrationChargePix::GetMeanFFactorFADC2Phot()
270//   8)  MCalibrationQEPix::GetQECascadesFFactor()
271//   9)  MCalibrationQEPix::GetQECascadesBlindPixel()
272//   10) MCalibrationQEPix::GetQECascadesPINDiode()
273//   11) MCalibrationQEPix::GetQECascadesCombined()
274//   12) MCalibrationQEPix::IsAverageQEFFactorAvailable()
275//   13) MCalibrationQEPix::IsAverageQEBlindPixelAvailable()
276//   14) MCalibrationQEPix::IsAverageQEPINDiodeAvailable()
277//   15) MCalibrationQEPix::IsAverageQECombinedAvailable()
278//   16) MCalibrationChargePix::IsHiGainSaturation()
279//   17) MCalibrationPix::GetHiLoMeansDivided()
280//   18) MCalibrationPix::GetHiLoSigmasDivided()
281//   19) MCalibrationChargePix::GetHiGainPickup()
282//   20) MCalibrationChargePix::GetLoGainPickup()
283//   21) MCalibrationChargePix::GetHiGainBlackout()
284//   22) MCalibrationChargePix::GetLoGainBlackout()
285//   23) MCalibrationPix::IsExcluded()
286//   24) MBadPixelsPix::IsUnsuitable(MBadPixelsPix::kUnsuitableRun)
287//   25) MBadPixelsPix::IsUnsuitable(MBadPixelsPix::kUnreliableRun)
288//   26) MBadPixelsPix::IsUncalibrated(MBadPixelsPix::kHiGainOscillating)
289//   27) MBadPixelsPix::IsUncalibrated(MBadPixelsPix::kLoGainOscillating)
290//   28) MCalibrationChargePix::GetAbsTimeMean()
291//   29) MCalibrationChargePix::GetAbsTimeRms()
292//
293// If the flag SetFullDisplay() is set, all MHCameras will be displayed.
294// if the flag SetDataCheckDisplay() is set, only the most important ones are displayed
295// and otherwise, (default: SetNormalDisplay()), a good selection of plots is given
296//
297void MJCalibration::DisplayResult(MParList &plist)
298{
299    if (!fDisplay)
300        return;
301
302    TString drawoption = "nonew ";
303    if (fDisplayType == kDataCheckDisplay)
304        drawoption += "datacheck";
305    if (fDisplayType == kFullDisplay)
306        drawoption += "all";
307
308    if (IsUsePINDiode())
309        DrawTab(plist, "MHCalibrationChargePINDiode", "PINDiode",  drawoption);
310    if (IsUseBlindPixel())
311        DrawTab(plist, "MHCalibrationChargeBlindCam", "BlindPix",  drawoption);
312    if (IsRelTimes())
313        DrawTab(plist, "MHCalibrationRelTimeCam",     "Time",      drawoption);
314    DrawTab(plist, "MHCalibrationChargeCam",          "Charge",    drawoption);
315
316    //
317    // Update display
318    //
319    TString title = fDisplay->GetTitle();
320    title += "--  Calibration ";
321    title += Form("calib%08d", fSequence.GetSequence());
322    title += "  --";
323    fDisplay->SetTitle(title);
324
325    //
326    // Get container from list
327    //
328    MGeomCam &geomcam = *(MGeomCam*)plist.FindObject("MGeomCam");
329
330    // Create histograms to display
331    MHCamera disp1 (geomcam, "Charge",            "Fitted Mean Signal (Charges)");
332    MHCamera disp2 (geomcam, "SigmaCharge",       "Sigma of Fitted Signal");
333    MHCamera disp3 (geomcam, "RSigma",            "Reduced Sigmas");
334    MHCamera disp4 (geomcam, "RSigmaPerCharge",   "Reduced Sigma per Charge");
335    MHCamera disp5 (geomcam, "NumPhes",           "Number Photo-electrons");
336    MHCamera disp6 (geomcam, "ConvFADC2Phes",     "Phes per Charge (Before Flat-Field)");
337    MHCamera disp7 (geomcam, "TotalFFactor",      "Total F-Factor(F-Factor Method)");
338    MHCamera disp8 (geomcam, "CascadesQEFFactor", "Cascades QE (F-Factor Method)");
339    MHCamera disp9 (geomcam, "CascadesQEBlindPix","Cascades QE (Blind Pixel Method)");
340    MHCamera disp10(geomcam, "CascadesQEPINDiode","Cascades QE (PIN Diode Method)");
341    MHCamera disp11(geomcam, "CascadesQECombined","Cascades QE (Combined Method)");
342    MHCamera disp12(geomcam, "FFactorValid",      "Pixels with Valid F-Factor Calibration");
343    MHCamera disp13(geomcam, "BlindPixelValid",   "Pixels with valid BlindPixel Calibration");
344    MHCamera disp14(geomcam, "PINdiodeValid",     "Pixels with Valid PINDiode Calibration");
345    MHCamera disp15(geomcam, "CombinedValid",     "Pixels with Valid Combined Calibration");
346    MHCamera disp16(geomcam, "Saturation",        "Pixels with Saturated Hi Gain");
347    MHCamera disp17(geomcam, "ConversionMeans",   "Conversion HiGain.vs.LoGain Means");
348    MHCamera disp18(geomcam, "ConversionSigmas",  "Conversion HiGain.vs.LoGain Sigmas");
349    MHCamera disp19(geomcam, "HiGainPickup",      "Number Pickup Events Hi Gain");
350    MHCamera disp20(geomcam, "LoGainPickup",      "Number Pickup Events Lo Gain");
351    MHCamera disp21(geomcam, "HiGainBlackout",    "Number Blackout Events Hi Gain");
352    MHCamera disp22(geomcam, "LoGainBlackout",    "Number Blackout Events Lo Gain");
353    MHCamera disp23(geomcam, "Excluded",          "Pixels Previously Excluded");
354    MHCamera disp24(geomcam, "UnSuitable",        "Pixels NOT Suited for Further Analysis");
355    MHCamera disp25(geomcam, "UnReliable",        "Pixels Suitable, but NOT Reliable for Further Analysis");
356    MHCamera disp26(geomcam, "HiGainOscillating", "Oscillating Pixels High Gain");
357    MHCamera disp27(geomcam, "LoGainOscillating", "Oscillating Pixels Low Gain");
358    MHCamera disp28(geomcam, "AbsTimeMean",       "Abs. Arrival Times");
359    MHCamera disp29(geomcam, "AbsTimeRms",        "RMS of Arrival Times");
360    MHCamera disp30(geomcam, "MeanTime",          "Mean Rel. Arrival Times");
361    MHCamera disp31(geomcam, "SigmaTime",         "Sigma Rel. Arrival Times");
362    MHCamera disp32(geomcam, "TimeProb",          "Probability of Time Fit");
363    MHCamera disp33(geomcam, "TimeNotFitValid",   "Pixels with not valid Fit Results");
364    MHCamera disp34(geomcam, "TimeOscillating",   "Oscillating Pixels");
365    MHCamera disp35(geomcam, "TotalConv",         "Conversion Factor to Photons");
366    MHCamera disp36(geomcam, "RMSperMean",        "Charge histogram RMS per Mean");
367    MHCamera disp37(geomcam, "TotalConvPhe",      "Conversion Factor to equiv. Phe's");
368   
369    // Fitted charge means and sigmas
370    disp1.SetCamContent(fCalibrationCam,  0);
371    disp1.SetCamError(  fCalibrationCam,  1);
372    disp2.SetCamContent(fCalibrationCam,  2);
373    disp2.SetCamError(  fCalibrationCam,  3);
374
375    // Reduced Sigmas and reduced sigmas per charge
376    disp3.SetCamContent(fCalibrationCam,  5);
377    disp3.SetCamError(  fCalibrationCam,  6);
378    disp4.SetCamContent(fCalibrationCam,  7);
379    disp4.SetCamError(  fCalibrationCam,  8);
380
381    // F-Factor Method
382    disp5.SetCamContent(fCalibrationCam,  9);
383    disp5.SetCamError(  fCalibrationCam, 10);
384    disp6.SetCamContent(fCalibrationCam, 11);
385    disp6.SetCamError(  fCalibrationCam, 12);
386    disp7.SetCamContent(fCalibrationCam, 13);
387    disp7.SetCamError(  fCalibrationCam, 14);
388
389    // Quantum Efficiencies
390    disp8.SetCamContent (fQECam, 0 );
391    disp8.SetCamError   (fQECam, 1 );
392    disp9.SetCamContent (fQECam, 2 );
393    disp9.SetCamError   (fQECam, 3 );
394    disp10.SetCamContent(fQECam, 4 );
395    disp10.SetCamError  (fQECam, 5 );
396    disp11.SetCamContent(fQECam, 6 );
397    disp11.SetCamError  (fQECam, 7 );
398
399    // Valid flags
400    disp12.SetCamContent(fQECam, 8 );
401    disp13.SetCamContent(fQECam, 9 );
402    disp14.SetCamContent(fQECam, 10);
403    disp15.SetCamContent(fQECam, 11);
404
405    // Conversion Hi-Lo
406    disp16.SetCamContent(fCalibrationCam, 25);
407    disp17.SetCamContent(fCalibrationCam, 16);
408    disp17.SetCamError  (fCalibrationCam, 17);
409    disp18.SetCamContent(fCalibrationCam, 18);
410    disp18.SetCamError  (fCalibrationCam, 19);
411
412    // Pickup and Blackout
413    disp19.SetCamContent(fCalibrationCam, 21);
414    disp20.SetCamContent(fCalibrationCam, 22);
415    disp21.SetCamContent(fCalibrationCam, 23);
416    disp22.SetCamContent(fCalibrationCam, 24);
417
418    // Pixels with defects
419    disp23.SetCamContent(fCalibrationCam, 20);
420    disp24.SetCamContent(fBadPixels, 6);
421    disp25.SetCamContent(fBadPixels, 7);
422
423    // Oscillations
424    disp26.SetCamContent(fBadPixels, 10);
425    disp27.SetCamContent(fBadPixels, 11);
426
427    // Arrival Times
428    disp28.SetCamContent(fCalibrationCam, 26);
429    disp28.SetCamError(  fCalibrationCam, 27);
430    disp29.SetCamContent(fCalibrationCam, 27);
431
432    // RMS and Mean
433    disp36.SetCamContent(fCalibrationCam,32);
434    disp36.SetCamError(fCalibrationCam,33);
435
436    disp1.SetYTitle("Q [FADC cnts]");
437    disp2.SetYTitle("\\sigma_{Q} [FADC cnts]");
438
439    disp3.SetYTitle("\\sqrt{\\sigma^{2}_{Q} - RMS^{2}_{Ped}} [FADC cnts]");
440    disp4.SetYTitle("Red.Sigma/<Q> [1]");
441
442    disp5.SetYTitle("Photo-electons [1]");
443    disp6.SetYTitle("Phes/<Q> [FADC cnts^{-1}]");
444    disp7.SetYTitle("Total F-Factor [1]");
445
446    disp8.SetYTitle("QE [1]");
447    disp9.SetYTitle("QE [1]");
448    disp10.SetYTitle("QE [1]");
449    disp11.SetYTitle("QE [1]");
450
451    disp12.SetYTitle("[1]");
452    disp13.SetYTitle("[1]");
453    disp14.SetYTitle("[1]");
454    disp15.SetYTitle("[1]");
455    disp16.SetYTitle("[1]");
456
457    disp17.SetYTitle("<Q>(High)/<Q>(Low) [1]");
458    disp18.SetYTitle("\\sigma_{Q}(High)/\\sigma_{Q}(Low) [1]");
459
460    disp19.SetYTitle("[1]");
461    disp20.SetYTitle("[1]");
462    disp21.SetYTitle("[1]");
463    disp22.SetYTitle("[1]");
464    //    disp23.SetYTitle("[1]");
465    //    disp24.SetYTitle("[1]");
466    //    disp25.SetYTitle("[1]");
467    disp26.SetYTitle("[1]");
468    disp27.SetYTitle("[1]");
469
470    disp28.SetYTitle("Mean Abs. Time [FADC sl.]");
471    disp29.SetYTitle("RMS Abs. Time [FADC sl.]");
472    disp35.SetYTitle("Conv.Factor [Ph/FADC cnts]");
473    disp36.SetYTitle("Charge RMS/<Q> [1]");
474    disp37.SetYTitle("Conv.Factor [Phe/FADC cnts]");
475
476    for (UInt_t i=0;i<geomcam.GetNumPixels();i++)
477      {
478
479        MCalibrationChargePix &pix = (MCalibrationChargePix&)fCalibrationCam[i];
480        MCalibrationQEPix     &qe  = (MCalibrationQEPix&)fQECam[i];
481
482        if (!pix.IsFFactorMethodValid())
483          continue;
484
485        const Float_t convphe  = pix.GetMeanConvFADC2Phe();
486        const Float_t quaeff   = qe.GetQECascadesFFactor();
487       
488        disp35.Fill(i,convphe/quaeff);
489        disp35.SetUsed(i);
490
491        disp37.Fill(i,convphe/quaeff*MCalibrationQEPix::gkDefaultAverageQE);
492        disp37.SetUsed(i);
493      }
494   
495
496    if (IsRelTimes())
497    {
498        disp30.SetCamContent(fRelTimeCam, 0);
499        disp30.SetCamError(  fRelTimeCam, 1);
500        disp31.SetCamContent(fRelTimeCam, 2);
501        disp31.SetCamError(  fRelTimeCam, 3);
502        disp32.SetCamContent(fRelTimeCam, 4);
503        disp33.SetCamContent(fBadPixels, 20);
504        disp34.SetCamContent(fBadPixels, 21);
505   
506        disp30.SetYTitle("Time Offset [FADC units]");
507        disp31.SetYTitle("Timing resolution [FADC units]");
508        disp32.SetYTitle("P_{Time} [1]");
509        disp33.SetYTitle("[1]");
510        disp34.SetYTitle("[1]");
511    }
512
513    if (fDisplayType == kDataCheckDisplay)
514    {
515     
516      TCanvas &c1 = fDisplay->AddTab("FitCharge");
517      c1.Divide(3, 3);
518     
519      //
520      // MEAN CHARGES
521      //
522     
523      c1.cd(1);
524      gPad->SetBorderMode(0);
525      gPad->SetTicks();
526      MHCamera *obj1=(MHCamera*)disp1.DrawCopy("hist");
527      //
528      // for the datacheck, fix the ranges!!
529      //
530      // obj1->SetMinimum(fChargeMin);
531      // obj1->SetMaximum(fChargeMax);
532      //
533      // Set the datacheck sizes:
534      //
535      FixDataCheckHist((TH1D*)obj1);
536      obj1->SetStats(kFALSE);
537      //
538      // set reference lines
539      //
540      //        DisplayReferenceLines(obj1,0);
541     
542      c1.cd(4);
543      gPad->SetBorderMode(0);
544      obj1->SetPrettyPalette();
545      obj1->Draw();
546     
547      c1.cd(7);
548      gPad->SetBorderMode(0);
549      gPad->SetTicks();
550      TH1D *obj2 = (TH1D*)obj1->Projection(obj1->GetName());
551      obj2->Draw();
552      obj2->SetBit(kCanDelete);
553      obj2->Fit("gaus","Q");
554      TF1 *fun2 = obj2->GetFunction("gaus");
555      fun2->SetLineColor(kYellow);
556      gPad->Modified();
557      gPad->Update();     
558      TPaveStats *st = (TPaveStats*)obj2->GetListOfFunctions()->FindObject("stats");
559      st->SetY1NDC(0.55);
560      st->SetY2NDC(0.89);
561      st->SetX1NDC(0.65);
562      st->SetX2NDC(0.99);
563      gPad->Modified();
564      gPad->Update();     
565      //
566      // Set the datacheck sizes:
567      //
568      FixDataCheckHist(obj2);
569      obj2->SetStats(1);
570     
571      //
572      // Display the outliers as dead and noisy pixels
573      //
574      DisplayOutliers(obj2,"low-ampl.","high-ampl.");
575      TLatex flattex;
576      flattex.SetTextSize(0.07);
577      const Double_t minl = obj2->GetBinCenter(obj2->GetXaxis()->GetFirst());
578      const Double_t maxl = obj2->GetBinCenter(obj2->GetXaxis()->GetLast());
579      flattex.DrawLatex(minl+0.015*(maxl-minl),obj2->GetBinContent(obj2->GetMaximumBin())/1.35,
580                        Form("Flatfield precision: %4.2f%%",
581                             fun2->GetParameter(2)/fun2->GetParameter(1)*100.));
582     
583      //
584      // RMS per Charge
585      //
586     
587      c1.cd(2);
588      gPad->SetBorderMode(0);
589      gPad->SetTicks();
590      MHCamera *obj3=(MHCamera*)disp36.DrawCopy("hist");
591      //
592      // for the datacheck, fix the ranges!!
593      //
594      //      obj3->SetMinimum(0.);
595      // obj3->SetMaximum(fChargeMax);
596      //
597      // Set the datacheck sizes:
598      //
599      FixDataCheckHist((TH1D*)obj3);
600      obj3->SetStats(kFALSE);
601      //
602      // set reference lines
603      //
604      //        DisplayReferenceLines(obj3,0);
605     
606      c1.cd(5);
607      gPad->SetBorderMode(0);
608      obj3->SetPrettyPalette();
609      obj3->Draw();
610     
611      c1.cd(8);
612      gPad->SetBorderMode(0);
613      if (geomcam.InheritsFrom("MGeomCamMagic"))
614        DisplayDoubleProject(&disp36, "dead", "noisy");
615     
616      //
617      // PHOTO ELECTRONS
618      //
619     
620      c1.cd(3);
621      gPad->SetBorderMode(0);
622      gPad->SetTicks();
623      MHCamera *obj4=(MHCamera*)disp5.DrawCopy("hist");
624      //
625      // for the datacheck, fix the ranges!!
626      //
627      // obj3->SetMinimum(fChargeMin);
628      // obj3->SetMaximum(fChargeMax);
629      //
630      // Set the datacheck sizes:
631      //
632      FixDataCheckHist((TH1D*)obj4);
633      obj4->SetStats(kFALSE);
634      //
635      // set reference lines
636      //
637      //        DisplayReferenceLines(obj3,0);
638     
639      c1.cd(6);
640      gPad->SetBorderMode(0);
641      obj4->SetPrettyPalette();
642      obj4->Draw();
643     
644      c1.cd(9);
645      gPad->SetBorderMode(0);
646      if (geomcam.InheritsFrom("MGeomCamMagic"))
647        DisplayDoubleProject(&disp5, "dead", "noisy");
648     
649      //
650      // CONVERSION FACTORS
651      //
652      TCanvas &c2 = fDisplay->AddTab("Conversion");
653      c2.Divide(3,3);
654     
655      c2.cd(1);
656      gPad->SetBorderMode(0);
657      gPad->SetTicks();
658      MHCamera *obj5=(MHCamera*)disp6.DrawCopy("hist");
659      //
660      // for the datacheck, fix the ranges!!
661      //
662      obj5->SetMinimum(fConvFADC2PheMin);
663      obj5->SetMaximum(fConvFADC2PheMax);
664      //
665      // Set the datacheck sizes:
666      //
667      FixDataCheckHist((TH1D*)obj5);
668      obj5->SetStats(kFALSE);
669      //
670      // set reference lines
671      //
672      DisplayReferenceLines(obj5,2);
673     
674      c2.cd(4);
675      gPad->SetBorderMode(0);
676      obj5->SetPrettyPalette();
677      obj5->Draw();
678     
679      c2.cd(7);
680      gPad->SetBorderMode(0);
681      if (geomcam.InheritsFrom("MGeomCamMagic"))
682        DisplayDoubleProject(&disp6, "noisy", "dead");
683     
684      //
685      // QUANTUM EFFICIENCY
686      //
687      c2.cd(2);
688      gPad->SetBorderMode(0);
689      gPad->SetTicks();
690      MHCamera *obj6=(MHCamera*)disp8.DrawCopy("hist");
691      //
692      // for the datacheck, fix the ranges!!
693      //
694      obj6->SetMinimum(fQEMin);
695      obj6->SetMaximum(fQEMax);
696      //
697      // Set the datacheck sizes:
698      //
699      FixDataCheckHist((TH1D*)obj6);
700      obj6->SetStats(kFALSE);
701      //
702      // set reference lines
703      //
704      DisplayReferenceLines(obj6,0);
705     
706      c2.cd(5);
707      gPad->SetBorderMode(0);
708      obj6->SetPrettyPalette();
709      obj6->Draw();
710     
711      c2.cd(8);
712      gPad->SetBorderMode(0);
713      if (geomcam.InheritsFrom("MGeomCamMagic"))
714        DisplayDoubleProject(&disp8, "noisy", "dead");
715     
716      //
717      // CONVERSION FADC TO PHOTONS
718      //
719     
720      c2.cd(3);
721      gPad->SetBorderMode(0);
722      gPad->SetTicks();
723      MHCamera *obj7=(MHCamera*)disp37.DrawCopy("hist");
724      //
725      // for the datacheck, fix the ranges!!
726      //
727      obj7->SetMinimum(fConvFADC2PheMin);
728      obj7->SetMaximum(fConvFADC2PheMax);
729      //
730      // Set the datacheck sizes:
731      //
732      FixDataCheckHist((TH1D*)obj7);
733      obj7->SetStats(kFALSE);
734      //
735      // set reference lines
736      //
737      DisplayReferenceLines(obj7,1);
738     
739      c2.cd(6);
740      gPad->SetBorderMode(0);
741      obj7->SetPrettyPalette();
742      obj7->Draw();
743      c2.cd(9);
744      gPad->SetBorderMode(0);
745      if (geomcam.InheritsFrom("MGeomCamMagic"))
746        DisplayDoubleProject(&disp37, "noisy", "dead");
747
748      //
749      // ARRIVAL TIMES
750      //
751      TCanvas &c3 = fDisplay->AddTab("AbsTimes");
752      c3.Divide(2,3);
753     
754      c3.cd(1);
755      gPad->SetBorderMode(0);
756      gPad->SetTicks();
757      MHCamera *obj10=(MHCamera*)disp28.DrawCopy("hist");
758      //
759      // for the datacheck, fix the ranges!!
760      //
761      obj10->SetMinimum(fArrivalTimeMin);
762      obj10->SetMaximum(fArrivalTimeMax);
763      //
764      // Set the datacheck sizes:
765      //
766      FixDataCheckHist((TH1D*)obj10);
767      obj10->SetStats(kFALSE);
768      //
769      // set reference lines
770      //
771      DisplayReferenceLines(obj10,3);
772     
773      c3.cd(3);
774      gPad->SetBorderMode(0);
775      obj10->SetPrettyPalette();
776      obj10->Draw();
777     
778      c3.cd(5);
779      gPad->SetBorderMode(0);
780      if (geomcam.InheritsFrom("MGeomCamMagic"))
781        DisplayDoubleProject(&disp28, "early", "late");
782
783      //
784      // ARRIVAL TIMES JITTER
785      //
786      c3.cd(2);
787      gPad->SetBorderMode(0);
788      gPad->SetTicks();
789      MHCamera *obj11=(MHCamera*)disp29.DrawCopy("hist");
790      //
791      // for the datacheck, fix the ranges!!
792      //
793      //      obj11->SetMinimum(fArrivalTimeMin);
794      //      obj11->SetMaximum(fArrivalTimeMax);
795      //
796      // Set the datacheck sizes:
797      //
798      FixDataCheckHist((TH1D*)obj11);
799      obj11->SetStats(kFALSE);
800      //
801      // set reference lines
802      //
803      DisplayReferenceLines(obj11,4);
804     
805      c3.cd(4);
806      gPad->SetBorderMode(0);
807      obj11->SetPrettyPalette();
808      obj11->Draw();
809     
810      c3.cd(6);
811      gPad->SetBorderMode(0);
812      if (geomcam.InheritsFrom("MGeomCamMagic"))
813        DisplayDoubleProject(&disp29, "", "jittering");
814
815      //
816      // UNSUITABLE PIXELS
817      //
818      TCanvas &c4 = fDisplay->AddTab("Defect");
819      c4.Divide(2,2, 0.005, 0.005);
820
821      c4.cd(1);
822      gPad->SetBorderMode(0);
823      gPad->SetTicks();
824
825      MHCamera *obj8=(MHCamera*)disp24.DrawCopy("hist");
826
827      gStyle->SetPalette(1);
828      const Int_t numcol = gStyle->GetNumberOfColors();
829
830      const Double_t min = 1;
831      const Double_t max = 10.;
832      const Double_t f   = (numcol-1)/(max-min);
833
834      obj8->SetStats(kFALSE);
835      obj8->SetMinimum(min);
836      obj8->SetMaximum(max);
837
838      //
839      // Set the datacheck sizes:
840      //
841      FixDataCheckHist((TH1D*)obj8);
842
843      TPaveText *pave = new TPaveText(0.05,0.02,0.975,0.999);
844      pave->SetBit(kCanDelete);
845      pave->ConvertNDCtoPad();
846      pave->SetTextSize(0.045);
847      pave->SetFillColor(14);
848      pave->AddText("  ");
849      DrawBadPixel(*pave, disp24,  1, f, "Signal smaller 4.5 Pedestal RMS:               ");
850      DrawBadPixel(*pave, disp24,  2, f, "Low Gain Saturation:                                   ");
851      // DrawBadPixel(*pave, disp24,  3, f, "Mean Arr. Time In First Extraction Bin:      ");
852      // DrawBadPixel(*pave, disp24,  4, f, "Mean Arr. Time In Last 2 Extraction Bins:  ");
853      DrawBadPixel(*pave, disp24,  3, f, "High-Gain Histogram Overflow:                  ");
854      DrawBadPixel(*pave, disp24,  4, f, "Low-Gain Histogram Overflow:                   ");
855      DrawBadPixel(*pave, disp24,  5, f, "Presumably dead from Ped. Rms:              ");
856      DrawBadPixel(*pave, disp24,  6, f, "Deviating Number of Photo-electrons:       ");
857      DrawBadPixel(*pave, disp24,  7, f, "Deviation from median abs.arr-time rms:   ");
858      DrawBadPixel(*pave, disp24,  8, f, "Deviation from median rel.arr-time rms:     ");
859      DrawBadPixel(*pave, disp24,  9, f, "Too many Low-Gain Blackout Events:       ");
860      DrawBadPixel(*pave, disp24, 10, f, "Previously Excluded:                                   ");
861      pave->Draw();
862
863      c4.cd(3);
864      gPad->SetBorderMode(0);
865      obj8->SetPrettyPalette();
866      obj8->Draw();
867
868      //
869      // UNRELIABLE PIXELS
870      //
871      c4.cd(2);
872      gPad->SetBorderMode(0);
873      gPad->SetTicks();
874      MHCamera *obj9=(MHCamera*)disp25.DrawCopy("hist");
875
876      const Double_t min2 = 1;
877      const Double_t max2 = 8;
878      const Double_t f2   = (numcol-1)/(max2-min2);
879      obj9->SetMinimum(min2);
880      obj9->SetMaximum(max2);
881      obj9->SetStats(kFALSE);
882
883      FixDataCheckHist((TH1D*)obj9);
884
885      gStyle->SetPalette(1);
886
887      TPaveText *pave2 = new TPaveText(0.025,0.02,0.95,0.999);
888      pave2->SetBit(kCanDelete);
889      pave2->ConvertNDCtoPad();
890      pave2->SetTextSize(0.05);
891      pave2->SetFillColor(14);
892      pave2->AddText("  ");
893      DrawBadPixel(*pave2, disp25,  1, f2, "Signal Sigma smaller Pedestal RMS:      ");
894      DrawBadPixel(*pave2, disp25,  2, f2, "High Gain Signals could not be fitted:    ");
895      DrawBadPixel(*pave2, disp25,  3, f2, "Low  Gain Signals could not be fitted:    ");
896      DrawBadPixel(*pave2, disp25,  4, f2, "Relative Arr. Times could not be fitted:   ");
897      DrawBadPixel(*pave2, disp25,  5, f2, "High Gain Signals Oscillation:                 ");
898      DrawBadPixel(*pave2, disp25,  6, f2, "Low  Gain Signals Oscillation:                ");
899      DrawBadPixel(*pave2, disp25,  7, f2, "Relative Arr. Times Oscillation:               ");
900      DrawBadPixel(*pave2, disp25,  8, f2, "Deviating global F-Factor:                       ");
901      pave2->Draw();
902
903      c4.cd(4);
904      gPad->SetBorderMode(0);
905      obj9->SetPrettyPalette();
906      obj9->Draw();
907
908      if (IsRelTimes())
909        {
910          TCanvas &c5 = fDisplay->AddTab("RelTimes");
911          c5.Divide(2,3);
912         
913          //
914          // MEAN REL. ARR. TIMES
915          //
916          c5.cd(1);
917          gPad->SetBorderMode(0);
918          gPad->SetTicks();
919          MHCamera *obj10=(MHCamera*)disp30.DrawCopy("hist");
920          //
921          // for the datacheck, fix the ranges!!
922          //
923          obj10->SetMinimum(fTimeOffsetMin);
924          obj10->SetMaximum(fTimeOffsetMax);
925          //
926          // Set the datacheck sizes:
927          //
928          FixDataCheckHist((TH1D*)obj10);
929          obj10->SetStats(kFALSE);
930          //
931          // set reference lines
932          //
933          DisplayReferenceLines(obj10,5);
934     
935          c5.cd(3);
936          gPad->SetBorderMode(0);
937          obj10->SetPrettyPalette();
938          obj10->Draw();
939     
940          c5.cd(5);
941          gPad->SetBorderMode(0);
942          if (geomcam.InheritsFrom("MGeomCamMagic"))
943            DisplayDoubleProject(&disp30, "early", "late");
944         
945          //
946          // JITTER Rel. Arr. Times
947          //
948          c5.cd(2);
949          gPad->SetBorderMode(0);
950          gPad->SetTicks();
951          MHCamera *obj11=(MHCamera*)disp31.DrawCopy("hist");
952          //
953          // for the datacheck, fix the ranges!!
954          //
955          obj11->SetMinimum(fTimeResolutionMin);
956          obj11->SetMaximum(fTimeResolutionMax);
957          //
958          // Set the datacheck sizes:
959          //
960          FixDataCheckHist((TH1D*)obj11);
961          obj11->SetStats(kFALSE);
962          //
963          // set reference lines
964          //
965          DisplayReferenceLines(obj11,6);
966         
967          c5.cd(4);
968          gPad->SetBorderMode(0);
969          obj11->SetPrettyPalette();
970          obj11->Draw();
971         
972          c5.cd(6);
973          gPad->SetBorderMode(0);
974          if (geomcam.InheritsFrom("MGeomCamMagic"))
975            DisplayDoubleProject(&disp31, "too stable", "jittering");
976         
977        }
978      return;
979    }
980   
981    if (fDisplayType == kNormalDisplay)
982      {
983       
984        // Charges
985        TCanvas &c11 = fDisplay->AddTab("FitCharge");
986        c11.Divide(2, 4);
987       
988        disp1.CamDraw(c11, 1, 2, 5, 1);
989        disp2.CamDraw(c11, 2, 2, 5, 1);
990       
991        // Reduced Sigmas
992        TCanvas &c12 = fDisplay->AddTab("RedSigma");
993        c12.Divide(2,4);
994       
995        disp3.CamDraw(c12, 1, 2, 5, 1);
996        disp4.CamDraw(c12, 2, 2, 5, 1);
997       
998        //  F-Factor
999        TCanvas &c13 = fDisplay->AddTab("Phe's");
1000        c13.Divide(3,4);
1001       
1002        disp5.CamDraw(c13, 1, 3, 5, 1);
1003        disp6.CamDraw(c13, 2, 3, 5, 1);
1004        disp7.CamDraw(c13, 3, 3, 5, 1);
1005       
1006        // QE's
1007        TCanvas &c14 = fDisplay->AddTab("QE's");
1008        c14.Divide(4,4);
1009       
1010        disp8.CamDraw(c14, 1, 4, 5, 1);
1011        disp9.CamDraw(c14, 2, 4, 5, 1);
1012        disp10.CamDraw(c14, 3, 4, 5, 1);
1013        disp11.CamDraw(c14, 4, 4, 5, 1);
1014       
1015        // Defects
1016        TCanvas &c15 = fDisplay->AddTab("Defect");
1017        //      c15.Divide(5,2);
1018        c15.Divide(4,2);
1019       
1020        /*
1021        disp23.CamDraw(c15, 1, 5, 0);
1022        disp24.CamDraw(c15, 2, 5, 0);
1023        disp25.CamDraw(c15, 3, 5, 0);
1024        disp26.CamDraw(c15, 4, 5, 0);
1025        disp27.CamDraw(c15, 5, 5, 0);
1026        */
1027        disp24.CamDraw(c15, 1, 4, 0);
1028        disp25.CamDraw(c15, 2, 4, 0);
1029        disp26.CamDraw(c15, 3, 4, 0);
1030        disp27.CamDraw(c15, 4, 4, 0);
1031       
1032        // Abs. Times
1033        TCanvas &c16 = fDisplay->AddTab("AbsTimes");
1034        c16.Divide(2,3);
1035       
1036        disp28.CamDraw(c16, 1, 2, 5);
1037        disp29.CamDraw(c16, 2, 2, 5);
1038
1039        if (IsRelTimes())
1040        {
1041            // Rel. Times
1042            TCanvas &c17 = fDisplay->AddTab("RelTimes");
1043            c17.Divide(2,4);
1044
1045            disp30.CamDraw(c17, 1, 2, 5, 1);
1046            disp31.CamDraw(c17, 2, 2, 5, 1);
1047        }
1048       
1049        return;
1050    }
1051   
1052    if (fDisplayType == kFullDisplay)
1053    {
1054        MHCalibrationCam *cam = (MHCalibrationCam*)plist.FindObject("MHCalibrationChargeCam");
1055
1056        for (Int_t sector=1;sector<cam->GetAverageSectors();sector++)
1057        {
1058            cam->GetAverageHiGainSector(sector).DrawClone("all");
1059            cam->GetAverageLoGainSector(sector).DrawClone("all");
1060        }
1061
1062        // Charges
1063        TCanvas &c21 = fDisplay->AddTab("FitCharge");
1064        c21.Divide(2, 4);
1065
1066        disp1.CamDraw(c21, 1, 2, 2, 1);
1067        disp2.CamDraw(c21, 2, 2, 2, 1);
1068
1069        // Reduced Sigmas
1070        TCanvas &c23 = fDisplay->AddTab("RedSigma");
1071        c23.Divide(2,4);
1072
1073        disp3.CamDraw(c23, 1, 2, 2, 1);
1074        disp4.CamDraw(c23, 2, 2, 2, 1);
1075
1076        //  F-Factor
1077        TCanvas &c24 = fDisplay->AddTab("Phe's");
1078        c24.Divide(3,5);
1079       
1080        disp5.CamDraw(c24, 1, 3, 2, 1, 1);
1081        disp6.CamDraw(c24, 2, 3, 2, 1, 1);
1082        disp7.CamDraw(c24, 3, 3, 2, 1, 1);
1083       
1084        // QE's
1085        TCanvas &c25 = fDisplay->AddTab("QE's");
1086        c25.Divide(4,5);
1087       
1088        disp8.CamDraw(c25, 1, 4, 2, 1, 1);
1089        disp9.CamDraw(c25, 2, 4, 2, 1, 1);
1090        disp10.CamDraw(c25, 3, 4, 2, 1, 1);
1091        disp11.CamDraw(c25, 4, 4, 2, 1, 1);
1092       
1093        // Validity
1094        TCanvas &c26 = fDisplay->AddTab("Valid");
1095        c26.Divide(4,2);
1096       
1097        disp12.CamDraw(c26, 1, 4, 0);
1098        disp13.CamDraw(c26, 2, 4, 0);
1099        disp14.CamDraw(c26, 3, 4, 0);
1100        disp15.CamDraw(c26, 4, 4, 0);
1101       
1102        // Other info
1103        TCanvas &c27 = fDisplay->AddTab("HiLoGain");
1104        c27.Divide(3,3);
1105       
1106        disp16.CamDraw(c27, 1, 3, 0);
1107        disp17.CamDraw(c27, 2, 3, 1);
1108        disp18.CamDraw(c27, 3, 3, 1);
1109       
1110        // Pickup
1111        TCanvas &c28 = fDisplay->AddTab("Pickup");
1112        c28.Divide(4,2);
1113       
1114        disp19.CamDraw(c28, 1, 4, 0);
1115        disp20.CamDraw(c28, 2, 4, 0);
1116        disp21.CamDraw(c28, 3, 4, 0);
1117        disp22.CamDraw(c28, 4, 4, 0);
1118       
1119        // Defects
1120        TCanvas &c29 = fDisplay->AddTab("Defect");
1121        //      c29.Divide(5,2);
1122        c29.Divide(4,2);
1123       
1124        disp24.CamDraw(c29, 1, 4, 0);
1125        disp25.CamDraw(c29, 2, 4, 0);
1126        disp26.CamDraw(c29, 3, 4, 0);
1127        disp27.CamDraw(c29, 4, 4, 0);
1128       
1129        // Abs. Times
1130        TCanvas &c30 = fDisplay->AddTab("AbsTimes");
1131        c30.Divide(2,3);
1132       
1133        disp28.CamDraw(c30, 1, 2, 2);
1134        disp29.CamDraw(c30, 2, 2, 1);
1135
1136        if (IsRelTimes())
1137        {
1138            // Rel. Times
1139            TCanvas &c31 = fDisplay->AddTab("RelTimes");
1140            c31.Divide(3,5);
1141           
1142            disp30.CamDraw(c31, 1, 3, 2, 1, 1);
1143            disp31.CamDraw(c31, 2, 3, 2, 1, 1);
1144            disp32.CamDraw(c31, 3, 3, 4, 1, 1);
1145
1146            // Time Defects
1147            TCanvas &c32 = fDisplay->AddTab("DefTime");
1148            c32.Divide(2,2);
1149           
1150            disp33.CamDraw(c32, 1, 2, 0);
1151            disp34.CamDraw(c32, 2, 2, 0);
1152
1153            MHCalibrationCam *cam = (MHCalibrationCam*)plist.FindObject("MHCalibrationRelTimeCam");
1154           
1155            for (Int_t sector=1;sector<cam->GetAverageSectors();sector++)
1156            {
1157                cam->GetAverageHiGainSector(sector).DrawClone("fourierevents");
1158                cam->GetAverageLoGainSector(sector).DrawClone("fourierevents");
1159            }
1160
1161        }
1162
1163        return;
1164    }
1165}
1166   
1167
1168void  MJCalibration::DisplayReferenceLines(MHCamera *cam, const Int_t what) const
1169{
1170
1171  const MGeomCam *geom = cam->GetGeometry();
1172
1173  Double_t x = geom->InheritsFrom("MGeomCamMagic") ? 397 : cam->GetNbinsX() ;
1174
1175  TLine line;
1176  line.SetLineStyle(kDashed);
1177  line.SetLineWidth(3);
1178  line.SetLineColor(kBlue);
1179 
1180  TLine *l1 = NULL;
1181
1182  switch (what)
1183    {
1184    case 0:
1185      l1 = line.DrawLine(0, fRefQEInner, x, fRefQEInner);     
1186      break;
1187    case  1:
1188      l1 = line.DrawLine(0, fRefConvFADC2PheInner, x, fRefConvFADC2PheInner);
1189      break;
1190    case  2:
1191      l1 = line.DrawLine(0, fRefFADC2PheInner, x, fRefFADC2PheInner );
1192      break;
1193    case  3:
1194      l1 = line.DrawLine(0, fRefArrivalTimeInner, x, fRefArrivalTimeInner );
1195      break;
1196    case  4:
1197      l1 = line.DrawLine(0, fRefArrivalTimeRmsInner, x, fRefArrivalTimeRmsInner );
1198      break;
1199    case 5:
1200      l1 = line.DrawLine(0, 0, x, 0);
1201      break;
1202    case 6:
1203      l1 = line.DrawLine(0, fRefTimeResolutionInner, x, fRefTimeResolutionInner );
1204      break;
1205    default:
1206      break;
1207    }
1208
1209  if (geom->InheritsFrom("MGeomCamMagic"))
1210    {
1211      const Double_t x2 = cam->GetNbinsX();
1212
1213      switch (what)
1214        {
1215        case 0:
1216          line.DrawLine(x2, fRefQEOuter, 398, fRefQEOuter);     
1217          break;
1218        case 1:
1219          line.DrawLine(x2, fRefConvFADC2PheOuter, 398, fRefConvFADC2PheOuter );
1220          break;
1221        case 2:
1222          line.DrawLine(x2, fRefFADC2PheOuter, 398, fRefFADC2PheOuter);
1223          break;
1224        case 3:
1225          line.DrawLine(x2, fRefArrivalTimeOuter, 398, fRefArrivalTimeOuter);
1226          break;
1227        case 4:
1228          line.DrawLine(x2, fRefArrivalTimeRmsOuter, 398, fRefArrivalTimeRmsOuter);
1229          break;
1230        case 5:
1231          line.DrawLine(x2, fRefTimeOffsetOuter, 398, fRefTimeOffsetOuter);
1232          break;
1233        case 6:
1234          line.DrawLine(x2, fRefTimeResolutionOuter, 398, fRefTimeResolutionOuter);
1235          break;
1236        default:
1237          break;
1238        }
1239    }
1240 
1241  TLegend *leg = new TLegend(0.6,0.85,0.9 ,0.95);
1242  leg->SetBit(kCanDelete);
1243  leg->AddEntry(l1, "Reference","l");
1244  leg->Draw();
1245}
1246
1247void  MJCalibration::DisplayOutliers(TH1D *hist, const char* whatsmall, const char* whatbig) const
1248{
1249
1250  const Int_t kNotDraw = 1<<9;
1251  TF1 *f = hist->GetFunction("gaus");
1252  f->ResetBit(kNotDraw);
1253
1254  const Float_t mean  = f->GetParameter(1);
1255  const Float_t lolim = mean - 4.0*f->GetParameter(2);
1256  const Float_t uplim = mean + 4.0*f->GetParameter(2);
1257  const Stat_t  dead  = hist->Integral(0,hist->FindBin(lolim)-1);
1258  const Stat_t  noisy = hist->Integral(hist->FindBin(uplim)+1,hist->GetNbinsX()+1);
1259
1260  const Double_t max = hist->GetBinContent(hist->GetMaximumBin());                                           
1261 
1262  const Double_t minl = hist->GetBinCenter(hist->GetXaxis()->GetFirst());
1263  const Double_t maxl = hist->GetBinCenter(hist->GetXaxis()->GetLast());
1264
1265  TLatex deadtex;
1266  deadtex.SetTextSize(0.07);
1267  deadtex.DrawLatex(minl+0.015*(maxl-minl),max/1.1,
1268                    Form("%3i %s pixels",(Int_t)dead,whatsmall));
1269
1270  TLatex noisytex;
1271  noisytex.SetTextSize(0.07);
1272  noisytex.DrawLatex(minl+0.015*(maxl-minl),max/1.2,
1273                     Form("%3i %s pixels",(Int_t)noisy,whatbig));
1274
1275}
1276
1277void MJCalibration::FixDataCheckHist(TH1D *hist) const 
1278{
1279
1280    hist->SetDirectory(NULL);
1281
1282    //
1283    // set the labels bigger
1284    //
1285    TAxis *xaxe = hist->GetXaxis();
1286    TAxis *yaxe = hist->GetYaxis();
1287   
1288    xaxe->CenterTitle();
1289    yaxe->CenterTitle();   
1290    xaxe->SetTitleSize(0.06);
1291    yaxe->SetTitleSize(0.06);   
1292    xaxe->SetTitleOffset(0.8);
1293    yaxe->SetTitleOffset(0.85);   
1294    xaxe->SetLabelSize(0.05);
1295    yaxe->SetLabelSize(0.05);   
1296
1297}
1298
1299// --------------------------------------------------------------------------
1300//
1301// Retrieve the output file written by WriteResult()
1302//
1303const char* MJCalibration::GetOutputFileName() const
1304{
1305    return Form("calib%08d.root", fSequence.GetSequence());
1306}
1307
1308// --------------------------------------------------------------------------
1309//
1310// Read the following values from resource file:
1311//
1312//   ConvFADC2PheMin
1313//   ConvFADC2PheMax
1314//   ConvFADC2PhotMin
1315//   ConvFADC2PhotMax
1316//
1317//   QEMin
1318//   QEMax
1319//
1320//   ArrivalTimeMin
1321//   ArrivalTimeMax
1322//
1323//   TimeOffsetMin
1324//   TimeOffsetMax
1325//   TimeResolutionMin
1326//   TimeResolutionMax
1327//
1328//   RefConvFADC2PheInner
1329//   RefConvFADC2PheOuter
1330//   RefConvFADC2PhotInner
1331//   RefConvFADC2PhotOuter
1332//
1333//   RefQEInner
1334//   RefQEOuter
1335//
1336//   RefArrivalTimeInner
1337//   RefArrivalTimeOuter
1338//   RefArrivalTimeRmsInner
1339//   RefArrivalTimeRmsOuter
1340//
1341//   RefTimeOffsetOuter
1342//   RefTimeResolutionInner
1343//   RefTimeResolutionOuter
1344//
1345void MJCalibration::ReadReferenceFile()
1346{
1347    TEnv refenv(fReferenceFile);
1348   
1349    fConvFADC2PheMin        = refenv.GetValue("ConvFADC2PheMin",fConvFADC2PheMin);
1350    fConvFADC2PheMax        = refenv.GetValue("ConvFADC2PheMax",fConvFADC2PheMax);
1351    fConvFADC2PhotMin       = refenv.GetValue("ConvFADC2PhotMin",fConvFADC2PhotMin);
1352    fConvFADC2PhotMax       = refenv.GetValue("ConvFADC2PhotMax",fConvFADC2PhotMax);
1353    fQEMin                  = refenv.GetValue("QEMin",fQEMin);
1354    fQEMax                  = refenv.GetValue("QEMax",fQEMax);
1355    fArrivalTimeMin         = refenv.GetValue("ArrivalTimeMin",fArrivalTimeMin);
1356    fArrivalTimeMax         = refenv.GetValue("ArrivalTimeMax",fArrivalTimeMax);
1357    fTimeOffsetMin          = refenv.GetValue("TimeOffsetMin",fTimeOffsetMin);
1358    fTimeOffsetMax          = refenv.GetValue("TimeOffsetMax",fTimeOffsetMax);
1359    fTimeResolutionMin      = refenv.GetValue("TimeResolutionMin",fTimeResolutionMin);
1360    fTimeResolutionMax      = refenv.GetValue("TimeResolutionMax",fTimeResolutionMax);
1361                                                               
1362    fRefFADC2PheInner       = refenv.GetValue("RefFADC2PheInner",fRefFADC2PheInner);
1363    fRefFADC2PheOuter       = refenv.GetValue("RefFADC2PheOuter",fRefFADC2PheOuter);
1364    fRefConvFADC2PhotInner  = refenv.GetValue("RefConvFADC2PhotInner",fRefConvFADC2PhotInner);
1365    fRefConvFADC2PhotOuter  = refenv.GetValue("RefConvFADC2PhotOuter",fRefConvFADC2PhotOuter);
1366    fRefConvFADC2PheInner   = refenv.GetValue("RefConvFADC2PheInner",fRefConvFADC2PheInner);
1367    fRefConvFADC2PheOuter   = refenv.GetValue("RefConvFADC2PheOuter",fRefConvFADC2PheOuter);
1368    fRefQEInner             = refenv.GetValue("RefQEInner",fRefQEInner);
1369    fRefQEOuter             = refenv.GetValue("RefQEOuter",fRefQEOuter);
1370    fRefArrivalTimeInner    = refenv.GetValue("RefArrivalTimeInner",fRefArrivalTimeInner);
1371    fRefArrivalTimeOuter    = refenv.GetValue("RefArrivalTimeOuter",fRefArrivalTimeOuter);
1372    fRefArrivalTimeRmsInner = refenv.GetValue("RefArrivalTimeRmsInner",fRefArrivalTimeRmsInner);
1373    fRefArrivalTimeRmsOuter = refenv.GetValue("RefArrivalTimeRmsOuter",fRefArrivalTimeRmsOuter);
1374    fRefTimeOffsetOuter     = refenv.GetValue("RefTimeOffsetOuter",fRefTimeOffsetOuter);
1375    fRefTimeResolutionInner = refenv.GetValue("RefTimeResolutionInner",fRefTimeResolutionInner);
1376    fRefTimeResolutionOuter = refenv.GetValue("RefTimeResolutionOuter",fRefTimeResolutionOuter);
1377}
1378
1379// --------------------------------------------------------------------------
1380//
1381// Read the following values from resource file.
1382//
1383Bool_t MJCalibration::ReadHiLoCalibFile()
1384{
1385    if (fExtractor && !fExtractor->HasLoGain())
1386        return kTRUE;
1387
1388//    if (!fIsHiLoCalibration)
1389//        return kTRUE;
1390
1391    // We use the night time stamp to determine the period
1392    // because the night must be in the sequence file
1393    const MTime &night = fSequence.GetNight();
1394    const Int_t period = night.GetMagicPeriod();
1395
1396    // Open resource file
1397    MEnv env(fHiLoCalibFile);
1398    if (!env.IsValid())
1399    {
1400        *fLog << err << "ERROR - Resource file " << fHiLoCalibFile;
1401        *fLog << " could not be opened... abort." << endl;
1402        return kFALSE;
1403    }
1404
1405    // Defined resource id
1406    const TString id = fSequence.IsMonteCarlo() ? "MC" : Form("%02d", period);
1407
1408    // Check for a valid entry for the correct period
1409    TString fname = env.GetValue(id, "");
1410    if (fname.IsNull())
1411    {
1412        *fLog << err << "ERROR - No entry for resource id '" << id;
1413        *fLog << "' found in " << fHiLoCalibFile << "... looking for default." << endl;
1414        return kFALSE;
1415/*
1416        *fLog << warn << "WARNING - No entry for period " << period;
1417        *fLog << " found in " << fHiLoCalibFile << "... looking for default." << endl;
1418
1419        fname = env.GetValue("00", "");
1420        if (fname.IsNull())
1421        {
1422            *fLog << err << "ERROR - No default entry (00) found in ";
1423            *fLog << fHiLoCalibFile << "... abort." << endl;
1424            return kFALSE;
1425        }*/
1426    }
1427
1428    *fLog << inf << "Reading Hi-/Lo-Gain calibration constants from " << fname << endl;
1429
1430    // Open file with calibration constants
1431    TFile file(fname, "READ");
1432    if (!file.IsOpen())
1433    {
1434        *fLog << err << "ERROR - Couldn't open file " << fname << " for reading... abort." << endl;
1435        return kFALSE;
1436    }
1437
1438    // read calibration constants
1439    MHCamEvent hilocam;
1440    if (hilocam.Read()<=0)
1441    {
1442        *fLog << err << "ERROR - Unable to read MHCamEvent from " << fname << "... abort." << endl;
1443        return kFALSE;
1444    }
1445
1446    // Get histogram with constants
1447    MHCamera *hist = hilocam.GetHist();
1448    if (!hist)
1449    {
1450        *fLog << err << "ERROR - MHCamEvent from " << fname << " empty... abort." << endl;
1451        return kFALSE;
1452    }
1453
1454    // Do some sanity stuff
1455    if (fCalibrationCam.GetSize() < 1)
1456        fCalibrationCam.InitSize(hist->GetNumPixels());
1457 
1458    if (fBadPixels.GetSize() < 1)
1459        fBadPixels.InitSize(hist->GetNumPixels());
1460 
1461    if ((UInt_t)fCalibrationCam.GetSize() != hist->GetNumPixels())
1462    {
1463        *fLog << err << "ERROR - Size mismatch MHCamEvent and MCalibrationChargeCam.. abort." << endl;
1464        return kFALSE;
1465    }
1466
1467    // Copy the constants to their final location
1468    // FIXME: For what the hell do we need to have the constants in
1469    //        in MCalibrationChargeCam?
1470    for (UInt_t i=0; i<hist->GetNumPixels(); i++)
1471    {
1472        hist->SetBit(MHCamera::kProfile);
1473        Double_t v = hist->GetBinContent(i);
1474        hist->SetBit(MHCamera::kErrorMean);
1475        Double_t e = hist->GetBinError(i);
1476        hist->ResetBit(MHCamera::kErrorMean);
1477        Double_t s = hist->GetBinError(i);
1478
1479        if (!hist->IsUsed(i))
1480        {
1481            fBadPixels[i].SetUncalibrated(MBadPixelsPix::kConversionHiLoNotValid);
1482            v = e = s = -1;
1483        }
1484
1485        MCalibrationChargePix &cpix = (MCalibrationChargePix&)fCalibrationCam[i];
1486        cpix.SetConversionHiLo(v);
1487        cpix.SetConversionHiLoErr(e);
1488        cpix.SetConversionHiLoSigma(s);
1489    }
1490
1491    return kTRUE;
1492}
1493
1494// --------------------------------------------------------------------------
1495//
1496// MJCalibration allows to setup several option by a resource file:
1497//   MJCalibration.Display: full, datacheck, normal
1498//   MJCalibration.RelTimeCalibration: yes,no
1499//   MJCalibration.DataCheck: yes,no
1500//   MJCalibration.Debug: yes,no
1501//   MJCalibration.UseBlindPixel: yes,no
1502//   MJCalibration.UsePINDiode: yes,no
1503//   MJCalibration.Geometry: MGeomCamMagic, MGeomCamECO1000
1504//
1505// Name of a file containing reference values (see ReadReferenceFile)
1506//   Prefix.ReferenceFile:    filename
1507// (see ReadReferenceFile)
1508//
1509// For more details see the class description and the corresponding Getters
1510//
1511Bool_t MJCalibration::CheckEnvLocal()
1512{
1513    TString dis = GetEnv("Display", "");
1514    if (dis.BeginsWith("Full", TString::kIgnoreCase))
1515        SetFullDisplay();
1516    if (dis.BeginsWith("DataCheck", TString::kIgnoreCase))
1517        SetDataCheckDisplay();
1518    if (dis.BeginsWith("Normal", TString::kIgnoreCase))
1519        SetNormalDisplay();
1520
1521    if (!MJCalib::CheckEnvLocal())
1522        return kFALSE;
1523
1524    SetRelTimeCalibration(GetEnv("RelTimeCalibration", IsRelTimes()));
1525    SetDebug(GetEnv("Debug", IsDebug()));
1526
1527    SetUseBlindPixel(GetEnv("UseBlindPixel", IsUseBlindPixel()));
1528    SetUsePINDiode(GetEnv("UsePINDiode", IsUsePINDiode()));
1529    SetGeometry(GetEnv("Geometry", fGeometry));
1530
1531    fMinEvents = (UInt_t)GetEnv("MinEvents", (Int_t)fMinEvents);
1532
1533    fReferenceFile = GetEnv("ReferenceFile",fReferenceFile.Data());
1534    ReadReferenceFile();
1535
1536    fHiLoCalibFile = GetEnv("HiLoCalibFile",fHiLoCalibFile.Data());
1537
1538    /*
1539    if (IsUseMC() && !fHiLoCalibFile.EndsWith("_mc.root"))
1540    {
1541        if (!fHiLoCalibFile.EndsWith(".root"))
1542        {
1543            *fLog << warn << "WARNING - Hi-/Lo-Gain intercalibration file ";
1544            *fLog << fHiLoCalibFile << " has not .root as extension..." << endl;
1545        }
1546        else
1547            fHiLoCalibFile.Insert(fHiLoCalibFile.Length()-5, "_mc");
1548    }
1549    */
1550
1551    return ReadHiLoCalibFile();
1552}
1553
1554void MJCalibration::InitBlindPixel(MExtractBlindPixel &blindext,
1555                                   MHCalibrationChargeBlindCam &blindcam)
1556{
1557    const Int_t run = fSequence.GetLastRun();
1558
1559    //
1560    // Initialize the blind pixel. Unfortunately, there is a hardware
1561    // difference in the first blind pixel until run
1562    // gkSecondBlindPixelInstallation and the later setup. The first
1563    // needs to use a filter because of the length of spurious NSB photon
1564    // signals. The latter get better along extracting the amplitude
1565    // from a small window.
1566    //
1567    const MCalibrationBlindCamOneOldStyle   one;
1568    const MCalibrationBlindCamTwoNewStyle   two;
1569    const MCalibrationBlindCamThreeNewStyle three;
1570
1571    const MCalibrationBlindCam &blindresults =
1572        run<gkSecondBlindPixelInstallation ? static_cast<MCalibrationBlindCam>(one) :
1573        (run<gkThirdBlindPixelInstallation ? static_cast<MCalibrationBlindCam>(two) : static_cast<MCalibrationBlindCam>(three));
1574
1575    blindresults.Copy(fCalibrationBlindCam);
1576
1577    blindext.SetExtractionType(MExtractBlindPixel::kIntegral);
1578    blindext.SetExtractionType(MExtractBlindPixel::kFilter);
1579
1580    if (run<gkSecondBlindPixelInstallation)
1581    {
1582        blindext.SetRange(10,19,0,6);
1583        blindext.SetNSBFilterLimit(70);
1584    }
1585    else
1586    {
1587        blindext.SetRange(5,8,0,2);
1588        blindext.SetNSBFilterLimit(38);
1589    }
1590
1591    if (run>=gkThirdBlindPixelInstallation)
1592        blindext.SetDataType(MExtractBlindPixel::kRawEvt2);
1593}
1594
1595// --------------------------------------------------------------------------
1596//
1597// Execute the task list and the eventloop:
1598//
1599// - Check the colour of the files in fRuns (FindColor()), otherwise return
1600// - Check for consistency between run numbers and number of files
1601// - Add fRuns to MReadMarsFile
1602// - Put into MParList:
1603//   1) MPedestalCam          (pedcam)
1604//   2) MCalibrationQECam     (fQECam)
1605//   3) MCalibrationChargeCam (fCalibrationCam)
1606//   4) MCalibrationRelTimeCam (fRelTimeCam)   (only if flag IsRelTimes() is chosen)
1607//   5) MBadPixelsCam         (fBadPixels)
1608//   6) MCalibrationChargePINDiode
1609//   7) MCalibrationBlindPix
1610// - Put into the MTaskList:
1611//   1)  MReadMarsFile
1612//   2)  MBadPixelsMerge
1613//   3)  MGeomApply
1614//   4)  MExtractor
1615//   5)  MExtractPINDiode
1616//   6)  MExtractBlindPixel
1617//   7)  MExtractTime (only if flag IsRelTimes() is chosen)
1618//   8)  MContinue(MFCosmics)
1619//   9)  MFillH("MHCalibrationChargePINDiode", "MExtractedSignalPINDiode",   "FillPINDiode")
1620//   10) MFillH("MHCalibrationChargeBlindCam", "MExtractedSignalBlindPixel", "FillBlindCam")
1621//   11) MFillH("MHCalibrationChargeCam",      "MExtractedSignalCam",        "FillChargeCam")
1622//   12) MFillH("MHCalibrationChargeCam",      "MExtractedSignalCam",        "FillRelTime")
1623//   13) MCalibrationChargeCalc
1624//   14) MFillH("MHCalibrationRelTimeCam",     "MArrivalTimeCam") (only if flag IsRelTimes() is chosen)
1625//   15) MCalibrationRelTimeCalc
1626// - Execute MEvtLoop
1627// - DisplayResult()
1628// - WriteResult()
1629//
1630Bool_t MJCalibration::Process(MPedestalCam &pedcam)
1631{
1632    if (!fSequence.IsValid())
1633    {
1634          *fLog << err << "ERROR - Sequence invalid..." << endl;
1635          return kFALSE;
1636    }
1637
1638    *fLog << inf;
1639    fLog->Separator(GetDescriptor());
1640    *fLog << "Calculate calibration constants from Sequence #";
1641    *fLog << fSequence.GetSequence() << endl << endl;
1642
1643    // --------------------------------------------------------------------------------
1644   
1645    if (!CheckEnv())
1646        return kFALSE;
1647
1648    // --------------------------------------------------------------------------------
1649
1650    // Setup Tasklist
1651    MParList plist;
1652    MTaskList tlist;
1653    plist.AddToList(&tlist);
1654    plist.AddToList(this); // take care of fDisplay!
1655
1656    MDirIter iter;
1657    if (fSequence.SetupCalRuns(iter, 0, !fSequence.IsMonteCarlo())<=0)
1658        return kFALSE;
1659
1660    //
1661    // Input containers
1662    //
1663    pedcam.SetName("MPedestalCam"); // MPedestalFundamental
1664    plist.AddToList(&pedcam);
1665    plist.AddToList(&fBadPixels);
1666
1667    //
1668    // Calibration Results containers
1669    //
1670    plist.AddToList(&fQECam);
1671    plist.AddToList(&fCalibrationCam);
1672    plist.AddToList(&fRelTimeCam);
1673    if (IsUseBlindPixel())
1674        plist.AddToList(&fCalibrationBlindCam);
1675    if (IsUsePINDiode())
1676        plist.AddToList(&fCalibrationPINDiode);
1677
1678    //
1679    // Initialize two histogram containers which could be modified in this class
1680    //
1681    MHCalibrationRelTimeCam     reltimecam;
1682    MHCalibrationChargeCam      chargecam;
1683    MHCalibrationChargeBlindCam blindcam;
1684    plist.AddToList(&chargecam);
1685
1686    if (IsUseBlindPixel())
1687      plist.AddToList(&blindcam);
1688    if (IsRelTimes())
1689      plist.AddToList(&reltimecam);
1690    //
1691    // Data Reading tasks
1692    //
1693    MReadMarsFile read("Events");
1694    MRawFileRead rawread(NULL);
1695
1696    if (!fSequence.IsMonteCarlo())
1697    {
1698        rawread.AddFiles(iter);
1699        tlist.AddToList(&rawread);
1700    }
1701    else
1702    {
1703        read.DisableAutoScheme();
1704        read.AddFiles(iter);
1705        tlist.AddToList(&read);
1706    }
1707
1708    //
1709    // Other Tasks
1710    //
1711
1712    // Set the default for data version earlier than 5, where no valid
1713    // trigger pattern exists. There should not be pin diode or other
1714    // types of events inside the calibration files which should be skipped,
1715    // anyway. So we set the default such that the MContinue ccalib
1716    // will never be executed.
1717    // We allow to have only calibration events before Prescaling.
1718    // We require that the calibration events have not been prescaled (why?)
1719    MTriggerPatternDecode     trgpat;
1720    MFTriggerPattern          fcalib("CalibFilter");
1721    fcalib.SetDefault(kFALSE);
1722    fcalib.DenyCalibration(MFTriggerPattern::kPrescaled);
1723    fcalib.DenyAll();
1724    fcalib.AllowCalibration();
1725
1726    MContinue                 ccalib(&fcalib,"ContTrigPattern");
1727
1728    MCalibrationPatternDecode decode;
1729    MGeomApply                apply;
1730    apply.SetGeometry(fGeometry);
1731
1732    MBadPixelsMerge          merge(&fBadPixels);
1733    MExtractPINDiode         pinext;
1734    MExtractBlindPixel       blindext;
1735
1736    if (IsUseBlindPixel())
1737        InitBlindPixel(blindext, blindcam);
1738
1739//    MExtractSlidingWindow    extract2;
1740//    MExtractTimeHighestIntegral timehigh;
1741    MCalibrationChargeCalc   calcalc;
1742    MCalibrationRelTimeCalc  timecalc;
1743    calcalc.SetExtractor(fExtractor);
1744
1745    if (IsDebug())
1746    {
1747        chargecam.SetDebug();
1748        calcalc.SetDebug();
1749    }
1750
1751    //
1752    // Calibration histogramming
1753    //
1754    MFillH fillpin("MHCalibrationChargePINDiode", "MExtractedSignalPINDiode",   "FillPINDiode");
1755    MFillH fillbnd("MHCalibrationChargeBlindCam", "MExtractedSignalBlindPixel", "FillBlindCam");
1756    MFillH fillcam("MHCalibrationChargeCam",      "MExtractedSignalCam",        "FillChargeCam");
1757    MFillH filltme("MHCalibrationRelTimeCam",     "MArrivalTimeCam",            "FillRelTime");
1758    fillpin.SetBit(MFillH::kDoNotDisplay);
1759    fillbnd.SetBit(MFillH::kDoNotDisplay);
1760    fillcam.SetBit(MFillH::kDoNotDisplay);
1761    filltme.SetBit(MFillH::kDoNotDisplay);
1762
1763    //
1764    // Set default extractors in case, none has been set...
1765    //
1766    /*
1767    if (!fExtractor)
1768      fExtractor = &extract2;
1769    if (!fTimeExtractor)
1770      fTimeExtractor = &timehigh;
1771     */
1772    MExtractTimeAndChargeSpline spline;
1773    if (!fExtractor)
1774      fExtractor = &spline;
1775//    if (!fTimeExtractor)
1776//      fTimeExtractor = &timehigh;
1777
1778    const Bool_t istimecharge = fExtractor->InheritsFrom("MExtractTimeAndCharge");
1779
1780    //
1781    // Look if the extractor is a pure charge or also a time extractor
1782    //
1783    if (istimecharge)
1784    {
1785        if (fExtractorCam.GetSize() == pedcam.GetSize())
1786            calcalc.SetPedestals(&fExtractorCam);
1787        else
1788        {
1789            *fLog << err << GetDescriptor() << "ERROR - ";
1790            *fLog << "Used Extractor derives from MExtractTimeAndCharge, " << endl;
1791            *fLog << "but MExtractorCam size " << fExtractorCam.GetSize() << " ";
1792            *fLog << "mismatch pedcam size " << pedcam.GetSize() << "! " << endl;
1793            return kFALSE;
1794        }
1795    }
1796
1797    //
1798    // Setup more tasks and tasklist
1799    //
1800    MTaskEnv taskenv("ExtractSignal");
1801    taskenv.SetDefault(fExtractor);
1802
1803    tlist.AddToList(&trgpat);
1804    if (fColor != MCalibrationCam::kCT1)
1805        tlist.AddToList(&ccalib);
1806    tlist.AddToList(&decode);
1807    tlist.AddToList(&merge);
1808    tlist.AddToList(&apply);
1809
1810    // Produce pedestal subtracted raw-data
1811    MPedestalSubtract pedsub;
1812    pedsub.SetPedestalCam(&pedcam);
1813    tlist.AddToList(&pedsub);
1814
1815    MCalibColorSet colorset;
1816    if (fColor != MCalibrationCam::kNONE)
1817        colorset.SetExplicitColor(fColor);
1818    tlist.AddToList(&colorset);
1819
1820    tlist.AddToList(&taskenv);
1821
1822    if (IsUsePINDiode())
1823      tlist.AddToList(&pinext);
1824    if (IsUseBlindPixel())
1825      tlist.AddToList(&blindext);
1826
1827    MTaskEnv taskenv2("ExtractTime");
1828    if (!istimecharge)
1829    {
1830      taskenv2.SetDefault(fTimeExtractor);
1831
1832      if (IsRelTimes())
1833        tlist.AddToList(&taskenv2);
1834    }
1835
1836    //
1837    // Apply a filter against cosmics (this is for the old times in which
1838    // the calibration events where triggered by level 1 and for
1839    // sanity against empty trigger events)
1840    //
1841    MFCosmics cosmics;
1842    cosmics.SetMaxEmptyPixels(0.05);
1843    cosmics.SetMaxAcceptedFraction(0.5); // max=0.5 cosmics
1844
1845    MContinue cont(&cosmics, "ContCosmics");
1846    tlist.AddToList(&cont);
1847
1848    tlist.AddToList(&fillcam);
1849
1850    if (IsUseBlindPixel())
1851      tlist.AddToList(&fillbnd);
1852    if (IsUsePINDiode())
1853      tlist.AddToList(&fillpin);
1854
1855    tlist.AddToList(&calcalc);
1856
1857    if (IsRelTimes())
1858    {
1859        tlist.AddToList(&filltme);
1860        tlist.AddToList(&timecalc);
1861    }
1862
1863    MHCamEvent evt2(0, "Extra'd", "Extracted Calibration Signal;;S [cnts/sl]");
1864    MHCamEvent evt9(4, "ArrTm",   "Extracted ArrivalTime;;T");
1865
1866    MFillH fill2(&evt2, "MExtractedSignalCam", "FillExtractedSignal");
1867    MFillH fill9(&evt9, "MArrivalTimeCam",     "FillArrivalTime");
1868
1869    tlist.AddToList(&fill2);
1870    tlist.AddToList(&fill9);
1871
1872    /*
1873     MFillH fillP("MHPulseShape", "", "FillPulseShape");
1874     fillP.SetNameTab("Pulse");
1875     tlist.AddToList(&fillP);
1876     */
1877
1878    // Create and setup the eventloop
1879    MEvtLoop evtloop(fName);
1880    evtloop.SetParList(&plist);
1881    evtloop.SetDisplay(fDisplay);
1882    evtloop.SetLogStream(fLog);
1883    if (!SetupEnv(evtloop))
1884        return kFALSE;
1885
1886    if (!taskenv.GetTask() && !taskenv2.GetTask())
1887    {
1888        *fLog << err << "ERROR - Neither ExtractSignal nor ExtractTime initialized or both '<dummy>'." << endl;
1889        return kFALSE;
1890    }
1891
1892    if (!WriteTasks(taskenv.GetTask(), istimecharge ? 0 : taskenv2.GetTask()))
1893        return kFALSE;
1894
1895    // Execute first analysis
1896    const Bool_t rc = evtloop.Eventloop();
1897
1898    if (!fCalibrationPINDiode.IsValid())
1899        SetUsePINDiode(kFALSE);
1900
1901    const Int_t numexec = !fSequence.IsMonteCarlo() ? rawread.GetNumExecutions() : read.GetNumExecutions();
1902    if (numexec>0)
1903    {
1904        DisplayResult(plist);
1905        if (!WriteResult(plist))
1906            return kFALSE;
1907    }
1908
1909    if (!rc)
1910    {
1911        *fLog << err << GetDescriptor() << ": Failed." << endl;
1912        return kFALSE;
1913    }
1914
1915    if (calcalc.GetNumExecutions()<fMinEvents)
1916    {
1917        *fLog << err << GetDescriptor() << ": Failed. Less than the required " << fMinEvents << " evts processed." << endl;
1918        return kFALSE;
1919    }
1920
1921    // --------------------------------------------------------------------------------
1922
1923    if (fIsPixelCheck)
1924    {
1925        chargecam[fCheckedPixId].DrawClone("datacheck");
1926        chargecam(fCheckedPixId).DrawClone("datacheck");
1927
1928        if (IsRelTimes())
1929        {
1930            reltimecam[fCheckedPixId].DrawClone("");
1931            reltimecam(fCheckedPixId).DrawClone("");
1932        }
1933    }
1934
1935    *fLog << all << GetDescriptor() << ": Done." << endl;
1936
1937    return kTRUE;
1938}
1939
1940/*
1941Bool_t MJCalibration::WriteEventloop(MEvtLoop &evtloop) const
1942{
1943    if (IsNoStorage())
1944        return kTRUE;
1945
1946  if (fPathOut.IsNull())
1947    return kTRUE;
1948 
1949  const TString oname(GetOutputFile());
1950 
1951  *fLog << inf << "Writing to file: " << oname << endl;
1952 
1953  TFile file(oname, fOverwrite?"RECREATE":"NEW", "File created by MJCalibration", 9);
1954  if (!file.IsOpen())
1955  {
1956      *fLog << err << "ERROR - Couldn't open file " << oname << " for writing..." << endl;
1957      return kFALSE;
1958  }
1959
1960  if (evtloop.Write(fName)<=0)
1961  {
1962      *fLog << err << "Unable to write MEvtloop to " << oname << endl;
1963      return kFALSE;
1964  }
1965 
1966  return kTRUE;
1967}
1968*/
1969
1970Bool_t MJCalibration::WriteTasks(MTask *t1, MTask *t2) const
1971{
1972    if (IsNoStorage())
1973        return kTRUE;
1974
1975    TObjArray cont;
1976    if (t1)
1977        cont.Add(t1);
1978    if (t2)
1979        cont.Add(t2);
1980
1981    return WriteContainer(cont, GetOutputFileName(), fOverwrite?"RECREATE":"NEW");
1982}
1983
1984// --------------------------------------------------------------------------
1985//
1986// Write the result into the output file GetOutputFile(), if fOutputPath exists.
1987//
1988// The following containers are written:
1989// - MStatusDisplay
1990// - MCalibrationChargeCam
1991// - MCalibrationBlindCam
1992// - MCalibrationQECam
1993// - MCalibrationChargePINDiode
1994// - MBadPixelsCam
1995//
1996// If the flag kRelTimes is set, then also:
1997// - MCalibrationRelTimeCam
1998//
1999Bool_t MJCalibration::WriteResult(MParList &plist)
2000{
2001    if (IsNoStorage())
2002        return kTRUE;
2003
2004    TObjArray cont;
2005    cont.Add(&fBadPixels);
2006    cont.Add(&fCalibrationCam);
2007    cont.Add(&fQECam);
2008    cont.Add(&fCalibrationBlindCam);
2009    cont.Add(&fCalibrationPINDiode);
2010
2011    if (IsRelTimes())
2012        cont.Add(&fRelTimeCam);
2013
2014    if (fExtractorCam.GetSize() != 0)
2015    {
2016        fExtractorCam.SetName("MPedestalExtracted");
2017        cont.Add(&fExtractorCam);
2018    }
2019
2020    TObject *pedcam = plist.FindObject("MPedestalCam");
2021    if (!pedcam)
2022        *fLog << warn << " - WARNING - MPedestalCam (fundamental)... not found for writing!" << endl;
2023    else
2024        cont.Add(pedcam);
2025
2026    TObject *geom = plist.FindObject("MGeomCam");
2027    if (!geom)
2028        *fLog << warn << " - WARNING - MGeomCam... not found for writing!" << endl;
2029    else
2030        cont.Add(geom);
2031
2032    if (IsHistsStorage())
2033    {
2034        cont.Add(plist.FindObject("MHCalibrationChargeCam"));
2035        cont.Add(plist.FindObject("MHCalibrationChargeBlindCam"));
2036        cont.Add(plist.FindObject("MHCalibrationChargePINDiode"));
2037        if (IsRelTimes())
2038            cont.Add(plist.FindObject("MHCalibrationRelTimeCam"));
2039    }
2040
2041    if (fDisplay)
2042        cont.Add(fDisplay);
2043
2044    cont.Add(const_cast<TEnv*>(GetEnv()));
2045    cont.Add(&fSequence);
2046
2047    return WriteContainer(cont, GetOutputFileName(), "UPDATE");
2048}
2049
2050void MJCalibration::DisplayDoubleProject(MHCamera *cam, const char* whatsmall, const char* whatbig) const
2051{
2052
2053  TArrayI inner(1);
2054  inner[0] = 0;
2055
2056  TArrayI outer(1);
2057  outer[0] = 1;
2058
2059  TArrayI s1(3);
2060  s1[0] = 6;
2061  s1[1] = 1;
2062  s1[2] = 2;
2063
2064  TArrayI s2(3);
2065  s2[0] = 3;
2066  s2[1] = 4;
2067  s2[2] = 5;
2068
2069  TVirtualPad *pad = gPad;
2070  pad->Divide(2,1);
2071
2072  TH1D *inout[2];
2073
2074  for (int i=0; i<2; i++)
2075    {
2076      pad->cd(i+1);
2077      gPad->SetBorderMode(0);
2078      gPad->SetTicks();
2079
2080      inout[i] = cam->ProjectionS(TArrayI(), TArrayI(1,&i), i==0 ? "Inner" : "Outer");
2081      FixDataCheckHist(inout[i]);
2082      inout[i]->SetTitle(Form("%s %s",cam->GetTitle(),i==0 ? "Inner" : "Outer"));
2083      inout[i]->SetDirectory(NULL);
2084      inout[i]->SetLineColor(kRed+i);
2085      inout[i]->SetBit(kCanDelete);
2086      inout[i]->Draw();
2087      //
2088      // Display the outliers as dead and noisy pixels
2089      //
2090      if (!inout[i]->Fit("gaus","0Q"))
2091        DisplayOutliers(inout[i],whatsmall,whatbig);
2092
2093      gPad->Modified();
2094      gPad->Update();     
2095      TPaveStats *st = (TPaveStats*)inout[i]->GetListOfFunctions()->FindObject("stats");
2096      st->SetY1NDC(0.6);
2097      st->SetY2NDC(0.9);
2098      st->SetX1NDC(0.55);
2099      st->SetX2NDC(0.99);
2100      gPad->Modified();
2101      gPad->Update();     
2102
2103      TLegend *leg2 = new TLegend(0.55,0.4,0.99,0.6);
2104
2105      //
2106      // Display the two half of the camera separately
2107      //
2108      TH1D *half[2];
2109      half[0] = cam->ProjectionS(s1, TArrayI(1,&i), "Sector 6-1-2");
2110      half[1] = cam->ProjectionS(s2, TArrayI(1,&i), "Sector 3-4-5");
2111
2112      for (int j=0; j<2; j++)
2113        {
2114          half[j]->SetLineColor(kRed+i+2*j+1);
2115          half[j]->SetDirectory(NULL);
2116          half[j]->SetBit(kCanDelete);
2117          half[j]->Draw("same");
2118          leg2->AddEntry(half[j], half[j]->GetName(), "l");
2119        }
2120      leg2->Draw();
2121    }
2122}
Note: See TracBrowser for help on using the repository browser.