00001 #include "NeugenInterface/inuke_rw.h"
00002 #include "NeugenInterface/fill_stdhep.h"
00003 #include <iostream>
00004 #include <iomanip>
00005
00006 #include "TClonesArray.h"
00007 #include "TFile.h"
00008 #include "TTree.h"
00009 #include "TRandom.h"
00010
00011 #include "MCNtuple/NtpMCStdHep.h"
00012 #include "MCNtuple/NtpMCTruth.h"
00013 #include "StandardNtuple/NtpStRecord.h"
00014 #include "StandardNtuple/NtpStRecord.h"
00015
00016
00017 inuke_reweight::delta_fate::delta_fate():cex(0.0),elas(0.0),inel(0.0),abs(0.0),pp(0.0),npp(0.0),nnp(0.0),npnp(0.0),piprod(0.0){
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 }
00032
00033 std::ostream& inuke_reweight::delta_fate::print(std::ostream& os){
00034
00035
00036 os.fill(' ');
00037 os<<"delta_fate:\t"<<std::setw(4)<<std::setprecision(3)<< cex<<" "<<std::setw(4)<<std::setprecision(3)<<elas<<" "<<std::setw(4)<<std::setprecision(3)<<inel<<" "<<std::setw(4)<<std::setprecision(3)<<abs<<" "<<std::setw(4)<<std::setprecision(3)<<pp<<" "<<std::setw(4)<<std::setprecision(3)<<npp<<" "<<std::setw(4)<<std::setprecision(3)<<std::setw(4)<<std::setprecision(3)<<nnp<<" "<<std::setw(4)<<std::setprecision(3)<<npnp<<" "<<std::setw(4)<<std::setprecision(3)<<piprod;
00038 return os;
00039 }
00040
00041 void inuke_reweight::delta_fate::set_abs_fates(float f){
00042 abs=f; pp=f; npp=f; nnp=f; npnp=f;
00043 }
00044
00045 inuke_reweight::delta_scale::delta_scale():rhonuc(0.0),ft(0.0),xsec(0.0){}
00046
00047 std::ostream& inuke_reweight::delta_scale::print(std::ostream& os){
00048
00049
00050
00051 os<<"delta_scale:\t"<< std::setw(4)<<std::setprecision(3)<<rhonuc<<" "<< std::setw(4)<<std::setprecision(3)<<ft<<" "<<std::setw(4)<<std::setprecision(3)<<xsec;
00052 return os;
00053 }
00054
00055 std::ostream& inuke_reweight::parameter_set::print(std::ostream& os){
00056 os<<"pi "; pi_fate.print(os); os<<std::endl;
00057 os<<"pi "; pi_scale.print(os); os<<std::endl;
00058 os<<"pn "; pn_fate.print(os); os<<std::endl;
00059 os<<"pn "; pn_scale.print(os); os<<std::endl;
00060 os<<std::endl;
00061
00062 return os;
00063 }
00064
00065 double inuke_reweight::parameter_set::get_par(int ipar){
00066 double x=0;
00067 switch(ipar){
00068 case 0:
00069 x=pi_fate.cex;
00070 break;
00071 case 1:
00072 x=pi_fate.elas;
00073 break;
00074 case 2:
00075 x=pi_fate.inel;
00076 break;
00077 case 3:
00078 x=pi_fate.abs;
00079 break;
00080 case 4:
00081 x=pi_fate.pp;
00082 break;
00083 case 5:
00084 x=pi_fate.npp;
00085 break;
00086 case 6:
00087 x=pi_fate.nnp;
00088 break;
00089 case 7:
00090 x=pi_fate.npnp;
00091 break;
00092 case 8:
00093 x=pi_fate.piprod;
00094 break;
00095
00096 case 9:
00097 x=pn_fate.cex;
00098 break;
00099 case 10:
00100 x=pn_fate.elas;
00101 break;
00102 case 11:
00103 x=pn_fate.inel;
00104 break;
00105 case 12:
00106 x=pn_fate.abs;
00107 break;
00108 case 13:
00109 x=pn_fate.pp;
00110 break;
00111 case 14:
00112 x=pn_fate.npp;
00113 break;
00114 case 15:
00115 x=pn_fate.nnp;
00116 break;
00117 case 16:
00118 x=pn_fate.npnp;
00119 break;
00120 case 17:
00121 x=pn_fate.piprod;
00122 break;
00123
00124 case 18:
00125 x=pi_scale.rhonuc;
00126 break;
00127 case 19:
00128 x=pi_scale.ft;
00129 break;
00130 case 20:
00131 x=pi_scale.xsec;
00132 break;
00133
00134
00135 case 21:
00136 x=pn_scale.rhonuc;
00137 break;
00138 case 22:
00139 x=pn_scale.ft;
00140 break;
00141 case 23:
00142 x=pn_scale.xsec;
00143 break;
00144 default:
00145 x=0;
00146 break;
00147 }
00148 return x;
00149 }
00150
00151
00152 std::ostream& inuke_reweight::parameter_limits::print(std::ostream& os){
00153 os<<"Upper limits: \n";upper.print(os); os<<std::endl;
00154 os<<"Lower limits: \n";lower.print(os); os<<std::endl;
00155
00156 return os;
00157 }
00158
00159 extern "C" int change_fate_probs_(float* vmod, int* itype);
00160
00161 void inuke_reweight::change_fate_probs(const inuke_reweight::delta_fate& p,
00162 const inuke_reweight::inuke_particle_t& t) {
00163
00164
00165 float v[10];
00166 v[0]=p.cex; v[1]=p.elas; v[2]=p.inel;
00167 v[3]=p.abs; v[4]=p.pp; v[5]=p.npp;
00168 v[6]=p.nnp; v[7]=p.npnp; v[8]=p.piprod;
00169 v[9]=0.0;
00170
00171 int i=-1;
00172 if(t == inuke_reweight::kPion) i=0;
00173 else if( t == inuke_reweight::kNucleon ) i=1;
00174
00175 change_fate_probs_(v,&i);
00176
00177 }
00178
00179
00180 extern struct interaction_rw {
00181 float rw_pi_ft_scale; float rw_pn_ft_scale;
00182 float rw_pi_xsec_scale; float rw_pn_xsec_scale;
00183 float rw_rhonuc_scale;
00184
00185 } interaction_rw_;
00186
00187
00188 void inuke_reweight::change_inter_scales(const inuke_reweight::delta_scale& p,
00189 const inuke_reweight::inuke_particle_t&t){
00190
00191
00192
00193 interaction_rw_.rw_rhonuc_scale = (1+p.rhonuc);
00194
00195 if(t==inuke_reweight::kPion){
00196 interaction_rw_.rw_pi_ft_scale=(1+p.ft);
00197 interaction_rw_.rw_pi_xsec_scale=(1+p.xsec);
00198 }
00199 else if (t==inuke_reweight::kNucleon){
00200 interaction_rw_.rw_pn_ft_scale=(1+p.ft);
00201 interaction_rw_.rw_pn_xsec_scale=(1+p.xsec);
00202 }
00203
00204 }
00205
00206 extern "C" void identify_hadronic_system_(int*, int*);
00207 extern "C" void summarise_prenuke_(int*, int*);
00208 extern "C" void fill_shower_ntuple_();
00209 #include "shower_ntuple.h"
00210
00211 double inuke_reweight::calc_weights(){
00212 int idx_had, icode_had;
00213
00214 identify_hadronic_system_(&idx_had,&icode_had);
00215 if(icode_had==4){ return 1.0 ;}
00216 if(icode_had==0){ return 1.0 ;}
00217
00218
00219 summarise_prenuke_(&idx_had,&icode_had);
00220
00221 fill_shower_ntuple_();
00222
00223 double W=shwr_.tot_w_fate * shwr_.tot_w_inter;
00224 return W;
00225
00226 }
00227
00228
00229
00230 void inuke_reweight::calc_weights
00231 (const NtpStRecord* rec, const NtpMCTruth* mct,
00232 const std::vector<inuke_reweight::parameter_set>& psets,
00233 std::vector<double>& weights, double& nucrad, double& wrad,
00234 bool verbose){
00235 if(!rec) return;
00236 if(!mct) return;
00237 if(psets.size()==0) return;
00238
00239
00240 weights.resize(psets.size());
00241
00242 for (unsigned int i=0; i<psets.size(); i++){
00243 const parameter_set& p=psets[i];
00244 inuke_reweight::change_fate_probs(p.pi_fate,inuke_reweight::kPion);
00245 inuke_reweight::change_inter_scales(p.pi_scale,inuke_reweight::kPion);
00246 inuke_reweight::change_fate_probs(p.pn_fate,inuke_reweight::kNucleon);
00247 inuke_reweight::change_inter_scales(p.pn_scale,inuke_reweight::kNucleon);
00248
00249 const TClonesArray& stdheps = *(rec->stdhep);
00250
00251 if(verbose) mct->Print();
00252 int nfill = inuke_reweight::fill_stdhep(*mct, stdheps);
00253 if(verbose){
00254 std::cout<<"MC Event: "<<i<<" filled "<<nfill<<" entries"<<std::endl;
00255 inuke_reweight::print_stdhep(2);
00256 }
00257 double w=inuke_reweight::calc_weights();
00258 weights[i]=w;
00259 if(verbose) std::cout<<"weights["<<i<<"] = "<<w<<std::endl;
00260 nucrad=-1.0; wrad=1.0;
00261 if(mct->z == 26){
00262 int idx_had=inuke_reweight::get_idx_had();
00263 nucrad=inuke_reweight::get_nucrad(idx_had);
00264 wrad=inuke_reweight::unif_to_ws_fe(nucrad);
00265 }
00266
00267
00268 inuke_reweight::clear_stdhep();
00269 }
00270
00271 }
00272
00273
00274 void inuke_reweight::calc_weights(const NtpStRecord* rec, std::vector<double>& v, bool verbose){
00275
00276 const TClonesArray& mc_array= *(rec->mc);
00277 const TClonesArray& stdheps = *(rec->stdhep);
00278 const int nmc = rec->mchdr.nmc;
00279 for(int i=0; i<nmc; i++){
00280 const NtpMCTruth* mct = dynamic_cast<const NtpMCTruth*>(mc_array[i]);
00281 if(verbose) mct->Print();
00282
00283 int nfill = inuke_reweight::fill_stdhep(*mct, stdheps);
00284 if(verbose){
00285 std::cout<<"MC Event: "<<i<<" filled "<<nfill<<" entries"<<std::endl;
00286 inuke_reweight::print_stdhep(2);
00287 }
00288 double w=inuke_reweight::calc_weights();
00289 v.push_back(w);
00290 std::cout<<"Weight = "<<w<<std::endl;
00291
00292 inuke_reweight::clear_stdhep();
00293 }
00294 return;
00295
00296 }
00297
00298 void inuke_reweight::test_calc_weights(const char* filename, int entry,
00299 const inuke_reweight::parameter_set& p){
00300 inuke_reweight::test_calc_weights(filename, entry,
00301 p.pi_fate,p.pi_scale,p.pn_fate,p.pn_scale);
00302 }
00303
00304
00305 void inuke_reweight::test_calc_weights
00306 (const char* filename, int entry,
00307 const inuke_reweight::delta_fate& pi_fate,
00308 const inuke_reweight::delta_scale& pi_scale,
00309 const inuke_reweight::delta_fate& pn_fate,
00310 const inuke_reweight::delta_scale& pn_scale){
00311
00312
00313 TFile f(filename);
00314 TTree* t = (TTree*) f.Get("NtpSt");
00315 NtpStRecord* rec=0;
00316 t->SetBranchAddress("NtpStRecord",&rec);
00317 t->GetEntry(entry);
00318
00319 change_fate_probs(pi_fate,inuke_reweight::kPion);
00320 change_fate_probs(pn_fate,inuke_reweight::kNucleon);
00321
00322 change_inter_scales(pi_scale,inuke_reweight::kPion);
00323 change_inter_scales(pn_scale,inuke_reweight::kNucleon);
00324
00325 std::vector<double> v;
00326 bool verbose=false;
00327 calc_weights(rec,v,verbose);
00328 for (unsigned int i=0; i<v.size(); i++){
00329 std::cout<<i<<" "<<v[i]<<std::endl;
00330 }
00331
00332
00333 }
00334
00335 void inuke_reweight::get_1sigma_shifts(const inuke_reweight::delta_scale& f,
00336 std::vector<inuke_reweight::delta_scale>& v){
00337
00338 if(f.rhonuc!=0){
00339 inuke_reweight::delta_scale x;
00340 x.rhonuc=f.rhonuc; v.push_back(x);
00341 x.rhonuc*=-1; v.push_back(x);
00342 }
00343 if(f.ft!=0){
00344 inuke_reweight::delta_scale x;
00345 x.ft=f.ft; v.push_back(x);
00346 x.ft*=-1; v.push_back(x);
00347 }
00348 if(f.xsec!=0){
00349 inuke_reweight::delta_scale x;
00350 x.xsec=f.xsec; v.push_back(x);
00351 x.xsec*=-1; v.push_back(x);
00352 }
00353
00354 }
00355
00356
00357 void inuke_reweight::get_1sigma_shifts(const inuke_reweight::delta_fate& f,
00358 std::vector<inuke_reweight::delta_fate>& v){
00359
00360 if(f.cex!=0) {
00361 inuke_reweight::delta_fate x;
00362 x.cex=f.cex; v.push_back(x);
00363 x.cex*= -1; v.push_back(x);
00364 }
00365 if(f.elas!=0) {
00366 inuke_reweight::delta_fate x;
00367 x.elas=f.elas; v.push_back(x);
00368 x.elas*= -1; v.push_back(x);
00369 }
00370 if(f.inel!=0) {
00371 inuke_reweight::delta_fate x;
00372 x.inel=f.inel; v.push_back(x);
00373 x.inel*= -1; v.push_back(x);
00374 }
00375 if(f.abs!=0) {
00376 inuke_reweight::delta_fate x;
00377 x.abs=f.abs; v.push_back(x);
00378 x.abs*= -1; v.push_back(x);
00379 }
00380 if(f.pp!=0) {
00381 inuke_reweight::delta_fate x;
00382 x.pp=f.pp; v.push_back(x);
00383 x.pp*= -1; v.push_back(x);
00384 }
00385 if(f.npp!=0) {
00386 inuke_reweight::delta_fate x;
00387 x.npp=f.npp; v.push_back(x);
00388 x.npp*= -1; v.push_back(x);
00389 }
00390 if(f.nnp!=0) {
00391 inuke_reweight::delta_fate x;
00392 x.nnp=f.nnp; v.push_back(x);
00393 x.nnp*= -1; v.push_back(x);
00394 }
00395 if(f.npnp!=0) {
00396 inuke_reweight::delta_fate x;
00397 x.npnp=f.npnp; v.push_back(x);
00398 x.npnp*= -1; v.push_back(x);
00399 }
00400 if(f.piprod!=0) {
00401 inuke_reweight::delta_fate x;
00402 x.piprod=f.piprod; v.push_back(x);
00403 x.piprod*= -1; v.push_back(x);
00404 }
00405
00406
00407 }
00408
00409 void inuke_reweight::generate_1sigma_shifts
00410 (const inuke_reweight::parameter_set& sigmas,
00411 std::vector<inuke_reweight::parameter_set>& v){
00412
00413 std::vector<inuke_reweight::delta_fate> w;
00414 get_1sigma_shifts(sigmas.pi_fate,w);
00415 for (unsigned int i=0; i<w.size(); i++){
00416 inuke_reweight::parameter_set p;
00417 p.pi_fate=w[i];
00418 v.push_back(p);
00419 }
00420 w.clear();
00421 get_1sigma_shifts(sigmas.pn_fate,w);
00422 for (unsigned int i=0; i<w.size(); i++){
00423 inuke_reweight::parameter_set p;
00424 p.pn_fate=w[i];
00425 v.push_back(p);
00426 }
00427
00428 std::vector<inuke_reweight::delta_scale> y;
00429 get_1sigma_shifts(sigmas.pi_scale,y);
00430 for (unsigned int i=0; i<y.size(); i++){
00431 inuke_reweight::parameter_set p;
00432 p.pi_scale=y[i];
00433 v.push_back(p);
00434 }
00435 y.clear();
00436 get_1sigma_shifts(sigmas.pn_scale,y);
00437 for (unsigned int i=0; i<y.size(); i++){
00438 inuke_reweight::parameter_set p;
00439 p.pn_scale=y[i];
00440 v.push_back(p);
00441 }
00442
00443
00444
00445 }
00446
00447
00448 bool in_limits(float& x, float l, float h);
00449 bool in_limits(float& x, float l, float h){
00450 if(l==0.0 && h==0.0) {x=0.0; return true;}
00451 else return (x<h && x>l);
00452 }
00453
00454
00455
00456
00457 void inuke_reweight::get_uncor_shifts(const inuke_reweight::delta_scale& f,
00458 const inuke_reweight::delta_scale& llim,
00459 const inuke_reweight::delta_scale& ulim,
00460 inuke_reweight::delta_scale& x){
00461
00462 while(!in_limits(x.rhonuc=gRandom->Gaus()*f.rhonuc,llim.rhonuc,ulim.rhonuc));
00463
00464 while(!in_limits(x.ft=gRandom->Uniform(-1,1)*f.ft,llim.ft,ulim.ft));
00465 while(!in_limits(x.xsec=gRandom->Gaus()*f.xsec,llim.xsec,ulim.xsec));
00466
00467
00468
00469
00470
00471
00472
00473 }
00474
00475
00476 void inuke_reweight::get_uncor_shifts(const inuke_reweight::delta_fate& f,
00477 const inuke_reweight::delta_fate& llim,
00478 const inuke_reweight::delta_fate& ulim,
00479 inuke_reweight::delta_fate& x){
00480
00481 while(!in_limits(x.cex=gRandom->Gaus()*f.cex,llim.cex,ulim.cex));
00482 while(!in_limits(x.elas=gRandom->Gaus()*f.elas,llim.elas,ulim.elas));
00483 while(!in_limits(x.inel=gRandom->Gaus()*f.inel,llim.inel,ulim.inel));
00484 while(!in_limits(x.abs=gRandom->Gaus()*f.abs,llim.abs,ulim.abs));
00485 while(!in_limits(x.pp=gRandom->Gaus()*f.pp,llim.pp,ulim.pp));
00486 while(!in_limits(x.npp=gRandom->Gaus()*f.npp,llim.npp,ulim.npp));
00487 while(!in_limits(x.nnp=gRandom->Gaus()*f.nnp,llim.nnp,ulim.nnp));
00488 while(!in_limits(x.npnp=gRandom->Gaus()*f.npnp,llim.npnp,ulim.npnp));
00489 while(!in_limits(x.piprod=gRandom->Gaus()*f.piprod,llim.piprod,ulim.piprod));
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 }
00504
00505
00506 void inuke_reweight::generate_uncor_shifts
00507 (const inuke_reweight::parameter_set& sigmas,
00508 const inuke_reweight::parameter_limits& limits,
00509 inuke_reweight::parameter_set& p){
00510
00511 inuke_reweight::get_uncor_shifts(sigmas.pi_fate,
00512 limits.lower.pi_fate,
00513 limits.upper.pi_fate,
00514 p.pi_fate);
00515 inuke_reweight::get_uncor_shifts(sigmas.pn_fate,
00516 limits.lower.pn_fate,
00517 limits.upper.pn_fate,
00518 p.pn_fate);
00519
00520 inuke_reweight::get_uncor_shifts(sigmas.pi_scale,
00521 limits.lower.pi_scale,
00522 limits.upper.pi_scale,
00523 p.pi_scale);
00524 inuke_reweight::get_uncor_shifts(sigmas.pn_scale,
00525 limits.lower.pn_scale,
00526 limits.upper.pn_scale,
00527 p.pn_scale);
00528
00529 }
00530
00531 inuke_reweight::parameter_limits::parameter_limits() : upper(),lower(){}
00532
00533 inuke_reweight::parameter_limits::parameter_limits
00534 (const inuke_reweight::parameter_set& sigmas, float nsigma){
00535
00536 upper.pi_fate=sigmas.pi_fate;
00537 upper.pn_fate=sigmas.pn_fate;
00538 lower.pi_fate=sigmas.pi_fate;
00539 lower.pn_fate=sigmas.pn_fate;
00540
00541 inuke_reweight::delta_fate* v[4]={&(upper.pi_fate),&(lower.pi_fate),
00542 &(upper.pn_fate),&(lower.pn_fate)};
00543 for(int j=0; j<4; j++){
00544 inuke_reweight::delta_fate& f = *v[j];
00545
00546 f.cex=pow(-1,j)*(f.cex*nsigma);
00547 f.elas=pow(-1,j)*(f.elas*nsigma);
00548 f.inel=pow(-1,j)*(f.inel*nsigma);
00549 f.abs=pow(-1,j)*(f.abs*nsigma);
00550 f.pp=pow(-1,j)*(f.pp*nsigma);
00551 f.npp=pow(-1,j)*(f.npp*nsigma);
00552 f.nnp=pow(-1,j)*(f.nnp*nsigma);
00553 f.npnp=pow(-1,j)*(f.npnp*nsigma);
00554 f.piprod=pow(-1,j)*(f.piprod*nsigma);
00555 }
00556
00557
00558 upper.pi_scale=sigmas.pi_scale;
00559 upper.pn_scale=sigmas.pn_scale;
00560 lower.pi_scale=sigmas.pi_scale;
00561 lower.pn_scale=sigmas.pn_scale;
00562
00563 inuke_reweight::delta_scale* w[4]={&(upper.pi_scale),&(lower.pi_scale),
00564 &(upper.pn_scale),&(lower.pn_scale)};
00565
00566 for(int j=0; j<4; j++){
00567 inuke_reweight::delta_scale& f = *w[j];
00568 f.rhonuc=pow(-1,j)*(f.rhonuc*nsigma);
00569 f.ft=pow(-1,j)*(f.ft*nsigma);
00570 f.xsec=pow(-1,j)*(f.xsec*nsigma);
00571
00572 }
00573 }
00574
00575 double inuke_reweight::unif_to_ws_fe(double r){
00576 double c=1.0;
00577 if(r<5.36) {
00578
00579 c = ( (0.498473)/(1.+exp((r-4.1)/0.56)) )/(0.244814);
00580 }
00581 return c;
00582
00583 }
00584
00585 int inuke_reweight::get_idx_had(){
00586 int idx_had, icode_had;
00587 identify_hadronic_system_(&idx_had,&icode_had);
00588 if(icode_had==4){ return -1 ;}
00589 if(icode_had==0){ return -1 ;}
00590 return idx_had;
00591
00592 }
00593
00594 #include "stdhep.h"
00595
00596 double inuke_reweight::get_nucrad(int idx_had){
00597 double r=-1.0;
00598 int i=idx_had-1;
00599 if(i<0 || i>hepevt_.nhep) return r;
00600 r=0.0;
00601 for(int j=0; j<3; j++){
00602 r+=pow(hepevt_.vhep[i][j],2.0);
00603 }
00604 return sqrt(r);
00605 }