/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz, 1/2004 ! Markus Gaug, 02/2004 ! ! Copyright: MAGIC Software Development, 2000-2004 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MJCalibration // // Do one calibration loop over serious of runs with the same pulser // colour and the same intensity. The following containers (rectangular) and // tasks (ellipses) are called to produce an MCalibrationChargeCam and to // update the MCalibrationQECam: (MCalibrate is not called from this class) // //Begin_Html /* */ //End_Html // // Different signal extractors can be set with the command SetExtractor() // Only extractors deriving from MExtractor can be set, default is MExtractSlidingWindow // // Different arrival time extractors can be set with the command SetTimeExtractor() // Only extractors deriving from MExtractTime can be set, default is MExtractTimeSpline // // At the end of the eventloop, plots and results are displayed, depending on // the flags set (see DisplayResult()) // // If the flag SetFullDisplay() is set, all MHCameras will be displayed. // if the flag SetDataCheckDisplay() is set, only the most important ones are displayed // Otherwise, (default: SetNormalDisplay()), a good selection of plots is given // // If the flag SetDataCheck() is set, the calibration is used as in the data check at // La Palma, which mean especially running on raw data files. // // The absolute light calibration devices Blind Pixel and PIN Diode can be switched on // and off with the commands: // // - SetUseBlindPixel(Bool_t ) // - SetUsePINDiode(Bool_t ) // // See also: MHCalibrationChargePix, MHCalibrationChargeCam, MHGausEvents // MHCalibrationChargeBlindPix, MHCalibrationChargePINDiode // MCalibrationChargePix, MCalibrationChargeCam, MCalibrationChargeCalc // MCalibrationChargeBlindPix, MCalibrationChargePINDiode, // MCalibrationQECam, MBadPixelsPix, MBadPixelsCam // // If the flag RelTimeCalibration() is set, a calibration of the relative arrival // times is also performed. The following containers (rectangular) and // tasks (ellipses) are called to produce an MCalibrationRelTimeCam used by // MCalibrateTime to correct timing offset between pixels: (MCalibrateTime is not // called from this class) // //Begin_Html /* */ //End_Html // // Different arrival time extractors can be set directly with the command SetTimeExtractor(MExtractor *) // // See also: MHCalibrationRelTimePix, MHCalibrationRelTimeCam, MHGausEvents // MCalibrationRelTimePix, MCalibrationRelTimeCam // MBadPixelsPix, MBadPixelsCam // ///////////////////////////////////////////////////////////////////////////// #include "MJCalibration.h" #include #include #include #include #include #include #include #include #include #include #include "MLog.h" #include "MLogManip.h" #include "MRunIter.h" #include "MSequence.h" #include "MParList.h" #include "MTaskList.h" #include "MEvtLoop.h" #include "MHCamera.h" #include "MGeomCam.h" #include "MPedestalCam.h" #include "MCalibrationCam.h" #include "MCalibrationQECam.h" #include "MCalibrationQEPix.h" #include "MCalibrationChargeCam.h" #include "MCalibrationChargePix.h" #include "MCalibrationChargePINDiode.h" #include "MCalibrationChargeBlindPix.h" #include "MCalibrationChargeBlindCam.h" #include "MCalibrationChargeBlindCamOneOldStyle.h" #include "MCalibrationChargeBlindCamTwoNewStyle.h" #include "MCalibrationChargeCalc.h" #include "MHGausEvents.h" #include "MHCalibrationCam.h" #include "MHCalibrationChargeCam.h" #include "MHCalibrationChargeBlindCam.h" #include "MHCalibrationChargePINDiode.h" #include "MHCalibrationRelTimeCam.h" #include "MCalibrationRelTimeCam.h" #include "MCalibrationRelTimeCalc.h" #include "MReadMarsFile.h" #include "MRawFileRead.h" #include "MGeomApply.h" #include "MTaskEnv.h" #include "MBadPixelsMerge.h" #include "MBadPixelsCam.h" #include "MExtractTime.h" #include "MExtractor.h" #include "MExtractPINDiode.h" #include "MExtractBlindPixel.h" #include "MExtractSlidingWindow.h" #include "MExtractTimeFastSpline.h" #include "MFCosmics.h" #include "MContinue.h" #include "MFillH.h" #include "MArrivalTimeCam.h" #include "MStatusDisplay.h" ClassImp(MJCalibration); using namespace std; const Int_t MJCalibration::gkIFAEBoxInaugurationRun = 20113; const Int_t MJCalibration::gkSecondBlindPixelInstallation = 31693; const Int_t MJCalibration::gkThirdBlindPixelInstallation = 99999; const Double_t MJCalibration::fgConvFADC2PheMin = 0.; const Double_t MJCalibration::fgConvFADC2PheMax = 1.5; const Double_t MJCalibration::fgConvFADC2PhotMin = 0.; const Double_t MJCalibration::fgConvFADC2PhotMax = 10.; const Double_t MJCalibration::fgQEMin = 0.; const Double_t MJCalibration::fgQEMax = 0.3; const Float_t MJCalibration::fgRefConvFADC2PheInner = 0.14; const Float_t MJCalibration::fgRefConvFADC2PheOuter = 0.45; const Float_t MJCalibration::fgRefConvFADC2PhotInner = 0.8; const Float_t MJCalibration::fgRefConvFADC2PhotOuter = 3.8; const Float_t MJCalibration::fgRefQEInner = 0.18; const Float_t MJCalibration::fgRefQEOuter = 0.12; // -------------------------------------------------------------------------- // // Default constructor. // // - Sets fRuns to 0, fExtractor to NULL, fTimeExtractor to NULL, fColor to kNONE, // fDisplay to kNormalDisplay, fRelTime to kFALSE, fDataCheck to kFALSE, // - SetUseBlindPixel() // - SetUsePINDiode() // MJCalibration::MJCalibration(const char *name, const char *title) : fRuns(0), fExtractor(NULL), fTimeExtractor(NULL), fColor(MCalibrationCam::kNONE), fDisplayType(kNormalDisplay), fRelTimes(kFALSE), fDataCheck(kFALSE), fDebug(kFALSE) { fName = name ? name : "MJCalibration"; fTitle = title ? title : "Tool to create the calibration constants for one calibration run"; SetUseBlindPixel(); SetUsePINDiode(); } // -------------------------------------------------------------------------- // // Display the results in MStatusDisplay: // // - Add "Calibration" to the MStatusDisplay title // - Retrieve the MGeomCam from MParList // - Initialize the following MHCamera's: // 1) MCalibrationPix::GetMean() // 2) MCalibrationPix::Sigma() // 3) MCalibrationChargePix::GetRSigma() // 4) MCalibrationChargePix::GetRSigmaPerCharge() // 5) MCalibrationChargePix::GetPheFFactorMethod() // 6) MCalibrationChargePix::GetMeanConvFADC2Phe() // 7) MCalibrationChargePix::GetMeanFFactorFADC2Phot() // 8) MCalibrationQEPix::GetQECascadesFFactor() // 9) MCalibrationQEPix::GetQECascadesBlindPixel() // 10) MCalibrationQEPix::GetQECascadesPINDiode() // 11) MCalibrationQEPix::GetQECascadesCombined() // 12) MCalibrationQEPix::IsAverageQEFFactorAvailable() // 13) MCalibrationQEPix::IsAverageQEBlindPixelAvailable() // 14) MCalibrationQEPix::IsAverageQEPINDiodeAvailable() // 15) MCalibrationQEPix::IsAverageQECombinedAvailable() // 16) MCalibrationChargePix::IsHiGainSaturation() // 17) MCalibrationPix::GetHiLoMeansDivided() // 18) MCalibrationPix::GetHiLoSigmasDivided() // 19) MCalibrationChargePix::GetHiGainPickup() // 20) MCalibrationChargePix::GetLoGainPickup() // 21) MCalibrationChargePix::GetHiGainBlackout() // 22) MCalibrationChargePix::GetLoGainBlackout() // 23) MCalibrationPix::IsExcluded() // 24) MBadPixelsPix::IsUnsuitable(MBadPixelsPix::kUnsuitableRun) // 25) MBadPixelsPix::IsUnsuitable(MBadPixelsPix::kUnreliableRun) // 26) MBadPixelsPix::IsUncalibrated(MBadPixelsPix::kHiGainOscillating) // 27) MBadPixelsPix::IsUncalibrated(MBadPixelsPix::kLoGainOscillating) // 28) MCalibrationChargePix::GetAbsTimeMean() // 29) MCalibrationChargePix::GetAbsTimeRms() // // If the flag SetFullDisplay() is set, all MHCameras will be displayed. // if the flag SetDataCheckDisplay() is set, only the most important ones are displayed // and otherwise, (default: SetNormalDisplay()), a good selection of plots is given // void MJCalibration::DisplayResult(MParList &plist) { if (!fDisplay) return; // // Update display // TString title = fDisplay->GetTitle(); title += "-- Calibration "; title += fSequence.IsValid() ? Form("calib%06d", fSequence.GetSequence()) : (const char*)fRuns->GetRunsAsString(); title += " --"; fDisplay->SetTitle(title); // // Get container from list // MGeomCam &geomcam = *(MGeomCam*)plist.FindObject("MGeomCam"); // Create histograms to display MHCamera disp1 (geomcam, "Charge", "Fitted Mean Signal (Charges)"); MHCamera disp2 (geomcam, "SigmaCharge", "Sigma of Fitted Signal"); MHCamera disp3 (geomcam, "RSigma", "Reduced Sigmas"); MHCamera disp4 (geomcam, "RSigmaPerCharge", "Reduced Sigma per Charge"); MHCamera disp5 (geomcam, "NumPhes", "Number Photo-electrons"); MHCamera disp6 (geomcam, "ConvFADC2Phes", "Conversion Factor to Phes"); MHCamera disp7 (geomcam, "TotalFFactor", "Total F-Factor(F-Factor Method)"); MHCamera disp8 (geomcam, "CascadesQEFFactor", "Cascades QE (F-Factor Method)"); MHCamera disp9 (geomcam, "CascadesQEBlindPix","Cascades QE (Blind Pixel Method)"); MHCamera disp10(geomcam, "CascadesQEPINDiode","Cascades QE (PIN Diode Method)"); MHCamera disp11(geomcam, "CascadesQECombined","Cascades QE (Combined Method)"); MHCamera disp12(geomcam, "FFactorValid", "Pixels with valid F-Factor calibration"); MHCamera disp13(geomcam, "BlindPixelValid", "Pixels with valid BlindPixel calibration"); MHCamera disp14(geomcam, "PINdiodeValid", "Pixels with valid PINDiode calibration"); MHCamera disp15(geomcam, "CombinedValid", "Pixels with valid Combined calibration"); MHCamera disp16(geomcam, "Saturation", "Pixels with saturated Hi Gain"); MHCamera disp17(geomcam, "ConversionMeans", "Conversion HiGain.vs.LoGain Means"); MHCamera disp18(geomcam, "ConversionSigmas", "Conversion HiGain.vs.LoGain Sigmas"); MHCamera disp19(geomcam, "HiGainPickup", "Number Pickup events Hi Gain"); MHCamera disp20(geomcam, "LoGainPickup", "Number Pickup events Lo Gain"); MHCamera disp21(geomcam, "HiGainBlackout", "Number Blackout events Hi Gain"); MHCamera disp22(geomcam, "LoGainBlackout", "Number Blackout events Lo Gain"); MHCamera disp23(geomcam, "Excluded", "Pixels previously excluded"); MHCamera disp24(geomcam, "UnSuitable", "Pixels not suited for further analysis"); MHCamera disp25(geomcam, "UnReliable", "Pixels not reliable for further analysis"); MHCamera disp26(geomcam, "HiGainOscillating", "Oscillating Pixels High Gain"); MHCamera disp27(geomcam, "LoGainOscillating", "Oscillating Pixels Low Gain"); MHCamera disp28(geomcam, "AbsTimeMean", "Abs. Arrival Times"); MHCamera disp29(geomcam, "AbsTimeRms", "RMS of Arrival Times"); MHCamera disp30(geomcam, "MeanTime", "Mean Rel. Arrival Times"); MHCamera disp31(geomcam, "SigmaTime", "Sigma Rel. Arrival Times"); MHCamera disp32(geomcam, "TimeProb", "Probability of Time Fit"); MHCamera disp33(geomcam, "TimeNotFitValid", "Pixels with not valid fit results"); MHCamera disp34(geomcam, "TimeOscillating", "Oscillating Pixels"); MHCamera disp35(geomcam, "TotalConv", "Conversion Factor to photons"); // Fitted charge means and sigmas disp1.SetCamContent(fCalibrationCam, 0); disp1.SetCamError( fCalibrationCam, 1); disp2.SetCamContent(fCalibrationCam, 2); disp2.SetCamError( fCalibrationCam, 3); // Reduced Sigmas and reduced sigmas per charge disp3.SetCamContent(fCalibrationCam, 5); disp3.SetCamError( fCalibrationCam, 6); disp4.SetCamContent(fCalibrationCam, 7); disp4.SetCamError( fCalibrationCam, 8); // F-Factor Method disp5.SetCamContent(fCalibrationCam, 9); disp5.SetCamError( fCalibrationCam, 10); disp6.SetCamContent(fCalibrationCam, 11); disp6.SetCamError( fCalibrationCam, 12); disp7.SetCamContent(fCalibrationCam, 13); disp7.SetCamError( fCalibrationCam, 14); // Quantum Efficiencies disp8.SetCamContent (fQECam, 0 ); disp8.SetCamError (fQECam, 1 ); disp9.SetCamContent (fQECam, 2 ); disp9.SetCamError (fQECam, 3 ); disp10.SetCamContent(fQECam, 4 ); disp10.SetCamError (fQECam, 5 ); disp11.SetCamContent(fQECam, 6 ); disp11.SetCamError (fQECam, 7 ); // Valid flags disp12.SetCamContent(fQECam, 8 ); disp13.SetCamContent(fQECam, 9 ); disp14.SetCamContent(fQECam, 10); disp15.SetCamContent(fQECam, 11); // Conversion Hi-Lo disp16.SetCamContent(fCalibrationCam, 25); disp17.SetCamContent(fCalibrationCam, 16); disp17.SetCamError (fCalibrationCam, 17); disp18.SetCamContent(fCalibrationCam, 18); disp18.SetCamError (fCalibrationCam, 19); // Pickup and Blackout disp19.SetCamContent(fCalibrationCam, 21); disp20.SetCamContent(fCalibrationCam, 22); disp21.SetCamContent(fCalibrationCam, 23); disp22.SetCamContent(fCalibrationCam, 24); // Pixels with defects disp23.SetCamContent(fCalibrationCam, 20); disp24.SetCamContent(fBadPixels, 6); disp25.SetCamContent(fBadPixels, 7); // Oscillations disp26.SetCamContent(fBadPixels, 10); disp27.SetCamContent(fBadPixels, 11); // Arrival Times disp28.SetCamContent(fCalibrationCam, 26); disp28.SetCamError( fCalibrationCam, 27); disp29.SetCamContent(fCalibrationCam, 27); disp1.SetYTitle("Q [FADC counts]"); disp2.SetYTitle("\\sigma_{Q} [FADC counts]"); disp3.SetYTitle("\\sqrt{\\sigma^{2}_{Q} - RMS^{2}_{Ped}} [FADC Counts]"); disp4.SetYTitle("Red.Sigma/ [1]"); disp5.SetYTitle("Photo-electons [1]"); disp6.SetYTitle("Conv.Factor [PhE/FADC counts]"); disp7.SetYTitle("Total F-Factor [1]"); disp8.SetYTitle("QE [1]"); disp9.SetYTitle("QE [1]"); disp10.SetYTitle("QE [1]"); disp11.SetYTitle("QE [1]"); disp12.SetYTitle("[1]"); disp13.SetYTitle("[1]"); disp14.SetYTitle("[1]"); disp15.SetYTitle("[1]"); disp16.SetYTitle("[1]"); disp17.SetYTitle("(High)/(Low) [1]"); disp18.SetYTitle("\\sigma_{Q}(High)/\\sigma_{Q}(Low) [1]"); disp19.SetYTitle("[1]"); disp20.SetYTitle("[1]"); disp21.SetYTitle("[1]"); disp22.SetYTitle("[1]"); // disp23.SetYTitle("[1]"); // disp24.SetYTitle("[1]"); // disp25.SetYTitle("[1]"); disp26.SetYTitle("[1]"); disp27.SetYTitle("[1]"); disp28.SetYTitle("Mean Abs. Time [FADC slice]"); disp29.SetYTitle("RMS Abs. Time [FADC slices]"); disp35.SetYTitle("Conv.Factor [Ph/FADC counts]"); for (UInt_t i=0;iAddTab("Fit.Charge"); c1.Divide(3, 3); // // MEAN CHARGES // c1.cd(1); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj1=(MHCamera*)disp1.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // // obj1->SetMinimum(fgChargeMin); // obj1->SetMaximum(fgChargeMax); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj1); obj1->SetStats(kFALSE); // // set reference lines // // DisplayReferenceLines(obj1,0); c1.cd(4); gPad->SetBorderMode(0); obj1->SetPrettyPalette(); obj1->Draw(); c1.cd(7); gPad->SetBorderMode(0); gPad->SetTicks(); TH1D *obj2 = (TH1D*)obj1->Projection(obj1->GetName()); obj2->Draw(); obj2->SetBit(kCanDelete); obj2->Fit("gaus","Q"); TF1 *fun2 = obj2->GetFunction("gaus"); fun2->SetLineColor(kYellow); gPad->Modified(); gPad->Update(); TPaveStats *st = (TPaveStats*)obj2->GetListOfFunctions()->FindObject("stats"); st->SetY1NDC(0.55); st->SetY2NDC(0.89); st->SetX1NDC(0.65); st->SetX2NDC(0.99); gPad->Modified(); gPad->Update(); // // Set the datacheck sizes: // FixDataCheckHist(obj2); obj2->SetStats(1); // // Display the outliers as dead and noisy pixels // DisplayOutliers(obj2,"low-ampl.","high-ampl."); TLatex flattex; flattex.SetTextSize(0.07); const Double_t minl = obj2->GetBinCenter(obj2->GetXaxis()->GetFirst()); const Double_t maxl = obj2->GetBinCenter(obj2->GetXaxis()->GetLast()); flattex.DrawLatex(minl+0.015*(maxl-minl),obj2->GetBinContent(obj2->GetMaximumBin())/1.35, Form("Flatfield precision: %4.2f%%", fun2->GetParameter(2)/fun2->GetParameter(1)*100.)); // // REDUCED SIGMAS // c1.cd(2); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj3=(MHCamera*)disp4.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // // obj3->SetMinimum(fgChargeMin); // obj3->SetMaximum(fgChargeMax); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj3); obj3->SetStats(kFALSE); // // set reference lines // // DisplayReferenceLines(obj3,0); c1.cd(5); gPad->SetBorderMode(0); obj3->SetPrettyPalette(); obj3->Draw(); c1.cd(8); gPad->SetBorderMode(0); if (geomcam.InheritsFrom("MGeomCamMagic")) DisplayDoubleProject(&disp4, "dead", "noisy"); // // PHOTO ELECTRONS // c1.cd(3); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj4=(MHCamera*)disp5.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // // obj3->SetMinimum(fgChargeMin); // obj3->SetMaximum(fgChargeMax); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj4); obj4->SetStats(kFALSE); // // set reference lines // // DisplayReferenceLines(obj3,0); c1.cd(6); gPad->SetBorderMode(0); obj4->SetPrettyPalette(); obj4->Draw(); c1.cd(9); gPad->SetBorderMode(0); if (geomcam.InheritsFrom("MGeomCamMagic")) DisplayDoubleProject(&disp5, "dead", "noisy"); // // CONVERSION FACTORS // TCanvas &c2 = fDisplay->AddTab("Conversion"); c2.Divide(3,3); c2.cd(1); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj5=(MHCamera*)disp6.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // obj5->SetMinimum(fgConvFADC2PheMin); obj5->SetMaximum(fgConvFADC2PheMax); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj5); obj5->SetStats(kFALSE); // // set reference lines // DisplayReferenceLines(obj5,2); c2.cd(4); gPad->SetBorderMode(0); obj5->SetPrettyPalette(); obj5->Draw(); c2.cd(7); gPad->SetBorderMode(0); if (geomcam.InheritsFrom("MGeomCamMagic")) DisplayDoubleProject(&disp6, "noisy", "dead"); // // QUANTUM EFFICIENCY // c2.cd(2); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj6=(MHCamera*)disp8.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // obj6->SetMinimum(fgQEMin); obj6->SetMaximum(fgQEMax); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj6); obj6->SetStats(kFALSE); // // set reference lines // DisplayReferenceLines(obj6,0); c2.cd(5); gPad->SetBorderMode(0); obj6->SetPrettyPalette(); obj6->Draw(); c2.cd(8); gPad->SetBorderMode(0); if (geomcam.InheritsFrom("MGeomCamMagic")) DisplayDoubleProject(&disp8, "noisy", "dead"); // // CONVERSION FADC TO PHOTONS // c2.cd(3); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj7=(MHCamera*)disp35.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // obj7->SetMinimum(fgConvFADC2PhotMin); obj7->SetMaximum(fgConvFADC2PhotMax); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj7); obj7->SetStats(kFALSE); // // set reference lines // DisplayReferenceLines(obj7,1); c2.cd(6); gPad->SetBorderMode(0); obj7->SetPrettyPalette(); obj7->Draw(); c2.cd(9); gPad->SetBorderMode(0); if (geomcam.InheritsFrom("MGeomCamMagic")) DisplayDoubleProject(&disp35, "noisy", "dead"); // // UNSUITABLE PIXELS // TCanvas &c4 = fDisplay->AddTab("Defect"); c4.Divide(2,2); c4.cd(1); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj8=(MHCamera*)disp24.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // const Double_t max = 11.; obj8->SetMinimum(0.); obj8->SetMaximum(11.); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj8); obj8->SetStats(kFALSE); gStyle->SetPalette(1); const Int_t numcol = gStyle->GetNumberOfColors()-3; TPaveText *pave = new TPaveText(0.0,0.0,0.99,0.99); pave->SetBit(kCanDelete); pave->ConvertNDCtoPad(); pave->SetTextSize(0.05); pave->AddText(" "); TText *t1 = pave->AddText(Form("Signal smaller 3 Pedestal RMS: %3i pixels", CountBadPixels(&disp24,1))); t1->SetTextColor(gStyle->GetColorPalette(Int_t(1./max*numcol + 1.))); t1->SetTextAlign(12); TText *t2 = pave->AddText(Form("%s%3i%s","Signal Rel. error too large: ", CountBadPixels(&disp24,2)," pixels")); t2->SetTextColor(gStyle->GetColorPalette(Int_t(2./max*numcol + 1.))); t2->SetTextAlign(12); TText *t3 = pave->AddText(Form("Signal Sigma smaller than Pedestal RMS: %3i pixels", CountBadPixels(&disp24,3))); t3->SetTextColor(gStyle->GetColorPalette(Int_t(3./max*numcol + 1.))); t3->SetTextAlign(12); TText *t4 = pave->AddText(Form("Low Gain Saturation: %3i pixels", CountBadPixels(&disp24,4))); t4->SetTextColor(gStyle->GetColorPalette(Int_t(4./max*numcol + 1.))); t4->SetTextAlign(12); TText *t5 = pave->AddText(Form("Mean Arr. Time In First Extraction Bin: %3i pixels", CountBadPixels(&disp24,5))); t5->SetTextColor(gStyle->GetColorPalette(Int_t(5./max*numcol + 1.))); t5->SetTextAlign(12); TText *t6 = pave->AddText(Form("Mean Arr. Time In Last 2 Extraction Bins: %3i pixels", CountBadPixels(&disp24,6))); t6->SetTextColor(gStyle->GetColorPalette(Int_t(6./max*numcol + 1.))); t6->SetTextAlign(12); TText *t7 = pave->AddText(Form("Deviating Number of Photo-electrons: %3i pixels", CountBadPixels(&disp24,7))); t7->SetTextColor(gStyle->GetColorPalette(Int_t(7./max*numcol + 1.))); t7->SetTextAlign(12); TText *t8 = pave->AddText(Form("Deviating global F-Factor: %3i pixels", CountBadPixels(&disp24,8))); t8->SetTextColor(gStyle->GetColorPalette(Int_t(8./max*numcol + 1.))); t8->SetTextAlign(12); TText *t9 = pave->AddText(Form("Deviating Number of Photons: %3i pixels", CountBadPixels(&disp24,9))); t9->SetTextColor(gStyle->GetColorPalette(Int_t(9./max*numcol + 1.))); t9->SetTextAlign(12); TText *t10= pave->AddText(Form("Previously Excluded: %3i pixels", CountBadPixels(&disp24,10))); t10->SetTextColor(gStyle->GetColorPalette(Int_t(10./max*numcol + 1.))); t10->SetTextAlign(12); pave->Draw(); c4.cd(3); gPad->SetBorderMode(0); obj8->Draw(); obj8->SetPrettyPalette(); // // UNRELIABLE PIXELS // c4.cd(2); gPad->SetBorderMode(0); gPad->SetTicks(); MHCamera *obj9=(MHCamera*)disp25.DrawCopy("hist"); // // for the datacheck, fix the ranges!! // const Double_t max2 = 8.; obj9->SetMinimum(0.); obj9->SetMaximum(max2); // // Set the datacheck sizes: // FixDataCheckHist((TH1D*)obj9); obj9->SetStats(kFALSE); gStyle->SetPalette(1); TPaveText *pave2 = new TPaveText(0.0,0.0,0.99,0.99); pave2->SetBit(kCanDelete); pave2->ConvertNDCtoPad(); pave2->SetTextSize(0.05); pave2->AddText(" "); TText *tt1 = pave2->AddText(Form("High Gain Signals could not be fitted: %3i pixels", CountBadPixels(&disp25,1))); tt1->SetTextColor(gStyle->GetColorPalette(Int_t(1./max2*numcol + 1.))); tt1->SetTextAlign(12); TText *tt2 = pave2->AddText(Form("Low Gain Signals could not be fitted: %3i pixels", CountBadPixels(&disp25,2))); tt2->SetTextColor(gStyle->GetColorPalette(Int_t(2./max2*numcol + 1.))); tt2->SetTextAlign(12); TText *tt3 = pave2->AddText(Form("Relative Arr. Times could not be fitted: %3i pixels", CountBadPixels(&disp25,3))); tt3->SetTextColor(gStyle->GetColorPalette(Int_t(3./max2*numcol + 1.))); tt3->SetTextAlign(12); TText *tt4 = pave2->AddText(Form("High Gain Signals Oscillation: %3i pixels", CountBadPixels(&disp25,4))); tt4->SetTextColor(gStyle->GetColorPalette(Int_t(4./max2*numcol + 1.))); tt4->SetTextAlign(12); TText *tt5 = pave2->AddText(Form("Low Gain Signals Oscillation: %3i pixels", CountBadPixels(&disp25,5))); tt5->SetTextColor(gStyle->GetColorPalette(Int_t(5./max2*numcol + 1.))); tt5->SetTextAlign(12); TText *tt6 = pave2->AddText(Form("Relative Arr. Times Oscillation: %3i pixels", CountBadPixels(&disp25,6))); tt6->SetTextColor(gStyle->GetColorPalette(Int_t(6./max2*numcol + 1.))); tt6->SetTextAlign(12); pave2->Draw(); c4.cd(4); gPad->SetBorderMode(0); obj9->SetPrettyPalette(); obj9->Draw(); if (fRelTimes) { // Rel. Times TCanvas &c5 = fDisplay->AddTab("Rel. Times"); c5.Divide(2,4); disp30.CamDraw(c5, 1, 2, 2); disp31.CamDraw(c5, 2, 2, 2); } return; } if (fDisplayType == kNormalDisplay) { // Charges TCanvas &c11 = fDisplay->AddTab("Fit.Charge"); c11.Divide(2, 4); disp1.CamDraw(c11, 1, 2, 5, 1); disp2.CamDraw(c11, 2, 2, 5, 1); // Reduced Sigmas TCanvas &c12 = fDisplay->AddTab("Red.Sigma"); c12.Divide(2,4); disp3.CamDraw(c12, 1, 2, 5, 1); disp4.CamDraw(c12, 2, 2, 5, 1); // F-Factor TCanvas &c13 = fDisplay->AddTab("Phe's"); c13.Divide(3,4); disp5.CamDraw(c13, 1, 3, 5, 1); disp6.CamDraw(c13, 2, 3, 5, 1); disp7.CamDraw(c13, 3, 3, 5, 1); // QE's TCanvas &c14 = fDisplay->AddTab("QE's"); c14.Divide(4,4); disp8.CamDraw(c14, 1, 4, 5, 1); disp9.CamDraw(c14, 2, 4, 5, 1); disp10.CamDraw(c14, 3, 4, 5, 1); disp11.CamDraw(c14, 4, 4, 5, 1); // Defects TCanvas &c15 = fDisplay->AddTab("Defect"); // c15.Divide(5,2); c15.Divide(4,2); /* disp23.CamDraw(c15, 1, 5, 0); disp24.CamDraw(c15, 2, 5, 0); disp25.CamDraw(c15, 3, 5, 0); disp26.CamDraw(c15, 4, 5, 0); disp27.CamDraw(c15, 5, 5, 0); */ disp24.CamDraw(c15, 1, 4, 0); disp25.CamDraw(c15, 2, 4, 0); disp26.CamDraw(c15, 3, 4, 0); disp27.CamDraw(c15, 4, 4, 0); // Abs. Times TCanvas &c16 = fDisplay->AddTab("Abs. Times"); c16.Divide(2,3); disp28.CamDraw(c16, 1, 2, 5); disp29.CamDraw(c16, 2, 2, 5); if (fRelTimes) { // Rel. Times TCanvas &c17 = fDisplay->AddTab("Rel. Times"); c17.Divide(2,4); disp30.CamDraw(c17, 1, 2, 5, 1); disp31.CamDraw(c17, 2, 2, 5, 1); } return; } if (fDisplayType == kFullDisplay) { MHCalibrationCam *cam = (MHCalibrationCam*)plist.FindObject("MHCalibrationChargeCam"); for (Int_t sector=1;sectorGetAverageSectors();sector++) { cam->GetAverageHiGainSector(sector).DrawClone("all"); cam->GetAverageLoGainSector(sector).DrawClone("all"); } // Charges TCanvas &c21 = fDisplay->AddTab("Fit.Charge"); c21.Divide(2, 4); disp1.CamDraw(c21, 1, 2, 2, 1); disp2.CamDraw(c21, 2, 2, 2, 1); // Reduced Sigmas TCanvas &c23 = fDisplay->AddTab("Red.Sigma"); c23.Divide(2,4); disp3.CamDraw(c23, 1, 2, 2, 1); disp4.CamDraw(c23, 2, 2, 2, 1); // F-Factor TCanvas &c24 = fDisplay->AddTab("Phe's"); c24.Divide(3,5); disp5.CamDraw(c24, 1, 3, 2, 1, 1); disp6.CamDraw(c24, 2, 3, 2, 1, 1); disp7.CamDraw(c24, 3, 3, 2, 1, 1); // QE's TCanvas &c25 = fDisplay->AddTab("QE's"); c25.Divide(4,5); disp8.CamDraw(c25, 1, 4, 2, 1, 1); disp9.CamDraw(c25, 2, 4, 2, 1, 1); disp10.CamDraw(c25, 3, 4, 2, 1, 1); disp11.CamDraw(c25, 4, 4, 2, 1, 1); // Validity TCanvas &c26 = fDisplay->AddTab("Valid"); c26.Divide(4,2); disp12.CamDraw(c26, 1, 4, 0); disp13.CamDraw(c26, 2, 4, 0); disp14.CamDraw(c26, 3, 4, 0); disp15.CamDraw(c26, 4, 4, 0); // Other info TCanvas &c27 = fDisplay->AddTab("HiLoGain"); c27.Divide(3,3); disp16.CamDraw(c27, 1, 3, 0); disp17.CamDraw(c27, 2, 3, 1); disp18.CamDraw(c27, 3, 3, 1); // Pickup TCanvas &c28 = fDisplay->AddTab("Pickup"); c28.Divide(4,2); disp19.CamDraw(c28, 1, 4, 0); disp20.CamDraw(c28, 2, 4, 0); disp21.CamDraw(c28, 3, 4, 0); disp22.CamDraw(c28, 4, 4, 0); // Defects TCanvas &c29 = fDisplay->AddTab("Defect"); // c29.Divide(5,2); c29.Divide(4,2); disp24.CamDraw(c29, 1, 4, 0); disp25.CamDraw(c29, 2, 4, 0); disp26.CamDraw(c29, 3, 4, 0); disp27.CamDraw(c29, 4, 4, 0); // Abs. Times TCanvas &c30 = fDisplay->AddTab("Abs. Times"); c30.Divide(2,3); disp28.CamDraw(c30, 1, 2, 2); disp29.CamDraw(c30, 2, 2, 1); if (fRelTimes) { // Rel. Times TCanvas &c31 = fDisplay->AddTab("Rel. Times"); c31.Divide(3,5); disp30.CamDraw(c31, 1, 3, 2, 1, 1); disp31.CamDraw(c31, 2, 3, 2, 1, 1); disp32.CamDraw(c31, 3, 3, 4, 1, 1); // Time Defects TCanvas &c32 = fDisplay->AddTab("Time Def."); c32.Divide(2,2); disp33.CamDraw(c32, 1, 2, 0); disp34.CamDraw(c32, 2, 2, 0); MHCalibrationCam *cam = (MHCalibrationCam*)plist.FindObject("MHCalibrationRelTimeCam"); for (Int_t sector=1;sectorGetAverageSectors();sector++) { cam->GetAverageHiGainSector(sector).DrawClone("fourierevents"); cam->GetAverageLoGainSector(sector).DrawClone("fourierevents"); } } return; } } void MJCalibration::DisplayReferenceLines(MHCamera *cam, const Int_t what) const { const MGeomCam *geom = cam->GetGeometry(); Double_t x = geom->InheritsFrom("MGeomCamMagic") ? 397 : cam->GetNbinsX() ; TLine line; line.SetLineStyle(kDashed); line.SetLineWidth(3); line.SetLineColor(kBlue); TLine *l1 = NULL; if (what == 0) l1 = line.DrawLine(0, fgRefQEInner, x, fgRefQEInner); else if (what == 1) l1 = line.DrawLine(0, fgRefConvFADC2PhotInner, x, fgRefConvFADC2PhotInner); else if (what == 2) l1 = line.DrawLine(0, fgRefConvFADC2PheInner, x, fgRefConvFADC2PheInner ); if (geom->InheritsFrom("MGeomCamMagic")) { const Double_t x2 = cam->GetNbinsX(); switch (what) { case 0: line.DrawLine(x2, fgRefQEOuter, 398, fgRefQEOuter); break; case 1: line.DrawLine(x2, fgRefConvFADC2PhotOuter, 398, fgRefConvFADC2PhotOuter ); break; case 2: line.DrawLine(x2, fgRefConvFADC2PheOuter, 398, fgRefConvFADC2PheOuter); break; } } TLegend *leg = new TLegend(what ? 0.2 : 0.6,0.75,what ? 0.5 : 0.9 ,0.85); leg->SetBit(kCanDelete); leg->AddEntry(l1, "Reference","l"); leg->Draw(); } void MJCalibration::DisplayOutliers(TH1D *hist, const char* whatsmall, const char* whatbig) const { const Float_t mean = hist->GetFunction("gaus")->GetParameter(1); const Float_t lolim = mean - 4.0*hist->GetFunction("gaus")->GetParameter(2); const Float_t uplim = mean + 4.0*hist->GetFunction("gaus")->GetParameter(2); const Stat_t dead = hist->Integral(0,hist->FindBin(lolim)-1); const Stat_t noisy = hist->Integral(hist->FindBin(uplim)+1,hist->GetNbinsX()+1); const Double_t max = hist->GetBinContent(hist->GetMaximumBin()); const Double_t minl = hist->GetBinCenter(hist->GetXaxis()->GetFirst()); const Double_t maxl = hist->GetBinCenter(hist->GetXaxis()->GetLast()); TLatex deadtex; deadtex.SetTextSize(0.07); deadtex.DrawLatex(minl+0.015*(maxl-minl),max/1.1, Form("%3i %s pixels",(Int_t)dead,whatsmall)); TLatex noisytex; noisytex.SetTextSize(0.07); noisytex.DrawLatex(minl+0.015*(maxl-minl),max/1.2, Form("%3i %s pixels",(Int_t)noisy,whatbig)); } void MJCalibration::FixDataCheckHist(TH1D *hist) const { hist->SetDirectory(NULL); // // set the labels bigger // TAxis *xaxe = hist->GetXaxis(); TAxis *yaxe = hist->GetYaxis(); xaxe->CenterTitle(); yaxe->CenterTitle(); xaxe->SetTitleSize(0.06); yaxe->SetTitleSize(0.06); xaxe->SetTitleOffset(0.8); yaxe->SetTitleOffset(0.85); xaxe->SetLabelSize(0.05); yaxe->SetLabelSize(0.05); } const Int_t MJCalibration::CountBadPixels ( MHCamera *cam , const Int_t what ) const { Int_t cnt = 0; for (UInt_t pix=0; pixGetNumPixels();pix++) if ((Int_t)cam->GetPixContent(pix) == what) cnt++; return cnt; } // -------------------------------------------------------------------------- // // Find the colour of the pulsing LED: // - If the run number is smaller than gkIFAEBoxInaugurationRun, take MCalibrationCam::kCT1 // - Otherwise find the colour out of the run name // - If no colour is found, return kFALSE // Bool_t MJCalibration::FindColor() { if (fColor != MCalibrationCam::kNONE) return kTRUE; if (fSequence.IsValid()) { fColor = MCalibrationCam::kCT1; return kTRUE; } const UInt_t nruns = fRuns->GetNumRuns(); if (nruns == 0) return kFALSE; fRuns->Reset(); TString filenames; while (!(filenames=((MDirIter*)fRuns)->Next()).IsNull()) { MCalibrationCam::PulserColor_t newcolor = MCalibrationCam::kNONE; TString number = filenames(TRegexp("[0-9]+_._.+[.]root$")); Int_t num = atoi(number.Data()); if (num"; break; } *fLog << endl; if (fColor!=MCalibrationCam::kNONE) return kTRUE; *fLog << "No colour found in: " << fRuns->GetRunsAsString() << "... abort." << endl; return kFALSE; } // -------------------------------------------------------------------------- // // Retrieve the output file written by WriteResult() // const char* MJCalibration::GetOutputFile() const { if (fSequence.IsValid()) return Form("%s/calib%06d.root", (const char*)fPathOut, fSequence.GetSequence()); if (!fRuns) return ""; return Form("%s/%s-F1.root", (const char*)fPathOut, (const char*)fRuns->GetRunsAsFileName()); } Bool_t MJCalibration::IsUseBlindPixel() const { return TESTBIT(fDevices,kUseBlindPixel); } Bool_t MJCalibration::IsUsePINDiode() const { return TESTBIT(fDevices,kUsePINDiode); } // -------------------------------------------------------------------------- // // MJCalibration allows to setup several option by a resource file: // MJCalibration.Display: full, datacheck, normal // MJCalibration.RelTimeCalibration: yes,no // MJCalibration.Datacheck: yes,no // MJCalibration.Debug: yes,no // MJCalibration.UseBlindPixel: yes,no // MJCalibration.UsePINDiode: yes,no // // For more details see the class description and the corresponding Getters // Bool_t MJCalibration::CheckEnvLocal() { TString col = GetEnv("Color", ""); if (!col.IsNull()) { } TString dis = GetEnv("Display", ""); if (dis.BeginsWith("Full", TString::kIgnoreCase)) SetFullDisplay(); if (dis.BeginsWith("DataCheck", TString::kIgnoreCase)) SetDataCheckDisplay(); if (dis.BeginsWith("Normal", TString::kIgnoreCase)) SetNormalDisplay(); SetRelTimeCalibration(GetEnv("RelTimeCalibration", fRelTimes)); SetDataCheck(GetEnv("Datacheck", fDataCheck)); SetDebug(GetEnv("Debug", fDebug)); SetUseBlindPixel(GetEnv("UseBlindPixel", IsUseBlindPixel())); SetUsePINDiode(GetEnv("UsePINDiode", IsUsePINDiode())); return kTRUE; } // -------------------------------------------------------------------------- // // Call the ProcessFile(MPedestalCam) // Bool_t MJCalibration::Process(MPedestalCam &pedcam) { if (!ReadCalibrationCam()) return ProcessFile(pedcam); return kTRUE; } void MJCalibration::InitBlindPixel(MExtractBlindPixel &blindext, MHCalibrationChargeBlindCam &blindcam) { Int_t run = fSequence.IsValid() ? fSequence.GetLastRun() : fRuns->GetRuns()[fRuns->GetNumRuns()-1]; // // Initialize the blind pixel. Unfortunately, there is a hardware difference // in the first blind pixel until run "gkSecondBlindPixelInstallation" and the // later setup. The first needs to use a filter because of the length of // spurious NSB photon signals. The latter get better along extracting the amplitude // from a small window. // if (run < gkSecondBlindPixelInstallation) { MCalibrationChargeBlindCamOneOldStyle blindresults; blindresults.Copy(fCalibrationBlindCam); blindext.SetExtractionType(MExtractBlindPixel::kIntegral); blindext.SetExtractionType(MExtractBlindPixel::kFilter); blindext.SetRange(10,19,0,6); blindext.SetNSBFilterLimit(70); blindcam.SetFitFunc( MHCalibrationChargeBlindPix::kEPoisson5 ); } else if (run < gkThirdBlindPixelInstallation) { MCalibrationChargeBlindCamTwoNewStyle blindresults; blindresults.Copy(fCalibrationBlindCam); blindext.SetNumBlindPixels(blindresults.GetNumBlindPixels()); for (UInt_t i=0;iGetNumRuns() != fRuns->GetNumEntries()) { *fLog << err << "Number of files found doesn't match number of runs... abort." << fRuns->GetNumRuns() << " vs. " << fRuns->GetNumEntries() << endl; return kFALSE; } } //if (!CheckEnv()) // return kFALSE; CheckEnv(); // -------------------------------------------------------------------------------- *fLog << inf; fLog->Separator(GetDescriptor()); if (!FindColor()) return kFALSE; *fLog << "Calculate MCalibrationCam from "; if (fSequence.IsValid()) *fLog << "Sequence #" << fSequence.GetSequence() << endl; else *fLog << "Runs " << fRuns->GetRunsAsString() << endl; *fLog << endl; // -------------------------------------------------------------------------------- // Setup Tasklist MParList plist; MTaskList tlist; plist.AddToList(&tlist); plist.AddToList(this); // take care of fDisplay! MReadMarsFile read("Events"); MRawFileRead rawread(NULL); MDirIter iter; if (fSequence.IsValid()) { const Int_t n0 = fSequence.SetupCalRuns(iter, fPathData); const Int_t n1 = fSequence.GetNumCalRuns(); if (n0==0) { *fLog << err << "ERROR - No input files of sequence found!" << endl; return kFALSE; } if (n0!=n1) { *fLog << err << "ERROR - Number of files found (" << n0 << ") doesn't match number of files in sequence (" << n1 << ")" << endl; return kFALSE; } } if (fDataCheck) { rawread.AddFiles(fSequence.IsValid() ? iter : *fRuns); tlist.AddToList(&rawread); } else { read.DisableAutoScheme(); read.AddFiles(fSequence.IsValid() ? iter : *fRuns); tlist.AddToList(&read); } MHCalibrationChargeCam chargecam; MHCalibrationChargeBlindCam blindcam; plist.AddToList(&pedcam); plist.AddToList(&chargecam); plist.AddToList(&blindcam); plist.AddToList(&fBadPixels); plist.AddToList(&fQECam); plist.AddToList(&fCalibrationCam); plist.AddToList(&fCalibrationBlindCam); plist.AddToList(&fCalibrationPINDiode); plist.AddToList(&fRelTimeCam); MGeomApply apply; MBadPixelsMerge merge(&fBadPixels); MExtractPINDiode pinext; MExtractBlindPixel blindext; InitBlindPixel(blindext, blindcam); MExtractSlidingWindow extract2; MExtractTimeFastSpline timespline; MCalibrationChargeCalc calcalc; MCalibrationRelTimeCalc timecalc; if (!fSequence.IsValid()) { calcalc.SetOutputPath(fPathOut); calcalc.SetOutputFile(Form("%s-ChargeCalibStat.txt",(const char*)fRuns->GetRunsAsFileName())); } if (fDebug) { chargecam.SetDebug(); calcalc.SetDebug(); } // // As long as there are no DM's, have to colour by hand // chargecam.SetColor (fColor); calcalc.SetPulserColor(fColor); MFillH fillpin("MHCalibrationChargePINDiode", "MExtractedSignalPINDiode", "FillPINDiode"); MFillH fillbnd("MHCalibrationChargeBlindCam", "MExtractedSignalBlindPixel", "FillBlindCam"); MFillH fillcam("MHCalibrationChargeCam", "MExtractedSignalCam", "FillChargeCam"); MFillH filltme("MHCalibrationRelTimeCam", "MArrivalTimeCam", "FillRelTime"); fillpin.SetNameTab("PINDiode"); fillbnd.SetNameTab("BlindPix"); fillcam.SetNameTab("Charge"); filltme.SetNameTab("RelTimes"); TString drawoption; if (fDisplayType == kDataCheckDisplay) drawoption += "datacheck"; if (fDisplayType == kFullDisplay) drawoption += " all"; fillcam.SetDrawOption(drawoption.Data()); fillbnd.SetDrawOption(drawoption.Data()); fillpin.SetDrawOption(drawoption.Data()); filltme.SetDrawOption(drawoption.Data()); // // Apply a filter against cosmics // (will have to be needed in the future // when the calibration hardware-trigger is working) // MFCosmics cosmics; MContinue cont(&cosmics); tlist.AddToList(&merge); tlist.AddToList(&apply); MTaskEnv taskenv("ExtractSignal"); taskenv.SetDefault(fExtractor ? fExtractor : &extract2); tlist.AddToList(&taskenv); tlist.AddToList(&pinext); tlist.AddToList(&blindext); MTaskEnv taskenv2("ExtractTime"); taskenv2.SetDefault(fTimeExtractor ? fTimeExtractor : ×pline); if (fRelTimes) tlist.AddToList(&taskenv2); if (fColor == MCalibrationCam::kCT1) tlist.AddToList(&cont); tlist.AddToList(&fillcam); if (fRelTimes) { tlist.AddToList(&filltme); tlist.AddToList(&timecalc); } if (IsUseBlindPixel()) tlist.AddToList(&fillbnd); if (IsUsePINDiode()) tlist.AddToList(&fillpin); tlist.AddToList(&calcalc); // Create and setup the eventloop MEvtLoop evtloop(fName); evtloop.SetParList(&plist); evtloop.SetDisplay(fDisplay); evtloop.SetLogStream(fLog); if (!SetupEnv(evtloop)) return kFALSE; if (!taskenv.GetTask() && !taskenv2.GetTask()) { *fLog << err << "ERROR - Neither ExtractSignal nor ExtractTime initialized or both ''." << endl; return kFALSE; } if (!WriteTasks(taskenv.GetTask(), taskenv2.GetTask())) return kFALSE; // Execute first analysis if (!evtloop.Eventloop()) { *fLog << err << GetDescriptor() << ": Failed." << endl; return kFALSE; } tlist.PrintStatistics(); // // The next lines are necessary in order to avoid that // the last entry drawn by MFillH gets deleted again from // the display. No idea where this comes from... // // FIND THE REASON! THE NEXT CHANGE SOMEBODY DOES MIGHT RESULT // IN __YOUR__ WORKAROUN NOT WORKING IF IT IS NOT CLEANLY DONE! // // THE AUTHOR OF MFILLH SHOULD FIND THE REASON INSTEAD OF DELETING // CODE WITHOUT INFORMING THE DATACHECK PEOPLE - SORRY, I SPENT // TOO MANY DAYS TRYING TO FIND THIS REASON! // if (fDisplay) { if (IsUsePINDiode()) { MHCalibrationChargePINDiode *pin = (MHCalibrationChargePINDiode*)plist.FindObject("MHCalibrationChargePINDiode"); pin->DrawClone(Form("nonew %s",drawoption.Data())); } else if (IsUseBlindPixel()) { MHCalibrationChargeBlindCam *cam = (MHCalibrationChargeBlindCam*)plist.FindObject("MHCalibrationChargeBlindCam"); cam->DrawClone(Form("nonew %s",drawoption.Data())); } else if (fRelTimes) { MHCalibrationRelTimeCam *cam = (MHCalibrationRelTimeCam*)plist.FindObject("MHCalibrationRelTimeCam"); cam->DrawClone(Form("nonew %s",drawoption.Data())); } else { MHCalibrationChargeCam *cam = (MHCalibrationChargeCam*)plist.FindObject("MHCalibrationChargeCam"); cam->DrawClone(Form("nonew %s",drawoption.Data())); } } DisplayResult(plist); if (!WriteResult()) return kFALSE; *fLog << all << GetDescriptor() << ": Done." << endl; return kTRUE; } // -------------------------------------------------------------------------- // // Read the following containers from GetOutputFile() // - MCalibrationChargeCam // - MCalibrationQECam // - MBadPixelsCam // Bool_t MJCalibration::ReadCalibrationCam() { const TString fname = GetOutputFile(); if (gSystem->AccessPathName(fname, kFileExists)) { *fLog << err << "Input file " << fname << " doesn't exist." << endl; return kFALSE; } *fLog << inf << "Reading from file: " << fname << endl; TFile file(fname, "READ"); if (fCalibrationCam.Read()<=0) { *fLog << err << "Unable to read MCalibrationChargeCam from " << fname << endl; return kFALSE; } if (fQECam.Read()<=0) { *fLog << err << "Unable to read MCalibrationQECam from " << fname << endl; return kFALSE; } if (file.FindKey("MCalibrationRelTimeCam")) if (fRelTimeCam.Read()<=0) { *fLog << err << "Unable to read MCalibrationRelTimeCam from " << fname << endl; return kFALSE; } if (file.FindKey("MBadPixelsCam")) { MBadPixelsCam bad; if (bad.Read()<=0) { *fLog << err << "Unable to read MBadPixelsCam from " << fname << endl; return kFALSE; } fBadPixels.Merge(bad); } if (fDisplay /*&& !fDisplay->GetCanvas("Pedestals")*/) // FIXME! fDisplay->Read(); return kTRUE; } // -------------------------------------------------------------------------- // // Set the useage of the Blind Pixel device // void MJCalibration::SetUseBlindPixel(const Bool_t b) { b ? SETBIT(fDevices,kUseBlindPixel) : CLRBIT(fDevices,kUseBlindPixel); } // -------------------------------------------------------------------------- // // Set the useage of the PIN Diode device // void MJCalibration::SetUsePINDiode(const Bool_t b) { b ? SETBIT(fDevices,kUsePINDiode) : CLRBIT(fDevices,kUsePINDiode); } Bool_t MJCalibration::WriteEventloop(MEvtLoop &evtloop) const { if (fPathOut.IsNull()) return kTRUE; const TString oname(GetOutputFile()); *fLog << inf << "Writing to file: " << oname << endl; TFile file(oname, fOverwrite?"RECREATE":"NEW", "File created by MJCalibration", 9); if (!file.IsOpen()) { *fLog << err << "ERROR - Couldn't open file " << oname << " for writing..." << endl; return kFALSE; } if (evtloop.Write(fName)<=0) { *fLog << err << "Unable to write MEvtloop to " << oname << endl; return kFALSE; } return kTRUE; } Bool_t MJCalibration::WriteTasks(MTask *t1, MTask *t2) const { if (fPathOut.IsNull()) return kTRUE; const TString oname(GetOutputFile()); *fLog << inf << "Writing to file: " << oname << endl; TFile file(oname, fOverwrite?"RECREATE":"NEW", "File created by MJCalibration", 9); if (!file.IsOpen()) { *fLog << err << "ERROR - Couldn't open file " << oname << " for writing..." << endl; return kFALSE; } if (t1 && t1->Write()<=0) { *fLog << err << "Unable to write " << t1->GetName() << " to " << oname << endl; return kFALSE; } if (t2 && t2->Write()<=0) { *fLog << err << "Unable to write " << t2->GetName() << " to " << oname << endl; return kFALSE; } return kTRUE; } // -------------------------------------------------------------------------- // // Write the result into the output file GetOutputFile(), if fOutputPath exists. // // The following containers are written: // - MStatusDisplay // - MCalibrationChargeCam // - MCalibrationChargeBlindPix // - MCalibrationQECam // - MBadPixelsCam // Bool_t MJCalibration::WriteResult() { if (fPathOut.IsNull()) return kTRUE; const TString oname(GetOutputFile()); *fLog << inf << "Writing to file: " << oname << endl; TFile file(oname, "UPDATE", "File created by MJCalibration", 9); if (!file.IsOpen()) { *fLog << err << "ERROR - Couldn't open file " << oname << " for writing..." << endl; return kFALSE; } *fLog << inf << " - MStatusDisplay..." << flush; if (fDisplay && fDisplay->Write()<=0) { *fLog << err << "Unable to write MStatusDisplay to " << oname << endl; return kFALSE; } *fLog << inf << "ok." << endl; *fLog << inf << " - MCalibrationChargeCam..." << flush; if (fCalibrationCam.Write()<=0) { *fLog << err << "Unable to write MCalibrationChargeCam to " << oname << endl; return kFALSE; } *fLog << inf << "ok." << endl; *fLog << inf << " - MCalibrationChargeBlindCam..." << flush; if (fCalibrationBlindCam.Write()<=0) { *fLog << err << "Unable to write MCalibrationChargeBlindCam to " << oname << endl; return kFALSE; } *fLog << inf << "ok." << endl; *fLog << inf << " - MCalibrationChargePINDiode..." << flush; if (fCalibrationPINDiode.Write()<=0) { *fLog << err << "Unable to write MCalibrationChargePINDiode to " << oname << endl; return kFALSE; } *fLog << inf << "ok." << endl; *fLog << inf << " - MCalibrationQECam..." << flush; if (fQECam.Write()<=0) { *fLog << err << "Unable to write MCalibrationQECam to " << oname << endl; return kFALSE; } *fLog << inf << "ok." << endl; *fLog << inf << " - MBadPixelsCam..." << flush; if (fBadPixels.Write()<=0) { *fLog << err << "Unable to write MBadPixelsCam to " << oname << endl; return kFALSE; } *fLog << inf << "ok." << endl; if (fRelTimes) { *fLog << inf << " - MCalibrationRelTimeCam..." << flush; if (fRelTimeCam.Write()<=0) { *fLog << err << "Unable to write MCalibrationRelTimeCam to " << oname << endl; return kFALSE; } *fLog << inf << "ok." << endl; } return kTRUE; } void MJCalibration::DisplayDoubleProject(MHCamera *cam, const char* whatsmall, const char* whatbig) const { TArrayI inner(1); inner[0] = 0; TArrayI outer(1); outer[0] = 1; TArrayI s0(6); s0[0] = 6; s0[1] = 1; s0[2] = 2; s0[3] = 3; s0[4] = 4; s0[5] = 5; TArrayI s1(3); s1[0] = 6; s1[1] = 1; s1[2] = 2; TArrayI s2(3); s2[0] = 3; s2[1] = 4; s2[2] = 5; TVirtualPad *pad = gPad; pad->Divide(2,1); TH1D *inout[2]; inout[0] = cam->ProjectionS(s0, inner, "Inner"); inout[1] = cam->ProjectionS(s0, outer, "Outer"); FixDataCheckHist(inout[0]); FixDataCheckHist(inout[1]); inout[0]->SetTitle(Form("%s %s",cam->GetTitle(),"Inner")); inout[1]->SetTitle(Form("%s %s",cam->GetTitle(),"Outer")); for (int i=0; i<2; i++) { pad->cd(i+1); gPad->SetBorderMode(0); gPad->SetTicks(); inout[i]->SetDirectory(NULL); inout[i]->SetLineColor(kRed+i); inout[i]->SetBit(kCanDelete); inout[i]->Draw(); inout[i]->Fit("gaus", "Q"); gPad->Modified(); gPad->Update(); TPaveStats *st = (TPaveStats*)inout[i]->GetListOfFunctions()->FindObject("stats"); st->SetY1NDC(0.6); st->SetY2NDC(0.9); st->SetX1NDC(0.55); st->SetX2NDC(0.99); gPad->Modified(); gPad->Update(); TLegend *leg2 = new TLegend(0.55,0.4,0.99,0.6); // // Display the outliers as dead and noisy pixels // DisplayOutliers(inout[i],whatsmall,whatbig); // // Display the two half of the camera separately // TH1D *half[2]; half[0] = cam->ProjectionS(s1, i==0 ? inner : outer , "Sector 6-1-2"); half[1] = cam->ProjectionS(s2, i==0 ? inner : outer , "Sector 3-4-5"); for (int j=0; j<2; j++) { half[j]->SetLineColor(kRed+i+2*j+1); half[j]->SetDirectory(NULL); half[j]->SetBit(kCanDelete); half[j]->Draw("same"); leg2->AddEntry(half[j], half[j]->GetName(), "l"); } leg2->Draw(); } }