diff --git a/app/PrepareGENIE.cxx b/app/PrepareGENIE.cxx index 9521eaf..b67d856 100644 --- a/app/PrepareGENIE.cxx +++ b/app/PrepareGENIE.cxx @@ -1,860 +1,942 @@ -#include -#include #include "FitLogger.h" #include "PlotUtils.h" #include "TFile.h" #include "TH1D.h" #include "TTree.h" +#include +#include #ifdef __GENIE_ENABLED__ +#ifdef GENIE_PRE_R3 #include "Conventions/Units.h" #include "GHEP/GHepParticle.h" #include "PDG/PDGUtils.h" +#else +#include "Framework/Conventions/Units.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Framework/ParticleData/PDGUtils.h" +#endif #endif std::string gInputFiles = ""; std::string gOutputFile = ""; std::string gFluxFile = ""; std::string gTarget = ""; double MonoEnergy; int gNEvents = -999; bool IsMonoE = false; void PrintOptions(); -void ParseOptions(int argc, char* argv[]); +void ParseOptions(int argc, char *argv[]); void RunGENIEPrepareMono(std::string input, std::string target, std::string output); void RunGENIEPrepare(std::string input, std::string flux, std::string target, std::string output); -int main(int argc, char* argv[]) { +int main(int argc, char *argv[]) { ParseOptions(argc, argv); if (IsMonoE) { RunGENIEPrepareMono(gInputFiles, gTarget, gOutputFile); } else { RunGENIEPrepare(gInputFiles, gFluxFile, gTarget, gOutputFile); } } void RunGENIEPrepareMono(std::string input, std::string target, std::string output) { - LOG(FIT) << "Running GENIE Prepare in mono energetic with E = " << MonoEnergy << " GeV" << std::endl; + LOG(FIT) << "Running GENIE Prepare in mono energetic with E = " << MonoEnergy + << " GeV" << std::endl; // Setup TTree - TChain* tn = new TChain("gtree"); + TChain *tn = new TChain("gtree"); tn->AddFile(input.c_str()); if (tn->GetFile() == NULL) { tn->Print(); ERROR(FTL, "gtree not located in GENIE file: " << input); THROW("Check your inputs, they may need to be completely regenerated!"); throw; } int nevt = tn->GetEntries(); if (gNEvents != -999) { - LOG(FIT) << "Overriding number of events by user from " << nevt << " to " << gNEvents << std::endl; + LOG(FIT) << "Overriding number of events by user from " << nevt << " to " + << gNEvents << std::endl; nevt = gNEvents; } - NtpMCEventRecord* genientpl = NULL; + NtpMCEventRecord *genientpl = NULL; tn->SetBranchAddress("gmcrec", &genientpl); // Have the TH1D go from MonoEnergy/2 to MonoEnergy/2 - TH1D* fluxhist = new TH1D("flux", "flux", 1000, MonoEnergy/2., MonoEnergy*2.); + TH1D *fluxhist = + new TH1D("flux", "flux", 1000, MonoEnergy / 2., MonoEnergy * 2.); fluxhist->Fill(MonoEnergy); fluxhist->Scale(1, "width"); // Make Event Hist - TH1D* eventhist = (TH1D*)fluxhist->Clone(); + TH1D *eventhist = (TH1D *)fluxhist->Clone(); eventhist->Reset(); - TH1D* xsechist = (TH1D*)eventhist->Clone(); + TH1D *xsechist = (TH1D *)eventhist->Clone(); // Create maps - std::map modexsec; - std::map modecount; + std::map modexsec; + std::map modecount; std::vector genieids; std::vector targetids; std::vector interids; // Loop over all events for (int i = 0; i < nevt; i++) { tn->GetEntry(i); StopTalking(); - EventRecord& event = *(genientpl->event); - GHepParticle* neu = event.Probe(); + EventRecord &event = *(genientpl->event); + GHepParticle *neu = event.Probe(); StartTalking(); // Get XSec From Spline GHepRecord genie_record = static_cast(event); double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2)); // Parse Interaction String std::string mode = genie_record.Summary()->AsString(); std::vector modevec = GeneralUtils::ParseToStr(mode, ";"); std::string targ = (modevec[0] + ";" + modevec[1]); std::string inter = mode; // Fill lists of Unique IDS if (std::find(targetids.begin(), targetids.end(), targ) == targetids.end()) { targetids.push_back(targ); } if (std::find(interids.begin(), interids.end(), inter) == interids.end()) { interids.push_back(inter); } // Create entries Mode Maps if (modexsec.find(mode) == modexsec.end()) { genieids.push_back(mode); - modexsec[mode] = (TH1D*)xsechist->Clone(); - modecount[mode] = (TH1D*)xsechist->Clone(); + modexsec[mode] = (TH1D *)xsechist->Clone(); + modecount[mode] = (TH1D *)xsechist->Clone(); - modexsec[mode]->GetYaxis()->SetTitle("d#sigma/dE_{#nu} #times 10^{-38} (events weighted by #sigma)"); + modexsec[mode]->GetYaxis()->SetTitle( + "d#sigma/dE_{#nu} #times 10^{-38} (events weighted by #sigma)"); modecount[mode]->GetYaxis()->SetTitle("Number of events in file"); } // Fill XSec Histograms modexsec[mode]->Fill(neu->E(), xsec); modecount[mode]->Fill(neu->E()); // Fill total event hist eventhist->Fill(neu->E()); // Clear Event genientpl->Clear(); size_t freq = nevt / 20; if (freq && !(i % freq)) { LOG(FIT) << "Processed " << i << "/" << nevt - << " GENIE events (E: " << neu->E() - << " GeV, xsec: " << xsec << " E-38 cm^2/nucleon)" << std::endl; + << " GENIE events (E: " << neu->E() << " GeV, xsec: " << xsec + << " E-38 cm^2/nucleon)" << std::endl; } } LOG(FIT) << "Processed all events" << std::endl; - TFile* outputfile; + TFile *outputfile; // If no output is specified just append to the file if (!gOutputFile.length()) { tn->GetEntry(0); outputfile = tn->GetFile(); outputfile->cd(); } else { outputfile = new TFile(gOutputFile.c_str(), "RECREATE"); outputfile->cd(); QLOG(FIT, "Cloning input vector to output file: " << gOutputFile); - TTree* cloneTree = tn->CloneTree(); + TTree *cloneTree = tn->CloneTree(); cloneTree->SetDirectory(outputfile); cloneTree->Write(); QLOG(FIT, "Cloning input nova_wgts to output file: " << gOutputFile); // *********************************** // *********************************** // FUDGE FOR NOVA MINERVA WORKSHOP // Also check for the nova_wgts tree from Jeremy TChain *nova_chain = new TChain("nova_wgts"); nova_chain->AddFile(input.c_str()); - TTree* nova_tree = nova_chain->GetTree(); + TTree *nova_tree = nova_chain->GetTree(); if (!nova_tree) { QLOG(FIT, "Could not find nova_wgts tree in " << gOutputFile); } else { QLOG(FIT, "Found nova_wgts tree in " << gOutputFile); } if (nova_tree) { nova_tree->SetDirectory(outputfile); nova_tree->Write(); } QLOG(FIT, "Done cloning tree."); } LOG(FIT) << "Getting splines in mono-energetic..." << std::endl; // Save each of the reconstructed splines to file - std::map modeavg; + std::map modeavg; - TDirectory* inddir = (TDirectory*)outputfile->Get("IndividualGENIESplines"); - if (!inddir) inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines"); + TDirectory *inddir = (TDirectory *)outputfile->Get("IndividualGENIESplines"); + if (!inddir) + inddir = (TDirectory *)outputfile->mkdir("IndividualGENIESplines"); inddir->cd(); // Loop over GENIE ID's and get MEC count int MECcount = 0; bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm"); for (UInt_t i = 0; i < genieids.size(); i++) { if (genieids[i].find("MEC") != std::string::npos) { MECcount++; } } LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl; for (UInt_t i = 0; i < genieids.size(); i++) { std::string mode = genieids[i]; modexsec[mode]->Write((mode + "_summed_xsec").c_str(), TObject::kOverwrite); modecount[mode]->Write((mode + "_summed_evt").c_str(), TObject::kOverwrite); // Form extra avg xsec map -> Reconstructed spline - modeavg[mode] = (TH1D*)modexsec[mode]->Clone(); - modeavg[mode]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); + modeavg[mode] = (TH1D *)modexsec[mode]->Clone(); + modeavg[mode]->GetYaxis()->SetTitle( + "#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); modeavg[mode]->Divide(modecount[mode]); if (MECcorrect && (mode.find("MEC") != std::string::npos)) { modeavg[mode]->Scale(1.0 / double(MECcount)); } modeavg[mode]->Write((mode + "_rec_spline").c_str(), TObject::kOverwrite); } - TDirectory* targdir = (TDirectory*)outputfile->Get("TargetGENIESplines"); - if (!targdir) targdir = (TDirectory*)outputfile->mkdir("TargetGENIESplines"); + TDirectory *targdir = (TDirectory *)outputfile->Get("TargetGENIESplines"); + if (!targdir) + targdir = (TDirectory *)outputfile->mkdir("TargetGENIESplines"); targdir->cd(); LOG(FIT) << "Getting Target Splines" << std::endl; // For each target save a total spline - std::map targetsplines; + std::map targetsplines; for (uint i = 0; i < targetids.size(); i++) { std::string targ = targetids[i]; LOG(FIT) << "Getting target " << i << ": " << targ << std::endl; - targetsplines[targ] = (TH1D*)xsechist->Clone(); - targetsplines[targ]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); + targetsplines[targ] = (TH1D *)xsechist->Clone(); + targetsplines[targ]->GetYaxis()->SetTitle( + "#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); LOG(FIT) << "Created target spline for " << targ << std::endl; for (uint j = 0; j < genieids.size(); j++) { std::string mode = genieids[j]; if (mode.find(targ) != std::string::npos) { - LOG(FIT) << " Mode " << mode << " contains " << targ << " target" << std::endl; + LOG(FIT) << " Mode " << mode << " contains " << targ << " target" + << std::endl; targetsplines[targ]->Add(modeavg[mode]); - LOG(FIT) << "Finished with Mode " << mode << " " << modeavg[mode]->Integral() << std::endl; + LOG(FIT) << "Finished with Mode " << mode << " " + << modeavg[mode]->Integral() << std::endl; } } LOG(FIT) << "Saving target spline:" << targ << std::endl; targetsplines[targ]->Write(("Total_" + targ).c_str(), TObject::kOverwrite); } LOG(FIT) << "Getting total splines" << std::endl; // Now we have each of the targets we need to create a total cross-section. int totalnucl = 0; // Get the targets specified by the user, separated by commas // This has structure target1[fraction1], target2[fraction2] std::vector targprs = GeneralUtils::ParseToStr(target, ","); std::vector targ_list; std::vector frac_list; - // Chop up the target string which has format TARGET1[fraction1],TARGET2[fraction2] + // Chop up the target string which has format + // TARGET1[fraction1],TARGET2[fraction2] - //std::cout << "Targets: " << std::endl; + // std::cout << "Targets: " << std::endl; // Loop over the vector of strings "TARGET1[fraction1]" "TARGET2[fraction2]" - for (std::vector::iterator it = targprs.begin(); it != targprs.end(); ++it) { + for (std::vector::iterator it = targprs.begin(); + it != targprs.end(); ++it) { // Cut into "TARGET1" and "fraction1]" std::vector targind = GeneralUtils::ParseToStr(*it, "["); - //std::cout << " " << *it << std::endl; + // std::cout << " " << *it << std::endl; // Cut into "TARGET1" and "fraction1" - for (std::vector::iterator jt = targind.begin(); jt != targind.end(); ++jt) { + for (std::vector::iterator jt = targind.begin(); + jt != targind.end(); ++jt) { if ((*jt).find("]") != std::string::npos) { (*jt) = (*jt).substr(0, (*jt).find("]")); //*jt = "hello"; frac_list.push_back(*jt); // Won't find bracket for target } else { targ_list.push_back(*jt); } } } targprs = targ_list; std::vector targ_fractions; double minimum = 1.0; - for (std::vector::iterator it = frac_list.begin(); it != frac_list.end(); it++) { - //std::cout << " " << *it << std::endl; + for (std::vector::iterator it = frac_list.begin(); + it != frac_list.end(); it++) { + // std::cout << " " << *it << std::endl; double frac = std::atof((*it).c_str()); targ_fractions.push_back(frac); - if (frac < minimum) minimum = frac; + if (frac < minimum) + minimum = frac; } std::vector::iterator it = targ_fractions.begin(); std::vector::iterator jt = targ_list.begin(); double scaling = 0; for (; it != targ_fractions.end(); it++, jt++) { // First get the mass number from the targ_list int nucl = atoi((*jt).c_str()); - nucl = (nucl%10000)/10; + nucl = (nucl % 10000) / 10; // Gets the relative portions right - *it = (*it)/minimum; + *it = (*it) / minimum; // Scale relative the atomic mass //(*it) *= (double(nucl)/(*it)); - double tempscaling = double(nucl)/(*it); - if (tempscaling > scaling) scaling=tempscaling; + double tempscaling = double(nucl) / (*it); + if (tempscaling > scaling) + scaling = tempscaling; } it = targ_fractions.begin(); for (; it != targ_fractions.end(); it++) { // Round the scaling to nearest integer and multiply - *it *= int(scaling+0.5); + *it *= int(scaling + 0.5); // Round to nearest integer - *it = int(*it+0.5); + *it = int(*it + 0.5); totalnucl += *it; } if (totalnucl == 0) { - THROW("Didn't find any nucleons in input file. Did you really specify the target ratios?\ne.g. TARGET1[fraction1],TARGET2[fraction2]" << std::endl); + THROW("Didn't find any nucleons in input file. Did you really specify the " + "target ratios?\ne.g. TARGET1[fraction1],TARGET2[fraction2]" + << std::endl); } - TH1D* totalxsec = (TH1D*)xsechist->Clone(); + TH1D *totalxsec = (TH1D *)xsechist->Clone(); for (uint i = 0; i < targprs.size(); i++) { std::string targpdg = targprs[i]; // Check that we found the user requested target in GENIE bool FoundTarget = false; - for (std::map::iterator iter = targetsplines.begin(); - iter != targetsplines.end(); iter++) { + for (std::map::iterator iter = targetsplines.begin(); + iter != targetsplines.end(); iter++) { std::string targstr = iter->first; - TH1D* xsec = iter->second; + TH1D *xsec = iter->second; // Match the user targets to the targets found in GENIE if (targstr.find(targpdg) != std::string::npos) { FoundTarget = true; - LOG(FIT) << "Adding target spline " << targstr << " Integral = " << xsec->Integral("width") << std::endl; + LOG(FIT) << "Adding target spline " << targstr + << " Integral = " << xsec->Integral("width") << std::endl; totalxsec->Add(xsec); - //int nucl = atoi(targpdg.c_str()); - //totalnucl += int((nucl % 10000) / 10); - } + // int nucl = atoi(targpdg.c_str()); + // totalnucl += int((nucl % 10000) / 10); + } } // Check that targets were all found if (!FoundTarget) { - ERR(WRN) << "Didn't find target " << targpdg << " in the list of targets recorded by GENIE" << std::endl; + ERR(WRN) << "Didn't find target " << targpdg + << " in the list of targets recorded by GENIE" << std::endl; ERR(WRN) << " The list of targets you requested is: " << std::endl; - for (uint i = 0; i < targprs.size(); ++i) ERR(WRN) << " " << targprs[i] << std::endl; + for (uint i = 0; i < targprs.size(); ++i) + ERR(WRN) << " " << targprs[i] << std::endl; ERR(WRN) << " The list of targets found in GENIE is: " << std::endl; - for (std::map::iterator iter = targetsplines.begin(); iter != targetsplines.end(); iter++) ERR(WRN) << " " << iter->first<< std::endl; + for (std::map::iterator iter = targetsplines.begin(); + iter != targetsplines.end(); iter++) + ERR(WRN) << " " << iter->first << std::endl; } } outputfile->cd(); - totalxsec->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/nucleon)"); + totalxsec->GetYaxis()->SetTitle( + "#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/nucleon)"); totalxsec->Write("nuisance_xsec", TObject::kOverwrite); - eventhist = (TH1D*)fluxhist->Clone(); + eventhist = (TH1D *)fluxhist->Clone(); eventhist->Multiply(totalxsec); - eventhist->GetYaxis()->SetTitle((std::string("Event rate (N = #sigma #times #Phi) #times 10^{-38} (cm^{2}/nucleon) #times ")+eventhist->GetYaxis()->GetTitle()).c_str()); + eventhist->GetYaxis()->SetTitle( + (std::string("Event rate (N = #sigma #times #Phi) #times 10^{-38} " + "(cm^{2}/nucleon) #times ") + + eventhist->GetYaxis()->GetTitle()) + .c_str()); LOG(FIT) << "Dividing by Total Nucl = " << totalnucl << std::endl; eventhist->Scale(1.0 / double(totalnucl)); eventhist->Write("nuisance_events", TObject::kOverwrite); fluxhist->Write("nuisance_flux", TObject::kOverwrite); - LOG(FIT) << "Inclusive XSec Per Nucleon = " << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") << std::endl; - LOG(FIT) << "XSec Hist Integral = " << totalxsec->Integral("width") << std::endl; + LOG(FIT) << "Inclusive XSec Per Nucleon = " + << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") + << std::endl; + LOG(FIT) << "XSec Hist Integral = " << totalxsec->Integral("width") + << std::endl; outputfile->Close(); return; } void RunGENIEPrepare(std::string input, std::string flux, std::string target, - std::string output) { + std::string output) { LOG(FIT) << "Running GENIE Prepare with flux..." << std::endl; // Get Flux Hist std::vector fluxvect = GeneralUtils::ParseToStr(flux, ","); - TH1* fluxhist = NULL; + TH1 *fluxhist = NULL; if (fluxvect.size() == 3) { double from = GeneralUtils::StrToDbl(fluxvect[0]); double to = GeneralUtils::StrToDbl(fluxvect[1]); double step = GeneralUtils::StrToDbl(fluxvect[2]); int nstep = ceil((to - from) / step); to = from + step * nstep; QLOG(FIT, "Generating flat flux histogram from " - << from << " to " << to << " with bins " << step - << " wide (NBins = " << nstep << ")."); + << from << " to " << to << " with bins " << step + << " wide (NBins = " << nstep << ")."); - fluxhist = new TH1D("spectrum", ";E_{#nu} (GeV);Count (A.U.)", nstep, from, to); + fluxhist = + new TH1D("spectrum", ";E_{#nu} (GeV);Count (A.U.)", nstep, from, to); for (Int_t bi_it = 1; bi_it < fluxhist->GetXaxis()->GetNbins(); ++bi_it) { fluxhist->SetBinContent(bi_it, 1.0 / double(step * nstep)); } fluxhist->SetDirectory(0); } else if (fluxvect.size() == 2) { - TFile* fluxfile = new TFile(fluxvect[0].c_str(), "READ"); + TFile *fluxfile = new TFile(fluxvect[0].c_str(), "READ"); if (!fluxfile->IsZombie()) { - fluxhist = dynamic_cast(fluxfile->Get(fluxvect[1].c_str())); + fluxhist = dynamic_cast(fluxfile->Get(fluxvect[1].c_str())); if (!fluxhist) { ERR(FTL) << "Couldn't find histogram named: \"" << fluxvect[1] - << "\" in file: \"" << fluxvect[0] << std::endl; + << "\" in file: \"" << fluxvect[0] << std::endl; throw; } fluxhist->SetDirectory(0); } } else if (fluxvect.size() == 1) { MonoEnergy = GeneralUtils::StrToDbl(fluxvect[0]); RunGENIEPrepareMono(input, target, output); return; } else { LOG(FTL) << "Bad flux specification: \"" << flux << "\"." << std::endl; throw; } // Setup TTree - TChain* tn = new TChain("gtree"); + TChain *tn = new TChain("gtree"); + std::string first_file = ""; if (input.find_first_of(',') != std::string::npos) { std::vector inputvect = GeneralUtils::ParseToStr(input, ","); for (size_t iv_it = 0; iv_it < inputvect.size(); ++iv_it) { tn->AddFile(inputvect[iv_it].c_str()); QLOG(FIT, "Added input file: " << inputvect[iv_it]); + if (!first_file.length()) { + first_file = inputvect[iv_it]; + } } - } else { // The Add form can accept wildcards. + } else { // The Add form can accept wildcards. tn->Add(input.c_str()); + first_file = input; } if (tn->GetFile() == NULL) { tn->Print(); ERROR(FTL, "gtree not located in GENIE file: " << input); THROW("Check your inputs, they may need to be completely regenerated!"); throw; } int nevt = tn->GetEntries(); if (gNEvents != -999) { - LOG(FIT) << "Overriding number of events by user from " << nevt << " to " << gNEvents << std::endl; + LOG(FIT) << "Overriding number of events by user from " << nevt << " to " + << gNEvents << std::endl; nevt = gNEvents; } if (!nevt) { THROW("Couldn't load any events from input specification: \"" - << input.c_str() << "\""); + << input.c_str() << "\""); } else { QLOG(FIT, "Found " << nevt << " input entries in " << input); } - NtpMCEventRecord* genientpl = NULL; + NtpMCEventRecord *genientpl = NULL; tn->SetBranchAddress("gmcrec", &genientpl); // Make Event and xsec Hist - TH1D* eventhist = (TH1D*)fluxhist->Clone(); + TH1D *eventhist = (TH1D *)fluxhist->Clone(); + eventhist->SetDirectory(NULL); eventhist->Reset(); - TH1D* xsechist = (TH1D*)eventhist->Clone(); + TH1D *xsechist = (TH1D *)eventhist->Clone(); + xsechist->SetDirectory(NULL); // Create maps - std::map modexsec; - std::map modecount; + std::map modexsec; + std::map modecount; std::vector genieids; std::vector targetids; std::vector interids; // Loop over all events for (int i = 0; i < nevt; i++) { tn->GetEntry(i); // Hussssch GENIE StopTalking(); // Get the event - EventRecord& event = *(genientpl->event); + EventRecord &event = *(genientpl->event); // Get the neutrino - GHepParticle* neu = event.Probe(); + GHepParticle *neu = event.Probe(); StartTalking(); // Get XSec From Spline // Get the GHepRecord GHepRecord genie_record = static_cast(event); double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2)); // Parse Interaction String std::string mode = genie_record.Summary()->AsString(); std::vector modevec = GeneralUtils::ParseToStr(mode, ";"); std::string targ = (modevec[0] + ";" + modevec[1]); std::string inter = mode; // Get target nucleus // Alternative ways of getting the summaries - //GHepParticle *target = genie_record.TargetNucleus(); - //int pdg = target->Pdg(); + // GHepParticle *target = genie_record.TargetNucleus(); + // int pdg = target->Pdg(); // Fill lists of Unique IDS (neutrino and target) - if (std::find(targetids.begin(), targetids.end(), targ) == targetids.end()) { + if (std::find(targetids.begin(), targetids.end(), targ) == + targetids.end()) { targetids.push_back(targ); } // The full interaction list if (std::find(interids.begin(), interids.end(), inter) == interids.end()) { interids.push_back(inter); } // Create entries Mode Maps if (modexsec.find(mode) == modexsec.end()) { genieids.push_back(mode); - modexsec[mode] = (TH1D*)xsechist->Clone(); - modecount[mode] = (TH1D*)xsechist->Clone(); + modexsec[mode] = (TH1D *)xsechist->Clone(); + modecount[mode] = (TH1D *)xsechist->Clone(); - modexsec[mode]->GetYaxis()->SetTitle("d#sigma/dE_{#nu} #times 10^{-38} (events weighted by #sigma)"); + modexsec[mode]->SetDirectory(NULL); + modecount[mode]->SetDirectory(NULL); + + modexsec[mode]->GetYaxis()->SetTitle( + "d#sigma/dE_{#nu} #times 10^{-38} (events weighted by #sigma)"); modecount[mode]->GetYaxis()->SetTitle("Number of events in file"); } // Fill XSec Histograms modexsec[mode]->Fill(neu->E(), xsec); modecount[mode]->Fill(neu->E()); // Fill total event hist eventhist->Fill(neu->E()); if (i % (nevt / 20) == 0) { LOG(FIT) << "Processed " << i << "/" << nevt - << " GENIE events (E: " << neu->E() - << " GeV, xsec: " << xsec << " E-38 cm^2/nucleon)" << std::endl; + << " GENIE events (E: " << neu->E() << " GeV, xsec: " << xsec + << " E-38 cm^2/nucleon)" << std::endl; } // Clear Event genientpl->Clear(); } LOG(FIT) << "Processed all events" << std::endl; // Once event loop is done we can start saving stuff into the file - TFile* outputfile; + TFile *outputfile; if (!gOutputFile.length()) { - tn->GetEntry(0); - outputfile = tn->GetFile(); - outputfile->cd(); + // Shut the chain; + delete tn; + outputfile = new TFile(first_file.c_str(), "UPDATE"); } else { outputfile = new TFile(gOutputFile.c_str(), "RECREATE"); outputfile->cd(); QLOG(FIT, "Cloning input vector to output file: " << gOutputFile); - TTree* cloneTree = tn->CloneTree(); + TTree *cloneTree = tn->CloneTree(); cloneTree->SetDirectory(outputfile); cloneTree->Write(); // ******************************** // CLUDGE KLUDGE KLUDGE FOR NOVA QLOG(FIT, "Cloning input nova_wgts to output file: " << gOutputFile); // Also check for the nova_wgts tree from Jeremy TChain *nova_chain = new TChain("nova_wgts"); nova_chain->AddFile(input.c_str()); - TTree* nova_tree = nova_chain->CloneTree(); + TTree *nova_tree = nova_chain->CloneTree(); if (!nova_tree) { QLOG(FIT, "Could not find nova_wgts tree in " << input); } else { QLOG(FIT, "Found nova_wgts tree in " << input); nova_tree->SetDirectory(outputfile); nova_tree->Write(); } QLOG(FIT, "Done cloning tree."); } LOG(FIT) << "Getting splines..." << std::endl; // Save each of the reconstructed splines to file - std::map modeavg; + std::map modeavg; - TDirectory* inddir = (TDirectory*)outputfile->Get("IndividualGENIESplines"); - if (!inddir) inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines"); + TDirectory *inddir = (TDirectory *)outputfile->Get("IndividualGENIESplines"); + if (!inddir) + inddir = (TDirectory *)outputfile->mkdir("IndividualGENIESplines"); inddir->cd(); // Loop over GENIE ID's and get MEC count int MECcount = 0; bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm"); for (UInt_t i = 0; i < genieids.size(); i++) { if (genieids[i].find("MEC") != std::string::npos) { MECcount++; } } LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl; for (UInt_t i = 0; i < genieids.size(); i++) { std::string mode = genieids[i]; modexsec[mode]->Write((mode + "_summed_xsec").c_str(), TObject::kOverwrite); modecount[mode]->Write((mode + "_summed_evt").c_str(), TObject::kOverwrite); // Form extra avg xsec map -> Reconstructed spline - modeavg[mode] = (TH1D*)modexsec[mode]->Clone(); - modeavg[mode]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); + modeavg[mode] = (TH1D *)modexsec[mode]->Clone(); + modeavg[mode]->GetYaxis()->SetTitle( + "#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); modeavg[mode]->Divide(modecount[mode]); if (MECcorrect && (mode.find("MEC") != std::string::npos)) { modeavg[mode]->Scale(1.0 / double(MECcount)); } modeavg[mode]->Write((mode + "_rec_spline").c_str(), TObject::kOverwrite); } - TDirectory* targdir = (TDirectory*)outputfile->Get("TargetGENIESplines"); - if (!targdir) targdir = (TDirectory*)outputfile->mkdir("TargetGENIESplines"); + TDirectory *targdir = (TDirectory *)outputfile->Get("TargetGENIESplines"); + if (!targdir) + targdir = (TDirectory *)outputfile->mkdir("TargetGENIESplines"); targdir->cd(); LOG(FIT) << "Getting Target Splines" << std::endl; // For each target save a total spline - std::map targetsplines; + std::map targetsplines; for (uint i = 0; i < targetids.size(); i++) { std::string targ = targetids[i]; LOG(FIT) << "Getting target " << i << ": " << targ << std::endl; - targetsplines[targ] = (TH1D*)xsechist->Clone(); - targetsplines[targ]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); + targetsplines[targ] = (TH1D *)xsechist->Clone(); + targetsplines[targ]->GetYaxis()->SetTitle( + "#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)"); LOG(FIT) << "Created target spline for " << targ << std::endl; for (uint j = 0; j < genieids.size(); j++) { std::string mode = genieids[j]; // Look at all matching modes/targets if (mode.find(targ) != std::string::npos) { - LOG(FIT) << " Mode " << mode << " contains " << targ << " target" << std::endl; + LOG(FIT) << " Mode " << mode << " contains " << targ << " target" + << std::endl; targetsplines[targ]->Add(modeavg[mode]); - LOG(FIT) << "Finished with Mode " << mode << " " << modeavg[mode]->Integral() << std::endl; + LOG(FIT) << "Finished with Mode " << mode << " " + << modeavg[mode]->Integral() << std::endl; } } LOG(FIT) << "Saving target spline: " << targ << std::endl; targetsplines[targ]->Write(("Total_" + targ).c_str(), TObject::kOverwrite); } LOG(FIT) << "Getting total splines" << std::endl; // Now we have each of the targets we need to create a total cross-section. int totalnucl = 0; // This has structure target1[fraction1], target2[fraction2] std::vector targprs = GeneralUtils::ParseToStr(target, ","); std::vector targ_list; std::vector frac_list; - // Chop up the target string which has format TARGET1[fraction1],TARGET2[fraction2] + // Chop up the target string which has format + // TARGET1[fraction1],TARGET2[fraction2] - //std::cout << "Targets: " << std::endl; + // std::cout << "Targets: " << std::endl; // Loop over the vector of strings "TARGET1[fraction1]" "TARGET2[fraction2]" - for (std::vector::iterator it = targprs.begin(); it != targprs.end(); ++it) { + for (std::vector::iterator it = targprs.begin(); + it != targprs.end(); ++it) { // Cut into "TARGET1" and "fraction1]" std::vector targind = GeneralUtils::ParseToStr(*it, "["); - //std::cout << " " << *it << std::endl; + // std::cout << " " << *it << std::endl; // Cut into "TARGET1" and "fraction1" - for (std::vector::iterator jt = targind.begin(); jt != targind.end(); ++jt) { + for (std::vector::iterator jt = targind.begin(); + jt != targind.end(); ++jt) { if ((*jt).find("]") != std::string::npos) { (*jt) = (*jt).substr(0, (*jt).find("]")); //*jt = "hello"; frac_list.push_back(*jt); // Won't find bracket for target } else { targ_list.push_back(*jt); } } } targprs = targ_list; std::vector targ_fractions; double minimum = 1.0; - for (std::vector::iterator it = frac_list.begin(); it != frac_list.end(); it++) { - //std::cout << " " << *it << std::endl; + for (std::vector::iterator it = frac_list.begin(); + it != frac_list.end(); it++) { + // std::cout << " " << *it << std::endl; double frac = std::atof((*it).c_str()); targ_fractions.push_back(frac); - if (frac < minimum) minimum = frac; + if (frac < minimum) + minimum = frac; } std::vector::iterator it = targ_fractions.begin(); std::vector::iterator jt = targ_list.begin(); double scaling = 0; for (; it != targ_fractions.end(); it++, jt++) { // First get the mass number from the targ_list int nucl = atoi((*jt).c_str()); - nucl = (nucl%10000)/10; + nucl = (nucl % 10000) / 10; // Gets the relative portions right - *it = (*it)/minimum; + *it = (*it) / minimum; // Scale relative the atomic mass //(*it) *= (double(nucl)/(*it)); - double tempscaling = double(nucl)/(*it); - if (tempscaling > scaling) scaling=tempscaling; + double tempscaling = double(nucl) / (*it); + if (tempscaling > scaling) + scaling = tempscaling; } it = targ_fractions.begin(); for (; it != targ_fractions.end(); it++) { // Round the scaling to nearest integer and multiply - *it *= int(scaling+0.5); + *it *= int(scaling + 0.5); // Round to nearest integer - *it = int(*it+0.5); + *it = int(*it + 0.5); totalnucl += *it; } if (totalnucl == 0) { - THROW("Didn't find any nucleons in input file. Did you really specify the target ratios?\ne.g. TARGET1[fraction1],TARGET2[fraction2]" << std::endl); + THROW("Didn't find any nucleons in input file. Did you really specify the " + "target ratios?\ne.g. TARGET1[fraction1],TARGET2[fraction2]" + << std::endl); } - TH1D* totalxsec = (TH1D*)xsechist->Clone(); + TH1D *totalxsec = (TH1D *)xsechist->Clone(); // Loop over the specified targets by the user for (uint i = 0; i < targprs.size(); i++) { std::string targpdg = targprs[i]; // Check that we found the user requested target in GENIE bool FoundTarget = false; - for (std::map::iterator iter = targetsplines.begin(); iter != targetsplines.end(); iter++) { + for (std::map::iterator iter = targetsplines.begin(); + iter != targetsplines.end(); iter++) { std::string targstr = iter->first; - TH1D* xsec = iter->second; + TH1D *xsec = iter->second; // Match the user targets to the targets found in GENIE if (targstr.find(targpdg) != std::string::npos) { FoundTarget = true; - LOG(FIT) << "Adding target spline " << targstr << " Integral = " << xsec->Integral("width") << std::endl; + LOG(FIT) << "Adding target spline " << targstr + << " Integral = " << xsec->Integral("width") << std::endl; totalxsec->Add(xsec); - //int nucl = atoi(targpdg.c_str()); - //totalnucl += int((nucl % 10000) / 10); - } + // int nucl = atoi(targpdg.c_str()); + // totalnucl += int((nucl % 10000) / 10); + } } // Looped over target splines // Check that targets were all found if (!FoundTarget) { - ERR(WRN) << "Didn't find target " << targpdg << " in the list of targets recorded by GENIE" << std::endl; + ERR(WRN) << "Didn't find target " << targpdg + << " in the list of targets recorded by GENIE" << std::endl; ERR(WRN) << " The list of targets you requested is: " << std::endl; - for (uint i = 0; i < targprs.size(); ++i) ERR(WRN) << " " << targprs[i] << std::endl; + for (uint i = 0; i < targprs.size(); ++i) + ERR(WRN) << " " << targprs[i] << std::endl; ERR(WRN) << " The list of targets found in GENIE is: " << std::endl; - for (std::map::iterator iter = targetsplines.begin(); iter != targetsplines.end(); iter++) ERR(WRN) << " " << iter->first<< std::endl; + for (std::map::iterator iter = targetsplines.begin(); + iter != targetsplines.end(); iter++) + ERR(WRN) << " " << iter->first << std::endl; } } outputfile->cd(); - totalxsec->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/nucleon)"); + totalxsec->GetYaxis()->SetTitle( + "#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/nucleon)"); totalxsec->Write("nuisance_xsec", TObject::kOverwrite); - eventhist = (TH1D*)fluxhist->Clone(); + eventhist = (TH1D *)fluxhist->Clone(); eventhist->Multiply(totalxsec); - eventhist->GetYaxis()->SetTitle((std::string("Event rate (N = #sigma #times #Phi) #times 10^{-38} (cm^{2}/nucleon) #times ")+eventhist->GetYaxis()->GetTitle()).c_str()); + eventhist->GetYaxis()->SetTitle( + (std::string("Event rate (N = #sigma #times #Phi) #times 10^{-38} " + "(cm^{2}/nucleon) #times ") + + eventhist->GetYaxis()->GetTitle()) + .c_str()); LOG(FIT) << "Dividing by Total Nucl = " << totalnucl << std::endl; eventhist->Scale(1.0 / double(totalnucl)); eventhist->Write("nuisance_events", TObject::kOverwrite); fluxhist->Write("nuisance_flux", TObject::kOverwrite); - LOG(FIT) << "Inclusive XSec Per Nucleon = " << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") << std::endl; + LOG(FIT) << "Inclusive XSec Per Nucleon = " + << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") + << std::endl; LOG(FIT) << "XSec Hist Integral = " << totalxsec->Integral() << std::endl; outputfile->Close(); return; }; void PrintOptions() { std::cout << "PrepareGENIEEvents NUISANCE app. " << std::endl - << "Takes GHep Outputs and prepares events for NUISANCE." - << std::endl - << std::endl - << "PrepareGENIE [-h,-help,--h,--help] [-i " - "inputfile1.root,inputfile2.root,inputfile3.root,...] " - << "[-f flux_root_file.root,flux_hist_name] [-t " - "target1[frac1],target2[frac2],...]" - << "[-n number_of_events (experimental)]" - << std::endl - << std::endl; + << "Takes GHep Outputs and prepares events for NUISANCE." + << std::endl + << std::endl + << "PrepareGENIE [-h,-help,--h,--help] [-i " + "inputfile1.root,inputfile2.root,inputfile3.root,...] " + << "[-f flux_root_file.root,flux_hist_name] [-t " + "target1[frac1],target2[frac2],...]" + << "[-n number_of_events (experimental)]" << std::endl + << std::endl; std::cout << "Prepare Mode [Default] : Takes a single GHep file, " - "reconstructs the original GENIE splines, " - << " and creates a duplicate file that also contains the flux, " - "event rate, and xsec predictions that NUISANCE needs. " - << std::endl; + "reconstructs the original GENIE splines, " + << " and creates a duplicate file that also contains the flux, " + "event rate, and xsec predictions that NUISANCE needs. " + << std::endl; std::cout << "Following options are required for Prepare Mode:" << std::endl; std::cout << " [ -i inputfile.root ] : Reads in a single GHep input file " - "that needs the xsec calculation ran on it. " - << std::endl; + "that needs the xsec calculation ran on it. " + << std::endl; std::cout << " [ -f flux_file.root,hist_name ] : Path to root file " - "containing the flux histogram the GHep records were generated " - "with." - << " A simple method is to point this to the flux histogram genie " - "generatrs '-f /path/to/events/input-flux.root,spectrum'. " - << std::endl; + "containing the flux histogram the GHep records were generated " + "with." + << " A simple method is to point this to the flux histogram genie " + "generatrs '-f /path/to/events/input-flux.root,spectrum'. " + << std::endl; std::cout << " [ -f elow,ehigh,estep ] : Energy range specification when no " - "flux file was used." - << std::endl; + "flux file was used." + << std::endl; std::cout << " [ -t target ] : Target that GHepRecords were generated with. " - "Comma seperated list. E.g. for CH2 " - "target=1000060120,1000010010,1000010010" - << std::endl; + "Comma seperated list. E.g. for CH2 " + "target=1000060120,1000010010,1000010010" + << std::endl; std::cout << " [ -o outputfile.root ] : File to write prepared input file to." - << std::endl; - std::cout << " [ -m Mono_E_nu_GeV ] : Run in mono-energetic mode with m GeV neutrino energy." - << std::endl; - std::cout << " [ -n number_of_evt ] : Run with a reduced number of events for debugging purposes" - << std::endl; + << std::endl; + std::cout << " [ -m Mono_E_nu_GeV ] : Run in mono-energetic mode with m GeV " + "neutrino energy." + << std::endl; + std::cout << " [ -n number_of_evt ] : Run with a reduced number of events " + "for debugging purposes" + << std::endl; } -void ParseOptions(int argc, char* argv[]) { +void ParseOptions(int argc, char *argv[]) { bool flagopt = false; // If No Arguments print commands for (int i = 1; i < argc; ++i) { if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } if (i + 1 != argc) { // Cardfile if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } else if (!std::strcmp(argv[i], "-i")) { gInputFiles = argv[i + 1]; ++i; } else if (!std::strcmp(argv[i], "-o")) { gOutputFile = argv[i + 1]; ++i; } else if (!std::strcmp(argv[i], "-f")) { gFluxFile = argv[i + 1]; ++i; } else if (!std::strcmp(argv[i], "-t")) { gTarget = argv[i + 1]; ++i; } else if (!std::strcmp(argv[i], "-n")) { gNEvents = GeneralUtils::StrToInt(argv[i + 1]); ++i; } else if (!std::strcmp(argv[i], "-m")) { MonoEnergy = GeneralUtils::StrToDbl(argv[i + 1]); IsMonoE = true; ++i; } else { ERR(FTL) << "ERROR: unknown command line option given! - '" << argv[i] - << " " << argv[i + 1] << "'" << std::endl; + << " " << argv[i + 1] << "'" << std::endl; PrintOptions(); break; } } } if (gInputFiles == "" && !flagopt) { ERR(FTL) << "No input file(s) specified!" << std::endl; flagopt = true; } if (gFluxFile == "" && !flagopt && !IsMonoE) { ERR(FTL) << "No flux input specified for Prepare Mode" << std::endl; flagopt = true; } if (gTarget == "" && !flagopt) { ERR(FTL) << "No target specified for Prepare Mode" << std::endl; flagopt = true; } - if (gTarget.find("[") == std::string::npos || gTarget.find("]") == std::string::npos) { + if (gTarget.find("[") == std::string::npos || + gTarget.find("]") == std::string::npos) { ERR(FTL) << "Didn't specify target ratios in Prepare Mode" << std::endl; - ERR(FTL) << "Are you sure you gave it as -t \"TARGET1[fraction1],TARGET2[fraction]\"?" << std::endl; + ERR(FTL) << "Are you sure you gave it as -t " + "\"TARGET1[fraction1],TARGET2[fraction]\"?" + << std::endl; flagopt = true; } if (argc < 1 || flagopt) { PrintOptions(); exit(-1); } return; } diff --git a/app/nuiscomp.cxx b/app/nuiscomp.cxx index bea4c32..8d53d93 100644 --- a/app/nuiscomp.cxx +++ b/app/nuiscomp.cxx @@ -1,228 +1,226 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "ComparisonRoutines.h" //******************************* void printInputCommands() { //******************************* std::cout << "nuiscomp : NUISANCE Data Comparison App \n" << std::endl; std::cout << "# Running nuiscomp with a card file #\n" << "######################################\n" << "nuiscomp -c cardfile.xml [ -o outputfile.root ] [ -f routines ] [ -n maxevents ] \n" << " [ -i 'cardstructure' ] [ -d fakedata ] [ -q config=val ] [ +e/-e ] [ +v/-v ] \n" << "\n" << "# Running nuiscomp with structures at cmd line #\n" << "################################################\n" << "nuiscomp -i 'cardstructure' -o outputfile.root [ -c cardfile.xml [ -f routines ] [ -n maxevents ] \n" << " [ -d fakedata ] [ -q config=val ] [ +e/-e ] [ +v/-v ] \n" << std::endl; sleep(4); std::cout << "" << "\n" << " \n" << " -c cardfile.xml : NUISANCE format card file defining comparisons. \n" << " \n" << " -o outputfile.root : Output file that histograms will be saved in. If a card file is \n" << " given but no output file this will default to cardfile.xml.root \n" << " \n" << " -f routines : Comma separated list of comparison routines to run in order. \n" << " Allowed Routines : \n" << " Compare : Fixed comparison at nominal dial values. \n" << " \n" << " -n maxevents : Set limit on the number of event entries to process. \n" << " \n" << " -i \'cardstructure\' : Define card structure like those available in the standard NUISANCE \n" << " card format, but on the command line at runtime. MUST be enclosed \n" << " in single quotation marks. See examples below for usage. \n" << " \n" << " It is possible to entirely define the comparison using \' -i\' commands \n" << " without the need to write a card file explicitly. If you do this, \n" << " make sure to also use the \' -o\' flag to tell it where to go. \n" << " \n" << " -d fakedata : Define a fake data set to be used. All data in NUISANCE will be set \n" << " to the values defined in this fake data before comparisons are made. \n" << " \n" << " There are two possible methods. Fake data from MC or a previous file.\n" << " fakedata = \'MC\' : Sets the MC to the values defined by \'fake_parameters\' \n" << " shown in the examples below, and then sets the data \n" << " to be equal to this MC prediction. \n" << " fakedata = \'file.root\' : Reads in the ROOT file at the specified path \n" << " assuming its a standard NUISANCE file. Takes \n" << " MC predictions in this file and uses them as \n" << " fake data. \n" << " \n" << " -q config=val : Overrides default configurations provided in the cardfile and in \n" << " '$NUISANCE/parameters/config.xml\'. Any config parameter can be set. \n" << " Examples : \n" << " \'-q VERBOSITY=4\' \n" << " \'-q EventManager=1\' \n" << " \'-q drawOpts=DATA/MC\' \n" << " \n" << " +e/-e : Increase/Decrease the default error verbosity by 1. \n" << " \n" << " +v/-v : Increase/Decrease the default logging verbosity by 1.\n" << " \n\n" << std::endl; sleep(4); std::cout << "# nuiscomp Running Examples #" << "############################# \n" << " \n" << " 1. Generate cardfile comparisons with increased verbosity and only 50000 events \n\n" << " nuiscomp -c cardfile.card -o mycomp.root -n 50000 +v +v \n" << " \n\n" << " 2. Generate a comparison to MiniBooNE data using simple structure, saving it to outfile.root \n\n" << " nuiscomp -o outfile.root -i \'sample MiniBooNE_CCQE_XSec_1DQ2_nu NEUT:neutevents.root\' \n" << " \n\n" << " 3. Generate a comparison to MiniBooNE data using xml structure, reweight MaCCQE, and save the prediction to outfile.root \n\n" << " nuiscomp -o outfile.root -i \'sample name=\"MiniBooNE_CCQE_XSec_1DQ2_nu\" input=\"NEUT:neutevents.root\"\' \\ \n" << " -i \'sample name=\"MiniBooNE_CC1pip_XSec_1DQ2_nu\" input=\"NEUT:neutevents.root\"\' \\ \n" << " -i \'parameter name=\"MaCCQE\" nominal=\"1.0\" type=\"neut_parameter\"\' \n " << " \n\n" << " 4. Generate a comparison, using fake data from the MC predictions inside the fakedata.root \n\n" << " nuiscomp -c cardfile.card -o myfakecomp.root -d fakedata.root \n" << " \n\n" << " 5. Generate a comparison using fake data defined on the command line use fake parameters \n\n" << " nuiscomp -c cardfile.card -d MC -i \'fakeparameter name=\"MaCCQE\" nominal=\"1.0\"\' \n " << " -i \'parameter name=\"MaCCQE\" nominal=\"1.0\" type=\"neut_parameter\"' " << " \n\n" << std::endl; sleep(4); std::cout << "# NUISANCE Card Format Structure Examples # \n" << "########################################### \n" << "\n" << "The NUISANCE card can be defined as a simple text file, or an xml file. \n" << "Examples for both with relevant structures are given below. \n" << std::endl; std::cout << "# XML Card File Example # \n" << "cardfile.xml: \n" << "" << "\n" << " \n" << " \n" << " \n" << "\n" << " \n" << " \n" << " \n" << " \n" << " \n" << " \n" << " \n" << "\n" << " \n" << " \n" << "\n" << "\n" << " \n" << " \n" << " \n" << " \n" << " \n" << "\n" << " \n" << "\n" << " \n" << " \n" << " \n" << " \n" << " \n" << "\n" << " \n" << "\n" << " \n\n" << std::endl; std::cout << "# Simple Card File Example # \n" << "cardfile.card: \n" << "\n" << "# CONFIG STRUCTURE \n" << "# config name val \n" << "config VERBOSITY 4 \n" << "\n" << "# Sample Structure \n" << "# ID Corresponds to names given in src/FCN/SampleList.cxx \n" << "# TYPE is the generator type (NEUT,NUWRO,GENIE,GIBUU). \n" << "# FILE is the input generator events file. \n" << "# TYPE is optional and used to define options for a class. e.g. FREE \n" << "# NORM is optional and sets sample normalisations. \n" << "# sample ID TYPE:FILE TYPE 1.0 \n" << "\n" << "sample MiniBooNE_CCQE_XSec_1DQ2_nu GENIE:genieevents.root \n" << "sample MiniBooNE_CC1pip_XSec_1DQ2_nu GENIE:genieevents.root SHAPE \n" << "\n" << "\n" << "# Parameter Structure \n" << "# ID is the name of the dial in each generator RW engine \n" << "# TYPE is the dial type (neut,newer,genie,niwg,t2k,custom,norm) \n" << "# VAL is the nominal value in 1-sigma variation for the comparison \n" << "# TYPE_parameter ID VAL \n" << "\n" << "neut_parameter MaCCQE 0.5 \n" << "\n" << "# Fake Parameter Structure \n" << "# Sets values for fake data defined using the ‘MC’ flag. \n" << "# ID is the dial name, it MUST be specified before hand using a normal parameter structure \n" << "# VAL is the value to use for the fake data \n" << "# fake_parameter ID VAL \n" << "\n" << "fake_parameter MaCCQE 1.0 \n" << "\n" << std::endl; exit(-1); }; //******************************* int main(int argc, char* argv[]) { //******************************* // Program status; int status = 0; // If No Arguments print commands if (argc == 1) printInputCommands(); for (int i = 1; i < argc; ++i) { // Cardfile if (!std::strcmp(argv[i], "-h")) printInputCommands(); else break; } // Read input arguments such as card file, parameter arguments, and fit routines LOG(FIT) << "Starting nuiscomp.exe" << std::endl; // Make minimizer class and run fit ComparisonRoutines* comp = new ComparisonRoutines(argc, argv); comp->Run(); + delete comp; // Show Final Status LOG(FIT) << "------------------------------------ -" << std::endl; LOG(FIT) << "Comparison Complete." << std::endl; LOG(FIT) << "------------------------------------ -" << std::endl; return status; } - - - diff --git a/app/nuismin.cxx b/app/nuismin.cxx index 5bb48d8..afe4224 100644 --- a/app/nuismin.cxx +++ b/app/nuismin.cxx @@ -1,113 +1,113 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ // Author: Callum Wilkinson 01/2014 // Patrick Stowell 09/2015 /** Usage: ./GSLminimizerWithReWeight.exe -c card file, where samples and parameters are defined -o output file, where the results of the fit are stored where: */ #include "MinimizerRoutines.h" //******************************* void printInputCommands(){ //******************************* std::cout<<"ExtFit_minimizer.exe -c cardFile -o outFile [-f fitStategy] [-d fakeDataFile] [-i inputFile] [-q config_name=config_val] \n"; std::cout<SaveNominal(); if (FitPar::Config().GetParB("saveprefit")) min->SavePrefit(); - // Run the fit rotines + // Run the fit routines min->Run(); // Save by default min->SaveResults(); // Get Status status = min->GetStatus(); // Show Final Status LOG(FIT)<<"-------------------------------------"<. ################################################################################ # TODO # check system for libxml2 # check whether we need the includes # check if we can use a subset of the GENIE libraries +include(${CMAKE_SOURCE_DIR}/cmake/parseConfigApp.cmake) ################################################################################ # Check Dependencies ################################################################################ ################################# GENIE ###################################### if(GENIE STREQUAL "") cmessage(FATAL_ERROR "Variable GENIE is not defined. " "The location of a pre-built GENIE install must be defined either as" - " $ cmake -DGENIE=/path/to/GENIE or as and environment vairable" + " $ cmake -DGENIE=/path/to/GENIE or as an environment variable" " $ export GENIE=/path/to/GENIE") endif() if (BUILD_GEVGEN) cmessage(STATUS "Building custom gevgen") LIST(APPEND EXTRA_CXX_FLAGS -D__GEVGEN_ENABLED__) endif() if(GENIE_EMPMEC_REWEIGHT) cmessage(STATUS "Enable EMPMEC dials") LIST(APPEND EXTRA_CXX_FLAGS -D__GENIE_EMP_MECRW_ENABLED) endif() # Extract GENIE VERSION if (GENIE_VERSION STREQUAL "AUTO") execute_process (COMMAND ${CMAKE_SOURCE_DIR}/cmake/getgenieversion.sh ${GENIE} OUTPUT_VARIABLE GENIE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) endif() -execute_process (COMMAND genie-config - --libs OUTPUT_VARIABLE GENIE_LD_FLAGS_STR OUTPUT_STRIP_TRAILING_WHITESPACE) -execute_process (COMMAND genie-config - --topsrcdir OUTPUT_VARIABLE GENIE_INCLUDES_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) +execute_process(COMMAND genie-config --version +OUTPUT_VARIABLE GENIE_VER OUTPUT_STRIP_TRAILING_WHITESPACE) +cmessage(STATUS "genie_ver: ${GENIE_VER}") +if(GENIE_VER VERSION_GREATER 3.0.0) + set(GENIE_POST_R3 1) + string(REPLACE "." "" GENIE_VERSION ${GENIE_VER}) + cmessage(STATUS "set genie_post_r3") +endif() -string(REGEX MATCH "-L\([^ ]+\) \(.*\)$" PARSE_GENIE_LIBS_MATCH ${GENIE_LD_FLAGS_STR}) +if(NOT GENIE_POST_R3) +LIST(APPEND EXTRA_CXX_FLAGS -DGENIE_PRE_R3) +cmessage(STATUS "setting genie_pre_r3 ${EXTRA_CXX_FLAGS}") +endif() -cmessage(DEBUG "genie-config --libs: ${GENIE_LD_FLAGS_STR}") +execute_process (COMMAND genie-config + --topsrcdir OUTPUT_VARIABLE GENIE_INCLUDES_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) -if(NOT PARSE_GENIE_LIBS_MATCH) - cmessage(FATAL_ERROR "Expected to be able to parse the result of genie-config --libs to a lib directory and a list of libraries to include, but got: \"${GENIE_LD_FLAGS_STR}\"") +#Allows for external override in the case where genie-config lies. +if(NOT DEFINED GENIE_LIB_DIR OR GENIE_LIB_DIR STREQUAL "") + GETLIBDIRS(genie-config --libs GENIE_LIB_DIR) endif() - -set(GENIE_LIB_DIR ${CMAKE_MATCH_1}) -set(GENIE_LIBS_RAW ${CMAKE_MATCH_2}) -string(REPLACE "-l" "" GENIE_LIBS_STRIPED "${GENIE_LIBS_RAW}") +GETLIBS(genie-config --libs GENIE_LIBS) cmessage(STATUS "GENIE version : ${GENIE_VERSION}") cmessage(STATUS "GENIE libdir : ${GENIE_LIB_DIR}") -cmessage(STATUS "GENIE libs : ${GENIE_LIBS_STRIPED}") +cmessage(STATUS "GENIE libs : ${GENIE_LIBS}") -string(REGEX MATCH "ReinSeghal" WASMATCHED ${GENIE_LIBS_STRIPED}) +string(REGEX MATCH "ReinSeghal" WASMATCHED ${GENIE_LIBS}) if(WASMATCHED AND GENIE_VERSION STREQUAL "210") - set(GENIE_SEHGAL ${GENIE_LIBS_STRIPED}) - STRING(REPLACE "ReinSeghal" "ReinSehgal" GENIE_LIBS_STRIPED ${GENIE_SEHGAL}) - cmessage(DEBUG "Fixed inconsistency in library naming: ${GENIE_LIBS_STRIPED}") + set(GENIE_SEHGAL ${GENIE_LIBS}) + STRING(REPLACE "ReinSeghal" "ReinSehgal" GENIE_LIBS ${GENIE_SEHGAL}) + cmessage(DEBUG "Fixed inconsistency in library naming: ${GENIE_LIBS}") endif() -string(REGEX MATCH "ReWeight" WASMATCHED ${GENIE_LIBS_STRIPED}) -if(NOT WASMATCHED) - set(GENIE_LIBS_STRIPED "GReWeight ${GENIE_LIBS_STRIPED}") - cmessage(DEBUG "Force added ReWeight library: ${GENIE_LIBS_STRIPED}") +if(NOT GENIE_POST_R3) + LIST(FIND GENIE_LIBS GReWeight WAS_FOUND) + if(WAS_FOUND STREQUAL "-1") + LIST(APPEND GENIE_LIBS GReWeight) + cmessage(DEBUG "Force added ReWeight library: ${GENIE_LIBS}") + endif() +else() + LIST(FIND GENIE_LIBS GRwFwk WAS_FOUND) + if(WAS_FOUND STREQUAL "-1") + LIST(APPEND GENIE_LIBS GRwClc GRwFwk GRwIO) + cmessage(DEBUG "Force added ReWeight library: ${GENIE_LIBS}") + endif() endif() -string(REPLACE " " ";" GENIE_LIBS_LIST "-Wl,--no-as-needed -Wl,--start-group ${GENIE_LIBS_STRIPED} -Wl,--end-group") -cmessage(DEBUG "genie-config --libs -- MATCH1: ${CMAKE_MATCH_1}") -cmessage(DEBUG "genie-config --libs -- MATCH2: ${CMAKE_MATCH_2}") -cmessage(DEBUG "genie-config --libs -- libs stripped: ${GENIE_LIBS_STRIPED}") -cmessage(DEBUG "genie-config --libs -- libs list: ${GENIE_LIBS_LIST}") +LIST(APPEND GENIE_LIBS -Wl,--end-group ) +LIST(REVERSE GENIE_LIBS) +LIST(APPEND GENIE_LIBS -Wl,--start-group -Wl,--no-as-needed ) +LIST(REVERSE GENIE_LIBS) + +cmessage(DEBUG "GENIE_LIBS: ${GENIE_LIBS}") ################################ LHAPDF ###################################### if(LHAPDF_LIB STREQUAL "") - cmessage(FATAL_ERROR "Variable LHAPDF_LIB is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_LIB=/path/to/LHAPDF_libraries or as and environment vairable $ export LHAPDF_LIB=/path/to/LHAPDF_libraries") + cmessage(FATAL_ERROR "Variable LHAPDF_LIB is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_LIB=/path/to/LHAPDF_libraries or as an environment variable $ export LHAPDF_LIB=/path/to/LHAPDF_libraries") endif() if(LHAPDF_INC STREQUAL "") - cmessage(FATAL_ERROR "Variable LHAPDF_INC is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_INC=/path/to/LHAPDF_includes or as and environment vairable $ export LHAPDF_INC=/path/to/LHAPDF_includes") + cmessage(FATAL_ERROR "Variable LHAPDF_INC is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_INC=/path/to/LHAPDF_includes or as an environment variable $ export LHAPDF_INC=/path/to/LHAPDF_includes") endif() if(LHAPATH STREQUAL "") - cmessage(FATAL_ERROR "Variable LHAPATH is not defined. The location of a the LHAPATH directory must be defined either as $ cmake -DLHAPATH=/path/to/LHAPATH or as and environment variable $ export LHAPATH=/path/to/LHAPATH") + cmessage(FATAL_ERROR "Variable LHAPATH is not defined. The location of a the LHAPATH directory must be defined either as $ cmake -DLHAPATH=/path/to/LHAPATH or as an environment variable $ export LHAPATH=/path/to/LHAPATH") endif() ################################ LIBXML ###################################### if(LIBXML2_LIB STREQUAL "") - # Check for xml2-config - find_program(LIBXMLCFGLIBS xml2-config) - if(NOT LIBXMLCFGLIBS STREQUAL "LIBXMLLIBS-NOTFOUND") - execute_process (COMMAND ${LIBXMLCFGLIBS} --libs - OUTPUT_VARIABLE LIBXML2_LIB OUTPUT_STRIP_TRAILING_WHITESPACE) - else() - message(FATAL_ERROR "Variable LIBXML2_LIB is not defined and could not find xml2-config. The location of a pre-built libxml2 install must be defined either as $ cmake -DLIBXML2_LIB=/path/to/LIBXML2_libraries or as and environment vairable $ export LIBXML2_LIB=/path/to/LIBXML2_libraries") + GETLIBDIR(xml2-config --libs LIBXML2_LIB IGNORE_EMPTY_RESPONSE) + if(LIBXML2_LIB STREQUAL "") + message(WARNING "Variable LIBXML2_LIB is not defined, as xml2-config was found and didn't report a library include path, it is likely that libxml2.so can be found in the standard system location, lets hope so.") endif() endif() if(LIBXML2_INC STREQUAL "") - # Check for xml2-config - find_program(LIBXMLCFGINCS xml2-config) - if(NOT LIBXMLCFGINCS STREQUAL "LIBXMLINCS-NOTFOUND") - execute_process (COMMAND ${LIBXMLCFGINCS} --cflags - OUTPUT_VARIABLE LIBXML2_INC OUTPUT_STRIP_TRAILING_WHITESPACE) - else() - message(FATAL_ERROR "Variable LIBXML2_INC is not defined and could not find xml2-config. The location of a pre-built libxml2 install must be defined either as $ cmake -DLIBXML2_INC=/path/to/LIBXML2_libraries or as and environment vairable $ export LIBXML2_INC=/path/to/LIBXML2_libraries") + GETINCDIR(xml2-config --cflags LIBXML2_INC) + if(LIBXML2_INC STREQUAL "") + message(FATAL_ERROR "Variable LIBXML2_INC is not defined and could not be found with xml2-config. The location of a pre-built libxml2 install must be defined either as $ cmake -DLIBXML2_INC=/path/to/LIBXML2_includes or as an environment variable $ export LIBXML2_INC=/path/to/LIBXML2_includes") endif() endif() ############################### log4cpp ###################################### if(LOG4CPP_LIB STREQUAL "") - find_program(LOG4CPPCFG log4cpp-config) - if(NOT LOG4CPPCFG STREQUAL "LOG4CPPCFG-NOTFOUND") - execute_process (COMMAND ${LOG4CPPCFG} - --pkglibdir OUTPUT_VARIABLE LOG4CPP_LIB OUTPUT_STRIP_TRAILING_WHITESPACE) - else() - message(FATAL_ERROR "Variable LOG4CPP_LIB is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DLOG4CPP_LIB=/path/to/LOG4CPP_libraries or as and environment vairable $ export LOG4CPP_LIB=/path/to/LOG4CPP_libraries") + GETLIBDIR(log4cpp-config --libs LOG4CPP_LIB) + if(LOG4CPP_LIB STREQUAL "") + message(FATAL_ERROR "Variable LOG4CPP_LIB is not defined and could not be found with log4cpp-config. The location of a pre-built log4cpp install must be defined either as $ cmake -DLOG4CPP_LIB=/path/to/LOG4CPP_libraries or as an environment variable $ export LOG4CPP_LIB=/path/to/LOG4CPP_libraries") endif() endif() -if(LOG4CPP_INC STREQUAL "") - find_program(LOG4CPPCFG log4cpp-config) - if(NOT LOG4CPPCFG STREQUAL "LOG4CPPCFG-NOTFOUND") - execute_process (COMMAND ${LOG4CPPCFG} - --pkgincludedir OUTPUT_VARIABLE LOG4CPP_INC OUTPUT_STRIP_TRAILING_WHITESPACE) - else() - message(FATAL_ERROR "Variable LOG4CPP_INC is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DGENIE_LOG4CPP_INC=/path/to/LOG4CPP_includes or as and environment vairable $ export LOG4CPP_INC=/path/to/LOG4CPP_includes") +if(LOG4CPP_INC STREQUAL "") + GETINCDIR(log4cpp-config --cflags LOG4CPP_INC) + if(LOG4CPP_INC STREQUAL "") + message(FATAL_ERROR "Variable LOG4CPP_INC is not defined and could not be found with log4cpp-config. The location of a pre-built log4cpp install must be defined either as $ cmake -DLOG4CPP_INC=/path/to/LOG4CPP_includes or as an environment variable $ export LOG4CPP_INC=/path/to/LOG4CPP_includes") endif() endif() ################################################################################ LIST(APPEND EXTRA_CXX_FLAGS -D__GENIE_ENABLED__ -D__GENIE_VERSION__=${GENIE_VERSION}) -LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES - ${GENIE_INCLUDES_DIR} - ${GENIE_INCLUDES_DIR}/GHEP - ${GENIE_INCLUDES_DIR}/Ntuple - ${GENIE_INCLUDES_DIR}/ReWeight - ${GENIE_INCLUDES_DIR}/Apps - ${GENIE_INCLUDES_DIR}/FluxDrivers - ${GENIE_INCLUDES_DIR}/EVGDrivers - ${LHAPDF_INC} - ${LIBXML2_INC} - ${LOG4CPP_INC}) +LIST(APPEND EXTRA_LIBS ${GENIE_LIBS}) -SAYVARS() +############################### GSL ###################################### +if(GENIE_POST_R3) + if(GSL_LIB STREQUAL "") + GETLIBDIR(gsl-config --libs GSL_LIB) + if(GSL_LIB STREQUAL "") + message(FATAL_ERROR "Variable GSL_LIB is not defined and could not be found with gsl-config. The location of a pre-built gsl install must be defined either as $ cmake -DGSL_LIB=/path/to/GSL_libraries or as an environment variable $ export GSL_LIB=/path/to/GSL_libraries") + endif() + endif() + + if(GSL_INC STREQUAL "") + GETINCDIR(gsl-config --cflags GSL_INC) + if(GSL_INC STREQUAL "") + message(FATAL_ERROR "Variable GSL_INC is not defined and could not be found with gsl-config. The location of a pre-built gsl install must be defined either as $ cmake -DGSL_INC=/path/to/GSL_includes or as an environment variable $ export GSL_INC=/path/to/GSL_includes") + endif() + endif() + + GETLIBS(gsl-config --libs GSL_LIB_LIST) + + if(GENIE_REWEIGHT STREQUAL "") + message(FATAL_ERROR "Variable GENIE_REWEIGHT is not defined. When using GENIE v3+, we require the reweight product to be built and accessible via the environment variable GENIE_REWEIGHT") + endif() +endif() +################################################################################ + +LIST(APPEND EXTRA_LIBS LHAPDF xml2 log4cpp) LIST(APPEND EXTRA_LINK_DIRS ${GENIE_LIB_DIR} ${LHAPDF_LIB} - ${LIBXML2_LIB} ${LOG4CPP_LIB}) -LIST(APPEND EXTRA_LIBS ${GENIE_LIBS_LIST}) +if(NOT GENIE_POST_R3) + LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES + ${GENIE_INCLUDES_DIR} + ${GENIE_INCLUDES_DIR}/GHEP + ${GENIE_INCLUDES_DIR}/Ntuple + ${GENIE_INCLUDES_DIR}/ReWeight + ${GENIE_INCLUDES_DIR}/Apps + ${GENIE_INCLUDES_DIR}/FluxDrivers + ${GENIE_INCLUDES_DIR}/EVGDrivers + ${LHAPDF_INC} + ${LIBXML2_INC} + ${LOG4CPP_INC}) +else() + LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES + ${GENIE_INCLUDES_DIR} + ${GENIE_REWEIGHT}/src + ${GSL_INC} + ${LHAPDF_INC} + ${LIBXML2_INC} + ${LOG4CPP_INC}) -LIST(APPEND EXTRA_LIBS LHAPDF xml2 log4cpp) + LIST(APPEND EXTRA_LINK_DIRS + ${GENIE_REWEIGHT}/lib + ${GSL_LIB} + ) + + LIST(APPEND EXTRA_LIBS ${GSL_LIB_LIST}) + +endif() + +cmessage(WARNING ${EXTRA_LINK_DIRS}) +cmessage(WARNING ${EXTRA_LIBS}) + +SAYVARS() if(USE_PYTHIA8) set(NEED_PYTHIA8 TRUE) set(NEED_ROOTPYTHIA8 TRUE) else() set(NEED_PYTHIA6 TRUE) set(NEED_ROOTPYTHIA6 TRUE) endif() set(NEED_ROOTEVEGEN TRUE) SET(USE_GENIE TRUE CACHE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. " FORCE) diff --git a/cmake/NOvARwgtSetup.cmake b/cmake/NOvARwgtSetup.cmake new file mode 100644 index 0000000..eb67270 --- /dev/null +++ b/cmake/NOvARwgtSetup.cmake @@ -0,0 +1,14 @@ +if(NOVARWGT STREQUAL "") + cmessage(FATAL_ERROR "Variable NOVARWGT is not defined. " + "The location of a pre-built NOVARWGT install must be defined either as" + " $ cmake -DNOVARWGT=/path/to/NOVARWGT or as an environment variable" + " $ export NOVARWGT=/path/to/NOVARWGT") +endif() + +LIST(APPEND EXTRA_CXX_FLAGS -D__NOVA_ENABLED__) + +LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${NOVARWGT}/inc) + +LIST(APPEND EXTRA_LINK_DIRS ${NOVARWGT}/lib) + +LIST(APPEND EXTRA_LIBS NOvARwgt) diff --git a/cmake/ReweightEnginesSetup.cmake b/cmake/ReweightEnginesSetup.cmake index 16b9e85..4a84f0e 100644 --- a/cmake/ReweightEnginesSetup.cmake +++ b/cmake/ReweightEnginesSetup.cmake @@ -1,87 +1,93 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ ################################## T2K ###################################### if(USE_T2K) include(${CMAKE_SOURCE_DIR}/cmake/T2KSetup.cmake) cmessage(STATUS "Using T2K Reweight engine.") set(USE_T2K TRUE CACHE BOOL "Whether to enable T2KReWeight support. Requires external libraries. " FORCE) endif() ################################## NIWG ###################################### if(USE_NIWG) include(${CMAKE_SOURCE_DIR}/cmake/NIWGSetup.cmake) cmessage(STATUS "Using NIWG Reweight engine.") set(USE_NIWG TRUE CACHE BOOL "Whether to enable (T2K) NIWG ReWeight support. Requires external libraries. " FORCE) endif() ################################## MINERvA ###################################### if(USE_MINERvA_RW) include(${CMAKE_SOURCE_DIR}/cmake/MINERvASetup.cmake) cmessage(STATUS "Using MINERvA Reweight engine.") set(USE_MINERvA_RW TRUE CACHE BOOL "Whether to enable MINERvA ReWeight support. " FORCE) endif() ################################## NEUT ###################################### if(USE_NEUT) include(${CMAKE_SOURCE_DIR}/cmake/NEUTSetup.cmake) cmessage(STATUS "Using NEUT Reweight engine.") set(USE_NEUT TRUE CACHE BOOL "Whether to enable NEUT (reweight) support. Requires external libraries. " FORCE) endif() ################################# NuWro ###################################### if(USE_NuWro) include(${CMAKE_SOURCE_DIR}/cmake/NuWroSetup.cmake) cmessage(STATUS "Using NuWro Reweight engine.") set(USE_NuWro TRUE CACHE BOOL "Whether to enable NuWro support. " FORCE) endif() ################################## GENIE ##################################### if(USE_GENIE) include(${CMAKE_SOURCE_DIR}/cmake/GENIESetup.cmake) cmessage(STATUS "Using GENIE Reweight engine.") set(USE_GENIE TRUE CACHE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. " FORCE) endif() ################################################################################ +################################ NOvARwgt #################################### +if(USE_NOvARwgt) + include(${CMAKE_SOURCE_DIR}/cmake/NOvARwgtSetup.cmake) + cmessage(STATUS "Using NOvARwgt Reweight engine.") + set(USE_NOvARwgt TRUE CACHE BOOL "Whether to enable NOvARwgt (reweight) support. Requires external libraries. " FORCE) +endif() + +################################################################################ ################################ Prob3++ #################################### include(${CMAKE_SOURCE_DIR}/cmake/Prob3++Setup.cmake) ################################################################################ - cmessage(STATUS "Reweight engine include directories: ${RWENGINE_INCLUDE_DIRECTORIES}") if(NEED_ROOTEVEGEN) cmessage(STATUS "Require ROOT eve generation libraries") LIST(REVERSE ROOT_LIBS) LIST(APPEND ROOT_LIBS Gui Ged Geom TreePlayer EG Eve) LIST(REVERSE ROOT_LIBS) endif() if(NEED_ROOTPYTHIA6) cmessage(STATUS "Require ROOT Pythia6 libraries") LIST(APPEND ROOT_LIBS - EGPythia6 - Pythia6) + EGPythia6) endif() LIST(APPEND EXTRA_LIBS ${ROOT_LIBS}) diff --git a/cmake/cacheVariables.cmake b/cmake/cacheVariables.cmake index c7155b3..70e0763 100644 --- a/cmake/cacheVariables.cmake +++ b/cmake/cacheVariables.cmake @@ -1,217 +1,225 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ function(CheckAndSetDefaultEnv VARNAME DEFAULT CACHETYPE DOCSTRING ENVNAME) #cmessage(DEBUG "Trying to assign variable ${VARNAME} into the cache.") if(NOT DEFINED ${VARNAME}) if(DEFINED ENV{${ENVNAME}} AND NOT $ENV{${ENVNAME}} STREQUAL "") set(${VARNAME} $ENV{${ENVNAME}} CACHE ${CACHETYPE} ${DOCSTRING}) cmessage(DEBUG " Read ${VARNAME} from ENVVAR ${ENVNAME} as $ENV{${ENVNAME}}.") else() set(${VARNAME} ${DEFAULT} CACHE ${CACHETYPE} ${DOCSTRING}) endif() else() set(${VARNAME} ${${VARNAME}} CACHE ${CACHETYPE} ${DOCSTRING}) unset(${VARNAME}) endif() cmessage(CACHE "--Set cache variable: \"${VARNAME}\" to \"${${VARNAME}}\", in cache ${CACHETYPE}.") endfunction() function(CheckAndSetDefaultCache VARNAME DEFAULT CACHETYPE DOCSTRING) # cmessage(DEBUG "Trying to assign variable ${VARNAME} into the cache.") if(NOT DEFINED ${VARNAME}) set(${VARNAME} ${DEFAULT} CACHE ${CACHETYPE} ${DOCSTRING}) else() set(${VARNAME} ${${VARNAME}} CACHE ${CACHETYPE} ${DOCSTRING}) unset(${VARNAME}) endif() cmessage(CACHE "--Set cache variable: \"${VARNAME}\" to \"${${VARNAME}}\", in cache ${CACHETYPE}.") endfunction() function(CheckAndSetDefault VARNAME DEFAULT) # cmessage(DEBUG "Trying to assign variable ${VARNAME}.") if(NOT DEFINED ${VARNAME}) set(${VARNAME} ${DEFAULT} PARENT_SCOPE) set(${VARNAME} ${DEFAULT}) endif() cmessage(CACHE "--Set variable: \"${VARNAME}\" to \"${${VARNAME}}\".") endfunction() CheckAndSetDefaultCache(VERBOSE TRUE BOOL "Whether to configure loudly.") set (CMAKE_SKIP_BUILD_RPATH TRUE) #Changes default install path to be a subdirectory of the build dir. #Can set build dir at configure time with -DCMAKE_INSTALL_PREFIX=/install/path if(CMAKE_INSTALL_PREFIX STREQUAL "" OR CMAKE_INSTALL_PREFIX STREQUAL "/usr/local") set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}") elseif(NOT DEFINED CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}") endif() if(CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE DEBUG) elseif(NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE DEBUG) endif() CheckAndSetDefaultCache(EXTRA_SETUP_SCRIPT "" PATH "The path to an extra script to inject into the NUISANCE setup script. <>") CheckAndSetDefaultCache(USE_MINIMIZER TRUE INTERNAL "Whether we are using the ROOT minimization libraries. ") CheckAndSetDefaultCache(USE_ROOT6 FALSE INTERNAL "Whether we are using the ROOT 6. ") CheckAndSetDefaultCache(USE_HEPMC FALSE BOOL "Whether to enable HepMC input support. ") CheckAndSetDefaultEnv(HEPMC "" PATH "Path to HepMC source tree root directory. Overrides environment variable \$HEPMC <>" HEPMC) CheckAndSetDefaultCache(HEPMC_MOMUNIT "GEV" STRING "HepMC momentum units [MEV|GEV]. ") CheckAndSetDefaultCache(HEPMC_LENUNIT "CM" STRING "HepMC momentum units [MM|CM]. ") CheckAndSetDefaultCache(HEPMC_USED_EP FALSE INTERNAL "Whether we built HepMC or not. ") CheckAndSetDefaultCache(USE_NEUT FALSE BOOL "Whether to enable NEUT (reweight) support. Requires external libraries. ") CheckAndSetDefaultEnv(NEUT_VERSION FALSE STRING "NEUT version string, e.g. 5.4.0. <5.4.0>" NEUT_VERSION) CheckAndSetDefaultEnv(NEUT_ROOT "" PATH "Path to NEUT source tree root directory. Overrides environment variable \$NEUT_ROOT <>" NEUT_ROOT) CheckAndSetDefaultEnv(CERN "" PATH "Path to CERNLIB source tree root directory that NEUT was built against. Overrides environment variable \$CERN <>" CERN) CheckAndSetDefaultEnv(CERN_LEVEL "" STRING "CERNLIB Library version. Overrides environment variable \$CERN_LEVEL <>" CERN_LEVEL) CheckAndSetDefaultCache(USE_NuWro FALSE BOOL "Whether to enable NuWro support. ") CheckAndSetDefaultEnv(NUWRO "" PATH "Path to NuWro source tree root directory. Overrides environment variable \$NUWRO <>" NUWRO) CheckAndSetDefaultEnv(NUWRO_INC "" PATH "Path to NuWro installed includes directory, needs to contain \"params_all.h\". Overrides environment variable \$NUWRO_INC <>" NUWRO_INC) CheckAndSetDefaultCache(NUWRO_INPUT_FILE "" FILEPATH "Path to an input NuWro event vector, which can be used to build NuWro i/o libraries. <>") CheckAndSetDefaultCache(NUWRO_BUILT_FROM_FILE FALSE INTERNAL "Whether the NuWro libraries were built by NUISANCE. ") CheckAndSetDefaultCache(USE_NuWro_RW FALSE BOOL "Whether to try and build support for NuWro reweighting. ") CheckAndSetDefaultCache(USE_NuWro_SRW_Event FALSE BOOL "Whether to use cut down NuWro reweight event format. Requires NuWro reweight. ") CheckAndSetDefaultCache(USE_GENIE FALSE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. ") CheckAndSetDefaultCache(GENIE_VERSION "AUTO" STRING "GENIE Version ") CheckAndSetDefaultEnv(GENIE "" PATH "Path to GENIE source tree root directory. Overrides environment variable \$GENIE <>" GENIE) +CheckAndSetDefaultEnv(GENIE_REWEIGHT "" PATH "Path to GENIE ReWeight directory. Only relevant for GENIE v3+. Overrides environment variable \$GENIE_REWEIGHT <>" GENIE_REWEIGHT) CheckAndSetDefaultCache(GENIE_EMPMEC_REWEIGHT FALSE BOOL "Whether to use GENIE EMP MEC reweight (requires custom GENIE) ") CheckAndSetDefaultEnv(LHAPDF_LIB "" PATH "Path to pre-built LHAPDF libraries. Overrides environment variable \$LHAPDF_LIB. <>" LHAPDF_LIB) CheckAndSetDefaultEnv(LHAPDF_INC "" PATH "Path to installed LHAPDF headers. Overrides environment variable \$LHAPDF_INC. <>" LHAPDF_INC) CheckAndSetDefaultEnv(LHAPATH "" PATH "Path to LHA PDF inputs. Overrides environment variable \$LHAPATH. <>" LHAPATH) CheckAndSetDefaultEnv(LIBXML2_LIB "" PATH "Path to pre-built LIBXML2 libraries. Overrides environment variable \$LIBXML2_LIB. <>" LIBXML2_LIB) CheckAndSetDefaultEnv(LIBXML2_INC "" PATH "Path to installed LIBXML2 headers. Overrides environment variable \$LIBXML2_INC. <>" LIBXML2_INC) CheckAndSetDefaultEnv(LOG4CPP_LIB "" PATH "Path to pre-built LOG4CPP libraries. Overrides environment variable \$LOG4CPP_LIB. <>" LOG4CPP_LIB) CheckAndSetDefaultEnv(LOG4CPP_INC "" PATH "Path to installed LOG4CPP headers. Overrides environment variable \$LOG4CPP_INC. <>" LOG4CPP_INC) +CheckAndSetDefaultEnv(GSL_LIB "" PATH "Path to pre-built gsl libraries. Overrides environment variable \$GSL_LIB. <>" GSL_LIB) +CheckAndSetDefaultEnv(GSL_INC "" PATH "Path to installed gsl headers. Overrides environment variable \$GSL_INC. <>" GSL_INC) CheckAndSetDefaultCache(BUILD_GEVGEN FALSE BOOL "Whether to build nuisance_gevgen app.") CheckAndSetDefaultCache(USE_T2K FALSE BOOL "Whether to enable T2KReWeight support. Requires external libraries. ") CheckAndSetDefaultEnv(T2KREWEIGHT "" PATH "Path to installed T2KREWEIGHTReWeight. Overrides environment variable \$T2KREWEIGHT. <>" T2KREWEIGHT) CheckAndSetDefaultCache(USE_NIWG FALSE BOOL "Whether to enable (T2K) NIWG ReWeight support. Requires external libraries. ") CheckAndSetDefaultEnv(NIWG_ROOT "" PATH "Path to installed NIWGReWeight. Overrides environment variable \$NIWG. <>" NIWG) CheckAndSetDefaultCache(USE_MINERvA_RW FALSE BOOL "Whether to enable MINERvA ReWeight support. ") +CheckAndSetDefaultCache(USE_NOvARwgt FALSE BOOL "Whether to enable MINERvA ReWeight support. ") + +CheckAndSetDefaultEnv(NOVARWGT "" PATH "Path to directory containing libPythia6.so. Overrides environment variable \$NOVARWGT <>" NOVARWGT) + + CheckAndSetDefaultEnv(PYTHIA6 "" PATH "Path to directory containing libPythia6.so. Overrides environment variable \$PYTHIA6 <>" PYTHIA6) CheckAndSetDefaultEnv(PYTHIA8 "" PATH "Path to directory containing libPythia8.so. Overrides environment variable \$PYTHIA8 <>" PYTHIA8) CheckAndSetDefaultCache(USE_PYTHIA8 FALSE BOOL "Whether to enable PYTHIA8 event support. ") CheckAndSetDefaultCache(USE_GiBUU TRUE BOOL "Whether to enable GiBUU event support. ") CheckAndSetDefaultCache(BUILD_GiBUU FALSE BOOL "Whether to build supporting GiBUU event tools along with a patched version of GiBUU. ") CheckAndSetDefaultCache(USE_NUANCE TRUE BOOL "Whether to enable NUANCE event support. ") CheckAndSetDefaultCache(USE_PROB3PP FALSE BOOL "Whether to download and compile in Prob3++ support. ") CheckAndSetDefaultCache(NO_EXTERNAL_UPDATE FALSE BOOL "Whether to perform the update target for external dependencies. Note this may produce errors for CMake < 3.8 where a bug was fixed for the feature that this option invokes. ") CheckAndSetDefaultCache(USE_GPERFTOOLS FALSE BOOL "Whether to compile in google performance tools. ") CheckAndSetDefault(NEED_PYTHIA6 FALSE) CheckAndSetDefault(NEED_PYTHIA8 FALSE) CheckAndSetDefault(NEED_ROOTEVEGEN FALSE) CheckAndSetDefault(NEED_ROOTPYTHIA6 FALSE) CheckAndSetDefaultCache(USE_OMP FALSE BOOL "Whether to enable multicore features (there currently are none...). ") CheckAndSetDefaultCache(USE_DYNSAMPLES TRUE BOOL "Whether to enable the dynamic sample loader. ") CheckAndSetDefault(NO_EXPERIMENTS FALSE) cmessage(STATUS "NO_EXPERIMENTS: ${NO_EXPERIMENTS}") CheckAndSetDefaultCache(NO_ANL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ANL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_ArgoNeuT ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ArgoNeuT samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_BEBC ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BEBC samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_BNL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BNL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_FNAL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build FNAL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_GGM ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build GGM samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_K2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build K2K samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_MINERvA ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MINERvA samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_MiniBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MiniBooNE samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_T2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build T2K samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_SciBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build SciBooNE samples. <-DNO_EXPERIMENTS=FALSE>") function(SAYVARS) LIST(APPEND VARS USE_HEPMC HEPMC HEPMC_MOMUNIT HEPMC_LENUNIT HEPMC_USED_EP USE_NEUT NEUT_ROOT CERN CERN_LEVEL USE_NuWro NUWRO NUWRO_INC NUWRO_INPUT_FILE NUWRO_BUILT_FROM_FILE USE_GENIE GENIE LHAPDF_LIB LHAPDF_INC LIBXML2_LIB LIBXML2_INC LOG4CPP_LIB GENIE_LOG4CPP_INC BUILD_GEVGEN USE_T2K USE_NIWG USE_GiBUU BUILD_GiBUU USE_NUANCE NO_EXTERNAL_UPDATE USE_GPERFTOOLS NO_ANL NO_ArgoNeuT NO_BEBC NO_BNL NO_FNAL NO_GGM NO_K2K NO_MINERvA NO_MiniBooNE NO_T2K NO_SciBooNE) foreach(v ${VARS}) if(DEFINED ${v}) cmessage(DEBUG "VARIABLE: \"${v}\" = \"${${v}}\"") endif() endforeach(v) endfunction() diff --git a/cmake/parseConfigApp.cmake b/cmake/parseConfigApp.cmake new file mode 100644 index 0000000..2f72ce5 --- /dev/null +++ b/cmake/parseConfigApp.cmake @@ -0,0 +1,148 @@ +function(GETFIRSTMATCHINGDELMIMMEDDIR DELIM CONFIGAPP ARG DIR_OUT FAILURE_IS_NOT_ERROR) + + cmessage(DEBUG "CONFIGAPP: ${CONFIGAPP}, ARG: ${ARG} DIR_OUT: ${DIR_OUT}, FAILURE_IS_NOT_ERROR: ${FAILURE_IS_NOT_ERROR}") + + if(DELIM STREQUAL "") + cmessage(FATAL_ERROR "GETFIRSTMATCHINGDELMIMMEDDIR Passed no delimiter. This is a build configuration bug in NUISANCE, please report to the developers.") + endif() + + if(CONFIGAPP STREQUAL "") + cmessage(FATAL_ERROR "GETFIRSTMATCHINGDELMIMMEDDIR Passed no configuration application. This is a build configuration bug in NUISANCE, please report to the developers.") + endif() + + SET(CONFIGAPP_LOCATION "CONFIGAPP_LOCATION-NOTFOUND") + find_program(CONFIGAPP_LOCATION ${CONFIGAPP}) + if(NOT CONFIGAPP_LOCATION STREQUAL "CONFIGAPP_LOCATION-NOTFOUND") + execute_process (COMMAND ${CONFIGAPP_LOCATION} + ${ARG} OUTPUT_VARIABLE CONFIGAPP_RESPONSE_RAW OUTPUT_STRIP_TRAILING_WHITESPACE) + + cmessage(DEBUG "${CONFIGAPP_LOCATION} ${ARG} responded with: \"${CONFIGAPP_RESPONSE_RAW}\"") + + if(CONFIGAPP_RESPONSE_RAW STREQUAL "") + if(FAILURE_IS_NOT_ERROR) + cmessage(DEBUG "\"${CONFIGAPP_LOCATION} ${ARG}\" produced no output and was expected to.") + set(${DIR_OUT} "" PARENT_SCOPE) + else() + cmessage(FATAL_ERROR "\"${CONFIGAPP_LOCATION} ${ARG}\" produced no output and was required to.") + endif() + else() + string(REGEX MATCH "${DELIM}\([^ ]+\)" PARSE_CONFIGAPP_RESPONSE_MATCH ${CONFIGAPP_RESPONSE_RAW}) + + if(NOT PARSE_CONFIGAPP_RESPONSE_MATCH) + if(FAILURE_IS_NOT_ERROR) + cmessage(DEBUG "Couldn't find ${DELIM} flag, found: \"${CONFIGAPP_RESPONSE_RAW}\"") + set(${CMAKE_MATCH_1} "") + else() + cmessage(FATAL_ERROR "Expected to be able to parse the result of ${CONFIGAPP} ${ARG} to a lib directory, but couldn't find a ${DELIM} flag, found: \"${CONFIGAPP_RESPONSE_RAW}\"") + endif() + endif() + + set(${DIR_OUT} ${CMAKE_MATCH_1} PARENT_SCOPE) + endif() + else() + cmessage(FATAL_ERROR "[ERROR]: Failed to find dependency configuration application: \"${CONFIGAPP}\"") + endif() +endfunction() + +#Uselike GETLIBDIR(gsl-config --libs GSL_LIB_DIR) +function(GETLIBDIR CONFIGAPP ARG LIBDIR_OUT) + if(ARGN) + set(FAILURE_IS_NOT_ERROR TRUE) + else() + set(FAILURE_IS_NOT_ERROR FALSE) + endif() + GETFIRSTMATCHINGDELMIMMEDDIR( + "-L" + ${CONFIGAPP} + ${ARG} + MATCHING_DIR + ${FAILURE_IS_NOT_ERROR}) + set(${LIBDIR_OUT} ${MATCHING_DIR} PARENT_SCOPE) +endfunction() + +#Uselike GETINCDIR(gsl-config --cflags GSL_INC_DIR) +function(GETINCDIR CONFIGAPP ARG INCDIR_OUT) + if(ARGN) + set(FAILURE_IS_NOT_ERROR TRUE) + else() + set(FAILURE_IS_NOT_ERROR FALSE) + endif() + GETFIRSTMATCHINGDELMIMMEDDIR( + "-I" + ${CONFIGAPP} + ${ARG} + MATCHING_DIR + ${FAILURE_IS_NOT_ERROR}) + set(${INCDIR_OUT} ${MATCHING_DIR} PARENT_SCOPE) +endfunction() + +function(GETALLMATCHINGDELMIMMEDDIR DELIM CONFIGAPP ARG LIST_OUT) + if(DELIM STREQUAL "") + cmessage(FATAL_ERROR "GETALLMATCHINGDELMIMMEDDIR Passed no delimiter. This is a build configuration bug in NUISANCE, please report to the developers.") + endif() + + if(CONFIGAPP STREQUAL "") + cmessage(FATAL_ERROR "GETALLMATCHINGDELMIMMEDDIR Passed no configuration application. This is a build configuration bug in NUISANCE, please report to the developers.") + endif() + + #cmessage(WARNING "DELIM: ${DELIM}, CONFIGAPP: ${CONFIGAPP}, ARG: ${ARG}, LIST_OUT: ${LIST_OUT}") + + SET(CONFIGAPP_LOCATION "CONFIGAPP_LOCATION-NOTFOUND") + find_program(CONFIGAPP_LOCATION ${CONFIGAPP}) + if(NOT CONFIGAPP_LOCATION STREQUAL "CONFIGAPP_LOCATION-NOTFOUND") + execute_process (COMMAND ${CONFIGAPP_LOCATION} + ${ARG} OUTPUT_VARIABLE CONFIGAPP_RESPONSE_RAW OUTPUT_STRIP_TRAILING_WHITESPACE) + + string(REPLACE " " ";" CONFIGAPP_RESPONSE_LIST "${CONFIGAPP_RESPONSE_RAW}") + + # cmessage(WARNING "CONFIGAPP_RESPONSE_RAW: ${CONFIGAPP_RESPONSE_RAW}, CONFIGAPP_RESPONSE_LIST: ${CONFIGAPP_RESPONSE_LIST}") + + set(LIST_BUILD) + + foreach(I ${CONFIGAPP_RESPONSE_LIST}) + if(I) + string(REGEX MATCH "^${DELIM}" WASMATCHED ${I}) + if(WASMATCHED) + string(REPLACE "${DELIM}" "" I_STRIPPED "${I}") + LIST(APPEND LIST_BUILD ${I_STRIPPED}) + endif() + endif() + endforeach() + + set(${LIST_OUT} ${LIST_BUILD} PARENT_SCOPE) + else() + cmessage(FATAL_ERROR "[ERROR]: Failed to find dependency configuration application: \"${CONFIGAPP}\"") + endif() +endfunction() + +#Uselike GETLIBDIRS(gsl-config --libs GSL_LIB_DIR) +function(GETLIBDIRS CONFIGAPP ARG LIBDIR_OUT) + GETALLMATCHINGDELMIMMEDDIR( + "-L" + ${CONFIGAPP} + ${ARG} + MATCHING_DIR) + set(${LIBDIR_OUT} ${MATCHING_DIR} PARENT_SCOPE) +endfunction() + +#Uselike GETINCDIRS(gsl-config --cflags GSL_INC_DIR) +function(GETINCDIRS CONFIGAPP ARG INCDIR_OUT) + GETALLMATCHINGDELMIMMEDDIR( + "-I" + ${CONFIGAPP} + ${ARG} + MATCHING_DIR) + set(${INCDIR_OUT} ${MATCHING_DIR} PARENT_SCOPE) +endfunction() + +#Uselike GETLIBS(gsl-config --libs GSL_LIB_DIR) +function(GETLIBS CONFIGAPP ARG LIBLIST_OUT) + #cmessage(WARNING "LIBLIST_OUT: ${LIBLIST_OUT}") + GETALLMATCHINGDELMIMMEDDIR( + "-l" + ${CONFIGAPP} + ${ARG} + MATCHING_ITEMS) + set(${LIBLIST_OUT} ${MATCHING_ITEMS} PARENT_SCOPE) + #cmessage(WARNING "LIBLIST_OUT: ${LIBLIST_OUT}: ${${LIBLIST_OUT}}") +endfunction() diff --git a/cmake/pythia6Setup.cmake b/cmake/pythia6Setup.cmake index 012fa34..1a89b0c 100644 --- a/cmake/pythia6Setup.cmake +++ b/cmake/pythia6Setup.cmake @@ -1,31 +1,29 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ if(NEED_PYTHIA6) if(PYTHIA6 STREQUAL "") cmessage(FATAL_ERROR "Variable PYTHIA6 is not defined. This must be set to point to a prebuilt PYTHIA6 instance, please set the \$PYTHIA6 environment variable or configure with -DPYTHIA6=/path/to/pythia6.") endif() LIST(APPEND EXTRA_LINK_DIRS ${PYTHIA6}) - LIST(REVERSE EXTRA_LIBS) LIST(APPEND EXTRA_LIBS Pythia6 gfortran) - LIST(REVERSE EXTRA_LIBS) endif() diff --git a/cmake/setup.sh.in b/cmake/setup.sh.in index 123aaef..caf39bd 100644 --- a/cmake/setup.sh.in +++ b/cmake/setup.sh.in @@ -1,155 +1,165 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ #!/bin/sh ### Adapted from https://unix.stackexchange.com/questions/4965/keep-duplicates-out-of-path-on-source function add_to_PATH () { for d; do d=$(cd -- "$d" && { pwd -P || pwd; }) 2>/dev/null # canonicalize symbolic links if [ -z "$d" ]; then continue; fi # skip nonexistent directory if [ "$d" == "/usr/bin" ] || [ "$d" == "/usr/bin64" ] || [ "$d" == "/usr/local/bin" ] || [ "$d" == "/usr/local/bin64" ]; then case ":$PATH:" in *":$d:"*) :;; *) export PATH=$PATH:$d;; esac else case ":$PATH:" in *":$d:"*) :;; *) export PATH=$d:$PATH;; esac fi done } function add_to_LD_LIBRARY_PATH () { for d; do d=$(cd -- "$d" && { pwd -P || pwd; }) 2>/dev/null # canonicalize symbolic links if [ -z "$d" ]; then continue; fi # skip nonexistent directory if [ "$d" == "/usr/lib" ] || [ "$d" == "/usr/lib64" ] || [ "$d" == "/usr/local/lib" ] || [ "$d" == "/usr/local/lib64" ]; then case ":$LD_LIBRARY_PATH:" in *":$d:"*) :;; *) export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$d;; esac else case ":$LD_LIBRARY_PATH:" in *":$d:"*) :;; *) export LD_LIBRARY_PATH=$d:$LD_LIBRARY_PATH;; esac fi done } if [ "@EXTRA_SETUP_SCRIPT@" ]; then if [ ! -e @EXTRA_SETUP_SCRIPT@ ]; then echo "[WARN]: Extra setup script \"@EXTRA_SETUP_SCRIPT@\" requested, but could not be found. Skipping..." else echo "[INFO]: Sourcing extra setup from \"@EXTRA_SETUP_SCRIPT@\"." . @EXTRA_SETUP_SCRIPT@ fi fi add_to_PATH "@CMAKE_INSTALL_PREFIX@/bin" add_to_LD_LIBRARY_PATH "@CMAKE_INSTALL_PREFIX@/lib" if [ ! "${ROOTSYS}" ]; then echo "[INFO]: Sourcing ROOT from: @CMAKE_ROOTSYS@" source "@CMAKE_ROOTSYS@/bin/thisroot.sh" fi if [ "@USE_T2K@" != "FALSE" ]; then echo "[INFO]: Adding T2K paths to the environment." export T2KREWEIGHT=@T2KREWEIGHT@ add_to_LD_LIBRARY_PATH "@T2KREWEIGHT@/lib" fi if [ "@USE_NIWG@" != "FALSE" ]; then echo "[INFO]: Adding NIWG paths to the environment." export NIWG=@NIWG_ROOT@ export NIWGREWEIGHT_INPUTS=@NIWG_ROOT@/inputs add_to_LD_LIBRARY_PATH "@NIWG_ROOT@" fi if [ "@USE_NEUT@" != "FALSE" ]; then echo "[INFO]: Adding NEUT library paths to the environment." export NEUT_ROOT=@NEUT_ROOT@ export CERN=@CERN@ export CERN_LEVEL=@CERN_LEVEL@ add_to_LD_LIBRARY_PATH "${NEUT_LIB_DIR}" "${NEUT_ROOT}/src/reweight" fi if [ "@USE_NuWro@" != "FALSE" ]; then if [ "@NUWRO_BUILT_FROM_FILE@" == "FALSE" ]; then echo "[INFO]: Adding NuWro library paths to the environment." export NUWRO="@NUWRO@" add_to_PATH "@NUWRO@/bin" add_to_LD_LIBRARY_PATH "@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib" if [ "@NUWRO_INC@" ]; then export NUWRO_INC=@NUWRO_INC@ fi else echo "[INFO]: NuWro support included from input event file." fi fi if [ "@NEED_PYTHIA6@" != "FALSE" ]; then echo "[INFO]: Adding PYTHIA6 library paths to the environment." export PYTHIA6="@PYTHIA6@" add_to_LD_LIBRARY_PATH "@PYTHIA6@" fi if [ "@USE_GENIE@" != "FALSE" ]; then echo "[INFO]: Adding GENIE paths to the environment." export GENIE="@GENIE@" export LHAPDF_LIB="@LHAPDF_LIB@" export LHAPDF_INC="@LHAPDF_INC@" export LIBXML2_LIB="@LIBXML2_LIB@" export LIBXML2_INC="@LIBXML2_INC@" export LOG4CPP_LIB="@LOG4CPP_LIB@" export LOG4CPP_INC="@LOG4CPP_INC@" if [ "@LHAPATH@" ]; then export LHAPATH="@LHAPATH@" fi add_to_PATH "@GENIE@/bin" add_to_LD_LIBRARY_PATH "@GENIE@/lib" "@LHAPDF_LIB@" "@LIBXML2_LIB@" "@LOG4CPP_LIB@" + if [ "@GENIE_REWEIGHT@" ]; then + export GENIE_REWEIGHT="@GENIE_REWEIGHT@" + add_to_LD_LIBRARY_PATH "@GENIE_REWEIGHT@/lib" + fi + fi if [ "@BUILD_GiBUU@" != "FALSE" ]; then echo "[INFO]: Sourcing GiBUU tools." source @CMAKE_BINARY_DIR@/GiBUUTools/src/GiBUUTools-build/Linux/setup.sh fi +if [ "@USE_NOvARwgt@" != "FALSE" ]; then + export NOVARWGT=@NOVARWGT@ + add_to_LD_LIBRARY_PATH @NOVARWGT@/lib +fi + export NUISANCE="@CMAKE_SOURCE_DIR@" diff --git a/data/ArgoNeuT/CC1Pi_dsig_dmumom_nu.dat b/data/ArgoNeuT/CC1Pi_dsig_dmumom_nu.dat new file mode 100644 index 0000000..fa43e3f --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dmumom_nu.dat @@ -0,0 +1,8 @@ +# Bin (GeV/c), dsig/dp_mu (10^-38 cm^2 /nucleon /GeV /c), Error +# PRD 98, 052002 (2018) +0 0.0413 0.0280 +3 0.0563 0.0182 +6 0.0363 0.0129 +12 0.0063 0.0047 +21 0.0039 0.0025 +30 0.0000 0.0000 diff --git a/data/ArgoNeuT/CC1Pi_dsig_dmumom_nubar.dat b/data/ArgoNeuT/CC1Pi_dsig_dmumom_nubar.dat new file mode 100644 index 0000000..e70666a --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dmumom_nubar.dat @@ -0,0 +1,7 @@ +# Bin (GeV/c), dsig/dp_mu (10^-38 cm^2 /nucleon /GeV /c), Error +# PRD 98, 052002 (2018) +0 0.0336 0.0068 +3 0.0215 0.0042 +6 0.0066 0.0025 +9 0.0016 0.0009 +15 0.0000 0.0000 diff --git a/data/ArgoNeuT/CC1Pi_dsig_dthetamu_nu.dat b/data/ArgoNeuT/CC1Pi_dsig_dthetamu_nu.dat new file mode 100644 index 0000000..b30f5df --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dthetamu_nu.dat @@ -0,0 +1,7 @@ +# Bin (GeV/c), dsig/dtheta_mu (10^-38 cm^2 /nucleon /degree), Error +# PRD 98, 052002 (2018) + 0 0.0366 0.0112 + 8 0.0261 0.0082 +16 0.0104 0.0057 +24 0.0011 0.0016 +60 0.0000 0.0000 diff --git a/data/ArgoNeuT/CC1Pi_dsig_dthetamu_nubar.dat b/data/ArgoNeuT/CC1Pi_dsig_dthetamu_nubar.dat new file mode 100644 index 0000000..90bb5e6 --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dthetamu_nubar.dat @@ -0,0 +1,9 @@ +# Bin (GeV/c), dsig/dtheta_mu (10^-38 cm^2 /nucleon /degree), Error +# PRD 98, 052002 (2018) + 0 0.0071 0.0023 + 5 0.0100 0.0024 + 10 0.0104 0.0022 + 15 0.0060 0.0018 + 20 0.0019 0.0014 + 25 0.0010 0.0005 + 40 0.0000 0.0000 diff --git a/data/ArgoNeuT/CC1Pi_dsig_dthetamupi_nu.dat b/data/ArgoNeuT/CC1Pi_dsig_dthetamupi_nu.dat new file mode 100644 index 0000000..fd5be42 --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dthetamupi_nu.dat @@ -0,0 +1,9 @@ +# Bin (GeV/c), dsig/dtheta_mupi (10^-38 cm^2 /nucleon /degree), Error +# PRD 98, 052002 (2018) + 0 0.0015 0.0025 + 24 0.0091 0.0031 + 48 0.0066 0.0028 + 72 0.0044 0.0016 +105 0.0019 0.0010 +142 0.0004 0.0005 +180 0.0000 0.0000 diff --git a/data/ArgoNeuT/CC1Pi_dsig_dthetamupi_nubar.dat b/data/ArgoNeuT/CC1Pi_dsig_dthetamupi_nubar.dat new file mode 100644 index 0000000..8f065aa --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dthetamupi_nubar.dat @@ -0,0 +1,12 @@ +# Bin (GeV/c), dsig/dtheta_mupi (10^-38 cm^2 /nucleon /degree), Error +# PRD 98, 052002 (2018) + 0 0.0006 0.0005 + 18 0.0018 0.0005 + 36 0.0017 0.0005 + 54 0.0022 0.0006 + 72 0.0017 0.0006 + 90 0.0012 0.0004 +108 0.0009 0.0004 +126 0.0010 0.0004 +144 0.0002 0.0003 +180 0.0000 0.0000 diff --git a/data/ArgoNeuT/CC1Pi_dsig_dthetapi_nu.dat b/data/ArgoNeuT/CC1Pi_dsig_dthetapi_nu.dat new file mode 100644 index 0000000..b390f9c --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dthetapi_nu.dat @@ -0,0 +1,8 @@ +# Bin (GeV/c), dsig/dtheta_pi (10^-38 cm^2 /nucleon /degree), Error +# PRD 98, 052002 (2018) + 0 0.0060 0.0037 + 25 0.0062 0.0025 + 50 0.0101 0.0029 + 75 0.0020 0.0009 +125 0.0002 0.0004 +180 0.0000 0.0000 diff --git a/data/ArgoNeuT/CC1Pi_dsig_dthetapi_nubar.dat b/data/ArgoNeuT/CC1Pi_dsig_dthetapi_nubar.dat new file mode 100644 index 0000000..911e463 --- /dev/null +++ b/data/ArgoNeuT/CC1Pi_dsig_dthetapi_nubar.dat @@ -0,0 +1,12 @@ +# Bin (GeV/c), dsig/dtheta_pi (10^-38 cm^2 /nucleon /degree), Error +# PRD 98, 052002 (2018) + 0 0.0014 0.0005 + 18 0.0015 0.0006 + 36 0.0021 0.0005 + 54 0.0021 0.0005 + 72 0.0014 0.0004 + 90 0.0010 0.0004 +108 0.0014 0.0004 +126 0.0005 0.0003 +144 0.0002 0.0003 +180 0.0000 0.0000 diff --git a/parameters/config.xml b/parameters/config.xml index b4a01c0..f093aee 100644 --- a/parameters/config.xml +++ b/parameters/config.xml @@ -1,215 +1,219 @@ + + + + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.cxx new file mode 100644 index 0000000..4e53199 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.cxx @@ -0,0 +1,87 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu::ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("p_{#mu} (GeV)"); + fSettings.SetYTitle("d#sigma/dp_{#mu} (cm^{2} Ar^{-1} GeV^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #bar#nu_{#mu} 1Dp_{#mu}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dmumom_nubar.dat" ); + fSettings.DefineAllowedSpecies("numubar"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu::FillEventVariables(FitEvent *event) { + FitParticle* pmu = event->GetHMFSParticle(-13); + if (pmu) fXVar = pmu->fP.Vect().Mag() / 1000; + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, -14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.h new file mode 100644 index 0000000..cbb3562 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.cxx new file mode 100644 index 0000000..5a60f73 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.cxx @@ -0,0 +1,87 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dpmu_nu::ArgoNeuT_CC1Pi_XSec_1Dpmu_nu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dpmu_nu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("p_{#mu} (GeV)"); + fSettings.SetYTitle("d#sigma/dp_{#mu} (cm^{2} Ar^{-1} GeV^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #nu_{#mu} 1Dp_{#mu}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dmumom_nu.dat" ); + fSettings.DefineAllowedSpecies("numu"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dpmu_nu::FillEventVariables(FitEvent *event) { + FitParticle* pmu = event->GetHMFSParticle(13); + if (pmu) fXVar = pmu->fP.Vect().Mag() / 1000; + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dpmu_nu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, 14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.h new file mode 100644 index 0000000..3a6309f --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dpmu_nu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dpmu_nu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dpmu_nu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dpmu_nu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dpmu_nu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.cxx new file mode 100644 index 0000000..c6cbce8 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.cxx @@ -0,0 +1,87 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu::ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("#theta_{#mu} (GeV)"); + fSettings.SetYTitle("d#sigma/d#theta_{#mu} (cm^{2} nucleon^{-1} degree^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #bar#nu_{#mu} 1D#theta_{#mu}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dthetamu_nubar.dat" ); + fSettings.DefineAllowedSpecies("numubar"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu::FillEventVariables(FitEvent *event) { + FitParticle* pmu = event->GetHMFSParticle(-13); + if (pmu) fXVar = pmu->fP.Vect().Theta() * 180.0 / TMath::Pi(); + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, -14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.h new file mode 100644 index 0000000..2af9178 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.cxx new file mode 100644 index 0000000..3629843 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.cxx @@ -0,0 +1,87 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu::ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("#theta_{#mu} (GeV)"); + fSettings.SetYTitle("d#sigma/d#theta_{#mu} (cm^{2} nucleon^{-1} degree^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #nu_{#mu} 1D#theta_{#mu}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dthetamu_nu.dat" ); + fSettings.DefineAllowedSpecies("numu"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu::FillEventVariables(FitEvent *event) { + FitParticle* pmu = event->GetHMFSParticle(13); + if (pmu) fXVar = pmu->fP.Vect().Theta() * 180.0 / TMath::Pi(); + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, 14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.h new file mode 100644 index 0000000..21438a3 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.cxx new file mode 100644 index 0000000..13d90ec --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.cxx @@ -0,0 +1,88 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu::ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("#theta_{#mu#pi} (GeV)"); + fSettings.SetYTitle("d#sigma/d#theta_{#mu#pi} (cm^{2} nucleon^{-1} degree^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #bar#nu_{#mu} 1D#theta_{#mu#pi}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dthetamupi_nubar.dat" ); + fSettings.DefineAllowedSpecies("numubar"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu::FillEventVariables(FitEvent *event) { + FitParticle* pmu = event->GetHMFSParticle(-13); + FitParticle* ppi = event->GetHMFSChargePions(); + if (pmu && ppi) fXVar = pmu->fP.Vect().Angle(ppi->fP.Vect()) * 180.0 / TMath::Pi(); + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, -14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.h new file mode 100644 index 0000000..1cab874 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.cxx new file mode 100644 index 0000000..19350ad --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.cxx @@ -0,0 +1,88 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu::ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("#theta_{#mu#pi} (GeV)"); + fSettings.SetYTitle("d#sigma/d#theta_{#mu#pi} (cm^{2} nucleon^{-1} degree^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #nu_{#mu} 1D#theta_{#mu#pi}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dthetamupi_nu.dat" ); + fSettings.DefineAllowedSpecies("numu"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu::FillEventVariables(FitEvent *event) { + FitParticle* pmu = event->GetHMFSParticle(13); + FitParticle* ppi = event->GetHMFSChargePions(); + if (pmu && ppi) fXVar = pmu->fP.Vect().Angle(ppi->fP.Vect()) * 180.0 / TMath::Pi(); + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, 14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.h new file mode 100644 index 0000000..b9f3a0e --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.cxx new file mode 100644 index 0000000..d037562 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.cxx @@ -0,0 +1,87 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu::ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("#theta_{#pi} (GeV)"); + fSettings.SetYTitle("d#sigma/d#theta_{#pi} (cm^{2} nucleon^{-1} degree^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #bar#nu_{#mu} 1D#theta_{#pi}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dthetapi_nubar.dat" ); + fSettings.DefineAllowedSpecies("numubar"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu::FillEventVariables(FitEvent *event) { + FitParticle* p = event->GetHMFSChargePions(); + if (p) fXVar = p->fP.Vect().Theta() * 180.0 / TMath::Pi(); + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, -14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.h new file mode 100644 index 0000000..8444f08 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.cxx b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.cxx new file mode 100644 index 0000000..f357f6b --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.cxx @@ -0,0 +1,87 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ +#include "ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.h" + + +//******************************************************************** +ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu::ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu sample. \n" \ + "Target: Ar40 \n" \ + "Flux: \n" \ + "Signal: CC, single charged pion > 0.1 GeV/c, no other mesons. \n"; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); + fSettings.SetDescription(descrip); + fSettings.SetXTitle("#theta_{#pi} (GeV)"); + fSettings.SetYTitle("d#sigma/d#theta_{#pi} (cm^{2} nucleon^{-1} degree^{-1})"); + fSettings.SetAllowedTypes("FIX/DIAG", "FIX/DIAG"); + fSettings.SetEnuRange(0.0, 100.0); + fSettings.DefineAllowedTargets("Ar"); + + // CC1Pi plot information + fSettings.SetTitle("ArgoNeut CC1#pi^{#pm} #nu_{#mu} 1D#theta_{#pi}"); + fSettings.SetDataInput( FitPar::GetDataBase() + "/ArgoNeuT/CC1Pi_dsig_dthetapi_nu.dat" ); + fSettings.DefineAllowedSpecies("numu"); + + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / + TotalIntegratedFlux("width"); + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-38); + SetCovarFromDiagonal(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +void ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu::FillEventVariables(FitEvent *event) { + FitParticle* p = event->GetHMFSChargePions(); + if (p) fXVar = p->fP.Vect().Theta() * 180.0 / TMath::Pi(); + return; +}; + +//******************************************************************** +bool ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu::isSignal(FitEvent *event) +//******************************************************************** +{ + if (!SignalDef::isCCINC(event, 14, EnuMin, EnuMax)) return false; + + int nMesons = event->NumFSMesons(); + int nLeptons = event->NumFSLeptons(); + int nPiCharge = event->NumFSChargePions(); + int nPiZero = event->NumFSPiZero(); + + if (nPiCharge != 1 || nMesons != 1 || nLeptons != 1 || nPiZero > 0) { + return false; + } + + if (event->GetHMFSChargePions()->fP.Vect().Mag() < 100) return false; + + return true; +} + diff --git a/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.h b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.h new file mode 100644 index 0000000..eb14af9 --- /dev/null +++ b/src/ArgoNeuT/ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.h @@ -0,0 +1,35 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu_H_SEEN +#define ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu_H_SEEN + +#include "Measurement1D.h" + +class ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu : public Measurement1D { +public: + ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu(nuiskey samplekey); + virtual ~ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu() {}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); +}; + +#endif + diff --git a/src/ArgoNeuT/CMakeLists.txt b/src/ArgoNeuT/CMakeLists.txt index 1ebcad7..34a20a2 100644 --- a/src/ArgoNeuT/CMakeLists.txt +++ b/src/ArgoNeuT/CMakeLists.txt @@ -1,56 +1,72 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ set(IMPLFILES +ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.cxx +ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.cxx +ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.cxx +ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.cxx +ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.cxx +ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.cxx +ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.cxx +ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.cxx ArgoNeuT_CCInc_XSec_1Dpmu_antinu.cxx ArgoNeuT_CCInc_XSec_1Dpmu_nu.cxx ArgoNeuT_CCInc_XSec_1Dthetamu_antinu.cxx ArgoNeuT_CCInc_XSec_1Dthetamu_nu.cxx ) set(HEADERFILES +ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.h +ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.h +ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.h +ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.h +ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.h +ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.h +ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.h +ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.h ArgoNeuT_CCInc_XSec_1Dpmu_antinu.h ArgoNeuT_CCInc_XSec_1Dpmu_nu.h ArgoNeuT_CCInc_XSec_1Dthetamu_antinu.h ArgoNeuT_CCInc_XSec_1Dthetamu_nu.h ) set(LIBNAME expArgoNeuT) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) # Add Extra Links if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx index 34f7083..6e01efd 100755 --- a/src/FCN/JointFCN.cxx +++ b/src/FCN/JointFCN.cxx @@ -1,1130 +1,1128 @@ #include "JointFCN.h" #include "FitUtils.h" #include //*************************************************** JointFCN::JointFCN(TFile *outfile) { //*************************************************** fOutputDir = gDirectory; if (outfile) Config::Get().out = outfile; std::vector samplekeys = Config::QueryKeys("sample"); LoadSamples(samplekeys); std::vector covarkeys = Config::QueryKeys("covar"); LoadPulls(covarkeys); fCurIter = 0; fMCFilled = false; fIterationTree = false; fDialVals = NULL; fNDials = 0; fUsingEventManager = FitPar::Config().GetParB("EventManager"); fOutputDir->cd(); } //*************************************************** JointFCN::JointFCN(std::vector samplekeys, TFile *outfile) { //*************************************************** fOutputDir = gDirectory; if (outfile) Config::Get().out = outfile; LoadSamples(samplekeys); fCurIter = 0; fMCFilled = false; fOutputDir->cd(); fIterationTree = false; fDialVals = NULL; fNDials = 0; fUsingEventManager = FitPar::Config().GetParB("EventManager"); fOutputDir->cd(); } //*************************************************** JointFCN::~JointFCN() { //*************************************************** // Delete Samples for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; delete exp; } for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; delete pull; } // Sort Tree if (fIterationTree) DestroyIterationTree(); if (fDialVals) delete fDialVals; if (fSampleLikes) delete fSampleLikes; }; //*************************************************** void JointFCN::CreateIterationTree(std::string name, FitWeight *rw) { //*************************************************** LOG(FIT) << " Creating new iteration container! " << std::endl; DestroyIterationTree(); fIterationTreeName = name; // Add sample likelihoods and ndof for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; std::string name = exp->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Pull terms for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; std::string name = pull->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Likelihoods fNameValues.push_back("total_likelihood"); fCurrentValues.push_back(0.0); fNameValues.push_back("total_ndof"); fCurrentValues.push_back(0.0); // Setup Containers fSampleN = fSamples.size() + fPulls.size(); fSampleLikes = new double[fSampleN]; fSampleNDOF = new int[fSampleN]; // Add Dials std::vector dials = rw->GetDialNames(); for (size_t i = 0; i < dials.size(); i++) { fNameValues.push_back(dials[i]); fCurrentValues.push_back(0.0); } fNDials = dials.size(); fDialVals = new double[fNDials]; // Set IterationTree Flag fIterationTree = true; } //*************************************************** void JointFCN::DestroyIterationTree() { //*************************************************** fIterationCount.clear(); fCurrentValues.clear(); fNameValues.clear(); fIterationValues.clear(); } //*************************************************** void JointFCN::WriteIterationTree() { //*************************************************** LOG(FIT) << "Writing iteration tree" << std::endl; // Make a new TTree TTree *itree = new TTree(fIterationTreeName.c_str(), fIterationTreeName.c_str()); double *vals = new double[fNameValues.size()]; int count = 0; itree->Branch("iteration", &count, "Iteration/I"); for (size_t i = 0; i < fNameValues.size(); i++) { itree->Branch(fNameValues[i].c_str(), &vals[i], (fNameValues[i] + "/D").c_str()); } // Fill Iterations for (size_t i = 0; i < fIterationValues.size(); i++) { std::vector itervals = fIterationValues[i]; // Fill iteration state count = fIterationCount[i]; for (size_t j = 0; j < itervals.size(); j++) { vals[j] = itervals[j]; } // Save to TTree itree->Fill(); } // Write to file itree->Write(); } //*************************************************** void JointFCN::FillIterationTree(FitWeight *rw) { //*************************************************** // Loop over samples count int count = 0; for (int i = 0; i < fSampleN; i++) { fCurrentValues[count++] = fSampleLikes[i]; fCurrentValues[count++] = double(fSampleNDOF[i]); } // Fill Totals fCurrentValues[count++] = fLikelihood; fCurrentValues[count++] = double(fNDOF); // Loop Over Parameter Counts rw->GetAllDials(fDialVals, fNDials); for (int i = 0; i < fNDials; i++) { fCurrentValues[count++] = double(fDialVals[i]); } // Push Back Into Container fIterationCount.push_back(fCurIter); fIterationValues.push_back(fCurrentValues); } //*************************************************** double JointFCN::DoEval(const double *x) { //*************************************************** // WEIGHT ENGINE fDialChanged = FitBase::GetRW()->HasRWDialChanged(x); FitBase::GetRW()->UpdateWeightEngine(x); if (fDialChanged) { FitBase::GetRW()->Reconfigure(); FitBase::EvtManager().ResetWeightFlags(); } if (LOG_LEVEL(REC)) { FitBase::GetRW()->Print(); } // SORT SAMPLES ReconfigureSamples(); // GET TEST STAT fLikelihood = GetLikelihood(); fNDOF = GetNDOF(); // PRINT PROGRESS LOG(FIT) << "Current Stat (iter. " << this->fCurIter << ") = " << fLikelihood << std::endl; // UPDATE TREE if (fIterationTree) FillIterationTree(FitBase::GetRW()); return fLikelihood; } //*************************************************** int JointFCN::GetNDOF() { //*************************************************** int totaldof = 0; int count = 0; // Total number of Free bins in each MC prediction for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; int dof = exp->GetNDOF(); // Save Seperate DOF if (fIterationTree) { fSampleNDOF[count] = dof; } // Add to total totaldof += dof; count++; } // Loop over pulls for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; double dof = pull->GetLikelihood(); // Save seperate DOF if (fIterationTree) { fSampleNDOF[count] = dof; } // Add to total totaldof += dof; count++; } // Set Data Variable if (fIterationTree) { fSampleNDOF[count] = totaldof; } return totaldof; } //*************************************************** double JointFCN::GetLikelihood() { //*************************************************** LOG(MIN) << std::left << std::setw(43) << "Getting likelihoods..." << " : " << "-2logL" << std::endl; // Loop and add up likelihoods in an uncorrelated way double like = 0.0; int count = 0; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; double newlike = exp->GetLikelihood(); int ndof = exp->GetNDOF(); // Save seperate likelihoods if (fIterationTree) { fSampleLikes[count] = newlike; } LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : " << newlike << "/" << ndof << std::endl; // Add Weight Scaling // like *= FitBase::GetRW()->GetSampleLikelihoodWeight(exp->GetName()); // Add to total like += newlike; count++; } // Loop over pulls for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; double newlike = pull->GetLikelihood(); // Save seperate likelihoods if (fIterationTree) { fSampleLikes[count] = newlike; } // Add to total like += newlike; count++; } // Set Data Variable fLikelihood = like; if (fIterationTree) { fSampleLikes[count] = fLikelihood; } return like; }; void JointFCN::LoadSamples(std::vector samplekeys) { LOG(MIN) << "Loading Samples : " << samplekeys.size() << std::endl; for (size_t i = 0; i < samplekeys.size(); i++) { nuiskey key = samplekeys[i]; // Get Sample Options std::string samplename = key.GetS("name"); std::string samplefile = key.GetS("input"); std::string sampletype = key.GetS("type"); std::string fakeData = ""; LOG(MIN) << "Loading Sample : " << samplename << std::endl; fOutputDir->cd(); MeasurementBase *NewLoadedSample = SampleUtils::CreateSample(key); if (!NewLoadedSample) { ERR(FTL) << "Could not load sample provided: " << samplename << std::endl; ERR(FTL) << "Check spelling with that in src/FCN/SampleList.cxx" << std::endl; throw; } else { fSamples.push_back(NewLoadedSample); } } } //*************************************************** void JointFCN::LoadPulls(std::vector pullkeys) { //*************************************************** for (size_t i = 0; i < pullkeys.size(); i++) { nuiskey key = pullkeys[i]; std::string pullname = key.GetS("name"); std::string pullfile = key.GetS("input"); std::string pulltype = key.GetS("type"); fOutputDir->cd(); fPulls.push_back(new ParamPull(pullname, pullfile, pulltype)); } } //*************************************************** void JointFCN::ReconfigureSamples(bool fullconfig) { //*************************************************** int starttime = time(NULL); LOG(REC) << "Starting Reconfigure iter. " << this->fCurIter << std::endl; // std::cout << fUsingEventManager << " " << fullconfig << " " << fMCFilled << // std::endl; // Event Manager Reconf if (fUsingEventManager) { if (!fullconfig and fMCFilled) ReconfigureFastUsingManager(); else ReconfigureUsingManager(); } else { // Loop over all Measurement Classes for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; // If RW Either do signal or full reconfigure. if (fDialChanged or !fMCFilled or fullconfig) { if (!fullconfig and fMCFilled) exp->ReconfigureFast(); else exp->Reconfigure(); // If RW Not needed just do normalisation } else { exp->Renormalise(); } } } // Loop over pulls and update for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; pull->Reconfigure(); } fMCFilled = true; LOG(MIN) << "Finished Reconfigure iter. " << fCurIter << " in " << time(NULL) - starttime << "s" << std::endl; fCurIter++; } //*************************************************** void JointFCN::ReconfigureSignal() { //*************************************************** ReconfigureSamples(false); } //*************************************************** void JointFCN::ReconfigureAllEvents() { //*************************************************** FitBase::GetRW()->Reconfigure(); FitBase::EvtManager().ResetWeightFlags(); ReconfigureSamples(true); } std::vector JointFCN::GetInputList() { std::vector InputList; fIsAllSplines = true; MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase *exp = (*iterSam); std::vector subsamples = exp->GetSubSamples(); for (size_t i = 0; i < subsamples.size(); i++) { InputHandlerBase *inp = subsamples[i]->GetInput(); if (std::find(InputList.begin(), InputList.end(), inp) == InputList.end()) { if (subsamples[i]->GetInput()->GetType() != kSPLINEPARAMETER) fIsAllSplines = false; InputList.push_back(subsamples[i]->GetInput()); } } } return InputList; } std::vector JointFCN::GetSubSampleList() { std::vector SampleList; MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase *exp = (*iterSam); std::vector subsamples = exp->GetSubSamples(); for (size_t i = 0; i < subsamples.size(); i++) { SampleList.push_back(subsamples[i]); } } return SampleList; } //*************************************************** void JointFCN::ReconfigureUsingManager() { //*************************************************** // 'Slow' Event Manager Reconfigure LOG(REC) << "Event Manager Reconfigure" << std::endl; int timestart = time(NULL); // Reset all samples MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase *exp = (*iterSam); exp->ResetAll(); } // If we are siving signal, reset all containers. bool savesignal = (FitPar::Config().GetParB("SignalReconfigures")); if (savesignal) { // Reset all of our event signal vectors fSignalEventBoxes.clear(); fSignalEventFlags.clear(); fSampleSignalFlags.clear(); fSignalEventSplines.clear(); } // Make sure we have a list of inputs if (fInputList.empty()) { fInputList = GetInputList(); fSubSampleList = GetSubSampleList(); } // If all inputs are splines make sure the readers are told // they need to be reconfigured. std::vector::iterator inp_iter = fInputList.begin(); if (fIsAllSplines) { for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase *curinput = (*inp_iter); // Tell reader in each BaseEvent it needs a Reconfigure next weight calc. BaseFitEvt *curevent = curinput->FirstBaseEvent(); if (curevent->fSplineRead) { curevent->fSplineRead->SetNeedsReconfigure(true); } } } // MAIN INPUT LOOP ==================== int fillcount = 0; int inputcount = 0; inp_iter = fInputList.begin(); // Loop over each input in manager for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase *curinput = (*inp_iter); // Get event information FitEvent *curevent = curinput->FirstNuisanceEvent(); curinput->CreateCache(); int i = 0; int nevents = curinput->GetNEvents(); int countwidth = nevents / 10; // Start event loop iterating until we get a NULL pointer. while (curevent) { // Get Event Weight // The reweighting weight curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent); // The Custom weight and reweight curevent->Weight = curevent->RWWeight * curevent->InputWeight * curevent->CustomWeight; // double rwweight = curevent->Weight; // std::cout << "RWWeight = " << curevent->RWWeight << " " << // curevent->InputWeight << std::endl; // Logging // std::cout << CHECKLOG(1) << std::endl; if (LOGGING(REC)) { if (countwidth && (i % countwidth == 0)) { QLOG(REC, curinput->GetName() << " : Processed " << i << " events. [M, W] = [" << curevent->Mode << ", " << curevent->Weight << "]"); } } // Setup flag for if signal found in at least one sample bool foundsignal = false; // Create a new signal bitset for this event std::vector signalbitset(fSubSampleList.size()); // Create a new signal box vector for this event std::vector signalboxes; // Start measurement iterator size_t measitercount = 0; std::vector::iterator meas_iter = fSubSampleList.begin(); // Loop over all subsamples (sub in JointMeas) for (; meas_iter != fSubSampleList.end(); meas_iter++) { MeasurementBase *curmeas = (*meas_iter); // Compare input pointers, to current input, skip if not. // Pointer tells us if it matches without doing ID checks. if (curinput != curmeas->GetInput()) { if (savesignal) { // Set bit to 0 as definitely not signal signalbitset[measitercount] = 0; } // Count up what measurement we are on. measitercount++; // Skip sample as input not signal. continue; } // Fill events for matching inputs. MeasurementVariableBox *box = curmeas->FillVariableBox(curevent); bool signal = curmeas->isSignal(curevent); curmeas->SetSignal(signal); curmeas->FillHistograms(curevent->Weight); // If its Signal tally up fills if (signal) { fillcount++; } // If we are saving signal/splines fill the bitset if (savesignal) { signalbitset[measitercount] = signal; } // If signal save a clone of the event box for use later. if (savesignal and signal) { foundsignal = true; signalboxes.push_back(box->CloneSignalBox()); } // Keep track of Measurement we are on. measitercount++; } // Once we've filled the measurements, if saving signal // push back if any sample flagged this event as signal if (savesignal) { fSignalEventFlags.push_back(foundsignal); } // Save the vector of signal boxes for this event if (savesignal and foundsignal) { fSignalEventBoxes.push_back(signalboxes); fSampleSignalFlags.push_back(signalbitset); } // If all inputs are splines we can save the spline coefficients // for fast in memory reconfigures later. if (fIsAllSplines and savesignal and foundsignal) { // Make temp vector to push back with std::vector coeff; for (size_t l = 0; l < (UInt_t)curevent->fSplineRead->GetNPar(); l++) { coeff.push_back(curevent->fSplineCoeff[l]); } // Push back to signal event splines. Kept in sync with // fSignalEventBoxes size. // int splinecount = fSignalEventSplines.size(); fSignalEventSplines.push_back(coeff); // if (splinecount % 1000 == 0) { // std::cout << "Pushed Back Coeff " << splinecount << " : "; // for (size_t l = 0; l < fSignalEventSplines[splinecount].size(); l++) // { // std::cout << " " << fSignalEventSplines[splinecount][l]; // } // std::cout << std::endl; // } } // Clean up vectors once done with this event signalboxes.clear(); signalbitset.clear(); // Iterate to the next event. curevent = curinput->NextNuisanceEvent(); i++; } // curinput->RemoveCache(); // Keep track of what input we are on. inputcount++; } // End of Event Loop =============================== // Now event loop is finished loop over all Measurements // Converting Binned events to XSec Distributions iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase *exp = (*iterSam); exp->ConvertEventRates(); } // Print out statements on approximate memory usage for profiling. LOG(REC) << "Filled " << fillcount << " signal events." << std::endl; if (savesignal) { int mem = ( // sizeof(fSignalEventBoxes) + // fSignalEventBoxes.size() * sizeof(fSignalEventBoxes.at(0)) + sizeof(MeasurementVariableBox1D) * fillcount) * 1E-6; LOG(REC) << " -> Saved " << fillcount << " signal boxes for faster access. (~" << mem << " MB)" << std::endl; if (fIsAllSplines and !fSignalEventSplines.empty()) { int splmem = sizeof(float) * fSignalEventSplines.size() * fSignalEventSplines[0].size() * 1E-6; LOG(REC) << " -> Saved " << fillcount << " " << fSignalEventSplines.size() << " spline sets into memory. (~" << splmem << " MB)" << std::endl; } } LOG(REC) << "Time taken ReconfigureUsingManager() : " << time(NULL) - timestart << std::endl; // Check SignalReconfigures works for all samples if (savesignal) { double likefull = GetLikelihood(); ReconfigureFastUsingManager(); double likefast = GetLikelihood(); if (fabs(likefull - likefast) > 0.0001) { ERROR(FTL, "Fast and Full Likelihoods DIFFER! : " << likefull << " : " << likefast); ERROR(FTL, "This means some samples you are using are not setup to use " "SignalReconfigures=1"); ERROR(FTL, "Please turn OFF signal reconfigures."); throw; } else { LOG(FIT) << "Likelihoods for FULL and FAST match. Will use FAST next time." << std::endl; } } // End of reconfigure return; }; //*************************************************** void JointFCN::ReconfigureFastUsingManager() { //*************************************************** LOG(FIT) << " -> Doing FAST using manager" << std::endl; // Get Start time for profilling int timestart = time(NULL); // Reset all samples MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase *exp = (*iterSam); exp->ResetAll(); } // Check for saved variables if not do a full reconfigure. if (fSignalEventFlags.empty()) { ERR(WRN) << "Signal Flags Empty! Using normal manager." << std::endl; ReconfigureUsingManager(); return; } bool fFillNuisanceEvent = FitPar::Config().GetParB("FullEventOnSignalReconfigure"); // Setup fast vector iterators. std::vector::iterator inpsig_iter = fSignalEventFlags.begin(); std::vector >::iterator box_iter = fSignalEventBoxes.begin(); std::vector >::iterator spline_iter = fSignalEventSplines.begin(); std::vector >::iterator samsig_iter = fSampleSignalFlags.begin(); int splinecount = 0; // Setup stuff for logging int fillcount = 0; int nevents = fSignalEventFlags.size(); int countwidth = nevents / 10; // If All Splines tell splines they need a reconfigure. std::vector::iterator inp_iter = fInputList.begin(); if (fIsAllSplines) { LOG(REC) << "All Spline Inputs so using fast spline loop." << std::endl; for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase *curinput = (*inp_iter); // Tell each fSplineRead in BaseFitEvent to reconf next weight calc BaseFitEvt *curevent = curinput->FirstBaseEvent(); if (curevent->fSplineRead) curevent->fSplineRead->SetNeedsReconfigure(true); } } // Loop over all possible spline inputs double *coreeventweights = new double[fSignalEventBoxes.size()]; splinecount = 0; inp_iter = fInputList.begin(); inpsig_iter = fSignalEventFlags.begin(); spline_iter = fSignalEventSplines.begin(); // Loop over all signal flags // For each valid signal flag add one to splinecount // Get Splines from that count and add to weight // Add splinecount int sigcount = 0; splinecount = 0; // #pragma omp parallel for shared(splinecount,sigcount) for (uint iinput = 0; iinput < fInputList.size(); iinput++) { InputHandlerBase *curinput = fInputList[iinput]; BaseFitEvt *curevent = curinput->FirstBaseEvent(); for (int i = 0; i < curinput->GetNEvents(); i++) { double rwweight = 0.0; if (fSignalEventFlags[sigcount]) { // Get Event Info if (!fIsAllSplines) { if (fFillNuisanceEvent) { curevent = curinput->GetNuisanceEvent(i); } else { curevent = curinput->GetBaseEvent(i); } } else { curevent->fSplineCoeff = &fSignalEventSplines[splinecount][0]; } curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent); curevent->Weight = curevent->RWWeight * curevent->InputWeight * curevent->CustomWeight; rwweight = curevent->Weight; coreeventweights[splinecount] = rwweight; if (countwidth && ((splinecount % countwidth) == 0)) { LOG(REC) << "Processed " << splinecount << " event weights. W = " << rwweight << std::endl; } // #pragma omp atomic splinecount++; } // #pragma omp atomic sigcount++; } } LOG(SAM) << "Processed event weights." << std::endl; // #pragma omp barrier // Reset Iterators inpsig_iter = fSignalEventFlags.begin(); spline_iter = fSignalEventSplines.begin(); box_iter = fSignalEventBoxes.begin(); samsig_iter = fSampleSignalFlags.begin(); int nsplineweights = splinecount; splinecount = 0; // Start of Fast Event Loop ============================ // Start input iterators // Loop over number of inputs for (int ispline = 0; ispline < nsplineweights; ispline++) { double rwweight = coreeventweights[ispline]; // Get iterators for this event std::vector::iterator subsamsig_iter = (*samsig_iter).begin(); std::vector::iterator subbox_iter = (*box_iter).begin(); // Loop over all sub measurements. std::vector::iterator meas_iter = fSubSampleList.begin(); for (; meas_iter != fSubSampleList.end(); meas_iter++, subsamsig_iter++) { MeasurementBase *curmeas = (*meas_iter); // If event flagged as signal for this sample fill from the box. if (*subsamsig_iter) { curmeas->SetSignal(true); curmeas->FillHistogramsFromBox((*subbox_iter), rwweight); // Move onto next box if there is one. subbox_iter++; fillcount++; } } if (ispline % countwidth == 0) { LOG(REC) << "Filled " << ispline << " sample weights." << std::endl; } // Iterate over the main signal event containers. samsig_iter++; box_iter++; spline_iter++; splinecount++; } // End of Fast Event Loop =================== LOG(SAM) << "Filled sample distributions." << std::endl; // Now loop over all Measurements // Convert Binned events iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase *exp = (*iterSam); exp->ConvertEventRates(); } // Cleanup coreeventweights - if (fIsAllSplines) { - delete coreeventweights; - } + delete coreeventweights; // Print some reconfigure profiling. LOG(REC) << "Filled " << fillcount << " signal events." << std::endl; LOG(REC) << "Time taken ReconfigureFastUsingManager() : " << time(NULL) - timestart << std::endl; } //*************************************************** void JointFCN::Write() { //*************************************************** // Save a likelihood/ndof plot LOG(MIN) << "Writing likelihood plot.." << std::endl; std::vector likes; std::vector ndofs; std::vector names; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; double like = exp->GetLikelihood(); double ndof = exp->GetNDOF(); std::string name = exp->GetName(); likes.push_back(like); ndofs.push_back(ndof); names.push_back(name); } if (likes.size()) { TH1D likehist = TH1D("likelihood_hist", "likelihood_hist", likes.size(), 0.0, double(likes.size())); TH1D ndofhist = TH1D("ndof_hist", "ndof_hist", ndofs.size(), 0.0, double(ndofs.size())); TH1D divhist = TH1D("likedivndof_hist", "likedivndof_hist", likes.size(), 0.0, double(likes.size())); for (int i = 0; i < likehist.GetNbinsX(); i++) { likehist.SetBinContent(i + 1, likes[i]); ndofhist.SetBinContent(i + 1, ndofs[i]); if (ndofs[i] != 0.0) { divhist.SetBinContent(i + 1, likes[i] / ndofs[i]); } likehist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); ndofhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); divhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); } likehist.Write(); ndofhist.Write(); divhist.Write(); } // Loop over individual experiments and call Write LOG(MIN) << "Writing each of the data classes..." << std::endl; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; exp->Write(); } // Save Pull Terms for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; pull->Write(); } if (FitPar::Config().GetParB("EventManager")) { // Get list of inputs std::map fInputs = FitBase::EvtManager().GetInputs(); std::map::const_iterator iterInp; for (iterInp = fInputs.begin(); iterInp != fInputs.end(); iterInp++) { InputHandlerBase *input = (iterInp->second); input->GetFluxHistogram()->Write(); input->GetXSecHistogram()->Write(); input->GetEventHistogram()->Write(); } } }; //*************************************************** void JointFCN::SetFakeData(std::string fakeinput) { //*************************************************** LOG(MIN) << "Setting fake data from " << fakeinput << std::endl; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; exp->SetFakeDataValues(fakeinput); } return; } //*************************************************** void JointFCN::ThrowDataToy() { //*************************************************** for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; exp->ThrowDataToy(); } return; } //*************************************************** std::vector JointFCN::GetAllNames() { //*************************************************** // Vect of all likelihoods and total std::vector namevect; // Loop over samples first for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; // Get Likelihoods and push to vector namevect.push_back(exp->GetName()); } // Loop over pulls second for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; // Push back to vector namevect.push_back(pull->GetName()); } // Finally add the total namevect.push_back("total"); return namevect; } //*************************************************** std::vector JointFCN::GetAllLikelihoods() { //*************************************************** // Vect of all likelihoods and total std::vector likevect; double total_likelihood = 0.0; LOG(MIN) << "Likelihoods : " << std::endl; // Loop over samples first for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; // Get Likelihoods and push to vector double singlelike = exp->GetLikelihood(); likevect.push_back(singlelike); total_likelihood += singlelike; // Print Out LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : " << singlelike << std::endl; } // Loop over pulls second for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; // Push back to vector double singlelike = pull->GetLikelihood(); likevect.push_back(singlelike); total_likelihood += singlelike; // Print Out LOG(MIN) << "-> " << std::left << std::setw(40) << pull->GetName() << " : " << singlelike << std::endl; } // Finally add the total likelihood likevect.push_back(total_likelihood); return likevect; } //*************************************************** std::vector JointFCN::GetAllNDOF() { //*************************************************** // Vect of all ndof and total std::vector ndofvect; int total_ndof = 0; // Loop over samples first for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase *exp = *iter; // Get Likelihoods and push to vector int singlendof = exp->GetNDOF(); ndofvect.push_back(singlendof); total_ndof += singlendof; } // Loop over pulls second for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull *pull = *iter; // Push back to vector int singlendof = pull->GetNDOF(); ndofvect.push_back(singlendof); total_ndof += singlendof; } // Finally add the total ndof ndofvect.push_back(total_ndof); return ndofvect; } diff --git a/src/FCN/SampleList.cxx b/src/FCN/SampleList.cxx index c7c2f2a..a9a90f0 100644 --- a/src/FCN/SampleList.cxx +++ b/src/FCN/SampleList.cxx @@ -1,1382 +1,1407 @@ #include "SampleList.h" #ifndef __NO_ANL__ #include "ANL_CCQE_Evt_1DQ2_nu.h" #include "ANL_CCQE_XSec_1DEnu_nu.h" // ANL CC1ppip #include "ANL_CC1ppip_Evt_1DQ2_nu.h" #include "ANL_CC1ppip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1ppip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1ppip_Evt_1DcosthAdler_nu.h" #include "ANL_CC1ppip_Evt_1Dphi_nu.h" #include "ANL_CC1ppip_Evt_1Dppi_nu.h" #include "ANL_CC1ppip_Evt_1Dthpr_nu.h" #include "ANL_CC1ppip_XSec_1DEnu_nu.h" #include "ANL_CC1ppip_XSec_1DQ2_nu.h" // ANL CC1npip #include "ANL_CC1npip_Evt_1DQ2_nu.h" #include "ANL_CC1npip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1npip_Evt_1Dppi_nu.h" #include "ANL_CC1npip_XSec_1DEnu_nu.h" // ANL CC1pi0 #include "ANL_CC1pi0_Evt_1DQ2_nu.h" #include "ANL_CC1pi0_Evt_1DcosmuStar_nu.h" #include "ANL_CC1pi0_XSec_1DEnu_nu.h" // ANL NC1npip (mm, exotic!) #include "ANL_NC1npip_Evt_1Dppi_nu.h" // ANL NC1ppim (mm, exotic!) #include "ANL_NC1ppim_Evt_1DcosmuStar_nu.h" #include "ANL_NC1ppim_XSec_1DEnu_nu.h" // ANL CC2pi 1pim1pip (mm, even more exotic!) #include "ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dppim_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dppip_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu.h" #include "ANL_CC2pi_1pim1pip_XSec_1DEnu_nu.h" // ANL CC2pi 1pip1pip (mm, even more exotic!) #include "ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu.h" #include "ANL_CC2pi_1pip1pip_XSec_1DEnu_nu.h" // ANL CC2pi 1pip1pi0 (mm, even more exotic!) #include "ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu.h" #include "ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu.h" #endif #ifndef __NO_ArgoNeuT__ +// ArgoNeuT CC1Pi +#include "ArgoNeuT_CC1Pi_XSec_1Dpmu_nu.h" +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu.h" +#include "ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu.h" +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu.h" +#include "ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu.h" +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu.h" +#include "ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu.h" +#include "ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu.h" // ArgoNeuT CC-inclusive #include "ArgoNeuT_CCInc_XSec_1Dpmu_antinu.h" #include "ArgoNeuT_CCInc_XSec_1Dpmu_nu.h" #include "ArgoNeuT_CCInc_XSec_1Dthetamu_antinu.h" #include "ArgoNeuT_CCInc_XSec_1Dthetamu_nu.h" #endif #ifndef __NO_BNL__ // BNL CCQE #include "BNL_CCQE_Evt_1DQ2_nu.h" #include "BNL_CCQE_XSec_1DEnu_nu.h" // BNL CC1ppip #include "BNL_CC1ppip_Evt_1DQ2_nu.h" #include "BNL_CC1ppip_Evt_1DQ2_nu.h" #include "BNL_CC1ppip_Evt_1DcosthAdler_nu.h" #include "BNL_CC1ppip_Evt_1Dphi_nu.h" #include "BNL_CC1ppip_XSec_1DEnu_nu.h" // BNL CC1npip #include "BNL_CC1npip_Evt_1DQ2_nu.h" #include "BNL_CC1npip_XSec_1DEnu_nu.h" // BNL CC1pi0 #include "BNL_CC1pi0_Evt_1DQ2_nu.h" #include "BNL_CC1pi0_XSec_1DEnu_nu.h" #endif #ifndef __NO_FNAL__ // FNAL CCQE #include "FNAL_CCQE_Evt_1DQ2_nu.h" // FNAL CC1ppip #include "FNAL_CC1ppip_Evt_1DQ2_nu.h" #include "FNAL_CC1ppip_XSec_1DEnu_nu.h" #include "FNAL_CC1ppip_XSec_1DQ2_nu.h" // FNAL CC1ppim #include "FNAL_CC1ppim_XSec_1DEnu_antinu.h" #endif #ifndef __NO_BEBC__ // BEBC CCQE #include "BEBC_CCQE_XSec_1DQ2_nu.h" // BEBC CC1ppip #include "BEBC_CC1ppip_XSec_1DEnu_nu.h" #include "BEBC_CC1ppip_XSec_1DQ2_nu.h" // BEBC CC1npip #include "BEBC_CC1npip_XSec_1DEnu_nu.h" #include "BEBC_CC1npip_XSec_1DQ2_nu.h" // BEBC CC1pi0 #include "BEBC_CC1pi0_XSec_1DEnu_nu.h" #include "BEBC_CC1pi0_XSec_1DQ2_nu.h" // BEBC CC1npim #include "BEBC_CC1npim_XSec_1DEnu_antinu.h" #include "BEBC_CC1npim_XSec_1DQ2_antinu.h" // BEBC CC1ppim #include "BEBC_CC1ppim_XSec_1DEnu_antinu.h" #include "BEBC_CC1ppim_XSec_1DQ2_antinu.h" #endif #ifndef __NO_GGM__ // GGM CC1ppip #include "GGM_CC1ppip_Evt_1DQ2_nu.h" #include "GGM_CC1ppip_XSec_1DEnu_nu.h" #endif #ifndef __NO_MiniBooNE__ // MiniBooNE CCQE #include "MiniBooNE_CCQE_XSec_1DQ2_antinu.h" #include "MiniBooNE_CCQE_XSec_1DQ2_nu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_antinu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_antinu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_nu.h" // MiniBooNE CC1pi+ 1D #include "MiniBooNE_CC1pip_XSec_1DEnu_nu.h" #include "MiniBooNE_CC1pip_XSec_1DQ2_nu.h" #include "MiniBooNE_CC1pip_XSec_1DTpi_nu.h" #include "MiniBooNE_CC1pip_XSec_1DTu_nu.h" // MiniBooNE CC1pi+ 2D #include "MiniBooNE_CC1pip_XSec_2DQ2Enu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTpiCospi_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTpiEnu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTuCosmu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTuEnu_nu.h" // MiniBooNE CC1pi0 #include "MiniBooNE_CC1pi0_XSec_1DEnu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1DQ2_nu.h" #include "MiniBooNE_CC1pi0_XSec_1DTu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dppi0_nu.h" #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.h" #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.h" #include "MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.h" #include "MiniBooNE_NC1pi0_XSec_1Dppi0_nu.h" // MiniBooNE NC1pi0 //#include "MiniBooNE_NCpi0_XSec_1Dppi0_nu.h" // MiniBooNE NCEL #include "MiniBooNE_NCEL_XSec_Treco_nu.h" #endif #ifndef __NO_MINERvA__ // MINERvA CCQE #include "MINERvA_CCQE_XSec_1DQ2_antinu.h" #include "MINERvA_CCQE_XSec_1DQ2_joint.h" #include "MINERvA_CCQE_XSec_1DQ2_nu.h" // MINERvA CC0pi #include "MINERvA_CC0pi_XSec_1DEe_nue.h" #include "MINERvA_CC0pi_XSec_1DQ2_nu_proton.h" #include "MINERvA_CC0pi_XSec_1DQ2_nue.h" #include "MINERvA_CC0pi_XSec_1DThetae_nue.h" // 2018 MINERvA CC0pi STV #include "MINERvA_CC0pinp_STV_XSec_1D_nu.h" // 2018 MINERvA CC0pi 2D #include "MINERvA_CC0pi_XSec_2D_nu.h" #include "MINERvA_CC0pi_XSec_1D_2018_nu.h" // MINERvA CC1pi+ #include "MINERvA_CC1pip_XSec_1DTpi_20deg_nu.h" #include "MINERvA_CC1pip_XSec_1DTpi_nu.h" #include "MINERvA_CC1pip_XSec_1Dth_20deg_nu.h" #include "MINERvA_CC1pip_XSec_1Dth_nu.h" // 2017 data update #include "MINERvA_CC1pip_XSec_1D_2017Update.h" // MINERvA CCNpi+ #include "MINERvA_CCNpip_XSec_1DEnu_nu.h" #include "MINERvA_CCNpip_XSec_1DQ2_nu.h" #include "MINERvA_CCNpip_XSec_1DTpi_nu.h" #include "MINERvA_CCNpip_XSec_1Dpmu_nu.h" #include "MINERvA_CCNpip_XSec_1Dth_nu.h" #include "MINERvA_CCNpip_XSec_1Dthmu_nu.h" // MINERvA CC1pi0 #include "MINERvA_CC1pi0_XSec_1DEnu_antinu.h" #include "MINERvA_CC1pi0_XSec_1DQ2_antinu.h" #include "MINERvA_CC1pi0_XSec_1DTpi0_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dpmu_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dppi0_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dth_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dthmu_antinu.h" // MINERvA CC1pi0 neutrino #include "MINERvA_CC1pi0_XSec_1D_nu.h" // MINERvA CCINC #include "MINERvA_CCinc_XSec_1DEnu_ratio.h" #include "MINERvA_CCinc_XSec_1Dx_ratio.h" #include "MINERvA_CCinc_XSec_2DEavq3_nu.h" // MINERvA CCDIS #include "MINERvA_CCDIS_XSec_1DEnu_ratio.h" #include "MINERvA_CCDIS_XSec_1Dx_ratio.h" // MINERvA CCCOH pion #include "MINERvA_CCCOHPI_XSec_1DEnu_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DEnu_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DEpi_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DQ2_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DEpi_nu.h" #include "MINERvA_CCCOHPI_XSec_1DQ2_nu.h" #include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" #include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" #include "MINERvA_CCCOHPI_XSec_joint.h" #include "MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.h" #include "MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.h" //#include "MINERvA_CC0pi_XSec_2Dptpx_antinu.h" //#include "MINERvA_CC0pi_XSec_2Dptpx_nu.h" #endif #ifndef __NO_T2K__ // T2K CC0pi #include "T2K_CC0pi_XSec_2DPcos_nu.h" // T2K STV CC0pi #include "T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h" #include "T2K_CC0pinp_STV_XSec_1Ddpt_nu.h" #include "T2K_CC0pinp_STV_XSec_1Ddphit_nu.h" #include "T2K_CC0pinp_STV_XSec_1Ddat_nu.h" #include "T2K_CC0pi1p_XSec_3DPcoscos_nu_nonuniform.h" #include "T2K_CC0pinp_ifk_XSec_3Dinfp_nu.h" #include "T2K_CC0pinp_ifk_XSec_3Dinfa_nu.h" #include "T2K_CC0pinp_ifk_XSec_3Dinfip_nu.h" // T2K CC1pi+ on CH #include "T2K_CC1pip_CH_XSec_1DQ2_nu.h" #include "T2K_CC1pip_CH_XSec_1DWrec_nu.h" #include "T2K_CC1pip_CH_XSec_1Dpmu_nu.h" #include "T2K_CC1pip_CH_XSec_1Dppi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dq3_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthmupi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthpi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthq3pi_nu.h" // T2K CC1pi+ on H2O #include "T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.h" #include "T2K_CC1pip_H2O_XSec_1DEnuMB_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcosmu_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcospi_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dpmu_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dppi_nu.h" #endif #ifndef __NO_SciBooNE__ // SciBooNE COH studies #include "SciBooNE_CCCOH_1TRK_1DQ2_nu.h" #include "SciBooNE_CCCOH_1TRK_1Dpmu_nu.h" #include "SciBooNE_CCCOH_1TRK_1Dthetamu_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dthetamu_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dpmu_nu.h" #include "SciBooNE_CCCOH_MuPiVA_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPiVA_1Dpmu_nu.h" #include "SciBooNE_CCCOH_MuPiVA_1Dthetamu_nu.h" #include "SciBooNE_CCCOH_MuPr_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPr_1Dpmu_nu.h" #include "SciBooNE_CCCOH_MuPr_1Dthetamu_nu.h" #include "SciBooNE_CCCOH_STOPFINAL_1DQ2_nu.h" #include "SciBooNE_CCCOH_STOP_NTrks_nu.h" #endif #ifndef __NO_K2K__ // K2K NC1pi0 #include "K2K_NC1pi0_Evt_1Dppi0_nu.h" #endif // MC Studies #include "ExpMultDist_CCQE_XSec_1DVar_FakeStudy.h" #include "ExpMultDist_CCQE_XSec_2DVar_FakeStudy.h" #include "MCStudy_CCQEHistograms.h" #include "GenericFlux_Tester.h" #include "GenericFlux_Vectors.h" #include "ElectronFlux_FlatTree.h" #include "ElectronScattering_DurhamData.h" #include "MCStudy_KaonPreSelection.h" #include "MCStudy_MuonValidation.h" #include "OfficialNIWGPlots.h" #include "T2K2017_FakeData.h" #include "Simple_Osc.h" #include "Smear_SVDUnfold_Propagation_Osc.h" #include "FitWeight.h" #include "NuisConfig.h" #include "NuisKey.h" #ifdef __USE_DYNSAMPLES__ #include "TRegexp.h" #include // linux #include DynamicSampleFactory::DynamicSampleFactory() : NSamples(0), NManifests(0) { LoadPlugins(); QLOG(FIT, "Loaded " << NSamples << " from " << NManifests << " shared object libraries."); } DynamicSampleFactory* DynamicSampleFactory::glblDSF = NULL; DynamicSampleFactory::PluginManifest::~PluginManifest() { for (size_t i_it = 0; i_it < Instances.size(); ++i_it) { (*(DSF_DestroySample))(Instances[i_it]); } } std::string EnsureTrailingSlash(std::string const& inp) { if (!inp.length()) { return "/"; } if (inp[inp.length() - 1] == '/') { return inp; } return inp + "/"; } void DynamicSampleFactory::LoadPlugins() { std::vector SearchDirectories; if (Config::HasPar("dynamic_sample.path")) { SearchDirectories = GeneralUtils::ParseToStr(Config::GetParS("dynamic_sample.path"), ":"); } char const* envPath = getenv("NUISANCE_DS_PATH"); if (envPath) { std::vector envPaths = GeneralUtils::ParseToStr(envPath, ":"); for (size_t ep_it = 0; ep_it < envPaths.size(); ++ep_it) { SearchDirectories.push_back(envPaths[ep_it]); } } if (!SearchDirectories.size()) { char const* pwdPath = getenv("PWD"); if (pwdPath) { SearchDirectories.push_back(pwdPath); } } for (size_t sp_it = 0; sp_it < SearchDirectories.size(); ++sp_it) { std::string dirpath = EnsureTrailingSlash(SearchDirectories[sp_it]); QLOG(FIT, "Searching for dynamic sample manifests in: " << dirpath); Ssiz_t len = 0; DIR* dir; struct dirent* ent; dir = opendir(dirpath.c_str()); if (dir != NULL) { TRegexp matchExp("*.so", true); while ((ent = readdir(dir)) != NULL) { if (matchExp.Index(TString(ent->d_name), &len) != Ssiz_t(-1)) { QLOG(FIT, "\tFound shared object: " << ent->d_name << " checking for relevant methods..."); void* dlobj = dlopen((dirpath + ent->d_name).c_str(), RTLD_NOW | RTLD_GLOBAL); char const* dlerr_cstr = dlerror(); std::string dlerr; if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tDL Load Error: " << dlerr); continue; } PluginManifest plgManif; plgManif.dllib = dlobj; plgManif.soloc = (dirpath + ent->d_name); plgManif.DSF_NSamples = reinterpret_cast(dlsym(dlobj, "DSF_NSamples")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_NSamples\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSampleName = reinterpret_cast( dlsym(dlobj, "DSF_GetSampleName")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSampleName\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSample = reinterpret_cast( dlsym(dlobj, "DSF_GetSample")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSample\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_DestroySample = reinterpret_cast( dlsym(dlobj, "DSF_DestroySample")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "Failed to load symbol \"DSF_DestroySample\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.NSamples = (*(plgManif.DSF_NSamples))(); QLOG(FIT, "\tSuccessfully loaded dynamic sample manifest: " << plgManif.soloc << ". Contains " << plgManif.NSamples << " samples."); for (size_t smp_it = 0; smp_it < plgManif.NSamples; ++smp_it) { char const* smp_name = (*(plgManif.DSF_GetSampleName))(smp_it); if (!smp_name) { THROW("Could not load sample " << smp_it << " / " << plgManif.NSamples << " from " << plgManif.soloc); } if (Samples.count(smp_name)) { ERROR(WRN, "Already loaded a sample named: \"" << smp_name << "\". cannot load duplciates. This " "sample will be skipped."); continue; } plgManif.SamplesProvided.push_back(smp_name); Samples[smp_name] = std::make_pair(plgManif.soloc, smp_it); QLOG(FIT, "\t\t" << smp_name); } if (plgManif.SamplesProvided.size()) { Manifests[plgManif.soloc] = plgManif; NSamples += plgManif.SamplesProvided.size(); NManifests++; } else { dlclose(dlobj); } } } closedir(dir); } else { ERROR(WRN, "Tried to open non-existant directory."); } } } DynamicSampleFactory& DynamicSampleFactory::Get() { if (!glblDSF) { glblDSF = new DynamicSampleFactory(); } return *glblDSF; } void DynamicSampleFactory::Print() { std::map > ManifestSamples; for (std::map >::iterator smp_it = Samples.begin(); smp_it != Samples.end(); ++smp_it) { if (!ManifestSamples.count(smp_it->second.first)) { ManifestSamples[smp_it->second.first] = std::vector(); } ManifestSamples[smp_it->second.first].push_back(smp_it->first); } QLOG(FIT, "Dynamic sample manifest: "); for (std::map >::iterator m_it = ManifestSamples.begin(); m_it != ManifestSamples.end(); ++m_it) { QLOG(FIT, "\tLibrary " << m_it->first << " contains: "); for (size_t s_it = 0; s_it < m_it->second.size(); ++s_it) { QLOG(FIT, "\t\t" << m_it->second[s_it]); } } } bool DynamicSampleFactory::HasSample(std::string const& name) { return Samples.count(name); } bool DynamicSampleFactory::HasSample(nuiskey& samplekey) { return HasSample(samplekey.GetS("name")); } MeasurementBase* DynamicSampleFactory::CreateSample(nuiskey& samplekey) { if (!HasSample(samplekey)) { ERROR(WRN, "Asked to load unknown sample: \"" << samplekey.GetS("name") << "\"."); return NULL; } std::pair sample = Samples[samplekey.GetS("name")]; QLOG(SAM, "\tLoading sample " << sample.second << " from " << sample.first); return (*(Manifests[sample.first].DSF_GetSample))(sample.second, &samplekey); } DynamicSampleFactory::~DynamicSampleFactory() { Manifests.clear(); } #endif //! Functions to make it easier for samples to be created and handled. namespace SampleUtils { //! Create a given sample given its name, file, type, fakdata(fkdt) file and the //! current rw engine and push it back into the list fChain. MeasurementBase* CreateSample(std::string name, std::string file, std::string type, std::string fkdt, FitWeight* rw) { nuiskey samplekey = Config::CreateKey("sample"); samplekey.Set("name", name); samplekey.Set("input", file); samplekey.Set("type", type); return CreateSample(samplekey); } MeasurementBase* CreateSample(nuiskey samplekey) { #ifdef __USE_DYNSAMPLES__ if (DynamicSampleFactory::Get().HasSample(samplekey)) { QLOG(SAM, "Instantiating dynamic sample..."); MeasurementBase* ds = DynamicSampleFactory::Get().CreateSample(samplekey); if (ds) { QLOG(SAM, "Done."); return ds; } THROW("Failed to instantiate dynamic sample."); } #endif FitWeight* rw = FitBase::GetRW(); std::string name = samplekey.GetS("name"); std::string file = samplekey.GetS("input"); std::string type = samplekey.GetS("type"); std::string fkdt = ""; /* ANL CCQE Samples */ #ifndef __NO_ANL__ if (!name.compare("ANL_CCQE_XSec_1DEnu_nu") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRD26") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRL31") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRD16")) { return (new ANL_CCQE_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CCQE_Evt_1DQ2_nu") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRL31") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRD26") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRD16")) { return (new ANL_CCQE_Evt_1DQ2_nu(samplekey)); /* ANL CC1ppip samples */ } else if (!name.compare("ANL_CC1ppip_XSec_1DEnu_nu") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_XSec_1DQ2_nu")) { return (new ANL_CC1ppip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DQ2_nu") || !name.compare("ANL_CC1ppip_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1ppip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dppi_nu")) { return (new ANL_CC1ppip_Evt_1Dppi_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dthpr_nu")) { return (new ANL_CC1ppip_Evt_1Dthpr_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DcosmuStar_nu")) { return (new ANL_CC1ppip_Evt_1DcosmuStar_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DcosthAdler_nu")) { return (new ANL_CC1ppip_Evt_1DcosthAdler_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dphi_nu")) { return (new ANL_CC1ppip_Evt_1Dphi_nu(samplekey)); /* ANL CC1npip sample */ } else if (!name.compare("ANL_CC1npip_XSec_1DEnu_nu") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1DQ2_nu") || !name.compare("ANL_CC1npip_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1npip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1Dppi_nu")) { return (new ANL_CC1npip_Evt_1Dppi_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1DcosmuStar_nu")) { return (new ANL_CC1npip_Evt_1DcosmuStar_nu(samplekey)); /* ANL CC1pi0 sample */ } else if (!name.compare("ANL_CC1pi0_XSec_1DEnu_nu") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1pi0_Evt_1DQ2_nu") || !name.compare("ANL_CC1pi0_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1pi0_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1pi0_Evt_1DcosmuStar_nu")) { return (new ANL_CC1pi0_Evt_1DcosmuStar_nu(samplekey)); /* ANL NC1npip sample */ } else if (!name.compare("ANL_NC1npip_Evt_1Dppi_nu")) { return (new ANL_NC1npip_Evt_1Dppi_nu(samplekey)); /* ANL NC1ppim sample */ } else if (!name.compare("ANL_NC1ppim_XSec_1DEnu_nu")) { return (new ANL_NC1ppim_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_NC1ppim_Evt_1DcosmuStar_nu")) { return (new ANL_NC1ppim_Evt_1DcosmuStar_nu(samplekey)); /* ANL CC2pi sample */ } else if (!name.compare("ANL_CC2pi_1pim1pip_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pim1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dppip_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dppip_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dppim_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dppim_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pip1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu(samplekey)); /* ArgoNeut Samples */ } else #endif #ifndef __NO_ArgoNeuT__ - if (!name.compare("ArgoNeuT_CCInc_XSec_1Dpmu_antinu")) { + if (!name.compare("ArgoNeuT_CCInc_XSec_1Dpmu_antinu")) { return (new ArgoNeuT_CCInc_XSec_1Dpmu_antinu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dpmu_nu")) { return (new ArgoNeuT_CCInc_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dthetamu_antinu")) { return (new ArgoNeuT_CCInc_XSec_1Dthetamu_antinu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dthetamu_nu")) { return (new ArgoNeuT_CCInc_XSec_1Dthetamu_nu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dpmu_nu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dpmu_nu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dthetamu_nu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dthetapi_nu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dthetamupi_nu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dpmu_antinu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dthetamu_antinu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dthetapi_antinu(samplekey)); + } else if (!name.compare("ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu")) { + return (new ArgoNeuT_CC1Pi_XSec_1Dthetamupi_antinu(samplekey)); /* BNL Samples */ } else #endif #ifndef __NO_BNL__ if (!name.compare("BNL_CCQE_XSec_1DEnu_nu")) { return (new BNL_CCQE_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CCQE_Evt_1DQ2_nu")) { return (new BNL_CCQE_Evt_1DQ2_nu(samplekey)); /* BNL CC1ppip samples */ } else if (!name.compare("BNL_CC1ppip_XSec_1DEnu_nu") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_Uncorr") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_W14Cut") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_W14Cut_Uncorr")) { return (new BNL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1DQ2_nu") || !name.compare("BNL_CC1ppip_Evt_1DQ2_nu_W14Cut")) { return (new BNL_CC1ppip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1DcosthAdler_nu")) { return (new BNL_CC1ppip_Evt_1DcosthAdler_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1Dphi_nu")) { return (new BNL_CC1ppip_Evt_1Dphi_nu(samplekey)); /* BNL CC1npip samples */ } else if (!name.compare("BNL_CC1npip_XSec_1DEnu_nu") || !name.compare("BNL_CC1npip_XSec_1DEnu_nu_Uncorr")) { return (new BNL_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1npip_Evt_1DQ2_nu")) { return (new BNL_CC1npip_Evt_1DQ2_nu(samplekey)); /* BNL CC1pi0 samples */ } else if (!name.compare("BNL_CC1pi0_XSec_1DEnu_nu")) { return (new BNL_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1pi0_Evt_1DQ2_nu")) { return (new BNL_CC1pi0_Evt_1DQ2_nu(samplekey)); /* FNAL Samples */ } else #endif #ifndef __NO_FNAL__ if (!name.compare("FNAL_CCQE_Evt_1DQ2_nu")) { return (new FNAL_CCQE_Evt_1DQ2_nu(samplekey)); /* FNAL CC1ppip */ } else if (!name.compare("FNAL_CC1ppip_XSec_1DEnu_nu")) { return (new FNAL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("FNAL_CC1ppip_XSec_1DQ2_nu")) { return (new FNAL_CC1ppip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("FNAL_CC1ppip_Evt_1DQ2_nu")) { return (new FNAL_CC1ppip_Evt_1DQ2_nu(samplekey)); /* FNAL CC1ppim */ } else if (!name.compare("FNAL_CC1ppim_XSec_1DEnu_antinu")) { return (new FNAL_CC1ppim_XSec_1DEnu_antinu(samplekey)); /* BEBC Samples */ } else #endif #ifndef __NO_BEBC__ if (!name.compare("BEBC_CCQE_XSec_1DQ2_nu")) { return (new BEBC_CCQE_XSec_1DQ2_nu(samplekey)); /* BEBC CC1ppip samples */ } else if (!name.compare("BEBC_CC1ppip_XSec_1DEnu_nu")) { return (new BEBC_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1ppip_XSec_1DQ2_nu")) { return (new BEBC_CC1ppip_XSec_1DQ2_nu(samplekey)); /* BEBC CC1npip samples */ } else if (!name.compare("BEBC_CC1npip_XSec_1DEnu_nu")) { return (new BEBC_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1npip_XSec_1DQ2_nu")) { return (new BEBC_CC1npip_XSec_1DQ2_nu(samplekey)); /* BEBC CC1pi0 samples */ } else if (!name.compare("BEBC_CC1pi0_XSec_1DEnu_nu")) { return (new BEBC_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1pi0_XSec_1DQ2_nu")) { return (new BEBC_CC1pi0_XSec_1DQ2_nu(samplekey)); /* BEBC CC1npim samples */ } else if (!name.compare("BEBC_CC1npim_XSec_1DEnu_antinu")) { return (new BEBC_CC1npim_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("BEBC_CC1npim_XSec_1DQ2_antinu")) { return (new BEBC_CC1npim_XSec_1DQ2_antinu(samplekey)); /* BEBC CC1ppim samples */ } else if (!name.compare("BEBC_CC1ppim_XSec_1DEnu_antinu")) { return (new BEBC_CC1ppim_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("BEBC_CC1ppim_XSec_1DQ2_antinu")) { return (new BEBC_CC1ppim_XSec_1DQ2_antinu(samplekey)); /* GGM CC1ppip samples */ } else #endif #ifndef __NO_GGM__ if (!name.compare("GGM_CC1ppip_XSec_1DEnu_nu")) { return (new GGM_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("GGM_CC1ppip_Evt_1DQ2_nu")) { return (new GGM_CC1ppip_Evt_1DQ2_nu(samplekey)); /* MiniBooNE Samples */ /* CCQE */ } else #endif #ifndef __NO_MiniBooNE__ if (!name.compare("MiniBooNE_CCQE_XSec_1DQ2_nu") || !name.compare("MiniBooNE_CCQELike_XSec_1DQ2_nu")) { return (new MiniBooNE_CCQE_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_1DQ2_antinu") || !name.compare("MiniBooNE_CCQELike_XSec_1DQ2_antinu") || !name.compare("MiniBooNE_CCQE_CTarg_XSec_1DQ2_antinu")) { return (new MiniBooNE_CCQE_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_2DTcos_nu") || !name.compare("MiniBooNE_CCQELike_XSec_2DTcos_nu")) { return (new MiniBooNE_CCQE_XSec_2DTcos_nu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_2DTcos_antinu") || !name.compare("MiniBooNE_CCQELike_XSec_2DTcos_antinu")) { return (new MiniBooNE_CCQE_XSec_2DTcos_antinu(samplekey)); /* MiniBooNE CC1pi+ */ // 1D } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DQ2_nu")) { return (new MiniBooNE_CC1pip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DTpi_nu")) { return (new MiniBooNE_CC1pip_XSec_1DTpi_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DTu_nu")) { return (new MiniBooNE_CC1pip_XSec_1DTu_nu(samplekey)); // 2D } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DQ2Enu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DQ2Enu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTpiCospi_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTpiCospi_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTpiEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTpiEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTuCosmu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTuCosmu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTuEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTuEnu_nu(samplekey)); /* MiniBooNE CC1pi0 */ } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DEnu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DQ2_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DTu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DTu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dcosmu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dcosmu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dcospi0_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dcospi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dppi0_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dppi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_rhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_nu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_fhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dcospi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_antinu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_rhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dppi0_antinu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_nu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_fhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dppi0_nu(samplekey)); /* MiniBooNE NCEL */ } else if (!name.compare("MiniBooNE_NCEL_XSec_Treco_nu")) { return (new MiniBooNE_NCEL_XSec_Treco_nu(samplekey)); /* MINERvA Samples */ } else #endif #ifndef __NO_MINERvA__ if (!name.compare("MINERvA_CCQE_XSec_1DQ2_nu") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_20deg") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_20deg_oldflux")) { return (new MINERvA_CCQE_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MINERvA_CCQE_XSec_1DQ2_antinu") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_20deg") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_20deg_oldflux")) { return (new MINERvA_CCQE_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MINERvA_CCQE_XSec_1DQ2_joint_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint_20deg_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint_20deg")) { return (new MINERvA_CCQE_XSec_1DQ2_joint(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DEe_nue")) { return (new MINERvA_CC0pi_XSec_1DEe_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_nue")) { return (new MINERvA_CC0pi_XSec_1DQ2_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DThetae_nue")) { return (new MINERvA_CC0pi_XSec_1DThetae_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pinp_STV_XSec_1Dpmu_nu") || !name.compare("MINERvA_CC0pinp_STV_XSec_1Dthmu_nu") || !name.compare("MINERvA_CC0pinp_STV_XSec_1Dpprot_nu") || !name.compare("MINERvA_CC0pinp_STV_XSec_1Dthprot_nu") || !name.compare("MINERvA_CC0pinp_STV_XSec_1Dpnreco_nu") || !name.compare("MINERvA_CC0pinp_STV_XSec_1Ddalphat_nu") || !name.compare("MINERvA_CC0pinp_STV_XSec_1Ddpt_nu") || !name.compare("MINERvA_CC0pinp_STV_XSec_1Ddphit_nu")) { return (new MINERvA_CC0pinp_STV_XSec_1D_nu(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_nu_proton")) { return (new MINERvA_CC0pi_XSec_1DQ2_nu_proton(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtC_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtCH_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtFe_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtPb_nu")) { return (new MINERvA_CC0pi_XSec_1DQ2_Tgt_nu(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioC_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioFe_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioPb_nu")) { return (new MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu(samplekey)); // Dan Ruterbories measurements of late 2018 } else if ( !name.compare("MINERvA_CC0pi_XSec_2Dptpz_nu")) { //!name.compare("MINERvA_CC0pi_XSec_2DptQ2_nu")) { return (new MINERvA_CC0pi_XSec_2D_nu(samplekey)); } else if ( !name.compare("MINERvA_CC0pi_XSec_1Dpt_nu") || !name.compare("MINERvA_CC0pi_XSec_1Dpz_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2QE_nu") || !name.compare("MINERvA_CC0pi_XSec_1DEnuQE_nu")) { return (new MINERvA_CC0pi_XSec_1D_2018_nu(samplekey)); // C. Patrick's early 2018 measurements //} else if (!name.compare("MINERvA_CC0pi_XSec_2Dptpx_antinu")) { //return (new MINERvA_CC0pi_XSec_2Dptpx_antinu(samplekey)); /* CC1pi+ */ // DONE } else if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_20deg") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_fluxcorr") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_20deg_fluxcorr")) { return (new MINERvA_CC1pip_XSec_1DTpi_nu(samplekey)); // DONE } else if (!name.compare("MINERvA_CC1pip_XSec_1Dth_nu") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_20deg") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_fluxcorr") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_20deg_fluxcorr")) { return (new MINERvA_CC1pip_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dpmu_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dthmu_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1DQ2_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1DEnu_nu_2017")) { return (new MINERvA_CC1pip_XSec_1D_2017Update(samplekey)); /* CCNpi+ */ } else if (!name.compare("MINERvA_CCNpip_XSec_1Dth_nu") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2016") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_20deg") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_fluxcorr") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_20deg_fluxcorr")) { return (new MINERvA_CCNpip_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CCNpip_XSec_1DTpi_nu") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2016") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015_20deg") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015_fluxcorr") || !name.compare( "MINERvA_CCNpip_XSec_1DTpi_nu_2015_20deg_fluxcorr")) { return (new MINERvA_CCNpip_XSec_1DTpi_nu(samplekey)); } else if (!name.compare("MINERvA_CCNpip_XSec_1Dthmu_nu")) { return (new MINERvA_CCNpip_XSec_1Dthmu_nu(samplekey)); } else if (!name.compare("MINERvA_CCNpip_XSec_1Dpmu_nu")) { return (new MINERvA_CCNpip_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("MINERvA_CCNpip_XSec_1DQ2_nu")) { return (new MINERvA_CCNpip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MINERvA_CCNpip_XSec_1DEnu_nu")) { return (new MINERvA_CCNpip_XSec_1DEnu_nu(samplekey)); /* MINERvA CC1pi0 anti-nu */ // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2015") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2016") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_fluxcorr") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2015_fluxcorr") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2016_fluxcorr")) { return (new MINERvA_CC1pi0_XSec_1Dth_antinu(samplekey)); } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dppi0_antinu") || !name.compare("MINERvA_CC1pi0_XSec_1Dppi0_antinu_fluxcorr")) { return (new MINERvA_CC1pi0_XSec_1Dppi0_antinu(samplekey)); } else if (!name.compare("MINERvA_CC1pi0_XSec_1DTpi0_antinu")) { return (new MINERvA_CC1pi0_XSec_1DTpi0_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1DQ2_antinu")) { return (new MINERvA_CC1pi0_XSec_1DQ2_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dthmu_antinu")) { return (new MINERvA_CC1pi0_XSec_1Dthmu_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dpmu_antinu")) { return (new MINERvA_CC1pi0_XSec_1Dpmu_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1DEnu_antinu")) { return (new MINERvA_CC1pi0_XSec_1DEnu_antinu(samplekey)); // MINERvA CC1pi0 nu } else if (!name.compare("MINERvA_CC1pi0_XSec_1DTpi_nu") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_nu") || !name.compare("MINERvA_CC1pi0_XSec_1Dpmu_nu") || !name.compare("MINERvA_CC1pi0_XSec_1Dthmu_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DQ2_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DEnu_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DWexp_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DPPi0Mass_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DPPi0MassDelta_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DCosAdler_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DPhiAdler_nu")) { return (new MINERvA_CC1pi0_XSec_1D_nu(samplekey)); /* CCINC */ } else if (!name.compare("MINERvA_CCinc_XSec_2DEavq3_nu")) { return (new MINERvA_CCinc_XSec_2DEavq3_nu(samplekey)); } else if (!name.compare("MINERvA_CCinc_XSec_1Dx_ratio_C12_CH") || !name.compare("MINERvA_CCinc_XSec_1Dx_ratio_Fe56_CH") || !name.compare("MINERvA_CCinc_XSec_1Dx_ratio_Pb208_CH")) { return (new MINERvA_CCinc_XSec_1Dx_ratio(samplekey)); } else if (!name.compare("MINERvA_CCinc_XSec_1DEnu_ratio_C12_CH") || !name.compare("MINERvA_CCinc_XSec_1DEnu_ratio_Fe56_CH") || !name.compare("MINERvA_CCinc_XSec_1DEnu_ratio_Pb208_CH")) { return (new MINERvA_CCinc_XSec_1DEnu_ratio(samplekey)); /* CCDIS */ } else if (!name.compare("MINERvA_CCDIS_XSec_1Dx_ratio_C12_CH") || !name.compare("MINERvA_CCDIS_XSec_1Dx_ratio_Fe56_CH") || !name.compare("MINERvA_CCDIS_XSec_1Dx_ratio_Pb208_CH")) { return (new MINERvA_CCDIS_XSec_1Dx_ratio(samplekey)); } else if (!name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_C12_CH") || !name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_Fe56_CH") || !name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_Pb208_CH")) { return (new MINERvA_CCDIS_XSec_1DEnu_ratio(samplekey)); /* CC-COH */ } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_nu")) { return (new MINERvA_CCCOHPI_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_nu")) { return (new MINERvA_CCCOHPI_XSec_1DEpi_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_nu")) { return (new MINERvA_CCCOHPI_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_nu")) { return (new MINERvA_CCCOHPI_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DEpi_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_antinu")) { return (new MINERvA_CCCOHPI_XSec_1Dth_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); /* T2K Samples */ } else #endif #ifndef __NO_T2K__ if (!name.compare("T2K_CC0pi_XSec_2DPcos_nu") || !name.compare("T2K_CC0pi_XSec_2DPcos_nu_I") || !name.compare("T2K_CC0pi_XSec_2DPcos_nu_II")) { return (new T2K_CC0pi_XSec_2DPcos_nu(samplekey)); } else if (!name.compare("T2K_CC0pi_XSec_2DPcos_nu_nonuniform")) { return (new T2K_CC0pi_XSec_2DPcos_nu_nonuniform(samplekey)); /* T2K CC1pi+ CH samples */ // Comment these out for now because we don't have the proper data } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dpmu_nu")) { return (new T2K_CC1pip_CH_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dppi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dppi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1DQ2_nu")) { return (new T2K_CC1pip_CH_XSec_1DQ2_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dq3_nu")) { return (new T2K_CC1pip_CH_XSec_1Dq3_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthmupi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthmupi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthpi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthpi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthq3pi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthq3pi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1DWrec_nu")) { return (new T2K_CC1pip_CH_XSec_1DWrec_nu(file, rw, type, fkdt)); /* T2K CC1pi+ H2O samples */ } else if (!name.compare("T2K_CC1pip_H2O_XSec_1DEnuDelta_nu")) { return (new T2K_CC1pip_H2O_XSec_1DEnuDelta_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1DEnuMB_nu")) { return (new T2K_CC1pip_H2O_XSec_1DEnuMB_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcosmu_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcosmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcosmupi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcosmupi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcospi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcospi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dpmu_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dppi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dppi_nu(samplekey)); /* T2K CC0pi + np CH samples */ } else if (!name.compare("T2K_CC0pinp_STV_XSec_1Ddpt_nu")) { return (new T2K_CC0pinp_STV_XSec_1Ddpt_nu(samplekey)); } else if (!name.compare("T2K_CC0pinp_STV_XSec_1Ddphit_nu")) { return (new T2K_CC0pinp_STV_XSec_1Ddphit_nu(samplekey)); } else if (!name.compare("T2K_CC0pinp_STV_XSec_1Ddat_nu")) { return (new T2K_CC0pinp_STV_XSec_1Ddat_nu(samplekey)); } else if (!name.compare("T2K_CC0pi1p_XSec_3DPcoscos_nu_nonuniform")) { return (new T2K_CC0pi1p_XSec_3DPcoscos_nu_nonuniform(samplekey)); } else if (!name.compare("T2K_CC0pinp_ifk_XSec_3Dinfp_nu")) { return (new T2K_CC0pinp_ifk_XSec_3Dinfp_nu(samplekey)); } else if (!name.compare("T2K_CC0pinp_ifk_XSec_3Dinfa_nu")) { return (new T2K_CC0pinp_ifk_XSec_3Dinfa_nu(samplekey)); } else if (!name.compare("T2K_CC0pinp_ifk_XSec_3Dinfip_nu")) { return (new T2K_CC0pinp_ifk_XSec_3Dinfip_nu(samplekey)); // SciBooNE COH studies } else #endif #ifndef __NO_SciBooNE__ if (!name.compare("SciBooNE_CCCOH_STOP_NTrks_nu")) { return (new SciBooNE_CCCOH_STOP_NTrks_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_1TRK_1DQ2_nu")) { return (new SciBooNE_CCCOH_1TRK_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_1TRK_1Dpmu_nu")) { return (new SciBooNE_CCCOH_1TRK_1Dpmu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_1TRK_1Dthetamu_nu")) { return (new SciBooNE_CCCOH_1TRK_1Dthetamu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPr_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPr_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPr_1Dpmu_nu")) { return (new SciBooNE_CCCOH_MuPr_1Dpmu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPr_1Dthetamu_nu")) { return (new SciBooNE_CCCOH_MuPr_1Dthetamu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiVA_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPiVA_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiVA_1Dpmu_nu")) { return (new SciBooNE_CCCOH_MuPiVA_1Dpmu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiVA_1Dthetamu_nu")) { return (new SciBooNE_CCCOH_MuPiVA_1Dthetamu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dthetamu_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dthetamu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dpmu_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dpmu_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_STOPFINAL_1DQ2_nu")) { return (new SciBooNE_CCCOH_STOPFINAL_1DQ2_nu(samplekey)); /* K2K Samples */ /* NC1pi0 */ } else #endif #ifndef __NO_K2K__ if (!name.compare("K2K_NC1pi0_Evt_1Dppi0_nu")) { return (new K2K_NC1pi0_Evt_1Dppi0_nu(samplekey)); /* Fake Studies */ } else #endif if (name.find("ExpMultDist_CCQE_XSec_1D") != std::string::npos && name.find("_FakeStudy") != std::string::npos) { return ( new ExpMultDist_CCQE_XSec_1DVar_FakeStudy(name, file, rw, type, fkdt)); } else if (name.find("ExpMultDist_CCQE_XSec_2D") != std::string::npos && name.find("_FakeStudy") != std::string::npos) { return ( new ExpMultDist_CCQE_XSec_2DVar_FakeStudy(name, file, rw, type, fkdt)); } else if (name.find("GenericFlux_") != std::string::npos) { return (new GenericFlux_Tester(name, file, rw, type, fkdt)); } else if (name.find("GenericVectors_") != std::string::npos) { return (new GenericFlux_Vectors(name, file, rw, type, fkdt)); } else if (!name.compare("T2K2017_FakeData")) { return (new T2K2017_FakeData(samplekey)); } else if (!name.compare("MCStudy_CCQE")) { return (new MCStudy_CCQEHistograms(name, file, rw, type, fkdt)); } else if (!name.compare("ElectronFlux_FlatTree")) { return (new ElectronFlux_FlatTree(name, file, rw, type, fkdt)); } else if (name.find("ElectronData_") != std::string::npos) { return new ElectronScattering_DurhamData(samplekey); } else if (name.find("MuonValidation_") != std::string::npos) { return (new MCStudy_MuonValidation(name, file, rw, type, fkdt)); } else if (!name.compare("NIWGOfficialPlots")) { return (new OfficialNIWGPlots(samplekey)); } else if (!name.compare("Simple_Osc")) { return (new Simple_Osc(samplekey)); } else if (!name.compare("Smear_SVDUnfold_Propagation_Osc")) { return (new Smear_SVDUnfold_Propagation_Osc(samplekey)); } else { THROW("Error: No such sample: " << name << std::endl); } // Return NULL if no sample loaded. return NULL; } } diff --git a/src/FitBase/JointMeas1D.cxx b/src/FitBase/JointMeas1D.cxx index 6d99713..cfcd502 100644 --- a/src/FitBase/JointMeas1D.cxx +++ b/src/FitBase/JointMeas1D.cxx @@ -1,2303 +1,2300 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This ile is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "JointMeas1D.h" //******************************************************************** JointMeas1D::JointMeas1D(void) { //******************************************************************** // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; fCovar = NULL; fInvert = NULL; fDecomp = NULL; // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; for (std::vector::const_iterator iter = fSubChain.begin(); iter != fSubChain.end(); iter++) { MeasurementBase* exp = *iter; if (exp) delete exp; } fSubChain.clear(); // Flags for Joint Measurements fIsRatio = false; fIsSummed = false; fSaveSubMeas = false; fIsJoint = true; } //******************************************************************** void JointMeas1D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBins = fMCHist->GetNbinsX(); fMCFine = new TH1D( (fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1)); fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); fMCHist->Reset(); fMCFine->Reset(); // Setup the NEUT Mode Array PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG); PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes); return; } //******************************************************************** JointMeas1D::~JointMeas1D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; for (std::vector::const_iterator iter = fSubChain.begin(); iter != fSubChain.end(); iter++) { MeasurementBase* exp = *iter; if (exp) delete exp; } fSubChain.clear(); } //******************************************************************** SampleSettings JointMeas1D::LoadSampleSettings(nuiskey samplekey){ //******************************************************************** SampleSettings s = MeasurementBase::LoadSampleSettings(samplekey); // Parse Inputs fSubInFiles.clear(); std::vector entries = GeneralUtils::ParseToStr(s.GetS("input"), ";"); if (entries.size() < 2) { ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon " "separated input files, but recieved: \"" << s.GetS("input") << "\"" << std::endl; throw; } std::vector first_file_descriptor = GeneralUtils::ParseToStr(entries.front(), ":"); if (first_file_descriptor.size() != 2) { ERR(FTL) << "Found Joint measurement where the input file had no type: \"" << s.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"." << std::endl; throw; } std::string inpType = first_file_descriptor[0]; for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) { std::stringstream ss(""); ss << inpType << ":" << (*iter); fSubInFiles.push_back(ss.str()); } else { fSubInFiles.push_back(*iter); } } return s; } //******************************************************************** void JointMeas1D::FinaliseSampleSettings() { //******************************************************************** // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } // Parse Inputs fSubInFiles.clear(); std::vector entries = GeneralUtils::ParseToStr(fSettings.GetS("input"), ";"); if (entries.size() < 2) { ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon " "separated input files, but recieved: \"" << fSettings.GetS("input") << "\"" << std::endl; throw; } std::vector first_file_descriptor = GeneralUtils::ParseToStr(entries.front(), ":"); if (first_file_descriptor.size() != 2) { ERR(FTL) << "Found Joint measurement where the input file had no type: \"" << fSettings.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"." << std::endl; throw; } std::string inpType = first_file_descriptor[0]; for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) { std::stringstream ss(""); ss << inpType << ":" << (*iter); fSubInFiles.push_back(ss.str()); } else { fSubInFiles.push_back(*iter); } } // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } if (!fRW) fRW = FitBase::GetRW(); LOG(SAM) << "Finalised Sample Settings" << std::endl; } //******************************************************************** void JointMeas1D::SetDataFromTextFile(std::string datafile) { //******************************************************************** LOG(SAM) << "Reading data from text file: " << datafile << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(datafile, fSettings.GetName() + "_data", fSettings.GetFullTitles()); } //******************************************************************** void JointMeas1D::SetDataFromRootFile(std::string datafile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); return; }; //******************************************************************** void JointMeas1D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void JointMeas1D::SetCovarFromDiagonal(TH1D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } if (!fIsDiag) { ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " << "that is not set as diagonal." << std::endl; throw; } } //******************************************************************** void JointMeas1D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarFromMultipleTextFiles(std::string covfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector covList = GeneralUtils::ParseToStr(covfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < covList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << covList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(covList[i], dim); (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = fDataHist->GetNbinsX(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void JointMeas1D::SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector corrList = GeneralUtils::ParseToStr(corrfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < corrList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << corrList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(corrList[i], dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { // Note that there is a factor of 1E76 here. It is very silly indeed. // However, if you remove it, you also need to fix the factors of 1E38 added to the chi2 calculations! (*temp_cov)(i, j) = (*temp_cov)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1E76; } } (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } void JointMeas1D::SetShapeCovar(){ // Return if this is missing any pre-requisites if (!fFullCovar) return; if (!fDataHist) return; // Also return if it's bloody stupid under the circumstances if (fIsDiag) return; fShapeCovar = StatUtils::ExtractShapeOnlyCovar(fFullCovar, fDataHist); return; } //******************************************************************** void JointMeas1D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void JointMeas1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void JointMeas1D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void JointMeas1D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void JointMeas1D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbins = fDataHist->GetNbinsX(); fMaskHist = new TH1I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins); std::string line; std::ifstream mask(maskfile.c_str(), std::ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "JointMeas1D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[1] > 0) val = 1; fMaskHist->SetBinContent(entries[0], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void JointMeas1D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Push the diagonals of fFullCovar onto the data histogram // Comment out until scaling is used consistently... StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); // Setup fMCHist from data fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH1D("mcfine", "mcfine", fDataHist->GetNbinsX(), fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } /* if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } */ // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH1D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void JointMeas1D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; return; }; //******************************************************************** void JointMeas1D::SetSmearingMatrix(std::string smearfile, int truedim, int recodim) { //******************************************************************** // The smearing matrix describes the migration from true bins (rows) to reco // bins (columns) // Counter over the true bins! int row = 0; std::string line; std::ifstream smear(smearfile.c_str(), std::ifstream::in); // Note that the smearing matrix may be rectangular. fSmearMatrix = new TMatrixD(truedim, recodim); if (smear.is_open()) LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl; else ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile << std::endl; while (std::getline(smear >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*fSmearMatrix)(row, column) = (*iter) / 100.; // Convert to fraction from // percentage (this may not be // general enough) column++; } row++; } return; } //******************************************************************** void JointMeas1D::ApplySmearingMatrix() { //******************************************************************** if (!fSmearMatrix) { ERR(WRN) << fName << ": attempted to apply smearing matrix, but none was set" << std::endl; return; } TH1D* unsmeared = (TH1D*)fMCHist->Clone(); TH1D* smeared = (TH1D*)fMCHist->Clone(); smeared->Reset(); // Loop over reconstructed bins // true = row; reco = column for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) { // Sum up the constributions from all true bins double rBinVal = 0; // Loop over true bins for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) { rBinVal += (*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1); } smeared->SetBinContent(rbin + 1, rBinVal); } fMCHist = (TH1D*)smeared->Clone(); return; } /* Reconfigure LOOP */ //******************************************************************** void JointMeas1D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void JointMeas1D::FillHistograms() { //******************************************************************** if (Signal) { fMCHist->Fill(fXVar, Weight); fMCFine->Fill(fXVar, Weight); fMCStat->Fill(fXVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight); } return; }; //******************************************************************** void JointMeas1D::ScaleEvents() { //******************************************************************** LOG(FIT) << "Scaling JointMeas1D" << std::endl; // Fill MCWeighted; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); // if (fMCHist_Modes) { // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), // GetEventHistogram(), fScaleFactor, // fNEvents); // } // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up delete statratio; delete statratiofine; return; }; //******************************************************************** void JointMeas1D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int JointMeas1D::GetNDOF() { //******************************************************************** int ndof = fDataHist->GetNbinsX(); if (fMaskHist) ndof -= fMaskHist->Integral(); return ndof; } //******************************************************************** double JointMeas1D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Apply Masking to MC if Required. if (fIsMask and fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } // Sort Shape Scaling double scaleF = 0.0; if (fIsShape) { if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) { scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") / fMCHist->Integral(1, fMCHist->GetNbinsX(), "width"); fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); } } // Likelihood Calculation double stat = 0.; if (fIsChi2) { if (fIsRawEvents) { stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist); } else if (fIsDiag) { stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist); } else if (!fIsDiag and !fIsRawEvents) { stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist); } } // Sort Penalty Terms if (fAddNormPen) { double penalty = (1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError); stat += penalty; } // Return to normal scaling if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = stat; return stat; } /* Fake Data Functions */ //******************************************************************** void JointMeas1D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH1D* tempdata = (TH1D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH1D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void JointMeas1D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void JointMeas1D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void JointMeas1D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void JointMeas1D::ThrowDataToy(){ //******************************************************************** if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH1D* JointMeas1D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << "#chi^{2}=" << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH1D* JointMeas1D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void JointMeas1D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos){ fSettings.Set("#chi^{2}",fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // Write Data/MC GetDataHistogram()->Write(); GetMCHistogram()->Write(); // Write Fine Histogram if (drawOpt.find("FINE") != std::string::npos) GetFineList().at(0)->Write(); // Write Weighted Histogram if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted) fMCWeighted->Write(); // Save Flux/Evt if no event manager if (!FitPar::Config().GetParB("EventManager")) { if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram()) GetFluxHistogram()->Write(); if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); } // Write Mask if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) { fMaskHist->Write(); } // Write Covariances if (drawOpt.find("COV") != std::string::npos && fFullCovar) { PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName()); } if (drawOpt.find("INVCOV") != std::string::npos && covar) { PlotUtils::GetInvCovarPlot(covar, fSettings.GetName()); } if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) { PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName()); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // Ratio and Shape Plots if (drawOpt.find("RATIO") != std::string::npos) { WriteRatioPlot(); } if (drawOpt.find("SHAPE") != std::string::npos) { WriteShapePlot(); if (drawOpt.find("RATIO") != std::string::npos) WriteShapeRatioPlot(); } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); if (fSaveSubMeas) { for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; exp->Write(drawOpt); } } // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } //******************************************************************** void JointMeas1D::WriteRatioPlot() { //******************************************************************** // Setup mc data ratios TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH1D* mcRatio = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); // Extra MC Data Ratios for (int i = 0; i < mcRatio->GetNbinsX(); i++) { dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); dataRatio->SetBinError(i + 1, fDataHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinError(i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } // Write ratios mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } //******************************************************************** void JointMeas1D::WriteShapePlot() { //******************************************************************** TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); std::stringstream ss; ss << "Scale=" << shapeScale; mcShape->SetTitle(ss.str().c_str()); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); mcShape->Write(); delete mcShape; } //******************************************************************** void JointMeas1D::WriteShapeRatioPlot() { //******************************************************************** // Get a mcshape histogram TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); // Create shape ratio histograms TH1D* mcShapeRatio = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "JointMeas1D.h" /* Constructor/Deconstuctor */ /* Setup Functions */ //******************************************************************** void JointMeas1D::SetupMeasurement(std::string input, std::string type, FitWeight* rw, std::string fkdt) { //******************************************************************** // For joint samples, input files are given as a semi-colon seperated list. // Parse this list and save it for later, and set up the types etc. if (FitPar::Config().GetParB("EventManager")) { ERR(FTL) << "Event Manager does not yet work with JointMeas1D Samples" << std::endl; ERR(FTL) << "If you want good predictions for " << fName << " then run with it turned off! (-q EventManager=0)" << std::endl; } fSubInFiles.clear(); std::vector entries = GeneralUtils::ParseToStr(input, ";"); if (entries.size() < 2) { ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon " "separated input files, but recieved: \"" << input << "\"" << std::endl; throw; } std::vector first_file_descriptor = GeneralUtils::ParseToStr(entries.front(), ":"); if (first_file_descriptor.size() != 2) { ERR(FTL) << "Found Joint measurement where the input file had no type: \"" << input << "\", expected \"INPUTTYPE:File.root;File2.root\"." << std::endl; throw; } std::string inpType = first_file_descriptor[0]; for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) { std::stringstream ss(""); ss << inpType << ":" << (*iter); fSubInFiles.push_back(ss.str()); } else { fSubInFiles.push_back(*iter); } } // Set Engine and Fake Data fRW = rw; fFakeDataInput = fkdt; // Set Fit Options SetFitOptions(type); return; } /* XSec Functions */ //******************************************************************** double JointMeas1D::TotalIntegratedFlux(std::string intOpt, double low, double high) { //******************************************************************** double totalflux = 0.0; // Destroy the job for sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; double expflux = exp->TotalIntegratedFlux(intOpt, low, high); // Fill flux options if (fIsRatio) { totalflux = expflux; break; } if (fIsSummed) { totalflux += expflux; } } return totalflux; } /* Reconfigure Functions */ //******************************************************************** void JointMeas1D::Reconfigure() { //******************************************************************** for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; exp->Reconfigure(); } ConvertEventRates(); return; } //******************************************************************** void JointMeas1D::ConvertEventRates() { //******************************************************************** // Apply Event Scaling for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = static_cast(*expIter); exp->ScaleEvents(); } // Joint function called by top level class MakePlots(); // Do Final Normalisation ApplyNormScale(fRW->GetSampleNorm(this->fName)); } //******************************************************************** void JointMeas1D::MakePlots() { //******************************************************************** // Reset the 1D histograms but not the subClasses ResetAll(); // If Summed if (fIsSummed) { for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = static_cast(*expIter); this->fMCHist->Add(exp->GetMCList().at(0)); this->fMCFine->Add(exp->GetFineList().at(0)); } return; } // If Ratio if (fIsRatio) { int sample = 0; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; if (sample == 0) { this->fMCHist->Add(exp->GetMCList().at(0)); this->fMCFine->Add(exp->GetFineList().at(0)); } else if (sample == 1) { this->fMCHist->Divide(exp->GetMCList().at(0)); this->fMCFine->Divide(exp->GetFineList().at(0)); } else { break; } sample++; } return; } return; } /* Access Functions */ //******************************************************************** std::vector JointMeas1D::GetMCList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fMCHist); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetMCList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetDataList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fDataHist); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetDataList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetFineList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fMCFine); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetFineList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetMaskList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fMaskHist); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetMaskList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetFluxList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(MeasurementBase::GetFluxHistogram()); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetFluxList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetEventRateList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(MeasurementBase::GetEventHistogram()); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetEventRateList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetXSecList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(MeasurementBase::GetXSecHistogram()); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetXSecList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** TH1D* JointMeas1D::GetCombinedFlux() { //******************************************************************** TH1D* newflux = NULL; int sample = 0; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; // Get flux from experiment std::vector fluxVect = exp->GetFluxList(); // Setup newflux if (sample == 0) { newflux = (TH1D*)fluxVect.at(0); newflux->Reset(); } // Add all fluxes for (UInt_t i = 0; i < fluxVect.size(); i++) { newflux->Add((TH1D*)fluxVect.at(i)); sample++; } } if (!newflux){ ERR(FTL) << "No combined flux setup in JointMeas1D" << std::endl; } return newflux; } //******************************************************************** TH1D* JointMeas1D::GetCombinedEventRate() { //******************************************************************** TH1D* newflux = NULL; int sample = 0; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; // Get flux from experiment std::vector fluxVect = exp->GetFluxList(); // Setup newflux if (sample == 0) { newflux = (TH1D*)fluxVect.at(0); newflux->Reset(); } // Add all fluxes for (UInt_t i = 0; i < fluxVect.size(); i++) { newflux->Add(fluxVect.at(i)); sample++; } } if (!newflux){ ERR(FTL) << "No combined event rate setup in JointMeas1D" << std::endl; } return newflux; } //******************************************************************** std::vector JointMeas1D::GetSubSamples() { //******************************************************************** std::vector exps; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { exps.push_back(*expIter); } return exps; } //// CRAP TO BE REMOVED //******************************************************************** void JointMeas1D::SetDataValues(std::string dataFile) { //******************************************************************** // Override this function if the input file isn't in a suitable format LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles); fDataTrue = (TH1D*)fDataHist->Clone(); // Number of data points is number of bins fNDataPointsX = fDataHist->GetXaxis()->GetNbins(); return; }; //******************************************************************** void JointMeas1D::SetDataFromDatabase(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile( (GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void JointMeas1D::SetDataFromFile(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void JointMeas1D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Covariance function, only really used when reading in the MB Covariances. TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covarPlot = new TH2D(); - // TH2D* decmpPlot = new TH2D(); - TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); std::string covName = ""; std::string covOption = FitPar::Config().GetParS("thrown_covariance"); if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); - covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << "Incorrect thrown_covariance option in parameters." << std::endl; int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar); } // Get Deteriminant and inverse matrix // fCovDet = this->covar->Determinant(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // Sets the covariance matrix from a provided file in a text format // scale is a multiplicative pre-factor to apply in the case where the // covariance is given in some unit (e.g. 1E-38) void JointMeas1D::SetCovarMatrixFromText(std::string covarFile, int dim, double scale) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), std::ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; else ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile << std::endl; // Loop over the lines in the file while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*covar)(row, column) = *iter; (*fFullCovar)(row, column) = *iter; column++; } row++; } covarread.close(); // Scale the actualy covariance matrix by some multiplicative factor (*fFullCovar) *= scale; // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); // THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); // Now need to multiply by the scaling factor // If the covariance (*this->covar) *= 1. / (scale); return; }; //******************************************************************** void JointMeas1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream corr(corrFile.c_str(), std::ifstream::in); this->covar = new TMatrixDSym(dim); this->fFullCovar = new TMatrixDSym(dim); if (corr.is_open()) LOG(SAM) << "Reading and converting correlation matrix from file: " << corrFile << std::endl; else { ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile << std::endl; exit(-1); } while (std::getline(corr >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 * this->fDataHist->GetBinError(column + 1) * 1E38; if (val == 0) { ERR(FTL) << "Found a zero value in the covariance matrix, assuming " "this is an error!" << std::endl; exit(-1); } (*this->covar)(row, column) = val; (*this->fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76. // If this is the case we need to scale it so that the chi2 contribution is correct // NUISANCE internally assumes the covariance matrix has units of 1E76 void JointMeas1D::SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits) { //******************************************************************** LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName << std::endl; TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str()); covPlot->SetDirectory(0); // Scale the covariance matrix if it comes in normal units if (FullUnits) { covPlot->Scale(1.E76); } int dim = covPlot->GetNbinsX(); fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { (*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1); } } this->covar = (TMatrixDSym*)fFullCovar->Clone(); fDecomp = (TMatrixDSym*)fFullCovar->Clone(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); TDecompChol LUChol = TDecompChol(*fDecomp); LUChol.Decompose(); fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), ""); return; }; // std::vector JointMeas1D::GetMCList(void){ // std::vector temp; // return temp; // } // std::vector JointMeas1D::GetDataList(void){ // std::vector temp; // return temp; // } // std::vector JointMeas1D::GetMaskList(void){ // std::vector temp; // return temp; // } // std::vector JointMeas1D::GetFineList(void){ // std::vector temp; // return temp; // } diff --git a/src/FitBase/Measurement1D.cxx b/src/FitBase/Measurement1D.cxx index d962403..2e2a64b 100644 --- a/src/FitBase/Measurement1D.cxx +++ b/src/FitBase/Measurement1D.cxx @@ -1,1903 +1,1900 @@ // Copyright 2016 L. Pickering, P. Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This ile is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Measurement1D.h" //******************************************************************** Measurement1D::Measurement1D(void) { //******************************************************************** // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; fShapeCovar = NULL; fCovar = NULL; fInvert = NULL; fDecomp = NULL; // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK/NOWIDTH"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsNoWidth = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; } //******************************************************************** Measurement1D::~Measurement1D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; if (fShapeCovar) delete fShapeCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; } //******************************************************************** void Measurement1D::FinaliseSampleSettings() { //******************************************************************** MeasurementBase::FinaliseSampleSettings(); // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } if (!fRW) fRW = FitBase::GetRW(); if (!fInput and !fIsJoint) SetupInputs(fSettings.GetS("input")); // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } } //******************************************************************** void Measurement1D::CreateDataHistogram(int dimx, double* binx) { //******************************************************************** if (fDataHist) delete fDataHist; fDataHist = new TH1D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(), dimx, binx) ; } //******************************************************************** void Measurement1D::SetDataFromTextFile(std::string datafile) { //******************************************************************** LOG(SAM) << "Reading data from text file: " << datafile << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(datafile, fSettings.GetName() + "_data", fSettings.GetFullTitles()); } //******************************************************************** void Measurement1D::SetDataFromRootFile(std::string datafile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); return; }; //******************************************************************** void Measurement1D::SetEmptyData(){ //******************************************************************** fDataHist = new TH1D("EMPTY_DATA","EMPTY_DATA",1,0.0,1.0); } //******************************************************************** void Measurement1D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void Measurement1D::SetCovarFromDiagonal(TH1D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } // if (!fIsDiag) { // ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " // << "that is not set as diagonal." << std::endl; // throw; // } } //******************************************************************** void Measurement1D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarFromMultipleTextFiles(std::string covfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector covList = GeneralUtils::ParseToStr(covfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < covList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << covList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(covList[i], dim); (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = fDataHist->GetNbinsX(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement1D::SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector corrList = GeneralUtils::ParseToStr(corrfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < corrList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << corrList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(corrList[i], dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*temp_cov)(i, j) = (*temp_cov)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement1D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } void Measurement1D::SetShapeCovar(){ // Return if this is missing any pre-requisites if (!fFullCovar) return; if (!fDataHist) return; // Also return if it's bloody stupid under the circumstances if (fIsDiag) return; fShapeCovar = StatUtils::ExtractShapeOnlyCovar(fFullCovar, fDataHist); return; } //******************************************************************** void Measurement1D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void Measurement1D::ScaleDataErrors(double scale) { //******************************************************************** for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinError(i + 1, fDataHist->GetBinError(i + 1) * scale); } } //******************************************************************** void Measurement1D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void Measurement1D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbins = fDataHist->GetNbinsX(); fMaskHist = new TH1I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins); std::string line; std::ifstream mask(maskfile.c_str(), std::ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[1] > 0) val = 1; fMaskHist->SetBinContent(entries[0], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void Measurement1D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; if (fSettings.GetB("onlymc")){ if (fDataHist) delete fDataHist; fDataHist = new TH1D("empty_data","empty_data",1,0.0,1.0); } // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Push the diagonals of fFullCovar onto the data histogram // Comment this out until the covariance/data scaling is consistent! StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); // If shape only, set covar and fDecomp using the shape-only matrix (if set) if (fIsShape && fShapeCovar and FitPar::Config().GetParB("UseShapeCovar")){ if (covar) delete covar; covar = StatUtils::GetInvert(fShapeCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetDecomp(fFullCovar); } // Setup fMCHist from data fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH1D("mcfine", "mcfine", fDataHist->GetNbinsX() * 8, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH1D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void Measurement1D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("NOWIDTH") != std::string::npos) fIsNoWidth = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; return; }; //******************************************************************** void Measurement1D::SetSmearingMatrix(std::string smearfile, int truedim, int recodim) { //******************************************************************** // The smearing matrix describes the migration from true bins (rows) to reco // bins (columns) // Counter over the true bins! int row = 0; std::string line; std::ifstream smear(smearfile.c_str(), std::ifstream::in); // Note that the smearing matrix may be rectangular. fSmearMatrix = new TMatrixD(truedim, recodim); if (smear.is_open()) LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl; else ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile << std::endl; while (std::getline(smear >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*fSmearMatrix)(row, column) = (*iter) / 100.; // Convert to fraction from // percentage (this may not be // general enough) column++; } row++; } return; } //******************************************************************** void Measurement1D::ApplySmearingMatrix() { //******************************************************************** if (!fSmearMatrix) { ERR(WRN) << fName << ": attempted to apply smearing matrix, but none was set" << std::endl; return; } TH1D* unsmeared = (TH1D*)fMCHist->Clone(); TH1D* smeared = (TH1D*)fMCHist->Clone(); smeared->Reset(); // Loop over reconstructed bins // true = row; reco = column for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) { // Sum up the constributions from all true bins double rBinVal = 0; // Loop over true bins for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) { rBinVal += (*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1); } smeared->SetBinContent(rbin + 1, rBinVal); } fMCHist = (TH1D*)smeared->Clone(); return; } /* Reconfigure LOOP */ //******************************************************************** void Measurement1D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void Measurement1D::FillHistograms() { //******************************************************************** if (Signal) { QLOG(DEB, "Fill MCHist: " << fXVar << ", " << Weight); fMCHist->Fill(fXVar, Weight); fMCFine->Fill(fXVar, Weight); fMCStat->Fill(fXVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight); } return; }; //******************************************************************** void Measurement1D::ScaleEvents() { //******************************************************************** // Fill MCWeighted; // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); // fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); // } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); if (fMCHist_Modes) { // Loop over the modes fMCHist_Modes->FluxUnfold(GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); //PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), //GetEventHistogram(), fScaleFactor, //fNEvents); } } else if (fIsNoWidth) { fMCHist->Scale(fScaleFactor); fMCFine->Scale(fScaleFactor); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor); // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up - delete statratio; - delete statratiofine; + delete[] statratio; + delete[] statratiofine; return; }; //******************************************************************** void Measurement1D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int Measurement1D::GetNDOF() { //******************************************************************** int ndof = fDataHist->GetNbinsX(); if (fMaskHist and fIsMask) ndof -= fMaskHist->Integral(); return ndof; } //******************************************************************** double Measurement1D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Apply Masking to MC if Required. if (fIsMask and fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } // Sort Shape Scaling double scaleF = 0.0; // TODO Include !fIsRawEvents if (fIsShape) { if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) { scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") / fMCHist->Integral(1, fMCHist->GetNbinsX(), "width"); fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); } } // Likelihood Calculation double stat = 0.; if (fIsChi2) { if (fIsRawEvents) { stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist); } else if (fIsDiag) { stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist); } else if (!fIsDiag and !fIsRawEvents) { stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist); } } // Sort Penalty Terms if (fAddNormPen) { double penalty = (1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError); stat += penalty; } // Return to normal scaling if (fIsShape) { // and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = stat; return stat; } /* Fake Data Functions */ //******************************************************************** void Measurement1D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH1D* tempdata = (TH1D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH1D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void Measurement1D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void Measurement1D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void Measurement1D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void Measurement1D::ThrowDataToy(){ //******************************************************************** if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH1D* Measurement1D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; // if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); // if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); // if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); // if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); // if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH1D* Measurement1D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; // if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); // if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); // if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void Measurement1D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos){ fSettings.Set("#chi^{2}",fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // Write Data/MC if (drawOpt.find("DATA") != std::string::npos) GetDataList().at(0)->Write(); if (drawOpt.find("MC") != std::string::npos) { GetMCList().at(0)->Write(); if((fEvtRateScaleFactor != 0xdeadbeef) && GetMCList().at(0)){ TH1D * PredictedEvtRate = static_cast(GetMCList().at(0)->Clone()); PredictedEvtRate->Scale(fEvtRateScaleFactor); PredictedEvtRate->GetYaxis()->SetTitle("Predicted event rate"); PredictedEvtRate->Write(); } } // Write Fine Histogram if (drawOpt.find("FINE") != std::string::npos) GetFineList().at(0)->Write(); // Write Weighted Histogram if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted) fMCWeighted->Write(); // Save Flux/Evt if no event manager if (!FitPar::Config().GetParB("EventManager")) { if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram()) GetFluxHistogram()->Write(); if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram()) GetXSecHistogram()->Write(); } // Write Mask if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) { fMaskHist->Write(); } // Write Covariances if (drawOpt.find("COV") != std::string::npos && fFullCovar) { PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName()); } if (drawOpt.find("INVCOV") != std::string::npos && covar) { PlotUtils::GetInvCovarPlot(covar, fSettings.GetName()); } if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) { PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName()); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // Ratio and Shape Plots if (drawOpt.find("RATIO") != std::string::npos) { WriteRatioPlot(); } if (drawOpt.find("SHAPE") != std::string::npos) { WriteShapePlot(); if (drawOpt.find("RATIO") != std::string::npos) WriteShapeRatioPlot(); } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } //******************************************************************** void Measurement1D::WriteRatioPlot() { //******************************************************************** // Setup mc data ratios TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH1D* mcRatio = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); // Extra MC Data Ratios for (int i = 0; i < mcRatio->GetNbinsX(); i++) { dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); dataRatio->SetBinError(i + 1, fDataHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinError(i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } // Write ratios mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } //******************************************************************** void Measurement1D::WriteShapePlot() { //******************************************************************** TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); TH1D* dataShape = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE").c_str()); // Don't check error if (fShapeCovar) StatUtils::SetDataErrorFromCov(dataShape, fShapeCovar, 1E-38, false); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); std::stringstream ss; ss << shapeScale; mcShape->SetTitle(ss.str().c_str()); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); mcShape->Write(); dataShape->Write(); delete mcShape; } //******************************************************************** void Measurement1D::WriteShapeRatioPlot() { //******************************************************************** // Get a mcshape histogram TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); // Create shape ratio histograms TH1D* mcShapeRatio = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } //// CRAP TO BE REMOVED //******************************************************************** void Measurement1D::SetupMeasurement(std::string inputfile, std::string type, FitWeight * rw, std::string fkdt) { //******************************************************************** nuiskey samplekey = Config::CreateKey("sample"); samplekey.Set("name", fName); samplekey.Set("type",type); samplekey.Set("input",inputfile); fSettings = LoadSampleSettings(samplekey); // Reset everything to NULL // Init(); // Check if name contains Evt, indicating that it is a raw number of events // measurements and should thus be treated as once fIsRawEvents = false; if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!" << std::endl; LOG(SAM) << "Overriding this and setting fIsRawEvents == true!" << std::endl; } fIsEnu1D = false; if (fName.find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; throw; } fRW = rw; if (!fInput and !fIsJoint) SetupInputs(inputfile); // Set Default Options SetFitOptions(fDefaultTypes); // Set Passed Options SetFitOptions(type); // Still adding support for flat flux inputs // // Set Enu Flux Scaling // if (isFlatFluxFolding) this->Input()->ApplyFluxFolding( // this->defaultFluxHist ); // FinaliseMeasurement(); } //******************************************************************** void Measurement1D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBins = fMCHist->GetNbinsX(); fMCFine = new TH1D( (fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1)); fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); fMCHist->Reset(); fMCFine->Reset(); // Setup the NEUT Mode Array PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG); PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write); return; } //******************************************************************** void Measurement1D::SetDataValues(std::string dataFile) { //******************************************************************** // Override this function if the input file isn't in a suitable format LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles); fDataTrue = (TH1D*)fDataHist->Clone(); // Number of data points is number of bins fNDataPointsX = fDataHist->GetXaxis()->GetNbins(); return; }; //******************************************************************** void Measurement1D::SetDataFromDatabase(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile( (GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void Measurement1D::SetDataFromFile(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void Measurement1D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Covariance function, only really used when reading in the MB Covariances. TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covarPlot = new TH2D(); - // TH2D* decmpPlot = new TH2D(); - TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); std::string covName = ""; std::string covOption = FitPar::Config().GetParS("thrown_covariance"); if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); - covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << "Incorrect thrown_covariance option in parameters." << std::endl; int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar); } // Get Deteriminant and inverse matrix // fCovDet = this->covar->Determinant(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // Sets the covariance matrix from a provided file in a text format // scale is a multiplicative pre-factor to apply in the case where the // covariance is given in some unit (e.g. 1E-38) void Measurement1D::SetCovarMatrixFromText(std::string covarFile, int dim, double scale) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), std::ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; else ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile << std::endl; // Loop over the lines in the file while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*covar)(row, column) = *iter; (*fFullCovar)(row, column) = *iter; column++; } row++; } covarread.close(); // Scale the actualy covariance matrix by some multiplicative factor (*fFullCovar) *= scale; // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); // THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); // Now need to multiply by the scaling factor // If the covariance (*this->covar) *= 1. / (scale); return; }; //******************************************************************** void Measurement1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream corr(corrFile.c_str(), std::ifstream::in); this->covar = new TMatrixDSym(dim); this->fFullCovar = new TMatrixDSym(dim); if (corr.is_open()) LOG(SAM) << "Reading and converting correlation matrix from file: " << corrFile << std::endl; else { ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile << std::endl; exit(-1); } while (std::getline(corr >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 * this->fDataHist->GetBinError(column + 1) * 1E38; if (val == 0) { ERR(FTL) << "Found a zero value in the covariance matrix, assuming " "this is an error!" << std::endl; exit(-1); } (*this->covar)(row, column) = val; (*this->fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76. // If this is the case we need to scale it so that the chi2 contribution is correct // NUISANCE internally assumes the covariance matrix has units of 1E76 void Measurement1D::SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits) { //******************************************************************** LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName << std::endl; TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str()); covPlot->SetDirectory(0); // Scale the covariance matrix if it comes in normal units if (FullUnits) { covPlot->Scale(1.E76); } int dim = covPlot->GetNbinsX(); fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { (*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1); } } this->covar = (TMatrixDSym*)fFullCovar->Clone(); fDecomp = (TMatrixDSym*)fFullCovar->Clone(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); TDecompChol LUChol = TDecompChol(*fDecomp); LUChol.Decompose(); fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), ""); return; }; // //******************************************************************** // void Measurement1D::SetBinMask(std::string maskFile) { // //******************************************************************** // // Create a mask histogram. // int nbins = fDataHist->GetNbinsX(); // fMaskHist = // new TH1I((fName + "_fMaskHist").c_str(), // (fName + "_fMaskHist; Bin; Mask?").c_str(), nbins, 0, nbins); // std::string line; // std::ifstream mask(maskFile.c_str(), std::ifstream::in); // if (mask.is_open()) // LOG(SAM) << "Reading bin mask from file: " << maskFile << std::endl; // else // LOG(FTL) << " Cannot find mask file." << std::endl; // while (std::getline(mask >> std::ws, line, '\n')) { // std::vector entries = GeneralUtils::ParseToInt(line, " "); // // Skip lines with poorly formatted lines // if (entries.size() < 2) { // LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line // << std::endl; // continue; // } // // The first index should be the bin number, the second should be the mask // // value. // fMaskHist->SetBinContent(entries[0], entries[1]); // } // // Set masked data bins to zero // PlotUtils::MaskBins(fDataHist, fMaskHist); // return; // } // //******************************************************************** // void Measurement1D::GetBinContents(std::vector& cont, // std::vector& err) { // //******************************************************************** // // Return a vector of the main bin contents // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // cont.push_back(fMCHist->GetBinContent(i + 1)); // err.push_back(fMCHist->GetBinError(i + 1)); // } // return; // }; /* XSec Functions */ // //******************************************************************** // void Measurement1D::SetFluxHistogram(std::string fluxFile, int minE, int // maxE, // double fluxNorm) { // //******************************************************************** // // Note this expects the flux bins to be given in terms of MeV // LOG(SAM) << "Reading flux from file: " << fluxFile << std::endl; // TGraph f(fluxFile.c_str(), "%lg %lg"); // fFluxHist = // new TH1D((fName + "_flux").c_str(), (fName + "; E_{#nu} (GeV)").c_str(), // f.GetN() - 1, minE, maxE); // Double_t* yVal = f.GetY(); // for (int i = 0; i < fFluxHist->GetNbinsX(); ++i) // fFluxHist->SetBinContent(i + 1, yVal[i] * fluxNorm); // }; // //******************************************************************** // double Measurement1D::TotalIntegratedFlux(std::string intOpt, double low, // double high) { // //******************************************************************** // if (fInput->GetType() == kGiBUU) { // return 1.0; // } // // The default case of low = -9999.9 and high = -9999.9 // if (low == -9999.9) low = this->EnuMin; // if (high == -9999.9) high = this->EnuMax; // int minBin = fFluxHist->GetXaxis()->FindBin(low); // int maxBin = fFluxHist->GetXaxis()->FindBin(high); // // Get integral over custom range // double integral = fFluxHist->Integral(minBin, maxBin + 1, intOpt.c_str()); // return integral; // }; diff --git a/src/FitBase/Measurement2D.cxx b/src/FitBase/Measurement2D.cxx index 2b920bd..e9b2893 100644 --- a/src/FitBase/Measurement2D.cxx +++ b/src/FitBase/Measurement2D.cxx @@ -1,1922 +1,1917 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Measurement2D.h" #include "TDecompChol.h" //******************************************************************** Measurement2D::Measurement2D(void) { //******************************************************************** covar = NULL; fDecomp = NULL; fFullCovar = NULL; fMCHist = NULL; fMCFine = NULL; fDataHist = NULL; fMCHist_X = NULL; fMCHist_Y = NULL; fDataHist_X = NULL; fDataHist_Y = NULL; fMaskHist = NULL; fMapHist = NULL; fDataOrig = NULL; fDataTrue = NULL; fMCWeighted = NULL; fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/FITPROJX/" "FITPROJY"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu = false; // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; fCovar = NULL; fInvert = NULL; fDecomp = NULL; // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; } //******************************************************************** Measurement2D::~Measurement2D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; } //******************************************************************** void Measurement2D::FinaliseSampleSettings() { //******************************************************************** MeasurementBase::FinaliseSampleSettings(); // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } if (!fRW) fRW = FitBase::GetRW(); if (!fInput) SetupInputs(fSettings.GetS("input")); // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { fNormError = fSettings.GetNormError(); if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } } void Measurement2D::CreateDataHistogram(int dimx, double* binx, int dimy, double* biny) { if (fDataHist) delete fDataHist; LOG(SAM) << "Creating Data Histogram dim : " << dimx << " " << dimy << std::endl; fDataHist = new TH2D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(), dimx - 1, binx, dimy - 1, biny ); } void Measurement2D::SetDataFromTextFile(std::string datfile) { // fDataHist = PlotUtils::GetTH2DFromTextFile(datfile,""); } void Measurement2D::SetDataFromRootFile(std::string datfile, std::string histname) { LOG(SAM) << "Reading data from root file: " << datfile << ";" << histname << std::endl; fDataHist = PlotUtils::GetTH2DFromRootFile(datfile, histname); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); } void Measurement2D::SetDataValuesFromTextFile(std::string datfile, TH2D* hist) { LOG(SAM) << "Setting data values from text file" << std::endl; if (!hist) hist = fDataHist; // Read TH2D From textfile TH2D* valhist = (TH2D*) hist->Clone(); valhist->Reset(); PlotUtils::Set2DHistFromText(datfile, valhist, 1.0, true); LOG(SAM) << " -> Filling values from read hist." << std::endl; for (int i = 0; i < valhist->GetNbinsX(); i++) { for (int j = 0; j < valhist->GetNbinsY(); j++) { hist->SetBinContent(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1)); } } LOG(SAM) << " --> Done" << std::endl; } void Measurement2D::SetDataErrorsFromTextFile(std::string datfile, TH2D* hist) { LOG(SAM) << "Setting data errors from text file" << std::endl; if (!hist) hist = fDataHist; // Read TH2D From textfile TH2D* valhist = (TH2D*) hist->Clone(); valhist->Reset(); PlotUtils::Set2DHistFromText(datfile, valhist, 1.0); // Fill Errors LOG(SAM) << " -> Filling errors from read hist." << std::endl; for (int i = 0; i < valhist->GetNbinsX(); i++) { for (int j = 0; j < valhist->GetNbinsY(); j++) { hist->SetBinError(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1)); } } LOG(SAM) << " --> Done" << std::endl; } void Measurement2D::SetMapValuesFromText(std::string dataFile) { TH2D* hist = fDataHist; std::vector edgex; std::vector edgey; for (int i = 0; i <= hist->GetNbinsX(); i++) edgex.push_back(hist->GetXaxis()->GetBinLowEdge(i + 1)); for (int i = 0; i <= hist->GetNbinsY(); i++) edgey.push_back(hist->GetYaxis()->GetBinLowEdge(i + 1)); fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(), edgex.size() - 1, &edgex[0], edgey.size() - 1, &edgey[0]); LOG(SAM) << "Reading map from: " << dataFile << std::endl; PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0); } //******************************************************************** void Measurement2D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void Measurement2D::SetCovarFromDiagonal(TH2D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } // if (!fIsDiag) { // ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " // << "that is not set as diagonal." << std::endl; // throw; // } } //******************************************************************** void Measurement2D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading covariance from text file: " << covfile << " " << dim << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = this->GetNDOF(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement2D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement2D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading cholesky from text file: " << covfile << " " << dim << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement2D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement2D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void Measurement2D::ScaleDataErrors(double scale) { //******************************************************************** for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsY(); j++) { fDataHist->SetBinError(i + 1, j + 1, fDataHist->GetBinError(i + 1, j + 1) * scale); } } } //******************************************************************** void Measurement2D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void Measurement2D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbinsx = fDataHist->GetNbinsX(); int nbinxy = fDataHist->GetNbinsY(); fMaskHist = new TH2I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbinsx, 0, nbinsx, nbinxy, 0, nbinxy); std::string line; std::ifstream mask(maskfile.c_str(), std::ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "Measurement2D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[2] > 0) val = 1; fMaskHist->SetBinContent(entries[0], entries[1], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void Measurement2D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; if (fSettings.GetB("onlymc")) { if (fDataHist) delete fDataHist; fDataHist = new TH2D("empty_data", "empty_data", 1, 0.0, 1.0,1,0.0,1.0); } // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Setup fMCHist from data fMCHist = (TH2D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH2D("mcfine", "mcfine", fDataHist->GetNbinsX() * 6, fMCHist->GetXaxis()->GetBinLowEdge(1), fMCHist->GetXaxis()->GetBinLowEdge(fDataHist->GetNbinsX() + 1), fDataHist->GetNbinsY() * 6, fMCHist->GetYaxis()->GetBinLowEdge(1), fMCHist->GetYaxis()->GetBinLowEdge(fDataHist->GetNbinsY() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH2D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH2D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void Measurement2D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) fIsChi2 = false; else fIsChi2 = true; // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; fIsProjFitX = (opt.find("FITPROJX") != std::string::npos); fIsProjFitY = (opt.find("FITPROJY") != std::string::npos); return; }; /* Reconfigure LOOP */ //******************************************************************** void Measurement2D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void Measurement2D::FillHistograms() { //******************************************************************** if (Signal) { fMCHist->Fill(fXVar, fYVar, Weight); fMCFine->Fill(fXVar, fYVar, Weight); fMCStat->Fill(fXVar, fYVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, fYVar, Weight); } return; }; //******************************************************************** void Measurement2D::ScaleEvents() { //******************************************************************** // Fill MCWeighted; // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); // fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); // } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor); // if (fMCHist_Modes) { // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), // GetEventHistogram(), fScaleFactor, // fNEvents); // } // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); // if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up delete statratio; delete statratiofine; return; }; //******************************************************************** void Measurement2D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int Measurement2D::GetNDOF() { //******************************************************************** // Just incase it has gone... if (!fDataHist) return -1; int nDOF = 0; // If datahist has no errors make sure we don't include those bins as they are // not data points for (int xBin = 0; xBin < fDataHist->GetNbinsX(); ++xBin) { for (int yBin = 0; yBin < fDataHist->GetNbinsY(); ++yBin) { if (fDataHist->GetBinError(xBin+1, yBin+1) != 0) ++nDOF; } } // Account for possible bin masking int nMasked = 0; if (fMaskHist and fIsMask) if (fMaskHist->Integral() > 0) for (int xBin = 0; xBin < fMaskHist->GetNbinsX() + 1; ++xBin) for (int yBin = 0; yBin < fMaskHist->GetNbinsY() + 1; ++yBin) if (fMaskHist->GetBinContent(xBin, yBin) > 0.5) ++nMasked; // Take away those masked DOF if (fIsMask) { nDOF -= nMasked; } return nDOF; } //******************************************************************** double Measurement2D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Fix weird masking bug if (!fIsMask) { if (fMaskHist) { fMaskHist = NULL; } } else { if (fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } } // if (fIsProjFitX or fIsProjFitY) return GetProjectedChi2(); // Scale up the results to match each other (Not using width might be // inconsistent with Meas1D) double scaleF = fDataHist->Integral() / fMCHist->Integral(); if (fIsShape) { fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); //PlotUtils::ScaleNeutModeArray((TH1**)fMCHist_PDG, scaleF); } if (!fMapHist) { fMapHist = StatUtils::GenerateMap(fDataHist); } // Get the chi2 from either covar or diagonals double chi2 = 0.0; if (fIsChi2) { if (fIsDiag) { chi2 = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMapHist, fMaskHist); } else { chi2 = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMapHist, fMaskHist); } } // Add a normal penalty term if (fAddNormPen) { chi2 += (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError); LOG(REC) << "Norm penalty = " << (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError) << std::endl; } // Adjust the shape back to where it was. if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = chi2; return chi2; } /* Fake Data Functions */ //******************************************************************** void Measurement2D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH2D* tempdata = (TH2D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH2D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH2D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH2D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH2D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX() * fDataHist->GetNbinsY(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { if (tempdata->GetBinContent(i + 1) && tempdata->GetBinContent(j + 1)) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); } else { alpha_i = 0.0; alpha_j = 0.0; } (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void Measurement2D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH2D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void Measurement2D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH2D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void Measurement2D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void Measurement2D::ThrowDataToy() { //******************************************************************** if (!fDataTrue) fDataTrue = (TH2D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH2D* Measurement2D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH2D* Measurement2D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void Measurement2D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos) { fSettings.Set("#chi^{2}", fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } /// 2D VERSION // If null pointer return if (!fMCHist and !fDataHist) { LOG(SAM) << fName << "Incomplete histogram set!" << std::endl; return; } // Config::Get().out->cd(); // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); bool drawData = (drawOpt.find("DATA") != std::string::npos); bool drawNormal = (drawOpt.find("MC") != std::string::npos); bool drawEvents = (drawOpt.find("EVT") != std::string::npos); - bool drawXSec = (drawOpt.find("XSEC") != std::string::npos); bool drawFine = (drawOpt.find("FINE") != std::string::npos); bool drawRatio = (drawOpt.find("RATIO") != std::string::npos); // bool drawModes = (drawOpt.find("MODES") != std::string::npos); bool drawShape = (drawOpt.find("SHAPE") != std::string::npos); bool residual = (drawOpt.find("RESIDUAL") != std::string::npos); bool drawMatrix = (drawOpt.find("MATRIX") != std::string::npos); bool drawFlux = (drawOpt.find("FLUX") != std::string::npos); bool drawMask = (drawOpt.find("MASK") != std::string::npos); bool drawMap = (drawOpt.find("MAP") != std::string::npos); bool drawProj = (drawOpt.find("PROJ") != std::string::npos); // bool drawCanvPDG = (drawOpt.find("CANVPDG") != std::string::npos); bool drawCov = (drawOpt.find("COV") != std::string::npos); bool drawSliceCanvYMC = (drawOpt.find("CANVYMC") != std::string::npos); bool drawWeighted = (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted); if (FitPar::Config().GetParB("EventManager")) { drawFlux = false; - drawXSec = false; drawEvents = false; } // Save standard plots if (drawData) { GetDataList().at(0)->Write(); // Generate a simple map if (!fMapHist) fMapHist = StatUtils::GenerateMap(fDataHist); // Convert to 1D Lists TH1D* data_1D = StatUtils::MapToTH1D(fDataHist, fMapHist); data_1D->Write(); delete data_1D; } if (drawNormal) { GetMCList().at(0)->Write(); if (!fMapHist) fMapHist = StatUtils::GenerateMap(fDataHist); TH1D* mc_1D = StatUtils::MapToTH1D(fMCHist, fMapHist); mc_1D->Write(); delete mc_1D; } // Write Weighted Histogram if (drawWeighted) fMCWeighted->Write(); if (drawCov) { TH2D(*fFullCovar).Write((fName + "_COV").c_str()); } if (drawOpt.find("INVCOV") != std::string::npos) { TH2D(*covar).Write((fName + "_INVCOV").c_str()); } // Save only mc and data if splines if (fEventType == 4 or fEventType == 3) { return; } // Draw Extra plots if (drawFine) this->GetFineList().at(0)->Write(); if (drawFlux and GetFluxHistogram()) { GetFluxHistogram()->Write(); } if (drawEvents and GetEventHistogram()) { GetEventHistogram()->Write(); } if (fIsMask and drawMask) { fMaskHist->Write((fName + "_MSK").c_str()); //< save mask TH1I* mask_1D = StatUtils::MapToMask(fMaskHist, fMapHist); if (mask_1D) { mask_1D->Write(); TMatrixDSym* calc_cov = StatUtils::ApplyInvertedMatrixMasking(covar, mask_1D); TH1D* data_1D = StatUtils::MapToTH1D(fDataHist, fMapHist); TH1D* mc_1D = StatUtils::MapToTH1D(fMCHist, fMapHist); TH1D* calc_data = StatUtils::ApplyHistogramMasking(data_1D, mask_1D); TH1D* calc_mc = StatUtils::ApplyHistogramMasking(mc_1D, mask_1D); TH2D* bin_cov = new TH2D(*calc_cov); bin_cov->Write(); calc_data->Write(); calc_mc->Write(); delete mask_1D; delete calc_cov; delete calc_data; delete calc_mc; delete bin_cov; delete data_1D; delete mc_1D; } } if (drawMap) fMapHist->Write((fName + "_MAP").c_str()); //< save map // // Save neut stack // if (drawModes) { // THStack combo_fMCHist_PDG = PlotUtils::GetNeutModeStack( // (fName + "_MC_PDG").c_str(), (TH1**)fMCHist_PDG, 0); // combo_fMCHist_PDG.Write(); // } // Save Matrix plots if (drawMatrix and fFullCovar and covar and fDecomp) { TH2D cov = TH2D((*fFullCovar)); cov.SetNameTitle((fName + "_cov").c_str(), (fName + "_cov;Bins; Bins;").c_str()); cov.Write(); TH2D covinv = TH2D((*this->covar)); covinv.SetNameTitle((fName + "_covinv").c_str(), (fName + "_cov;Bins; Bins;").c_str()); covinv.Write(); TH2D covdec = TH2D((*fDecomp)); covdec.SetNameTitle((fName + "_covdec").c_str(), (fName + "_cov;Bins; Bins;").c_str()); covdec.Write(); } // Save ratio plots if required if (drawRatio) { // Needed for error bars for (int i = 0; i < fMCHist->GetNbinsX() * fMCHist->GetNbinsY(); i++) fMCHist->SetBinError(i + 1, 0.0); fDataHist->GetSumw2(); fMCHist->GetSumw2(); // Create Ratio Histograms TH2D* dataRatio = (TH2D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH2D* mcRatio = (TH2D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); mcRatio->Divide(fMCHist); dataRatio->Divide(fMCHist); // Cancel bin errors on MC for (int i = 0; i < mcRatio->GetNbinsX() * mcRatio->GetNbinsY(); i++) { mcRatio->SetBinError( i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } mcRatio->SetMinimum(0); mcRatio->SetMaximum(2); dataRatio->SetMinimum(0); dataRatio->SetMaximum(2); mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } // Save Shape Plots if required if (drawShape) { // Create Shape Histogram TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); // dashes mcShape->Write(); // Save shape ratios if (drawRatio) { // Needed for error bars mcShape->GetSumw2(); // Create shape ratio histograms TH2D* mcShapeRatio = (TH2D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH2D* dataShapeRatio = (TH2D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); // dashes mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } delete mcShape; } // Save residual calculations of what contributed to the chi2 values. if (residual) { } if (fIsProjFitX or fIsProjFitY or drawProj) { // If not already made, make the projections if (!fMCHist_X) { PlotUtils::MatchEmptyBins(fDataHist, fMCHist); fMCHist_X = PlotUtils::GetProjectionX(fMCHist, fMaskHist); fMCHist_Y = PlotUtils::GetProjectionY(fMCHist, fMaskHist); fDataHist_X = PlotUtils::GetProjectionX(fDataHist, fMaskHist); fDataHist_Y = PlotUtils::GetProjectionY(fDataHist, fMaskHist); double chi2X = StatUtils::GetChi2FromDiag(fDataHist_X, fMCHist_X); double chi2Y = StatUtils::GetChi2FromDiag(fDataHist_Y, fMCHist_Y); fMCHist_X->SetTitle(Form("%f", chi2X)); fMCHist_Y->SetTitle(Form("%f", chi2Y)); } // Save the histograms fDataHist_X->Write(); fMCHist_X->Write(); fDataHist_Y->Write(); fMCHist_Y->Write(); } if (drawSliceCanvYMC or true) { TCanvas* c1 = new TCanvas((fName + "_MC_CANV_Y").c_str(), (fName + "_MC_CANV_Y").c_str(), 800, 600); c1->Divide(int(sqrt(fDataHist->GetNbinsY() + 1)), int(sqrt(fDataHist->GetNbinsY() + 1))); TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); mcShape->Scale(shapeScale); mcShape->SetLineStyle(7); c1->cd(1); TLegend* leg = new TLegend(0.6, 0.6, 0.9, 0.9); leg->AddEntry(fDataHist, (fName + " Data").c_str(), "ep"); leg->AddEntry(fMCHist, (fName + " MC").c_str(), "l"); leg->AddEntry(mcShape, (fName + " Shape").c_str(), "l"); leg->Draw("SAME"); /* // Make Y slices for (int i = 0; i < fDataHist->GetNbinY(); i++){ c1->cd(i+2); TH1D* fDataHist_SliceY = PlotUtils::GetSliceY(fDataHist, i); fDataHist_SliceY->Draw("E1"); TH1D* fMCHist_SliceY = PlotUtils::GetSliceY(fMCHist, i); fMCHist_SliceY->Draw("SAME HIST C"); TH1D* mcShape_SliceY = PlotUtils::GetSliceY(mcShape, i); mcShape_SliceY->Draw("SAME HIST C"); } */ c1->Write(); } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } /* Setup Functions */ //******************************************************************** void Measurement2D::SetupMeasurement(std::string inputfile, std::string type, FitWeight* rw, std::string fkdt) { //******************************************************************** // Check if name contains Evt, indicating that it is a raw number of events // measurements and should thus be treated as once fIsRawEvents = false; if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!" << std::endl; LOG(SAM) << "Overriding this and setting fIsRawEvents == true!" << std::endl; } fIsEnu = false; if ((fName.find("XSec") != std::string::npos) && (fName.find("Enu") != std::string::npos)) { fIsEnu = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " "not flux averaged!" << std::endl; if (FitPar::Config().GetParB("EventManager")) { ERR(FTL) << "Enu Measurements do not yet work with the Event Manager!" << std::endl; ERR(FTL) << "If you want decent flux unfolded results please run in " "series mode (-q EventManager=0)" << std::endl; sleep(2); } } if (fIsEnu && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } // Reset everything to NULL fRW = rw; // Setting up 2D Inputs this->SetupInputs(inputfile); // Set Default Options SetFitOptions(fDefaultTypes); // Set Passed Options SetFitOptions(type); } //******************************************************************** void Measurement2D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH2D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBinsX = fMCHist->GetNbinsX(); Int_t nBinsY = fMCHist->GetNbinsY(); fMCFine = new TH2D((fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBinsX * 3, fMCHist->GetXaxis()->GetBinLowEdge(1), fMCHist->GetXaxis()->GetBinLowEdge(nBinsX + 1), nBinsY * 3, fMCHist->GetYaxis()->GetBinLowEdge(1), fMCHist->GetYaxis()->GetBinLowEdge(nBinsY + 1)); // Setup MC Stat fMCStat = (TH2D*)fMCHist->Clone(); fMCStat->Reset(); // Setup the NEUT Mode Array //PlotUtils::CreateNeutModeArray(fMCHist, (TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } return; } //******************************************************************** void Measurement2D::SetDataValues(std::string dataFile, std::string TH2Dname) { //******************************************************************** if (dataFile.find(".root") == std::string::npos) { ERR(FTL) << "Error! " << dataFile << " is not a .root file" << std::endl; ERR(FTL) << "Currently only .root file reading is supported (MiniBooNE " "CC1pi+ 2D), but implementing .txt should be dirt easy" << std::endl; ERR(FTL) << "See me at " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } else { TFile* inFile = new TFile(dataFile.c_str(), "READ"); fDataHist = (TH2D*)(inFile->Get(TH2Dname.c_str())->Clone()); fDataHist->SetDirectory(0); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_MC" + fPlotTitles).c_str()); delete inFile; } return; } //******************************************************************** void Measurement2D::SetDataValues(std::string dataFile, double dataNorm, std::string errorFile, double errorNorm) { //******************************************************************** // Make a counter to track the line number int yBin = 0; std::string line; std::ifstream data(dataFile.c_str(), std::ifstream::in); fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(), fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); if (data.is_open()) LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; while (std::getline(data >> std::ws, line, '\n')) { int xBin = 0; // Loop over entries and insert them into the histogram std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { fDataHist->SetBinContent(xBin + 1, yBin + 1, (*iter) * dataNorm); xBin++; } yBin++; } yBin = 0; std::ifstream error(errorFile.c_str(), std::ifstream::in); if (error.is_open()) LOG(SAM) << "Reading errors from: " << errorFile.c_str() << std::endl; while (std::getline(error >> std::ws, line, '\n')) { int xBin = 0; // Loop over entries and insert them into the histogram std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { fDataHist->SetBinError(xBin + 1, yBin + 1, (*iter) * errorNorm); xBin++; } yBin++; } return; }; //******************************************************************** void Measurement2D::SetDataValuesFromText(std::string dataFile, double dataNorm) { //******************************************************************** fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(), fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); LOG(SAM) << "Reading data from: " << dataFile << std::endl; PlotUtils::Set2DHistFromText(dataFile, fDataHist, dataNorm, true); return; }; //******************************************************************** void Measurement2D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Used to read a covariance matrix from a root file TFile* tempFile = new TFile(covarFile.c_str(), "READ"); // Make plots that we want TH2D* covarPlot = new TH2D(); - // TH2D* decmpPlot = new TH2D(); - TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); // Get covariance options for fake data studies std::string covName = ""; std::string covOption = FitPar::Config().GetParS("throw_covariance"); // Which matrix to get? if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); - covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); // Throw either the sub matrix or the full matrix if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << " Incorrect thrown_covariance option in parameters." << std::endl; // Bin masking? int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); // Make new covars this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); // Full covariance values int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // masking can be dodgy // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { for (Int_t i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinError( i + 1, sqrt((covarPlot->GetBinContent(i + 1, i + 1))) * 1E-38); } } TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); tempFile->Close(); delete tempFile; return; }; //******************************************************************** void Measurement2D::SetCovarMatrixFromText(std::string covarFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covar(covarFile.c_str(), std::ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covar.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * fDataHist->GetBinError(row + 1) * 1E38 * fDataHist->GetBinError(column + 1) * 1E38; (*this->covar)(row, column) = val; (*fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** void Measurement2D::SetCovarMatrixFromChol(std::string covarFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), std::ifstream::in); TMatrixD* newcov = new TMatrixD(dim, dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*newcov)(row, column) = *iter; column++; } row++; } covarread.close(); // Form full covariance TMatrixD* trans = (TMatrixD*)(newcov)->Clone(); trans->T(); (*trans) *= (*newcov); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); delete newcov; delete trans; // Robust matrix inversion method TDecompChol LU = TDecompChol(*this->fFullCovar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; // //******************************************************************** // void Measurement2D::SetMapValuesFromText(std::string dataFile) { // //******************************************************************** // fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(), // fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); // LOG(SAM) << "Reading map from: " << dataFile << std::endl; // PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0); // return; // }; diff --git a/src/FitBase/MeasurementBase.cxx b/src/FitBase/MeasurementBase.cxx index 9c8c621..cad257f 100644 --- a/src/FitBase/MeasurementBase.cxx +++ b/src/FitBase/MeasurementBase.cxx @@ -1,597 +1,589 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MeasurementBase.h" /* Constructor/Destructors */ //******************************************************************** // 2nd Level Constructor (Inherits From MeasurementBase.h) MeasurementBase::MeasurementBase(void) { //******************************************************************** fScaleFactor = 1.0; fMCFilled = false; fNoData = false; fInput = NULL; NSignal = 0; // Set the default values // After-wards this gets set in SetupMeasurement EnuMin = 0.; EnuMax = 1.E5; fMeasurementSpeciesType = kSingleSpeciesMeasurement; fEventVariables = NULL; fIsJoint = false; fNPOT = 0xdeadbeef; fFluxIntegralOverride = 0xdeadbeef; fTargetVolume = 0xdeadbeef; fTargetMaterialDensity = 0xdeadbeef; fEvtRateScaleFactor = 0xdeadbeef; }; void MeasurementBase::FinaliseMeasurement() { // Used to setup default data hists, covars, etc. } //******************************************************************** // 2nd Level Destructor (Inherits From MeasurementBase.h) MeasurementBase::~MeasurementBase(){ //******************************************************************** }; //******************************************************************** double MeasurementBase::TotalIntegratedFlux(std::string intOpt, double low, double high) { //******************************************************************** // Set Energy Limits if (low == -9999.9) low = this->EnuMin; if (high == -9999.9) high = this->EnuMax; return GetInput()->TotalIntegratedFlux(low, high, intOpt); }; //******************************************************************** double MeasurementBase::PredictedEventRate(std::string intOpt, double low, double high) { //******************************************************************** // Set Energy Limits if (low == -9999.9) low = this->EnuMin; if (high == -9999.9) high = this->EnuMax; return GetInput()->PredictedEventRate(low, high, intOpt) * 1E-38; }; //******************************************************************** void MeasurementBase::SetupInputs(std::string inputfile) { //******************************************************************** // Add this infile to the global manager if (FitPar::Config().GetParB("EventManager")) { fInput = FitBase::AddInput(fName, inputfile); } else { std::vector file_descriptor = GeneralUtils::ParseToStr(inputfile, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inpType = InputUtils::ParseInputType(file_descriptor[0]); fInput = InputUtils::CreateInputHandler(fName, inpType, file_descriptor[1]); } fNEvents = fInput->GetNEvents(); // Expect INPUTTYPE:FileLocation(s) std::vector file_descriptor = GeneralUtils::ParseToStr(inputfile, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } fInputType = InputUtils::ParseInputType(file_descriptor[0]); fInputFileName = file_descriptor[1]; if (EnuMin == 0 && EnuMax == 1.E5) { EnuMin = fInput->GetFluxHistogram()->GetBinLowEdge(1); EnuMax = fInput->GetFluxHistogram()->GetBinLowEdge( fInput->GetFluxHistogram()->GetNbinsX() + 1); } fFluxHist = fInput->GetFluxHistogram(); fEventHist = fInput->GetEventHistogram(); } //*********************************************** int MeasurementBase::GetInputID() { //*********************************************** return FitBase::GetInputID(fInputFileName); } //*********************************************** SampleSettings MeasurementBase::LoadSampleSettings(nuiskey samplekey) { //*********************************************** SampleSettings setting = SampleSettings(samplekey); fName = setting.GetS("name"); // Used as an initial setup function incase we need to do anything here. LOG(SAM) << "Loading Sample : " << setting.GetName() << std::endl; fEvtRateScaleFactor = 0xdeadbeef; if (!fIsJoint) { SetupInputs(setting.GetS("input")); fNPOT = samplekey.Has("NPOT") ? samplekey.GetD("NPOT") : 1; fFluxIntegralOverride = samplekey.Has("FluxIntegralOverride") ? samplekey.GetD("FluxIntegralOverride") : 0xdeadbeef; fTargetVolume = samplekey.Has("TargetVolume") ? samplekey.GetD("TargetVolume") : 0xdeadbeef; fTargetMaterialDensity = samplekey.Has("TargetMaterialDensity") ? samplekey.GetD("TargetMaterialDensity") : 0xdeadbeef; if ((fTargetVolume != 0xdeadbeef) && (fTargetMaterialDensity != 0xdeadbeef)) { double TargetMass_kg = fTargetVolume * fTargetMaterialDensity; double NNucleons = TargetMass_kg / PhysConst::mass_nucleon_kg; double NNeutrinos = ((fFluxIntegralOverride == 0xdeadbeef) ? TotalIntegratedFlux() : fFluxIntegralOverride) * fNPOT; fEvtRateScaleFactor = NNeutrinos * NNucleons; QLOG(SAM, "\tEvent rate prediction : "); QLOG(SAM, "\t\tTarget volume : " << fTargetVolume << " m^3"); QLOG(SAM, "\t\tTarget density : " << fTargetMaterialDensity << " kg/m^3"); QLOG(SAM, "\t\tTarget mass : " << TargetMass_kg << " kg"); QLOG(SAM, "\t\tNTarget Nucleons : " << NNucleons); if ((fNPOT != 1)) { QLOG(SAM, "\t\tTotal POT : " << fNPOT); } QLOG(SAM, "\t\tNNeutrinos : " << NNeutrinos << ((fNPOT != 1) ? " /cm^2" : " /POT /cm^2")); QLOG(SAM, "\t\tXSec -> EvtRate scale factor : " << fEvtRateScaleFactor); } } return setting; } //*********************************************** SampleSettings MeasurementBase::LoadSampleSettings(std::string name, std::string input, std::string type) { //*********************************************** nuiskey samplekey = Config::CreateKey("sample"); samplekey.SetS("name", name); samplekey.SetS("input", input); samplekey.SetS("type", type); return LoadSampleSettings(samplekey); } void MeasurementBase::FinaliseSampleSettings() { EnuMin = fSettings.GetD("enu_min"); EnuMax = fSettings.GetD("enu_max"); } //*********************************************** void MeasurementBase::Reconfigure() { //*********************************************** LOG(REC) << " Reconfiguring sample " << fName << std::endl; // Reset Histograms ResetExtraHistograms(); AutoResetExtraTH1(); this->ResetAll(); // FitEvent* cust_event = fInput->GetEventPointer(); int fNEvents = fInput->GetNEvents(); int countwidth = (fNEvents / 5); // MAIN EVENT LOOP FitEvent* cust_event = fInput->FirstNuisanceEvent(); int i = 0; int npassed = 0; while (cust_event) { cust_event->RWWeight = fRW->CalcWeight(cust_event); cust_event->Weight = cust_event->RWWeight * cust_event->InputWeight; Weight = cust_event->Weight; // Initialize fXVar = -999.9; fYVar = -999.9; fZVar = -999.9; Signal = false; Mode = cust_event->Mode; // Extract Measurement Variables this->FillEventVariables(cust_event); Signal = this->isSignal(cust_event); if (Signal) npassed++; GetBox()->SetX(fXVar); GetBox()->SetY(fYVar); GetBox()->SetZ(fZVar); GetBox()->SetMode(Mode); // GetBox()->fSignal = Signal; // Fill Histogram Values GetBox()->FillBoxFromEvent(cust_event); // this->FillExtraHistograms(GetBox(), Weight); this->FillHistogramsFromBox(GetBox(), Weight); // Print Out if (LOG_LEVEL(REC) && countwidth > 0 && !(i % countwidth)) { std::stringstream ss(""); ss.unsetf(std::ios_base::fixed); ss << std::setw(7) << std::right << i << "/" << fNEvents << " events (" << std::setw(2) << double(i) / double(fNEvents) * 100. << std::left << std::setw(5) << "%) " << "[S,X,Y,Z,M,W] = [" << std::fixed << std::setprecision(2) << std::right << Signal << ", " << std::setw(5) << fXVar << ", " << std::setw(5) << fYVar << ", " << std::setw(5) << fYVar << ", " << std::setw(3) << (int)Mode << ", " << std::setw(5) << Weight << "] " << std::endl; LOG(SAM) << ss.str(); } // iterate cust_event = fInput->NextNuisanceEvent(); i++; } LOG(SAM) << npassed << "/" << fNEvents << " passed selection " << std::endl; if (npassed == 0) { LOG(SAM) << "WARNING: NO EVENTS PASSED SELECTION!" << std::endl; } LOG(REC) << std::setw(10) << std::right << NSignal << "/" << fNEvents << " events passed selection + binning after reweight" << std::endl; // Finalise Histograms fMCFilled = true; this->ConvertEventRates(); } void MeasurementBase::FillHistogramsFromBox(MeasurementVariableBox* var, double weight) { fXVar = var->GetX(); fYVar = var->GetY(); fZVar = var->GetZ(); Weight = weight; fEventVariables = var; FillHistograms(); FillExtraHistograms(var, weight); } void MeasurementBase::FillHistograms(double weight) { Weight = weight * GetBox()->GetSampleWeight(); FillHistograms(); FillExtraHistograms(GetBox(), Weight); } MeasurementVariableBox* MeasurementBase::FillVariableBox(FitEvent* event) { GetBox()->Reset(); Mode = event->Mode; Weight = 1.0; // event->Weight; this->FillEventVariables(event); Signal = this->isSignal(event); GetBox()->FillBoxFromEvent(event); GetBox()->SetX(fXVar); GetBox()->SetY(fYVar); GetBox()->SetZ(fZVar); GetBox()->SetMode(event->Mode); GetBox()->SetSampleWeight(Weight); // GetBox()->fSignal = Signal; return GetBox(); } MeasurementVariableBox* MeasurementBase::GetBox() { if (!fEventVariables) fEventVariables = CreateBox(); return fEventVariables; } //*********************************************** void MeasurementBase::ReconfigureFast() { //*********************************************** this->Reconfigure(); } //*********************************************** void MeasurementBase::ConvertEventRates() { //*********************************************** AutoScaleExtraTH1(); ScaleExtraHistograms(GetBox()); this->ScaleEvents(); double normval = fRW->GetSampleNorm(this->fName); if (normval < 0.01 or normval > 10.0) { ERR(WRN) << "Norm Value inside MeasurementBase::ConvertEventRates() looks off!" << std::endl; ERR(WRN) << "It could have become out of sync with the minimizer norm list." << std::endl; ERR(WRN) << "Setting it to 1.0" << std::endl; normval = 1.0; } AutoNormExtraTH1(normval); NormExtraHistograms(GetBox(), normval); this->ApplyNormScale(normval); } //*********************************************** InputHandlerBase* MeasurementBase::GetInput() { //*********************************************** if (!fInput) { ERR(FTL) << "MeasurementBase::fInput not set. Please submit your command " "line options and input cardfile with a bug report to: " "nuisance@projects.hepforge.org" << std::endl; throw; } return fInput; }; //*********************************************** void MeasurementBase::Renormalise() { //*********************************************** // Called when the fitter has changed a measurements normalisation but not any // reweight dials // Means we don't have to call the time consuming reconfigure when this // happens. double norm = fRW->GetDialValue(this->fName + "_norm"); if ((this->fCurrentNorm == 0.0 and norm != 0.0) or not fMCFilled) { this->ReconfigureFast(); return; } if (this->fCurrentNorm == norm) return; this->ApplyNormScale(1.0 / this->fCurrentNorm); this->ApplyNormScale(norm); return; }; //*********************************************** void MeasurementBase::SetSignal(bool sig) { //*********************************************** Signal = sig; } //*********************************************** void MeasurementBase::SetSignal(FitEvent* evt) { //*********************************************** Signal = this->isSignal(evt); } //*********************************************** void MeasurementBase::SetWeight(double wght) { //*********************************************** Weight = wght; } //*********************************************** void MeasurementBase::SetMode(int md) { //*********************************************** Mode = md; } //*********************************************** std::vector MeasurementBase::GetFluxList() { //*********************************************** return GetInput()->GetFluxList(); } //*********************************************** std::vector MeasurementBase::GetEventRateList() { //*********************************************** return GetInput()->GetEventList(); } //*********************************************** std::vector MeasurementBase::GetXSecList() { //*********************************************** return GetInput()->GetXSecList(); } void MeasurementBase::ProcessExtraHistograms(int cmd, MeasurementVariableBox* vars, double weight) { // This should be overriden if we have extra histograms!!! // Add a flag to tell user this... return; } void MeasurementBase::FillExtraHistograms(MeasurementVariableBox* vars, double weight) { ProcessExtraHistograms(kCMD_Fill, vars, weight); } void MeasurementBase::ScaleExtraHistograms(MeasurementVariableBox* vars) { ProcessExtraHistograms(kCMD_Scale, vars, 1.0); } void MeasurementBase::ResetExtraHistograms() { ProcessExtraHistograms(kCMD_Reset, NULL, 1.0); } void MeasurementBase::NormExtraHistograms(MeasurementVariableBox* vars, double norm) { ProcessExtraHistograms(kCMD_Norm, vars, norm); } void MeasurementBase::WriteExtraHistograms() { ProcessExtraHistograms(kCMD_Write, NULL, 1.00); } void MeasurementBase::SetAutoProcessTH1(TH1* hist, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(hist); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(TH1* hist, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(hist); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(TGraph* g, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(g); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(TF1* f, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(f); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(StackBase* hist, int c1, int c2, int c3, int c4, int c5) { SetAutoProcessTH1(hist, c1, c2, c3, c4, c5); } void MeasurementBase::SetAutoProcessTH1(StackBase* hist, int c1, int c2, int c3, int c4, int c5) { // Set Defaults // int ncommands = kCMD_extraplotflags; - bool autoflags[5]; - autoflags[0] = false; - autoflags[1] = false; - autoflags[2] = false; - autoflags[3] = false; - autoflags[4] = false; - int givenflags[5]; givenflags[0] = c1; givenflags[1] = c2; givenflags[2] = c3; givenflags[3] = c4; givenflags[4] = c5; fExtraTH1s[hist] = std::vector(5, 0); // Setup a default one. if (c1 == -1 && c2 == -1 && c3 == -1 && c4 == -1 && c5 == -1) { fExtraTH1s[hist][kCMD_Reset] = 1; fExtraTH1s[hist][kCMD_Scale] = 1; fExtraTH1s[hist][kCMD_Norm] = 1; fExtraTH1s[hist][kCMD_Write] = 1; } for (int i = 0; i < 5; i++) { switch (givenflags[i]) { // Skip over... case -1: break; case kCMD_Reset: case kCMD_Scale: case kCMD_Norm: case kCMD_Write: fExtraTH1s[hist][givenflags[i]] = 1; break; case kCMD_Fill: ERR(FTL) << "Can't auto fill yet!" << std::endl; - autoflags[givenflags[i]] = 1; break; default: break; } } // LOG(SAM) << "AutoProcessing " << hist->GetName() << std::endl; }; void MeasurementBase::AutoFillExtraTH1() { ERR(FTL) << "Can't auto fill yet! it's too inefficent!" << std::endl; return; } void MeasurementBase::AutoResetExtraTH1() { for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!((*iter).second)[kCMD_Reset]) continue; (*iter).first->Reset(); } }; void MeasurementBase::AutoScaleExtraTH1() { for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!((*iter).second)[kCMD_Scale]) continue; if (fIsNoWidth) { (*iter).first->Scale(fScaleFactor); } else { (*iter).first->Scale(fScaleFactor, "width"); } } }; void MeasurementBase::AutoNormExtraTH1(double norm) { double sfactor = 0.0; if (norm != 0.0) sfactor = 1.0 / norm; for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!((*iter).second)[kCMD_Norm]) continue; (*iter).first->Scale(sfactor); } }; void MeasurementBase::AutoWriteExtraTH1() { for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!(((*iter).second)[kCMD_Write])) continue; (*iter).first->Write(); } }; diff --git a/src/FitBase/MeasurementBase.h b/src/FitBase/MeasurementBase.h index 00dddc7..87eae43 100644 --- a/src/FitBase/MeasurementBase.h +++ b/src/FitBase/MeasurementBase.h @@ -1,362 +1,366 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef INPUTHANDLER_H_SEEN #define INPUTHANDLER_H_SEEN /*! * \addtogroup FitBase * @{ */ // C Includes #include #include #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include #include // External data fit includes #include "FitEvent.h" #include "FitUtils.h" #include "GeneralUtils.h" #include "PlotUtils.h" #include "StatUtils.h" #include "InputFactory.h" #include "FitWeight.h" #include "TMultiDimFit.h" #ifdef __GENIE_ENABLED__ +#ifdef GENIE_PRE_R3 #include "Conventions/Units.h" +#else +#include "Framework/Conventions/Units.h" +#endif #endif #include "EventManager.h" #include "TObject.h" #include "InputHandler.h" #include "NuisConfig.h" #include "NuisKey.h" #include "SampleSettings.h" #include "StackBase.h" #include "StandardStacks.h" /// Enumerations to help with extra plot functions enum extraplotflags { kCMD_Reset = 0, kCMD_Fill, kCMD_Scale, kCMD_Norm, kCMD_Write, kCMD_Error, kCMD_extraplotflags }; enum MeasurementSpeciesClass { kSingleSpeciesMeasurement = 0, kNumuWithWrongSignMeasurement, kNueWithWrongSignMeasurement, kFourSpeciesMeasurement, }; /// InputHandler Class /// /// Inherits from Measurement base to handle whatever input is throwna t the /// fitter automatically. /// All functions here handle how files are read in, converted to custom formats /// and reconfigures are called. /// Used generally for the MC inputs. //! 2nd level experiment class that handles converting MC into a common format //! and calling reconfigure class MeasurementBase { public: /* Constructor/Destructors */ //! Default Constructor. Set everything to NULL MeasurementBase(); //! Default virtual destructor virtual ~MeasurementBase(void); virtual void InitialSetup(void) {}; /* Reconfigure Functions */ //! Function called if MC tuning dials haven't been changed and all we want to //! do is update the normalisation. virtual void Renormalise(void); //! Call reconfigure only looping over signal events to save time. virtual void ReconfigureFast(void); virtual void FillHistograms(double weight); //! Call reconfigure looping over all MC events including background virtual void Reconfigure(void); // virtual TH2D GetCovarMatrix(void) = 0; virtual double GetLikelihood(void) { return 0.0; }; virtual int GetNDOF(void) { return 0; }; virtual void ThrowCovariance(void) = 0; virtual void ThrowDataToy(void) = 0; virtual void SetFakeDataValues(std::string fkdt) = 0; //! Get the total integrated flux between this samples energy range virtual double TotalIntegratedFlux(std::string intOpt = "width", double low = -9999.9, double high = -9999.9); //! Get the predicted event rate for this sample virtual double PredictedEventRate(std::string intOpt = "width", double low = -9999.9, double high = -9999.9); virtual SampleSettings LoadSampleSettings(nuiskey samplekey); virtual SampleSettings LoadSampleSettings(std::string name, std::string input, std::string type); virtual void FinaliseSampleSettings(); virtual void FinaliseMeasurement(); virtual void ProcessExtraHistograms(int cmd, MeasurementVariableBox* vars, double weight = 1.0); virtual void FillExtraHistograms(MeasurementVariableBox* vars, double weight = 1.0); virtual void ScaleExtraHistograms(MeasurementVariableBox* vars); virtual void ResetExtraHistograms(); virtual void NormExtraHistograms(MeasurementVariableBox* vars, double norm = 1.0); virtual void WriteExtraHistograms(); virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox();}; int GetPassed() { int signalSize = 0; return signalSize; } int GetTotal() { return fNEvents; } /* Reconfigure LOOP */ // All these should be virtual ///! Reset Histograms (Handled at Measurement Stage) virtual void ResetAll(void) = 0; ///! Fill the event variables for this sample (Handled in each inherited /// sample) virtual void FillEventVariables(FitEvent* event) { (void)event; }; ///! Check whether this event is signle (Handled in each inherited sample) virtual bool isSignal(FitEvent* event) { (void)event; return false; }; ///! Fill the histogram for this event using fXVar and fYVar (Handled in each /// inherited sample) virtual void FillHistograms(void) {}; ///! Convert event rates to whatever distributions you need. virtual void ConvertEventRates(void); ///! Call scale events after the plots have been filled at the end of /// reconfigure. virtual void ScaleEvents(void) {}; ///! Apply the scale factor at the end of reconfigure. virtual void ApplyNormScale(double norm) { (void)norm; }; ///! Save Histograms virtual void Write(std::string drawOpt = "") = 0; virtual MeasurementVariableBox* FillVariableBox(FitEvent* event); virtual MeasurementVariableBox* GetBox(); void FillHistogramsFromBox(MeasurementVariableBox* var, double weight); /* Histogram Access Functions */ ///! Virtual function to get data histogram virtual std::vector GetDataList(void) = 0; ///! Virtual function to get MC histogram virtual std::vector GetMCList(void) = 0; virtual std::vector GetFineList(void) = 0; virtual std::vector GetMaskList(void) = 0; ///! Return flux histograms in a vector virtual std::vector GetFluxList(void); virtual std::vector GetEventRateList(void); virtual std::vector GetXSecList(void); virtual TH1D* GetEventHistogram() { return fInput->GetEventHistogram(); }; virtual TH1D* GetXSecHistogram() { return fInput->GetXSecHistogram(); }; virtual TH1D* GetFluxHistogram() { return fInput->GetFluxHistogram(); }; ///! Return input for this sample InputHandlerBase* GetInput(void); std::string GetName(void) { return fName; }; double GetScaleFactor(void) { return fScaleFactor; }; double GetXVar(void) { return fXVar; }; double GetYVar(void) { return fYVar; }; double GetZVar(void) { return fZVar; }; double GetMode(void) { return this->Mode; }; double GetEnu(void) { return this->Enu; }; void SetupInputs(std::string inputfile); int GetInputID(void); std::string GetInputFileName() { return fInputFileName; }; void SetSignal(bool sig); void SetSignal(FitEvent* evt); void SetWeight(double wght); void SetMode(int md); void SetNoData(bool isTrue = true) { fNoData = isTrue; }; inline void SetXVar(double xvar) { fXVar = xvar; }; inline void SetYVar(double yvar) { fYVar = yvar; }; inline void SetZVar(double zvar) { fZVar = zvar; }; virtual std::vector GetSubSamples() { return std::vector(1, this); } void SetAutoProcessTH1(TH1* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(TH1* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(TGraph* g, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(TF1* f, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(StackBase* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcessTH1(StackBase* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void AutoFillExtraTH1(); void AutoResetExtraTH1(); void AutoScaleExtraTH1(); void AutoNormExtraTH1(double norm); void AutoWriteExtraTH1(); // functions that need to be added. // - Initial Check // - Check Target/Beam loop. // - Check flux shape if suggested one given. // - Return MeasurementList (returns ) protected: // Minimum and maximum energies double Enu; //!< Neutrino Energy double EnuMin; //!< Minimum incoming particle energy of events to include double EnuMax; //!< Maximum incoming particle energy of events to include BaseFitEvt* signal_event; FitEvent* cust_event; FitWeight* fRW; //!< Pointer to the rw engine InputHandlerBase* fInput; //!< Instance of the input handler std::string fName; //!< Name of the sample int fEventType; double fBeamDistance; //!< Incoming Particle flight distance (for oscillation //! analysis) double fScaleFactor; //!< fScaleFactor applied to events to convert from //! eventrate to final distribution double fCurrentNorm; //!< current normalisation factor applied if fit is "FREE" bool fMCFilled; //!< flag whether MC plots have been filled (For //! ApplyNormalisation) bool fNoData; //!< flag whether data plots do not exist (for ratios) bool fIsNoWidth; ///< Flag : Don't scale by bin width // TEMP OBJECTS TO HANDLE MERGE double fXVar, fYVar, fZVar, Mode, Weight; bool Signal; int ievt; int fNEvents; double Enu_rec, ThetaMu, CosThetaMu; InputUtils::InputType fInputType; std::string fInputFileName; TH1D* fFluxHist; TH1D* fEventHist; MeasurementSpeciesClass fMeasurementSpeciesType; SampleSettings fSettings; MeasurementVariableBox* fEventVariables; std::map > fExtraTH1s; int NSignal; // std::map fExtaStacks; bool fIsJoint; double fNPOT, fFluxIntegralOverride, fTargetVolume, fTargetMaterialDensity; double fEvtRateScaleFactor; }; // Class TypeDefs typedef std::list::const_iterator MeasListConstIter; typedef std::list::iterator MeasListIter; typedef std::vector::const_iterator MeasVectConstIter; typedef std::vector::iterator MeasVectIter; /*! @} */ #endif diff --git a/src/InputHandler/BaseFitEvt.h b/src/InputHandler/BaseFitEvt.h index 84316aa..84e3d88 100644 --- a/src/InputHandler/BaseFitEvt.h +++ b/src/InputHandler/BaseFitEvt.h @@ -1,141 +1,147 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef FITEVENTBASE_H_SEEN #define FITEVENTBASE_H_SEEN /*! * \addtogroup InputHandler * @{ */ #ifdef __NEUT_ENABLED__ #include "neutpart.h" #include "neutvect.h" #endif #ifdef __NUWRO_ENABLED__ #ifdef __USE_NUWRO_SRW_EVENTS__ #include "NuwroReWeightSimpleEvent.h" #else #include "event1.h" #endif #endif #ifdef __GENIE_ENABLED__ +#ifdef GENIE_PRE_R3 #include "EVGCore/EventRecord.h" #include "GHEP/GHepRecord.h" #include "Ntuple/NtpMCEventRecord.h" +#else +#include "Framework/EventGen/EventRecord.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/Ntuple/NtpMCEventRecord.h" +#endif using namespace genie; #endif #ifdef __NUANCE_ENABLED__ #include "NuanceEvent.h" #endif #include "StdHepEvt.h" #include "SplineReader.h" #include "InputTypes.h" #include "GeneratorInfoBase.h" /// Base Event Class used to store just the generator event pointers class BaseFitEvt { public: /// Base Constructor BaseFitEvt(void); ~BaseFitEvt(); /// Copy base fit event pointers BaseFitEvt(const BaseFitEvt* obj); BaseFitEvt(BaseFitEvt const &); BaseFitEvt operator=(BaseFitEvt const &); /// Reset weight to 1.0 void ResetWeight(); /// Return combined weight for this event double GetWeight(); /// Manually set event type inline void SetType(int type){fType = type;}; // Global Event Variables/Weights int Mode; ///< True interaction mode double probe_E; ///< True probe energy double probe_pdg; // Weighting Info double Weight; ///< Total Weight For Event double InputWeight; ///< Input Starting Weight (used for GiBUU) double RWWeight; ///< Saved RW from FitWeight double CustomWeight; ///< Extra custom weight that samples can set double SavedRWWeight; ///< Saved RW value for FitEvents double CustomWeightArray[6]; ///< For custom tuning using arrays, e.g. NOvA MINERvA WS // Spline Info Coefficients and Readers float* fSplineCoeff; ///< ND Array of Spline Coefficients SplineReader* fSplineRead; ///< Spline Interpretter // Generator Info GeneratorInfoBase* fGenInfo; ///< Generator Variable Box UInt_t fType; ///< Generator Event Type #ifdef __NEUT_ENABLED__ /// Setup Event Reading from NEUT Event void SetNeutVect(NeutVect* v); NeutVect* fNeutVect; ///< Pointer to Neut Vector #endif #ifdef __NUWRO_ENABLED__ #ifdef __USE_NUWRO_SRW_EVENTS__ SRW::SRWEvent fNuwroSRWEvent; ///< Pointer to Nuwro event params * fNuwroParams; #endif event* fNuwroEvent; ///< Pointer to Nuwro event #endif #ifdef __GENIE_ENABLED__ /// Setup Event Reading from GENIE Event void SetGenieEvent(NtpMCEventRecord* ntpl); NtpMCEventRecord* genie_event; ///< Pointer to NTuple Genie Event GHepRecord* genie_record; ///< Pointer to actually accessible Genie Record #endif #ifdef __NUANCE_ENABLED__ /// Setup Event Reading from NUANCE Event void SetNuanceEvent(NuanceEvent* e); NuanceEvent* nuance_event; ///< Pointer to Nuance reader #endif #ifdef __GiBUU_ENABLED__ GiBUUStdHepReader* GiRead; ///< Pointer to GiBUU reader #endif /// Setup Event Type to FitEvent void SetInputFitEvent(); /// Setup Event Type to FitSpline void SetInputFitSpline(); /// Setup Event Type to HepMC void SetInputHepMC(); }; /*! @} */ #endif diff --git a/src/InputHandler/GENIEInputHandler.cxx b/src/InputHandler/GENIEInputHandler.cxx index a5eb414..600d076 100644 --- a/src/InputHandler/GENIEInputHandler.cxx +++ b/src/InputHandler/GENIEInputHandler.cxx @@ -1,503 +1,523 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifdef __GENIE_ENABLED__ #include "GENIEInputHandler.h" +#pragma push_macro("LOG") +#undef LOG +#pragma push_macro("ERROR") +#undef ERROR +#ifdef GENIE_PRE_R3 +#include "Messenger/Messenger.h" +#else +#include "Framework/Messenger/Messenger.h" +#endif +#pragma pop_macro("LOG") +#pragma pop_macro("ERROR") + + #include "InputUtils.h" GENIEGeneratorInfo::~GENIEGeneratorInfo() { DeallocateParticleStack(); } void GENIEGeneratorInfo::AddBranchesToTree(TTree* tn) { tn->Branch("GenieParticlePDGs", &fGenieParticlePDGs, "GenieParticlePDGs/I"); } void GENIEGeneratorInfo::SetBranchesFromTree(TTree* tn) { tn->SetBranchAddress("GenieParticlePDGs", &fGenieParticlePDGs); } void GENIEGeneratorInfo::AllocateParticleStack(int stacksize) { fGenieParticlePDGs = new int[stacksize]; } void GENIEGeneratorInfo::DeallocateParticleStack() { delete fGenieParticlePDGs; } void GENIEGeneratorInfo::FillGeneratorInfo(NtpMCEventRecord* ntpl) { Reset(); // Check for GENIE Event if (!ntpl) return; if (!ntpl->event) return; // Cast Event Record GHepRecord* ghep = static_cast(ntpl->event); if (!ghep) return; // Fill Particle Stack GHepParticle* p = 0; TObjArrayIter iter(ghep); // Loop over all particles int i = 0; while ((p = (dynamic_cast((iter).Next())))) { if (!p) continue; // Get PDG fGenieParticlePDGs[i] = p->Pdg(); i++; } } void GENIEGeneratorInfo::Reset() { for (int i = 0; i < kMaxParticles; i++) { fGenieParticlePDGs[i] = 0; } } GENIEInputHandler::GENIEInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating GENIEInputHandler : " << handle << std::endl; + genie::Messenger::Instance()->SetPriorityLevel("GHepUtils", pFATAL); + // Run a joint input handling fName = handle; // Setup the TChain fGENIETree = new TChain("gtree"); fSaveExtra = FitPar::Config().GetParB("SaveExtraGenie"); fCacheSize = FitPar::Config().GetParI("CacheSize"); fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); // Are we running with NOvA weights fNOvAWeights = FitPar::Config().GetParB("NOvA_Weights"); MAQEw = 1.0; NonResw = 1.0; RPAQEw = 1.0; RPARESw = 1.0; MECw = 1.0; DISw = 1.0; NOVAw = 1.0; // Loop over all inputs and grab flux, eventhist, and nevents std::vector inputs = InputUtils::ParseInputFileList(rawinputs); for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { // Open File for histogram access TFile* inp_file = new TFile( InputUtils::ExpandInputDirectories(inputs[inp_it]).c_str(), "READ"); if (!inp_file or inp_file->IsZombie()) { THROW("GENIE File IsZombie() at : '" << inputs[inp_it] << "'" << std::endl << "Check that your file paths are correct and the file exists!" << std::endl << "$ ls -lh " << inputs[inp_it]); } // Get Flux/Event hist TH1D* fluxhist = (TH1D*)inp_file->Get("nuisance_flux"); TH1D* eventhist = (TH1D*)inp_file->Get("nuisance_events"); if (!fluxhist or !eventhist) { ERROR(FTL, "Input File Contents: " << inputs[inp_it]); inp_file->ls(); THROW("GENIE FILE doesn't contain flux/xsec info." << std::endl << "Try running the app PrepareGENIE first on :" << inputs[inp_it] << std::endl << "$ PrepareGENIE -h"); } // Get N Events TTree* genietree = (TTree*)inp_file->Get("gtree"); if (!genietree) { ERROR(FTL, "gtree not located in GENIE file: " << inputs[inp_it]); THROW("Check your inputs, they may need to be completely regenerated!"); throw; } - + int nevents = genietree->GetEntries(); if (nevents <= 0) { THROW("Trying to a TTree with " << nevents << " to TChain from : " << inputs[inp_it]); } // Check for precomputed weights TTree *weighttree = (TTree*)inp_file->Get("nova_wgts"); if (fNOvAWeights) { if (!weighttree) { THROW("Did not find nova_wgts tree in file " << inputs[inp_it] << " but you specified it" << std::endl); } else { LOG(FIT) << "Found nova_wgts tree in file " << inputs[inp_it] << std::endl; } } // Register input to form flux/event rate hists RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); // Add To TChain fGENIETree->AddFile(inputs[inp_it].c_str()); if (weighttree != NULL) fGENIETree->AddFriend(weighttree); } // Registor all our file inputs SetupJointInputs(); // Assign to tree fEventType = kGENIE; fGenieNtpl = NULL; fGENIETree->SetBranchAddress("gmcrec", &fGenieNtpl); // Set up the custom weights if (fNOvAWeights) { fGENIETree->SetBranchAddress("MAQEwgt", &MAQEw); fGENIETree->SetBranchAddress("nonResNormWgt", &NonResw); fGENIETree->SetBranchAddress("RPAQEWgt", &RPAQEw); fGENIETree->SetBranchAddress("RPARESWgt", &RPARESw); fGENIETree->SetBranchAddress("MECWgt", &MECw); fGENIETree->SetBranchAddress("DISWgt", &DISw); fGENIETree->SetBranchAddress("nova2018CVWgt", &NOVAw); } // Libraries should be seen but not heard... StopTalking(); fGENIETree->GetEntry(0); StartTalking(); // Create Fit Event fNUISANCEEvent = new FitEvent(); fNUISANCEEvent->SetGenieEvent(fGenieNtpl); if (fSaveExtra) { fGenieInfo = new GENIEGeneratorInfo(); fNUISANCEEvent->AddGeneratorInfo(fGenieInfo); } fNUISANCEEvent->HardReset(); }; GENIEInputHandler::~GENIEInputHandler() { // if (fGenieGHep) delete fGenieGHep; // if (fGenieNtpl) delete fGenieNtpl; // if (fGENIETree) delete fGENIETree; // if (fGenieInfo) delete fGenieInfo; } void GENIEInputHandler::CreateCache() { if (fCacheSize > 0) { // fGENIETree->SetCacheEntryRange(0, fNEvents); fGENIETree->AddBranchToCache("*", 1); fGENIETree->SetCacheSize(fCacheSize); } } void GENIEInputHandler::RemoveCache() { // fGENIETree->SetCacheEntryRange(0, fNEvents); fGENIETree->AddBranchToCache("*", 0); fGENIETree->SetCacheSize(0); } FitEvent* GENIEInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { if (entry >= (UInt_t)fNEvents) return NULL; + // Clear the previous event (See Note 1 in ROOT TClonesArray documentation) + if (fGenieNtpl) { + fGenieNtpl->Clear(); + } + // Read Entry from TTree to fill NEUT Vect in BaseFitEvt; fGENIETree->GetEntry(entry); // Run NUISANCE Vector Filler if (!lightweight) { CalcNUISANCEKinematics(); } #ifdef __PROB3PP_ENABLED__ else { // Check for GENIE Event if (!fGenieNtpl) return NULL; if (!fGenieNtpl->event) return NULL; // Cast Event Record fGenieGHep = static_cast(fGenieNtpl->event); if (!fGenieGHep) return NULL; TObjArrayIter iter(fGenieGHep); genie::GHepParticle* p; while ((p = (dynamic_cast((iter).Next())))) { if (!p) { continue; } // Get Status int state = GetGENIEParticleStatus(p, fNUISANCEEvent->Mode); if (state != genie::kIStInitialState) { continue; } fNUISANCEEvent->probe_E = p->E() * 1.E3; fNUISANCEEvent->probe_pdg = p->Pdg(); break; } } #endif // Setup Input scaling for joint inputs fNUISANCEEvent->InputWeight = GetInputWeight(entry); return fNUISANCEEvent; } int GENIEInputHandler::GetGENIEParticleStatus(genie::GHepParticle* p, int mode) { /* kIStUndefined = -1, kIStInitialState = 0, / generator-level initial state / kIStStableFinalState = 1, / generator-level final state: particles to be tracked by detector-level MC / kIStIntermediateState = 2, kIStDecayedState = 3, kIStCorrelatedNucleon = 10, kIStNucleonTarget = 11, kIStDISPreFragmHadronicState = 12, kIStPreDecayResonantState = 13, kIStHadronInTheNucleus = 14, / hadrons inside the nucleus: marked for hadron transport modules to act on / kIStFinalStateNuclearRemnant = 15, / low energy nuclear fragments entering the record collectively as a 'hadronic blob' pseudo-particle / kIStNucleonClusterTarget = 16, // for composite nucleons before phase space decay */ int state = kUndefinedState; switch (p->Status()) { case genie::kIStNucleonTarget: case genie::kIStInitialState: case genie::kIStCorrelatedNucleon: case genie::kIStNucleonClusterTarget: state = kInitialState; break; case genie::kIStStableFinalState: state = kFinalState; break; case genie::kIStHadronInTheNucleus: if (abs(mode) == 2) state = kInitialState; else state = kFSIState; break; case genie::kIStPreDecayResonantState: case genie::kIStDISPreFragmHadronicState: case genie::kIStIntermediateState: state = kFSIState; break; case genie::kIStFinalStateNuclearRemnant: case genie::kIStUndefined: case genie::kIStDecayedState: default: break; } // Flag to remove nuclear part in genie if (p->Pdg() > 1000000) { if (state == kInitialState) state = kNuclearInitial; else if (state == kFinalState) state = kNuclearRemnant; } return state; } #endif #ifdef __GENIE_ENABLED__ int GENIEInputHandler::ConvertGENIEReactionCode(GHepRecord* gheprec) { // Electron Scattering if (gheprec->Summary()->ProcInfo().IsEM()) { if (gheprec->Summary()->InitState().ProbePdg() == 11) { if (gheprec->Summary()->ProcInfo().IsQuasiElastic()) return 1; else if (gheprec->Summary()->ProcInfo().IsMEC()) return 2; else if (gheprec->Summary()->ProcInfo().IsResonant()) return 13; else if (gheprec->Summary()->ProcInfo().IsDeepInelastic()) return 26; else { ERROR(WRN, "Unknown GENIE Electron Scattering Mode!" << std::endl << "ScatteringTypeId = " << gheprec->Summary()->ProcInfo().ScatteringTypeId() << " " << "InteractionTypeId = " << gheprec->Summary()->ProcInfo().InteractionTypeId() << std::endl << genie::ScatteringType::AsString( gheprec->Summary()->ProcInfo().ScatteringTypeId()) << " " << genie::InteractionType::AsString( gheprec->Summary()->ProcInfo().InteractionTypeId()) << " " << gheprec->Summary()->ProcInfo().IsMEC()); return 0; } } // Weak CC } else if (gheprec->Summary()->ProcInfo().IsWeakCC()) { // CC MEC if (gheprec->Summary()->ProcInfo().IsMEC()) { if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) return 2; else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg())) return -2; // CC OTHER } else { return utils::ghep::NeutReactionCode(gheprec); } // Weak NC } else if (gheprec->Summary()->ProcInfo().IsWeakNC()) { // NC MEC if (gheprec->Summary()->ProcInfo().IsMEC()) { if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) return 32; else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg())) return -32; // NC OTHER } else { return utils::ghep::NeutReactionCode(gheprec); } } return 0; } void GENIEInputHandler::CalcNUISANCEKinematics() { // Reset all variables fNUISANCEEvent->ResetEvent(); // Check for GENIE Event if (!fGenieNtpl) return; if (!fGenieNtpl->event) return; // Cast Event Record fGenieGHep = static_cast(fGenieNtpl->event); if (!fGenieGHep) return; // Convert GENIE Reaction Code fNUISANCEEvent->Mode = ConvertGENIEReactionCode(fGenieGHep); // Set Event Info fNUISANCEEvent->fEventNo = 0.0; fNUISANCEEvent->fTotCrs = fGenieGHep->XSec(); fNUISANCEEvent->fTargetA = 0.0; fNUISANCEEvent->fTargetZ = 0.0; fNUISANCEEvent->fTargetH = 0; fNUISANCEEvent->fBound = 0.0; fNUISANCEEvent->InputWeight = 1.0; //(1E+38 / genie::units::cm2) * fGenieGHep->XSec(); // And the custom weights if (fNOvAWeights) { fNUISANCEEvent->CustomWeight = NOVAw; fNUISANCEEvent->CustomWeightArray[0] = MAQEw; fNUISANCEEvent->CustomWeightArray[1] = NonResw; fNUISANCEEvent->CustomWeightArray[2] = RPAQEw; fNUISANCEEvent->CustomWeightArray[3] = RPARESw; fNUISANCEEvent->CustomWeightArray[4] = MECw; fNUISANCEEvent->CustomWeightArray[5] = NOVAw; } else { fNUISANCEEvent->CustomWeight = 1.0; fNUISANCEEvent->CustomWeightArray[0] = 1.0; fNUISANCEEvent->CustomWeightArray[1] = 1.0; fNUISANCEEvent->CustomWeightArray[2] = 1.0; fNUISANCEEvent->CustomWeightArray[3] = 1.0; fNUISANCEEvent->CustomWeightArray[4] = 1.0; fNUISANCEEvent->CustomWeightArray[5] = 1.0; } // Get N Particle Stack unsigned int npart = fGenieGHep->GetEntries(); unsigned int kmax = fNUISANCEEvent->kMaxParticles; if (npart > kmax) { ERR(WRN) << "GENIE has too many particles, expanding stack." << std::endl; fNUISANCEEvent->ExpandParticleStack(npart); } // Fill Particle Stack GHepParticle* p = 0; TObjArrayIter iter(fGenieGHep); fNUISANCEEvent->fNParticles = 0; // Loop over all particles while ((p = (dynamic_cast((iter).Next())))) { if (!p) continue; // Get Status int state = GetGENIEParticleStatus(p, fNUISANCEEvent->Mode); // Remove Undefined if (kRemoveUndefParticles && state == kUndefinedState) continue; // Remove FSI if (kRemoveFSIParticles && state == kFSIState) continue; if (kRemoveNuclearParticles && (state == kNuclearInitial || state == kNuclearRemnant)) continue; // Fill Vectors int curpart = fNUISANCEEvent->fNParticles; fNUISANCEEvent->fParticleState[curpart] = state; // Mom fNUISANCEEvent->fParticleMom[curpart][0] = p->Px() * 1.E3; fNUISANCEEvent->fParticleMom[curpart][1] = p->Py() * 1.E3; fNUISANCEEvent->fParticleMom[curpart][2] = p->Pz() * 1.E3; fNUISANCEEvent->fParticleMom[curpart][3] = p->E() * 1.E3; // PDG fNUISANCEEvent->fParticlePDG[curpart] = p->Pdg(); // Add to N particle count fNUISANCEEvent->fNParticles++; // Extra Check incase GENIE fails. if ((UInt_t)fNUISANCEEvent->fNParticles == kmax) { ERR(WRN) << "Number of GENIE Particles exceeds maximum!" << std::endl; ERR(WRN) << "Extend kMax, or run without including FSI particles!" << std::endl; break; } } // Fill Extra Stack if (fSaveExtra) fGenieInfo->FillGeneratorInfo(fGenieNtpl); // Run Initial, FSI, Final, Other ordering. fNUISANCEEvent->OrderStack(); FitParticle* ISNeutralLepton = fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos); if (ISNeutralLepton) { fNUISANCEEvent->probe_E = ISNeutralLepton->E(); fNUISANCEEvent->probe_pdg = ISNeutralLepton->PDG(); } return; } void GENIEInputHandler::Print() {} #endif diff --git a/src/InputHandler/GENIEInputHandler.h b/src/InputHandler/GENIEInputHandler.h index d2a1d18..16a7092 100644 --- a/src/InputHandler/GENIEInputHandler.h +++ b/src/InputHandler/GENIEInputHandler.h @@ -1,119 +1,130 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef GENIEINPUTHANDLER_H #define GENIEINPUTHANDLER_H /*! * \addtogroup InputHandler * @{ */ #ifdef __GENIE_ENABLED__ #include "InputHandler.h" #include "InputUtils.h" #include "PlotUtils.h" +#ifdef GENIE_PRE_R3 #include "GHEP/GHepParticle.h" #include "PDG/PDGUtils.h" #include "GHEP/GHepUtils.h" #include "Conventions/Units.h" #include "EVGCore/EventRecord.h" #include "GHEP/GHepRecord.h" #include "Ntuple/NtpMCEventRecord.h" +#else +#include "Framework/GHEP/GHepParticle.h" +#include "Framework/ParticleData/PDGUtils.h" +#include "Framework/GHEP/GHepUtils.h" +#include "Framework/Conventions/Units.h" +#include "Framework/EventGen/EventRecord.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/Ntuple/NtpMCEventRecord.h" +#endif + using namespace genie; /// GENIE Generator Container to save extra particle status codes. class GENIEGeneratorInfo : public GeneratorInfoBase { public: GENIEGeneratorInfo() {}; virtual ~GENIEGeneratorInfo(); /// Assigns information to branches void AddBranchesToTree(TTree* tn); /// Setup reading information from branches void SetBranchesFromTree(TTree* tn); /// Allocate any dynamic arrays for a new particle stack size void AllocateParticleStack(int stacksize); /// Clear any dynamic arrays void DeallocateParticleStack(); /// Read extra genie information from the event void FillGeneratorInfo(NtpMCEventRecord* ntpl); /// Reset extra information to default/empty values void Reset(); int kMaxParticles; ///< Number of particles in stack int* fGenieParticlePDGs; ///< GENIE Particle PDGs (example) }; /// Main GENIE InputHandler class GENIEInputHandler : public InputHandlerBase { public: /// Standard constructor given a name and input files GENIEInputHandler(std::string const& handle, std::string const& rawinputs); virtual ~GENIEInputHandler(); /// Create a TTree Cache to speed up file read void CreateCache(); /// Remove TTree Cache to save memory void RemoveCache(); /// Returns a NUISANCE format event from the GENIE TTree. If !lightweight /// then CalcNUISANCEKinematics() is called to convert the GENIE event into /// a standard NUISANCE format. FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false); /// Converts GENIE event into standard NUISANCE FitEvent by looping over all /// particles in the event and adding them to stack in fNUISANCEEvent. void CalcNUISANCEKinematics(); /// Placeholder for GENIE related event printing. void Print(); /// Converts GENIE particle status codes into NUISANCE status codes. int GetGENIEParticleStatus(genie::GHepParticle* part, int mode = 0); /// Converts GENIE event reaction codes into NUISANCE reaction codes. int ConvertGENIEReactionCode(GHepRecord* gheprec); GHepRecord* fGenieGHep; ///< Pointer to actual event record NtpMCEventRecord* fGenieNtpl; ///< Ntpl Wrapper Class TChain* fGENIETree; ///< Main GENIE Event TTree bool fSaveExtra; ///< Flag to save Extra GENIE info into Nuisance Event GENIEGeneratorInfo* fGenieInfo; ///< Extra GENIE Generator Info Writer bool fNOvAWeights; ///< Flag to save nova weights or not // Extra weights from Jeremy for NOvA weights double MAQEw; double NonResw; double RPAQEw; double RPARESw; double MECw; double DISw; double NOVAw; }; /*! @} */ #endif #endif diff --git a/src/MINERvA/MINERvA_CC0pi_XSec_2D_nu.cxx b/src/MINERvA/MINERvA_CC0pi_XSec_2D_nu.cxx index ef98c0b..8b5e505 100755 --- a/src/MINERvA/MINERvA_CC0pi_XSec_2D_nu.cxx +++ b/src/MINERvA/MINERvA_CC0pi_XSec_2D_nu.cxx @@ -1,241 +1,239 @@ //Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ /* Authors: Adrian Orea (v1 2017) Clarence Wret (v2 2018) */ #include "MINERvA_SignalDef.h" #include "MINERvA_CC0pi_XSec_2D_nu.h" //******************************************************************** void MINERvA_CC0pi_XSec_2D_nu::SetupDataSettings() { //******************************************************************** // Set Distribution // See header file for enum and some descriptions std::string name = fSettings.GetS("name"); // Have two distributions as of summer 2018 if (!name.compare("MINERvA_CC0pi_XSec_2Dptpz_nu")) fDist = kPtPz; // Define what files to use from the dist std::string datafile = ""; std::string corrfile = ""; std::string titles = ""; std::string distdescript = ""; std::string histname = ""; switch (fDist) { case (kPtPz): datafile = "MINERvA/CC0pi_2D/cov_ptpl_2D_qelike.root"; corrfile = "MINERvA/CC0pi_2D/cov_ptpl_2D_qelike.root"; titles = "MINERvA CC0#pi #nu_{#mu} p_{t} p_{z};p_{z} (GeV);p_{t} (GeV);d^{2}#sigma/dP_{t}dP_{z} (cm^{2}/GeV^{2}/nucleon)"; distdescript = "MINERvA_CC0pi_XSec_2Dptpz_nu sample"; histname = "pt_pl_cross_section"; break; default: THROW("Unknown Analysis Distribution : " << fDist); } fSettings.SetTitle( GeneralUtils::ParseToStr(titles,";")[0] ); fSettings.SetXTitle( GeneralUtils::ParseToStr(titles,";")[1] ); fSettings.SetYTitle( GeneralUtils::ParseToStr(titles,";")[2] ); fSettings.SetYTitle( GeneralUtils::ParseToStr(titles,";")[3] ); // Sample overview --------------------------------------------------- std::string descrip = distdescript + "\n"\ "Target: CH \n" \ "Flux: MINERvA Low Energy FHC numu \n" \ "Signal: CC-0pi \n"; fSettings.SetDescription(descrip); // The input ROOT file fSettings.SetDataInput( FitPar::GetDataBase() + datafile); fSettings.SetCovarInput( FitPar::GetDataBase() + corrfile); // Set the data file SetDataValues(fSettings.GetDataInput(), histname); } //******************************************************************** MINERvA_CC0pi_XSec_2D_nu::MINERvA_CC0pi_XSec_2D_nu(nuiskey samplekey) { //******************************************************************** // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); SetupDataSettings(); FinaliseSampleSettings(); fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); TMatrixDSym* tempmat = StatUtils::GetCovarFromRootFile(fSettings.GetCovarInput(), "TotalCovariance"); fFullCovar = tempmat; // Decomposition is stable for entries that aren't E-xxx double ScalingFactor = 1E38*1E38; (*fFullCovar) *= ScalingFactor; // Just check that the data error and covariance are the same for (int i = 0; i < fFullCovar->GetNrows(); ++i) { for (int j = 0; j < fFullCovar->GetNcols(); ++j) { // Get the global bin int xbin1, ybin1, zbin1; fDataHist->GetBinXYZ(i, xbin1, ybin1, zbin1); double xlo1 = fDataHist->GetXaxis()->GetBinLowEdge(xbin1); double xhi1 = fDataHist->GetXaxis()->GetBinLowEdge(xbin1+1); double ylo1 = fDataHist->GetYaxis()->GetBinLowEdge(ybin1); double yhi1 = fDataHist->GetYaxis()->GetBinLowEdge(ybin1+1); if (xlo1 < fDataHist->GetXaxis()->GetBinLowEdge(1) || ylo1 < fDataHist->GetYaxis()->GetBinLowEdge(1) || xhi1 > fDataHist->GetXaxis()->GetBinLowEdge(fDataHist->GetXaxis()->GetNbins()+1) || yhi1 > fDataHist->GetYaxis()->GetBinLowEdge(fDataHist->GetYaxis()->GetNbins()+1)) continue; double data_error = fDataHist->GetBinError(xbin1, ybin1); double cov_error = sqrt((*fFullCovar)(i,i)/ScalingFactor); if (fabs(data_error - cov_error) > 1E-5) { std::cerr << "Error on data is different to that of covariance" << std::endl; ERR(FTL) << "Data error: " << data_error << std::endl; ERR(FTL) << "Cov error: " << cov_error << std::endl; ERR(FTL) << "Data/Cov: " << data_error/cov_error << std::endl; ERR(FTL) << "Data-Cov: " << data_error-cov_error << std::endl; ERR(FTL) << "For x: " << xlo1 << "-" << xhi1 << std::endl; ERR(FTL) << "For y: " << ylo1 << "-" << yhi1 << std::endl; throw; } } } // Now can make the inverted covariance covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); // Now scale back (*fFullCovar) *= 1.0/ScalingFactor; (*covar) *= ScalingFactor; (*fDecomp) *= ScalingFactor; // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** void MINERvA_CC0pi_XSec_2D_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Checking to see if there is a Muon if (event->NumFSParticle(13) == 0) return; // Get the muon kinematics TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; Double_t px = Pmu.X()/1000; Double_t py = Pmu.Y()/1000; Double_t pt = sqrt(px*px+py*py); // y-axis is transverse momentum for both measurements fYVar = pt; // Now we set the x-axis switch (fDist) { case kPtPz: { // Don't want to assume the event generators all have neutrino coming along z // pz is muon momentum projected onto the neutrino direction Double_t pz = Pmu.Vect().Dot(Pnu.Vect()*(1.0/Pnu.Vect().Mag()))/1000.; // Set Hist Variables fXVar = pz; break; } default: THROW("DIST NOT FOUND : " << fDist); break; } }; //******************************************************************** bool MINERvA_CC0pi_XSec_2D_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC0pi_MINERvAPTPZ(event, 14, EnuMin, EnuMax); }; //******************************************************************** // Custom likelihood calculator because binning of covariance matrix double MINERvA_CC0pi_XSec_2D_nu::GetLikelihood() { //******************************************************************** // The calculated chi2 double chi2 = 0.0; // Support shape comparisons double scaleF = fDataHist->Integral() / fMCHist->Integral(); if (fIsShape) { fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); } // Even though this chi2 calculation looks ugly it is _EXACTLY_ what MINERvA used for their measurement // Can be prettified in due time but for now keep - bool chi2_use_overflow_err = false; - //const int lowBin = chi2_use_overflow_err?0:1; // Either they both use underflow, or neither of them does int nbinsx=fMCHist->GetNbinsX(); int nbinsy=fMCHist->GetNbinsY(); Int_t Nbins = nbinsx*nbinsy; // Loop over the covariance matrix bins for (int i = 0; i < Nbins; ++i) { int xbin = i%nbinsx+1; int ybin = i/nbinsx+1; double datax = fDataHist->GetBinContent(xbin,ybin); double mcx = fMCHist->GetBinContent(xbin,ybin); for (int j = 0; j < Nbins; ++j) { int xbin2 = j%nbinsx+1; int ybin2 = j/nbinsx+1; double datay = fDataHist->GetBinContent(xbin2,ybin2); double mcy = fMCHist->GetBinContent(xbin2,ybin2); double chi2_xy = (datax-mcx)*(*covar)(i,j)*(datay-mcy); chi2 += chi2_xy; } } // Normalisation penalty term if included if (fAddNormPen) { chi2 += (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError); LOG(REC) << "Norm penalty = " << (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError) << std::endl; } // Adjust the shape back to where it was. if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = chi2; return chi2; }; diff --git a/src/MiniBooNE/MiniBooNE_NCEL_XSec_Treco_nu.cxx b/src/MiniBooNE/MiniBooNE_NCEL_XSec_Treco_nu.cxx index e46ae68..5dd7b87 100644 --- a/src/MiniBooNE/MiniBooNE_NCEL_XSec_Treco_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_NCEL_XSec_Treco_nu.cxx @@ -1,264 +1,264 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_NCEL_XSec_Treco_nu.h" #include "TLorentzVector.h" //******************************************************************** MiniBooNE_NCEL_XSec_Treco_nu::MiniBooNE_NCEL_XSec_Treco_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_NCEL_XSec_Treco_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Numu Flux \n" \ "Signal: Any event with True NCEL modes \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("T_{reco} (MeV)"); fSettings.SetYTitle("Events/(12 MeV)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL,DIAG"); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetEnuRange(0.0, 10.0); double arr_treco[52] = {40.0, 52.0, 63.9, 75.9, 87.8, 99.8, 111.8, 123.7, 135.7, 147.6, 159.6, 171.6, 183.5, 195.5, \ 207.5, 219.4, 231.4, 243.3, 255.3, 267.3, 279.2, 291.2, 303.1, 315.1, 327.1, 339.0, 351.0, 362.9, 374.9, 386.9, \ 398.8, 410.8, 422.7, 434.7, 446.7, 458.6, 470.6, 482.5, 494.5, 506.5, 518.4, 530.4, 542.4, 554.3, 566.3, 578.2, \ 590.2, 602.2, 614.1, 626.1, 638.0, 650.0}; SetDataValues(FitPar::GetDataBase()+"/MiniBooNE/ncqe/input_data.txt", arr_treco); SetCovarMatrix(FitPar::GetDataBase()+"/MiniBooNE/ncqe/ErrorMatrix.tab", 51); SetResponseMatrix(FitPar::GetDataBase()+"/MiniBooNE/ncqe/response_mat.txt", 51, arr_treco); SetFluxHistogram(FitPar::GetDataBase()+"/MiniBooNE/ncqe/flux.txt"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // The scale factor is quite complicated because MB didn't divide by number of targets. // nMolMB is the number of CH_2 molecules in the MB FV (610.6 cm radius sphere) and 0.845 is the published density of the mineral oil. // UPDATE: nMolMB is the number of CH_2 molecules in the MB FV (500 cm radius sphere) and 0.845 is the published density of the mineral oil. // UPDATE UPDATE: They didn't account for fiducial cut, so neither do we. double nMolMB = 6.023E+23*0.845*4.0*M_PI*610.6*610.6*610.6/3.0; double POT = 6.46e20; // Need to update scalefactor to reflect actual flux used fScaleFactor = (this->newFluxHist->Integral("")*POT*(GetEventHistogram()->Integral("width"))*1E-38*14.08/(fNEvents+0.))*nMolMB; fScaleFactor /= GetFluxHistogram()->Integral("width"); // Final setup --------------------------------------------------- FinaliseMeasurement(); // Usually the MCFine histogram is a finer binned version of MC Hist. // In this case we need to use it to save the true distribution before smearing. if (fMCFine) delete fMCFine; fMCFine = new TH1D((this->fName+"_Ttrue").c_str(), (this->fName+this->fPlotTitles).c_str(), 50, 0, 900); }; void MiniBooNE_NCEL_XSec_Treco_nu::Write(std::string arg){ newFluxHist->Write("MB_NCEL_newFlux"); response_mat->Write("MB_NCEL_response matrix"); Measurement1D::Write(arg); return; } void MiniBooNE_NCEL_XSec_Treco_nu::FillEventVariables(FitEvent *event){ double t_raw = 0.0; // Loop and add all Tnucleon for (UInt_t i = 0; i < event->Npart(); i++){ if (event->PartInfo(i)->Status() != kFinalState) continue; int pdg = event->PartInfo(i)->fPID; if (pdg == 2212 || pdg == 2112){ t_raw += FitUtils::T(event->PartInfo(i)->fP)*1.E3; } } fXVar = t_raw; } void MiniBooNE_NCEL_XSec_Treco_nu::ScaleEvents(){ // Now convert Ttrue to Treco... for (int treco = 0; treco < 51; ++treco){ double total = 0.; for (int ttrue = 0; ttrue < 50; ++ttrue) total += fMCFine->GetBinContent(ttrue+1)*response_mat->GetBinContent(ttrue+1, treco+1); fMCHist->SetBinContent(treco+1, total); } // Scale this->fMCHist->Scale(this->fScaleFactor, "width"); this->fMCFine->Scale(this->fScaleFactor, "width"); PlotUtils::ScaleNeutModeArray((TH1**)fMCHist_PDG, fScaleFactor, "width"); // Add in the backgrounds... for (int treco = 0; treco < 51; ++treco){ double total = this->fMCHist->GetBinContent(treco+1) + this->BKGD_other->GetBinContent(treco+1) + this->BKGD_irrid->GetBinContent(treco+1); this->fMCHist->SetBinContent(treco+1, total); } } bool MiniBooNE_NCEL_XSec_Treco_nu::isSignal(FitEvent *event){ // Should put in MB SignalDef eventually if (event->Mode != 51 && event->Mode != 52) return false; // Numu or nue if (event->PDGnu() != 14 && event->PDGnu() != 12) return false; // Enu if (event->Enu() < EnuMin*1000.0 || event->Enu() > EnuMax*1000.0) return false; return true; }; void MiniBooNE_NCEL_XSec_Treco_nu::SetFluxHistogram(std::string dataFile){ this->newFluxHist = PlotUtils::GetTH1DFromFile(dataFile.c_str(), (this->fName+"Real Flux Hist"), "idgaf"); this->newFluxHist->Print(); return; } // Read in the covariance matrix from the file specified in the constructor void MiniBooNE_NCEL_XSec_Treco_nu::SetCovarMatrix(std::string covarFile, int dim){ // Use Utils // // Make a counter to track the line number int row = 0; std::string line; - std::ifstream covar(covarFile.c_str(),ifstream::in); + std::ifstream covar(covarFile.c_str(),std::ifstream::in); this->covar = new TMatrixDSym(dim); if(covar.is_open()) LOG(DEB) << "Reading covariance matrix from file: " << covarFile << std::endl; while(std::getline(covar >> std::ws, line, '\n')){ std::istringstream stream(line); double entry; int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation matrix while(stream >> entry){ (*this->covar)(row, column) = entry; if (row == column) this->fDataHist->SetBinError(row+1, sqrt(entry)); column++; } row++; } // // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU .Invert().GetMatrixArray(), ""); return; }; // Override the usual function in the base class because this is more complicated for the NCEL sample... void MiniBooNE_NCEL_XSec_Treco_nu::SetDataValues(std::string inputFile, double* arr_treco){ std::string line; - std::ifstream input(inputFile.c_str(),ifstream::in); + std::ifstream input(inputFile.c_str(),std::ifstream::in); if(input.is_open()) LOG(DEB) << "Reading data from file: " << inputFile << std::endl; this->fDataHist = new TH1D((this->fName+"_data").c_str(), (this->fName+this->fPlotTitles).c_str(), 51, arr_treco); this->BKGD_other = new TH1D((this->fName+"_BKGD_other").c_str(), (this->fName+this->fPlotTitles).c_str(), 51, arr_treco); this->BKGD_irrid = new TH1D((this->fName+"_BKGD_irrid").c_str(), (this->fName+this->fPlotTitles).c_str(), 51, arr_treco); // To get the nDOF correct... this->fNDataPointsX= 52; double entry = 0; int xBin = 0; // First line is the MB data std::getline(input >> std::ws, line, '\n'); std::istringstream stream1(line); while(stream1 >> entry){ this->fDataHist->SetBinContent(xBin+1, entry); xBin++; } // Second line is "other" backgrounds std::getline(input >> std::ws, line, '\n'); std::istringstream stream2(line); entry = 0; xBin = 0; while(stream2 >> entry){ this->BKGD_other->SetBinContent(xBin+1, entry); xBin++; } // Third line is the irreducible background std::getline(input >> std::ws, line, '\n'); std::istringstream stream3(line); entry = 0; xBin = 0; while(stream3 >> entry){ this->BKGD_irrid->SetBinContent(xBin+1, entry); xBin++; } }; // Read in the response matrix -- thus far, a response matrix is unique to the NCEL sample void MiniBooNE_NCEL_XSec_Treco_nu::SetResponseMatrix(std::string responseFile, int dim, double* arr_treco){ // Make a counter to track the line number int xBin = 0; std::string line; - std::ifstream response(responseFile.c_str(),ifstream::in); + std::ifstream response(responseFile.c_str(),std::ifstream::in); // Response matrix: x axis is Ttrue, y axis is Treco this->response_mat = new TH2D((this->fName+"_RESPONSE_MATRIX").c_str(), (this->fName+this->fPlotTitles).c_str(), 50, 0, 900, 51, arr_treco); if(response.is_open()) LOG(DEB) << "Reading in the response matrix from file: " << responseFile << std::endl; while(std::getline(response, line, '\n')){ std::istringstream stream(line); double entry; int yBin = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation matrix while(stream >> entry){ this->response_mat->SetBinContent(xBin+1, yBin+1, entry); yBin++; } xBin++; } }; diff --git a/src/Reweight/CMakeLists.txt b/src/Reweight/CMakeLists.txt index 55b9fef..5ca22b8 100644 --- a/src/Reweight/CMakeLists.txt +++ b/src/Reweight/CMakeLists.txt @@ -1,83 +1,91 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ set(IMPLFILES GlobalDialList.cxx FitWeight.cxx WeightEngineBase.cxx NEUTWeightEngine.cxx NuWroWeightEngine.cxx GENIEWeightEngine.cxx WeightUtils.cxx SampleNormEngine.cxx LikelihoodWeightEngine.cxx SplineWeightEngine.cxx NUISANCESyst.cxx T2KWeightEngine.cxx NUISANCEWeightEngine.cxx NUISANCEWeightCalcs.cxx NIWGWeightEngine.cxx OscWeightEngine.cxx MINERvAWeightCalcs.cxx weightRPA.h ) +if(USE_NOvARwgt) + LIST(APPEND IMPLFILES NOvARwgtEngine.cxx) +endif() + set(HEADERFILES GlobalDialList.h FitWeight.h WeightEngineBase.h NEUTWeightEngine.h NuWroWeightEngine.h GENIEWeightEngine.h WeightUtils.h SampleNormEngine.h LikelihoodWeightEngine.h SplineWeightEngine.h NUISANCESyst.h T2KWeightEngine.h NUISANCEWeightEngine.h NUISANCEWeightCalcs.h NIWGWeightEngine.h OscWeightEngine.h MINERvAWeightCalcs.h weightRPA.h ) +if(USE_NOvARwgt) + LIST(APPEND HEADERFILES NOvARwgtEngine.h) +endif() + set(LIBNAME Reweight) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) set_target_properties(${LIBNAME} PROPERTIES VERSION "${ExtFit_VERSION_MAJOR}.${ExtFit_VERSION_MINOR}.${ExtFit_VERSION_REVISION}") #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/Reweight/FitWeight.cxx b/src/Reweight/FitWeight.cxx index 36964a8..863d143 100644 --- a/src/Reweight/FitWeight.cxx +++ b/src/Reweight/FitWeight.cxx @@ -1,275 +1,284 @@ #include "FitWeight.h" #include "GENIEWeightEngine.h" #include "LikelihoodWeightEngine.h" #include "ModeNormEngine.h" #include "NEUTWeightEngine.h" #include "NIWGWeightEngine.h" #include "NUISANCEWeightEngine.h" #include "NuWroWeightEngine.h" #include "OscWeightEngine.h" #include "SampleNormEngine.h" #include "SplineWeightEngine.h" #include "T2KWeightEngine.h" +#ifdef __NOVA_ENABLED__ +#include "NOvARwgtEngine.h" +#endif + void FitWeight::AddRWEngine(int type) { LOG(FIT) << "Adding reweight engine " << type << std::endl; switch (type) { - case kNEUT: - fAllRW[type] = new NEUTWeightEngine("neutrw"); - break; - - case kNUWRO: - fAllRW[type] = new NuWroWeightEngine("nuwrorw"); - break; - - case kGENIE: - fAllRW[type] = new GENIEWeightEngine("genierw"); - break; - - case kNORM: - fAllRW[type] = new SampleNormEngine("normrw"); - break; - - case kLIKEWEIGHT: - fAllRW[type] = new LikelihoodWeightEngine("likerw"); - break; - - case kT2K: - fAllRW[type] = new T2KWeightEngine("t2krw"); - break; - - case kCUSTOM: - fAllRW[type] = new NUISANCEWeightEngine("nuisrw"); - break; - - case kSPLINEPARAMETER: - fAllRW[type] = new SplineWeightEngine("splinerw"); - break; - - case kNIWG: - fAllRW[type] = new NIWGWeightEngine("niwgrw"); - break; - case kOSCILLATION: - fAllRW[type] = new OscWeightEngine(); - break; - case kMODENORM: - fAllRW[type] = new ModeNormEngine(); - break; - default: - THROW("CANNOT ADD RW Engine for unknown dial type: " << type); - break; + case kNEUT: + fAllRW[type] = new NEUTWeightEngine("neutrw"); + break; + + case kNUWRO: + fAllRW[type] = new NuWroWeightEngine("nuwrorw"); + break; + + case kGENIE: + fAllRW[type] = new GENIEWeightEngine("genierw"); + break; + + case kNORM: + fAllRW[type] = new SampleNormEngine("normrw"); + break; + + case kLIKEWEIGHT: + fAllRW[type] = new LikelihoodWeightEngine("likerw"); + break; + + case kT2K: + fAllRW[type] = new T2KWeightEngine("t2krw"); + break; + + case kCUSTOM: + fAllRW[type] = new NUISANCEWeightEngine("nuisrw"); + break; + + case kSPLINEPARAMETER: + fAllRW[type] = new SplineWeightEngine("splinerw"); + break; + + case kNIWG: + fAllRW[type] = new NIWGWeightEngine("niwgrw"); + break; + case kOSCILLATION: + fAllRW[type] = new OscWeightEngine(); + break; + case kMODENORM: + fAllRW[type] = new ModeNormEngine(); + break; + case kNOvARWGT: + fAllRW[type] = new NOvARwgtEngine(); + break; + default: + THROW("CANNOT ADD RW Engine for unknown dial type: " << type); + break; } } -WeightEngineBase* FitWeight::GetRWEngine(int type) { +WeightEngineBase *FitWeight::GetRWEngine(int type) { if (HasRWEngine(type)) { return fAllRW[type]; } THROW("CANNOT get RW Engine for dial type: " << type); } bool FitWeight::HasRWEngine(int type) { switch (type) { - case kNEUT: - case kNUWRO: - case kGENIE: - case kNORM: - case kLIKEWEIGHT: - case kT2K: - case kCUSTOM: - case kSPLINEPARAMETER: - case kNIWG: - case kOSCILLATION: { - return fAllRW.count(type); - } - default: { THROW("CANNOT get RW Engine for dial type: " << type); } + case kNEUT: + case kNUWRO: + case kGENIE: + case kNORM: + case kLIKEWEIGHT: + case kT2K: + case kCUSTOM: + case kSPLINEPARAMETER: + case kNIWG: + case kOSCILLATION: + case kNOvARWGT: { + return fAllRW.count(type); + } + default: { THROW("CANNOT get RW Engine for dial type: " << type); } } } void FitWeight::IncludeDial(std::string name, std::string type, double val) { // Should register the dial here. int typeenum = Reweight::ConvDialType(type); IncludeDial(name, typeenum, val); } void FitWeight::IncludeDial(std::string name, int dialtype, double val) { // Get the dial enum int nuisenum = Reweight::ConvDial(name, dialtype); if (nuisenum == -1) { THROW("NUISENUM == " << nuisenum << " for " << name); } // Setup RW Engine Pointer if (fAllRW.find(dialtype) == fAllRW.end()) { AddRWEngine(dialtype); } - WeightEngineBase* rw = fAllRW[dialtype]; + WeightEngineBase *rw = fAllRW[dialtype]; // Include the dial rw->IncludeDial(name, val); // Set Dial Value if (val != -9999.9) { rw->SetDialValue(name, val); } // Sort Maps fAllEnums[name] = nuisenum; fAllValues[nuisenum] = val; // Sort Lists fNameList.push_back(name); fEnumList.push_back(nuisenum); fValueList.push_back(val); } void FitWeight::Reconfigure(bool silent) { // Reconfigure all added RW engines - for (std::map::iterator iter = fAllRW.begin(); + for (std::map::iterator iter = fAllRW.begin(); iter != fAllRW.end(); iter++) { (*iter).second->Reconfigure(silent); } } void FitWeight::SetDialValue(std::string name, double val) { // Add extra check, if name not found look for one with name in it. int nuisenum = fAllEnums[name]; SetDialValue(nuisenum, val); } // Allow for name aswell using GlobalList to determine sample name. void FitWeight::SetDialValue(int nuisenum, double val) { // Conv dial type int dialtype = Reweight::GetDialType(nuisenum); if (fAllRW.find(dialtype) == fAllRW.end()) { THROW("Cannot find RW Engine for dialtype = " << dialtype << ", " << Reweight::RemoveDialType(nuisenum)); } // Get RW Engine for this dial fAllRW[dialtype]->SetDialValue(nuisenum, val); fAllValues[nuisenum] = val; // Update ValueList for (size_t i = 0; i < fEnumList.size(); i++) { if (fEnumList[i] == nuisenum) { fValueList[i] = val; } } } -void FitWeight::SetAllDials(const double* x, int n) { +void FitWeight::SetAllDials(const double *x, int n) { for (size_t i = 0; i < (UInt_t)n; i++) { int rwenum = fEnumList[i]; SetDialValue(rwenum, x[i]); } Reconfigure(); } double FitWeight::GetDialValue(std::string name) { // Add extra check, if name not found look for one with name in it. int nuisenum = fAllEnums[name]; return GetDialValue(nuisenum); } double FitWeight::GetDialValue(int nuisenum) { return fAllValues[nuisenum]; } int FitWeight::GetDialPos(std::string name) { int rwenum = fAllEnums[name]; return GetDialPos(rwenum); } int FitWeight::GetDialPos(int nuisenum) { for (size_t i = 0; i < fEnumList.size(); i++) { if (fEnumList[i] == nuisenum) { return i; } } ERR(FTL) << "No Dial Found! " << std::endl; throw; return -1; } bool FitWeight::DialIncluded(std::string name) { return (fAllEnums.find(name) != fAllEnums.end()); } bool FitWeight::DialIncluded(int rwenum) { return (fAllValues.find(rwenum) != fAllValues.end()); } -double FitWeight::CalcWeight(BaseFitEvt* evt) { +double FitWeight::CalcWeight(BaseFitEvt *evt) { double rwweight = 1.0; - for (std::map::iterator iter = fAllRW.begin(); + for (std::map::iterator iter = fAllRW.begin(); iter != fAllRW.end(); iter++) { double w = (*iter).second->CalcWeight(evt); rwweight *= w; } return rwweight; } -void FitWeight::UpdateWeightEngine(const double* x) { +void FitWeight::UpdateWeightEngine(const double *x) { size_t count = 0; for (std::vector::iterator iter = fEnumList.begin(); iter != fEnumList.end(); iter++) { SetDialValue((*iter), x[count]); count++; } } -void FitWeight::GetAllDials(double* x, int n) { +void FitWeight::GetAllDials(double *x, int n) { for (int i = 0; i < n; i++) { x[i] = GetDialValue(fEnumList[i]); } } // bool FitWeight::NeedsEventReWeight(const double* x) { // bool haschange = false; // size_t count = 0; // // Compare old to new and decide if RW needed. // for (std::vector::iterator iter = fEnumList.begin(); // iter != fEnumList.end(); iter++) { // int nuisenum = (*iter); // int type = (nuisenum / 1000) - (nuisenum % 1000); // // Compare old to new // double oldval = GetDialValue(nuisenum); // double newval = x[count]; // if (oldval != newval) { // if (fAllRW[type]->NeedsEventReWeight()) { // haschange = true; // } // } // count++; // } // return haschange; // } double FitWeight::GetSampleNorm(std::string name) { - if (name.empty()) return 1.0; + if (name.empty()) + return 1.0; // Find norm dial if (fAllEnums.find(name + "_norm") != fAllEnums.end()) { if (fAllValues.find(fAllEnums[name + "_norm"]) != fAllValues.end()) { return fAllValues[fAllEnums[name + "_norm"]]; } else { return 1.0; } } else { return 1.0; } } void FitWeight::Print() { LOG(REC) << "Fit Weight State: " << std::endl; for (size_t i = 0; i < fNameList.size(); i++) { LOG(REC) << " -> Par " << i << ". " << fNameList[i] << " " << fValueList[i] << std::endl; } } diff --git a/src/Reweight/GENIEWeightEngine.cxx b/src/Reweight/GENIEWeightEngine.cxx index 52b433f..31afebb 100644 --- a/src/Reweight/GENIEWeightEngine.cxx +++ b/src/Reweight/GENIEWeightEngine.cxx @@ -1,267 +1,277 @@ #include "GENIEWeightEngine.h" #ifdef __GENIE_EMP_MECRW_ENABLED #include "ReWeight/GReWeightXSecEmpiricalMEC.h" #endif GENIEWeightEngine::GENIEWeightEngine(std::string name) { #ifdef __GENIE_ENABLED__ // Setup the NEUT Reweight engien fCalcName = name; LOG(FIT) << "Setting up GENIE RW : " << fCalcName << std::endl; // Create RW Engine suppressing cout StopTalking(); fGenieRW = new genie::rew::GReWeight(); // Get List of Vetos (Just for debugging) std::string rw_engine_list = FitPar::Config().GetParS("FitWeight_fGenieRW_veto"); bool xsec_ncel = rw_engine_list.find("xsec_ncel") == std::string::npos; bool xsec_ccqe = rw_engine_list.find("xsec_ccqe") == std::string::npos; bool xsec_coh = rw_engine_list.find("xsec_coh") == std::string::npos; bool xsec_nnres = rw_engine_list.find("xsec_nonresbkg") == std::string::npos; bool xsec_nudis = rw_engine_list.find("nuclear_dis") == std::string::npos; bool xsec_resdec = rw_engine_list.find("hadro_res_decay") == std::string::npos; bool xsec_fzone = rw_engine_list.find("hadro_intranuke") == std::string::npos; bool xsec_intra = rw_engine_list.find("hadro_fzone") == std::string::npos; bool xsec_agky = rw_engine_list.find("hadro_agky") == std::string::npos; bool xsec_qevec = rw_engine_list.find("xsec_ccqe_vec") == std::string::npos; bool xsec_dis = rw_engine_list.find("xsec_dis") == std::string::npos; bool xsec_nc = rw_engine_list.find("xsec_nc") == std::string::npos; bool xsec_ccres = rw_engine_list.find("xsec_ccres") == std::string::npos; bool xsec_ncres = rw_engine_list.find("xsec_ncres") == std::string::npos; bool xsec_nucqe = rw_engine_list.find("nuclear_qe") == std::string::npos; bool xsec_qeaxial = rw_engine_list.find("xsec_ccqe_axial") == std::string::npos; #ifdef __GENIE_EMP_MECRW_ENABLED bool xsec_empMEC = rw_engine_list.find("xsec_empMEC") == std::string::npos; #endif +#ifndef GENIE_PRE_R3 + genie::RunOpt* grunopt = genie::RunOpt::Instance(); + grunopt->EnableBareXSecPreCalc(true); + grunopt->SetEventGeneratorList(Config::GetParS("GENIEEventGeneratorList")); + grunopt->SetTuneName(Config::GetParS("GENIETune")); + grunopt->BuildTune(); + std::string genv = std::string(getenv("GENIE")) + "/config/Messenger_laconic.xml"; + genie::utils::app_init::MesgThresholds(genv); +#endif + // Now actually add the RW Calcs if (xsec_ncel) fGenieRW->AdoptWghtCalc("xsec_ncel", new genie::rew::GReWeightNuXSecNCEL); if (xsec_ccqe) { fGenieRW->AdoptWghtCalc("xsec_ccqe", new genie::rew::GReWeightNuXSecCCQE); // (dynamic_cast (fGenieRW->WghtCalc("xsec_ccqe"))) // ->SetXSecModel( FitPar::Config().GetParS("GENIEXSecModelCCQE") ); } #ifdef __GENIE_EMP_MECRW_ENABLED if (xsec_empMEC) { fGenieRW->AdoptWghtCalc("xsec_empMEC", new genie::rew::GReWeightXSecEmpiricalMEC); } #endif if (xsec_coh) { fGenieRW->AdoptWghtCalc("xsec_coh", new genie::rew::GReWeightNuXSecCOH()); // (dynamic_cast (fGenieRW->WghtCalc("xsec_coh"))) // ->SetXSecModel( FitPar::Config().GetParS("GENIEXSecModelCOH") ); } if (xsec_nnres) fGenieRW->AdoptWghtCalc("xsec_nonresbkg", new genie::rew::GReWeightNonResonanceBkg); if (xsec_nudis) fGenieRW->AdoptWghtCalc("nuclear_dis", new genie::rew::GReWeightDISNuclMod); if (xsec_resdec) fGenieRW->AdoptWghtCalc("hadro_res_decay", new genie::rew::GReWeightResonanceDecay); if (xsec_fzone) fGenieRW->AdoptWghtCalc("hadro_fzone", new genie::rew::GReWeightFZone); if (xsec_intra) fGenieRW->AdoptWghtCalc("hadro_intranuke", new genie::rew::GReWeightINuke); if (xsec_agky) fGenieRW->AdoptWghtCalc("hadro_agky", new genie::rew::GReWeightAGKY); if (xsec_qevec) fGenieRW->AdoptWghtCalc("xsec_ccqe_vec", new genie::rew::GReWeightNuXSecCCQEvec); #if __GENIE_VERSION__ >= 212 if (xsec_qeaxial) fGenieRW->AdoptWghtCalc("xsec_ccqe_axial", new genie::rew::GReWeightNuXSecCCQEaxial); #endif if (xsec_dis) fGenieRW->AdoptWghtCalc("xsec_dis", new genie::rew::GReWeightNuXSecDIS); if (xsec_nc) fGenieRW->AdoptWghtCalc("xsec_nc", new genie::rew::GReWeightNuXSecNC); if (xsec_ccres) { #if __GENIE_VERSION__ < 213 fGenieRW->AdoptWghtCalc("xsec_ccres", new genie::rew::GReWeightNuXSecCCRES); #else fGenieRW->AdoptWghtCalc( "xsec_ccres", new genie::rew::GReWeightNuXSecCCRES( FitPar::Config().GetParS("GENIEXSecModelCCRES"), "Default")); #endif } if (xsec_ncres) fGenieRW->AdoptWghtCalc("xsec_ncres", new genie::rew::GReWeightNuXSecNCRES); if (xsec_nucqe) fGenieRW->AdoptWghtCalc("nuclear_qe", new genie::rew::GReWeightFGM); if (xsec_ccqe) { GReWeightNuXSecCCQE *rwccqe = dynamic_cast(fGenieRW->WghtCalc("xsec_ccqe")); rwccqe->SetMode(GReWeightNuXSecCCQE::kModeMa); } if (xsec_ccres) { // Default to include shape and normalization changes for CCRES (can be // changed downstream if desired) GReWeightNuXSecCCRES *rwccres = dynamic_cast(fGenieRW->WghtCalc("xsec_ccres")); std::string marestype = FitPar::Config().GetParS("GENIEWeightEngine_CCRESMode"); if (!marestype.compare("kModeNormAndMaMvShape")) { rwccres->SetMode(GReWeightNuXSecCCRES::kModeNormAndMaMvShape); } else if (!marestype.compare("kModeMaMv")) { rwccres->SetMode(GReWeightNuXSecCCRES::kModeMaMv); } else { THROW("Unkown MARES Mode in GENIE Weight Engine : " << marestype); } } if (xsec_ncres) { // Default to include shape and normalization changes for NCRES (can be // changed downstream if desired) GReWeightNuXSecNCRES *rwncres = dynamic_cast(fGenieRW->WghtCalc("xsec_ncres")); rwncres->SetMode(GReWeightNuXSecNCRES::kModeMaMv); } if (xsec_dis) { // Default to include shape and normalization changes for DIS (can be // changed downstream if desired) GReWeightNuXSecDIS *rwdis = dynamic_cast(fGenieRW->WghtCalc("xsec_dis")); rwdis->SetMode(GReWeightNuXSecDIS::kModeABCV12u); // Set Abs Twk Config fIsAbsTwk = (FitPar::Config().GetParB("setabstwk")); } // allow cout again StartTalking(); #else ERR(FTL) << "GENIE RW NOT ENABLED" << std::endl; #endif }; void GENIEWeightEngine::IncludeDial(std::string name, double startval) { #ifdef __GENIE_ENABLED__ // Get First enum int nuisenum = Reweight::ConvDial(name, kGENIE); // Setup Maps fEnumIndex[nuisenum]; // = std::vector(0); fNameIndex[name]; // = std::vector(0); // Split by commas std::vector allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get RW genie::rew::GSyst_t rwsyst = GSyst::FromString(singlename); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fGENIESysts.push_back(rwsyst); // Initialize dial std::cout << "Registering " << singlename << " from " << name << std::endl; fGenieRW->Systematics().Init(fGENIESysts[index]); // If Absolute if (fIsAbsTwk) { GSystUncertainty::Instance()->SetUncertainty(rwsyst, 1.0, 1.0); } // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(nuisenum, startval); } #endif }; void GENIEWeightEngine::SetDialValue(int nuisenum, double val) { #ifdef __GENIE_ENABLED__ std::vector indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fGenieRW->Systematics().Set(fGENIESysts[indices[i]], val); } #endif } void GENIEWeightEngine::SetDialValue(std::string name, double val) { #ifdef __GENIE_ENABLED__ std::vector indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fGenieRW->Systematics().Set(fGENIESysts[indices[i]], val); } #endif } void GENIEWeightEngine::Reconfigure(bool silent) { #ifdef __GENIE_ENABLED__ // Hush now... if (silent) StopTalking(); // Reconf fGenieRW->Reconfigure(); fGenieRW->Print(); // Shout again if (silent) StartTalking(); #endif } double GENIEWeightEngine::CalcWeight(BaseFitEvt *evt) { double rw_weight = 1.0; #ifdef __GENIE_ENABLED__ - // Skip Non GENIE - if (evt->fType != kGENIE) - return 1.0; - // Make nom weight if (!evt) { THROW("evt not found : " << evt); } + // Skip Non GENIE + if (evt->fType != kGENIE) + return 1.0; + if (!(evt->genie_event)) { THROW("evt->genie_event not found!" << evt->genie_event); } if (!(evt->genie_event->event)) { THROW("evt->genie_event->event GHepRecord not found!" << (evt->genie_event->event)); } if (!fGenieRW) { THROW("GENIE RW Not Found!" << fGenieRW); } rw_weight = fGenieRW->CalcWeight(*(evt->genie_event->event)); // std::cout << "Returning GENIE Weight for electron scattering = " << // rw_weight << std::endl; #endif // Return rw_weight return rw_weight; } diff --git a/src/Reweight/GENIEWeightEngine.h b/src/Reweight/GENIEWeightEngine.h index b0d3d03..e0a7f7e 100644 --- a/src/Reweight/GENIEWeightEngine.h +++ b/src/Reweight/GENIEWeightEngine.h @@ -1,64 +1,88 @@ #ifndef WEIGHT_ENGINE_GENIE_H #define WEIGHT_ENGINE_GENIE_H #include "FitLogger.h" #ifdef __GENIE_ENABLED__ -#include "EVGCore/EventRecord.h" +#ifdef GENIE_PRE_R3 #include "EVGCore/EventRecord.h" #include "GHEP/GHepRecord.h" -#include "GSyst.h" -#include "GSystUncertainty.h" +#include "ReWeight/GSyst.h" +#include "ReWeight/GSystUncertainty.h" #include "Ntuple/NtpMCEventRecord.h" #include "ReWeight/GReWeight.h" #include "ReWeight/GReWeightAGKY.h" #include "ReWeight/GReWeightDISNuclMod.h" #include "ReWeight/GReWeightFGM.h" #include "ReWeight/GReWeightFZone.h" #include "ReWeight/GReWeightINuke.h" #include "ReWeight/GReWeightNonResonanceBkg.h" #include "ReWeight/GReWeightNuXSecCCQE.h" #include "ReWeight/GReWeightNuXSecCCQEvec.h" #include "ReWeight/GReWeightNuXSecCCRES.h" #include "ReWeight/GReWeightNuXSecCOH.h" #include "ReWeight/GReWeightNuXSecDIS.h" #include "ReWeight/GReWeightNuXSecNC.h" #include "ReWeight/GReWeightNuXSecNCEL.h" #include "ReWeight/GReWeightNuXSecNCRES.h" #include "ReWeight/GReWeightResonanceDecay.h" - #if __GENIE_VERSION__ >= 212 #include "ReWeight/GReWeightNuXSecCCQEaxial.h" #endif - +#else +#include "Framework/EventGen/EventRecord.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Framework/Ntuple/NtpMCEventRecord.h" +#include "Framework/Utils/RunOpt.h" +#include "Framework/Utils/AppInit.h" +#include "RwFramework/GSyst.h" +#include "RwFramework/GSystUncertainty.h" +#include "RwFramework/GReWeight.h" +#include "RwCalculators/GReWeightAGKY.h" +#include "RwCalculators/GReWeightDISNuclMod.h" +#include "RwCalculators/GReWeightFGM.h" +#include "RwCalculators/GReWeightFZone.h" +#include "RwCalculators/GReWeightINuke.h" +#include "RwCalculators/GReWeightNonResonanceBkg.h" +#include "RwCalculators/GReWeightNuXSecCCQE.h" +#include "RwCalculators/GReWeightNuXSecCCQEvec.h" +#include "RwCalculators/GReWeightNuXSecCCRES.h" +#include "RwCalculators/GReWeightNuXSecCOH.h" +#include "RwCalculators/GReWeightNuXSecDIS.h" +#include "RwCalculators/GReWeightNuXSecNC.h" +#include "RwCalculators/GReWeightNuXSecNCEL.h" +#include "RwCalculators/GReWeightNuXSecNCRES.h" +#include "RwCalculators/GReWeightResonanceDecay.h" +#include "RwCalculators/GReWeightNuXSecCCQEaxial.h" +#endif using namespace genie; using namespace genie::rew; #endif - #include "GeneratorUtils.h" #include "WeightEngineBase.h" #include "FitWeight.h" class GENIEWeightEngine : public WeightEngineBase { public: GENIEWeightEngine(std::string name); ~GENIEWeightEngine() {}; void IncludeDial(std::string name, double startval); void SetDialValue(int rwenum, double val); void SetDialValue(std::string name, double val); void Reconfigure(bool silent = false); double CalcWeight(BaseFitEvt* evt); inline bool NeedsEventReWeight() { return true; }; #ifdef __GENIE_ENABLED__ std::vector fGENIESysts; genie::rew::GReWeight* fGenieRW; //!< Genie RW Object #endif }; #endif diff --git a/src/Reweight/MINERvAWeightCalcs.h b/src/Reweight/MINERvAWeightCalcs.h index 79e4654..965010d 100644 --- a/src/Reweight/MINERvAWeightCalcs.h +++ b/src/Reweight/MINERvAWeightCalcs.h @@ -1,148 +1,158 @@ #ifndef MINERVA_WEIGHT_CALCS #define MINERVA_WEIGHT_CALCS #include #ifdef __MINERVA_RW_ENABLED__ #ifdef __GENIE_ENABLED__ +#ifdef GENIE_PRE_R3 #include "Conventions/Units.h" #include "EVGCore/EventRecord.h" -#include "FitEvent.h" - #include "GHEP/GHepParticle.h" #include "GHEP/GHepRecord.h" #include "GHEP/GHepUtils.h" -#include "GeneralUtils.h" -#include "NUISANCESyst.h" -#include "NUISANCEWeightCalcs.h" #include "Ntuple/NtpMCEventRecord.h" #include "PDG/PDGUtils.h" +#else +#include "Framework/Conventions/Units.h" +#include "Framework/EventGen/EventRecord.h" +#include "Framework/GHEP/GHepParticle.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/GHEP/GHepUtils.h" +#include "Framework/Ntuple/NtpMCEventRecord.h" +#include "Framework/ParticleData/PDGUtils.h" +#endif + +#include "NUISANCEWeightCalcs.h" +#include "GeneralUtils.h" +#include "NUISANCESyst.h" +#include "FitEvent.h" #include "WeightUtils.h" #include "weightRPA.h" using namespace genie; class BaseFitEvt; namespace nuisance { namespace reweight { // MEC Dials class MINERvAReWeight_QE : public NUISANCEWeightCalc { public: MINERvAReWeight_QE(); virtual ~MINERvAReWeight_QE(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double fTwk_NormCCQE; double fCur_NormCCQE; double fDef_NormCCQE; bool fTweaked; }; // MEC Dials class MINERvAReWeight_MEC : public NUISANCEWeightCalc { public: MINERvAReWeight_MEC(); virtual ~MINERvAReWeight_MEC(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double fTwk_NormCCMEC; double fCur_NormCCMEC; double fDef_NormCCMEC; bool fTweaked; }; // RES Dials class MINERvAReWeight_RES : public NUISANCEWeightCalc { public: MINERvAReWeight_RES(); virtual ~MINERvAReWeight_RES(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double fTwk_NormCCRES; double fCur_NormCCRES; double fDef_NormCCRES; bool fTweaked; }; /// RPA Weight Calculator that applies RPA systematics /// to GENIE events. GENIE EVENTS ONLY! class RikRPA : public NUISANCEWeightCalc { public: RikRPA(); ~RikRPA(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); void SetupRPACalculator(int calcenum); int GetRPACalcEnum(int bpdg, int tpdg); bool fApplyDial_RPACorrection; double fTwkDial_RPALowQ2; double fDefDial_RPALowQ2; double fCurDial_RPALowQ2; double fErrDial_RPALowQ2; double fTwkDial_RPAHighQ2; double fDefDial_RPAHighQ2; double fCurDial_RPAHighQ2; double fErrDial_RPAHighQ2; bool fApplyDial_RESRPACorrection; double fTwkDial_RESRPALowQ2; double fDefDial_RESRPALowQ2; double fCurDial_RESRPALowQ2; double fErrDial_RESRPALowQ2; double fTwkDial_RESRPAHighQ2; double fDefDial_RESRPAHighQ2; double fCurDial_RESRPAHighQ2; double fErrDial_RESRPAHighQ2; double* fEventWeights; bool fTweaked; const static int kMaxCalculators = 10; enum rpacalcenums { kNuMuC12, kNuMuO16, kNuMuAr40, kNuMuCa40, kNuMuFe56, kNuMuBarC12, kNuMuBarO16, kNuMuBarAr40, kNuMuBarCa40, kNuMuBarFe56 }; weightRPA* fRPACalculators[kMaxCalculators]; }; }; // namespace reweight }; // namespace nuisance #endif // __GENIE_ENABLED__ #endif //__MINERVA_RW_ENABLED__ #endif diff --git a/src/Reweight/NOvARwgtEngine.cxx b/src/Reweight/NOvARwgtEngine.cxx new file mode 100644 index 0000000..31c2afd --- /dev/null +++ b/src/Reweight/NOvARwgtEngine.cxx @@ -0,0 +1,252 @@ +#include "NOvARwgtEngine.h" + +#include "NOvARwgt/interfaces/GenieInterface.h" + +#include "NOvARwgt/rwgt/genie/QE/MAQEWgts.h" +#include "NOvARwgt/rwgt/genie/QE/RPAWeights.h" + +#include "NOvARwgt/rwgt/genie/MEC/EmpiricalMECOtherTunes.h" +#include "NOvARwgt/rwgt/genie/MEC/EmpiricalMECTune2017.h" +#include "NOvARwgt/rwgt/genie/MEC/EmpiricalMECTune2018.h" +#include "NOvARwgt/rwgt/genie/MEC/EmpiricalMECTuneSA.h" + +#include "NOvARwgt/rwgt/genie/DIS/HighWDISWeight.h" +#include "NOvARwgt/rwgt/genie/DIS/Nonres1piWeights.h" + +#include "NOvARwgt/rwgt/EventRecord.h" +#include "NOvARwgt/rwgt/IWeightGenerator.h" + +static size_t const kRPAWeightCCQESA = 0; +static size_t const kRPAWeightCCQE_2017 = 1; +static size_t const kRPAWeightQ2_2017 = 2; +static size_t const kMAQEWeight_2018 = 3; +static size_t const kTufts2p2hWgtSA = 4; +static size_t const kEmpiricalMEC_to_Valencia_Wgt = 5; +static size_t const kEmpiricalMECWgt2018 = 6; +static size_t const kMECEnuShapeWgt = 7; +static size_t const kMECInitStateNPFracWgt = 8; +static size_t const kEmpiricalMECWgt2017 = 9; +static size_t const kEmpiricalMEC_to_GENIEQE_Wgt = 10; +static size_t const kEmpiricalMEC_to_GENIERES_Wgt = 11; +static size_t const kEmpiricalMECWgt2018RPAFix = 12; +static size_t const kMEC2018_QElike_Wgt = 13; +static size_t const kMEC2018_RESlike_Wgt = 14; +static size_t const kMEC2018RPAFix_QElike_Wgt = 15; +static size_t const kMEC2018RPAFix_RESlike_Wgt = 16; +static size_t const kNonres1PiWgt = 17; +static size_t const kHighWDISWgt_2018 = 18; +static size_t const kNoSuchWeightEngine = std::numeric_limits::max(); + +size_t NOvARwgtEngine::GetWeightGeneratorIndex(std::string const &strname) { + + if (strname == "RPAWeightCCQESA") { + return kRPAWeightCCQESA; + } else if (strname == "RPAWeightCCQE_2017") { + return kRPAWeightCCQE_2017; + } else if (strname == "RPAWeightQ2_2017") { + return kRPAWeightQ2_2017; + } else if (strname == "MAQEWeight_2018") { + return kMAQEWeight_2018; + } else if (strname == "Tufts2p2hWgtSA") { + return kTufts2p2hWgtSA; + } else if (strname == "EmpiricalMEC_to_Valencia_Wgt") { + return kEmpiricalMEC_to_Valencia_Wgt; + } else if (strname == "EmpiricalMECWgt2018") { + return kEmpiricalMECWgt2018; + } else if (strname == "MECEnuShapeWgt") { + return kMECEnuShapeWgt; + } else if (strname == "MECInitStateNPFracWgt") { + return kMECInitStateNPFracWgt; + } else if (strname == "EmpiricalMECWgt2017") { + return kEmpiricalMECWgt2017; + } else if (strname == "EmpiricalMEC_to_GENIEQE_Wgt") { + return kEmpiricalMEC_to_GENIEQE_Wgt; + } else if (strname == "EmpiricalMEC_to_GENIERES_Wgt") { + return kEmpiricalMEC_to_GENIERES_Wgt; + } else if (strname == "EmpiricalMECWgt2018RPAFix") { + return kEmpiricalMECWgt2018RPAFix; + } else if (strname == "MEC2018_QElike_Wgt") { + return kMEC2018_QElike_Wgt; + } else if (strname == "MEC2018_RESlike_Wgt") { + return kMEC2018_RESlike_Wgt; + } else if (strname == "MEC2018RPAFix_QElike_Wgt") { + return kMEC2018RPAFix_QElike_Wgt; + } else if (strname == "MEC2018RPAFix_RESlike_Wgt") { + return kMEC2018RPAFix_RESlike_Wgt; + } else if (strname == "Nonres1PiWgt") { + return kNonres1PiWgt; + } else if (strname == "HighWDISWgt_2018") { + return kHighWDISWgt_2018; + } + return kNoSuchWeightEngine; +} + +novarwgt::IWeightGenerator *IWeightGeneratorFactory(size_t e) { + switch (e) { + case kRPAWeightCCQESA: { + return new novarwgt::RPAWeightCCQESA(); + } + case kRPAWeightCCQE_2017: { + return new novarwgt::RPAWeightCCQE_2017("CV"); + } + case kRPAWeightQ2_2017: { + return new novarwgt::RPAWeightQ2_2017(); + } + case kMAQEWeight_2018: { + return new novarwgt::MAQEWeight_2018(); + } + case kTufts2p2hWgtSA: { + return new novarwgt::Tufts2p2hWgtSA(); + } + case kEmpiricalMEC_to_Valencia_Wgt: { + return new novarwgt::EmpiricalMEC_to_Valencia_Wgt(); + } + case kEmpiricalMECWgt2018: { + return new novarwgt::EmpiricalMECWgt2018(); + } + case kMECEnuShapeWgt: { + return new novarwgt::MECEnuShapeWgt(); + } + case kMECInitStateNPFracWgt: { + return new novarwgt::MECInitStateNPFracWgt(); + } + case kEmpiricalMECWgt2017: { + return new novarwgt::EmpiricalMECWgt2017(); + } + case kEmpiricalMEC_to_GENIEQE_Wgt: { + return new novarwgt::EmpiricalMEC_to_GENIEQE_Wgt(); + } + case kEmpiricalMEC_to_GENIERES_Wgt: { + return new novarwgt::EmpiricalMEC_to_GENIERES_Wgt(); + } + case kEmpiricalMECWgt2018RPAFix: { + return new novarwgt::EmpiricalMECWgt2018RPAFix(); + } + case kMEC2018_QElike_Wgt: { + return new novarwgt::MEC2018_QElike_Wgt(); + } + case kMEC2018_RESlike_Wgt: { + return new novarwgt::MEC2018_RESlike_Wgt(); + } + case kMEC2018RPAFix_QElike_Wgt: { + return new novarwgt::MEC2018RPAFix_QElike_Wgt(); + } + case kMEC2018RPAFix_RESlike_Wgt: { + return new novarwgt::MEC2018RPAFix_RESlike_Wgt(); + } + case kNonres1PiWgt: { + return new novarwgt::Nonres1PiWgt(); + } + case kHighWDISWgt_2018: { + return new novarwgt::HighWDISWgt_2018(); + } + default: { return nullptr; } + } +} + +void NOvARwgtEngine::IncludeDial(std::string name, double startval) { + size_t e = GetWeightGeneratorIndex(name); + if (e == kNoSuchWeightEngine) { + THROW("[ERROR]: Invalid NOvARwgt Engine name: " << name); + } + if (fWeightEngineEnums.find(e) != fWeightEngineEnums.end()) { + THROW("[ERROR]: NOvARwgt Engine name: " << name << " already included."); + } + fWeightEngineEnums[e] = fWeightEngines.size(); + fWeightEngines.push_back(IWeightGeneratorFactory(e)); + fWeightEngineValues.push_back(startval); +}; + +void NOvARwgtEngine::SetDialValue(int nuisenum, double val) { + size_t we_indx = (nuisenum % 1000); + if (!fWeightEngineEnums.count(we_indx)) { + THROW("[ERROR]: SetDialValue for NOvARwgt dial: " + << we_indx << " but that engine hasn't been included yet."); + } + size_t engine_index = fWeightEngineEnums[we_indx]; + + fWeightEngineValues[engine_index] = val; +} + +void NOvARwgtEngine::SetDialValue(std::string name, double val) { + size_t we_indx = GetWeightGeneratorIndex(name); + if (we_indx == kNoSuchWeightEngine) { + THROW("[ERROR]: Invalid NOvARwgt Engine name: " << name); + } + if (!fWeightEngineEnums.count(we_indx)) { + THROW("[ERROR]: SetDialValue for NOvARwgt dial: " + << we_indx << " but that engine hasn't been included yet."); + } + size_t engine_index = fWeightEngineEnums[we_indx]; + + fWeightEngineValues[engine_index] = val; +} + +bool NOvARwgtEngine::IsDialIncluded(std::string name) { + size_t we_indx = GetWeightGeneratorIndex(name); + if (we_indx == kNoSuchWeightEngine) { + THROW("[ERROR]: Invalid NOvARwgt Engine name: " << name); + } + return fWeightEngineEnums.count(we_indx); +} +bool NOvARwgtEngine::IsDialIncluded(int nuisenum) { + size_t we_indx = (nuisenum % 1000); + return fWeightEngineEnums.count(we_indx); +} + +double NOvARwgtEngine::GetDialValue(std::string name) { + size_t we_indx = GetWeightGeneratorIndex(name); + if (we_indx == kNoSuchWeightEngine) { + THROW("[ERROR]: Invalid NOvARwgt Engine name: " << name); + } + if (!fWeightEngineEnums.count(we_indx)) { + THROW("[ERROR]: SetDialValue for NOvARwgt dial: " + << we_indx << " but that engine hasn't been included yet."); + } + return fWeightEngineValues[fWeightEngineEnums[we_indx]]; +} +double NOvARwgtEngine::GetDialValue(int nuisenum) { + size_t we_indx = (nuisenum % 1000); + if (!fWeightEngineEnums.count(we_indx)) { + THROW("[ERROR]: SetDialValue for NOvARwgt dial: " + << we_indx << " but that engine hasn't been included yet."); + } + return fWeightEngineValues[fWeightEngineEnums[we_indx]]; +} + +double NOvARwgtEngine::CalcWeight(BaseFitEvt *evt) { + double rw_weight = 1.0; + + // Make nom weight + if (!evt) { + THROW("evt not found : " << evt); + } + + // Skip Non GENIE + if (evt->fType != kGENIE) + return 1.0; + + if (!(evt->genie_event)) { + THROW("evt->genie_event not found!" << evt->genie_event); + } + + if (!(evt->genie_event->event)) { + THROW("evt->genie_event->event GHepRecord not found!" + << (evt->genie_event->event)); + } + + novarwgt::EventRecord rcd = + novarwgt::ConvertGenieEvent(evt->genie_event->event); + + static novarwgt::InputVals const dummyparams; + + for (size_t w_it = 0; w_it < fWeightEngines.size(); ++w_it) { + if (fWeightEngineValues[w_it] == + 0) { // if a dial is set to 0, don't include its weight + continue; + } + rw_weight *= fWeightEngines[w_it]->GetWeight(rcd, dummyparams); + } + + return rw_weight; +} diff --git a/src/Reweight/NOvARwgtEngine.h b/src/Reweight/NOvARwgtEngine.h new file mode 100644 index 0000000..ef2bf09 --- /dev/null +++ b/src/Reweight/NOvARwgtEngine.h @@ -0,0 +1,36 @@ +#pragma once + +#include "WeightEngineBase.h" + +namespace novarwgt { +class IWeightGenerator; +} + +class NOvARwgtEngine : public WeightEngineBase { +public: + NOvARwgtEngine(){}; + virtual ~NOvARwgtEngine(){}; + + static size_t GetWeightGeneratorIndex(std::string const &); + + // Functions requiring Override + void IncludeDial(std::string name, double startval); + + void SetDialValue(int nuisenum, double val); + void SetDialValue(std::string name, double val); + + bool IsDialIncluded(std::string name); + bool IsDialIncluded(int nuisenum); + + double GetDialValue(std::string name); + double GetDialValue(int nuisenum); + + void Reconfigure(bool silent){}; + + double CalcWeight(BaseFitEvt *evt); + bool NeedsEventReWeight() { return true; } + + std::map fWeightEngineEnums; + std::vector fWeightEngines; + std::vector fWeightEngineValues; +}; diff --git a/src/Reweight/WeightUtils.cxx b/src/Reweight/WeightUtils.cxx index 1a1bd77..b4d0d81 100644 --- a/src/Reweight/WeightUtils.cxx +++ b/src/Reweight/WeightUtils.cxx @@ -1,614 +1,665 @@ #include "WeightUtils.h" #include "FitLogger.h" #ifdef __T2KREW_ENABLED__ #include "T2KGenieReWeight.h" #include "T2KNIWGReWeight.h" #include "T2KNIWGUtils.h" #include "T2KNeutReWeight.h" #include "T2KNeutUtils.h" #include "T2KReWeight.h" using namespace t2krew; #endif #ifdef __NIWG_ENABLED__ #include "NIWGReWeight.h" #include "NIWGReWeight1piAngle.h" #include "NIWGReWeight2010a.h" #include "NIWGReWeight2012a.h" #include "NIWGReWeight2014a.h" #include "NIWGReWeightDeltaMass.h" #include "NIWGReWeightEffectiveRPA.h" #include "NIWGReWeightHadronMultSwitch.h" #include "NIWGReWeightMEC.h" #include "NIWGReWeightPiMult.h" #include "NIWGReWeightProtonFSIbug.h" #include "NIWGReWeightRPA.h" #include "NIWGReWeightSpectralFunc.h" #include "NIWGReWeightSplineEnu.h" #include "NIWGSyst.h" #include "NIWGSystUncertainty.h" #endif #ifdef __NEUT_ENABLED__ #include "NReWeight.h" #include "NReWeightCasc.h" #include "NReWeightNuXSecCCQE.h" #include "NReWeightNuXSecCCRES.h" #include "NReWeightNuXSecCOH.h" #include "NReWeightNuXSecDIS.h" #include "NReWeightNuXSecNC.h" #include "NReWeightNuXSecNCEL.h" #include "NReWeightNuXSecNCRES.h" #include "NReWeightNuXSecRES.h" #include "NReWeightNuclPiless.h" #include "NSyst.h" #include "NSystUncertainty.h" #include "neutpart.h" #include "neutvect.h" #endif #ifdef __NUWRO_ENABLED__ #include "event1.h" #endif #ifdef __NUWRO_REWEIGHT_ENABLED__ #include "NuwroReWeight.h" #include "NuwroReWeight_FlagNorm.h" #include "NuwroReWeight_QEL.h" #include "NuwroReWeight_SPP.h" #include "NuwroSyst.h" #include "NuwroSystUncertainty.h" #endif #ifdef __GENIE_ENABLED__ -#include "EVGCore/EventRecord.h" +#ifdef GENIE_PRE_R3 #include "EVGCore/EventRecord.h" #include "GHEP/GHepRecord.h" -#include "GSyst.h" -#include "GSystUncertainty.h" #include "Ntuple/NtpMCEventRecord.h" #include "ReWeight/GReWeight.h" #include "ReWeight/GReWeightAGKY.h" #include "ReWeight/GReWeightDISNuclMod.h" #include "ReWeight/GReWeightFGM.h" #include "ReWeight/GReWeightFZone.h" #include "ReWeight/GReWeightINuke.h" #include "ReWeight/GReWeightNonResonanceBkg.h" #include "ReWeight/GReWeightNuXSecCCQE.h" #include "ReWeight/GReWeightNuXSecCCQEvec.h" #include "ReWeight/GReWeightNuXSecCCRES.h" #include "ReWeight/GReWeightNuXSecCOH.h" #include "ReWeight/GReWeightNuXSecDIS.h" #include "ReWeight/GReWeightNuXSecNC.h" #include "ReWeight/GReWeightNuXSecNCEL.h" #include "ReWeight/GReWeightNuXSecNCRES.h" #include "ReWeight/GReWeightResonanceDecay.h" +#include "ReWeight/GSyst.h" +#include "ReWeight/GSystUncertainty.h" +#else +#include "Framework/EventGen/EventRecord.h" +#include "Framework/GHEP/GHepRecord.h" +#include "Framework/Ntuple/NtpMCEventRecord.h" +#include "RwCalculators/GReWeightAGKY.h" +#include "RwCalculators/GReWeightDISNuclMod.h" +#include "RwCalculators/GReWeightFGM.h" +#include "RwCalculators/GReWeightFZone.h" +#include "RwCalculators/GReWeightINuke.h" +#include "RwCalculators/GReWeightNonResonanceBkg.h" +#include "RwCalculators/GReWeightNuXSecCCQE.h" +#include "RwCalculators/GReWeightNuXSecCCQEvec.h" +#include "RwCalculators/GReWeightNuXSecCCRES.h" +#include "RwCalculators/GReWeightNuXSecCOH.h" +#include "RwCalculators/GReWeightNuXSecDIS.h" +#include "RwCalculators/GReWeightNuXSecNC.h" +#include "RwCalculators/GReWeightNuXSecNCEL.h" +#include "RwCalculators/GReWeightNuXSecNCRES.h" +#include "RwCalculators/GReWeightResonanceDecay.h" +#include "RwFramework/GReWeight.h" +#include "RwFramework/GSyst.h" +#include "RwFramework/GSystUncertainty.h" +#endif using namespace genie; using namespace genie::rew; #endif +#ifdef __NOVA_ENABLED__ +#include "NOvARwgtEngine.h" +#endif + #include "GlobalDialList.h" #include "ModeNormEngine.h" #include "NUISANCESyst.h" #include "OscWeightEngine.h" //******************************************************************** TF1 FitBase::GetRWConvFunction(std::string const &type, std::string const &name) { //******************************************************************** std::string dialfunc = "x"; std::string parType = type; double low = -10000.0; double high = 10000.0; - if (parType.find("parameter") == std::string::npos) parType += "_parameter"; + if (parType.find("parameter") == std::string::npos) + parType += "_parameter"; std::string line; std::ifstream card( (GeneralUtils::GetTopLevelDir() + "/parameters/dial_conversion.card") .c_str(), std::ifstream::in); while (std::getline(card >> std::ws, line, '\n')) { std::vector inputlist = GeneralUtils::ParseToStr(line, " "); // Check the line length - if (inputlist.size() < 4) continue; + if (inputlist.size() < 4) + continue; // Check whether this is a comment - if (inputlist[0].c_str()[0] == '#') continue; + if (inputlist[0].c_str()[0] == '#') + continue; // Check whether this is the correct parameter type - if (inputlist[0].compare(parType) != 0) continue; + if (inputlist[0].compare(parType) != 0) + continue; // Check the parameter name - if (inputlist[1].compare(name) != 0) continue; + if (inputlist[1].compare(name) != 0) + continue; // inputlist[2] should be the units... ignore for now dialfunc = inputlist[3]; // High and low are optional, check whether they exist - if (inputlist.size() > 4) low = GeneralUtils::StrToDbl(inputlist[4]); - if (inputlist.size() > 5) high = GeneralUtils::StrToDbl(inputlist[5]); + if (inputlist.size() > 4) + low = GeneralUtils::StrToDbl(inputlist[4]); + if (inputlist.size() > 5) + high = GeneralUtils::StrToDbl(inputlist[5]); } TF1 convfunc = TF1((name + "_convfunc").c_str(), dialfunc.c_str(), low, high); return convfunc; } //******************************************************************** std::string FitBase::GetRWUnits(std::string const &type, std::string const &name) { //******************************************************************** std::string unit = "sig."; std::string parType = type; if (parType.find("parameter") == std::string::npos) { parType += "_parameter"; } std::string line; std::ifstream card( (GeneralUtils::GetTopLevelDir() + "/parameters/dial_conversion.card") .c_str(), std::ifstream::in); while (std::getline(card >> std::ws, line, '\n')) { std::vector inputlist = GeneralUtils::ParseToStr(line, " "); // Check the line length - if (inputlist.size() < 3) continue; + if (inputlist.size() < 3) + continue; // Check whether this is a comment - if (inputlist[0].c_str()[0] == '#') continue; + if (inputlist[0].c_str()[0] == '#') + continue; // Check whether this is the correct parameter type - if (inputlist[0].compare(parType) != 0) continue; + if (inputlist[0].compare(parType) != 0) + continue; // Check the parameter name - if (inputlist[1].compare(name) != 0) continue; + if (inputlist[1].compare(name) != 0) + continue; unit = inputlist[2]; break; } return unit; } //******************************************************************** double FitBase::RWAbsToSigma(std::string const &type, std::string const &name, double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.GetX(val); - if (fabs(conv_val) < 1E-10) conv_val = 0.0; + if (fabs(conv_val) < 1E-10) + conv_val = 0.0; QLOG(FIT, "AbsToSigma(" << name << ") = " << val << " -> " << conv_val); return conv_val; } //******************************************************************** double FitBase::RWSigmaToAbs(std::string const &type, std::string const &name, double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.Eval(val); return conv_val; } //******************************************************************** double FitBase::RWFracToSigma(std::string const &type, std::string const &name, double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.GetX((val * f1.Eval(0.0))); - if (fabs(conv_val) < 1E-10) conv_val = 0.0; + if (fabs(conv_val) < 1E-10) + conv_val = 0.0; return conv_val; } //******************************************************************** double FitBase::RWSigmaToFrac(std::string const &type, std::string const &name, double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.Eval(val) / f1.Eval(0.0); return conv_val; } int FitBase::ConvDialType(std::string const &type) { if (!type.compare("neut_parameter")) return kNEUT; else if (!type.compare("niwg_parameter")) return kNIWG; else if (!type.compare("nuwro_parameter")) return kNUWRO; else if (!type.compare("t2k_parameter")) return kT2K; else if (!type.compare("genie_parameter")) return kGENIE; else if (!type.compare("custom_parameter")) return kCUSTOM; else if (!type.compare("norm_parameter")) return kNORM; else if (!type.compare("likeweight_parameter")) return kLIKEWEIGHT; else if (!type.compare("spline_parameter")) return kSPLINEPARAMETER; else if (!type.compare("osc_parameter")) return kOSCILLATION; else if (!type.compare("modenorm_parameter")) return kMODENORM; + else if (!type.compare("nova_parameter")) + return kNOvARWGT; else return kUNKNOWN; } std::string FitBase::ConvDialType(int type) { switch (type) { - case kNEUT: { - return "neut_parameter"; - } - case kNIWG: { - return "niwg_parameter"; - } - case kNUWRO: { - return "nuwro_parameter"; - } - case kT2K: { - return "t2k_parameter"; - } - case kGENIE: { - return "genie_parameter"; - } - case kNORM: { - return "norm_parameter"; - } - case kCUSTOM: { - return "custom_parameter"; - } - case kLIKEWEIGHT: { - return "likeweight_parameter"; - } - case kSPLINEPARAMETER: { - return "spline_parameter"; - } - case kOSCILLATION: { - return "osc_parameter"; - } - case kMODENORM: { - return "modenorm_parameter"; - } - default: - return "unknown_parameter"; + case kNEUT: { + return "neut_parameter"; + } + case kNIWG: { + return "niwg_parameter"; + } + case kNUWRO: { + return "nuwro_parameter"; + } + case kT2K: { + return "t2k_parameter"; + } + case kGENIE: { + return "genie_parameter"; + } + case kNORM: { + return "norm_parameter"; + } + case kCUSTOM: { + return "custom_parameter"; + } + case kLIKEWEIGHT: { + return "likeweight_parameter"; + } + case kSPLINEPARAMETER: { + return "spline_parameter"; + } + case kOSCILLATION: { + return "osc_parameter"; + } + case kMODENORM: { + return "modenorm_parameter"; + } + case kNOvARWGT: { + return "nova_parameter"; + } + default: + return "unknown_parameter"; } } int FitBase::GetDialEnum(std::string const &type, std::string const &name) { return FitBase::GetDialEnum(FitBase::ConvDialType(type), name); } int FitBase::GetDialEnum(int type, std::string const &name) { int offset = type * 1000; - int this_enum = Reweight::kNoDialFound; // Not Found + int this_enum = Reweight::kNoDialFound; // Not Found QLOG(DEB, "Getting dial enum " << type << " " << name); // Select Types switch (type) { - // NEUT DIAL TYPE - case kNEUT: { + // NEUT DIAL TYPE + case kNEUT: { #ifdef __NEUT_ENABLED__ - int neut_enum = (int)neut::rew::NSyst::FromString(name); - if (neut_enum != 0) { - this_enum = neut_enum + offset; - } + int neut_enum = (int)neut::rew::NSyst::FromString(name); + if (neut_enum != 0) { + this_enum = neut_enum + offset; + } #else - this_enum = Reweight::kNoTypeFound; // Not enabled + this_enum = Reweight::kNoTypeFound; // Not enabled #endif - break; - } + break; + } - // NIWG DIAL TYPE - case kNIWG: { + // NIWG DIAL TYPE + case kNIWG: { #ifdef __NIWG_ENABLED__ - int niwg_enum = (int)niwg::rew::NIWGSyst::FromString(name); - if (niwg_enum != 0) { - this_enum = niwg_enum + offset; - } + int niwg_enum = (int)niwg::rew::NIWGSyst::FromString(name); + if (niwg_enum != 0) { + this_enum = niwg_enum + offset; + } #else - this_enum = Reweight::kNoTypeFound; + this_enum = Reweight::kNoTypeFound; #endif - break; - } + break; + } - // NUWRO DIAL TYPE - case kNUWRO: { + // NUWRO DIAL TYPE + case kNUWRO: { #ifdef __NUWRO_REWEIGHT_ENABLED__ - int nuwro_enum = (int)nuwro::rew::NuwroSyst::FromString(name); - if (nuwro_enum > 0) { - this_enum = nuwro_enum + offset; - } + int nuwro_enum = (int)nuwro::rew::NuwroSyst::FromString(name); + if (nuwro_enum > 0) { + this_enum = nuwro_enum + offset; + } #else - this_enum = Reweight::kNoTypeFound; + this_enum = Reweight::kNoTypeFound; #endif - } + } - // GENIE DIAL TYPE - case kGENIE: { + // GENIE DIAL TYPE + case kGENIE: { #ifdef __GENIE_ENABLED__ - int genie_enum = (int)genie::rew::GSyst::FromString(name); - if (genie_enum > 0) { - this_enum = genie_enum + offset; - } + int genie_enum = (int)genie::rew::GSyst::FromString(name); + if (genie_enum > 0) { + this_enum = genie_enum + offset; + } #else - this_enum = Reweight::kNoTypeFound; + this_enum = Reweight::kNoTypeFound; #endif - break; - } + break; + } - case kCUSTOM: { - int custom_enum = 0; // PLACEHOLDER - this_enum = custom_enum + offset; - break; - } + case kCUSTOM: { + int custom_enum = 0; // PLACEHOLDER + this_enum = custom_enum + offset; + break; + } - // T2K DIAL TYPE - case kT2K: { + // T2K DIAL TYPE + case kT2K: { #ifdef __T2KREW_ENABLED__ - int t2k_enum = (int)t2krew::T2KSyst::FromString(name); - if (t2k_enum > 0) { - this_enum = t2k_enum + offset; - } + int t2k_enum = (int)t2krew::T2KSyst::FromString(name); + if (t2k_enum > 0) { + this_enum = t2k_enum + offset; + } #else - this_enum = Reweight::kNoTypeFound; + this_enum = Reweight::kNoTypeFound; #endif - break; - } + break; + } - case kNORM: { - if (gNormEnums.find(name) == gNormEnums.end()) { - gNormEnums[name] = gNormEnums.size() + 1 + offset; - } - this_enum = gNormEnums[name]; - break; + case kNORM: { + if (gNormEnums.find(name) == gNormEnums.end()) { + gNormEnums[name] = gNormEnums.size() + 1 + offset; } + this_enum = gNormEnums[name]; + break; + } - case kLIKEWEIGHT: { - if (gLikeWeightEnums.find(name) == gLikeWeightEnums.end()) { - gLikeWeightEnums[name] = gLikeWeightEnums.size() + 1 + offset; - } - this_enum = gLikeWeightEnums[name]; - break; + case kLIKEWEIGHT: { + if (gLikeWeightEnums.find(name) == gLikeWeightEnums.end()) { + gLikeWeightEnums[name] = gLikeWeightEnums.size() + 1 + offset; } + this_enum = gLikeWeightEnums[name]; + break; + } - case kSPLINEPARAMETER: { - if (gSplineParameterEnums.find(name) == gSplineParameterEnums.end()) { - gSplineParameterEnums[name] = gSplineParameterEnums.size() + 1 + offset; - } - this_enum = gSplineParameterEnums[name]; - break; + case kSPLINEPARAMETER: { + if (gSplineParameterEnums.find(name) == gSplineParameterEnums.end()) { + gSplineParameterEnums[name] = gSplineParameterEnums.size() + 1 + offset; } - case kOSCILLATION: { + this_enum = gSplineParameterEnums[name]; + break; + } + case kOSCILLATION: { #ifdef __PROB3PP_ENABLED__ - int oscEnum = OscWeightEngine::SystEnumFromString(name); - if (oscEnum != 0) { - this_enum = oscEnum + offset; - } + int oscEnum = OscWeightEngine::SystEnumFromString(name); + if (oscEnum != 0) { + this_enum = oscEnum + offset; + } #else - this_enum = Reweight::kNoTypeFound; // Not enabled + this_enum = Reweight::kNoTypeFound; // Not enabled #endif + } + case kMODENORM: { + size_t us_pos = name.find_first_of('_'); + std::string numstr = name.substr(us_pos + 1); + int mode_num = std::atoi(numstr.c_str()); + LOG(FTL) << "Getting mode num " << mode_num << std::endl; + if (!mode_num) { + ERR(FTL) << "Attempting to parse dial name: \"" << name + << "\" as a mode norm dial but failed." << std::endl; + throw; } - case kMODENORM: { - size_t us_pos = name.find_first_of('_'); - std::string numstr = name.substr(us_pos + 1); - int mode_num = std::atoi(numstr.c_str()); - LOG(FTL) << "Getting mode num " << mode_num << std::endl; - if (!mode_num) { - ERR(FTL) << "Attempting to parse dial name: \"" << name - << "\" as a mode norm dial but failed." << std::endl; - throw; - } - this_enum = 60 + mode_num + offset; - break; - } + this_enum = 60 + mode_num + offset; + break; + } } // If Not Enabled if (this_enum == Reweight::kNoTypeFound) { ERR(FTL) << "RW Engine not supported for " << FitBase::ConvDialType(type) << std::endl; ERR(FTL) << "Check dial " << name << std::endl; } // If Not Found if (this_enum == Reweight::kNoDialFound) { ERR(FTL) << "Dial " << name << " not found." << std::endl; } return this_enum; } int Reweight::ConvDialType(std::string const &type) { return FitBase::ConvDialType(type); } std::string Reweight::ConvDialType(int type) { return FitBase::ConvDialType(type); } int Reweight::GetDialType(int type) { int t = (type / 1000); return t > kMODENORM ? Reweight::kNoDialFound : t; } int Reweight::RemoveDialType(int type) { return (type % 1000); } int Reweight::NEUTEnumFromName(std::string const &name) { #ifdef __NEUT_ENABLED__ int neutenum = (int)neut::rew::NSyst::FromString(name); return (neutenum > 0) ? neutenum : Reweight::kNoDialFound; #else return Reweight::kGeneratorNotBuilt; #endif } int Reweight::NIWGEnumFromName(std::string const &name) { #ifdef __NIWG_ENABLED__ int niwgenum = (int)niwg::rew::NIWGSyst::FromString(name); return (niwgenum != 0) ? niwgenum : Reweight::kNoDialFound; #else return Reweight::kGeneratorNotBuilt; #endif } int Reweight::NUWROEnumFromName(std::string const &name) { #ifdef __NUWRO_REWEIGHT_ENABLED__ int nuwroenum = (int)nuwro::rew::NuwroSyst::FromString(name); return (nuwroenum > 0) ? nuwroenum : Reweight::kNoDialFound; #else return Reweight::kGeneratorNotBuilt; #endif } int Reweight::GENIEEnumFromName(std::string const &name) { #ifdef __GENIE_ENABLED__ int genieenum = (int)genie::rew::GSyst::FromString(name); return (genieenum > 0) ? genieenum : Reweight::kNoDialFound; #else return Reweight::kGeneratorNotBuilt; #endif } int Reweight::T2KEnumFromName(std::string const &name) { #ifdef __T2KREW_ENABLED__ int t2kenum = (int)t2krew::T2KSyst::FromString(name); return (t2kenum > 0) ? t2kenum : Reweight::kNoDialFound; #else return Reweight::kGeneratorNotBuilt; #endif } int Reweight::OscillationEnumFromName(std::string const &name) { #ifdef __PROB3PP_ENABLED__ int oscEnum = OscWeightEngine::SystEnumFromString(name); return (oscEnum > 0) ? oscEnum : Reweight::kNoDialFound; #else return Reweight::kGeneratorNotBuilt; #endif } int Reweight::NUISANCEEnumFromName(std::string const &name, int type) { int nuisenum = Reweight::DialList().EnumFromNameAndType(name, type); return nuisenum; } int Reweight::CustomEnumFromName(std::string const &name) { int custenum = Reweight::ConvertNUISANCEDial(name); return custenum; } int Reweight::ConvDial(std::string const &name, std::string const &type, bool exceptions) { return Reweight::ConvDial(name, Reweight::ConvDialType(type), exceptions); } int Reweight::ConvDial(std::string const &fullname, int type, bool exceptions) { std::string name = - GeneralUtils::ParseToStr(fullname, ",")[0]; // Only use first dial given + GeneralUtils::ParseToStr(fullname, ",")[0]; // Only use first dial given // Produce offset seperating each type. int offset = type * 1000; int genenum = Reweight::kNoDialFound; switch (type) { - case kNEUT: - genenum = NEUTEnumFromName(name); - break; - - case kNIWG: - genenum = NIWGEnumFromName(name); - break; - - case kNUWRO: - genenum = NUWROEnumFromName(name); - break; - - case kGENIE: - genenum = GENIEEnumFromName(name); - break; - - case kT2K: - genenum = T2KEnumFromName(name); - break; - - case kCUSTOM: - genenum = CustomEnumFromName(name); - break; - - case kNORM: - case kLIKEWEIGHT: - case kSPLINEPARAMETER: - case kNEWSPLINE: - genenum = NUISANCEEnumFromName(name, type); - break; - - case kOSCILLATION: - genenum = OscillationEnumFromName(name); - break; - - case kMODENORM: - genenum = ModeNormEngine::SystEnumFromString(name); - break; - - default: - genenum = Reweight::kNoTypeFound; - break; + case kNEUT: + genenum = NEUTEnumFromName(name); + break; + + case kNIWG: + genenum = NIWGEnumFromName(name); + break; + + case kNUWRO: + genenum = NUWROEnumFromName(name); + break; + + case kGENIE: + genenum = GENIEEnumFromName(name); + break; + + case kT2K: + genenum = T2KEnumFromName(name); + break; + + case kCUSTOM: + genenum = CustomEnumFromName(name); + break; + + case kNORM: + case kLIKEWEIGHT: + case kSPLINEPARAMETER: + case kNEWSPLINE: + genenum = NUISANCEEnumFromName(name, type); + break; + + case kOSCILLATION: + genenum = OscillationEnumFromName(name); + break; + + case kMODENORM: + genenum = ModeNormEngine::SystEnumFromString(name); + break; + +#ifdef __NOVA_ENABLED__ + case kNOvARWGT: + genenum = NOvARwgtEngine::GetWeightGeneratorIndex(name); + break; +#endif + + default: + genenum = Reweight::kNoTypeFound; + break; } // Throw if required. if (exceptions) { // If Not Enabled if (genenum == Reweight::kGeneratorNotBuilt) { ERR(FTL) << "RW Engine not supported for " << FitBase::ConvDialType(type) << std::endl; ERR(FTL) << "Check dial " << name << std::endl; throw; } // If no type enabled if (genenum == Reweight::kNoTypeFound) { ERR(FTL) << "Type mismatch inside ConvDialEnum" << std::endl; throw; } // If Not Found if (genenum == Reweight::kNoDialFound) { ERR(FTL) << "Dial " << name << " not found." << std::endl; throw; } } // Add offset if no issue int nuisenum = genenum; if ((genenum != Reweight::kGeneratorNotBuilt) && (genenum != Reweight::kNoTypeFound) && (genenum != Reweight::kNoDialFound)) { nuisenum += offset; } // Now register dial Reweight::DialList().RegisterDialEnum(name, type, nuisenum); return nuisenum; } std::string Reweight::ConvDial(int nuisenum) { for (size_t i = 0; i < Reweight::DialList().fAllDialEnums.size(); i++) { if (Reweight::DialList().fAllDialEnums[i] == nuisenum) { return Reweight::DialList().fAllDialNames[i]; } } LOG(FIT) << "Cannot find dial with enum = " << nuisenum << std::endl; return ""; } diff --git a/src/Reweight/WeightUtils.h b/src/Reweight/WeightUtils.h index c7b044f..4af1a2d 100644 --- a/src/Reweight/WeightUtils.h +++ b/src/Reweight/WeightUtils.h @@ -1,63 +1,64 @@ #ifndef WEIGHTUTILS_H #define WEIGHTUTILS_H #include "FitEvent.h" #include "TF1.h" enum extra_reweight_types { kOSCILLATION = kLast_generator_event_type, - kMODENORM + kMODENORM, + kNOvARWGT }; namespace FitBase { TF1 GetRWConvFunction(std::string const &type, std::string const &name); std::string GetRWUnits(std::string const &type, std::string const &name); double RWSigmaToFrac(std::string const &type, std::string const &name, double val); double RWSigmaToAbs(std::string const &type, std::string const &name, double val); double RWAbsToSigma(std::string const &type, std::string const &name, double val); double RWFracToSigma(std::string const &type, std::string const &name, double val); int ConvDialType(std::string const &type); std::string ConvDialType(int type); int GetDialEnum(std::string const &type, std::string const &name); int GetDialEnum(int type, std::string const &name); static std::map gNormEnums; static std::map gLikeWeightEnums; static std::map gSplineParameterEnums; } namespace Reweight { int ConvDial(std::string const &name, std::string const &type, bool exceptions = false); int ConvDial(std::string const &name, int type, bool exceptions = false); std::string ConvDial(int nuisenum); int ConvDialType(std::string const &type); std::string ConvDialType(int type); int GetDialType(int type); int RemoveDialType(int type); int NEUTEnumFromName(std::string const &name); int NIWGEnumFromName(std::string const &name); int NUWROEnumFromName(std::string const &name); int T2KEnumFromName(std::string const &name); int GENIEEnumFromName(std::string const &name); int CustomEnumFromName(std::string const &name); int NUISANCEEnumFromName(std::string const &name, int type); int OscillationEnumFromName(std::string const &name); static const int kNoDialFound = -1; static const int kNoTypeFound = -2; static const int kGeneratorNotBuilt = -3; } #endif diff --git a/src/Routines/ComparisonRoutines.cxx b/src/Routines/ComparisonRoutines.cxx index 1f4f7bb..a4adcd6 100755 --- a/src/Routines/ComparisonRoutines.cxx +++ b/src/Routines/ComparisonRoutines.cxx @@ -1,532 +1,531 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "ComparisonRoutines.h" /* Constructor/Destructor */ //************************ void ComparisonRoutines::Init() { //************************ fOutputFile = ""; fOutputRootFile = NULL; fStrategy = "Compare"; fRoutines.clear(); fCardFile = ""; fFakeDataInput = ""; fSampleFCN = NULL; fAllowedRoutines = ("Compare"); }; //************************************* ComparisonRoutines::~ComparisonRoutines() { //************************************* +delete fOutputRootFile; }; /* Input Functions */ //************************************* ComparisonRoutines::ComparisonRoutines(int argc, char* argv[]) { //************************************* // Initialise Defaults Init(); nuisconfig configuration = Config::Get(); // Default containers std::string cardfile = ""; std::string maxevents = "-1"; int errorcount = 0; int verbocount = 0; std::vector xmlcmds; std::vector configargs; // Make easier to handle arguments. std::vector args = GeneralUtils::LoadCharToVectStr(argc, argv); ParserUtils::ParseArgument(args, "-c", fCardFile, true); ParserUtils::ParseArgument(args, "-o", fOutputFile, false, false); ParserUtils::ParseArgument(args, "-n", maxevents, false, false); ParserUtils::ParseArgument(args, "-f", fStrategy, false, false); ParserUtils::ParseArgument(args, "-d", fFakeDataInput, false, false); ParserUtils::ParseArgument(args, "-i", xmlcmds); ParserUtils::ParseArgument(args, "-q", configargs); ParserUtils::ParseCounter(args, "e", errorcount); ParserUtils::ParseCounter(args, "v", verbocount); ParserUtils::CheckBadArguments(args); // Add extra defaults if none given if (fCardFile.empty() and xmlcmds.empty()) { ERR(FTL) << "No input supplied!" << std::endl; throw; } if (fOutputFile.empty() and !fCardFile.empty()) { fOutputFile = fCardFile + ".root"; ERR(WRN) << "No output supplied so saving it to: " << fOutputFile << std::endl; } else if (fOutputFile.empty()) { ERR(FTL) << "No output file or cardfile supplied!" << std::endl; throw; } // Configuration Setup ============================= // Check no comp key is available nuiskey fCompKey; if (Config::Get().GetNodes("nuiscomp").empty()) { fCompKey = Config::Get().CreateNode("nuiscomp"); } else { fCompKey = Config::Get().GetNodes("nuiscomp")[0]; } if (!fCardFile.empty()) fCompKey.Set("cardfile", fCardFile); if (!fOutputFile.empty()) fCompKey.Set("outputfile", fOutputFile); if (!fStrategy.empty()) fCompKey.Set("strategy", fStrategy); // Load XML Cardfile configuration.LoadSettings( fCompKey.GetS("cardfile"), ""); // Add Config Args for (size_t i = 0; i < configargs.size(); i++) { configuration.OverrideConfig(configargs[i]); } if (maxevents.compare("-1")){ configuration.OverrideConfig("MAXEVENTS=" + maxevents); } // Finish configuration XML configuration.FinaliseSettings(fCompKey.GetS("outputfile") + ".xml"); // Add Error Verbo Lines verbocount += Config::GetParI("VERBOSITY"); errorcount += Config::GetParI("ERROR"); bool trace = Config::GetParB("TRACE"); std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl; std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl; SETVERBOSITY(verbocount); SETTRACE(trace); // Comparison Setup ======================================== // Proper Setup fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); SetupComparisonsFromXML(); SetupRWEngine(); SetupFCN(); return; }; //************************************* void ComparisonRoutines::SetupComparisonsFromXML() { //************************************* LOG(FIT) << "Setting up nuiscomp" << std::endl; // Setup Parameters ------------------------------------------ std::vector parkeys = Config::QueryKeys("parameter"); if (!parkeys.empty()) { LOG(FIT) << "Number of parameters : " << parkeys.size() << std::endl; } for (size_t i = 0; i < parkeys.size(); i++) { nuiskey key = parkeys.at(i); // Check for type,name,nom if (!key.Has("type")) { ERR(FTL) << "No type given for parameter " << i << std::endl; ERR(FTL) << "type='PARAMETER_TYPE'" << std::endl; throw; } else if (!key.Has("name")) { ERR(FTL) << "No name given for parameter " << i << std::endl; ERR(FTL) << "name='SAMPLE_NAME'" << std::endl; throw; } else if (!key.Has("nominal")) { ERR(FTL) << "No nominal given for parameter " << i << std::endl; ERR(FTL) << "nominal='NOMINAL_VALUE'" << std::endl; throw; } // Get Inputs std::string partype = key.GetS("type"); std::string parname = key.GetS("name"); double parnom = key.GetD("nominal"); double parlow = parnom - 1; double parhigh = parnom + 1; double parstep = 1; // override if state not given if (!key.Has("state")){ key.SetS("state","FIX"); } std::string parstate = key.GetS("state"); // Check for incomplete limtis int limdef = ((int)key.Has("low") + (int)key.Has("high") + (int)key.Has("step")); if (limdef > 0 and limdef < 3){ ERR(FTL) << "Incomplete limit set given for parameter : " << parname << std::endl; ERR(FTL) << "Requires: low='LOWER_LIMIT' high='UPPER_LIMIT' step='STEP_SIZE' " << std::endl; throw; } // Extra limits if (key.Has("low")) { parlow = key.GetD("low"); parhigh = key.GetD("high"); parstep = key.GetD("step"); LOG(FIT) << "Read " << partype << " : " << parname << " = " << parnom << " : " << parlow << " < p < " << parhigh << " : " << parstate << std::endl; } else { LOG(FIT) << "Read " << partype << " : " << parname << " = " << parnom << " : " << parstate << std::endl; } // Convert if required if (parstate.find("ABS") != std::string::npos) { parnom = FitBase::RWAbsToSigma( partype, parname, parnom ); parlow = FitBase::RWAbsToSigma( partype, parname, parlow ); parhigh = FitBase::RWAbsToSigma( partype, parname, parhigh ); parstep = FitBase::RWAbsToSigma( partype, parname, parstep ); } else if (parstate.find("FRAC") != std::string::npos) { parnom = FitBase::RWFracToSigma( partype, parname, parnom ); parlow = FitBase::RWFracToSigma( partype, parname, parlow ); parhigh = FitBase::RWFracToSigma( partype, parname, parhigh ); parstep = FitBase::RWFracToSigma( partype, parname, parstep ); } // Push into vectors fParams.push_back(parname); fTypeVals[parname] = FitBase::ConvDialType(partype);; fCurVals[parname] = parnom; fStateVals[parname] = parstate; } // Setup Samples ---------------------------------------------- std::vector samplekeys = Config::QueryKeys("sample"); if (!samplekeys.empty()) { LOG(FIT) << "Number of samples : " << samplekeys.size() << std::endl; } for (size_t i = 0; i < samplekeys.size(); i++) { nuiskey key = samplekeys.at(i); // Get Sample Options std::string samplename = key.GetS("name"); std::string samplefile = key.GetS("input"); std::string sampletype = key.Has("type") ? key.GetS("type") : "DEFAULT"; double samplenorm = key.Has("norm") ? key.GetD("norm") : 1.0; // Print out LOG(FIT) << "Read Sample " << i << ". : " << samplename << " (" << sampletype << ") [Norm=" << samplenorm<<"]"<< std::endl << " -> input='" << samplefile << "'" << std::endl; // If FREE add to parameters otherwise continue if (sampletype.find("FREE") == std::string::npos) { continue; } // Form norm dial from samplename + sampletype + "_norm"; std::string normname = samplename + "_norm"; // Check normname not already present if (fTypeVals.find("normname") != fTypeVals.end()) { continue; } // Add new norm dial to list if its passed above checks fParams.push_back(normname); fTypeVals[normname] = kNORM; fStateVals[normname] = sampletype; fCurVals[normname] = samplenorm; } // Setup Fake Parameters ----------------------------- std::vector fakekeys = Config::QueryKeys("fakeparameter"); if (!fakekeys.empty()) { LOG(FIT) << "Number of fake parameters : " << fakekeys.size() << std::endl; } for (size_t i = 0; i < fakekeys.size(); i++) { nuiskey key = fakekeys.at(i); // Check for type,name,nom if (!key.Has("name")) { ERR(FTL) << "No name given for fakeparameter " << i << std::endl; throw; } else if (!key.Has("nominal")) { ERR(FTL) << "No nominal given for fakeparameter " << i << std::endl; throw; } // Get Inputs std::string parname = key.GetS("name"); double parnom = key.GetD("nominal"); // Push into vectors fFakeVals[parname] = parnom; } } //************************************* void ComparisonRoutines::SetupRWEngine() { //************************************* LOG(FIT) << "Setting up FitWeight Engine" << std::endl; for (UInt_t i = 0; i < fParams.size(); i++) { std::string name = fParams[i]; FitBase::GetRW()->IncludeDial(name, fTypeVals.at(name)); } return; } //************************************* void ComparisonRoutines::SetupFCN() { //************************************* LOG(FIT) << "Building the SampleFCN" << std::endl; if (fSampleFCN) delete fSampleFCN; Config::Get().out = fOutputRootFile; fOutputRootFile->cd(); fSampleFCN = new JointFCN(fOutputRootFile); SetFakeData(); return; } //************************************* void ComparisonRoutines::SetFakeData() { //************************************* if (fFakeDataInput.empty()) return; if (fFakeDataInput.compare("MC") == 0) { LOG(FIT) << "Setting fake data from MC starting prediction." << std::endl; UpdateRWEngine(fFakeVals); FitBase::GetRW()->Reconfigure(); fSampleFCN->ReconfigureAllEvents(); fSampleFCN->SetFakeData("MC"); UpdateRWEngine(fCurVals); LOG(FIT) << "Set all data to fake MC predictions." << std::endl; } else { LOG(FIT) << "Setting fake data from: " << fFakeDataInput << std::endl; fSampleFCN->SetFakeData(fFakeDataInput); } return; } /* Fitting Functions */ //************************************* void ComparisonRoutines::UpdateRWEngine( std::map& updateVals) { //************************************* for (UInt_t i = 0; i < fParams.size(); i++) { std::string name = fParams[i]; if (updateVals.find(name) == updateVals.end()) continue; FitBase::GetRW()->SetDialValue(name, updateVals.at(name)); } FitBase::GetRW()->Reconfigure(); return; } //************************************* void ComparisonRoutines::Run() { //************************************* LOG(FIT) << "Running ComparisonRoutines : " << fStrategy << std::endl; if (FitPar::Config().GetParB("save_nominal")) { SaveNominal(); } // Parse given routines fRoutines = GeneralUtils::ParseToStr(fStrategy, ","); if (fRoutines.empty()) { ERR(FTL) << "Trying to run ComparisonRoutines with no routines given!" << std::endl; throw; } for (UInt_t i = 0; i < fRoutines.size(); i++) { std::string routine = fRoutines.at(i); LOG(FIT) << "Routine: " << routine << std::endl; if (!routine.compare("Compare")) { UpdateRWEngine(fCurVals); GenerateComparison(); PrintState(); SaveCurrentState(); } } return; } //************************************* void ComparisonRoutines::GenerateComparison() { //************************************* LOG(FIT) << "Generating Comparison." << std::endl; // Main Event Loop from event Manager fSampleFCN->ReconfigureAllEvents(); return; } //************************************* void ComparisonRoutines::PrintState() { //************************************* LOG(FIT) << "------------" << std::endl; // Count max size int maxcount = 0; for (UInt_t i = 0; i < fParams.size(); i++) { maxcount = max(int(fParams[i].size()), maxcount); } // Header LOG(FIT) << " # " << left << setw(maxcount) << "Parameter " << " = " << setw(10) << "Value" << " +- " << setw(10) << "Error" << " " << setw(8) << "(Units)" << " " << setw(10) << "Conv. Val" << " +- " << setw(10) << "Conv. Err" << " " << setw(8) << "(Units)" << std::endl; // Parameters for (UInt_t i = 0; i < fParams.size(); i++) { std::string syst = fParams.at(i); std::string typestr = FitBase::ConvDialType(fTypeVals[syst]); std::string curunits = "(sig.)"; double curval = fCurVals[syst]; double curerr = 0.0; if (fStateVals[syst].find("ABS") != std::string::npos) { curval = FitBase::RWSigmaToAbs(typestr, syst, curval); curerr = (FitBase::RWSigmaToAbs(typestr, syst, curerr) - FitBase::RWSigmaToAbs(typestr, syst, 0.0)); curunits = "(Abs.)"; } else if (fStateVals[syst].find("FRAC") != std::string::npos) { curval = FitBase::RWSigmaToFrac(typestr, syst, curval); curerr = (FitBase::RWSigmaToFrac(typestr, syst, curerr) - FitBase::RWSigmaToFrac(typestr, syst, 0.0)); curunits = "(Frac)"; } std::string convunits = "(" + FitBase::GetRWUnits(typestr, syst) + ")"; double convval = FitBase::RWSigmaToAbs(typestr, syst, curval); double converr = (FitBase::RWSigmaToAbs(typestr, syst, curerr) - FitBase::RWSigmaToAbs(typestr, syst, 0.0)); std::ostringstream curparstring; curparstring << " " << setw(3) << left << i << ". " << setw(maxcount) << syst << " = " << setw(10) << curval << " +- " << setw(10) << curerr << " " << setw(8) << curunits << " " << setw(10) << convval << " +- " << setw(10) << converr << " " << setw(8) << convunits; LOG(FIT) << curparstring.str() << std::endl; } LOG(FIT) << "------------" << std::endl; double like = fSampleFCN->GetLikelihood(); LOG(FIT) << std::left << std::setw(46) << "Likelihood for JointFCN: " << like << std::endl; LOG(FIT) << "------------" << std::endl; } /* Write Functions */ //************************************* void ComparisonRoutines::SaveCurrentState(std::string subdir) { //************************************* LOG(FIT) << "Saving current full FCN predictions" << std::endl; // Setup DIRS TDirectory* curdir = gDirectory; if (!subdir.empty()) { TDirectory* newdir = (TDirectory*)gDirectory->mkdir(subdir.c_str()); newdir->cd(); } fSampleFCN->Write(); // Change back to current DIR curdir->cd(); return; } //************************************* void ComparisonRoutines::SaveNominal() { //************************************* fOutputRootFile->cd(); LOG(FIT) << "Saving Nominal Predictions (be cautious with this)" << std::endl; FitBase::GetRW()->Reconfigure(); GenerateComparison(); SaveCurrentState("nominal"); }; - - diff --git a/src/SciBooNE/SciBooNEUtils.cxx b/src/SciBooNE/SciBooNEUtils.cxx index a1183ad..635c31e 100644 --- a/src/SciBooNE/SciBooNEUtils.cxx +++ b/src/SciBooNE/SciBooNEUtils.cxx @@ -1,570 +1,565 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "SciBooNEUtils.h" #include "FitUtils.h" double SciBooNEUtils::GetSciBarDensity(){ static double density = 0xdeadbeef; if (density == 0xdeadbeef){ density = FitPar::Config().GetParD("SciBarDensity"); } return density; } double SciBooNEUtils::GetSciBarRecoDist(){ static double dist = 0xdeadbeef; if (dist == 0xdeadbeef){ dist = FitPar::Config().GetParD("SciBarRecoDist"); } return dist; } double SciBooNEUtils::GetPenetratingMuonE(){ static double mue = 0xdeadbeef; if (mue == 0xdeadbeef){ mue = FitPar::Config().GetParD("PenetratingMuonEnergy"); } return mue; } // Replacs with a function to draw from the z distribution that Zach made, and require the pion goes further. // Ignores correlation between angle and distance, but... nevermind double SciBooNEUtils::GetMainPionRange(){ static TF1 *func = new TF1("f1", "250 - (2./3.)*(x-10)", 10, 160); return func->GetRandom(); } int SciBooNEUtils::GetNumRangeSteps(){ static uint nsteps = 0xdeadbeef; if (nsteps == 0xdeadbeef){ nsteps = FitPar::Config().GetParI("NumRangeSteps"); } return nsteps; } bool SciBooNEUtils::GetUseProton(){ static bool isSet = false; static bool usep = false; if (!isSet){ usep = FitPar::Config().GetParB("UseProton"); isSet = true; } return usep; } bool SciBooNEUtils::GetUseZackEff(){ static bool isSet = false; static bool use = false; if (!isSet){ use = FitPar::Config().GetParB("UseZackEff"); isSet = true; } return use; } double SciBooNEUtils::GetFlatEfficiency(){ static double var = 0xdeadbeef; if (var == 0xdeadbeef){ var = FitPar::Config().GetParD("FlatEfficiency"); } return var; } // Obtained from a simple fit to test beam data 1 < p < 2 GeV double SciBooNEUtils::ProtonMisIDProb(double mom){ return 0.1; double prob = 0.10; if (mom < 1) return prob; if (mom > 2) mom = 2; prob = -2.83 + 3.75*mom - 0.96*mom*mom; if (prob < 0.10) prob = 0.10; return prob; } // This function uses pion-scintillator cross sections to calculate the pion SI probability double SciBooNEUtils::PionReinteractionProb(double energy, double thickness){ static TGraph *total_xsec = 0; static TGraph *inel_xsec = 0; if (!total_xsec){ total_xsec = PlotUtils::GetTGraphFromRootFile(FitPar::GetDataBase()+"/SciBooNE/cross_section_pion_scintillator_hd.root", "totalXS"); } if (!inel_xsec){ inel_xsec = PlotUtils::GetTGraphFromRootFile(FitPar::GetDataBase()+"/SciBooNE/cross_section_pion_scintillator_hd.root", "inelXS"); } if (total_xsec->Eval(energy) == 0) return 0; double total = total_xsec->Eval(energy)*1E-27; double inel = inel_xsec->Eval(energy)*1E-27; double prob = (1 - exp(-thickness*SciBooNEUtils::GetSciBarDensity()*4.63242e+22*total))*(inel/total); return prob; } bool SciBooNEUtils::ThrowAcceptReject(double test_value, double ceiling){ static TRandom3 *rand = 0; if (!rand){ rand = new TRandom3(0); } double throw_value = rand->Uniform(ceiling); if (throw_value < test_value) return false; return true; } double SciBooNEUtils::StoppedEfficiency(TH2D *effHist, FitParticle *nu, FitParticle *muon){ double eff = 0.; if (!effHist) return eff; // For Morgan's efficiencies if (!SciBooNEUtils::GetUseZackEff()) eff = effHist->GetBinContent(effHist->GetXaxis()->FindBin(FitUtils::p(muon)), effHist->GetYaxis()->FindBin(FitUtils::th(nu, muon)/TMath::Pi()*180.)); // For Zack's efficiencies else eff = effHist->GetBinContent(effHist->GetXaxis()->FindBin(FitUtils::th(nu, muon)/TMath::Pi()*180.), effHist->GetYaxis()->FindBin(FitUtils::p(muon)*1000.)); return eff; } double SciBooNEUtils::ProtonEfficiency(TH2D *effHist, FitParticle *nu, FitParticle *muon){ double eff = 0.; if (!effHist) return eff; eff = effHist->GetBinContent(effHist->GetXaxis()->FindBin(FitUtils::th(nu, muon)/TMath::Pi()*180.), effHist->GetYaxis()->FindBin(FitUtils::p(muon)*1000.)); return eff; } double SciBooNEUtils::PenetratedEfficiency(FitParticle *nu, FitParticle *muon){ double eff = 0.; if (FitUtils::th(nu, muon)/TMath::Pi()*180. > 50) eff = 0.; if (FitUtils::p(muon) < SciBooNEUtils::GetPenetratingMuonE()) eff = 0.; return eff; } double SciBooNEUtils::BetheBlochCH(double E, double mass){ double beta2 = 1 - mass*mass/E/E; double gamma = 1./sqrt(1-beta2); double mass_ratio = PhysConst::mass_electron*1000./mass; // Argh, have to remember to convert to MeV or you'll hate yourself! double I2 = 68.7e-6*68.7e-6; double w_max = 2*PhysConst::mass_electron*1000.*beta2*gamma*gamma; w_max /= 1 + 2*gamma*mass_ratio + mass_ratio*mass_ratio; // Values taken from the PDG for K = 0.307075 MeV mol-1 cm2, mean ionization energy I = 68.7 eV (Polystyrene) // = 0.53768 (pdg.lbl.gov/AtomicNuclearProperties) double log_term = log(2*PhysConst::mass_electron*1000.*beta2*gamma*gamma*w_max/I2); double dedx = 0.307075*0.53768/beta2*(0.5*log_term - beta2); return dedx; } // This function returns an estimate of the range of the particle in scintillator. // It uses crude integration and Bethe-Bloch to approximate the range. double SciBooNEUtils::RangeInScintillator(FitParticle* particle, int nsteps){ // The particle energy double E = particle->fP.E(); double M = particle->fP.M(); double Ek = E - M; double step_size = Ek/float(nsteps+1); double range = 0; // Add an offset to make the integral a touch more accurate Ek -= step_size/2.; for (int i = 0; i < nsteps; ++i){ double dEdx = SciBooNEUtils::BetheBlochCH(Ek+M, M); Ek -= step_size; // dEdx is -ve range -= step_size/dEdx; // If the particle is a pion. Also consider the reinteraction probability if (abs(particle->fPID) == 211){ double prob = SciBooNEUtils::PionReinteractionProb(Ek, step_size/dEdx/SciBooNEUtils::GetSciBarDensity()); if (!SciBooNEUtils::ThrowAcceptReject(prob)) break; } } // Account for density of polystyrene range /= SciBooNEUtils::GetSciBarDensity(); // Range estimate is in cm return range; } // Function to calculate the distance the particle travels in scintillator bool SciBooNEUtils::PassesDistanceCut(FitParticle* beam, FitParticle* particle){ // First apply some basic thresholds (from K2K SciBar description) if (FitUtils::p(particle) < 0.15) return false; if (particle->fPID == 2212 && FitUtils::p(particle) < 0.45) return false; double dist = SciBooNEUtils::RangeInScintillator(particle, SciBooNEUtils::GetNumRangeSteps()); double zdist = dist*cos(FitUtils::th(beam, particle)); // Allow for vertex migration for backward tracks //if (zdist < 0) zdist -= 2; if (abs(zdist) < SciBooNEUtils::GetSciBarRecoDist()) return false; return true; } int SciBooNEUtils::isProton(FitParticle* track){ if (track->fPID == 2212) return true; return false; } // Function to return the MainTrk int SciBooNEUtils::GetMainTrack(FitEvent *event, TH2D *mupiHist, TH2D *protonHist, FitParticle*& mainTrk, double& weight, bool penetrated){ FitParticle *nu = event->GetNeutrinoIn(); int index = 0; int indexPr = 0; - double highMom = 0; double highWeight = 0; - double highMomPr = 0; double highWeightPr = 0; double runningWeight= 0; mainTrk = NULL; // Loop over particles for (uint j = 2; j < event->Npart(); ++j){ // Final state only! if (!(event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; int PID = event->PartInfo(j)->fPID; // Only consider pions, muons for now if (abs(PID) != 211 && abs(PID) != 13 && PID != 2212) continue; if (!SciBooNEUtils::GetUseProton() && PID == 2212) continue; // Get the track with the highest weight double thisWeight = 0; - double thisMom = FitUtils::p(event->PartInfo(j)); if (PID == 2212) { thisWeight = SciBooNEUtils::ProtonEfficiency(protonHist, nu, event->PartInfo(j)); if (thisWeight == 0) continue; if (runningWeight == 0) runningWeight = thisWeight; else runningWeight += (1 - runningWeight)*thisWeight; if (thisWeight < highWeightPr) continue; - highMomPr = thisMom; highWeightPr = thisWeight; indexPr = j; } else { thisWeight = SciBooNEUtils::StoppedEfficiency(mupiHist, nu, event->PartInfo(j)); if (thisWeight == 0) continue; if (runningWeight == 0) runningWeight = thisWeight; else runningWeight += (1 - runningWeight)*thisWeight; if (thisWeight < highWeight) continue; // Add a range calculation for pi+ if (abs(PID) == 211){ double range = SciBooNEUtils::RangeInScintillator(event->PartInfo(j)); if (abs(range) < SciBooNEUtils::GetMainPionRange()) continue; } - highMom = thisMom; highWeight = thisWeight; index = j; } } // end loop over particle stack // Use MuPi if it's there, if not, use proton info if (highWeightPr > highWeight){ highWeight = highWeightPr; index = indexPr; } // Pass the weight back (don't want to apply a weight twice by accident) mainTrk = event->PartInfo(index); weight *= highWeight; //weight *= runningWeight; //std::cout << "High weight = " << highWeight << "; running weight = " << runningWeight << std::endl; return index; } void SciBooNEUtils::GetOtherTrackInfo(FitEvent *event, int mainIndex, int& nProtons, int& nPiMus, int& nVertex, FitParticle*& secondTrk){ // Reset everything nPiMus = 0; nProtons = 0; nVertex = 0; secondTrk = NULL; if (mainIndex == 0) return; double highestMom = 0.; // Loop over particles for (uint j = 2; j < event->Npart(); ++j){ // Don't re-count the main track if (j == (uint)mainIndex) continue; // Final state only! if (!(event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; int PID = event->PartInfo(j)->fPID; // Only consider pions, muons, protons if (abs(PID) != 211 && PID != 2212 && abs(PID) != 13) continue; // Must be reconstructed as a track in SciBooNE, and pass inefficiency cut if (SciBooNEUtils::PassesDistanceCut(event->PartInfo(0), event->PartInfo(j)) && !SciBooNEUtils::ThrowAcceptReject(SciBooNEUtils::GetFlatEfficiency())){ // Keep track of the second highest momentum track if (FitUtils::p(event->PartInfo(j)) > highestMom){ highestMom = FitUtils::p(event->PartInfo(j)); secondTrk = event->PartInfo(j); } if (PID == 2212) nProtons += 1; else nPiMus += 1; // Ignore backward tracks for VA } else if ( FitUtils::th(event->PartInfo(0), event->PartInfo(j))/TMath::Pi() < 0.5) nVertex += 1; } // end loop over particle stack return; } double SciBooNEUtils::apply_smear(double central, double width){ static TRandom3 *rand = 0; if (!rand){ rand = new TRandom3(0); } double output = rand->Gaus(central, width); return output; } // double SciBooNEUtils::apply_double_gaus_smear(double central1, double width1, double central2, double width2){ // static TF1 *func = new TF1("double_gaus", "exp(-0.5*((x)/1.)**2) + 0.1*exp(-0.5*((x)/5.)**2", -20, 20); // return func->GetRandom(); //} double SciBooNEUtils::smear_p(FitParticle* track, double smear){ static TF1 *f1 = new TF1("f1", "gaus(0)+gaus(3)", -0.8, 0.8); static bool set_pars = false; if (!set_pars){ f1->SetParameter(0, 1275.87); f1->SetParameter(1, -0.0160104); f1->SetParameter(2, 0.0424547); f1->SetParameter(3, 116.157); f1->SetParameter(4, -0.0287358); f1->SetParameter(5, 0.157022); set_pars = true; } double mod_mom = FitUtils::p(track) + f1->GetRandom(); return mod_mom; } double SciBooNEUtils::smear_th(FitParticle* track1, FitParticle* track2, double smear){ static TF1 *f1 = new TF1("f1", "gaus(0)+gaus(3)", -15, 15); static bool set_pars = false; if (!set_pars){ f1->SetParameter(0, 1878.41); f1->SetParameter(1, 0.0622622); f1->SetParameter(2, 0.869508); f1->SetParameter(3, 616.559); f1->SetParameter(4, 0.138734); f1->SetParameter(5, 1.96287); set_pars = true; } double mod_th = FitUtils::th(track1, track2) + f1->GetRandom()*TMath::Pi()/180; return mod_th; } // NOTE: need to adapt this to allow for penetrating events... // Simpler, but gives the same results as in Hirade-san's thesis double SciBooNEUtils::CalcThetaPr(FitEvent *event, FitParticle *main, FitParticle *second, bool penetrated){ FitParticle *nu = event->GetNeutrinoIn(); if (!main || !nu || !second) return -999; // Construct the vector p_pr = (-p_mux, -p_muy, Enurec - pmucosthetamu) // where p_mux, p_muy are the projections of the candidate muon momentum onto the x and y dimension respectively double pmu = main->fP.Vect().Mag(); double pmu_x = main->fP.Vect().X(); double pmu_y = main->fP.Vect().Y(); double theta_s = cos(FitUtils::th(nu, main)); double Enuqe = FitUtils::EnuQErec(pmu/1000.,theta_s, 27., true)*1000.; double p_pr_z = Enuqe - pmu*theta_s; TVector3 p_pr = TVector3(-pmu_x, -pmu_y, p_pr_z); double thetapr = p_pr.Angle(second->fP.Vect())/TMath::Pi()*180.; return thetapr; } double SciBooNEUtils::CalcThetaPi(FitEvent *event, FitParticle *second){ FitParticle *nu = event->GetNeutrinoIn(); if (!second || !nu) return -999; double thetapi = FitUtils::th(nu, second)/TMath::Pi()*180.; return thetapi; } /// Functions to deal with the SB mode stacks SciBooNEUtils::ModeStack::ModeStack(std::string name, std::string title, TH1* hist) { fName = name; fTitle = title; AddMode(0, "CCCOH", "CCCOH", kGreen+2, 2, 3244); AddMode(1, "CCRES", "CCRES", kRed, 2, 3304); AddMode(2, "CCQE", "CCQE", kGray+2, 2, 1001); AddMode(3, "2p2h", "2p2h", kMagenta, 2, 1001); AddMode(4, "Other", "Other", kAzure+1, 2, 1001); StackBase::SetupStack(hist); }; int SciBooNEUtils::ModeStack::ConvertModeToIndex(int mode){ switch (abs(mode)){ case 16: return 0; // CCCOH case 11: case 12: case 13: return 1; // CCRES case 1: return 2; // CCQE case 2: return 3; // 2p2h default: return 4; // Other } }; void SciBooNEUtils::ModeStack::Fill(int mode, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack::ConvertModeToIndex(mode), x, y, z, weight); }; void SciBooNEUtils::ModeStack::Fill(FitEvent* evt, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; void SciBooNEUtils::ModeStack::Fill(BaseFitEvt* evt, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; // Functions to deal with Main track PID stack SciBooNEUtils::MainPIDStack::MainPIDStack(std::string name, std::string title, TH1* hist) { fName = name; fTitle = title; AddMode(0, "mu", "#mu^{-}", kGreen+2, 2, 3244); AddMode(1, "pip", "#pi^{+}", kRed, 2, 3304); AddMode(2, "pim", "#pi^{-}", kGray+2, 2, 1001); AddMode(3, "proton", "p", kMagenta, 2, 1001); AddMode(4, "Other", "Other", kAzure+1, 2, 1001); StackBase::SetupStack(hist); }; int SciBooNEUtils::MainPIDStack::ConvertPIDToIndex(int PID){ switch (PID){ case 13: return 0; case 211: return 1; case -211: return 2; case 2212: return 3; default: return 4; } }; void SciBooNEUtils::MainPIDStack::Fill(int PID, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::MainPIDStack::ConvertPIDToIndex(PID), x, y, z, weight); }; // Functions to deal with second type of mode breakdown (from the thesis) SciBooNEUtils::ModeStack2::ModeStack2(std::string name, std::string title, TH1* hist) { fName = name; fTitle = title; AddMode(0, "CCCOH", "#nu CC coh. #pi", kGreen+2, 2, 3244); AddMode(1, "CCRES", "#nu CC res. #pi", kRed, 2, 3304); AddMode(2, "ANTINU", "#bar{#nu} BG", kMagenta, 2, 1001); AddMode(3, "NC", "#nu NC", kYellow, 2, 1001); AddMode(4, "CCOTHER", "#nu CC other", kBlue+2, 2, 1001); AddMode(5, "CCQE", "#nu CCQE", kBlack, 2, 1001); AddMode(6, "2p2h", "#nu 2p2h", kGray+1, 2, 1001); StackBase::SetupStack(hist); }; int SciBooNEUtils::ModeStack2::ConvertModeToIndex(int mode){ // Catch wrong sign contribution if (mode < 0) return 2; // Catch NC contributions if (mode > 30) return 3; switch (abs(mode)){ case 16: return 0; // CCCOH case 11: case 12: case 13: return 1; // CCRES case 1: return 5; // CCQE case 2: return 6; // 2p2h default: return 4; // Other } }; void SciBooNEUtils::ModeStack2::Fill(int mode, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack2::ConvertModeToIndex(mode), x, y, z, weight); }; void SciBooNEUtils::ModeStack2::Fill(FitEvent* evt, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack2::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; void SciBooNEUtils::ModeStack2::Fill(BaseFitEvt* evt, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack2::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; diff --git a/src/Statistical/StatUtils.cxx b/src/Statistical/StatUtils.cxx index c4a173c..5261f06 100644 --- a/src/Statistical/StatUtils.cxx +++ b/src/Statistical/StatUtils.cxx @@ -1,1362 +1,1362 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "StatUtils.h" #include "GeneralUtils.h" #include "NuisConfig.h" #include "TH1D.h" //******************************************************************* Double_t StatUtils::GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask) { //******************************************************************* Double_t Chi2 = 0.0; TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // Add MC Error to data if required if (FitPar::Config().GetParB("addmcerror")) { for (int i = 0; i < calc_data->GetNbinsX(); i++) { double dterr = calc_data->GetBinError(i + 1); double mcerr = calc_mc->GetBinError(i + 1); if (dterr > 0.0) { calc_data->SetBinError(i + 1, sqrt(dterr * dterr + mcerr * mcerr)); } } } // Apply masking if required if (mask) { calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Iterate over bins in X for (int i = 0; i < calc_data->GetNbinsX(); i++) { // Ignore bins with zero data or zero bin error if (calc_data->GetBinError(i + 1) <= 0.0 || calc_data->GetBinContent(i + 1) == 0.0) continue; // Take mc data difference double diff = calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1); double err = calc_data->GetBinError(i + 1); Chi2 += (diff * diff) / (err * err); } // cleanup delete calc_data; delete calc_mc; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) map = GenerateMap(data); // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate 1D chi2 from 1D Plots Double_t Chi2 = StatUtils::GetChi2FromDiag(data_1D, mc_1D, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromCov(TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask, double data_scale, double covar_scale) { //******************************************************************* Double_t Chi2 = 0.0; TMatrixDSym* calc_cov = (TMatrixDSym*)invcov->Clone(); TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // If a mask if applied we need to apply it before the matrix is inverted if (mask) { calc_cov = ApplyInvertedMatrixMasking(invcov, mask); calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Add MC Error to data if required if (FitPar::Config().GetParB("statutils.addmcerror")) { // Make temp cov TMatrixDSym* newcov = StatUtils::GetInvert(calc_cov); // Add MC err to diag for (int i = 0; i < calc_data->GetNbinsX(); i++) { double mcerr = calc_mc->GetBinError(i + 1) * sqrt(covar_scale); double oldval = (*newcov)(i, i); LOG(FIT) << "Adding cov stat " << mcerr * mcerr << " to " << (*newcov)(i, i) << std::endl; (*newcov)(i, i) = oldval + mcerr * mcerr; } // Reset the calc_cov to new invert delete calc_cov; calc_cov = GetInvert(newcov); // Delete the tempcov delete newcov; } calc_data->Scale(data_scale); calc_mc->Scale(data_scale); (*calc_cov) *= covar_scale; // iterate over bins in X (i,j) QLOG(DEB, "START Chi2 Calculation================="); for (int i = 0; i < calc_data->GetNbinsX(); i++) { QLOG(DEB, "[CHI2] i = " << i << " [" << calc_data->GetXaxis()->GetBinLowEdge(i + 1) << " -- " << calc_data->GetXaxis()->GetBinUpEdge(i + 1) << "]."); for (int j = 0; j < calc_data->GetNbinsX(); j++) { QLOG(DEB, "[CHI2]\t j = " << i << " [" << calc_data->GetXaxis()->GetBinLowEdge(j + 1) << " -- " << calc_data->GetXaxis()->GetBinUpEdge(j + 1) << "]."); if ((calc_data->GetBinContent(i + 1) != 0 || calc_mc->GetBinContent(i + 1) != 0) && ((*calc_cov)(i, j) != 0)) { QLOG(DEB, "[CHI2]\t\t Chi2 contribution (i,j) = (" << i << "," << j << ")"); QLOG(DEB, "[CHI2]\t\t Data - MC(i) = " << calc_data->GetBinContent(i + 1) << " - " << calc_mc->GetBinContent(i + 1) << " = " << (calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1))); QLOG(DEB, "[CHI2]\t\t Data - MC(j) = " << calc_data->GetBinContent(j + 1) << " - " << calc_mc->GetBinContent(j + 1) << " = " << (calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1))); QLOG(DEB, "[CHI2]\t\t Covar = " << (*calc_cov)(i, j)); QLOG(DEB, "[CHI2]\t\t Cont chi2 = " << ((calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1)) * (*calc_cov)(i, j) * (calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1))) << " " << Chi2); Chi2 += ((calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1)) * (*calc_cov)(i, j) * (calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1))); } else { QLOG(DEB, "Skipping chi2 contribution (i,j) = (" << i << "," << j << "), Data = " << calc_data->GetBinContent(i + 1) << ", MC = " << calc_mc->GetBinContent(i + 1) << ", Cov = " << (*calc_cov)(i, j)); Chi2 += 0.; } } } // Cleanup delete calc_cov; delete calc_data; delete calc_mc; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromCov(TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) { map = StatUtils::GenerateMap(data); } // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate 1D chi2 from 1D Plots Double_t Chi2 = StatUtils::GetChi2FromCov(data_1D, mc_1D, invcov, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromSVD(TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask) { //******************************************************************* Double_t Chi2 = 0.0; TMatrixDSym* calc_cov = (TMatrixDSym*)cov->Clone(); TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // If a mask if applied we need to apply it before the matrix is inverted if (mask) { calc_cov = StatUtils::ApplyMatrixMasking(cov, mask); calc_data = StatUtils::ApplyHistogramMasking(data, mask); calc_mc = StatUtils::ApplyHistogramMasking(mc, mask); } // Decompose matrix TDecompSVD LU = TDecompSVD((*calc_cov)); LU.Decompose(); TMatrixDSym* cov_U = new TMatrixDSym(calc_data->GetNbinsX(), LU.GetU().GetMatrixArray(), ""); TVectorD* cov_S = new TVectorD(LU.GetSig()); // Apply basis rotation before adding up chi2 Double_t rotated_difference = 0.0; for (int i = 0; i < calc_data->GetNbinsX(); i++) { rotated_difference = 0.0; // Rotate basis of Data - MC for (int j = 0; j < calc_data->GetNbinsY(); j++) rotated_difference += (calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1)) * (*cov_U)(j, i); // Divide by rotated error cov_S Chi2 += rotated_difference * rotated_difference * 1E76 / (*cov_S)(i); } // Cleanup delete calc_cov; delete calc_data; delete calc_mc; delete cov_U; delete cov_S; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromSVD(TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) map = StatUtils::GenerateMap(data); // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate from 1D Double_t Chi2 = StatUtils::GetChi2FromSVD(data_1D, mc_1D, cov, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; } //******************************************************************* double StatUtils::GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask) { //******************************************************************* // If just an event rate, for chi2 just use Poission Likelihood to calculate // the chi2 component double chi2 = 0.0; TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // Apply masking if required if (mask) { calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Iterate over bins in X for (int i = 0; i < calc_data->GetNbinsX(); i++) { double dt = calc_data->GetBinContent(i + 1); double mc = calc_mc->GetBinContent(i + 1); if (mc <= 0) continue; if (dt <= 0) { // Only add difference chi2 += 2 * (mc - dt); } else { // Do the chi2 for Poisson distributions chi2 += 2 * (mc - dt + (dt * log(dt / mc))); } /* LOG(REC)<<"Evt Chi2 cont = "<Clone(); // If a mask is provided we need to apply it before getting NDOF if (mask) { calc_hist = StatUtils::ApplyHistogramMasking(hist, mask); } // NDOF is defined as total number of bins with non-zero errors Int_t NDOF = 0; for (int i = 0; i < calc_hist->GetNbinsX(); i++) { if (calc_hist->GetBinError(i + 1) > 0.0) NDOF++; } delete calc_hist; return NDOF; }; //******************************************************************* Int_t StatUtils::GetNDOF(TH2D* hist, TH2I* map, TH2I* mask) { //******************************************************************* Int_t NDOF = 0; if (!map) map = StatUtils::GenerateMap(hist); for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (mask->GetBinContent(i + 1, j + 1)) continue; if (map->GetBinContent(i + 1, j + 1) <= 0) continue; NDOF++; } } return NDOF; }; //******************************************************************* TH1D* StatUtils::ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag, TH1I* mask) { //******************************************************************* TH1D* calc_hist = (TH1D*)hist->Clone((std::string(hist->GetName()) + "_THROW").c_str()); TMatrixDSym* calc_cov = (TMatrixDSym*)cov->Clone(); Double_t correl_val = 0.0; // If a mask if applied we need to apply it before the matrix is decomposed if (mask) { calc_cov = ApplyMatrixMasking(cov, mask); calc_hist = ApplyHistogramMasking(calc_hist, mask); } // If a covariance is provided we need a preset random vector and a decomp std::vector rand_val; - TMatrixDSym* decomp_cov; + TMatrixDSym* decomp_cov = NULL; if (cov) { for (int i = 0; i < hist->GetNbinsX(); i++) { rand_val.push_back(gRandom->Gaus(0.0, 1.0)); } // Decomp the matrix decomp_cov = StatUtils::GetDecomp(calc_cov); } // iterate over bins for (int i = 0; i < hist->GetNbinsX(); i++) { // By Default the errors on the histogram are thrown uncorrelated to the other errors /* if (throwdiag) { calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + \ gRandom->Gaus(0.0, 1.0) * calc_hist->GetBinError(i + 1)) ); } */ // If a covariance is provided that is also thrown if (cov) { correl_val = 0.0; for (int j = 0; j < hist->GetNbinsX(); j++) { correl_val += rand_val[j] * (*decomp_cov)(j, i); } calc_hist->SetBinContent( i + 1, (calc_hist->GetBinContent(i + 1) + correl_val * 1E-38)); } } delete calc_cov; delete decomp_cov; // return this new thrown data return calc_hist; }; //******************************************************************* TH2D* StatUtils::ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map, bool throwdiag, TH2I* mask) { //******************************************************************* // PLACEHOLDER!!!!!!!!! // Currently no support for throwing 2D Histograms from a covariance (void)hist; (void)cov; (void)map; (void)throwdiag; (void)mask; // /todo // Sort maps if required // Throw the covariance for a 1D plot // Unmap back to 2D Histogram return hist; } //******************************************************************* TH1D* StatUtils::ApplyHistogramMasking(TH1D* hist, TH1I* mask) { //******************************************************************* if (!mask) return ((TH1D*)hist->Clone()); // This masking is only sufficient for chi2 calculations, and will have dodgy // bin edges. // Get New Bin Count Int_t NBins = 0; for (int i = 0; i < hist->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) continue; NBins++; } // Make new hist std::string newmaskname = std::string(hist->GetName()) + "_MSKD"; TH1D* calc_hist = new TH1D(newmaskname.c_str(), newmaskname.c_str(), NBins, 0, NBins); // fill new hist int binindex = 0; for (int i = 0; i < hist->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) { LOG(REC) << "Applying mask to bin " << i + 1 << " " << hist->GetName() << std::endl; continue; } calc_hist->SetBinContent(binindex + 1, hist->GetBinContent(i + 1)); calc_hist->SetBinError(binindex + 1, hist->GetBinError(i + 1)); binindex++; } return calc_hist; }; //******************************************************************* TH2D* StatUtils::ApplyHistogramMasking(TH2D* hist, TH2I* mask) { //******************************************************************* TH2D* newhist = (TH2D*)hist->Clone(); if (!mask) return newhist; for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (mask->GetBinContent(i + 1, j + 1) > 0) { newhist->SetBinContent(i + 1, j + 1, 0.0); newhist->SetBinContent(i + 1, j + 1, 0.0); } } } return newhist; } //******************************************************************* TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask) { //******************************************************************* if (!mask) return (TMatrixDSym*)(mat->Clone()); // Get New Bin Count Int_t NBins = 0; for (int i = 0; i < mask->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) continue; NBins++; } // make new matrix TMatrixDSym* calc_mat = new TMatrixDSym(NBins); int col, row; // Need to mask out bins in the current matrix row = 0; for (int i = 0; i < mask->GetNbinsX(); i++) { col = 0; // skip if masked if (mask->GetBinContent(i + 1) > 0.5) continue; for (int j = 0; j < mask->GetNbinsX(); j++) { // skip if masked if (mask->GetBinContent(j + 1) > 0.5) continue; (*calc_mat)(row, col) = (*mat)(i, j); col++; } row++; } return calc_mat; }; //******************************************************************* TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1I* mask_1D = StatUtils::MapToMask(mask, map); TMatrixDSym* newmat = StatUtils::ApplyMatrixMasking(mat, mask_1D); delete mask_1D; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask) { //******************************************************************* TMatrixDSym* new_mat = GetInvert(mat); TMatrixDSym* masked_mat = ApplyMatrixMasking(new_mat, mask); TMatrixDSym* inverted_mat = GetInvert(masked_mat); delete masked_mat; delete new_mat; return inverted_mat; }; //******************************************************************* TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1I* mask_1D = StatUtils::MapToMask(mask, map); TMatrixDSym* newmat = ApplyInvertedMatrixMasking(mat, mask_1D); delete mask_1D; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::GetInvert(TMatrixDSym* mat) { //******************************************************************* TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone(); // Check for diagonal bool non_diagonal = false; for (int i = 0; i < new_mat->GetNrows(); i++) { for (int j = 0; j < new_mat->GetNrows(); j++) { if (i == j) continue; if ((*new_mat)(i, j) != 0.0) { non_diagonal = true; break; } } } // If diag, just flip the diag if (!non_diagonal or new_mat->GetNrows() == 1) { for (int i = 0; i < new_mat->GetNrows(); i++) { if ((*new_mat)(i, i) != 0.0) (*new_mat)(i, i) = 1.0 / (*new_mat)(i, i); else (*new_mat)(i, i) = 0.0; } return new_mat; } // Invert full matrix TDecompSVD LU = TDecompSVD((*new_mat)); new_mat = new TMatrixDSym(new_mat->GetNrows(), LU.Invert().GetMatrixArray(), ""); return new_mat; } //******************************************************************* TMatrixDSym* StatUtils::GetDecomp(TMatrixDSym* mat) { //******************************************************************* TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone(); int nrows = new_mat->GetNrows(); // Check for diagonal bool diagonal = true; for (int i = 0; i < nrows; i++) { for (int j = 0; j < nrows; j++) { if (i == j) continue; if ((*new_mat)(i, j) != 0.0) { diagonal = false; break; } } } // If diag, just flip the diag if (diagonal or nrows == 1) { for (int i = 0; i < nrows; i++) { if ((*new_mat)(i, i) > 0.0) (*new_mat)(i, i) = sqrt((*new_mat)(i, i)); else (*new_mat)(i, i) = 0.0; } return new_mat; } TDecompChol LU = TDecompChol(*new_mat); LU.Decompose(); delete new_mat; TMatrixDSym* dec_mat = new TMatrixDSym(nrows, LU.GetU().GetMatrixArray(), ""); return dec_mat; } //******************************************************************* -void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH1D* hist, double norm) { +void StatUtils::ForceNormIntoCovar(TMatrixDSym*& mat, TH1D* hist, double norm) { //******************************************************************* if (!mat) mat = MakeDiagonalCovarMatrix(hist); int nbins = mat->GetNrows(); TMatrixDSym* new_mat = new TMatrixDSym(nbins); for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { double valx = hist->GetBinContent(i + 1) * 1E38; double valy = hist->GetBinContent(j + 1) * 1E38; (*new_mat)(i, j) = (*mat)(i, j) + norm * norm * valx * valy; } } // Swap the two delete mat; mat = new_mat; return; }; //******************************************************************* void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1D* data_1D = MapToTH1D(data, map); StatUtils::ForceNormIntoCovar(mat, data_1D, norm); delete data_1D; return; } //******************************************************************* TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH1D* data, double scaleF) { //******************************************************************* TMatrixDSym* newmat = new TMatrixDSym(data->GetNbinsX()); for (int i = 0; i < data->GetNbinsX(); i++) { (*newmat)(i, i) = data->GetBinError(i + 1) * data->GetBinError(i + 1) * scaleF * scaleF; } return newmat; } //******************************************************************* TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH2D* data, TH2I* map, double scaleF) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1D* data_1D = MapToTH1D(data, map); return StatUtils::MakeDiagonalCovarMatrix(data_1D, scaleF); }; //******************************************************************* void StatUtils::SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale, bool ErrorCheck) { //******************************************************************* // Check if (ErrorCheck) { if (cov->GetNrows() != data->GetNbinsX()) { ERR(FTL) << "Nrows in cov don't match nbins in data for SetDataErrorFromCov" << std::endl; ERR(FTL) << "Nrows = " << cov->GetNrows() << std::endl; ERR(FTL) << "Nbins = " << data->GetNbinsX() << std::endl; throw; } } // Set bin errors form cov diag // Check if the errors are set bool ErrorsSet = false; for (int i = 0; i < data->GetNbinsX(); i++) { if (ErrorsSet == true) break; if (data->GetBinError(i+1) != 0) ErrorsSet = true; } // Now loop over if (ErrorsSet && ErrorCheck) { for (int i = 0; i < data->GetNbinsX(); i++) { double dataerr = data->GetBinError(i + 1); double coverr = sqrt((*cov)(i, i))*scale; // Check that the errors are within 1% of eachother if (fabs(dataerr-coverr)/dataerr > 0.01) { ERR(FTL) << "Data error does not match covariance error for bin " << i+1 << " (" << data->GetXaxis()->GetBinLowEdge(i+1) << "-" << data->GetXaxis()->GetBinLowEdge(i+2) << ")" << std::endl; ERR(FTL) << "Data error: " << dataerr << std::endl; ERR(FTL) << "Cov error: " << coverr << std::endl; } } // Else blindly trust the covariance } else { for (int i = 0; i < data->GetNbinsX(); i++) { data->SetBinError(i+1, sqrt((*cov)(i,i))*scale); } } return; } //******************************************************************* void StatUtils::SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map, double scale, bool ErrorCheck) { //******************************************************************* // Check if (ErrorCheck) { if (cov->GetNrows() != data->GetNbinsX()*data->GetNbinsY()) { ERR(FTL) << "Nrows in cov don't match nbins in data for SetDataErrorFromCov" << std::endl; ERR(FTL) << "Nrows = " << cov->GetNrows() << std::endl; ERR(FTL) << "Nbins = " << data->GetNbinsX() << std::endl; throw; } } // Set bin errors form cov diag // Check if the errors are set bool ErrorsSet = false; for (int i = 0; i < data->GetNbinsX(); i++) { for (int j = 0; j < data->GetNbinsX(); j++) { if (ErrorsSet == true) break; if (data->GetBinError(i+1, j+1) != 0) ErrorsSet = true; } } // Create map if required if (!map) map = StatUtils::GenerateMap(data); // Set Bin Errors from cov diag int count = 0; for (int i = 0; i < data->GetNbinsX(); i++) { for (int j = 0; j < data->GetNbinsY(); j++) { if (data->GetBinContent(i + 1, j + 1) == 0.0) continue; // Get the entry in the cov matrix count = map->GetBinContent(i + 1, j + 1) - 1; double dataerr = data->GetBinError(i+1, j+1); double coverr = sqrt((*cov)(count,count))*scale; // Check that the errors are within 1% of eachother if (ErrorsSet && ErrorCheck) { if (fabs(dataerr-coverr)/dataerr > 0.01) { ERR(FTL) << "Data error does not match covariance error for bin " << i+1 << " (" << data->GetXaxis()->GetBinLowEdge(i+1) << "-" << data->GetXaxis()->GetBinLowEdge(i+2) << ")" << std::endl; ERR(FTL) << "Data error: " << dataerr << std::endl; ERR(FTL) << "Cov error: " << coverr << std::endl; } } else { data->SetBinError(i + 1, j + 1, sqrt((*cov)(count, count)) * scale); } } } return; } TMatrixDSym* StatUtils::ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale) { int nbins = full_covar->GetNrows(); TMatrixDSym* shape_covar = new TMatrixDSym(nbins); // Check nobody is being silly if (data_hist->GetNbinsX() != nbins) { ERR(WRN) << "Inconsistent matrix and data histogram passed to " "StatUtils::ExtractShapeOnlyCovar!" << std::endl; ERR(WRN) << "data_hist has " << data_hist->GetNbinsX() << " matrix has " << nbins << std::endl; int err_bins = data_hist->GetNbinsX(); if (nbins > err_bins) err_bins = nbins; for (int i = 0; i < err_bins; ++i) { ERR(WRN) << "Matrix diag. = " << (*full_covar)(i, i) << " data = " << data_hist->GetBinContent(i + 1) << std::endl; } return NULL; } double total_data = 0; double total_covar = 0; // Initial loop to calculate some constants for (int i = 0; i < nbins; ++i) { total_data += data_hist->GetBinContent(i + 1) * data_scale; for (int j = 0; j < nbins; ++j) { total_covar += (*full_covar)(i, j); } } if (total_data == 0 || total_covar == 0) { ERR(WRN) << "Stupid matrix or data histogram passed to " "StatUtils::ExtractShapeOnlyCovar! Ignoring..." << std::endl; return NULL; } LOG(SAM) << "Norm error = " << sqrt(total_covar) / total_data << std::endl; // Now loop over and calculate the shape-only matrix for (int i = 0; i < nbins; ++i) { double data_i = data_hist->GetBinContent(i + 1) * data_scale; for (int j = 0; j < nbins; ++j) { double data_j = data_hist->GetBinContent(j + 1) * data_scale; double norm_term = data_i * data_j * total_covar / total_data / total_data; double mix_sum1 = 0; double mix_sum2 = 0; for (int k = 0; k < nbins; ++k) { mix_sum1 += (*full_covar)(k, j); mix_sum2 += (*full_covar)(i, k); } double mix_term1 = data_i * (mix_sum1 / total_data - total_covar * data_j / total_data / total_data); double mix_term2 = data_j * (mix_sum2 / total_data - total_covar * data_i / total_data / total_data); (*shape_covar)(i, j) = (*full_covar)(i, j) - mix_term1 - mix_term2 - norm_term; } } return shape_covar; } //******************************************************************* TH2I* StatUtils::GenerateMap(TH2D* hist) { //******************************************************************* std::string maptitle = std::string(hist->GetName()) + "_MAP"; TH2I* map = new TH2I(maptitle.c_str(), maptitle.c_str(), hist->GetNbinsX(), 0, hist->GetNbinsX(), hist->GetNbinsY(), 0, hist->GetNbinsY()); Int_t index = 1; for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (hist->GetBinContent(i + 1, j + 1) > 0 && hist->GetBinError(i + 1, j + 1) > 0) { map->SetBinContent(i + 1, j + 1, index); index++; } else { map->SetBinContent(i + 1, j + 1, 0); } } } return map; } //******************************************************************* TH1D* StatUtils::MapToTH1D(TH2D* hist, TH2I* map) { //******************************************************************* if (!hist) return NULL; // Get N bins for 1D plot Int_t Nbins = map->GetMaximum(); std::string name1D = std::string(hist->GetName()) + "_1D"; // Make new 1D Hist TH1D* newhist = new TH1D(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins); // map bin contents for (int i = 0; i < map->GetNbinsX(); i++) { for (int j = 0; j < map->GetNbinsY(); j++) { if (map->GetBinContent(i + 1, j + 1) == 0) continue; newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1)); newhist->SetBinError(map->GetBinContent(i + 1, j + 1), hist->GetBinError(i + 1, j + 1)); } } // return return newhist; } //******************************************************************* TH1I* StatUtils::MapToMask(TH2I* hist, TH2I* map) { //******************************************************************* TH1I* newhist = NULL; if (!hist) return newhist; // Get N bins for 1D plot Int_t Nbins = map->GetMaximum(); std::string name1D = std::string(hist->GetName()) + "_1D"; // Make new 1D Hist newhist = new TH1I(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins); // map bin contents for (int i = 0; i < map->GetNbinsX(); i++) { for (int j = 0; j < map->GetNbinsY(); j++) { if (map->GetBinContent(i + 1, j + 1) == 0) continue; newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1)); } } // return return newhist; } TMatrixDSym* StatUtils::GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data) { int nbins = correl->GetNrows(); TMatrixDSym* covar = new TMatrixDSym(nbins); for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { (*covar)(i, j) = (*correl)(i, j) * data->GetBinError(i + 1) * data->GetBinError(j + 1); } } return covar; } //******************************************************************* TMatrixD* StatUtils::GetMatrixFromTextFile(std::string covfile, int dimx, int dimy) { //******************************************************************* // Determine dim if (dimx == -1 and dimy == -1) { std::string line; std::ifstream covar(covfile.c_str(), std::ifstream::in); int row = 0; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { column++; if (column > dimx) dimx = column; } row++; if (row > dimy) dimy = row; } } // Or assume symmetric if (dimx != -1 and dimy == -1) { dimy = dimx; } assert(dimy != -1 && " matrix dimy not set."); // Make new matrix TMatrixD* mat = new TMatrixD(dimx, dimy); std::string line; std::ifstream covar(covfile.c_str(), std::ifstream::in); int row = 0; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { // Check Rows // assert(row > mat->GetNrows() && " covar rows doesn't match matrix // rows."); // assert(column > mat->GetNcols() && " covar cols doesn't match matrix // cols."); // Fill Matrix (*mat)(row, column) = (*iter); column++; } row++; } return mat; } //******************************************************************* TMatrixD* StatUtils::GetMatrixFromRootFile(std::string covfile, std::string histname) { //******************************************************************* std::string inputfile = covfile + ";" + histname; std::vector splitfile = GeneralUtils::ParseToStr(inputfile, ";"); if (splitfile.size() < 2) { ERR(FTL) << "No object name given!" << std::endl; throw; } // Get file TFile* tempfile = new TFile(splitfile[0].c_str(), "READ"); // Get Object TObject* obj = tempfile->Get(splitfile[1].c_str()); if (!obj) { ERR(FTL) << "Object " << splitfile[1] << " doesn't exist!" << std::endl; throw; } // Try casting TMatrixD* mat = dynamic_cast(obj); if (mat) { TMatrixD* newmat = (TMatrixD*)mat->Clone(); delete mat; tempfile->Close(); return newmat; } TMatrixDSym* matsym = dynamic_cast(obj); if (matsym) { TMatrixD* newmat = new TMatrixD(matsym->GetNrows(), matsym->GetNrows()); for (int i = 0; i < matsym->GetNrows(); i++) { for (int j = 0; j < matsym->GetNrows(); j++) { (*newmat)(i, j) = (*matsym)(i, j); } } delete matsym; tempfile->Close(); return newmat; } TH2D* mathist = dynamic_cast(obj); if (mathist) { TMatrixD* newmat = new TMatrixD(mathist->GetNbinsX(), mathist->GetNbinsX()); for (int i = 0; i < mathist->GetNbinsX(); i++) { for (int j = 0; j < mathist->GetNbinsX(); j++) { (*newmat)(i, j) = mathist->GetBinContent(i + 1, j + 1); } } delete mathist; tempfile->Close(); return newmat; } return NULL; } //******************************************************************* TMatrixDSym* StatUtils::GetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************* // Delete TempMat TMatrixD* tempmat = GetMatrixFromTextFile(covfile, dim, dim); // Make a symmetric covariance TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows()); for (int i = 0; i < tempmat->GetNrows(); i++) { for (int j = 0; j < tempmat->GetNrows(); j++) { (*newmat)(i, j) = (*tempmat)(i, j); } } delete tempmat; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::GetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************* TMatrixD* tempmat = GetMatrixFromRootFile(covfile, histname); TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows()); for (int i = 0; i < tempmat->GetNrows(); i++) { for (int j = 0; j < tempmat->GetNrows(); j++) { (*newmat)(i, j) = (*tempmat)(i, j); } } delete tempmat; return newmat; } diff --git a/src/Statistical/StatUtils.h b/src/Statistical/StatUtils.h index 10b1e18..435e6a7 100644 --- a/src/Statistical/StatUtils.h +++ b/src/Statistical/StatUtils.h @@ -1,255 +1,255 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef STATUTILS_H #define STATUTILS_H // C Includes #include #include #include #include #include #include #include #include #include "assert.h" // Root Includes #include "TH1D.h" #include "TH2I.h" #include "TH2D.h" #include "TFile.h" #include "TMatrixDSym.h" #include "TDecompSVD.h" #include "TMath.h" #include "TRandom3.h" #include "TDecompChol.h" #include "TGraphErrors.h" // Fit Includes #include "FitLogger.h" /*! * \addtogroup Utils * @{ */ //! Functions for handling statistics calculations namespace StatUtils{ /* Chi2 Functions */ //! Get Chi2 using diagonal bin errors from the histogram. Masking applied before calculation if mask provided. Double_t GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Get Chi2 using diagonal bin errors from the histogram. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using an inverted covariance for the data Double_t GetChi2FromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL, double data_scale=1, double covar_scale=1E76); //! Get Chi2 using an inverted covariance for the data //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using an SVD method on the covariance before calculation. //! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work. Double_t GetChi2FromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL); //! Get Chi2 using an SVD method on the covariance before calculation. //! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using only the raw event rates given in each bin using a -2LL method. Double_t GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Get Chi2 using only the raw event rates given in each bin using a -2LL method. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); // Likelihood Functions //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); /* NDOF Functions */ //! Return 1D Histogram NDOF considering masking and empty bins Int_t GetNDOF(TH1D* hist, TH1I* mask=NULL); //! Return 2D Histogram NDOF considering masking and empty bins Int_t GetNDOF(TH2D* hist, TH2I* map=NULL, TH2I* mask=NULL); /* Fake Data Functions */ //! Given a full covariance for a 1D data set throw the decomposition to generate fake data. //! throwdiag determines whether diagonal statistical errors are thrown. //! If no covariance is provided only statistical errors are thrown. TH1D* ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag=true, TH1I* mask=NULL); //! Given a full covariance for a 2D data set throw the decomposition to generate fake data. //! Plots are converted to 1D histograms and the 1D ThrowHistogram is used, before being converted back to 2D histograms. TH2D* ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map=NULL, bool throwdiag=true, TH2I* mask=NULL); /* Masking Functions */ //! Given a mask histogram, mask out any bins in hist with non zero entries in mask. TH1D* ApplyHistogramMasking(TH1D* hist, TH1I* mask); //! Given a mask histogram, mask out any bins in hist with non zero entries in mask. TH2D* ApplyHistogramMasking(TH2D* hist, TH2I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse. TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse. //! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D. TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance //! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D. TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL); /* Covariance Handling Functions */ //! Return inverted matrix of TMatrixDSym TMatrixDSym* GetInvert(TMatrixDSym* mat); //! Return Cholesky Decomposed matrix of TMatrixDSym TMatrixDSym* GetDecomp(TMatrixDSym* mat); //! Return full covariances TMatrixDSym* GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data); //! Given a normalisation factor for a dataset add in a new normalisation term to the covariance. - void ForceNormIntoCovar(TMatrixDSym* mat, TH1D* data, double norm); + void ForceNormIntoCovar(TMatrixDSym*& mat, TH1D* data, double norm); //! Given a normalisation factor for a dataset add in a new normalisation term to the covariance. //! Convertes 2D to 1D, before using 1D ForceNormIntoCovar void ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map=NULL); //! Given a dataset generate an uncorrelated covariance matrix using the bin errors. TMatrixDSym* MakeDiagonalCovarMatrix(TH1D* data, double scaleF=1E38); //! Given a dataset generate an uncorrelated covariance matrix using the bin errors. TMatrixDSym* MakeDiagonalCovarMatrix(TH2D* data, TH2I* map=NULL, double scaleF=1E38); //! Given a covariance set the errors in each bin on the data from the covariance diagonals. void SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale=1.0, bool ErrorCheck = true); //! Given a covariance set the errors in each bin on the data from the covariance diagonals. void SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map=NULL, double scale=1.0, bool ErrorCheck = true); //! Given a covariance, extracts the shape-only matrix using the method from the MiniBooNE TN TMatrixDSym* ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale=1E38); /* Mapping Functions */ //! If no map is provided for the 2D histogram, generate one by counting up through the bins along x and y. TH2I* GenerateMap(TH2D* hist); //! Apply a map to a 2D histogram converting it into a 1D histogram. TH1D* MapToTH1D(TH2D* hist, TH2I* map); //! Apply a map to a 2D mask convering it into a 1D mask. TH1I* MapToMask(TH2I* hist, TH2I* map); /// \brief Read TMatrixD from a text file /// /// - covfile = full path to text file /// - dimx = x dimensions of matrix /// - dimy = y dimensions of matrix /// /// Format of textfile should be: \n /// cov_11 cov_12 ... cov_1N \n /// cov_21 cov_22 ... cov_2N \n /// ... ... ... ... \n /// cov_N1 ... ... cov_NN \n /// /// If no dimensions are given, dimx and dimy are determined from rows/columns /// inside textfile. /// /// If only dimx is given a symmetric matrix is assumed. TMatrixD* GetMatrixFromTextFile(std::string covfile, int dimx=-1, int dimy=-1); /// \brief Read TMatrixD from a ROOT file /// /// - covfile = full path to root file (+';histogram') /// - histname = histogram name /// /// If no histogram name is given function assumes it has been appended /// covfile path as: \n /// 'covfile.root;histname' /// /// histname can point to a TMatrixD object, a TMatrixDSym object, or /// a TH2D object. TMatrixD* GetMatrixFromRootFile(std::string covfile, std::string histname=""); /// \brief Calls GetMatrixFromTextFile and turns it into a TMatrixDSym TMatrixDSym* GetCovarFromTextFile(std::string covfile, int dim); /// \brief Calls GetMatrixFromRootFile and turns it into a TMatrixDSym TMatrixDSym* GetCovarFromRootFile(std::string covfile, std::string histname); }; /*! @} */ #endif