Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F8308737
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Subscribers
None
View Options
diff --git a/src/Reweight/weightRPA.h b/src/Reweight/weightRPA.h
index ca8e635..30de03c 100644
--- a/src/Reweight/weightRPA.h
+++ b/src/Reweight/weightRPA.h
@@ -1,419 +1,417 @@
#ifndef weightRPA_h
#define weightRPA_h
#include <fstream> //ifstream
#include <iostream> //cout
#include <TString.h>
#include <TH2D.h>
#include <TH1D.h>
#include <TFile.h>
#include "math.h"
#include "assert.h"
//For Compatibility with ROOT compiler
//uncomment the following:
//#define ROOT
/*!
* Code example to extract the RPA effect central weight
* and its uncertainties from the prepared files.
* Heidi Schellman (Oregon State) and Rik Gran (Minnesota Duluth)
* for use in MINERvA experiment analysis
* must compile with the ROOT libraries
* g++ `root-config --glibs --cflags` -O3 weightRPAtest.cxx -o weightRPA
* The underlying model is from the IFIC Valencia group
* see (public) minerva docdb:12688 for the full physics discussion
*/
// NOTE UNITS ARE GEV in the calculation
// make sure you convert MeV to GeV before calling these functions
// Class for getting RPA paramaters inputs from a given file
// Includes methods that return all five RPA weights at once
// (is the most cpu efficient way to get them)
// Or return just the central value
// (skipping the uncertainties code completely if only cv wanted)
// Or return each CV and uncertainty one at a time
// (is the least cpu efficient, repeats some calculations 5 times)
class weightRPA {
public:
//Constructor: Read in params from a filename
weightRPA(const TString f) { read(f); } //Read in params from file
TString filename;
TFile* fRPAratio;
TH2D *hRPArelratio;
TH2D *hRPAnonrelratio;
TH1D *hQ2relratio;
TH1D *hQ2nonrelratio;
TArrayD *TADrpapolyrel;
Double_t *rpapolyrel ;
TArrayD *TADrpapolynonrel;
Double_t *rpapolynonrel;
static const int CENTRAL=0;
static const int LOWQ2 = 1;
static const int HIGHQ2 = 2;
// true to take from histogram, false use parameterization
static const bool Q2histORparam = true;
// MINERvA holds kinematics in MeV, but all these functions require GeV
// So make sure you pass them in GeV.
inline double getWeight(const double mc_q0, const double mc_q3, double * weights); //in GeV
inline double getWeight(const double mc_q0, const double mc_q3); //in GeV
inline double getWeight(const double mc_q0, const double mc_q3, int type, int sign); //in GeV
inline double getWeight(const double Q2); //in GeV^2
inline double getWeightLowQ2(const double mc_q0, const double mc_q3, const int sign);
inline double getWeightHighQ2(const double mc_q0, const double mc_q3, const int sign);
inline double getWeightQ2(const double mc_Q2, const bool relORnonrel=true);
//Initializer
inline void read(const TString f);
// q0 and q3 in GeV, type = 1 for low Q2, 2 for high Q2, 0 for central
//double getWeightInternal(const double mc_q0, const double mc_q3,int type, int sign);
private:
inline double getWeightInternal(const double mc_Q2);
inline double getWeightInternal(const double mc_q0, const double mc_q3, const int type, const int sign);
inline double getWeightInternal(const double mc_q0, const double mc_q3, double *weights=0);
inline double getWeightQ2parameterization(const double mc_Q2, const bool relORnonrel);
inline double getWeightQ2fromhistogram(const double mc_Q2, const bool relORnonrel);
};
void weightRPA::read(const TString f)
//Read in the params doubles from a file
//argument: valid filename
{
fRPAratio = TFile::Open(f,"READONLY");
if (fRPAratio){
hRPArelratio = (TH2D*)fRPAratio->Get("hrelratio");
hRPAnonrelratio = (TH2D*)fRPAratio->Get("hnonrelratio");
hQ2relratio = (TH1D*)fRPAratio->Get("hQ2relratio");
hQ2nonrelratio = (TH1D*)fRPAratio->Get("hQ2nonrelratio");
TADrpapolyrel = (TArrayD*)fRPAratio->Get("rpapolyrel");
rpapolyrel = TADrpapolyrel->GetArray();
TADrpapolynonrel = (TArrayD*)fRPAratio->Get("rpapolynonrel");
rpapolynonrel = TADrpapolynonrel->GetArray();
hRPArelratio->Print();
std::cout << "have read in ratios from file " << f <<std::endl;
} else {
//File could not be read
std::cout << "File could not be read" << std::endl;
}
}
double weightRPA::getWeightInternal(const double mc_q0, const double mc_q3, double *weights){
assert(hRPArelratio);
if (weights != 0){
for (int i = 0; i < 5; i++){
weights[i] = 1.0;
}
}
// the construction here is that the histogram bins
// line up in mev-sized steps e.g. from 0.018 to 0.019
// and the value stored is the value at bin-center.
// double gevmev = 0.001 ;
const Double_t gevlimit = 3.; // upper limit for 2d
Int_t rpamevlimit = gevlimit*1000.;
//Double_t Q2gev = mc_Q2*gevmev*gevmev;
Double_t Q2gev = mc_q3*mc_q3-mc_q0*mc_q0;
Int_t q3bin = Int_t(mc_q3*1000.);
Int_t q0bin = Int_t(mc_q0*1000.);
if(mc_q0 >= gevlimit) q0bin = rpamevlimit - 1;
if(mc_q3 >= gevlimit) q3bin = rpamevlimit - 1;
// Nieves does not calculate anything below binding energy.
// I don't know what GENIE does, but lets be soft about this.
// Two things lurking here at once.
// One, we are taking out a 10 MeV offset between GENIE and Valencia.
// Second, we are protecting against being asked for a weight that is too low in q0.
// It actually shouldn't happen for real GENIE events,
// but this protection does something that doesn't suck, just in case.
// you would see the artifact in a plot for sure, but better than writing 1.0.
// CWret after talking to Rik in Nov 2018 at MINERvA CM
// 2.12.8 sets this to 27 because change of Q definition: need to offset GENIE and Nieves Eb even more
#if __GENIE_VERSION__ >= 210
Int_t q0offsetValenciaGENIE = 27;
#else
Int_t q0offsetValenciaGENIE = 10;
#endif
- std::cout << "q0offsetValenciaGENIE: " << q0offsetValenciaGENIE << std::endl;
-
if(mc_q0 < 0.018) q0bin = 18+q0offsetValenciaGENIE;
Double_t thisrwtemp = hRPArelratio->GetBinContent(q3bin,q0bin-q0offsetValenciaGENIE);
// now trap bogus entries. Not sure why they happen, but set to 1.0 not 0.0
if(thisrwtemp <= 0.001)thisrwtemp = 1.0;
// events in genie but not in valencia should get a weight
// related to a similar q0 from the bulk distribution.
if(mc_q0 < 0.15 && thisrwtemp > 0.9){
thisrwtemp = hRPArelratio->GetBinContent(q3bin+150, q0bin-q0offsetValenciaGENIE);
}
//Double_t *mypoly;
//mypoly = rpapoly;
if(Q2gev >= 9.0){
thisrwtemp = 1.0;
}
else if(Q2gev > 3.0) {
// hiding option, use the Q2 parameterization everywhere
// } else if(Q2gev > 3.0 || rwRPAQ2) {
// turn rwRPAQ2 all the way on to override the 2D histogram
// illustrates the old-style Q2 suppression many folks still use.
thisrwtemp = getWeightQ2(Q2gev,true);
// double powerQ2 = 1.0;
//thisrwtemp = 0.0;
//for(int ii=0; ii<10; ii++){
// thisrwtemp += rpapoly[ii]*powerQ2;
// powerQ2 *= Q2gev;
//}
//std::cout << "test temp " << thisrwtemp << " " << rpamypoly[2] << std::endl;
}
if(!(thisrwtemp >= 0.001 && thisrwtemp <= 2.0))thisrwtemp = 1.0;
// hiding option, turn off the enhancement.
//if(rwoffSRC && thisrwtemp > 1.0)thisrwtemp = 1.0;
if (0 == weights) return thisrwtemp;
// if this was called without passing an array,
// the user didn't want us to calculate the +/- 1-sigma bounds
// so the above line returned before even trying.
weights[0] = thisrwtemp;
//if (type == 0) return thisrwtemp;
//if (type == 1) {
// Construct the error bands on the low Q2 suppression.
// Double_t thisrwSupP1 = 1.0;
// Double_t thisrwSupM1 = 1.0;
if( thisrwtemp < 1.0){
// make the suppression stronger or weaker to muon capture uncertainty
// rwRPAonesig is either +1 or -1, which is 0.25 (25%).
// possible to be re-written to produce 2 and 3 sigma.
weights[1] = thisrwtemp + 1.0 * (0.25)*(1.0 - thisrwtemp);
weights[2] = thisrwtemp - 1.0 * (0.25)*(1.0 - thisrwtemp);
}
else{
weights[1] = thisrwtemp;
weights[2] = thisrwtemp;
}
//std::cout << "check " << thisrwtemp << " " << weights[1] << " " << weights[2] << std::endl;
// Construct the rest of the error bands on the low Q2 suppression.
// this involves getting the weight from the non-relativistic ratio
//if (type == 2){
Double_t thisrwEnhP1 = 1.0;
Double_t thisrwEnhM1 = 1.0;
// make enhancement stronger or weaker to Federico Sanchez uncertainty
// this does NOT mean two sigma, its overloading the option.
Double_t thisrwextreme = hRPAnonrelratio->GetBinContent(q3bin,q0bin-q0offsetValenciaGENIE);
// now trap bogus entries. Not sure why they happen, but set to 1.0 not 0.0
if(thisrwextreme <= 0.001)thisrwextreme = 1.0;
if(mc_q0 < 0.15 && thisrwextreme > 0.9){
thisrwextreme = hRPAnonrelratio->GetBinContent(q3bin+150, q0bin-q0offsetValenciaGENIE);
}
//std::cout << "ext " << thisrwextreme << " " << thisrwtemp << std::endl;
// get the same for the Q2 dependent thing,
// but from the nonrelativistic polynomial
if(Q2gev >= 9.0){
thisrwextreme = 1.0;
}
else if(Q2gev > 3.0 ) {
thisrwextreme = getWeightQ2(Q2gev,false);
//double powerQ2 = 1.0;
//thisrwextreme = 0.0;
//for(int ii=0; ii<10; ii++){
// thisrwextreme += rpapolynonrel[ii]*powerQ2;
// powerQ2 *= Q2gev;
//}
//std::cout << "test extreme " << thisrwextreme << " " << mypolynonrel[2] << std::endl;
}
if(!(thisrwextreme >= 0.001 && thisrwextreme <= 2.0))thisrwextreme = 1.0;
//std::cout << "test extreme " << Q2gev << " " << thisrwextreme << " " << thisrwtemp << std::endl;
Double_t RelToNonRel = 0.6;
// based on some distance between central value and extreme
thisrwEnhP1 = thisrwtemp + RelToNonRel * (thisrwextreme-thisrwtemp);
Double_t thisrwEnhP1max = thisrwextreme;
if(Q2gev < 0.9)thisrwEnhP1 += 1.5*(0.9 - Q2gev)*(thisrwEnhP1max - thisrwEnhP1);
// sanity check, don't let the upper error bound go above the nonrel limit.
if(thisrwEnhP1 > thisrwEnhP1max)thisrwEnhP1 = thisrwEnhP1max;
// don't let positive error bound be closer than 3% above the central value
// will happen at very high Q2 and very close to Q2 = 0
if(thisrwEnhP1 < thisrwtemp + 0.03)thisrwEnhP1 = thisrwtemp + 0.03;
thisrwEnhM1 = thisrwtemp - RelToNonRel * (thisrwextreme-thisrwtemp);
// don't let negative error bound be closer than 3% below the central value
if(thisrwEnhM1 > thisrwtemp - 0.03)thisrwEnhM1 = thisrwtemp - 0.03;
// even still, don't let the lower error bound go below 1.0 at high-ish Q2
if(Q2gev > 1.0 && thisrwEnhM1 < 1.0)thisrwEnhM1 = 1.0;
// whew. so now return the main weight
// and return the array of all five weights in some array
// thisrwtemp, thisrwSupP1, thisrwSupM1, thisrwEnhP1, thisrwEnhM1
//if (sign == 1) return thisrwEnhP1;
//if (sign == -1) return thisrwEnhM1;
weights[3] = thisrwEnhP1;
weights[4] = thisrwEnhM1;
// still return the central value
return thisrwtemp;
}
double weightRPA::getWeight(const double mc_q0, const double mc_q3){
return getWeightInternal(mc_q0, mc_q3);
}
double weightRPA::getWeight(const double mc_q0, const double mc_q3, double *weights){
return getWeightInternal(mc_q0, mc_q3, weights);
}
double weightRPA::getWeight(const double mc_q0, const double mc_q3, int type, int sign){
return getWeightInternal(mc_q0, mc_q3, type, sign);
}
double weightRPA::getWeight(const double mc_Q2){
return getWeightQ2(mc_Q2);
}
double weightRPA::getWeightInternal(const double mc_q0, const double mc_q3, int type, int sign){
double weights[5] = {1., 1., 1., 1., 1.};
double cv = getWeightInternal(mc_q0, mc_q3, weights);
if(type==0)return cv;
else if(type==weightRPA::LOWQ2 && sign == 1)return weights[1];
else if(type==weightRPA::LOWQ2 && sign == -1)return weights[2];
else if(type==weightRPA::HIGHQ2 && sign == 1)return weights[3];
else if(type==weightRPA::HIGHQ2 && sign == -1)return weights[4];
//else {
// // should never happen? Bork ?
// return cv; //?
//}
return cv;
}
double weightRPA::getWeightQ2(const double mc_Q2, const bool relORnonrel){
if(mc_Q2 < 0.0)return 1.0; // this is Q2 actually, not sure hw
if(mc_Q2 > 9.0)return 1.0;
// this function needs to know two options.
// does user want rel (cv) or nonrel
// does user want to use the histogram or parameterization
if(Q2histORparam)return getWeightQ2fromhistogram(mc_Q2, relORnonrel);
else return getWeightQ2parameterization(mc_Q2, relORnonrel);
}
double weightRPA::getWeightQ2parameterization(const double mc_Q2, const bool relORnonrel){
if(mc_Q2 < 0.0)return 1.0;
if(mc_Q2 > 9.0)return 1.0;
// this one returns just the polynomial Q2 version
// for special tests. Poor answer for baseline MINERvA QE events.
// No uncertainty assigned to this usecase at this time.
//double gevmev = 0.001; // minerva sends in MeV.
double Q2gev = mc_Q2;
double powerQ2 = 1.0;
double thisrwtemp = 0.0;
thisrwtemp = 0.0;
for(int ii=0; ii<10; ii++){
if(relORnonrel)thisrwtemp += rpapolyrel[ii]*powerQ2;
else thisrwtemp += rpapolynonrel[ii]*powerQ2;
powerQ2 *= Q2gev;
}
return thisrwtemp;
}
double weightRPA::getWeightQ2fromhistogram(const double mc_Q2, const bool relORnonrel){
if(mc_Q2 < 0.0)return 1.0;
if(mc_Q2 > 9.0) return 1.0;
if(relORnonrel)return hQ2relratio->GetBinContent( hQ2relratio->FindBin(mc_Q2) );
else return hQ2nonrelratio->GetBinContent( hQ2nonrelratio->FindBin(mc_Q2) );
// interpolation might be overkill for such a finely binned histogram, 0.01%
// but the extra cpu cycles maybe small.
// save it here for some future use.
//if(relORnonrel)return hQ2relratio->Interpolate(mc_Q2);
//else return hQ2nonrelratio->Interpolate(mc_Q2);
}
double weightRPA::getWeightLowQ2(const double mc_q0, const double mc_q3, int sign){
return getWeightInternal(mc_q0,mc_q3,weightRPA::LOWQ2,sign);
}
double weightRPA::getWeightHighQ2(const double mc_q0, const double mc_q3, int sign){
return getWeightInternal(mc_q0,mc_q3,weightRPA::HIGHQ2,sign);
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Dec 21, 1:00 PM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4022869
Default Alt Text
(14 KB)
Attached To
rNUISANCEGIT nuisancegit
Event Timeline
Log In to Comment