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

Last change on this file since 8804 was 8804, checked in by tbretz, 14 years ago
*** empty log message ***
File size: 65.4 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-2007
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 MTriggerPatternDecode trgpat;
1718 MFTriggerPattern fcalib("CalibFilter");
1719 fcalib.SetDefault(kFALSE);
1720 fcalib.DenyCalibration(MFTriggerPattern::kPrescaled);
1721
1722 MContinue ccalib(&fcalib,"ContTrigPattern");
1723
1724 MCalibrationPatternDecode decode;
1725 MGeomApply apply;
1726 apply.SetGeometry(fGeometry);
1727
1728 MBadPixelsMerge merge(&fBadPixels);
1729 MExtractPINDiode pinext;
1730 MExtractBlindPixel blindext;
1731
1732 if (IsUseBlindPixel())
1733 InitBlindPixel(blindext, blindcam);
1734
1735// MExtractSlidingWindow extract2;
1736// MExtractTimeHighestIntegral timehigh;
1737 MCalibrationChargeCalc calcalc;
1738 MCalibrationRelTimeCalc timecalc;
1739 calcalc.SetExtractor(fExtractor);
1740
1741 if (IsDebug())
1742 {
1743 chargecam.SetDebug();
1744 calcalc.SetDebug();
1745 }
1746
1747 //
1748 // Calibration histogramming
1749 //
1750 MFillH fillpin("MHCalibrationChargePINDiode", "MExtractedSignalPINDiode", "FillPINDiode");
1751 MFillH fillbnd("MHCalibrationChargeBlindCam", "MExtractedSignalBlindPixel", "FillBlindCam");
1752 MFillH fillcam("MHCalibrationChargeCam", "MExtractedSignalCam", "FillChargeCam");
1753 MFillH filltme("MHCalibrationRelTimeCam", "MArrivalTimeCam", "FillRelTime");
1754 fillpin.SetBit(MFillH::kDoNotDisplay);
1755 fillbnd.SetBit(MFillH::kDoNotDisplay);
1756 fillcam.SetBit(MFillH::kDoNotDisplay);
1757 filltme.SetBit(MFillH::kDoNotDisplay);
1758
1759 //
1760 // Set default extractors in case, none has been set...
1761 //
1762 /*
1763 if (!fExtractor)
1764 fExtractor = &extract2;
1765 if (!fTimeExtractor)
1766 fTimeExtractor = &timehigh;
1767 */
1768 MExtractTimeAndChargeSpline spline;
1769 if (!fExtractor)
1770 fExtractor = &spline;
1771// if (!fTimeExtractor)
1772// fTimeExtractor = &timehigh;
1773
1774 const Bool_t istimecharge = fExtractor->InheritsFrom("MExtractTimeAndCharge");
1775
1776 //
1777 // Look if the extractor is a pure charge or also a time extractor
1778 //
1779 if (istimecharge)
1780 {
1781 if (fExtractorCam.GetSize() == pedcam.GetSize())
1782 calcalc.SetPedestals(&fExtractorCam);
1783 else
1784 {
1785 *fLog << err << GetDescriptor() << "ERROR - ";
1786 *fLog << "Used Extractor derives from MExtractTimeAndCharge, " << endl;
1787 *fLog << "but MExtractorCam size " << fExtractorCam.GetSize() << " ";
1788 *fLog << "mismatch pedcam size " << pedcam.GetSize() << "! " << endl;
1789 return kFALSE;
1790 }
1791 }
1792
1793 //
1794 // Setup more tasks and tasklist
1795 //
1796 MTaskEnv taskenv("ExtractSignal");
1797 taskenv.SetDefault(fExtractor);
1798
1799 tlist.AddToList(&trgpat);
1800 if (fColor != MCalibrationCam::kCT1)
1801 tlist.AddToList(&ccalib);
1802 tlist.AddToList(&decode);
1803 tlist.AddToList(&merge);
1804 tlist.AddToList(&apply);
1805
1806 // Produce pedestal subtracted raw-data
1807 MPedestalSubtract pedsub;
1808 pedsub.SetPedestalCam(&pedcam);
1809 tlist.AddToList(&pedsub);
1810
1811 MCalibColorSet colorset;
1812 if (fColor != MCalibrationCam::kNONE)
1813 colorset.SetExplicitColor(fColor);
1814 tlist.AddToList(&colorset);
1815
1816 tlist.AddToList(&taskenv);
1817
1818 if (IsUsePINDiode())
1819 tlist.AddToList(&pinext);
1820 if (IsUseBlindPixel())
1821 tlist.AddToList(&blindext);
1822
1823 MTaskEnv taskenv2("ExtractTime");
1824 if (!istimecharge)
1825 {
1826 taskenv2.SetDefault(fTimeExtractor);
1827
1828 if (IsRelTimes())
1829 tlist.AddToList(&taskenv2);
1830 }
1831
1832 //
1833 // Apply a filter against cosmics
1834 // (will have to be needed in the future
1835 // when the calibration hardware-trigger is working)
1836 //
1837 MFCosmics cosmics;
1838 cosmics.SetMaxEmptyPixels(0.05);
1839 cosmics.SetMaxAcceptedFraction(0.5); // max=0.5 cosmics
1840
1841 MContinue cont(&cosmics, "ContCosmics");
1842 tlist.AddToList(&cont);
1843
1844 tlist.AddToList(&fillcam);
1845
1846 if (IsUseBlindPixel())
1847 tlist.AddToList(&fillbnd);
1848 if (IsUsePINDiode())
1849 tlist.AddToList(&fillpin);
1850
1851 tlist.AddToList(&calcalc);
1852
1853 if (IsRelTimes())
1854 {
1855 tlist.AddToList(&filltme);
1856 tlist.AddToList(&timecalc);
1857 }
1858
1859 MHCamEvent evt2(0, "Extra'd", "Extracted Calibration Signal;;S [cnts/sl]");
1860 MHCamEvent evt9(4, "ArrTm", "Extracted ArrivalTime;;T");
1861
1862 MFillH fill2(&evt2, "MExtractedSignalCam", "FillExtractedSignal");
1863 MFillH fill9(&evt9, "MArrivalTimeCam", "FillArrivalTime");
1864
1865 tlist.AddToList(&fill2);
1866 tlist.AddToList(&fill9);
1867
1868 /*
1869 MFillH fillP("MHPulseShape", "", "FillPulseShape");
1870 fillP.SetNameTab("Pulse");
1871 tlist.AddToList(&fillP);
1872 */
1873
1874 // Create and setup the eventloop
1875 MEvtLoop evtloop(fName);
1876 evtloop.SetParList(&plist);
1877 evtloop.SetDisplay(fDisplay);
1878 evtloop.SetLogStream(fLog);
1879 if (!SetupEnv(evtloop))
1880 return kFALSE;
1881
1882 if (!taskenv.GetTask() && !taskenv2.GetTask())
1883 {
1884 *fLog << err << "ERROR - Neither ExtractSignal nor ExtractTime initialized or both '<dummy>'." << endl;
1885 return kFALSE;
1886 }
1887
1888 if (!WriteTasks(taskenv.GetTask(), istimecharge ? 0 : taskenv2.GetTask()))
1889 return kFALSE;
1890
1891 // Execute first analysis
1892 const Bool_t rc = evtloop.Eventloop();
1893
1894 if (!fCalibrationPINDiode.IsValid())
1895 SetUsePINDiode(kFALSE);
1896
1897 const Int_t numexec = !fSequence.IsMonteCarlo() ? rawread.GetNumExecutions() : read.GetNumExecutions();
1898 if (numexec>0)
1899 {
1900 DisplayResult(plist);
1901 if (!WriteResult(plist))
1902 return kFALSE;
1903 }
1904
1905 if (!rc)
1906 {
1907 *fLog << err << GetDescriptor() << ": Failed." << endl;
1908 return kFALSE;
1909 }
1910
1911 if (calcalc.GetNumExecutions()<fMinEvents)
1912 {
1913 *fLog << err << GetDescriptor() << ": Failed. Less than the required " << fMinEvents << " evts processed." << endl;
1914 return kFALSE;
1915 }
1916
1917 // --------------------------------------------------------------------------------
1918
1919 if (fIsPixelCheck)
1920 {
1921 chargecam[fCheckedPixId].DrawClone("datacheck");
1922 chargecam(fCheckedPixId).DrawClone("datacheck");
1923
1924 if (IsRelTimes())
1925 {
1926 reltimecam[fCheckedPixId].DrawClone("");
1927 reltimecam(fCheckedPixId).DrawClone("");
1928 }
1929 }
1930
1931 *fLog << all << GetDescriptor() << ": Done." << endl;
1932
1933 return kTRUE;
1934}
1935
1936/*
1937Bool_t MJCalibration::WriteEventloop(MEvtLoop &evtloop) const
1938{
1939 if (IsNoStorage())
1940 return kTRUE;
1941
1942 if (fPathOut.IsNull())
1943 return kTRUE;
1944
1945 const TString oname(GetOutputFile());
1946
1947 *fLog << inf << "Writing to file: " << oname << endl;
1948
1949 TFile file(oname, fOverwrite?"RECREATE":"NEW", "File created by MJCalibration", 9);
1950 if (!file.IsOpen())
1951 {
1952 *fLog << err << "ERROR - Couldn't open file " << oname << " for writing..." << endl;
1953 return kFALSE;
1954 }
1955
1956 if (evtloop.Write(fName)<=0)
1957 {
1958 *fLog << err << "Unable to write MEvtloop to " << oname << endl;
1959 return kFALSE;
1960 }
1961
1962 return kTRUE;
1963}
1964*/
1965
1966Bool_t MJCalibration::WriteTasks(MTask *t1, MTask *t2) const
1967{
1968 if (IsNoStorage())
1969 return kTRUE;
1970
1971 TObjArray cont;
1972 if (t1)
1973 cont.Add(t1);
1974 if (t2)
1975 cont.Add(t2);
1976
1977 return WriteContainer(cont, GetOutputFileName(), fOverwrite?"RECREATE":"NEW");
1978}
1979
1980// --------------------------------------------------------------------------
1981//
1982// Write the result into the output file GetOutputFile(), if fOutputPath exists.
1983//
1984// The following containers are written:
1985// - MStatusDisplay
1986// - MCalibrationChargeCam
1987// - MCalibrationBlindCam
1988// - MCalibrationQECam
1989// - MCalibrationChargePINDiode
1990// - MBadPixelsCam
1991//
1992// If the flag kRelTimes is set, then also:
1993// - MCalibrationRelTimeCam
1994//
1995Bool_t MJCalibration::WriteResult(MParList &plist)
1996{
1997 if (IsNoStorage())
1998 return kTRUE;
1999
2000 TObjArray cont;
2001 cont.Add(&fBadPixels);
2002 cont.Add(&fCalibrationCam);
2003 cont.Add(&fQECam);
2004 cont.Add(&fCalibrationBlindCam);
2005 cont.Add(&fCalibrationPINDiode);
2006
2007 if (IsRelTimes())
2008 cont.Add(&fRelTimeCam);
2009
2010 if (fExtractorCam.GetSize() != 0)
2011 {
2012 fExtractorCam.SetName("MPedestalExtracted");
2013 cont.Add(&fExtractorCam);
2014 }
2015
2016 TObject *pedcam = plist.FindObject("MPedestalCam");
2017 if (!pedcam)
2018 *fLog << warn << " - WARNING - MPedestalCam (fundamental)... not found for writing!" << endl;
2019 else
2020 cont.Add(pedcam);
2021
2022 TObject *geom = plist.FindObject("MGeomCam");
2023 if (!geom)
2024 *fLog << warn << " - WARNING - MGeomCam... not found for writing!" << endl;
2025 else
2026 cont.Add(geom);
2027
2028 if (IsHistsStorage())
2029 {
2030 cont.Add(plist.FindObject("MHCalibrationChargeCam"));
2031 cont.Add(plist.FindObject("MHCalibrationChargeBlindCam"));
2032 cont.Add(plist.FindObject("MHCalibrationChargePINDiode"));
2033 if (IsRelTimes())
2034 cont.Add(plist.FindObject("MHCalibrationRelTimeCam"));
2035 }
2036
2037 if (fDisplay)
2038 cont.Add(fDisplay);
2039
2040 cont.Add(const_cast<TEnv*>(GetEnv()));
2041 cont.Add(&fSequence);
2042
2043 return WriteContainer(cont, GetOutputFileName(), "UPDATE");
2044}
2045
2046void MJCalibration::DisplayDoubleProject(MHCamera *cam, const char* whatsmall, const char* whatbig) const
2047{
2048
2049 TArrayI inner(1);
2050 inner[0] = 0;
2051
2052 TArrayI outer(1);
2053 outer[0] = 1;
2054
2055 TArrayI s1(3);
2056 s1[0] = 6;
2057 s1[1] = 1;
2058 s1[2] = 2;
2059
2060 TArrayI s2(3);
2061 s2[0] = 3;
2062 s2[1] = 4;
2063 s2[2] = 5;
2064
2065 TVirtualPad *pad = gPad;
2066 pad->Divide(2,1);
2067
2068 TH1D *inout[2];
2069
2070 for (int i=0; i<2; i++)
2071 {
2072 pad->cd(i+1);
2073 gPad->SetBorderMode(0);
2074 gPad->SetTicks();
2075
2076 inout[i] = cam->ProjectionS(TArrayI(), TArrayI(1,&i), i==0 ? "Inner" : "Outer");
2077 FixDataCheckHist(inout[i]);
2078 inout[i]->SetTitle(Form("%s %s",cam->GetTitle(),i==0 ? "Inner" : "Outer"));
2079 inout[i]->SetDirectory(NULL);
2080 inout[i]->SetLineColor(kRed+i);
2081 inout[i]->SetBit(kCanDelete);
2082 inout[i]->Draw();
2083 //
2084 // Display the outliers as dead and noisy pixels
2085 //
2086 if (!inout[i]->Fit("gaus","0Q"))
2087 DisplayOutliers(inout[i],whatsmall,whatbig);
2088
2089 gPad->Modified();
2090 gPad->Update();
2091 TPaveStats *st = (TPaveStats*)inout[i]->GetListOfFunctions()->FindObject("stats");
2092 st->SetY1NDC(0.6);
2093 st->SetY2NDC(0.9);
2094 st->SetX1NDC(0.55);
2095 st->SetX2NDC(0.99);
2096 gPad->Modified();
2097 gPad->Update();
2098
2099 TLegend *leg2 = new TLegend(0.55,0.4,0.99,0.6);
2100
2101 //
2102 // Display the two half of the camera separately
2103 //
2104 TH1D *half[2];
2105 half[0] = cam->ProjectionS(s1, TArrayI(1,&i), "Sector 6-1-2");
2106 half[1] = cam->ProjectionS(s2, TArrayI(1,&i), "Sector 3-4-5");
2107
2108 for (int j=0; j<2; j++)
2109 {
2110 half[j]->SetLineColor(kRed+i+2*j+1);
2111 half[j]->SetDirectory(NULL);
2112 half[j]->SetBit(kCanDelete);
2113 half[j]->Draw("same");
2114 leg2->AddEntry(half[j], half[j]->GetName(), "l");
2115 }
2116 leg2->Draw();
2117 }
2118}
Note: See TracBrowser for help on using the repository browser.