/* ======================================================================== *\ ! ! * ! * 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/2009 ! ! Copyright: MAGIC Software Development, 2000-2009 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MJSimulation // // // Force reading a corsika file even if the footer (RUNE-section) is missing // by setting fForceMode to kTRUE or from the resource file by // // ForceMode: Yes // // // To switch off the simulation of the camera electronics, use: // // Camera: Off // // Note, that the border of the camera and the propertied of the cones // are still simulated (simply because it is fast). Furthermore, this // switches off the trigger for the output, i.e. all data which deposits // at least one photon in at least one pixel is written to the output file. // // // In case of a pedestal or calibration run the artificial trigger can // be "switched off" and the cosmics trrigger "switched on" by setting // fForceTrigger to kTRUE or from the resource file by // // ForceTrigger: Yes // // ///////////////////////////////////////////////////////////////////////////// #include "MJSimulation.h" #include #include // Core #include "MLog.h" #include "MLogManip.h" #include "MArgs.h" #include "MDirIter.h" #include "MParList.h" #include "MTaskList.h" #include "MEvtLoop.h" #include "MStatusDisplay.h" // Tasks #include "MCorsikaRead.h" #include "MContinue.h" #include "MFillH.h" #include "MGeomApply.h" #include "MParameterCalc.h" #include "MHillasCalc.h" #include "MImgCleanStd.h" #include "MWriteRootFile.h" #include "MWriteFitsFile.h" #include "MSimMMCS.h" #include "MSimAbsorption.h" #include "MSimAtmosphere.h" #include "MSimReflector.h" #include "MSimPointingPos.h" #include "MSimPSF.h" #include "MSimGeomCam.h" #include "MSimSignalCam.h" #include "MSimAPD.h" #include "MSimExcessNoise.h" #include "MSimCamera.h" #include "MSimTrigger.h" #include "MSimReadout.h" #include "MSimRandomPhotons.h" #include "MSimBundlePhotons.h" #include "MSimCalibrationSignal.h" // Histograms #include "MBinning.h" #include "MHn.h" #include "MHCamera.h" #include "MHCamEvent.h" #include "MHPhotonEvent.h" // Container #include "MRawRunHeader.h" #include "MParameters.h" #include "MReflector.h" #include "MParEnv.h" #include "MSpline3.h" #include "MParSpline.h" #include "MGeomCam.h" #include "MPedestalCam.h" #include "MPedestalPix.h" ClassImp(MJSimulation); using namespace std; // -------------------------------------------------------------------------- // // Default constructor. // // Sets fRuns to 0, fExtractor to NULL, fDataCheck to kFALSE // MJSimulation::MJSimulation(const char *name, const char *title) : fForceMode(kFALSE), fCamera(kTRUE), fForceTrigger(kFALSE), fWriteFitsFile(kFALSE), fOperationMode(kModeData), fRunNumber(-1) { fName = name ? name : "MJSimulation"; fTitle = title ? title : "Standard analysis and reconstruction"; } Bool_t MJSimulation::CheckEnvLocal() { fForceMode = GetEnv("ForceMode", fForceMode); fForceTrigger = GetEnv("ForceTrigger", fForceTrigger); fCamera = GetEnv("Camera", fCamera); return kTRUE; } /* TString MJSimulation::GetOutFile(const MSequence &seq) const { return seq.IsValid() ? Form("ceres%08d.root", seq.GetSequence()) : "ceres.root"; } */ Bool_t MJSimulation::WriteResult(const MParList &plist, const MSequence &seq, Int_t num) { if (fPathOut.IsNull()) { *fLog << inf << "No output path specified via SetPathOut - no output written." << endl; return kTRUE; } TObjArray cont; cont.Add(const_cast(GetEnv())); if (seq.IsValid()) cont.Add(const_cast(&seq)); cont.Add(plist.FindObject("PulseShape")); cont.Add(plist.FindObject("Reflector")); cont.Add(plist.FindObject("MGeomCam")); cont.Add(plist.FindObject("GeomCones")); TNamed cmdline("CommandLine", fCommandLine.Data()); cont.Add(&cmdline); if (fDisplay) { TString title = "-- Ceres"; if (seq.IsValid()) { title += ": "; title += seq.GetSequence(); } title += " --"; fDisplay->SetTitle("Ceres", kFALSE); cont.Add(fDisplay); } const TString name = Form("ceres%08d.root", num); return WriteContainer(cont, name, "RECREATE"); } void MJSimulation::SetupHist(MHn &hist) const { hist.AddHist("MCorsikaEvtHeader.fTotalEnergy"); hist.InitName("Energy"); hist.InitTitle("Energy;E [GeV]"); hist.SetLog(kTRUE, kTRUE, kFALSE); hist.AddHist("MPhotonEvent.GetNumExternal"); hist.InitName("Size"); hist.InitTitle("Size;S [#]"); hist.SetLog(kTRUE, kTRUE, kFALSE); /* hist.AddHist("-MCorsikaEvtHeader.fX/100","-MCorsikaEvtHeader.fY/100"); hist.SetDrawOption("colz"); hist.InitName("Impact;Impact;Impact"); hist.InitTitle("Impact;West <--> East [m];South <--> North [m]"); hist.SetAutoRange(); */ hist.AddHist("MCorsikaEvtHeader.GetImpact/100"); hist.InitName("Impact"); hist.InitTitle("Impact;Impact [m]"); hist.SetAutoRange(); hist.AddHist("MCorsikaEvtHeader.fFirstInteractionHeight/100000"); hist.InitName("Height"); hist.InitTitle("FirstInteractionHeight;h [km]"); hist.AddHist("(MCorsikaEvtHeader.fAz+MCorsikaRunHeader.fMagneticFieldAz)*TMath::RadToDeg()", "MCorsikaEvtHeader.fZd*TMath::RadToDeg()"); hist.InitName("SkyOrigin;Az;Zd"); hist.InitTitle("Sky Origin;Az [\\circ];Zd [\\circ]"); hist.SetDrawOption("colz"); hist.SetAutoRange(); hist.AddHist("IncidentAngle.fVal"); hist.InitName("ViewCone"); hist.InitTitle("Incident Angle;\\alpha [\\circ]"); } void MJSimulation::SetupCommonFileStructure(MWriteRootFile &write) const { // Common run headers write.AddContainer("MMcCorsikaRunHeader", "RunHeaders", kFALSE); write.AddContainer("MCorsikaRunHeader", "RunHeaders", kFALSE); write.AddContainer("MRawRunHeader", "RunHeaders"); write.AddContainer("MGeomCam", "RunHeaders"); write.AddContainer("MMcRunHeader", "RunHeaders"); // Common events write.AddContainer("MCorsikaEvtHeader", "Events", kFALSE); write.AddContainer("MRawEvtHeader", "Events"); write.AddContainer("MMcEvt", "Events"); write.AddContainer("IncidentAngle", "Events", kFALSE); } //FIXME Etienne. I'm doing the same for fits and root. I probably should adapt somehow void MJSimulation::SetupCommonFileStructure(MWriteFitsFile& write) const { // Common run headers write.AddContainer("MMcCorsikaRunHeader", "RunHeaders", kFALSE); write.AddContainer("MCorsikaRunHeader", "RunHeaders", kFALSE); write.AddContainer("MRawRunHeader", "RunHeaders"); write.AddContainer("MGeomCam", "RunHeaders"); write.AddContainer("MMcRunHeader", "RunHeaders"); // Common events write.AddContainer("MCorsikaEvtHeader", "Events", kFALSE); write.AddContainer("MRawEvtHeader", "Events"); write.AddContainer("MMcEvt", "Events"); write.AddContainer("IncidentAngle", "Events", kFALSE); } Bool_t MJSimulation::Process(const MArgs &args, const MSequence &seq) { /* if (!fSequence.IsValid()) { *fLog << err << "ERROR - Sequence invalid!" << endl; return kFALSE; } */ // if (!HasWritePermission(CombinePath(fPathOut, GetOutFile(seq)))) // return kFALSE; *fLog << inf; fLog->Separator(GetDescriptor()); if (!CheckEnv()) return kFALSE; if (seq.IsValid()) *fLog << fSequence.GetFileName() << endl; else *fLog << "Input: " << args.GetNumArguments() << "-files" << endl; *fLog << endl; MDirIter iter; if (seq.IsValid() && seq.GetRuns(iter, MSequence::kCorsika)<=0) { *fLog << err << "ERROR - Sequence valid but without files." << endl; return kFALSE; } // -------------------------------------------------------------------------------- // Setup Parlist MParList plist; plist.AddToList(this); // take care of fDisplay! // setup TaskList MTaskList tasks; plist.AddToList(&tasks); // -------------------------------------------------------------------------------- // FIXME: Allow empty GeomCones! MParEnv env0("Reflector"); MParEnv env1("GeomCones"); MParEnv env2("MGeomCam"); env0.SetClassName("MReflector"); env1.SetClassName("MGeomCam"); env2.SetClassName("MGeomCam"); plist.AddToList(&env0); plist.AddToList(&env1); plist.AddToList(&env2); plist.FindCreateObj("MPedPhotCam", "MPedPhotFromExtractorRndm"); MParSpline shape("PulseShape"); plist.AddToList(&shape); // *** FIXME *** FIXME *** FIXME *** plist.FindCreateObj("MMcRunHeader"); MRawRunHeader header; header.SetValidMagicNumber(); //header.InitFadcType(3); switch (fOperationMode) { case kModeData: header.SetRunType(MRawRunHeader::kRTMonteCarlo|MRawRunHeader::kRTData); header.SetRunInfo(0, fRunNumber<0 ? 3 : fRunNumber); break; case kModePed: header.SetRunType(MRawRunHeader::kRTMonteCarlo|MRawRunHeader::kRTPedestal); header.SetSourceInfo("Pedestal"); header.SetRunInfo(0, fRunNumber<0 ? 1 : fRunNumber); break; case kModeCal: header.SetRunType(MRawRunHeader::kRTMonteCarlo|MRawRunHeader::kRTCalibration); header.SetSourceInfo("Calibration"); header.SetRunInfo(0, fRunNumber<0 ? 2 : fRunNumber); break; case kModePointRun: header.SetRunType(MRawRunHeader::kRTMonteCarlo|MRawRunHeader::kRTPointRun); header.SetRunInfo(0, fRunNumber<0 ? 0 : fRunNumber); break; } // FIXME: Move to MSimPointingPos, MSimCalibrationSignal // Can we use this as input for MSimPointingPos? header.SetObservation("On", "MonteCarlo"); plist.AddToList(&header); // ++++++++ FIXME FIXME FIXME +++++++++++++ /* MPedestalCam pedcam; pedcam.Init(geomcam.GetNumPixels()); for (UInt_t i=0; i(write3af) : static_cast(write3ar); write3af.SetHeaderKey("DUMMY0", 3, "First dummy"); write3af.SetHeaderKey("DUMMY1", 3.14159265358979323846, "Second dummy"); write3af.SetHeaderKey("DUMMY2", true, "Third dummy"); write3af.SetHeaderKey("DUMMY3", "one value", "Fourth dummy"); write3af.VetoColumn("MParameterD.fVal"); write3af.VetoColumn("MCorsikaEvtHeader.fEvtNumber"); write3af.VetoColumn("MCorsikaEvtHeader.fNumReuse"); write3af.VetoColumn("MCorsikaEvtHeader.fTotalEnergy"); write3af.VetoColumn("MCorsikaEvtHeader.fStartAltitude"); write3af.VetoColumn("MCorsikaEvtHeader.fFirstTargetNum"); write3af.VetoColumn("MCorsikaEvtHeader.fFirstInteractionHeight"); write3af.VetoColumn("MCorsikaEvtHeader.fMomentumX"); write3af.VetoColumn("MCorsikaEvtHeader.fMomentumY"); write3af.VetoColumn("MCorsikaEvtHeader.fMomentumZ"); write3af.VetoColumn("MCorsikaEvtHeader.fAz"); write3af.VetoColumn("MCorsikaEvtHeader.fWeightedNumPhotons"); write3af.VetoColumn("MCorsikaEvtHeader.fZd"); write3af.VetoColumn("MCorsikaEvtHeader.fAd"); write3af.VetoColumn("MCorsikaEvtHeader.fX"); write3af.VetoColumn("MCorsikaEvtHeader.fY"); write3af.VetoColumn("MCorsikaEvtHeader.fWeightNumPhotons"); write3af.VetoColumn("MMcEvt.fEvtNumber"); write3af.VetoColumn("MMcEvt.fThick0"); write3af.VetoColumn("MMcEvt.fFirstTarget"); write3af.VetoColumn("MMcEvt.fZFirstInteraction"); write3af.VetoColumn("MMcEvt.fCoreD"); write3af.VetoColumn("MMcEvt.fCoreX"); write3af.VetoColumn("MMcEvt.fCoreY"); write3af.VetoColumn("MMcEvt.fTimeFirst"); write3af.VetoColumn("MMcEvt.fTimeLast"); write3af.VetoColumn("MMcEvt.fLongiNmax"); write3af.VetoColumn("MMcEvt.fLongit0"); write3af.VetoColumn("MMcEvt.fLongitmax"); write3af.VetoColumn("MMcEvt.fLongia"); write3af.VetoColumn("MMcEvt.fLongib"); write3af.VetoColumn("MMcEvt.fLongic"); write3af.VetoColumn("MMcEvt.fLongichi2"); write3af.VetoColumn("MMcEvt.fPhotIni"); write3af.VetoColumn("MMcEvt.fPassPhotAtm"); write3af.VetoColumn("MMcEvt.fPassPhotRef"); write3af.VetoColumn("MMcEvt.fPassPhotCone"); write3af.VetoColumn("MMcEvt.fPhotElfromShower"); write3af.VetoColumn("MMcEvt.fPhotElinCamera"); write3af.VetoColumn("MMcEvt.fElecCphFraction"); write3af.VetoColumn("MMcEvt.fMuonCphFraction"); write3af.VetoColumn("MMcEvt.fOtherCphFraction"); write3af.VetoColumn("MMcEvt.fFadcTimeJitter"); write3af.VetoColumn("MMcEvt.fEventReuse"); write3af.VetoColumn("MRawEvtData.fHiGainPixId"); write3af.VetoColumn("MRawEvtData.fLoGainPixId"); write3af.VetoColumn("MRawEvtData.fLoGainFadcSamples"); write3af.VetoColumn("MRawEvtData.fABFlags"); write3af.VetoColumn("MRawEvtData.fStartCells"); write3af.VetoColumn("MRawEvtData.fNumBytesPerSample"); write3af.VetoColumn("MRawEvtData.fIsSigned"); write3af.VetoColumn("MRawEvtHeader.fDAQEvtNumber"); //EventNum ? write3af.VetoColumn("MRawEvtHeader.fNumTrigLvl1"); write3af.VetoColumn("MRawEvtHeader.fNumTrigLvl2"); write3af.VetoColumn("MRawEvtHeader.fTrigPattern"); write3af.VetoColumn("MRawEvtHeader.fNumLoGainOn"); write3af.SetBytesPerSample("Data", 2); write1a.SetName("WriteRefData"); write1b.SetName("WriteRefMC"); write2a.SetName("WriteSigData"); write2b.SetName("WriteSigMC"); write3a.SetName("WriteCamData"); write3b.SetName("WriteCamMC"); write4a.SetName("WriteImgData"); write4b.SetName("WriteImgMC"); SetupCommonFileStructure(write1a); SetupCommonFileStructure(write2a); SetupCommonFileStructure(write3ar); SetupCommonFileStructure(write3af); SetupCommonFileStructure(write4a); // R: Dedicated file structure write1a.AddContainer("MPhotonEvent", "Events"); // Y: Dedicated file structure write2a.AddContainer("MPedPhotFromExtractorRndm", "RunHeaders"); // FIXME: Needed for the signal files to be display in MARS write2a.AddContainer("MSignalCam", "Events"); // D: Dedicated file structure write3af.AddContainer("ElectronicNoise", "RunHeaders"); write3af.AddContainer("IntendedPulsePos", "RunHeaders"); write3af.AddContainer("MRawEvtData", "Events"); write3ar.AddContainer("ElectronicNoise", "RunHeaders"); write3ar.AddContainer("IntendedPulsePos", "RunHeaders"); write3ar.AddContainer("MRawEvtData", "Events"); // It doesn't make much sene to write this information // to the file because the units are internal units not // related to the output samples // if (header.IsDataRun() || fForceTrigger) // write3a.AddContainer("TriggerPos", "Events"); // I: Dedicated file structure write4a.AddContainer("MHillas", "Events"); write4a.AddContainer("MHillasSrc", "Events"); write4a.AddContainer("MImagePar", "Events"); write4a.AddContainer("MNewImagePar", "Events"); // Basic MC data write1b.AddContainer("MMcEvtBasic", "OriginalMC"); write2b.AddContainer("MMcEvtBasic", "OriginalMC"); write3b.AddContainer("MMcEvtBasic", "OriginalMC"); write4b.AddContainer("MMcEvtBasic", "OriginalMC"); // ------------------------------------------------------------------- MGeomApply apply; MSimPSF simpsf; MSimGeomCam simgeom; simgeom.SetNameGeomCam("GeomCones"); MSimCalibrationSignal simcal; simcal.SetNameGeomCam("GeomCones"); // Sky Quality Meter: 21.82M = 2.02e-4cd/m^2 // 1cd = 12.566 lm / 4pi sr // FIXME: Simulate photons before cones and QE! MSimRandomPhotons simnsb; simnsb.SetFreq(5.8, 0.004); // ph/m^2/nm/sr/ns NSB, 4MHz dark count rate simnsb.SetNameGeomCam("GeomCones"); // FIXME: How do we handle star-light? We need the rate but we also // need to process it through the mirror! MSimAPD simapd; simapd.SetNameGeomCam("GeomCones"); MSimExcessNoise simexcnoise; MSimBundlePhotons simsum; MSimSignalCam simsignal; MSimCamera simcam; MSimTrigger simtrig; MSimReadout simdaq; MContinue conttrig("TriggerPos.fVal<0", "ContTrigger"); MParameterD pulpos("IntendedPulsePos"); // FIXME: Set a default which could be 1/3 of the digitization window // pulpos.SetVal(40); // [ns] plist.AddToList(&pulpos); MParameterD trigger("TriggerPos"); trigger.SetVal(0); plist.AddToList(&trigger); // ------------------------------------------------------------------- // Remove isolated pixels MImgCleanStd clean(0, 0); //clean.SetCleanLvl0(0); // The level above which isolated pixels are kept clean.SetCleanRings(0); clean.SetMethod(MImgCleanStd::kAbsolute); //clean.SetNamePedPhotCam("MPedPhotFromExtractorRndm"); MHillasCalc hcalc; hcalc.Disable(MHillasCalc::kCalcConc); MHCamEvent evt0a(/*10*/3, "Signal", "Average signal (absolute);;S [ph]"); MHCamEvent evt0c(/*10*/3, "MaxSignal", "Maximum signal (absolute);;S [ph]"); MHCamEvent evt0d(/*11*/8, "ArrTm", "Time after first photon;;T [ns]"); evt0a.SetErrorSpread(kFALSE); evt0c.SetCollectMax(); MContinue cut("", "Cut"); MFillH fillx0a(&evt0a, "MSignalCam", "FillAvgSignal"); MFillH fillx0c(&evt0c, "MSignalCam", "FillMaxSignal"); MFillH fillx0d(&evt0d, "MSignalCam", "FillArrTm"); MFillH fillx1("MHHillas", "MHillas", "FillHillas"); MFillH fillx3("MHHillasSrc", "MHillasSrc", "FillHillasSrc"); MFillH fillx4("MHNewImagePar", "MNewImagePar", "FillNewImagePar"); MFillH fillth("MHThreshold", "", "FillThreshold"); MFillH fillca("MHCollectionArea", "", "FillTrigArea"); fillth.SetNameTab("Threshold"); fillca.SetNameTab("TrigArea"); // ------------------------------------------------------------------- if (header.IsDataRun()) { tasks.AddToList(&read); tasks.AddToList(&precut); tasks.AddToList(&pointing); tasks.AddToList(&simmmcs); if (!fPathOut.IsNull() && !HasNullOut()) { //tasks.AddToList(&write1b); tasks.AddToList(&write2b); if (fCamera) tasks.AddToList(&write3b); if (header.IsDataRun()) tasks.AddToList(&write4b); } // if (header.IsPointRun()) // tasks.AddToList(&stars); if (1) tasks.AddToList(&simatm); // Here because before fillh1 tasks.AddToList(&calcangle); tasks.AddToList(&fillh1); tasks.AddToList(&fillG); if (!header.IsPointRun()) { tasks.AddToList(&absapd); tasks.AddToList(&absmir); if (0) tasks.AddToList(&simatm); // FASTER? } tasks.AddToList(&reflect); if (!header.IsPointRun()) { tasks.AddToList(&fill0); //tasks.AddToList(&fill1); tasks.AddToList(&fill2); tasks.AddToList(&fill3); tasks.AddToList(&fill4); tasks.AddToList(&fillF1); } tasks.AddToList(&cones); tasks.AddToList(&cones2); //if (header.IsPointRun()) // tasks.AddToList(&fillP); tasks.AddToList(&cont1); } // ------------------------------- tasks.AddToList(&apply); if (header.IsDataRun()) { tasks.AddToList(&simpsf); tasks.AddToList(&simgeom); tasks.AddToList(&cont2); if (!header.IsPointRun()) { tasks.AddToList(&fillF2); tasks.AddToList(&fillh2); } tasks.AddToList(&cont3); } if (fCamera) { if (header.IsPedestalRun() || header.IsCalibrationRun()) tasks.AddToList(&simcal); tasks.AddToList(&simnsb); tasks.AddToList(&simapd); tasks.AddToList(&simexcnoise); } tasks.AddToList(&simsum); if (fCamera) { tasks.AddToList(&simcam); if (header.IsDataRun() || fForceTrigger) tasks.AddToList(&simtrig); tasks.AddToList(&conttrig); tasks.AddToList(&simdaq); } tasks.AddToList(&simsignal); // What do we do if signal<0? if (!fPathOut.IsNull() && !HasNullOut()) { //tasks.AddToList(&write1a); if (!header.IsPedestalRun()) tasks.AddToList(&write2a); if (fCamera) tasks.AddToList(&write3a); } // ------------------------------- if (fCamera) { // FIXME: MHCollectionArea Trigger Area! if (header.IsDataRun()) tasks.AddToList(&fillh3); tasks.AddToList(&filltp); } if (header.IsDataRun()) { tasks.AddToList(&fillew); tasks.AddToList(&filled); } if (!header.IsPedestalRun()) { tasks.AddToList(&fillx0a); tasks.AddToList(&fillx0c); } if (header.IsDataRun()) { tasks.AddToList(&clean); tasks.AddToList(&hcalc); tasks.AddToList(&cut); tasks.AddToList(&fillx0d); tasks.AddToList(&fillx1); //tasks.AddToList(&fillx2); tasks.AddToList(&fillx3); tasks.AddToList(&fillx4); if (!HasNullOut()) tasks.AddToList(&write4a); //tasks.AddToList(&fillx5); tasks.AddToList(&fillh4); tasks.AddToList(&fillth); tasks.AddToList(&fillca); } //------------------------------------------- tasks.SetAccelerator(MTask::kAccDontReset|MTask::kAccDontTime); // Create and setup the eventloop MEvtLoop evtloop(fName); evtloop.SetParList(&plist); evtloop.SetDisplay(fDisplay); evtloop.SetLogStream(&gLog); if (!SetupEnv(evtloop)) return kFALSE; // FIXME: If pedestal file given use the values from this file //------------------------------------------- MGeomCam *cam = static_cast(env2.GetCont()); if (binstr.IsDefault()) binstr.SetEdgesLin(150, -shape.GetWidth(), header.GetFreqSampling()/1000.*header.GetNumSamples()+shape.GetWidth()); if (binsd.IsDefault() && cam) binsd.SetEdgesLin(100, 0, cam->GetMaxRadius()*cam->GetConvMm2Deg()); if (binsd0.IsDefault() && cam) binsd0.SetEdgesLin(100, 0, cam->GetMaxRadius()*cam->GetConvMm2Deg()); header.Print(); // FIXME: Display acceptance curves! if (fDisplay) { TCanvas &c = fDisplay->AddTab("Info"); c.Divide(2,2); c.cd(1); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); shape.DrawClone()->SetBit(kCanDelete); if (env0.GetCont() && (header.IsDataRun() || header.IsPointRun())) { c.cd(3); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); static_cast(env0.GetCont())->DrawClone("line")->SetBit(kCanDelete); } if (fCamera) { if (env1.GetCont()) { c.cd(2); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); MHCamera *c = new MHCamera(static_cast(*env1.GetCont())); c->SetStats(kFALSE); c->SetBit(MHCamera::kNoLegend); c->SetBit(kCanDelete); c->Draw(); } if (cam) { c.cd(4); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); MHCamera *c = new MHCamera(*cam); c->SetStats(kFALSE); c->SetBit(MHCamera::kNoLegend); c->SetBit(kCanDelete); c->Draw(); } } TCanvas &d = fDisplay->AddTab("Info2"); d.Divide(2,3); d.cd(1); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); splinepde.DrawClone()->SetBit(kCanDelete); d.cd(3); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); splinecones2.DrawClone()->SetBit(kCanDelete); d.cd(5); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); splinemirror.DrawClone()->SetBit(kCanDelete); d.cd(2); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); splinecones.DrawClone()->SetBit(kCanDelete); //splinecones2.DrawClone("same")->SetBit(kCanDelete); d.cd(6); gPad->SetBorderMode(0); gPad->SetFrameBorderMode(0); gPad->SetGridx(); gPad->SetGridy(); gROOT->SetSelectedPad(0); MParSpline *all = (MParSpline*)splinepde.DrawClone(); //all->SetTitle("Combined acceptance"); all->SetBit(kCanDelete); if (splinemirror.GetSpline()) all->Multiply(*splinemirror.GetSpline()); if (splinecones2.GetSpline()) all->Multiply(*splinecones2.GetSpline()); } //------------------------------------------- // Execute first analysis if (!evtloop.Eventloop(fMaxEvents)) { gLog << err << GetDescriptor() << ": Failed." << endl; return kFALSE; } //------------------------------------------- // FIXME: Display Spline in tab // FIXME: Display Reflector in tab // FIXME: Display Routing(?) in tab // FIXME: Display Camera(s) in tab //------------------------------------------- if (!WriteResult(plist, seq, header.GetRunNumber())) return kFALSE; *fLog << all << GetDescriptor() << ": Done." << endl << endl << endl;; return kTRUE; }