TargetAttenuationReweighter.cpp
Go to the documentation of this file.
1 
3 #include <iostream>
4 #include <locale>
5 #include <cstdlib>
6 #include <stdexcept>
7 #include "AttenuationMC.h"
8 #include "MIPPNumiYieldsBins.h"
9 #include "MakeReweight.h"
10 #include "ReweightDriver.h"
11 
12 
13 // FIXME: hzpos may be uninitialized in TargetAttenuationReweighter.cpp
14 #if defined __clang__
15 #elif defined __GNUC__
16  #pragma GCC diagnostic push
17  #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
18 #endif
19 namespace NeutrinoFluxReweight{
20 
22  :cvPars(cv_pars),univPars(univ_pars),iUniv(iuniv){
23 
24  // const boost::interprocess::flat_map<std::string, double>& this_table = univPars.getMap();
25  prod_prtC_xsec = univPars.getParameterValue("prod_prtC_xsec");
26  qe_prtC_xsec = univPars.getParameterValue("qe_prtC_xsec");
28  delta_sigma_kapC_xsec_lowP = univPars.getParameterValue("inel_kapC_xsec_lowP");
29  delta_sigma_kapC_xsec_highP = univPars.getParameterValue("inel_kapC_xsec_highP");
30  delta_sigma_kamC_xsec_lowP = univPars.getParameterValue("inel_kamC_xsec_lowP");
31  delta_sigma_kamC_xsec_highP = univPars.getParameterValue("inel_kamC_xsec_highP");
32 
33  }
35 
36  }
38  std::vector<bool> can_rws;
39  std::vector<InteractionData> vec_inter = aa.interaction_chain;
40  int ninter = vec_inter.size();
41  std::string mode(getenv("MODE"));
42  //Looking if there is a proton-Target interaction:
43  for(int ii=0;ii<ninter;ii++){
44  if(vec_inter[ii].Inc_P==0.0){
45  can_rws.push_back(false);
46  return can_rws;
47  }
48  if(ii==0){
49  //first interaction in the target or a primary proton passing through the target
50 
51  bool is_tgt_int = vec_inter[0].Vol == "BudalMonitor" || vec_inter[0].Vol == "TGT1" || vec_inter[0].Vol == "Budal_HFVS" || vec_inter[0].Vol == "Budal_VFHS";
52  if((mode=="REF")||(mode=="OPT")){
53  is_tgt_int = vec_inter[0].Vol == "TargetFinHorizontal" || vec_inter[0].Vol == "TargetNoSplitSegment" || vec_inter[0].Vol=="tCoreLog";
54  }
55  if(is_tgt_int)can_rws.push_back(true);
56  else if(vec_inter[0].Inc_pdg == 2212)can_rws.push_back(true);
57  else can_rws.push_back(false);
58  }
59  //Absorption in the target of the secondaries:
60  else{
61  bool starts_tgt = vec_inter[ii-1].Vol == "BudalMonitor" || vec_inter[ii-1].Vol == "TGT1" || vec_inter[ii-1].Vol == "Budal_HFVS" || vec_inter[ii-1].Vol == "Budal_VFHS";
62  bool ends_tgt = vec_inter[ii].Vol == "BudalMonitor" || vec_inter[ii].Vol == "TGT1" || vec_inter[ii-1].Vol == "Budal_HFVS" || vec_inter[ii-1].Vol == "Budal_VFHS";
63  if((mode=="REF")||(mode=="OPT")){
64  starts_tgt = vec_inter[ii-1].Vol == "TargetFinHorizontal" || vec_inter[ii-1].Vol == "TargetNoSplitSegment"|| vec_inter[0].Vol=="tCoreLog";
65  ends_tgt = vec_inter[ii-1].Vol == "TargetFinHorizontal" || vec_inter[ii-1].Vol == "TargetNoSplitSegment"||vec_inter[0].Vol=="tCoreLog";
66  }
67  if(starts_tgt && ends_tgt){
68  can_rws.push_back(true);
69  }
70  else if(starts_tgt && !ends_tgt){
71  can_rws.push_back(true);
72  }
73  else{
74  can_rws.push_back(false);
75  }
76  }
77  }
78 
79  return can_rws;
80  }
82  std::string mode(getenv("MODE"));
83  double wgt =1.0;
84 
86  bool domipp = (makerew->cv_rw)->doMIPPNumi;
87 
88  //Some constants:
89  const double graphite_density=1.78;// g/cc
90  const double avog_x_mb2cm2 = 6.02214e-4; //useful constant
91  const double graphite_A = 12.01; // g/mole
92 
93  std::vector<InteractionData> vec_inter = aa.interaction_chain;
94 
95  //Finding the Data and MC total cross sections:
98 
99  bool there_is_MIPP = false;
100  bool it_is_survival = false;
101 
102  //MIPP:
103  TargetData tar = aa.tar_info;
104  int binID = MIPPbins->BinID(tar.Pz,tar.Pt,tar.Tar_pdg);
105  bool is_le = isLE(aa.target_config);
106  bool is_me = isME(aa.target_config);
107  if( !is_le && !is_me ){
108  throw std::runtime_error("cannot determine if it's LE or ME beam");
109  }
110 
111  TH1D* hzpos;
112  if(binID>=0){
113  if(tar.Tar_pdg == 211 || tar.Tar_pdg ==- 211){
114  there_is_MIPP = true;
115  if(tar.Tar_pdg == 211 && is_le)hzpos = dtH->hzpostgt_pip_le[binID];
116  if(tar.Tar_pdg == 211 && is_me)hzpos = dtH->hzpostgt_pip_me[binID];
117  if(tar.Tar_pdg ==-211 && is_le)hzpos = dtH->hzpostgt_pim_le[binID];
118  if(tar.Tar_pdg ==-211 && is_me)hzpos = dtH->hzpostgt_pim_me[binID];
119  }
120  else if(tar.Tar_pdg == 321){
121  int aux_binID = MIPPbins->BinID(tar.Pz,tar.Pt,211);
122  if(aux_binID>=0){
123  there_is_MIPP = true;
124  //I substracted 78 because we store all histos in AttenuationMC but the kaon histograms make
125  // sense after P>20 GeV/c and we are using bin ID convention here.
126  if(is_le)hzpos = dtH->hzpostgt_kap_le[aux_binID-78];
127  if(is_me)hzpos = dtH->hzpostgt_kap_me[aux_binID-78];
128  }
129  }
130  else if(tar.Tar_pdg == -321){
131  int aux_binID = MIPPbins->BinID(tar.Pz,tar.Pt,-211);
132  if(aux_binID>=0){
133  there_is_MIPP = true;
134  if(is_le)hzpos = dtH->hzpostgt_kam_le[aux_binID-78];
135  if(is_me)hzpos = dtH->hzpostgt_kam_me[aux_binID-78];
136  }
137  }
138  else if(tar.Tar_pdg == 130 || tar.Tar_pdg == 310){
139  int aux_binID = MIPPbins->BinID(tar.Pz,tar.Pt,211);
140  if(aux_binID>=0){
141  there_is_MIPP = true;
142  if(is_le)hzpos = dtH->hzpostgt_kap_le[aux_binID-78];
143  if(is_me)hzpos = dtH->hzpostgt_kap_me[aux_binID-78];
144  }
145  }
146  else{
147  std::cout<<"=> There is an in MIPPNumiYieldsBins"<<std::endl;
148  }
149  }
150 
151  //Survival:
152  if(!there_is_MIPP && vec_inter[0].Vol!="BudalMonitor" && vec_inter[0].Vol!="TGT1" && vec_inter[0].Vol!="Budal_HFVS" && vec_inter[0].Vol!="Budal_VFHS"){
153  it_is_survival = true;
154  }
155  if((mode=="REF")||(mode=="OPT")){
156  if(!there_is_MIPP && vec_inter[0].Vol!="TargetFinHorizontal" && vec_inter[0].Vol!="TargetNoSplitSegment" && vec_inter[0].Vol!="tCoreLog"){
157 
158  it_is_survival = true;
159  }
160  }
161 
162  double delta_sigma = 0.0; // sigma_data - sigma_mc
163  double ratio_sigma = 0.0; // sigma_data / sigma_mc
164 
165  delta_sigma = prod_prtC_xsec;
166  delta_sigma += qe_prtC_xsec;
167 
168  int binpartC = (dtH->hXS_prtC)->FindBin(vec_inter[0].Inc_P);
169  double mcval = (dtH->hXS_prtC)->GetBinContent(binpartC);
170  if(mcval<1.e-12){
171  std::cout<<"This seems especial cases in which the proton interact before the target (Air?). we need to investigate it."<<" Inc_P "<<vec_inter[0].Inc_P<<std::endl;
172  return 1.;
173  }
174  ratio_sigma = delta_sigma / mcval;
175  delta_sigma -= mcval;
176 
177  //Finding the target penetration for the primary proton beam:
178 
179  double startZ = targetStartZ(aa.target_config) + shiftPlaylist(aa.playlist);
180  double endZ = (vec_inter[0].Vtx)[2];
181  double totmatZ = 0.; //this will be the amount of material passed.
182 
183  if( is_le){
184  //check of initial z position:
185  if(vec_inter[0].Vol=="BudalMonitor"){
186  if(endZ<startZ || endZ>(startZ+2.0))std::cout<<"Potential error of BudalMonitor=> startZ, endZ: "<<startZ<<" "<<endZ<<std::endl;
187  }
188  if((mode=="OPT")||(mode=="REF")){
189  if(vec_inter[0].Vol=="TargetFinHorizontal"){
190  if(endZ<startZ || endZ>(startZ+2.0))std::cout<<"Potential error of BudalMonitor=> startZ, endZ: "<<startZ<<" "<<endZ<<std::endl;
191  }
192  }
193  totmatZ = getTargetPenetrationLE(startZ,endZ,startZ);
194  // std::cout<<"TargetAttenuation:: Start Z "<<startZ<<" End Z "<<endZ<<" totMatZ "<<totmatZ<<" "<<vec_inter[0].Vol<<std::endl;
195  }
196  else if( is_me ){
197  //check of initial z position:
198  if(vec_inter[0].Vol=="Budal_HFVS"){
199  if(endZ<startZ || endZ>(startZ+2.4))std::cout<<"Potential error of Budal_HFVS => startZ, endZ: "<<startZ<<" "<<endZ<<std::endl;
200  }
201  totmatZ = getTargetPenetrationME(startZ,endZ,startZ);
202  }
203 
204  if(totmatZ<0)totmatZ=0;
205 
206  totmatZ *= avog_x_mb2cm2;
207  totmatZ /= graphite_A;
208  totmatZ *= graphite_density;
209 
210  //Calculating the weight:
211  double norm = 1.0;
212  if(there_is_MIPP && domipp){
213  int nbins = hzpos->GetXaxis()->GetNbins();
214  double integral_mc = 0;
215  double integral_wt = 0;
216  for(int ib=1;ib<=nbins;ib++){
217  double cont = hzpos->GetBinContent(ib);
218  double crr = hzpos->GetXaxis()->GetBinCenter(ib);
219  integral_mc += cont;
220  integral_wt += cont*ratio_sigma*exp(-1.0*crr*avog_x_mb2cm2*graphite_density*delta_sigma/graphite_A);
221  }
222  if(integral_wt<=0 || integral_mc<=0){
223  throw std::runtime_error("yield is zero or negative... check!");
224  }
225  norm = integral_mc/integral_wt;
226  }
227 
228  //Calculating the weight for the primary:
229  double wgt_pri = 1.0;
230 
231  if(it_is_survival){
232  wgt_pri = exp(-1.0*totmatZ*delta_sigma);
233  }
234  else{
235  wgt_pri = norm*ratio_sigma*exp(-1.0*totmatZ*delta_sigma);
236  }
237 
238  //Calculating the weight for secondaries, tertiaries, etc:
239  double wgt_sec = 1.0;
240  if(!domipp){
241  for(size_t ii=1;ii<vec_inter.size();ii++){
242  bool starts_tgt = vec_inter[ii-1].Vol == "BudalMonitor" || vec_inter[ii-1].Vol == "TGT1" || vec_inter[ii-1].Vol == "Budal_HFVS" || vec_inter[ii-1].Vol == "Budal_VFHS";
243  if((mode=="REF")||(mode=="OPT")){
244  starts_tgt = vec_inter[ii-1].Vol == "TargetFinHorizontal" || vec_inter[ii-1].Vol == "TargetNoSplitSegment"|| vec_inter[ii-1].Vol == "tCoreLog";
245  }
246  if(!starts_tgt)continue;
247  bool ends_tgt = vec_inter[ii].Vol == "BudalMonitor" || vec_inter[ii].Vol == "TGT1" || vec_inter[ii].Vol == "Budal_HFVS" || vec_inter[ii].Vol == "Budal_VFHS";
248  if((mode=="REF")||(mode=="OPT")){
249  ends_tgt = vec_inter[ii].Vol == "TargetFinHorizontal" || vec_inter[ii].Vol == "TargetNoSplitSegment" || vec_inter[ii].Vol == "tCoreLog";
250  }
251  //double totmatR = 0.0;
252  double dsigma = 0.0;
253  double fact_int = 1.0;
254  double fact = 1.0;
255  //dsigma and fact_int:
256  if(vec_inter[ii].Inc_pdg==2212){
257  dsigma = delta_sigma;
258  binpartC = (dtH->hXS_prtC)->FindBin(vec_inter[ii].Inc_P);
259  mcval = (dtH->hXS_prtC)->GetBinContent(binpartC);
260  fact_int = (dsigma+mcval)/mcval;
261  }
262  else if(vec_inter[ii].Inc_pdg==211 || vec_inter[ii].Inc_pdg==-211){
263  dsigma = delta_sigma_piC_xsec;
264  binpartC = (dtH->hXS_piC)->FindBin(vec_inter[ii].Inc_P);
265  mcval = (dtH->hXS_piC)->GetBinContent(binpartC);
266  fact_int = (dsigma+mcval)/mcval;
267  }
268  else if(vec_inter[ii].Inc_pdg == 321){
269  if(vec_inter[ii].Inc_P<2.0) dsigma = delta_sigma_kapC_xsec_lowP;
270  if(vec_inter[ii].Inc_P>=2.0)dsigma = delta_sigma_kapC_xsec_highP;
271  binpartC = (dtH->hXS_kapC)->FindBin(vec_inter[ii].Inc_P);
272  mcval = (dtH->hXS_kapC)->GetBinContent(binpartC);
273  fact_int = (dsigma+mcval)/mcval;
274  }
275  else if(vec_inter[ii].Inc_pdg ==-321){
276  if(vec_inter[ii].Inc_P<2.0) dsigma = delta_sigma_kamC_xsec_lowP;
277  if(vec_inter[ii].Inc_P>=2.0)dsigma = delta_sigma_kamC_xsec_highP;
278  binpartC = (dtH->hXS_kamC)->FindBin(vec_inter[ii].Inc_P);
279  mcval = (dtH->hXS_kamC)->GetBinContent(binpartC);
280  fact_int = (dsigma+mcval)/mcval;
281  }
282  else if(totmatZ<1.e-12){
283  dsigma = 0.0;
284  fact_int = 1.0;
285  }
286  else{
287  if(vec_inter[ii].Inc_P<2.0) dsigma = delta_sigma_kapC_xsec_lowP;
288  if(vec_inter[ii].Inc_P>=2.0)dsigma = delta_sigma_kapC_xsec_highP;
289  binpartC = (dtH->hXS_kapC)->FindBin(vec_inter[ii].Inc_P);
290  mcval = (dtH->hXS_kapC)->GetBinContent(binpartC);
291  fact_int = (dsigma+mcval)/mcval;
292  }
293  if(mcval<1.e-12){
294 
295  //std::cout<<"This seems especial cases in which the proton interact before the target (Air?). we need to investigate it."<<" Inc_P "<<vec_inter[0].Inc_P<<std::endl;
296 
297  return 1.;
298 
299  }
300  //Two cases: 1) ending in th target and leaving the target.
301  double zi = (vec_inter[ii-1].Vtx)[2];
302  double zf = 0.0;
303  if(ends_tgt){
304  zf = (vec_inter[ii].Vtx)[2];
305  fact = fact_int;
306  }
307  else if(!ends_tgt){
308  double startpart[3] = {(vec_inter[ii-1].Vtx)[0],(vec_inter[ii-1].Vtx)[1],(vec_inter[ii-1].Vtx)[2]};
309  double momtar[3] = {tar.Px,tar.Py,tar.Pz};
310  zf = getZTgtExit(startpart,momtar,is_le,is_me);
311  }
312  if(is_le) totmatZ = getTargetPenetrationLE(zi,zf,startZ);
313  if(is_me) totmatZ = getTargetPenetrationME(zi,zf,startZ);
314 
315  if(totmatZ<1.e-12){
316  dsigma = 0.0;
317  fact = 1.0;
318  }
319 
320  totmatZ *= avog_x_mb2cm2;
321  totmatZ /= graphite_A;
322  totmatZ *= graphite_density;
323  wgt_sec *= fact*exp(-1.0*totmatZ*dsigma);
324  if(isinf(wgt_sec))std::cout<<"BAD "<<zi<<" "<<zf<<" "<<totmatZ<<" "<<startZ<<
325  " "<<dsigma<<" "<<fact<<std::endl;
326 
327  }
328  }
329  // if(isinf(wgt_pri*wgt_sec))std::cout<<wgt_pri<<" "<<wgt_sec<<" "<<zi<<" "<<zf<<std::endl;
330  return wgt = wgt_pri*wgt_sec;
331 
332  }
333 
335 
336  std::string mode(getenv("MODE"));
337  //check this (Leo)
338  double z0=-51.1; // position of the upstream edge of the budal monitor in 000z config
339  // check to see if we are in LE config and adjust accordingly
340  if( isLE(tgtcfg) ) {
341  z0=-51.72; // determined by ntuple tomography
342  if(mode=="OPT")z0=0.0;//-27.3347;
343  if(mode=="REF")z0=-64.7002;
344  // check to see if we are in ME config and adjust accordingly
345  }else if( isME(tgtcfg) ){
346  z0=-143.3; // determined by ntuple tomography
347  // compared to LE target: recall, LE target is stuffed into the horn.
348  }
349  else{
350  throw std::runtime_error("cannot determine if it's LE or ME beam");
351  }
352  // pull out all the numbers, recording them into a string
353  std::string just_nums;
354  for (size_t i=0; i<tgtcfg.length(); ++i) {
355  if(isdigit(tgtcfg[i])) just_nums.push_back(tgtcfg[i]);
356  if(tgtcfg[i]=='z') break;
357  }
358  // now convert the string to a number
359  double dz=atof(just_nums.c_str());
360  //
361  return z0-dz;
362  }
363 
365  return (tgtcfg.find("LE")==0)|| (tgtcfg.find("le")==0) || (tgtcfg.find("Le")==0);
366  }
367 
368 
370  return (tgtcfg.find("ME")==0) || (tgtcfg.find("me")==0) || (tgtcfg.find("Me")==0);
371  }
372 
374  //Minerva definies dk2nu.vint[1] as the playlist ID.
375  //If this variable is not filled, then the value is filled as -1 in InteractionChainData
376  //If the experiment definied dk2nu.vint[1], this function needs to be remade.
377  double shift_for_playlist = 0;
378  if( ipl == -1 ){
379  shift_for_playlist = 0.;
380  }
381  else if( ipl == 0 || ipl == 1 ){
382  shift_for_playlist = 0.50;
383  }
384  else if( ipl == 7 || ipl == 10 || ipl == 6 ){
385  shift_for_playlist = 0.82;
386  }
387  else if( ipl == 9 ){
388  shift_for_playlist = -0.40;
389  }
390  else if( ipl == 13){
391  shift_for_playlist = 0.83;
392  }
393  else if( ipl == 5 ){
394  shift_for_playlist = 1.15;
395  }
396  else if( ipl == 2 || ipl == 3 ){
397  shift_for_playlist = 0.43;
398  }
399  else if( ipl == 11 || ipl == 12 ){
400  shift_for_playlist = 0.83;
401  }
402  else if( ipl == 4 ){
403  shift_for_playlist = 0.43;
404  }
405  else if( ipl == 8 ){
406  shift_for_playlist = - 0.09;
407  }
408 
409  return shift_for_playlist;
410 
411  }
412 
413  double TargetAttenuationReweighter::getTargetPenetrationLE(double z_start, double z_end, double z0_budal){
414  /*!
415  * Returns the amount of target material penetrated by a particle starting at
416  * z_start and interacting or exiting the target at z_end.
417  * the upstream edge of the budal monitor must be supplied.
418  * All inputs must be in units of cm.
419  */
420 
421  // fin edges determined by printing their position from inside g4numi.
422  // coordinate system will need to be translated such that the upstream
423  // edge of the budal monitor is at the value returned by target
424  // start z.
425  // coordinate here in cm
426  std::string mode(getenv("MODE"));
427  const int nfins=48;
428  const double us_edges[nfins]={25.4484, 42.1683, 44.1983, 46.2283, 48.2583,
429  50.2883, 52.3183, 54.3483, 56.3783,
430  58.4083, 60.4383, 62.4683, 64.4983,
431  66.5283, 68.5583, 70.5883, 72.6183,
432  74.6483, 76.6783, 78.7083, 80.7383,
433  82.7683, 84.7983, 86.8283, 88.8583,
434  90.8883, 92.9183, 94.9483, 96.9783,
435  99.0083, 101.0383, 103.0683, 105.0983,
436  107.1283, 109.1583, 111.1883, 113.2183,
437  115.2483, 117.2783, 119.3083, 121.3383,
438  123.3683, 125.3983, 127.4283, 129.4583,
439  131.4883, 133.5183, 135.5483};
440  const int nfins_ref=49;
441  //This is for the DUNE reference design target. A. Bashyal
442  const double us_edges_ref[nfins_ref]={-64.7002,-46.9176,-44.8909, -42.8609, -40.8309, -38.8009, -36.7709,
443  -34.7409, -32.7109, -30.6809, -28.6509, -26.6209, -24.5909,
444  -22.5609, -20.5309, -18.5009, -16.4709, -14.4409, -12.4109, -10.3809, -8.3509, -6.3209,
445  -4.2909, -2.2609, -0.2309, 1.7991, 3.8291, 5.8591, 7.8891, 9.9191, 11.9491, 13.9791, 16.0091,
446  18.0391, 20.0691, 22.0991, 24.1291, 26.1591, 28.1891, 30.2191,
447  32.2491, 34.2791, 36.3091, 38.3391, 40.3691, 42.3991, 44.4291, 46.4591, 48.4891};
448 
449  const int nfins_opt = 119;
450  const double us_edges_opt[nfins_opt] = {-27.3347,-0.0054, 4.0917, 6.0876, 8.1176, 10.1476, 12.1776, 14.2076, 16.2376, 18.2676, 20.2976, 22.3276, 24.3576, 26.3876, 28.4176, 30.4476, 32.4776, 34.5076, 36.5376, 38.5676, 40.5976,
451  42.6276, 44.6576, 46.6876, 48.7176, 50.7476, 52.7776, 54.8076, 56.8376, 58.8676, 60.8976, 62.9276, 64.9576, 66.9876, 69.0176, 71.0476, 73.0776, 75.1076, 77.1376, 79.1676, 81.1976,
452  83.2276, 85.2576, 87.2876, 89.3176, 91.3476, 93.3776, 95.4076, 97.4376, 99.4676, 101.498, 103.528, 105.558, 107.588, 109.618, 111.648, 113.678, 115.708, 117.738, 119.768, 121.798,
453  123.828, 125.858, 127.888, 129.918, 131.948, 133.978, 136.008, 138.038, 140.068, 142.098, 144.128, 146.158, 148.188, 150.218, 152.248, 154.278, 156.308, 158.338, 160.368, 162.398,
454  164.428, 166.458, 168.488, 170.518, 172.548, 174.578, 176.608, 178.638, 180.668, 182.698, 184.728, 186.758, 188.788, 190.818, 192.848, 194.878, 196.908, 198.938, 200.968, 202.998,
455  205.028, 207.058, 209.088, 211.118, 213.148, 215.178, 217.208, 219.238, 221.268, 223.298, 225.328, 227.358, 229.388,
456  231.418, 233.448, 235.478, 237.508};
457 
458 
459  // const int nfins_opt = 1;
460  // const double us_edges_opt[nfins_opt] = {0.0};
461 
462  std::vector<double> vus_edges;
463  for(int i = 0;i<nfins;i++){
464  vus_edges.push_back(us_edges[i]);
465  }
466  if(mode=="REF"){
467  vus_edges.clear();
468  for(int i = 0;i<nfins_ref-1;i++){
469  vus_edges.push_back(us_edges_ref[i]);
470  }
471  }
472  if(mode=="OPT"){
473  vus_edges.clear();
474  for(int i = 0;i<nfins_opt;i++){ //this was still nfins_opt
475  vus_edges.push_back(us_edges_opt[i]);
476  }
477  }
478 
479  const double budal_us_edge=vus_edges.at(0); // fin[0] is the budal
480  double fin_width=2.0;
481  //just to be not confused...this is fin thickness....the number taken from GEANT4. //Amit Bashyal
482  if(mode=="OPT")fin_width = 1.95;
483  if(mode=="REF")fin_width = 2.02;
484 
485  // budal_us_edge + z_trans = z0_budal
486  // z_trans = z0_budal - budal_us_edge
487  const double z_trans=z0_budal - budal_us_edge;
488 
489  // translated upstream edge of budal
490  // const double z_up=budal_us_edge+z_trans;
491 
492  // now, count the amount of material between z_up and z_start
493  // for primary protons this will be zero, but the routine
494  // should be written generally enough to handle the case
495  // in which a trajectory starts in the target
496  // we will end up subtracting this from the material between
497  // z_up and z_end to get the material traversed.
498 
499  double mat_start=0.0;
500  double mat_end = 0.0;
501 
502  for(unsigned int ifin=0; ifin<vus_edges.size(); ifin++){
503  const double fin_us_edge=vus_edges.at(ifin)+z_trans;
504  const double fin_ds_edge=fin_us_edge+fin_width;
505  if(z_start<=fin_us_edge) break; // no more material to add up
506  else if(z_start<fin_ds_edge){ // z_start in this fin
507  mat_start+=(z_start-fin_us_edge);
508  break;
509  }
510  else{ // z_start after this fin (z_start>fin_ds_edge)
511  mat_start+=fin_width;
512  }
513  }
514 
515  // now do the same thing for z_end
516 
517  for(unsigned int ifin=0; ifin<vus_edges.size(); ifin++){
518  const double fin_us_edge=vus_edges.at(ifin)+z_trans;
519  const double fin_ds_edge=fin_us_edge+fin_width;
520  if(z_end<=fin_us_edge) break; // no more material to add up
521  else if(z_end<fin_ds_edge){ // z_end in this fin
522  mat_end+=(z_end-fin_us_edge);
523  break;
524  }
525  else{ // z_end after this fin (z_end>fin_ds_edge)
526  mat_end+=fin_width;
527  }
528  }
529 
530 
531  double mat_traversed=mat_end-mat_start;
532 
533  // std::cout<<"material traversed is "<<mat_traversed<<std::endl;
534 
535  return mat_traversed;
536 
537  }
538 
539  double TargetAttenuationReweighter::getTargetPenetrationME(double z_start, double z_end, double z0_budal){
540 
541  /*!
542  * Returns the amount of target material penetrated by a particle starting at
543  * z_start and interacting or exiting the target at z_end.
544  * the upstream edge of the budal monitor must be supplied.
545  * All inputs must be in units of cm.
546  */
547 
548  // fin edges determined by printing their position from inside g4numi.
549  // coordinate system will need to be translated such that the upstream
550  // edge of the budal monitor is at the value returned by target
551  // start z.
552  // coordinate here in cm
553  const int nfins=50;
554  const double us_edges[nfins]={ 19.285, 22.185, 25.035, 27.485,
555  29.935, 32.385, 34.835, 37.285,
556  39.735, 42.185, 44.635, 47.085,
557  49.535, 51.985, 54.435, 56.885,
558  59.335, 61.785, 64.235, 66.685,
559  69.135, 71.585, 74.035, 76.485,
560  78.935, 81.385, 83.835, 86.285,
561  88.735, 91.185, 93.635, 96.085,
562  98.535, 100.985, 103.435, 105.885,
563  108.335, 110.785, 113.235, 115.685,
564  118.135, 120.585, 123.035, 125.485,
565  127.935, 130.385, 132.835, 135.285,
566  137.735, 140.185};
567 
568  const double ds_edges[nfins]={21.685, 24.585, 27.435, 29.885,
569  32.335, 34.785, 37.235, 39.685,
570  42.135, 44.585, 47.035, 49.485,
571  51.935, 54.385, 56.835, 59.285,
572  61.735, 64.185, 66.635, 69.085,
573  71.535, 73.985, 76.435, 78.885,
574  81.335, 83.785, 86.235, 88.685,
575  91.135, 93.585, 96.035, 98.485,
576  100.935, 103.385, 105.835, 108.285,
577  110.735, 113.185, 115.635, 118.085,
578  120.535, 122.985, 125.435, 127.885,
579  130.335, 132.785, 135.235, 137.685,
580  140.135, 142.585};
581 
582  // fin[0] is the first budal (HFVS) (horizontal fin, vertical scan)
583  // fin[1] is the second budal (VFHS)
584  const double budal_us_edge=us_edges[0];
585 
586  // budal_us_edge + z_trans = z0_budal
587  // z_trans = z0_budal - budal_us_edge
588  const double z_trans=z0_budal - budal_us_edge;
589 
590  // translated upstream edge of budal
591  // const double z_up=budal_us_edge+z_trans;
592 
593  // now, count the amount of material between z_up and z_start
594  // for primary protons this will be zero, but the routine
595  // should be written generally enough to handle the case
596  // in which a trajectory starts in the target
597  // we will end up subtracting this from the material between
598  // z_up and z_end to get the material traversed.
599  double mat_start=0.0;
600  for(int ifin=0; ifin<nfins; ifin++){
601  const double fin_us_edge=us_edges[ifin]+z_trans;
602  const double fin_ds_edge=ds_edges[ifin]+z_trans;
603  if(z_start<=fin_us_edge) break; // no more material to add up
604  else if(z_start<fin_ds_edge){ // z_start in this fin
605  mat_start+=(z_start-fin_us_edge);
606  break;
607  }
608  else{ // z_start after this fin (z_start>fin_ds_edge)
609  mat_start+=(fin_ds_edge-fin_us_edge);
610  }
611  }
612 
613  // now do the same thing for z_end
614  double mat_end=0.0;
615  for(int ifin=0; ifin<nfins; ifin++){
616  const double fin_us_edge=us_edges[ifin]+z_trans;
617  const double fin_ds_edge=ds_edges[ifin]+z_trans;
618  if(z_end<=fin_us_edge) break; // no more material to add up
619  else if(z_end<fin_ds_edge){ // z_end in this fin
620  mat_end+=(z_end-fin_us_edge);
621  break;
622  }
623  else{ // z_end after this fin (z_end>fin_ds_edge)
624  mat_end+=(fin_ds_edge-fin_us_edge);
625  }
626  }
627  double mat_traversed=mat_end-mat_start;
628 
629 
630  return mat_traversed;
631 
632  }
633 
634  double TargetAttenuationReweighter::getZTgtExit(double pos_start[], double mom_start[], bool leflag, bool meflag){
635  //check:
636  // if(mom_start[2]<0)std::cout<<"alert momz<0"<<std::endl;
637  //this function approximates the z position of the particle that exit the target
638  //for LE assuming 1.5 cm x 0.64 cm. xy view.
639 
640  //First, find the xy point where the partice leaves the target:
641  std::string mode(getenv("MODE"));
642  double a = -1;
643  double b = -1;
644  if(leflag){
645  a = 0.32;
646  b = 0.75;
647  }
648  if(meflag){
649  a = 0.37;
650  b = 5.93;
651  }
652  if(mode=="REF"){
653  a = 0.52;
654  b = 1.34;
655  }
656  if(mode=="OPT"){
657  a = 0.49; //0.37; These numbers changed after discussion with Laura Fields. 06/30/2016
658  b = 1.34; //1.05;
659  }
660 
661  double shift = -1;
662 
663  //X:
664  double mx = mom_start[0]/mom_start[2];
665  if(mx>0)shift = (a-pos_start[0])/mx;
666  else shift = (-1.*a-pos_start[0])/mx;
667  double z_usingx = pos_start[2] + shift;
668 
669  //Y:
670  double my = mom_start[1]/mom_start[2];
671  if(my>0){
672  if(leflag)shift = (b-pos_start[1])/my;
673  if(meflag)shift = (a-pos_start[1])/my;
674  }
675  else{
676  shift = (-1.*b-pos_start[1])/my;
677  }
678  double z_usingy = pos_start[2] + shift;
679 
680 
681 
682  double zout = z_usingx;
683  if(z_usingy<z_usingx)zout = z_usingy;
684 
685  return zout;
686 
687  }
688 
689 }
690 #if defined __clang__
691 #elif defined __GNUC__
692  #pragma GCC diagnostic pop
693 #endif
A list/table of parameter names and values.
std::vector< TH1D * > hzpostgt_kam_le
Definition: AttenuationMC.h:29
static bool isLE(const std::string &tgtcfg)
does the configuration correspond to the LE beam?
A class to make the reweight event by event.
Definition: MakeReweight.h:32
std::vector< TH1D * > hzpostgt_pip_le
Definition: AttenuationMC.h:26
std::string string
Definition: nybbler.cc:12
Information about the chain of interactions leading to a neutrino.
static MakeReweight * getInstance()
static double shiftPlaylist(const int ipl)
Get the additional shift for the Minerva playlist if this is defined.
double getParameterValue(const std::string &name) const
get the value of a parameter. throw an exception of a well defined type if we don&#39;t have it ...
std::vector< InteractionData > interaction_chain
vector of neutrino ancestors
std::vector< TH1D * > hzpostgt_kam_me
Definition: AttenuationMC.h:29
static double getZTgtExit(double pos_start[], double mom_start[], bool leflag, bool meflag)
int FindBin(double value, std::vector< double > binning)
static double getTargetPenetrationLE(double z_start, double z_end, double z0_budal)
int Tar_pdg
pdg code of the particle
Definition: TargetData.h:24
std::vector< TH1D * > hzpostgt_pim_me
Definition: AttenuationMC.h:27
static bool isME(const std::string &tgtcfg)
does the configuration correspond to the ME beam?
const double e
std::vector< TH1D * > hzpostgt_pip_me
Definition: AttenuationMC.h:26
std::vector< TH1D * > hzpostgt_kap_me
Definition: AttenuationMC.h:28
const double a
std::string getenv(std::string const &name)
Definition: getenv.cc:15
double Px
P_{x} (GeV/c) of the particle.
Definition: TargetData.h:30
TargetAttenuationReweighter(int iuniv, const ParameterTable &cv_pars, const ParameterTable &univ_pars)
std::string target_config
The target configuration. Example: le010z.
int BinID(double pz, double pt, int pdgcode)
Return the Bin ID for this data.
auto norm(Vector const &v)
Return norm of the specified vector.
std::vector< TH1D * > hzpostgt_kap_le
Definition: AttenuationMC.h:28
A class to manage the bin definitions for MIPP Numi Yields.
int playlist
The tgt playlist (exact position of the target after survey)
static AttenuationMC * getInstance()
virtual std::vector< bool > canReweight(const InteractionChainData &aa)
Look through the InteractionChainData input and identify those Interactions that can be reweighted as...
std::vector< TH1D * > hzpostgt_pim_le
Definition: AttenuationMC.h:27
static MIPPNumiYieldsBins * getInstance()
double Pt
Transversal momentum (GeV/c) of the particle.
Definition: TargetData.h:39
virtual double calculateWeight(const InteractionChainData &aa)
calculate a weight for this interaction chain given the central value parameters and the parameters f...
static bool * b
Definition: config.cpp:1043
static double getTargetPenetrationME(double z_start, double z_end, double z0_budal)
The information about the hadron that exits the target.
Definition: TargetData.h:12
double Pz
Longitudinal momentum (GeV/c) of the particle.
Definition: TargetData.h:27
ReweightDriver * cv_rw
Reweighter Drivers for the central value.
Definition: MakeReweight.h:68
double Py
P_{y} (GeV/c) of the particle.
Definition: TargetData.h:33
TargetData tar_info
Information about the hadron which exited the target.
QTextStream & endl(QTextStream &s)