All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FluxCalcPrep.cxx
Go to the documentation of this file.
1 #include "FluxCalcPrep.h"
2 //Need to include headers explicitly after v9_33_00
3 
4 #include "fhiclcpp/ParameterSet.h"
5 
6 
7 namespace sbn {
8  namespace evwgh {
9 
10  //Configure everything here!
11  void FluxWeightCalc::Configure(fhicl::ParameterSet const& p,
12  CLHEP::HepRandomEngine& engine) {
13  std::cout<<"SBNEventWeight Flux: configure "<< GetName() << std::endl;
14 
15  fGeneratorModuleLabel = p.get<std::string>("generator_module_label");//use this label to get MC*Handle
16  const fhicl::ParameterSet& pset = p.get<fhicl::ParameterSet>(GetName());
17 
18  //0. << Reweighting Environment >>
19 
20  //skip "random_seed"
21  auto const& pars = pset.get<std::vector<std::string> >("parameter_list");
22  std::vector< float > parsigmas(pars.size(), 1.0);
23  if (pars.size() != parsigmas.size()) {
24  throw cet::exception(__PRETTY_FUNCTION__) << GetName() << ": "
25  << "parameter_list and parameter_sigma length mismatch."
26  << std::endl;
27  }
28 
29  if(!pset.get_if_present("parameter_sigma", parsigmas)){
30  std::cout<<"SBNEventWeight Flux: `parameter_sigma` was not set; now it is set as 1"<<std::endl;
31  }
32 
33  std::string fMode = pset.get<std::string>("mode");//3 types: multisim/pmNsigma/fixed
34  int number_of_multisims = pset.get<int>("number_of_multisims", 1);
35 
36  fParameterSet.Configure(GetFullName(), fMode, number_of_multisims);
37  for (size_t i=0; i<pars.size(); i++) {
38  //Note: no sigma is used in this script.
39  fParameterSet.AddParameter(pars[i], parsigmas[i]);//parsigmas[i]);
40  }
41 
42 
43  //1. << Calculator Settings >>
44  CalcType = pset.get< std::string >("calc_type");//Unisim,PrimaryHadronSWCentralSplineVariation,PrimaryHadronFeynmanScaling,PrimaryHadronSanfordWang,PrimaryHadronNormalization
45  std::cout<<"SBNEventWeight Flux: Calculator type: "<<CalcType<<std::endl;
46 
47  fScalePos = pset.get<double>("scale_factor_pos");
48  if(!pset.get_if_present("scale_factor_neg",fScaleNeg)){
49  std::cout<<"SBNEventWeight Flux: auto-assignment: scale_factor_neg = 1."<<std::endl;
50  }
51 
52  cet::search_path sp("FW_SEARCH_PATH");
53  bool validC = true;
54 
55  //----------------------------
56  //-- Non hadrons production --
57  //----------------------------
58 
59 
60  fParameterSet.Sample(engine);//random_seed is loaded at sbncode/Base/WeightManager.h
61 
62  if( CalcType == "Unisim"){//Unisim Calculator
63 
64  std::string dataInput1 = pset.get< std::string >("CentralValue_hist_file");
65  std::string cvfile_path = sp.find_file(dataInput1);
66  TFile fcv(Form("%s",cvfile_path.c_str()));
67 
68  std::string dataInput2pos = pset.get< std::string >("PositiveSystematicVariation_hist_file");
69  std::string rwfilepos = sp.find_file(dataInput2pos);
70  TFile frwpos(Form("%s", rwfilepos.c_str()));
71 
72  std::string dataInput2neg = pset.get< std::string >("NegativeSystematicVariation_hist_file");
73  std::string rwfileneg = sp.find_file(dataInput2neg);
74  TFile frwneg(Form("%s", rwfileneg.c_str()));
75 
76  if(dataInput2pos == dataInput2neg) PosOnly = true;//true - for skin depth
77  //Those May07*.root use the following convention to name histograms
78  int cptype[4] = {1,2,3,4}; //mu, pi, k0, k
79  int cntype[4] = {1,2,3,4}; //nue, anue, numu, anumu
80 
81  for (int iptyp=0;iptyp<4;iptyp++) {
82  for (int intyp=0;intyp<4;intyp++) {
83  for (int ibin=0;ibin<200;ibin++) { //Grab events from ibin+1
84  fCV[iptyp][intyp][ibin]=(dynamic_cast<TH1F*> (fcv.Get(Form("h5%d%d",cptype[iptyp],cntype[intyp]))))->GetBinContent(ibin+1);
85  fRWpos[iptyp][intyp][ibin]=(dynamic_cast<TH1F*> (frwpos.Get(Form("h5%d%d",cptype[iptyp],cntype[intyp]))))->GetBinContent(ibin+1);
86  fRWneg[iptyp][intyp][ibin]=(dynamic_cast<TH1F*> (frwneg.Get(Form("h5%d%d",cptype[iptyp],cntype[intyp]))))->GetBinContent(ibin+1);
87  }// energy bin
88  }// type of neutrinos
89  }//type of hadron parent
90  fcv.Close();
91  frwpos.Close();
92  frwneg.Close();
93 
94  //-------------
95  //-- Hadrons --
96  //-------------
97  } else if( CalcType.compare(0, 13,"PrimaryHadron") == 0){//Hadron Calculators
98 
99  fprimaryHad = pset.get< std::vector<int>>("PrimaryHadronGeantCode");
100 
101  if( CalcType == "PrimaryHadronNormalization" ){//k-
102 
103  fParameterSet.Sample(engine);//Yes.. load it again;
104 
105  } else{//Other Hadron Calculators
106 
107  std::string dataInput = pset.get< std::string >("ExternalData");
108  std::string ExternalDataInput = sp.find_file(dataInput);
109  TFile* file = new TFile(Form("%s",ExternalDataInput.c_str()));
110 
111  std::vector< std::string > pname; // these are keys to histograms
112  if( CalcType == "PrimaryHadronFeynmanScaling" ){//k+
113 
114  pname.push_back("FS/KPlus/FSKPlusFitVal");
115  pname.push_back("FS/KPlus/FSKPlusFitCov");
116 
117  TArrayD* FSKPlusFitValArray = (TArrayD*) file->Get(pname[0].c_str());
118  FitVal = FluxWeightCalc::ConvertToVector(FSKPlusFitValArray);
119  FitCov = (TMatrixD*) file->Get(pname[1].c_str());
120  *(FitCov) *= fScalePos*fScalePos;
121 
122  }else if( CalcType == "PrimaryHadronSanfordWang" ){//k0
123  pname.push_back("SW/K0s/SWK0sFitVal");
124  pname.push_back("SW/K0s/SWK0sFitCov");
125  TArrayD* SWK0FitValArray = (TArrayD*) file->Get(pname[0].c_str());
126 
127  FitVal = FluxWeightCalc::ConvertToVector(SWK0FitValArray);//TArrayD--> vector
128  FitCov = (TMatrixD*) file->Get(pname[1].c_str());
129  *(FitCov) *= fScalePos*fScalePos;
130 
131  }else if( CalcType == "PrimaryHadronSWCentralSplineVariation" ){//pi+-
132 
133  std::string fitInput = pset.get< std::string >("ExternalFit");
134  std::string HadronName;
135  std::string HadronAbriviation;
136  if(fprimaryHad[0] == 211){
137  HadronName = "PiPlus";
138  HadronAbriviation = "PP";
139  } else if(fprimaryHad[0] == -211){
140  HadronName = "PiMinus";
141  HadronAbriviation = "PM";
142  } else{
143  throw art::Exception(art::errors::StdException)
144  << "sanford-wang is only configured for charged pions ";
145  }
146  pname.push_back( Form("HARPData/%s/%sCrossSection",HadronName.c_str(),HadronAbriviation.c_str()) ); // Cross Section
147  pname.push_back( Form("HARPData/%s/%scovarianceMatrix",HadronName.c_str(),HadronAbriviation.c_str()) ); // Covariance Matrix
148  pname.push_back( Form("HARPData/%s/%smomentumBoundsArray",HadronName.c_str(),HadronAbriviation.c_str()) ); // Momentum Bounds
149  pname.push_back( Form("HARPData/%s/%sthetaBoundsArray",HadronName.c_str(),HadronAbriviation.c_str()) ); // Theta Bounds
150 
151  HARPXSec = (TMatrixD*) file->Get(pname[0].c_str());
152  TMatrixD* HARPCov = (TMatrixD*) file->Get(pname[1].c_str());
153 
154  TDecompChol dc = TDecompChol(*(HARPCov));//perform Choleskey Decomposition
155  if(!dc.Decompose()){
156  throw art::Exception(art::errors::StdException)
157  << "Cannot decompose covariance matrix to begin smearing.";
158  }
159 
160  //Get upper triangular matrix. This maintains the relations in the
161  // covariance matrix, but simplifies the structure.
162  fIsDecomposed = true;
163  FitCov = new TMatrixD(dc.GetU());
164 
165 
166  TArrayD* HARPmomentumBoundsArray = (TArrayD*) file->Get(pname[2].c_str());
167  HARPmomentumBounds = FluxWeightCalc::ConvertToVector(HARPmomentumBoundsArray);
168 
169  TArrayD* HARPthetaBoundsArray = (TArrayD*) file->Get(pname[3].c_str());
170  HARPthetaBounds = FluxWeightCalc::ConvertToVector(HARPthetaBoundsArray);
171 
172  /////////////////
173  //
174  // Extract the Sanford-Wang Fit Parmeters
175  //
176  ////////////////
177 
178  std::string ExternalFitInput = sp.find_file(fitInput);
179  TFile* Fitfile = new TFile(Form("%s",ExternalFitInput.c_str()));
180 
181  std::string fitname; // these are what we will extract from the file
182  fitname = Form("SW/%s/SW%sFitVal",HadronName.c_str(),HadronName.c_str()); // Sanford-Wang Fit Parameters
183 
184  TArrayD* SWParamArray = (TArrayD*) Fitfile->Get(fitname.c_str());
186 
187 
188  }else validC = false;//slightly incorrect calculator name in *fcl
189 
190  if(validC){//load random numbers based on FitCov
191  //{2*multisim vector}
192  //{{Ncols() elements}} <-- feed these amount everytime;
193  for( int index = 1; index < 2*(FitCov->GetNcols()); index ++){
194  fParameterSet.Sample(engine);//load it 2*<number_of_multisims> times
195  }
196 
197  }else {
198  throw cet::exception(__PRETTY_FUNCTION__) << GetName() << ": "
199  <<" calculator "+CalcType + "is invalid"
200  <<std::endl;
201  }
202 
203 
204  }//end of special Hadron calculator configurations
205 
206  } else validC = false; //the calculator name is way too off.
207 // std::cout<<"SBNEventWeight : finish configuration."<<std::endl;
208  }//End of Configure() function
209 
210 
211  std::vector<float> FluxWeightCalc::GetWeight(art::Event& e, size_t inu) {
212  bool count_weights = false;
213 // std::cout<<"SBNEventWeight : getweight for the "<<inu<<" th particles of an event"<< std::endl;
214  //MCFlux & MCTruth
215  art::Handle< std::vector<simb::MCFlux> > mcFluxHandle;
216  e.getByLabel(fGeneratorModuleLabel,mcFluxHandle);
217  std::vector<simb::MCFlux> const& fluxlist = *mcFluxHandle;
218  //or do the above 3 lines in one line
219 // auto const& mclist = *e.getValidHandle<std::vector<simb::MCTruth>>(fGeneratorModuleLabel);
220 
221  // If no neutrinos in this event, gives 0 weight;
222  int NUni = fParameterSet.fNuniverses;
223  std::vector<float> weights;//( mclist.size(), 0);
224  if(fluxlist.size() == 0){
225  std::cout<<"SBNEventWeight Flux: EMPTY WEIGHTS"<<std::endl;
226  return weights;
227  }
228 
229  //Iterate through each neutrino in the event
230  std::cout<<"SBNEventWeight Flux: Get calculator "<<CalcType<<std::endl;
231  if( CalcType == "Unisim"){//Unisim Calculator
232  weights.resize(NUni);
233  //Unisim specific
234  //containers for the parent and neutrino type information
235  int ptype = std::numeric_limits<int>::max();
236  int ntype = std::numeric_limits<int>::max();
237 
238  // Discover the neutrino parent type
239  // This contains the neutrino's parentage information
240  if ( fluxlist[inu].fptype==13 || fluxlist[inu].fptype==-13 ) ptype = 0;//mu
241  else if ( fluxlist[inu].fptype==211 || fluxlist[inu].fptype==-211 ) ptype = 1;//pi
242  else if ( fluxlist[inu].fptype==130 ) ptype = 2;//K0
243  else if ( fluxlist[inu].fptype==321 || fluxlist[inu].fptype==-321 ) ptype = 3;//K
244  else {
245  throw cet::exception(__FUNCTION__) << GetName()<<"::Unknown ptype "<<fluxlist[0].fptype<< std::endl;
246  }
247 
248  // Discover the neutrino type
249  // This contains the neutrino's flavor information
250  if ( fluxlist[inu].fntype== 12 ) ntype=0;//nue
251  else if ( fluxlist[inu].fntype==-12 ) ntype=1;//nuebar
252  else if ( fluxlist[inu].fntype== 14 ) ntype=2;//numu
253  else if ( fluxlist[inu].fntype==-14 ) ntype=3;//numubar
254  else {
255  throw cet::exception(__FUNCTION__) << GetName()<<"::Unknown ntype "<<fluxlist[inu].fntype<< std::endl;
256  }
257 
258  // Collect neutrino energy; mclist is replaced with fluxlist.
259 // double enu= mclist[inu].GetNeutrino().Nu().E();
260  double enu= fluxlist[inu].fnenergyn;
261 
262  //Let's make a weights based on the calculator you have requested
263 
265 
266  for (size_t i=0;i<weights.size();i++) {
267  double randomN = (fParameterSet.fParameterMap.begin())->second[i];
268  weights[i]=UnisimWeightCalc(enu, ptype, ntype, randomN , PosOnly);//AddParameter result does not work here;
269 
270  if(count_weights){
271  if(weights[i]<0){
272  wcn++;
273  }else if((weights[i]-0)<1e-30){
274  wc0++;
275  }else if(fabs(weights[i]-30) < 1e-30){
276  wc30++;
277  } else if(fabs(weights[i]-1)<1e-30){
278  wc1++;
279  } else {
280  wc++;
281  }
282  }
283  }//Iterate through the number of universes
284  }
285  } else{//then this must be PrimaryHadron
286 
287 
288  // First let's check that the parent of the neutrino we are looking for is
289  // the particle we intended it to be, if not set all weights to 1
290  if (std::find(fprimaryHad.begin(), fprimaryHad.end(),(fluxlist[inu].ftptype)) == fprimaryHad.end() ){//if it does not contain any particles we need get 1
291  weights.resize( NUni);
292  std::fill(weights.begin(), weights.end(), 1);
293  return weights;//done, all 1
294  }// Hadronic parent check
295 
297 
298  for (unsigned int i = 0; int(weights.size()) < NUni; i++) {//if all weights are 1, no need to calculate weights;
299  std::pair<bool, double> test_weight;
300 
301  std::vector< float > Vrandom = (fParameterSet.fParameterMap.begin())->second;//vector of random #
302  std::vector< float > subVrandom;//sub-vector of random numbers;
303  if( CalcType == "PrimaryHadronNormalization"){//Normalization
304  test_weight = PHNWeightCalc(fluxlist[inu], Vrandom[i]);
305 
306  } else {
307  subVrandom = {Vrandom.begin()+i*FitCov->GetNcols(), Vrandom.begin()+(i+1)*FitCov->GetNcols()};
308  if( CalcType == "PrimaryHadronFeynmanScaling"){//FeynmanScaling
309  test_weight = PHFSWeightCalc(fluxlist[inu], subVrandom);
310 
311  } else if( CalcType == "PrimaryHadronSanfordWang"){//SanfordWang
312  test_weight = PHSWWeightCalc(fluxlist[inu], subVrandom);
313 
314  } else if( CalcType == "PrimaryHadronSWCentralSplineVariation"){//SWCentaralSplineVariation
315  test_weight = PHSWCSVWeightCalc(fluxlist[inu], subVrandom);
316 
317  } else throw cet::exception(__PRETTY_FUNCTION__) << GetName() << ": this shouldnt happen.."<<std::endl;
318  }
319 
320  if(test_weight.first){
321  weights.push_back(test_weight.second);
322  double tmp_weight = test_weight.second;
323 // std::cout<<i<<" ("<<tmp_weight<<") ";
324  if(count_weights){
325  if(tmp_weight<0){
326  wcn++;
327  }else if((tmp_weight-0)<1e-30){
328  wc0++;
329  }else if(fabs(tmp_weight-30) < 1e-30){
330  wc30++;
331  } else if(fabs(tmp_weight-1)<1e-30){
332  wc1++;
333  } else {
334  wc++;
335  }
336  }
337 
338  };
339 
340  }//Iterate through the number of universes
341  }//Yes, Multisim
342  }
343 
344  if(count_weights){
345  std::cout<<"SBNEventWeight Flux: Weights counter: (normal, <0, ==0, 1, 30)= ";
346  std::cout<<wc<<", "<<wcn<<", "<<wc0<<", "<<wc1<<", "<<wc30<<std::endl;
347  }
348 // std::cout<<"Next partile/event\n"<<std::endl;
349 
350  return weights;
351  }//GetWeight()
352 
353 
354  std::vector<double> FluxWeightCalc::ConvertToVector(TArrayD const* array) {
355  std::vector<double> v(array->GetSize());
356  std::copy(array->GetArray(), array->GetArray() + array->GetSize(),
357  v.begin());
358  return v;
359  } // ConvertToVector()
360 
362  } // namespace evwgh
363 } // namespace sbn
364 
void AddParameter(std::string name, float width, float mean=0, size_t covIndex=0)
std::vector< double > FitVal
Definition: FluxCalcPrep.h:71
std::vector< double > HARPmomentumBounds
Definition: FluxCalcPrep.h:76
std::string fGeneratorModuleLabel
Definition: FluxCalcPrep.h:55
* file
Definition: file_to_url.sh:69
std::pair< bool, double > PHSWCSVWeightCalc(simb::MCFlux flux, std::vector< float > rand)
pdgs p
Definition: selectors.fcl:22
double UnisimWeightCalc(double enu, int ptype, int ntype, double randomN, bool noNeg)
double fRWpos[4][4][200]
Definition: FluxCalcPrep.h:64
void Configure(std::string name, ReweightType rwtype, size_t nuni=1)
std::pair< bool, double > PHSWWeightCalc(simb::MCFlux flux, std::vector< float > rand)
ReweightType fRWType
Type of throws (the same for all parameters in a set)
createEngine fMode
void Sample(CLHEP::HepRandomEngine &engine)
std::map< EventWeightParameter, std::vector< float > > fParameterMap
Mapping of definitions to the set of values.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
size_t fNuniverses
Number of universes (i.e. random throws)
std::vector< double > SWParam
Definition: FluxCalcPrep.h:78
then ntype
std::vector< double > ConvertToVector(TArrayD const *array)
std::vector< double > HARPthetaBounds
Definition: FluxCalcPrep.h:77
double fRWneg[4][4][200]
Definition: FluxCalcPrep.h:65
void Configure(fhicl::ParameterSet const &p, CLHEP::HepRandomEngine &engine) override
#define REGISTER_WEIGHTCALC(wghcalc)
do i e
T copy(T const &v)
std::pair< bool, double > PHNWeightCalc(simb::MCFlux flux, float rand)
std::pair< bool, double > PHFSWeightCalc(simb::MCFlux flux, std::vector< float > rand)
std::vector< int > fprimaryHad
Definition: FluxCalcPrep.h:69
double fCV[4][4][200]
Definition: FluxCalcPrep.h:63
BEGIN_PROLOG could also be cout
std::vector< float > GetWeight(art::Event &e, size_t inu) override