All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PrimaryHadronSanfordWangWeightCalc.cxx
Go to the documentation of this file.
1 //Built from PrimaryHadronSanfordWang.cxx in ubcode/EventWeight/Calculator/Flux/BNBPrimaryHadron directory
2 
3 #include "FluxCalcPrep.h"
4 
5 
6 namespace sbn {
7  namespace evwgh {
8 
9  std::pair<bool, double> FluxWeightCalc::PHSWWeightCalc(simb::MCFlux flux, std::vector<float> rand){
10 
11  //
12  // Largely built off the MiniBooNE code
13  // but this is intended to expand beyond it
14  //
15  // Edits from MiniBooNE code:
16  //
17  // JZ (6/2017) : Remove max weight, set to max_limit of a double
18  // JZ (6/2017) : Changed guards on c9 to be double point precision
19  //
20 
21  // We need to guard against unphysical parameters
22  bool parameters_pass = true;
23 
24  // Get Neutrino Parent Kinimatics
25  double HadronMass = 0.4976;
26 
27 
28  // if(std::find(fprimaryHad.begin(), fprimaryHad.end(), 130) != fprimaryHad.end() ||
29  // std::find(fprimaryHad.begin(), fprimaryHad.end(), 310) != fprimaryHad.end() ||
30  // std::find(fprimaryHad.begin(), fprimaryHad.end(), 311) != fprimaryHad.end())
31  // {
32  // HadronMass = 0.4976; //Neutral Kaon
33  // }
34  // else{
35  // throw art::Exception(art::errors::StdException)
36  // << "Sanford-Wang is only configured for Netrual Kaons";
37  // }
38 
39  TLorentzVector HadronVec;
40  double HadronPx = flux.ftpx;
41  double HadronPy = flux.ftpy;
42  double HadronPz = flux.ftpz;
43  double HadronE = sqrt(HadronPx*HadronPx +
44  HadronPy*HadronPy +
45  HadronPz*HadronPz +
46  HadronMass*HadronMass);
47  HadronVec.SetPxPyPzE(HadronPx,HadronPy,HadronPz,HadronE);
48 
49  // Get Initial Proton Kinitmatics
50  // CURRENTLY GSimple flux files drop information about
51  // the initial state proton, but that this
52  TLorentzVector ProtonVec;
53  double ProtonMass = 0.9382720;
54  double ProtonPx = 0;
55  double ProtonPy = 0;
56  double ProtonPz = 8.89; //GeV
57  double ProtonE = sqrt(ProtonPx*ProtonPx +
58  ProtonPy*ProtonPy +
59  ProtonPz*ProtonPz +
60  ProtonMass*ProtonMass);
61  ProtonVec.SetPxPyPzE(ProtonPx,ProtonPy,ProtonPz,ProtonE);
62 
63  // Define the central value cross section
64  // Pull out the parameters for the Sanford-Wang Fit
65  double c1 = FitVal.at(0);
66  double c2 = FitVal.at(1);
67  double c3 = FitVal.at(2);
68  double c4 = FitVal.at(3);
69  double c5 = FitVal.at(4);
70  double c6 = FitVal.at(5);
71  double c7 = FitVal.at(6);
72  double c8 = FitVal.at(7);
73  double c9 = FitVal.at(8);
74 
75  //Sanford-Wang Parameterization
76  // Eq 11 from PhysRevD.79.072002
77 
78  double CV = c1 * pow(HadronVec.P(), c2) *
79  (1. - HadronVec.P()/(ProtonVec.P() - c9)) *
80  exp(-1. * c3 * pow(HadronVec.P(), c4) / pow(ProtonVec.P(), c5)) *
81  exp(-1. * c6 * HadronVec.Theta() *(HadronVec.P() - c7 * ProtonVec.P() * pow(cos(HadronVec.Theta()), c8)));
82 
83  // Check taken from MiniBooNE code
84  if((HadronVec.P()) > ((ProtonVec.P()) - (c9))){
85  CV = 0;
86  }
87 
88  // Define the variations around that cross section
89  // To do this we will call the a function from WeightCalc
90  // that will generate a set of smeared parameters based
91  // on the covariance matrix that we imported
92  std::vector< double > SWK0FitSmeared = MultiGaussianSmearing(FitVal, FitCov, rand);
93 
94  // Pull out the smeared parameters for the Sanford-Wang Fit
95  double smeared_c1 = SWK0FitSmeared.at(0);
96  double smeared_c2 = SWK0FitSmeared.at(1);
97  double smeared_c3 = SWK0FitSmeared.at(2);
98  double smeared_c4 = SWK0FitSmeared.at(3);
99  double smeared_c5 = SWK0FitSmeared.at(4);
100  double smeared_c6 = SWK0FitSmeared.at(5);
101  double smeared_c7 = SWK0FitSmeared.at(6);
102  double smeared_c8 = SWK0FitSmeared.at(7);
103  double smeared_c9 = SWK0FitSmeared.at(8);
104 
105  /// Perform the MiniBooNE
106  if(smeared_c1 < 0 ||
107  smeared_c3 < 0 ||
108  smeared_c6 < 0){
109  parameters_pass = false;
110  }
111 
112  double RW = smeared_c1 * pow(HadronVec.P(), smeared_c2) *
113  (1. - HadronVec.P()/(ProtonVec.P() - smeared_c9)) *
114  exp(-1. * smeared_c3 * pow(HadronVec.P(), smeared_c4) / pow(ProtonVec.P(), smeared_c5)) *
115  exp(-1. * smeared_c6 * HadronVec.Theta() *(HadronVec.P() - smeared_c7 * ProtonVec.P() * pow(cos(HadronVec.Theta()), smeared_c8)));
116 
117  // Check taken from MiniBooNE code
118  if((HadronVec.P()) > ((ProtonVec.P()) - (smeared_c9))){
119  RW = 0;
120  }
121 
122  double weight = 1;
123 
124  if(RW < 0 || CV < 0){//dont bother this; if this happens, the weight would be skipped...
125  weight = 1;
126  }
127  else if(fabs(CV) < 1.e-12){
128  weight = 1;
129  }
130  else{
131  weight *= RW/CV;
132  }
133 
134  if(weight < 0) weight = 0;
135  if(weight > 30) weight = 30;
136  if(!(std::isfinite(weight))){
137  std::cout << "SW : Failed to get a finite weight" << std::endl;
138  weight = 30;
139  }
140 
141  std::pair<bool, double> output(parameters_pass, weight);
142 
143  return output;
144 
145 
146  }
147 
148 
149  } // namespace evwgh
150 } // namespace sbn
151 
152 
153 
std::vector< double > FitVal
Definition: FluxCalcPrep.h:71
std::pair< bool, double > PHSWWeightCalc(simb::MCFlux flux, std::vector< float > rand)
bool isfinite(Vector const &v)
Returns whether all components of the vector are finite.
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG simSlidingORM6O6 effSlidingORW output
std::vector< std::vector< double > > MultiGaussianSmearing(std::vector< double > const &centralValue, std::vector< std::vector< double > > const &inputCovarianceMatrix, int n_multisims, CLHEP::RandGaussQ &GaussRandom)
BEGIN_PROLOG could also be cout