diff --git a/scripts/maketarball.sh b/scripts/maketarball.sh new file mode 100644 index 0000000..2cda989 --- /dev/null +++ b/scripts/maketarball.sh @@ -0,0 +1,32 @@ +#!/bin/sh +nuiscomp=$(which nuiscomp) +binfolder=$(dirname $nuiscomp) +echo $binfolder +allfiles="" +for file in $(find $binfolder/ -type f -perm /a+x -exec ldd {} \; | \grep so | sed -e '/^[^\t]/ d' | sed -e 's/\t//' | sed -e 's/.*=..//' | sed -e 's/ (0.*)//' | sort | uniq -c | sort -n); +do + if [[ "$file" == "/usr/lib"* || "$file" == "/lib"* ]] + then + continue + fi + if [ -e $file ] + then + echo $file + allfiles="$allfiles $file" + fi +done +mkdir nuisance_reqs +mkdir ./nuisance_reqs/lib/ +mkdir ./nuisance_reqs/bin/ +cp -v $allfiles ./nuisance_reqs/lib/ +cp -v $binfolder/../lib/ ./nuisance_reqs/lib/ +cp -r $NUISANCE/data/ ./nuisance_reqs/data/ +cp -r $NUISANCE/parameters/ ./nuisance_reqs/parameters/ +cp -r $binfolder/* ./nuisance_reqs/bin/ +echo "#!/bin/sh" > ./nuisance_reqs/setup.sh +echo 'export NUISANCE=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )' >> ./nuisance_reqs/setup.sh +echo 'export PATH=$NUISANCE/bin:$PATH' >> ./nuisance_reqs/setup.sh +echo 'export LD_LIBRARY_PATH=$NUISANCE/lib:$LD_LIBRARY_PATH' >> ./nuisance_reqs/setup.sh +#GZIP=-9 +#tar -zcf ./nuisance_reqs.tar.gz ./nuisance_reqs/ +#rm -rf ./nuisance_reqs \ No newline at end of file diff --git a/src/MINERvA/MINERvA_CCNpip_XSec_1Dth_nu.cxx b/src/MINERvA/MINERvA_CCNpip_XSec_1Dth_nu.cxx index c6270a9..f753eba 100644 --- a/src/MINERvA/MINERvA_CCNpip_XSec_1Dth_nu.cxx +++ b/src/MINERvA/MINERvA_CCNpip_XSec_1Dth_nu.cxx @@ -1,258 +1,253 @@ // 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CCNpip_XSec_1Dth_nu.h" //******************************************************************** MINERvA_CCNpip_XSec_1Dth_nu::MINERvA_CCNpip_XSec_1Dth_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CCNpip_XSec_1Dth_nu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("#theta_{#pi} (degrees)"); fSettings.SetYTitle("(1/T#Phi) dN_{#pi}/d#theta_{#pi} (cm^{2}/degrees/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fFullPhaseSpace = !fSettings.Found("name", "_20deg"); fFluxCorrection = fSettings.Found("name", "fluxcorr"); fUpdatedData = !fSettings.Found("name", "2015"); fSettings.SetTitle("MINERvA_CCNpip_XSec_1Dth_nu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- // Full Phase Space if (fFullPhaseSpace) { // 2016 release data if (fUpdatedData) { SetDataFromTextFile( GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2016/nu-ccNpi+-xsec-pion-angle.csv"); // MINERvA has the error quoted as a percentage of the cross-section // Need to make this into an absolute error before we go from correlation matrix -> covariance matrix since it depends on the error in the ith bin for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, fDataHist->GetBinContent(i + 1) * (fDataHist->GetBinError(i + 1) / 100.)); } // This is a correlation matrix! but it's all fixed in SetCovarMatrixFromText SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2016/nu-ccNpi+-correlation-pion-angle.csv"); // 2015 release data } else { // 2015 release allows for shape comparisons if (fIsShape) { SetDataFromTextFile( GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th_shape.txt"); SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th_shape_cov.txt"); } else { SetDataFromTextFile( GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th.txt"); SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th_cov.txt"); } } // Restricted Phase Space Data } else { // 2016 release data unfortunately not released in 20degree forward-going, revert to 2015 data if (fUpdatedData) { ERR(FTL) << fName << " has no updated 2016 data for restricted phase space! Using 2015 data." << std::endl; throw; } // Only 2015 20deg data if (fIsShape) { SetDataFromTextFile( GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th_20deg_shape.txt"); SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th_20deg_shape_cov.txt"); } else { SetDataFromTextFile( GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th_20deg.txt"); SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_th_20deg_cov.txt"); } } // Scale the MINERvA data to account for the flux difference // Adjust MINERvA data to flux correction; roughly a 11% normalisation increase in data // Please change when MINERvA releases new data! if (fFluxCorrection) { for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) * 1.11); } } // Make some auxillary helper plots onePions = (TH1D*)(fDataHist->Clone()); onePions->SetNameTitle((fName + "_1pions").c_str(), (fName + "_1pions" + fPlotTitles).c_str()); SetAutoProcessTH1(onePions, kCMD_Reset, kCMD_Scale, kCMD_Norm); twoPions = (TH1D*)(fDataHist->Clone()); twoPions->SetNameTitle((fName + "_2pions").c_str(), (fName + "_2pions;" + fPlotTitles).c_str()); SetAutoProcessTH1(twoPions, kCMD_Reset, kCMD_Scale, kCMD_Norm); threePions = (TH1D*)(fDataHist->Clone()); threePions->SetNameTitle((fName + "_3pions").c_str(), (fName + "_3pions" + fPlotTitles).c_str()); SetAutoProcessTH1(threePions, kCMD_Reset, kCMD_Scale, kCMD_Norm); morePions = (TH1D*)(fDataHist->Clone()); morePions->SetNameTitle((fName + "_4pions").c_str(), (fName + "_4pions" + fPlotTitles).c_str()); SetAutoProcessTH1(morePions, kCMD_Reset, kCMD_Scale, kCMD_Norm); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; // ******************************************** // Fill the event variables // Here we want to fill the angle for every pion we can find in the event void MINERvA_CCNpip_XSec_1Dth_nu::FillEventVariables(FitEvent *event) { // ******************************************** if (event->NumFSParticle(211) == 0 && event->NumFSParticle(-211) == 0) return; if (event->NumFSParticle(13) == 0) return; GetBox()->Reset(); TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; - - double hadMass = FitUtils::Wrec(Pnu, Pmu); - - if (hadMass < 1800) { - - TLorentzVector Ppip; - // Loop over the particle stack - for (unsigned int j = 2; j < event->Npart(); ++j) { - - // Only include alive particles - if ((event->PartInfo(j))->fIsAlive <= 0) continue; - if ((event->PartInfo(j))->fNEUTStatusCode != 0) continue; - - int PID = (event->PartInfo(j))->fPID; - // Select highest momentum (energy) charged pion - if (abs(PID) == 211) { - Ppip = (event->PartInfo(j))->fP; - double th = (180. / M_PI) * FitUtils::th(Pnu, Ppip); - GetPionBox()->fthpiVect.push_back(th); - } + TLorentzVector Ppip; + // Loop over the particle stack + for (unsigned int j = 2; j < event->Npart(); ++j) { + + // Only include alive particles + if ((event->PartInfo(j))->fIsAlive <= 0) continue; + if ((event->PartInfo(j))->fNEUTStatusCode != 0) continue; + + int PID = (event->PartInfo(j))->fPID; + // Select highest momentum (energy) charged pion + if (abs(PID) == 211) { + Ppip = (event->PartInfo(j))->fP; + double th = (180. / M_PI) * FitUtils::th(Pnu, Ppip); + GetPionBox()->fthpiVect.push_back(th); } } + fXVar = 0; return; }; //******************************************************************** // The signal definition for MINERvA CCNpi+ // Last bool refers to if we're selecting on the full phase space or not bool MINERvA_CCNpip_XSec_1Dth_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCCNpip_MINERvA(event, EnuMin, EnuMax, !fFullPhaseSpace); } //******************************************************************** // Need to override FillHistograms() here because we fill the histogram N_pion times void MINERvA_CCNpip_XSec_1Dth_nu::FillHistograms() { //******************************************************************** if (Signal) { unsigned int nPions = GetPionBox()->fthpiVect.size(); // Need to loop over all the pions in the event for (size_t k = 0; k < nPions; ++k) { double th = GetPionBox()->fthpiVect[k]; this->fMCHist->Fill(th, Weight); this->fMCFine->Fill(th, Weight); this->fMCStat->Fill(th, 1.0); if (nPions == 1) { onePions->Fill(th, Weight); } else if (nPions == 2) { twoPions->Fill(th, Weight); } else if (nPions == 3) { threePions->Fill(th, Weight); } else if (nPions > 3) { morePions->Fill(th, Weight); } if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, th, Weight); // PlotUtils::FillNeutModeArray(fMCHist_PDG, Mode, th, Weight); } } return; } //******************************************************************** void MINERvA_CCNpip_XSec_1Dth_nu::Write(std::string drawOpts) { //******************************************************************** Measurement1D::Write(drawOpts); // Draw the npions stack onePions->SetTitle("1#pi"); onePions->SetLineColor(kBlack); //onePions->SetFillStyle(0); onePions->SetFillColor(onePions->GetLineColor()); twoPions->SetTitle("2#pi"); twoPions->SetLineColor(kRed); //twoPions->SetFillStyle(0); twoPions->SetFillColor(twoPions->GetLineColor()); threePions->SetTitle("3#pi"); threePions->SetLineColor(kGreen); //threePions->SetFillStyle(0); threePions->SetFillColor(threePions->GetLineColor()); morePions->SetTitle(">3#pi"); morePions->SetLineColor(kBlue); //morePions->SetFillStyle(0); morePions->SetFillColor(morePions->GetLineColor()); THStack pionStack = THStack((fName + "_pionStack").c_str(), (fName + "_pionStack").c_str()); pionStack.Add(onePions); pionStack.Add(twoPions); pionStack.Add(threePions); pionStack.Add(morePions); pionStack.Write(); return; } diff --git a/src/MINERvA/MINERvA_SignalDef.cxx b/src/MINERvA/MINERvA_SignalDef.cxx index 519e6ea..798fb8e 100644 --- a/src/MINERvA/MINERvA_SignalDef.cxx +++ b/src/MINERvA/MINERvA_SignalDef.cxx @@ -1,266 +1,267 @@ // 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 <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "SignalDef.h" #include "FitUtils.h" #include "MINERvA_SignalDef.h" namespace SignalDef { // ********************************* // MINERvA CC1pi+/- signal definition (2015 release) // Note: There is a 2016 release which is different to this (listed below), but // it is CCNpi+ and has a different W cut // Note2: The W cut is implemented in the class implementation in MINERvA/ // rather than here so we can draw events that don't pass the W cut (W cut is // 1.4 GeV) // Could possibly be changed for slight speed increase since less events // would be used // // MINERvA signal is slightly different to MiniBooNE // // Exactly one negative muon // Exactly one charged pion (both + and -); however, there is a Michel e- // requirement but UNCLEAR IF UNFOLDED OR NOT (so don't know if should be // applied) // Exactly 1 charged pion exits (so + and - charge), however, has Michel // electron requirement, so look for + only here? // No restriction on neutral pions or other mesons // MINERvA has unfolded and not unfolded muon phase space for 2015 // // Possible issues with the data: // 1) pi- is allowed in signal even when Michel cut included; most pi- is efficiency corrected in GENIE // 2) There is a T_pi < 350 MeV cut coming from requiring a stopping pion; this is efficiency corrected in GENIE // 3) There is a 1.5 < Enu < 10.0 cut in signal definition // 4) There is an angular muon cut which is sometimes efficiency corrected (why we have bool isRestricted below) // // Nice things: // Much data given: with and without muon angle cuts and with and without shape // only data + covariance // bool isCC1pip_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool isRestricted) { // ********************************* // Signal is both pi+ and pi- // WARNING: PI- CONTAMINATION IS FULLY GENIE BECAUSE THE MICHEL TAG // First, make sure it's CCINC if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; // Allow pi+/pi- int piPDG[] = {211, -211}; int nLeptons = event->NumFSLeptons(); int nPion = event->NumFSParticle(piPDG); // Check that the desired pion exists and is the only meson if (nPion != 1) return false; // Check that there is only one final state lepton if (nLeptons != 1) return false; // MINERvA released another CC1pi+ xsec without muon unfolding! // here the muon angle is < 20 degrees (seen in MINOS) TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; if (isRestricted) { double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; if (th_nu_mu >= 20) return false; } // Extract Hadronic Mass double hadMass = FitUtils::Wrec(pnu, pmu); // Actual cut is True GENIE Ws! Arg.! Use gNtpcConv definition. #ifdef __GENIE_ENABLED__ if (event->fType == kGENIE){ - GHepRecord* ghep = static_cast<GHepRecord*>(event->genie_event->event); - const Interaction * interaction = ghep->Summary(); + EventRecord * gevent = static_cast<EventRecord*>(event->genie_event->event); + const Interaction * interaction = gevent->Summary(); const Kinematics & kine = interaction->Kine(); double Ws = kine.W (true); + // std::cout << "Ws versus WRec = " << Ws << " vs " << hadMass << " " << kine.W(false) << std::endl; hadMass = Ws * 1000.0; } #endif - if (hadMass > 1400.0 || hadMass < 0.0) return false; + if (hadMass > 1400.0) return false; return true; }; // ********************************* // MINERvA CCNpi+/- signal definition from 2016 publication // Different to CC1pi+/- listed above; additional has W < 1.8 GeV // // For notes on strangeness of signal definition, see CC1pip_MINERvA // // One negative muon // At least one charged pion // 1.5 < Enu < 10 // No restrictions on pi0 or other mesons or baryons // W_reconstructed (ignoring initial state motion) cut at 1.8 GeV // // Also writes number of pions (nPions) if studies on this want to be done... bool isCCNpip_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool isRestricted) { // ********************************* // First, make sure it's CCINC if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; int nLeptons = event->NumFSLeptons(); // Write the number of pions to the measurement class... // Maybe better to just do that inside the class? int nPions = event->NumFSParticle(PhysConst::pdg_charged_pions); // Check that there is a pion! if (nPions == 0) return false; // Check that there is only one final state lepton if (nLeptons != 1) return false; // Need the muon and the neutrino to check angles and W TLorentzVector pnu = event->GetNeutrinoIn()->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; // MINERvA released some data with restricted muon angle // Here the muon angle is < 20 degrees (seen in MINOS) if (isRestricted) { double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; if (th_nu_mu >= 20.) return false; } // Lastly check the W cut (always at 1.8 GeV) double Wrec = FitUtils::Wrec(pnu, pmu) + 0.; // Actual cut is True GENIE Ws! Arg.! Use gNtpcConv definition. #ifdef __GENIE_ENABLED__ if (event->fType == kGENIE){ GHepRecord* ghep = static_cast<GHepRecord*>(event->genie_event->event); const Interaction * interaction = ghep->Summary(); const Kinematics & kine = interaction->Kine(); double Ws = kine.W (true); Wrec = Ws * 1000.0; // Say Wrec is Ws } #endif if (Wrec > 1800. || Wrec < 0.0) return false; return true; }; //******************************************************************** bool isCCQEnumu_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool fullphasespace) { //******************************************************************** if (!isCCQELike(event, 14, EnuMin, EnuMax)) return false; TLorentzVector pnu = event->GetHMISParticle(14)->fP; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; double ThetaMu = pnu.Vect().Angle(pmu.Vect()); double Enu_rec = FitUtils::EnuQErec(pmu, cos(ThetaMu), 34., true); // If Restricted phase space if (!fullphasespace && ThetaMu > 0.34906585) return false; // restrict energy range if (Enu_rec < EnuMin || Enu_rec > EnuMax) return false; return true; }; //******************************************************************** bool isCCQEnumubar_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool fullphasespace) { //******************************************************************** if (!isCCQELike(event, -14, EnuMin, EnuMax)) return false; TLorentzVector pnu = event->GetHMISParticle(-14)->fP; TLorentzVector pmu = event->GetHMFSParticle(-13)->fP; double ThetaMu = pnu.Vect().Angle(pmu.Vect()); double Enu_rec = FitUtils::EnuQErec(pmu, cos(ThetaMu), 30., true); // If Restricted phase space if (!fullphasespace && ThetaMu > 0.34906585) return false; // restrict energy range if (Enu_rec < EnuMin || Enu_rec > EnuMax) return false; return true; } //******************************************************************** bool isCCincLowRecoil_MINERvA(FitEvent *event, double EnuMin, double EnuMax) { //******************************************************************** if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; // Need at least one muon if (event->NumFSParticle(13) < 1) return false; TLorentzVector pmu = event->GetHMFSParticle(13)->fP; TLorentzVector pnu = event->GetHMISParticle(14)->fP; // Cut on muon angle greated than 20deg if (cos(pnu.Vect().Angle(pmu.Vect())) < 0.93969262078) return false; // Cut on muon energy < 1.5 GeV if (pmu.E()/1000.0 < 1.5) return false; return true; } bool isCC0pi1p_MINERvA(FitEvent *event, double enumin, double enumax) { // Require numu CC0pi event with a proton above threshold bool signal = (isCC0pi(event, 14, enumin, enumax) && HasProtonKEAboveThreshold(event, 110.0)); return signal; } // 2015 analysis just asks for 1pi0 and no pi+/pi- bool isCC1pi0_MINERvA_2015(FitEvent *event, double EnuMin, double EnuMax) { bool CC1pi0_anu = SignalDef::isCC1pi(event, -14, 111, EnuMin, EnuMax); return CC1pi0_anu; } // 2016 analysis just asks for 1pi0 and no other charged tracks bool isCC1pi0_MINERvA_2016(FitEvent *event, double EnuMin, double EnuMax) { bool CC1pi0_anu = SignalDef::isCC1pi(event, -14, 111, EnuMin, EnuMax); // Additionally look for charged proton track bool HasProton = event->HasFSParticle(2212); if (CC1pi0_anu) { if (!HasProton) { return true; } else { return false; } } else { return false; } return false; } }