/* ======================================================================== *\ ! ! * ! * 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, 09/2002 ! Abelardo Moralejo, 03/2003 ! Wolfgang Wittek, 04/2003 ! ! Copyright: MAGIC Software Development, 2000-2003 ! ! \* ======================================================================== */ // //------------------------------------------------------------------------ // // fcn calculates the function to be minimized (using TMinuit::Migrad) // void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag) { MEvtLoop *evtloop = (MEvtLoop*)gMinuit->GetObjectFit(); MTaskList *tlist = (MTaskList*)evtloop->GetParList()->FindObject("MTaskList"); // GetTaskList(); MChisqEval *eval = (MChisqEval*) tlist->FindObject("MChisqEval"); MEnergyEstParam *eest = (MEnergyEstParam*)tlist->FindObject("MEnergyEstParam"); eest->SetCoeff(TArrayD(eest->GetNumCoeff(), par)); evtloop->Eventloop(); f = eval->GetChisq(); } //------------------------------------------------------------------------ void CT1EgyEst() { TString inPath = "~magican/ct1test/wittek/marsoutput/optionA/"; TString fileNameIn = "MC2.root"; TString outPath = "~magican/ct1test/wittek/marsoutput/optionA/"; TString energyParName = "energyest.root"; TString hilName = "MHillas"; TString hilSrcName = "MHillasSrc"; TString hadronnessName = "MHadronness"; Int_t howMany = 2200; Float_t maxhadronness = 0.4; Float_t maxalpha = 20.0; CT1EEst(inPath, fileNameIn, outPath, energyParName, hilName, hilSrcName, hadronnessName, howMany, maxhadronness, maxalpha); } //------------------------------------------------------------------------ // // Arguments of CT1EEst : // ------------------------ // // inPath, fileNameIn path and name of input file (MC gamma events) // outPath, energyParName path and name of file containing the parameters // of the energy estimator // hilName, hilSrcName names of "MHillas" and "MHillasSrc" containers // hadronnessName name of container holding the hadronness // howMany no.of events to be read from input file // maxhadronness maximum value of hadronness to be accepted // maxalpha maximum value of |ALPHA| to be accepted // void CT1EEst(TString inPath, TString fileNameIn, TString outPath, TString energyParName, TString hilName, TString hilSrcName, TString hadronnessName, Int_t howMany, Float_t maxhadronness, Float_t maxalpha) { cout << "================================================================" << endl; cout << "Start of energy estimation part" << endl; cout << "" << endl; cout << "CT1EEst input values : " << endl; cout << "---------------------- " << endl; cout << "inPath, fileNameIn = " << inPath << ", " << fileNameIn << endl; cout << "outPath, energyParName = " << outPath << ", " << energyParName << endl; cout << "hilName, hilSrcName, hadronnessName = " << hilName << ", " << hilSrcName << ", " << hadronnessName << endl; cout << "howMany, maxhadronness, maxalpha = " << howMany << ", " << maxhadronness << ", " << maxalpha << endl; cout << "" << endl; // convert from [deg] to [mm] // MGeomCamCT1 gct1; //maxdist /= gct1.GetConvMm2Deg(); //========================================================================== // Start of Part 1 (determination of the parameters of the energy estimator) // //----------------------------------------------------------------------- // Fill events into a MHMatrix, // to be used later in the minimization by MINUIT // MParList parlist; TString inputfile(outPath); inputfile += fileNameIn; MFEventSelector selector; selector.SetNumSelectEvts(howMany); cout << "Read events from file '" << inputfile << "'" << endl; MReadTree read("Events"); read.AddFile(inputfile); read.DisableAutoScheme(); read.SetSelector(&selector); MFCT1SelFinal filterhadrons; filterhadrons.SetCuts(maxhadronness, maxalpha); filterhadrons.SetHadronnessName(hadronnessName); filterhadrons.SetInverted(); cout << "Define columns of matrix" << endl; MHMatrix matrix; Int_t colenergy = matrix.AddColumn("MMcEvt.fEnergy"); Int_t colimpact = matrix.AddColumn("MMcEvt.fImpact"); if (colenergy < 0 || colimpact < 0) { cout << "colenergy, colimpact = " << colenergy << ", " << colimpact << endl; return; } MEnergyEstParam eest(hilName); eest.Add(hilSrcName); eest.InitMapping(&matrix); cout << "--------------------------------------" << endl; cout << "Fill events into the matrix" << endl; if ( !matrix.Fill(&parlist, &read, &filterhadrons) ) return; cout << "Matrix was filled with " << matrix.GetNumRows() << " events" << endl; //----------------------------------------------------------------------- // // Setup the eventloop which will be executed in the fcn of MINUIT // cout << "--------------------------------------" << endl; cout << "Setup event loop to be used in 'fcn'" << endl; MParList parlist; MTaskList tasklist; MMatrixLoop loop(&matrix); MChisqEval eval; eval.SetY1(new MDataElement(&matrix, colenergy)); eval.SetY2(new MDataMember("MEnergyEst.fEnergy")); eval.SetOwner(); //******************************** // Entries in MParList parlist.AddToList(&tasklist); //******************************** // Entries in MTaskList tasklist.AddToList(&loop); tasklist.AddToList(&eest); tasklist.AddToList(&eval); //******************************** cout << "Event loop was setup" << endl; MEvtLoop evtloop; evtloop.SetParList(&parlist); //.......................................................................... //---------- Start of minimization part -------------------- // // Do the minimization with MINUIT // // Be careful: This is not thread safe // cout << "--------------------------------------" << endl; cout << "Start minimization" << endl; TMinuit minuit(12); minuit.SetPrintLevel(-1); minuit.SetFCN(fcn); // Ready for: minuit.mnexcm("SET ERR", arglist, 1, ierflg) if (minuit.SetErrorDef(1)) { cout << "SetErrorDef failed." << endl; return; } // // Set initial values of the parameters (close enough to the final ones, taken // from previous runs of the procedure). Parameter fA[4] is not used in the default // energy estimation model (from D. Kranich). // TArrayD fA(5); TArrayD fB(7); fA[0] = 21006.2; fA[1] = -43.2648; fA[2] = -690.403; fA[3] = -0.0428544; fA[4] = 1.; fB[0] = -3391.05; fB[1] = 136.58; fB[2] = 0.253807; fB[3] = 254.363; fB[4] = 61.0386; fB[5] = -0.0190984; fB[6] = -421695; // // Set starting values and step sizes for parameters // for (Int_t i=0; iWrite("EnergyParams"); outfile.Close(); cout << "--------------------------------------" << endl; cout << "Write parameters of energy estimator onto file '" << paramout << endl; cout << "--------------------------------------" << endl; // // End of Part 1 (determination of the parameters of the energy estimator) //========================================================================= //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //========================================================================== // Start of Part 2 (test quality of energy estimation) // // //-------------------------------------------- // Read the parameters of the energy estimator // TString paramin(outPath); paramin += energyParName; cout << "--------------------------------------" << endl; cout << "Read parameters of energy estimator from file '" << paramin << endl; TFile enparam(paramin); //======================================================================= // Setup the event loop // cout << "--------------------------------------" << endl; cout << "Setup event loop for checking quality of energy estimation" << endl; MTaskList tlist2; MParList parlist2; //----------------------------------------------- // Read events // TString inputfile(inPath); inputfile += fileNameIn; cout << "Read events from file '" << inputfile << "'" << endl; MReadTree read2("Events"); read2.AddFile(inputfile); read2.DisableAutoScheme(); //----------------------------------------------- // Select events // cout << "Select events with hadronness < " << maxhadronness << " and |alpha| < " << maxalpha << endl; MFCT1SelFinal hcut2; hcut2.SetCuts(maxhadronness, maxalpha); hcut2.SetHadronnessName(hadronnessName); MContinue cont(&hcut2); //----------------------------------------------- // Create some histograms to display the results // MH3 mh3ed ("log10(MMcEvt.fEnergy)", "MEnergyEst.fEnergy/MMcEvt.fEnergy-1.0"); MH3 mh3ed2("log10(MEnergyEst.fEnergy)", "MEnergyEst.fEnergy/MMcEvt.fEnergy-1.0"); MH3 mhe ("log10(MMcEvt.fEnergy)", "log10(MEnergyEst.fEnergy)"); mhe.SetName("HistEE"); mh3ed.SetName("HistEnergyDelta"); mh3ed2.SetName("HistEnergyDelta"); MBinning binsedx("BinningHistEnergyDeltaX"); MBinning binsedy("BinningHistEnergyDeltaY"); MBinning binseex("BinningHistEEX"); MBinning binseey("BinningHistEEY"); binsedx.SetEdges(35, 2.0, 5.5); binsedy.SetEdges(40,-1.5, 2.5); binseex.SetEdges(35, 2.0, 5.5); binseey.SetEdges(35, 2.0, 5.5); MFillH hfilled(&mh3ed); MFillH hfilled2(&mh3ed2); MFillH hfillee(&mhe); //----------------------------------------------- // Create energy estimator task, add necessary containers and // initialize parameters read from file: // MEnergyEstParam eest2(hilName); eest2.Add(hilSrcName); TArrayD parA(5); TArrayD parB(7); for (Int_t i=0; iGetXaxis()->SetTitle("log_{10} E_{MC} (GeV)"); mhe.GetHist()->GetYaxis()->SetTitle("log_{10} E_{EST} (GeV)"); mhe.GetHist()->GetXaxis()->SetTitleOffset(1.2); TCanvas *c = new TCanvas("energy","CT1 Energy estimation"); c->Divide(2,2); c->cd(1); energy_1->SetBottomMargin(0.12); mhe.DrawClone("PROFXnonew"); mh3ed.GetHist()->GetXaxis()->SetTitle("log_{10} E_{MC} (GeV)"); mh3ed.GetHist()->GetYaxis()->SetTitle("\\frac{E_{EST} - E_{MC}}{E_{MC}}"); mh3ed.GetHist()->GetXaxis()->SetTitleOffset(1.2); mh3ed.GetHist()->GetYaxis()->SetTitleOffset(1.5); c->cd(2); energy_2->SetLeftMargin(0.15); energy_2->SetBottomMargin(0.12); mh3ed.DrawClone("PROFXnonew"); mh3ed2.GetHist()->GetXaxis()->SetTitle("log_{10} E_{EST} (GeV)"); mh3ed2.GetHist()->GetYaxis()->SetTitle("\\frac{E_{EST} - E_{MC}}{E_{MC}}"); mh3ed2.GetHist()->GetXaxis()->SetTitleOffset(1.2); mh3ed2.GetHist()->GetYaxis()->SetTitleOffset(1.5); c->cd(3); energy_3->SetLeftMargin(0.15); energy_3->SetBottomMargin(0.12); mh3ed2.DrawClone("PROFXnonew"); ((TH2*)mh3ed2.GetHist())->ProjectionY("deltae"); c->cd(4); energy_4->SetLeftMargin(0.1); energy_4->SetRightMargin(0.05); energy_4->SetBottomMargin(0.12); deltae.GetXaxis()->SetTitleOffset(1.2); deltae.GetXaxis()->SetTitle("(E_{EST} - E_{MC}) / E_{MC}"); deltae.Draw("e"); //------------------------------------------- // // include the histograms // into the root file containing the parameters of the energy estimator // TString paramout(outPath); paramout += energyParName; TFile out2(paramout, "UPDATE"); ((TH2*)mh3ed.GetHist())->Write("mh3ed"); ((TH2*)mh3ed2.GetHist())->Write("mh3ed2"); ((TH2*)mhe.GetHist())->Write("mhe"); deltae.Write(); out2.Close(); cout << "Quality histograms were added onto the file '" << paramout << endl; cout << "" << endl; cout << "End of energy estimation part" << endl; cout << "================================================================" << endl; // // End of Part 2 (test quality of energy estimation) //========================================================================== return; } //============================================================================