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

Last change on this file since 4626 was 4626, checked in by gaug, 21 years ago
*** empty log message ***
File size: 54.1 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 1/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Markus Gaug, 02/2004 <mailto:markus@ifae.es>
20!
21! Copyright: MAGIC Software Development, 2000-2004
22!
23!
24\* ======================================================================== */
25/////////////////////////////////////////////////////////////////////////////
26//
27// MJCalibration
28//
29// Do one calibration loop over serious of runs with the same pulser
30// colour and the same intensity. The following containers (rectangular) and
31// tasks (ellipses) are called to produce an MCalibrationChargeCam and to
32// update the MCalibrationQECam: (MCalibrate is not called from this class)
33//
34//Begin_Html
35/*
36<img src="images/CalibClasses.gif">
37*/
38//End_Html
39//
40// Different signal extractors can be set with the command SetExtractor()
41// Only extractors deriving from MExtractor can be set, default is MExtractSlidingWindow
42//
43// Different arrival time extractors can be set with the command SetTimeExtractor()
44// Only extractors deriving from MExtractTime can be set, default is MExtractTimeSpline
45//
46// At the end of the eventloop, plots and results are displayed, depending on
47// the flags set (see DisplayResult())
48//
49// If the flag SetFullDisplay() is set, all MHCameras will be displayed.
50// if the flag SetDataCheckDisplay() is set, only the most important ones are displayed
51// Otherwise, (default: SetNormalDisplay()), a good selection of plots is given
52//
53// If the flag SetDataCheck() is set, the calibration is used as in the data check at
54// La Palma, which mean especially running on raw data files.
55//
56// The absolute light calibration devices Blind Pixel and PIN Diode can be switched on
57// and off with the commands:
58//
59// - SetUseBlindPixel(Bool_t )
60// - SetUsePINDiode(Bool_t )
61//
62// See also: MHCalibrationChargePix, MHCalibrationChargeCam, MHGausEvents
63// MHCalibrationChargeBlindPix, MHCalibrationChargePINDiode
64// MCalibrationChargePix, MCalibrationChargeCam, MCalibrationChargeCalc
65// MCalibrationChargeBlindPix, MCalibrationChargePINDiode,
66// MCalibrationQECam, MBadPixelsPix, MBadPixelsCam
67//
68// If the flag RelTimeCalibration() is set, a calibration of the relative arrival
69// times is also performed. The following containers (rectangular) and
70// tasks (ellipses) are called to produce an MCalibrationRelTimeCam used by
71// MCalibrateTime to correct timing offset between pixels: (MCalibrateTime is not
72// called from this class)
73//
74//Begin_Html
75/*
76<img src="images/RelTimeClasses.gif">
77*/
78//End_Html
79//
80// Different arrival time extractors can be set directly with the command SetTimeExtractor(MExtractor *)
81//
82// See also: MHCalibrationRelTimePix, MHCalibrationRelTimeCam, MHGausEvents
83// MCalibrationRelTimePix, MCalibrationRelTimeCam
84// MBadPixelsPix, MBadPixelsCam
85//
86/////////////////////////////////////////////////////////////////////////////
87#include "MJCalibration.h"
88
89#include <TEnv.h>
90#include <TFile.h>
91#include <TStyle.h>
92#include <TCanvas.h>
93#include <TSystem.h>
94#include <TLine.h>
95#include <TLatex.h>
96#include <TLegend.h>
97
98#include "MLog.h"
99#include "MLogManip.h"
100
101#include "MRunIter.h"
102#include "MSequence.h"
103#include "MParList.h"
104#include "MTaskList.h"
105#include "MEvtLoop.h"
106
107#include "MHCamera.h"
108#include "MGeomCam.h"
109
110#include "MPedestalCam.h"
111#include "MCalibrationCam.h"
112#include "MCalibrationQECam.h"
113#include "MCalibrationQEPix.h"
114#include "MCalibrationChargeCam.h"
115#include "MCalibrationChargePix.h"
116#include "MCalibrationChargePINDiode.h"
117#include "MCalibrationChargeBlindPix.h"
118#include "MCalibrationChargeBlindCam.h"
119#include "MCalibrationChargeBlindPix.h"
120#include "MCalibrationChargeCalc.h"
121
122#include "MHGausEvents.h"
123#include "MHCalibrationCam.h"
124#include "MHCalibrationChargeCam.h"
125#include "MHCalibrationChargeBlindCam.h"
126#include "MHCalibrationChargePINDiode.h"
127#include "MHCalibrationRelTimeCam.h"
128#include "MCalibrationRelTimeCam.h"
129#include "MCalibrationRelTimeCalc.h"
130
131#include "MReadMarsFile.h"
132#include "MRawFileRead.h"
133#include "MGeomApply.h"
134#include "MTaskEnv.h"
135#include "MBadPixelsMerge.h"
136#include "MBadPixelsCam.h"
137#include "MExtractTime.h"
138#include "MExtractor.h"
139#include "MExtractPINDiode.h"
140#include "MExtractBlindPixel.h"
141#include "MExtractSlidingWindow.h"
142#include "MExtractTimeFastSpline.h"
143#include "MFCosmics.h"
144#include "MContinue.h"
145#include "MFillH.h"
146
147#include "MArrivalTimeCam.h"
148
149#include "MStatusDisplay.h"
150
151ClassImp(MJCalibration);
152
153using namespace std;
154
155const Int_t MJCalibration::gkIFAEBoxInaugurationRun = 20113;
156const Int_t MJCalibration::gkSecondBlindPixelInstallation = 31693;
157const Int_t MJCalibration::gkThirdBlindPixelInstallation = 99999;
158
159const Double_t MJCalibration::fgConvFADC2PheMin = 0.;
160const Double_t MJCalibration::fgConvFADC2PheMax = 1.5;
161const Double_t MJCalibration::fgConvFADC2PhotMin = 0.;
162const Double_t MJCalibration::fgConvFADC2PhotMax = 10.;
163const Double_t MJCalibration::fgQEMin = 0.;
164const Double_t MJCalibration::fgQEMax = 0.3;
165
166const Float_t MJCalibration::fgRefConvFADC2PheInner = 0.14;
167const Float_t MJCalibration::fgRefConvFADC2PheOuter = 0.45;
168const Float_t MJCalibration::fgRefConvFADC2PhotInner = 0.8;
169const Float_t MJCalibration::fgRefConvFADC2PhotOuter = 3.8;
170const Float_t MJCalibration::fgRefQEInner = 0.18;
171const Float_t MJCalibration::fgRefQEOuter = 0.12;
172// --------------------------------------------------------------------------
173//
174// Default constructor.
175//
176// - Sets fRuns to 0, fExtractor to NULL, fTimeExtractor to NULL, fColor to kNONE,
177// fDisplay to kNormalDisplay, fRelTime to kFALSE, fDataCheck to kFALSE,
178// - SetUseBlindPixel()
179// - SetUsePINDiode()
180//
181MJCalibration::MJCalibration(const char *name, const char *title)
182 : fEnv(0), fRuns(0), fSequence(0), fExtractor(NULL), fTimeExtractor(NULL),
183 fColor(MCalibrationCam::kNONE), fDisplayType(kNormalDisplay),
184 fRelTimes(kFALSE), fDataCheck(kFALSE), fDebug(kFALSE)
185{
186
187 fName = name ? name : "MJCalibration";
188 fTitle = title ? title : "Tool to create the calibration constants for one calibration run";
189
190 SetUseBlindPixel();
191 SetUsePINDiode();
192
193}
194
195MJCalibration::~MJCalibration()
196{
197 if (fEnv)
198 delete fEnv;
199}
200
201// --------------------------------------------------------------------------
202//
203// Display the results in MStatusDisplay:
204//
205// - Add "Calibration" to the MStatusDisplay title
206// - Retrieve the MGeomCam from MParList
207// - Initialize the following MHCamera's:
208// 1) MCalibrationPix::GetMean()
209// 2) MCalibrationPix::Sigma()
210// 3) MCalibrationChargePix::GetRSigma()
211// 4) MCalibrationChargePix::GetRSigmaPerCharge()
212// 5) MCalibrationChargePix::GetPheFFactorMethod()
213// 6) MCalibrationChargePix::GetMeanConvFADC2Phe()
214// 7) MCalibrationChargePix::GetMeanFFactorFADC2Phot()
215// 8) MCalibrationQEPix::GetQECascadesFFactor()
216// 9) MCalibrationQEPix::GetQECascadesBlindPixel()
217// 10) MCalibrationQEPix::GetQECascadesPINDiode()
218// 11) MCalibrationQEPix::GetQECascadesCombined()
219// 12) MCalibrationQEPix::IsAverageQEFFactorAvailable()
220// 13) MCalibrationQEPix::IsAverageQEBlindPixelAvailable()
221// 14) MCalibrationQEPix::IsAverageQEPINDiodeAvailable()
222// 15) MCalibrationQEPix::IsAverageQECombinedAvailable()
223// 16) MCalibrationChargePix::IsHiGainSaturation()
224// 17) MCalibrationPix::GetHiLoMeansDivided()
225// 18) MCalibrationPix::GetHiLoSigmasDivided()
226// 19) MCalibrationChargePix::GetHiGainPickup()
227// 20) MCalibrationChargePix::GetLoGainPickup()
228// 21) MCalibrationChargePix::GetHiGainBlackout()
229// 22) MCalibrationChargePix::GetLoGainBlackout()
230// 23) MCalibrationPix::IsExcluded()
231// 24) MBadPixelsPix::IsUnsuitable(MBadPixelsPix::kUnsuitableRun)
232// 25) MBadPixelsPix::IsUnsuitable(MBadPixelsPix::kUnreliableRun)
233// 26) MBadPixelsPix::IsUncalibrated(MBadPixelsPix::kHiGainOscillating)
234// 27) MBadPixelsPix::IsUncalibrated(MBadPixelsPix::kLoGainOscillating)
235// 28) MCalibrationChargePix::GetAbsTimeMean()
236// 29) MCalibrationChargePix::GetAbsTimeRms()
237//
238// If the flag SetFullDisplay() is set, all MHCameras will be displayed.
239// if the flag SetDataCheckDisplay() is set, only the most important ones are displayed
240// and otherwise, (default: SetNormalDisplay()), a good selection of plots is given
241//
242void MJCalibration::DisplayResult(MParList &plist)
243{
244
245 if (!fDisplay)
246 return;
247
248 //
249 // Update display
250 //
251 TString title = fDisplay->GetTitle();
252 title += "-- Calibration ";
253 title += fSequence ? Form("calib%06d", fSequence->GetSequence()) : fRuns->GetRunsAsString();
254 title += " --";
255 fDisplay->SetTitle(title);
256
257 //
258 // Get container from list
259 //
260 MGeomCam &geomcam = *(MGeomCam*)plist.FindObject("MGeomCam");
261
262 // Create histograms to display
263 MHCamera disp1 (geomcam, "Charge", "Fitted Mean Charges");
264 MHCamera disp2 (geomcam, "SigmaCharge", "Sigma of Fitted Charges");
265 MHCamera disp3 (geomcam, "RSigma", "Reduced Sigmas");
266 MHCamera disp4 (geomcam, "RSigmaPerCharge", "Reduced Sigma per Charge");
267 MHCamera disp5 (geomcam, "NumPhes", "Number of Phes");
268 MHCamera disp6 (geomcam, "ConvFADC2Phes", "Conversion Factor to Phes");
269 MHCamera disp7 (geomcam, "TotalFFactor", "Total F-Factor (F-Factor Method)");
270 MHCamera disp8 (geomcam, "CascadesQEFFactor", "Cascades QE (F-Factor Method)");
271 MHCamera disp9 (geomcam, "CascadesQEBlindPix","Cascades QE (Blind Pixel Method)");
272 MHCamera disp10(geomcam, "CascadesQEPINDiode","Cascades QE (PIN Diode Method)");
273 MHCamera disp11(geomcam, "CascadesQECombined","Cascades QE (Combined Method)");
274 MHCamera disp12(geomcam, "FFactorValid", "Pixels with valid F-Factor calibration");
275 MHCamera disp13(geomcam, "BlindPixelValid", "Pixels with valid BlindPixel calibration");
276 MHCamera disp14(geomcam, "PINdiodeValid", "Pixels with valid PINDiode calibration");
277 MHCamera disp15(geomcam, "CombinedValid", "Pixels with valid Combined calibration");
278 MHCamera disp16(geomcam, "Saturation", "Pixels with saturated Hi Gain");
279 MHCamera disp17(geomcam, "ConversionMeans", "Conversion HiGain.vs.LoGain Means");
280 MHCamera disp18(geomcam, "ConversionSigmas", "Conversion HiGain.vs.LoGain Sigmas");
281 MHCamera disp19(geomcam, "HiGainPickup", "Number Pickup events Hi Gain");
282 MHCamera disp20(geomcam, "LoGainPickup", "Number Pickup events Lo Gain");
283 MHCamera disp21(geomcam, "HiGainBlackout", "Number Blackout events Hi Gain");
284 MHCamera disp22(geomcam, "LoGainBlackout", "Number Blackout events Lo Gain");
285 MHCamera disp23(geomcam, "Excluded", "Pixels previously excluded");
286 MHCamera disp24(geomcam, "UnSuitable", "Pixels not suited for further analysis");
287 MHCamera disp25(geomcam, "UnReliable", "Pixels not reliable for further analysis");
288 MHCamera disp26(geomcam, "HiGainOscillating", "Oscillating Pixels High Gain");
289 MHCamera disp27(geomcam, "LoGainOscillating", "Oscillating Pixels Low Gain");
290 MHCamera disp28(geomcam, "AbsTimeMean", "Abs. Arrival Times");
291 MHCamera disp29(geomcam, "AbsTimeRms", "RMS of Arrival Times");
292 MHCamera disp30(geomcam, "MeanTime", "Mean Rel. Arrival Times");
293 MHCamera disp31(geomcam, "SigmaTime", "Sigma Rel. Arrival Times");
294 MHCamera disp32(geomcam, "TimeProb", "Probability of Time Fit");
295 MHCamera disp33(geomcam, "TimeNotFitValid", "Pixels with not valid fit results");
296 MHCamera disp34(geomcam, "TimeOscillating", "Oscillating Pixels");
297 MHCamera disp35(geomcam, "TotalConv", "Conversion Factor to photons");
298
299 // Fitted charge means and sigmas
300 disp1.SetCamContent(fCalibrationCam, 0);
301 disp1.SetCamError( fCalibrationCam, 1);
302 disp2.SetCamContent(fCalibrationCam, 2);
303 disp2.SetCamError( fCalibrationCam, 3);
304
305 // Reduced Sigmas and reduced sigmas per charge
306 disp3.SetCamContent(fCalibrationCam, 5);
307 disp3.SetCamError( fCalibrationCam, 6);
308 disp4.SetCamContent(fCalibrationCam, 7);
309 disp4.SetCamError( fCalibrationCam, 8);
310
311 // F-Factor Method
312 disp5.SetCamContent(fCalibrationCam, 9);
313 disp5.SetCamError( fCalibrationCam, 10);
314 disp6.SetCamContent(fCalibrationCam, 11);
315 disp6.SetCamError( fCalibrationCam, 12);
316 disp7.SetCamContent(fCalibrationCam, 13);
317 disp7.SetCamError( fCalibrationCam, 14);
318
319 // Quantum Efficiencies
320 disp8.SetCamContent (fQECam, 0 );
321 disp8.SetCamError (fQECam, 1 );
322 disp9.SetCamContent (fQECam, 2 );
323 disp9.SetCamError (fQECam, 3 );
324 disp10.SetCamContent(fQECam, 4 );
325 disp10.SetCamError (fQECam, 5 );
326 disp11.SetCamContent(fQECam, 6 );
327 disp11.SetCamError (fQECam, 7 );
328
329 // Valid flags
330 disp12.SetCamContent(fQECam, 8 );
331 disp13.SetCamContent(fQECam, 9 );
332 disp14.SetCamContent(fQECam, 10);
333 disp15.SetCamContent(fQECam, 11);
334
335 // Conversion Hi-Lo
336 disp16.SetCamContent(fCalibrationCam, 25);
337 disp17.SetCamContent(fCalibrationCam, 16);
338 disp17.SetCamError (fCalibrationCam, 17);
339 disp18.SetCamContent(fCalibrationCam, 18);
340 disp18.SetCamError (fCalibrationCam, 19);
341
342 // Pickup and Blackout
343 disp19.SetCamContent(fCalibrationCam, 21);
344 disp20.SetCamContent(fCalibrationCam, 22);
345 disp21.SetCamContent(fCalibrationCam, 23);
346 disp22.SetCamContent(fCalibrationCam, 24);
347
348 // Pixels with defects
349 disp23.SetCamContent(fCalibrationCam, 20);
350 disp24.SetCamContent(fBadPixels, 1);
351 disp25.SetCamContent(fBadPixels, 3);
352
353 // Oscillations
354 disp26.SetCamContent(fBadPixels, 10);
355 disp27.SetCamContent(fBadPixels, 11);
356
357 // Arrival Times
358 disp28.SetCamContent(fCalibrationCam, 26);
359 disp28.SetCamError( fCalibrationCam, 27);
360 disp29.SetCamContent(fCalibrationCam, 27);
361
362 disp1.SetYTitle("Q [FADC counts]");
363 disp2.SetYTitle("\\sigma_{Q} [FADC counts]");
364
365 disp3.SetYTitle("\\sqrt{\\sigma^{2}_{Q} - RMS^{2}_{Ped}} [FADC Counts]");
366 disp4.SetYTitle("Red.Sigma/<Q> [1]");
367
368 disp5.SetYTitle("Phes [1]");
369 disp6.SetYTitle("Conv.Factor [PhE/FADC counts]");
370 disp7.SetYTitle("Total F-Factor [1]");
371
372 disp8.SetYTitle("QE [1]");
373 disp9.SetYTitle("QE [1]");
374 disp10.SetYTitle("QE [1]");
375 disp11.SetYTitle("QE [1]");
376
377 disp12.SetYTitle("[1]");
378 disp13.SetYTitle("[1]");
379 disp14.SetYTitle("[1]");
380 disp15.SetYTitle("[1]");
381 disp16.SetYTitle("[1]");
382
383 disp17.SetYTitle("<Q>(High)/<Q>(Low) [1]");
384 disp18.SetYTitle("\\sigma_{Q}(High)/\\sigma_{Q}(Low) [1]");
385
386 disp19.SetYTitle("[1]");
387 disp20.SetYTitle("[1]");
388 disp21.SetYTitle("[1]");
389 disp22.SetYTitle("[1]");
390 disp23.SetYTitle("[1]");
391 disp24.SetYTitle("[1]");
392 disp25.SetYTitle("[1]");
393 disp26.SetYTitle("[1]");
394 disp27.SetYTitle("[1]");
395
396 disp28.SetYTitle("Mean Abs. Time [FADC slice]");
397 disp29.SetYTitle("RMS Abs. Time [FADC slices]");
398
399 disp35.SetYTitle("Conv.Factor [Ph/FADC counts]");
400
401 for (UInt_t i=0;i<geomcam.GetNumPixels();i++)
402 {
403
404 MCalibrationChargePix &pix = (MCalibrationChargePix&)fCalibrationCam[i];
405 MCalibrationQEPix &qe = (MCalibrationQEPix&) fQECam [i];
406
407 if (!pix.IsFFactorMethodValid())
408 continue;
409
410 const Float_t convphe = pix.GetMeanConvFADC2Phe();
411 const Float_t quaeff = qe.GetQECascadesFFactor(0.);
412
413 disp35.Fill(i,convphe/quaeff);
414 disp35.SetUsed(i);
415 }
416
417
418 if (fRelTimes)
419 {
420 disp30.SetCamContent(fRelTimeCam,0);
421 disp30.SetCamError( fRelTimeCam,1);
422 disp31.SetCamContent(fRelTimeCam,2);
423 disp31.SetCamError( fRelTimeCam,3);
424 disp32.SetCamContent(fRelTimeCam,4);
425 disp33.SetCamContent(fBadPixels,20);
426 disp34.SetCamContent(fBadPixels,21);
427
428 disp30.SetYTitle("Time Offset [FADC units]");
429 disp31.SetYTitle("Timing resolution [FADC units]");
430 disp32.SetYTitle("P_{Time} [1]");
431 disp33.SetYTitle("[1]");
432 disp34.SetYTitle("[1]");
433 }
434
435
436
437 if (fDisplayType == kDataCheckDisplay)
438 {
439
440 TCanvas &c1 = fDisplay->AddTab("Fit.Charge");
441 c1.Divide(3, 3);
442
443 //
444 // MEAN CHARGES
445 //
446
447 c1.cd(1);
448 gPad->SetBorderMode(0);
449 gPad->SetTicks();
450 MHCamera *obj1=(MHCamera*)disp1.DrawCopy("hist");
451 //
452 // for the datacheck, fix the ranges!!
453 //
454 // obj1->SetMinimum(fgChargeMin);
455 // obj1->SetMaximum(fgChargeMax);
456 //
457 // Set the datacheck sizes:
458 //
459 FixDataCheckHist((TH1D*)obj1);
460 //
461 // set reference lines
462 //
463 // DisplayReferenceLines(obj1,0);
464
465 c1.cd(4);
466 gPad->SetBorderMode(0);
467 obj1->SetPrettyPalette();
468 obj1->Draw();
469
470 c1.cd(7);
471 gPad->SetBorderMode(0);
472 gPad->SetTicks();
473 TH1D *obj2 = (TH1D*)obj1->Projection(obj1->GetName());
474 obj2->Draw();
475 obj2->SetBit(kCanDelete);
476 obj2->Fit("gaus","Q");
477 TF1 *fun2 = obj2->GetFunction("gaus");
478 fun2->SetLineColor(kYellow);
479 //
480 // Set the datacheck sizes:
481 //
482 FixDataCheckHist(obj2);
483 obj2->SetStats(1);
484
485 //
486 // Display the outliers as dead and noisy pixels
487 //
488 DisplayOutliers(obj2,"dead","noisy");
489 TLatex flattex;
490 flattex.SetTextSize(0.06);
491 const Double_t minl = obj2->GetBinCenter(obj2->GetXaxis()->GetFirst());
492 const Double_t maxl = obj2->GetBinCenter(obj2->GetXaxis()->GetLast());
493 flattex.DrawLatex(minl+0.1*(maxl-minl),obj2->GetBinContent(obj2->GetMaximumBin())/1.3,
494 Form("Flatfielding precision: %4.2f%%",
495 fun2->GetParameter(2)/fun2->GetParameter(1)*100.));
496
497 //
498 // REDUCED SIGMAS
499 //
500
501 c1.cd(2);
502 gPad->SetBorderMode(0);
503 gPad->SetTicks();
504 MHCamera *obj3=(MHCamera*)disp4.DrawCopy("hist");
505 //
506 // for the datacheck, fix the ranges!!
507 //
508 // obj3->SetMinimum(fgChargeMin);
509 // obj3->SetMaximum(fgChargeMax);
510 //
511 // Set the datacheck sizes:
512 //
513 FixDataCheckHist((TH1D*)obj3);
514 //
515 // set reference lines
516 //
517 // DisplayReferenceLines(obj3,0);
518
519 c1.cd(5);
520 gPad->SetBorderMode(0);
521 obj3->SetPrettyPalette();
522 obj3->Draw();
523
524 c1.cd(8);
525 gPad->SetBorderMode(0);
526 if (geomcam.InheritsFrom("MGeomCamMagic"))
527 DisplayDoubleProject(&disp4, "dead", "noisy");
528
529 //
530 // PHOTO ELECTRONS
531 //
532
533 c1.cd(3);
534 gPad->SetBorderMode(0);
535 gPad->SetTicks();
536 MHCamera *obj4=(MHCamera*)disp5.DrawCopy("hist");
537 //
538 // for the datacheck, fix the ranges!!
539 //
540 // obj3->SetMinimum(fgChargeMin);
541 // obj3->SetMaximum(fgChargeMax);
542 //
543 // Set the datacheck sizes:
544 //
545 FixDataCheckHist((TH1D*)obj4);
546 //
547 // set reference lines
548 //
549 // DisplayReferenceLines(obj3,0);
550
551 c1.cd(6);
552 gPad->SetBorderMode(0);
553 obj4->SetPrettyPalette();
554 obj4->Draw();
555
556 c1.cd(9);
557 gPad->SetBorderMode(0);
558 if (geomcam.InheritsFrom("MGeomCamMagic"))
559 DisplayDoubleProject(&disp5, "dead", "noisy");
560
561 //
562 // CONVERSION FACTORS
563 //
564
565 TCanvas &c2 = fDisplay->AddTab("Conversion");
566 c2.Divide(3,3);
567
568 c2.cd(1);
569 gPad->SetBorderMode(0);
570 gPad->SetTicks();
571 MHCamera *obj5=(MHCamera*)disp6.DrawCopy("hist");
572 //
573 // for the datacheck, fix the ranges!!
574 //
575 obj5->SetMinimum(fgConvFADC2PheMin);
576 obj5->SetMaximum(fgConvFADC2PheMax);
577 //
578 // Set the datacheck sizes:
579 //
580 FixDataCheckHist((TH1D*)obj5);
581 //
582 // set reference lines
583 //
584 DisplayReferenceLines(obj5,2);
585
586 c2.cd(4);
587 gPad->SetBorderMode(0);
588 obj5->SetPrettyPalette();
589 obj5->Draw();
590
591 c2.cd(7);
592 gPad->SetBorderMode(0);
593 if (geomcam.InheritsFrom("MGeomCamMagic"))
594 DisplayDoubleProject(&disp6, "noisy", "dead");
595
596 //
597 // QUANTUM EFFICIENCY
598 //
599
600 c2.cd(2);
601 gPad->SetBorderMode(0);
602 gPad->SetTicks();
603 MHCamera *obj6=(MHCamera*)disp8.DrawCopy("hist");
604 //
605 // for the datacheck, fix the ranges!!
606 //
607 obj6->SetMinimum(fgQEMin);
608 obj6->SetMaximum(fgQEMax);
609 //
610 // Set the datacheck sizes:
611 //
612 FixDataCheckHist((TH1D*)obj6);
613 //
614 // set reference lines
615 //
616 DisplayReferenceLines(obj6,0);
617
618 c2.cd(5);
619 gPad->SetBorderMode(0);
620 obj6->SetPrettyPalette();
621 obj6->Draw();
622
623 c2.cd(8);
624 gPad->SetBorderMode(0);
625 if (geomcam.InheritsFrom("MGeomCamMagic"))
626 DisplayDoubleProject(&disp8, "noisy", "dead");
627
628 //
629 // CONVERSION FADC TO PHOTONS
630 //
631
632 c2.cd(3);
633 gPad->SetBorderMode(0);
634 gPad->SetTicks();
635 MHCamera *obj7=(MHCamera*)disp35.DrawCopy("hist");
636 //
637 // for the datacheck, fix the ranges!!
638 //
639 obj7->SetMinimum(fgConvFADC2PhotMin);
640 obj7->SetMaximum(fgConvFADC2PhotMax);
641 //
642 // Set the datacheck sizes:
643 //
644 FixDataCheckHist((TH1D*)obj7);
645 //
646 // set reference lines
647 //
648 DisplayReferenceLines(obj7,1);
649
650 c2.cd(6);
651 gPad->SetBorderMode(0);
652 obj7->SetPrettyPalette();
653 obj7->Draw();
654 c2.cd(9);
655 gPad->SetBorderMode(0);
656 if (geomcam.InheritsFrom("MGeomCamMagic"))
657 DisplayDoubleProject(&disp35, "noisy", "dead");
658
659 //
660 // DEFECTS
661 //
662 TCanvas &c4 = fDisplay->AddTab("Defect");
663 c4.Divide(2,2);
664
665 disp24.CamDraw(c4, 1, 2, 0);
666 disp25.CamDraw(c4, 2, 2, 0);
667
668 if (fRelTimes)
669 {
670 // Rel. Times
671 TCanvas &c5 = fDisplay->AddTab("Rel. Times");
672 c5.Divide(2,4);
673
674 disp30.CamDraw(c5, 1, 2, 2);
675 disp31.CamDraw(c5, 2, 2, 2);
676 }
677
678 return;
679 }
680
681 if (fDisplayType == kNormalDisplay)
682 {
683
684 // Charges
685 TCanvas &c11 = fDisplay->AddTab("Fit.Charge");
686 c11.Divide(2, 4);
687
688 disp1.CamDraw(c11, 1, 2, 5, 1);
689 disp2.CamDraw(c11, 2, 2, 5, 1);
690
691 // Reduced Sigmas
692 TCanvas &c12 = fDisplay->AddTab("Red.Sigma");
693 c12.Divide(2,4);
694
695 disp3.CamDraw(c12, 1, 2, 5, 1);
696 disp4.CamDraw(c12, 2, 2, 5, 1);
697
698 // F-Factor
699 TCanvas &c13 = fDisplay->AddTab("Phe's");
700 c13.Divide(3,4);
701
702 disp5.CamDraw(c13, 1, 3, 5, 1);
703 disp6.CamDraw(c13, 2, 3, 5, 1);
704 disp7.CamDraw(c13, 3, 3, 5, 1);
705
706 // QE's
707 TCanvas &c14 = fDisplay->AddTab("QE's");
708 c14.Divide(4,4);
709
710 disp8.CamDraw(c14, 1, 4, 5, 1);
711 disp9.CamDraw(c14, 2, 4, 5, 1);
712 disp10.CamDraw(c14, 3, 4, 5, 1);
713 disp11.CamDraw(c14, 4, 4, 5, 1);
714
715 // Defects
716 TCanvas &c15 = fDisplay->AddTab("Defect");
717 // c15.Divide(5,2);
718 c15.Divide(4,2);
719
720 /*
721 disp23.CamDraw(c15, 1, 5, 0);
722 disp24.CamDraw(c15, 2, 5, 0);
723 disp25.CamDraw(c15, 3, 5, 0);
724 disp26.CamDraw(c15, 4, 5, 0);
725 disp27.CamDraw(c15, 5, 5, 0);
726 */
727 disp24.CamDraw(c15, 1, 4, 0);
728 disp25.CamDraw(c15, 2, 4, 0);
729 disp26.CamDraw(c15, 3, 4, 0);
730 disp27.CamDraw(c15, 4, 4, 0);
731
732 // Abs. Times
733 TCanvas &c16 = fDisplay->AddTab("Abs. Times");
734 c16.Divide(2,3);
735
736 disp28.CamDraw(c16, 1, 2, 5);
737 disp29.CamDraw(c16, 2, 2, 5);
738
739 if (fRelTimes)
740 {
741 // Rel. Times
742 TCanvas &c17 = fDisplay->AddTab("Rel. Times");
743 c17.Divide(2,4);
744
745 disp30.CamDraw(c17, 1, 2, 5, 1);
746 disp31.CamDraw(c17, 2, 2, 5, 1);
747 }
748
749 return;
750 }
751
752 if (fDisplayType == kFullDisplay)
753 {
754 MHCalibrationCam *cam = (MHCalibrationCam*)plist.FindObject("MHCalibrationChargeCam");
755
756 for (Int_t sector=1;sector<cam->GetAverageSectors();sector++)
757 {
758 cam->GetAverageHiGainSector(sector).DrawClone("all");
759 cam->GetAverageLoGainSector(sector).DrawClone("all");
760 }
761
762 // Charges
763 TCanvas &c21 = fDisplay->AddTab("Fit.Charge");
764 c21.Divide(2, 4);
765
766 disp1.CamDraw(c21, 1, 2, 2, 1);
767 disp2.CamDraw(c21, 2, 2, 2, 1);
768
769 // Reduced Sigmas
770 TCanvas &c23 = fDisplay->AddTab("Red.Sigma");
771 c23.Divide(2,4);
772
773 disp3.CamDraw(c23, 1, 2, 2, 1);
774 disp4.CamDraw(c23, 2, 2, 2, 1);
775
776 // F-Factor
777 TCanvas &c24 = fDisplay->AddTab("Phe's");
778 c24.Divide(3,5);
779
780 disp5.CamDraw(c24, 1, 3, 2, 1, 1);
781 disp6.CamDraw(c24, 2, 3, 2, 1, 1);
782 disp7.CamDraw(c24, 3, 3, 2, 1, 1);
783
784 // QE's
785 TCanvas &c25 = fDisplay->AddTab("QE's");
786 c25.Divide(4,5);
787
788 disp8.CamDraw(c25, 1, 4, 2, 1, 1);
789 disp9.CamDraw(c25, 2, 4, 2, 1, 1);
790 disp10.CamDraw(c25, 3, 4, 2, 1, 1);
791 disp11.CamDraw(c25, 4, 4, 2, 1, 1);
792
793 // Validity
794 TCanvas &c26 = fDisplay->AddTab("Valid");
795 c26.Divide(4,2);
796
797 disp12.CamDraw(c26, 1, 4, 0);
798 disp13.CamDraw(c26, 2, 4, 0);
799 disp14.CamDraw(c26, 3, 4, 0);
800 disp15.CamDraw(c26, 4, 4, 0);
801
802 // Other info
803 TCanvas &c27 = fDisplay->AddTab("HiLoGain");
804 c27.Divide(3,3);
805
806 disp16.CamDraw(c27, 1, 3, 0);
807 disp17.CamDraw(c27, 2, 3, 1);
808 disp18.CamDraw(c27, 3, 3, 1);
809
810 // Pickup
811 TCanvas &c28 = fDisplay->AddTab("Pickup");
812 c28.Divide(4,2);
813
814 disp19.CamDraw(c28, 1, 4, 0);
815 disp20.CamDraw(c28, 2, 4, 0);
816 disp21.CamDraw(c28, 3, 4, 0);
817 disp22.CamDraw(c28, 4, 4, 0);
818
819 // Defects
820 TCanvas &c29 = fDisplay->AddTab("Defect");
821 // c29.Divide(5,2);
822 c29.Divide(4,2);
823
824 disp24.CamDraw(c29, 1, 4, 0);
825 disp25.CamDraw(c29, 2, 4, 0);
826 disp26.CamDraw(c29, 3, 4, 0);
827 disp27.CamDraw(c29, 4, 4, 0);
828
829 // Abs. Times
830 TCanvas &c30 = fDisplay->AddTab("Abs. Times");
831 c30.Divide(2,3);
832
833 disp28.CamDraw(c30, 1, 2, 2);
834 disp29.CamDraw(c30, 2, 2, 1);
835
836 if (fRelTimes)
837 {
838 // Rel. Times
839 TCanvas &c31 = fDisplay->AddTab("Rel. Times");
840 c31.Divide(3,5);
841
842 disp30.CamDraw(c31, 1, 3, 2, 1, 1);
843 disp31.CamDraw(c31, 2, 3, 2, 1, 1);
844 disp32.CamDraw(c31, 3, 3, 4, 1, 1);
845
846 // Time Defects
847 TCanvas &c32 = fDisplay->AddTab("Time Def.");
848 c32.Divide(2,2);
849
850 disp33.CamDraw(c32, 1, 2, 0);
851 disp34.CamDraw(c32, 2, 2, 0);
852
853 MHCalibrationCam *cam = (MHCalibrationCam*)plist.FindObject("MHCalibrationRelTimeCam");
854
855 for (Int_t sector=1;sector<cam->GetAverageSectors();sector++)
856 {
857 cam->GetAverageHiGainSector(sector).DrawClone("fourierevents");
858 cam->GetAverageLoGainSector(sector).DrawClone("fourierevents");
859 }
860
861 }
862
863 return;
864 }
865}
866
867
868void MJCalibration::DisplayReferenceLines(MHCamera *cam, const Int_t what) const
869{
870
871 const MGeomCam *geom = cam->GetGeometry();
872
873 Double_t x = geom->InheritsFrom("MGeomCamMagic") ? 397 : cam->GetNbinsX() ;
874
875 TLine line;
876 line.SetLineStyle(kDashed);
877 line.SetLineWidth(3);
878 line.SetLineColor(kBlue);
879
880 TLine *l1 = NULL;
881
882 if (what == 0)
883 l1 = line.DrawLine(0, fgRefQEInner, x, fgRefQEInner);
884 else if (what == 1)
885 l1 = line.DrawLine(0, fgRefConvFADC2PhotInner, x, fgRefConvFADC2PhotInner);
886 else if (what == 2)
887 l1 = line.DrawLine(0, fgRefConvFADC2PheInner, x, fgRefConvFADC2PheInner );
888
889 if (geom->InheritsFrom("MGeomCamMagic"))
890 {
891 const Double_t x2 = cam->GetNbinsX();
892
893 switch (what)
894 {
895 case 0:
896 line.DrawLine(x2, fgRefQEOuter, 398, fgRefQEOuter);
897 break;
898 case 1:
899 line.DrawLine(x2, fgRefConvFADC2PhotOuter, 398, fgRefConvFADC2PhotOuter );
900 break;
901 case 2:
902 line.DrawLine(x2, fgRefConvFADC2PheOuter, 398, fgRefConvFADC2PheOuter);
903 break;
904 }
905 }
906
907 TLegend *leg = new TLegend(what ? 0.2 : 0.6,0.75,what ? 0.5 : 0.9 ,0.85);
908 leg->SetBit(kCanDelete);
909 leg->AddEntry(l1, "Reference","l");
910 leg->Draw();
911}
912
913void MJCalibration::DisplayOutliers(TH1D *hist, const char* whatsmall, const char* whatbig) const
914{
915
916 const Float_t mean = hist->GetFunction("gaus")->GetParameter(1);
917 const Float_t lolim = mean - 4.0*hist->GetFunction("gaus")->GetParameter(2);
918 const Float_t uplim = mean + 4.0*hist->GetFunction("gaus")->GetParameter(2);
919 const Stat_t dead = hist->Integral(0,hist->FindBin(lolim)-1);
920 const Stat_t noisy = hist->Integral(hist->FindBin(uplim)+1,hist->GetNbinsX()+1);
921
922 const Double_t max = hist->GetBinContent(hist->GetMaximumBin());
923
924 const Double_t minl = hist->GetBinCenter(hist->GetXaxis()->GetFirst());
925 const Double_t maxl = hist->GetBinCenter(hist->GetXaxis()->GetLast());
926
927 TLatex deadtex;
928 deadtex.SetTextSize(0.06);
929 deadtex.DrawLatex(minl+0.1*(maxl-minl),max/1.1,
930 Form("%3i %s pixels",(Int_t)dead,whatsmall));
931
932 TLatex noisytex;
933 noisytex.SetTextSize(0.06);
934 noisytex.DrawLatex(minl+0.1*(maxl-minl),max/1.2,
935 Form("%3i %s pixels",(Int_t)noisy,whatbig));
936
937}
938
939void MJCalibration::FixDataCheckHist(TH1D *hist) const
940{
941
942 hist->SetDirectory(NULL);
943
944 //
945 // set the labels bigger
946 //
947 TAxis *xaxe = hist->GetXaxis();
948 TAxis *yaxe = hist->GetYaxis();
949
950 xaxe->CenterTitle();
951 yaxe->CenterTitle();
952 xaxe->SetTitleSize(0.06);
953 yaxe->SetTitleSize(0.06);
954 xaxe->SetTitleOffset(0.8);
955 yaxe->SetTitleOffset(0.85);
956 xaxe->SetLabelSize(0.05);
957 yaxe->SetLabelSize(0.05);
958
959}
960
961// --------------------------------------------------------------------------
962//
963// Find the colour of the pulsing LED:
964// - If the run number is smaller than gkIFAEBoxInaugurationRun, take MCalibrationCam::kCT1
965// - Otherwise find the colour out of the run name
966// - If no colour is found, return kFALSE
967//
968Bool_t MJCalibration::FindColor()
969{
970
971 if (fSequence)
972 {
973 fColor = MCalibrationCam::kCT1;
974 return kTRUE;
975 }
976
977 const UInt_t nruns = fRuns->GetNumRuns();
978
979 if (nruns == 0)
980 return kFALSE;
981
982 TArrayI arr = fRuns->GetRuns();
983
984 if (arr[nruns-1] < gkIFAEBoxInaugurationRun)
985 {
986 *fLog << "Found colour kCT1 in runs: " << fRuns->GetRunsAsString() << endl;
987 fColor = MCalibrationCam::kCT1;
988 return kTRUE;
989 }
990
991 TString filenames;
992 ((MDirIter*)fRuns)->Reset();
993
994 while (!(filenames=((MDirIter*)fRuns)->Next()).IsNull())
995 {
996
997 filenames.ToLower();
998
999 //
1000 // Here starts the list of runs where the shifters did not put
1001 // a colour, but which have been found out by other means.
1002 // FIXME: This list has is only preliminary and has to move into the
1003 // database!!
1004 //
1005 if (filenames.Contains("_30090_"))
1006 if (fColor == MCalibrationCam::kNONE)
1007 {
1008 *fLog << "Found colour: kGREEN in " << filenames << endl;
1009 fColor = MCalibrationCam::kGREEN;
1010 }
1011 else if (fColor != MCalibrationCam::kNONE)
1012 {
1013 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1014 return kFALSE;
1015 }
1016
1017 if (filenames.Contains("_27474_"))
1018 if (fColor == MCalibrationCam::kNONE)
1019 {
1020 *fLog << "Sorry, run 27474 was taken with CLOSED LIDS. It should not be used! "
1021 << "Selected runs were: " << filenames << endl;
1022 fColor = MCalibrationCam::kNONE;
1023 return kFALSE;
1024 }
1025 else if (fColor != MCalibrationCam::kNONE)
1026 {
1027 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1028 return kFALSE;
1029 }
1030
1031 if (filenames.Contains("_26924_"))
1032 if (fColor == MCalibrationCam::kNONE)
1033 {
1034 *fLog << "Found colour: kGREEN in " << filenames << endl;
1035 fColor = MCalibrationCam::kGREEN;
1036 }
1037 else if (fColor != MCalibrationCam::kGREEN)
1038 {
1039 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1040 return kFALSE;
1041 }
1042
1043
1044 if (filenames.Contains("_26568_"))
1045 if (fColor == MCalibrationCam::kNONE)
1046 {
1047 *fLog << "Found colour: kGREEN in " << filenames << endl;
1048 fColor = MCalibrationCam::kGREEN;
1049 }
1050 else if (fColor != MCalibrationCam::kGREEN)
1051 {
1052 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1053 return kFALSE;
1054 }
1055
1056 if (filenames.Contains("_26412_"))
1057 if (fColor == MCalibrationCam::kNONE)
1058 {
1059 *fLog << "Found colour: kGREEN in " << filenames << endl;
1060 fColor = MCalibrationCam::kGREEN;
1061 }
1062 else if (fColor != MCalibrationCam::kGREEN)
1063 {
1064 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1065 return kFALSE;
1066 }
1067
1068
1069 if (filenames.Contains("_26409_"))
1070 if (fColor == MCalibrationCam::kNONE)
1071 {
1072 *fLog << "Found colour: kGREEN in " << filenames << endl;
1073 fColor = MCalibrationCam::kGREEN;
1074 }
1075 else if (fColor != MCalibrationCam::kGREEN)
1076 {
1077 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1078 return kFALSE;
1079 }
1080
1081 if (filenames.Contains("_26408_"))
1082 if (fColor == MCalibrationCam::kNONE)
1083 {
1084 *fLog << "Found colour: kGREEN in " << filenames << endl;
1085 fColor = MCalibrationCam::kGREEN;
1086 }
1087 else if (fColor != MCalibrationCam::kGREEN)
1088 {
1089 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1090 return kFALSE;
1091 }
1092
1093
1094 if (filenames.Contains("_26402_"))
1095 if (fColor == MCalibrationCam::kNONE)
1096 {
1097 *fLog << "Found colour: kBLUE in " << filenames << endl;
1098 fColor = MCalibrationCam::kBLUE;
1099 }
1100 else if (fColor != MCalibrationCam::kBLUE)
1101 {
1102 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1103 return kFALSE;
1104 }
1105
1106 if (filenames.Contains("_20661_"))
1107 if (fColor == MCalibrationCam::kNONE)
1108 {
1109 *fLog << "Found colour: kGREEN in " << filenames << endl;
1110 fColor = MCalibrationCam::kGREEN;
1111 }
1112 else if (fColor != MCalibrationCam::kGREEN)
1113 {
1114 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1115 return kFALSE;
1116 }
1117
1118 if (filenames.Contains("_20660_"))
1119 if (fColor == MCalibrationCam::kNONE)
1120 {
1121 *fLog << "Found colour: kGREEN in " << filenames << endl;
1122 fColor = MCalibrationCam::kGREEN;
1123 }
1124 else if (fColor != MCalibrationCam::kGREEN)
1125 {
1126 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1127 return kFALSE;
1128 }
1129
1130 //
1131 // Here start the runs where the shifter put
1132 // the colour.
1133 //
1134 if (filenames.Contains("green"))
1135 if (fColor == MCalibrationCam::kNONE)
1136 {
1137 *fLog << "Found colour: kGREEN in " << filenames << endl;
1138 fColor = MCalibrationCam::kGREEN;
1139 }
1140 else if (fColor != MCalibrationCam::kGREEN)
1141 {
1142 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1143 return kFALSE;
1144 }
1145
1146 if (filenames.Contains("blue"))
1147 if (fColor == MCalibrationCam::kNONE)
1148 {
1149 *fLog << "Found colour: kBLUE in " << filenames << endl;
1150 fColor = MCalibrationCam::kBLUE;
1151 }
1152 else if (fColor != MCalibrationCam::kBLUE)
1153 {
1154 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1155 return kFALSE;
1156 }
1157
1158 if (filenames.Contains("uv"))
1159 if (fColor == MCalibrationCam::kNONE)
1160 {
1161 *fLog << "Found colour: kUV in " << filenames << endl;
1162 fColor = MCalibrationCam::kUV;
1163 }
1164 else if (fColor != MCalibrationCam::kUV)
1165 {
1166 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1167 return kFALSE;
1168 }
1169
1170 if (filenames.Contains("ct1"))
1171 if (fColor == MCalibrationCam::kNONE)
1172 {
1173 *fLog << "Found colour: kCT1 in " << filenames << endl;
1174 fColor = MCalibrationCam::kCT1;
1175 }
1176 else if (fColor != MCalibrationCam::kCT1)
1177 {
1178 *fLog << err << "Different colour found in " << filenames << "... abort" << endl;
1179 return kFALSE;
1180 }
1181
1182 }
1183
1184 if (fColor == MCalibrationCam::kNONE)
1185 {
1186 *fLog << "No colour found in filenames of runs: " << fRuns->GetRunsAsString()
1187 << "... abort" << endl;
1188 return kFALSE;
1189 }
1190
1191
1192 return kTRUE;
1193}
1194
1195// --------------------------------------------------------------------------
1196//
1197// Retrieve the output file written by WriteResult()
1198//
1199const char* MJCalibration::GetOutputFile() const
1200{
1201 if (fSequence)
1202 return Form("%s/calib%06d.root", (const char*)fOutputPath, fSequence->GetSequence());
1203 if (!fRuns)
1204 return "";
1205
1206 return Form("%s/%s-F1.root", (const char*)fOutputPath, (const char*)fRuns->GetRunsAsFileName());
1207}
1208
1209Bool_t MJCalibration::IsUseBlindPixel() const
1210{
1211 return TESTBIT(fDevices,kUseBlindPixel);
1212}
1213
1214Bool_t MJCalibration::IsUsePINDiode() const
1215{
1216 return TESTBIT(fDevices,kUsePINDiode);
1217}
1218
1219void MJCalibration::SetEnv(const char *env)
1220{
1221 if (fEnv)
1222 delete fEnv;
1223 fEnv = new TEnv(env);
1224}
1225
1226void MJCalibration::CheckEnv()
1227{
1228 if (!fEnv)
1229 return;
1230
1231 TString e1 = fEnv->GetValue("MJCalibration.OutputPath", "");
1232 if (!e1.IsNull())
1233 {
1234 e1.ReplaceAll("\015", "");
1235 SetOutputPath(e1);
1236 }
1237
1238 TString col = fEnv->GetValue("MJCalibration.Color", "");
1239 if (!col.IsNull())
1240 {
1241 }
1242
1243 TString dis = fEnv->GetValue("MJCalibration.Display", "");
1244 if (dis.BeginsWith("Full", TString::kIgnoreCase))
1245 SetFullDisplay();
1246 if (dis.BeginsWith("DataCheck", TString::kIgnoreCase))
1247 SetDataCheckDisplay();
1248 if (dis.BeginsWith("Normal", TString::kIgnoreCase))
1249 SetNormalDisplay();
1250
1251 SetRelTimeCalibration(fEnv->GetValue("MJCalibration.RelTimeCalibration", fRelTimes));
1252 SetDataCheck(fEnv->GetValue("MJCalibration.Datacheck", fDataCheck));
1253 SetDebug(fEnv->GetValue("MJCalibration.Debug", fDebug));
1254 SetUseBlindPixel(fEnv->GetValue("MJCalibration.UseBlindPixel", IsUseBlindPixel()));
1255 SetUsePINDiode(fEnv->GetValue("MJCalibration.UsePINDiode", IsUsePINDiode()));
1256}
1257
1258// --------------------------------------------------------------------------
1259//
1260// Call the ProcessFile(MPedestalCam)
1261//
1262Bool_t MJCalibration::Process(MPedestalCam &pedcam)
1263{
1264 if (!ReadCalibrationCam())
1265 return ProcessFile(pedcam);
1266
1267 return kTRUE;
1268}
1269
1270void MJCalibration::InitBlindPixel(MExtractBlindPixel &blindext,
1271 MHCalibrationChargeBlindCam &blindcam)
1272{
1273
1274 Int_t run = fSequence ? fSequence->GetLastRun() : fRuns->GetRuns()[fRuns->GetNumRuns()-1];
1275
1276 //
1277 // Initialize the blind pixel. Unfortunately, there is a hardware difference
1278 // in the first blind pixel until run "gkSecondBlindPixelInstallation" and the
1279 // later setup. The first needs to use a filter because of the length of
1280 // spurious NSB photon signals. The latter get better along extracting the amplitude
1281 // from a small window.
1282 //
1283 if (run < gkSecondBlindPixelInstallation)
1284 {
1285 blindext.SetModified(kFALSE);
1286 blindext.SetExtractionType(MExtractBlindPixel::kIntegral);
1287 blindext.SetExtractionType(MExtractBlindPixel::kFilter);
1288 blindext.SetRange(10,19,0,6);
1289 blindext.SetNSBFilterLimit(70);
1290 blindcam.SetFitFunc( MHCalibrationChargeBlindPix::kEPoisson5 );
1291 }
1292 else
1293 {
1294 blindext.SetModified(kTRUE);
1295 blindext.SetExtractionType(MExtractBlindPixel::kAmplitude);
1296 blindext.SetExtractionType(MExtractBlindPixel::kFilter);
1297 blindext.SetRange(5,8,0,2);
1298 blindext.SetNSBFilterLimit(38);
1299
1300 if (run < gkThirdBlindPixelInstallation)
1301 blindext.SetNumBlindPixels(2);
1302 else
1303 blindext.SetNumBlindPixels(3);
1304 }
1305}
1306
1307// --------------------------------------------------------------------------
1308//
1309// Execute the task list and the eventloop:
1310//
1311// - Check if there are fRuns, otherwise return
1312// - Check the colour of the files in fRuns (FindColor()), otherwise return
1313// - Check for consistency between run numbers and number of files
1314// - Add fRuns to MReadMarsFile
1315// - Put into MParList:
1316// 1) MPedestalCam (pedcam)
1317// 2) MCalibrationQECam (fQECam)
1318// 3) MCalibrationChargeCam (fCalibrationCam)
1319// 4) MCalibrationRelTimeCam (fRelTimeCam) (only if flag fRelTimes is chosen)
1320// 5) MBadPixelsCam (fBadPixels)
1321// 6) MCalibrationChargePINDiode
1322// 7) MCalibrationChargeBlindPix
1323// - Put into the MTaskList:
1324// 1) MReadMarsFile
1325// 2) MBadPixelsMerge
1326// 3) MGeomApply
1327// 4) MExtractor
1328// 5) MExtractPINDiode
1329// 6) MExtractBlindPixel
1330// 7) MExtractTime (only if flag fRelTimes is chosen)
1331// 8) MContinue(MFCosmics)
1332// 9) MFillH("MHCalibrationChargePINDiode", "MExtractedSignalPINDiode")
1333// 10) MFillH("MHCalibrationChargeBlindCam", "MExtractedSignalBlindPixel")
1334// 11) MFillH("MHCalibrationChargeCam", "MExtractedSignalCam")
1335// 12) MFillH("MHCalibrationChargeCam", "MExtractedSignalCam")
1336// 13) MCalibrationChargeCalc
1337// 14) MFillH("MHCalibrationRelTimeCam", "MArrivalTimeCam") (only if flag fRelTimes is chosen)
1338// 15) MCalibrationRelTimeCalc
1339// - Execute MEvtLoop
1340// - DisplayResult()
1341// - WriteResult()
1342//
1343Bool_t MJCalibration::ProcessFile(MPedestalCam &pedcam)
1344{
1345 if (!fRuns && !fSequence)
1346 {
1347 *fLog << err << "No Runs choosen... abort." << endl;
1348 return kFALSE;
1349 }
1350
1351 if (!fSequence && fRuns->GetNumRuns() != fRuns->GetNumEntries())
1352 {
1353 *fLog << err << "Number of files found doesn't match number of runs... abort."
1354 << fRuns->GetNumRuns() << " vs. " << fRuns->GetNumEntries() << endl;
1355 return kFALSE;
1356 }
1357
1358 *fLog << inf;
1359 fLog->Separator(GetDescriptor());
1360
1361 if (!FindColor())
1362 return kFALSE;
1363
1364 *fLog << "Calculate MCalibrationCam from ";
1365 if (fSequence)
1366 *fLog << "Sequence #" << fSequence->GetSequence() << endl;
1367 else
1368 *fLog << "Runs " << fRuns->GetRunsAsString() << endl;
1369 *fLog << endl;
1370
1371 CheckEnv();
1372
1373 // Setup Tasklist
1374 MParList plist;
1375 MTaskList tlist;
1376 plist.AddToList(&tlist);
1377
1378 MReadMarsFile read("Events");
1379 MRawFileRead rawread(NULL);
1380
1381 MDirIter iter;
1382 if (fSequence)
1383 fSequence->SetupCalRuns(iter);
1384
1385 if (fDataCheck)
1386 {
1387 rawread.AddFiles(fSequence ? iter : *fRuns);
1388 tlist.AddToList(&rawread);
1389 }
1390 else
1391 {
1392 read.DisableAutoScheme();
1393 static_cast<MRead&>(read).AddFiles(fSequence ? iter : *fRuns);
1394 tlist.AddToList(&read);
1395 }
1396
1397 MHCalibrationChargeCam chargecam;
1398 MHCalibrationChargeBlindCam blindcam;
1399
1400 plist.AddToList(&pedcam);
1401 plist.AddToList(&chargecam);
1402 plist.AddToList(&blindcam);
1403 plist.AddToList(&fBadPixels);
1404 plist.AddToList(&fQECam);
1405 plist.AddToList(&fCalibrationCam);
1406 plist.AddToList(&fCalibrationBlindCam);
1407 plist.AddToList(&fCalibrationPINDiode);
1408 plist.AddToList(&fRelTimeCam);
1409
1410 MGeomApply apply;
1411 MBadPixelsMerge merge(&fBadPixels);
1412 MExtractPINDiode pinext;
1413 MExtractBlindPixel blindext;
1414 InitBlindPixel(blindext, blindcam);
1415 MExtractSlidingWindow extract2;
1416 MExtractTimeFastSpline timespline;
1417 MCalibrationChargeCalc calcalc;
1418 MCalibrationRelTimeCalc timecalc;
1419
1420 if (!fSequence)
1421 {
1422 calcalc.SetOutputPath(fOutputPath);
1423 calcalc.SetOutputFile(Form("%s-ChargeCalibStat.txt",(const char*)fRuns->GetRunsAsFileName()));
1424 }
1425
1426 if (fDebug)
1427 {
1428 chargecam.SetDebug();
1429 calcalc.SetDebug();
1430 }
1431
1432 //
1433 // As long as there are no DM's, have to colour by hand
1434 //
1435 calcalc.SetPulserColor(fColor);
1436
1437 MFillH fillpin("MHCalibrationChargePINDiode", "MExtractedSignalPINDiode");
1438 MFillH fillbnd("MHCalibrationChargeBlindPix", "MExtractedSignalBlindPixel");
1439 MFillH fillcam("MHCalibrationChargeCam", "MExtractedSignalCam");
1440 MFillH filltme("MHCalibrationRelTimeCam", "MArrivalTimeCam");
1441 fillpin.SetNameTab("PINDiode");
1442 fillbnd.SetNameTab("BlindPix");
1443 fillcam.SetNameTab("Charge");
1444 filltme.SetNameTab("RelTimes");
1445
1446 TString drawoption;
1447
1448 if (fDisplayType == kDataCheckDisplay)
1449 drawoption += "datacheck";
1450 if (fDisplayType == kFullDisplay)
1451 drawoption += " all";
1452
1453 fillcam.SetDrawOption(drawoption.Data());
1454 fillbnd.SetDrawOption(drawoption.Data());
1455 fillpin.SetDrawOption(drawoption.Data());
1456 filltme.SetDrawOption(drawoption.Data());
1457
1458 //
1459 // Apply a filter against cosmics
1460 // (will have to be needed in the future
1461 // when the calibration hardware-trigger is working)
1462 //
1463 MFCosmics cosmics;
1464 MContinue cont(&cosmics);
1465
1466 tlist.AddToList(&merge);
1467 tlist.AddToList(&apply);
1468
1469 MTaskEnv taskenv("ExtractSignal");
1470 taskenv.SetDefault(fExtractor ? fExtractor : &extract2);
1471
1472 tlist.AddToList(&taskenv);
1473 tlist.AddToList(&pinext);
1474 tlist.AddToList(&blindext);
1475
1476 MTaskEnv taskenv2("ExtractTime");
1477 taskenv2.SetDefault(fTimeExtractor ? fTimeExtractor : &timespline);
1478
1479 if (fRelTimes)
1480 tlist.AddToList(&taskenv2);
1481
1482 if (fColor == MCalibrationCam::kCT1)
1483 tlist.AddToList(&cont);
1484
1485 tlist.AddToList(&fillcam);
1486
1487 if (fRelTimes)
1488 {
1489 tlist.AddToList(&filltme);
1490 tlist.AddToList(&timecalc);
1491 }
1492
1493 if (IsUseBlindPixel())
1494 tlist.AddToList(&fillbnd);
1495 if (IsUsePINDiode())
1496 tlist.AddToList(&fillpin);
1497
1498 tlist.AddToList(&calcalc);
1499
1500 // Create and setup the eventloop
1501 MEvtLoop evtloop(fName);
1502 evtloop.SetParList(&plist);
1503 evtloop.SetDisplay(fDisplay);
1504 evtloop.SetLogStream(fLog);
1505 if (fEnv)
1506 evtloop.ReadEnv(*fEnv);
1507
1508 // Execute first analysis
1509 if (!evtloop.Eventloop())
1510 {
1511 *fLog << err << GetDescriptor() << ": Failed." << endl;
1512 return kFALSE;
1513 }
1514
1515 tlist.PrintStatistics();
1516
1517 //
1518 // The next lines are necessary in order to avoid that
1519 // the last entry drawn by MFillH gets deleted again from
1520 // the display. No idea where this comes from...
1521 //
1522 if (fDisplay)
1523 {
1524 if (IsUsePINDiode())
1525 {
1526 MHCalibrationChargePINDiode *pin =
1527 (MHCalibrationChargePINDiode*)plist.FindObject("MHCalibrationChargePINDiode");
1528 pin->DrawClone(Form("nonew %s",drawoption.Data()));
1529 }
1530 else if (IsUseBlindPixel())
1531 {
1532 MHCalibrationChargeBlindCam *cam =
1533 (MHCalibrationChargeBlindCam*)plist.FindObject("MHCalibrationChargeBlindCam");
1534 cam->DrawClone(Form("nonew %s",drawoption.Data()));
1535 }
1536 else if (fRelTimes)
1537 {
1538 MHCalibrationRelTimeCam *cam =
1539 (MHCalibrationRelTimeCam*)plist.FindObject("MHCalibrationRelTimeCam");
1540 cam->DrawClone(Form("nonew %s",drawoption.Data()));
1541 }
1542 else
1543 {
1544 MHCalibrationChargeCam *cam =
1545 (MHCalibrationChargeCam*)plist.FindObject("MHCalibrationChargeCam");
1546 cam->DrawClone(Form("nonew %s",drawoption.Data()));
1547 }
1548 }
1549
1550 DisplayResult(plist);
1551
1552 if (!WriteResult())
1553 return kFALSE;
1554
1555 *fLog << inf << GetDescriptor() << ": Done." << endl;
1556
1557 return kTRUE;
1558}
1559
1560// --------------------------------------------------------------------------
1561//
1562// Read the following containers from GetOutputFile()
1563// - MCalibrationChargeCam
1564// - MCalibrationQECam
1565// - MBadPixelsCam
1566//
1567Bool_t MJCalibration::ReadCalibrationCam()
1568{
1569 const TString fname = GetOutputFile();
1570
1571 if (gSystem->AccessPathName(fname, kFileExists))
1572 {
1573 *fLog << err << "Input file " << fname << " doesn't exist." << endl;
1574 return kFALSE;
1575 }
1576
1577 *fLog << inf << "Reading from file: " << fname << endl;
1578
1579 TFile file(fname, "READ");
1580 if (fCalibrationCam.Read()<=0)
1581 {
1582 *fLog << err << "Unable to read MCalibrationChargeCam from " << fname << endl;
1583 return kFALSE;
1584 }
1585
1586 if (fQECam.Read()<=0)
1587 {
1588 *fLog << err << "Unable to read MCalibrationQECam from " << fname << endl;
1589 return kFALSE;
1590 }
1591
1592
1593 if (file.FindKey("MCalibrationRelTimeCam"))
1594 if (fRelTimeCam.Read()<=0)
1595 {
1596 *fLog << err << "Unable to read MCalibrationRelTimeCam from " << fname << endl;
1597 return kFALSE;
1598 }
1599
1600 if (file.FindKey("MBadPixelsCam"))
1601 {
1602 MBadPixelsCam bad;
1603 if (bad.Read()<=0)
1604 {
1605 *fLog << err << "Unable to read MBadPixelsCam from " << fname << endl;
1606 return kFALSE;
1607 }
1608 fBadPixels.Merge(bad);
1609 }
1610
1611 if (fDisplay /*&& !fDisplay->GetCanvas("Pedestals")*/) // FIXME!
1612 fDisplay->Read();
1613
1614 return kTRUE;
1615}
1616
1617
1618// --------------------------------------------------------------------------
1619//
1620// Set the path for output files, written by WriteResult()
1621//
1622void MJCalibration::SetOutputPath(const char *path)
1623{
1624 fOutputPath = path;
1625 if (fOutputPath.EndsWith("/"))
1626 fOutputPath = fOutputPath(0, fOutputPath.Length()-1);
1627}
1628
1629// --------------------------------------------------------------------------
1630//
1631// Set the useage of the Blind Pixel device
1632//
1633void MJCalibration::SetUseBlindPixel(const Bool_t b)
1634{
1635 b ? SETBIT(fDevices,kUseBlindPixel) : CLRBIT(fDevices,kUseBlindPixel);
1636}
1637
1638// --------------------------------------------------------------------------
1639//
1640// Set the useage of the PIN Diode device
1641//
1642void MJCalibration::SetUsePINDiode(const Bool_t b)
1643{
1644 b ? SETBIT(fDevices,kUsePINDiode) : CLRBIT(fDevices,kUsePINDiode);
1645}
1646
1647// --------------------------------------------------------------------------
1648//
1649// Write the result into the output file GetOutputFile(), if fOutputPath exists.
1650//
1651// The following containers are written:
1652// - MStatusDisplay
1653// - MCalibrationChargeCam
1654// - MCalibrationChargeBlindPix
1655// - MCalibrationQECam
1656// - MBadPixelsCam
1657//
1658Bool_t MJCalibration::WriteResult()
1659{
1660 if (fOutputPath.IsNull())
1661 return kTRUE;
1662
1663 const TString oname(GetOutputFile());
1664
1665 *fLog << inf << "Writing to file: " << oname << endl;
1666
1667 TFile file(oname, "UPDATE");
1668
1669 if (fDisplay && fDisplay->Write()<=0)
1670 {
1671 *fLog << err << "Unable to write MStatusDisplay to " << oname << endl;
1672 return kFALSE;
1673 }
1674
1675 if (fCalibrationCam.Write()<=0)
1676 {
1677 *fLog << err << "Unable to write MCalibrationChargeCam to " << oname << endl;
1678 return kFALSE;
1679 }
1680
1681 if (fCalibrationBlindCam.Write()<=0)
1682 {
1683 *fLog << err << "Unable to write MCalibrationChargeBlindCam to " << oname << endl;
1684 return kFALSE;
1685 }
1686
1687 if (fCalibrationPINDiode.Write()<=0)
1688 {
1689 *fLog << err << "Unable to write MCalibrationChargePINDiode to " << oname << endl;
1690 return kFALSE;
1691 }
1692
1693 if (fQECam.Write()<=0)
1694 {
1695 *fLog << err << "Unable to write MCalibrationQECam to " << oname << endl;
1696 return kFALSE;
1697 }
1698
1699 if (fRelTimes)
1700 if (fRelTimeCam.Write()<=0)
1701 {
1702 *fLog << err << "Unable to write MCalibrationRelTimeCam to " << oname << endl;
1703 return kFALSE;
1704 }
1705
1706 if (fBadPixels.Write()<=0)
1707 {
1708 *fLog << err << "Unable to write MBadPixelsCam to " << oname << endl;
1709 return kFALSE;
1710 }
1711
1712 return kTRUE;
1713
1714}
1715
1716void MJCalibration::DisplayDoubleProject(MHCamera *cam, const char* whatsmall, const char* whatbig) const
1717{
1718
1719 TArrayI inner(1);
1720 inner[0] = 0;
1721
1722 TArrayI outer(1);
1723 outer[0] = 1;
1724
1725 TArrayI s0(6);
1726 s0[0] = 6;
1727 s0[1] = 1;
1728 s0[2] = 2;
1729 s0[3] = 3;
1730 s0[4] = 4;
1731 s0[5] = 5;
1732
1733 TArrayI s1(3);
1734 s1[0] = 6;
1735 s1[1] = 1;
1736 s1[2] = 2;
1737
1738 TArrayI s2(3);
1739 s2[0] = 3;
1740 s2[1] = 4;
1741 s2[2] = 5;
1742
1743 TVirtualPad *pad = gPad;
1744 pad->Divide(2,1);
1745
1746 TH1D *inout[2];
1747 inout[0] = cam->ProjectionS(s0, inner, "Inner");
1748 inout[1] = cam->ProjectionS(s0, outer, "Outer");
1749 FixDataCheckHist(inout[0]);
1750 FixDataCheckHist(inout[1]);
1751
1752 inout[0]->SetTitle(Form("%s %s",cam->GetTitle(),"Inner"));
1753 inout[1]->SetTitle(Form("%s %s",cam->GetTitle(),"Outer"));
1754
1755 for (int i=0; i<2; i++)
1756 {
1757 pad->cd(i+1);
1758 gPad->SetBorderMode(0);
1759 gPad->SetTicks();
1760
1761 inout[i]->SetDirectory(NULL);
1762 inout[i]->SetLineColor(kRed+i);
1763 inout[i]->SetBit(kCanDelete);
1764 inout[i]->Draw();
1765 inout[i]->Fit("gaus", "Q");
1766
1767 TLegend *leg2 = new TLegend(0.6,0.5,0.9,0.7);
1768 //
1769 // Display the outliers as dead and noisy pixels
1770 //
1771 DisplayOutliers(inout[i],whatsmall,whatbig);
1772
1773 //
1774 // Display the two half of the camera separately
1775 //
1776 TH1D *half[2];
1777 half[0] = cam->ProjectionS(s1, i==0 ? inner : outer , "Sector 6-1-2");
1778 half[1] = cam->ProjectionS(s2, i==0 ? inner : outer , "Sector 3-4-5");
1779
1780 for (int j=0; j<2; j++)
1781 {
1782 half[j]->SetLineColor(kRed+i+2*j+1);
1783 half[j]->SetDirectory(NULL);
1784 half[j]->SetBit(kCanDelete);
1785 half[j]->Draw("same");
1786 leg2->AddEntry(half[j], half[j]->GetName(), "l");
1787 }
1788 leg2->Draw();
1789 }
1790}
Note: See TracBrowser for help on using the repository browser.