00001
00005 #include "MessageService/MsgFormat.h"
00006 #include "MessageService/MsgService.h"
00007 #include "Conventions/ReleaseType.h"
00008 #include "Conventions/Munits.h"
00009 #include "Conventions/Detector.h"
00010 #include "Conventions/SimFlag.h"
00011
00012 #include "NuMuBar/NuTransition.h"
00013
00014 #include "NtupleUtils/NuUtilities.h"
00015 #include "NtupleUtils/NuEvent.h"
00016 #include "NtupleUtils/NuMCEvent.h"
00017 #include "NtupleUtils/NuSystematic.h"
00018 #include "NtupleUtils/NuXMLConfig.h"
00019
00020
00021 #include "NeugenInterface/neugen_wrapper.h"
00022 #include "NeugenInterface/neugen_config.h"
00023 #include "NeugenInterface/interaction.h"
00024 #include "NeugenInterface/process.h"
00025 #include "NeugenInterface/kinematic_variable.h"
00026 #include "NeugenInterface/init_state.h"
00027 #include "NeugenInterface/final_state.h"
00028 #include "NeugenInterface/flavor.h"
00029 #include "TLorentzVector.h"
00030
00031 #include "TFile.h"
00032 #include "TROOT.h"
00033 #include "TObject.h"
00034 #include "TDirectory.h"
00035 #include "TH1.h"
00036 #include "TMath.h"
00037 #include "TGraph.h"
00038
00039 #include <cstdlib>
00040 #include <stdexcept>
00041
00042 CVSID("$Id: NuTransition.cxx,v 1.10 2009/10/01 19:01:24 bckhouse Exp $");
00043
00044
00045 NuTransition::NuTransition(const NuXMLConfig *xmlConfig)
00046 {
00047
00048 if (!xmlConfig) {
00049
00050 doNothing = true;
00051
00052 MAXMSG("NuTransition",Msg::kInfo,5)
00053 << "No NuXMLConfig object supplied: "
00054 << "performing no systematic shifts, oscillations, or transitions."
00055 << endl;
00056 return;
00057 }
00058
00059 fxmlConfig = (NuXMLConfig*)xmlConfig->Clone();
00060 firstRunTrans = true;
00061
00062 MSG("NuTransition",Msg::kInfo) << "Applying parameters: "
00063 << "dm2nu = " << xmlConfig->DM2Nu() << ", sn2nu = " << xmlConfig->SN2Nu()
00064 << ", dm2bar = " << xmlConfig->DM2Bar() << ", sn2bar = " << xmlConfig->SN2Bar()
00065 << ", alpha = " << xmlConfig->TransitionProb() << endl;
00066
00067 doNothing = false;
00068
00069 if (doNothing) return;
00070
00071 fSyst = new NuSystematic(*fxmlConfig);
00072
00073
00074 const NuUtilities cuts;
00075
00076
00077 NuBinningScheme::NuBinningScheme_t binningScheme =
00078 static_cast<NuBinningScheme::NuBinningScheme_t>(xmlConfig->BinningScheme());
00079
00080 std::vector<Double_t> vReco = cuts.RecoBins(binningScheme);
00081 std::vector<Double_t> vTrue = cuts.TrueBins(binningScheme);
00082
00083 Int_t numRecoBins = vReco.size() - 1;
00084 Int_t numTrueBins = vTrue.size() - 1;
00085
00086 Double_t *recoBinsArray = &(vReco[0]);
00087 Double_t *trueBinsArray = &(vTrue[0]);
00088
00089
00090 numu_flux = new TH1D("numu_flux","numu_flux",numTrueBins,trueBinsArray);
00091 nubar_flux = new TH1D("nubar_flux","nubar_flux",numRecoBins,recoBinsArray);
00092 flux_weight = new TH1D("flux_weight","flux_weight",numRecoBins,recoBinsArray);
00093
00094
00095 if (NuSystematic::FluxSyst(*xmlConfig)) {
00096 MSG("NuTransition", Msg::kInfo) << "Not applying " << xmlConfig->Name()
00097 << " to transitions b/c it's a flux systematic." << endl;
00098 applyTranSyst = false;
00099 }
00100 else {
00101 applyTranSyst = true;
00102 }
00103
00104
00105 TDirectory *start = gDirectory;
00106
00107 MSG("NuTransition",Msg::kInfo) << "Get cross-section graphs from file." << endl;
00108
00109 const char * fxsecfilename = getenv("xf");
00110
00111 MSG("NuTransition",Msg::kInfo) << "Opening xsec file: " << fxsecfilename << endl;
00112 TFile *xsecfile = new TFile(fxsecfilename,"READ");
00113
00114
00115 if (!xsecfile->IsOpen()) {
00116 MSG("NuTransition", Msg::kError) << "\n\n"
00117 << "*****************************************************************************\n"
00118 << "Failed to open cross section file.\n"
00119 << "Currently the cross section file is found through the 'xf' environment variable.\n"
00120 << "Perhaps you need to issue a command such as:\n "
00121 << " export xf=\"$SRT_PRIVATE_CONTEXT/NtupleUtils/data/xsec_minos_modbyrs4_v3_5_0_mk.root\"\n"
00122 << "*****************************************************************************\n\n"
00123 << endl;
00124 throw runtime_error("Failed to read crosssection file");
00125 }
00126
00127
00128 TH1F *fhNuMuCCCrossSections = (TH1F*) xsecfile->Get("h_numu_cc_tot");
00129 Float_t *x = new Float_t[fhNuMuCCCrossSections->GetNbinsX()];
00130 Float_t *y = new Float_t[fhNuMuCCCrossSections->GetNbinsX()];
00131 for(int i=0;i<fhNuMuCCCrossSections->GetNbinsX();i++) {
00132 x[i] = fhNuMuCCCrossSections->GetBinCenter(i+1);
00133 y[i] = fhNuMuCCCrossSections->GetBinContent(i+1);
00134 }
00135 fNuMuXGraph = new TGraph(fhNuMuCCCrossSections->GetNbinsX(),x,y);
00136 if (x) {delete[] x; x = 0;}
00137 if (y) {delete[] y; y = 0;}
00138
00139
00140 TH1F *fhNuBarCCCrossSections = (TH1F*) xsecfile->Get("h_numubar_cc_tot");
00141 x = new Float_t[fhNuBarCCCrossSections->GetNbinsX()];
00142 y = new Float_t[fhNuBarCCCrossSections->GetNbinsX()];
00143 for(int i=0;i<fhNuBarCCCrossSections->GetNbinsX();i++) {
00144 x[i] = fhNuBarCCCrossSections->GetBinCenter(i+1);
00145 y[i] = fhNuBarCCCrossSections->GetBinContent(i+1);
00146 }
00147 fNuBarXGraph = new TGraph(fhNuBarCCCrossSections->GetNbinsX(),x,y);
00148 if (x) {delete[] x; x = 0;}
00149 if (y) {delete[] y; y = 0;}
00150
00151 xsecfile->Close();
00152 if (xsecfile){delete xsecfile; xsecfile = 0;}
00153
00154 gDirectory = start;
00155
00156 }
00157
00158
00159 NuTransition::~NuTransition()
00160 {
00161 if (numu_flux) delete numu_flux; numu_flux = 0;
00162 if (nubar_flux) delete nubar_flux; nubar_flux = 0;
00163 if (flux_weight) delete flux_weight; flux_weight = 0;
00164 }
00165
00166
00167 void NuTransition::Fill(NuMCEvent &mc)
00168 {
00169 if (doNothing) return;
00170
00171
00172 if (mc.iaction==1) {
00173 double fw = 1;
00174
00175
00176 fw *= this->GetXSecGraph(mc);
00177
00178 if (mc.inu == 14) {
00179 numu_flux->Fill(mc.neuEnMC, mc.rw/fw);
00180 MAXMSG("NuTransition",Msg::kInfo,5) << "===> Fill numu, xsec=" << fw << endl;
00181 }
00182 else if (mc.inu == -14) {
00183 nubar_flux->Fill(mc.neuEnMC, mc.rw/fw);
00184 MAXMSG("NuTransition",Msg::kInfo,5) << "===> Fill nubar, xsec=" << fw << endl;
00185 }
00186 else{
00187 MAXMSG("NuTransition",Msg::kInfo,5) << "===> Fill nothing, ntyp=" << mc.inu << endl;
00188 }
00189 }
00190 }
00191
00192
00193 void NuTransition::Reweight(NuEvent& nu)
00194 {
00195
00196 if (doNothing) return;
00197
00198 double wTotal = 1;
00199
00200
00201
00202 if (applyTranSyst) {
00203 this->DoSystematicShifts(nu);
00204 }
00205 else {
00206 NuEvent * nuCopy = (NuEvent*)nu.Clone();
00207 this->DoSystematicShifts(*nuCopy);
00208 wTotal *= nuCopy->rw / nu.rw;
00209 delete nuCopy;
00210 }
00211
00212
00213 bool isNuMu = (nu.inu == 14 || nu.inu == -14);
00214 bool isNuTau = (nu.inu == 16 || nu.inu == -16);
00215
00216
00217 if (SimFlag::kData == nu.simFlag) {
00218
00219 MAXMSG("NuTransition",Msg::kInfo,1)
00220 << "Not applying fake oscillations to data" << endl;
00221 }
00222 else if (Detector::kFar != nu.detector) {
00223
00224 MAXMSG("NuTransition",Msg::kInfo,1)
00225 << "Not applying fake oscillations to ND MC" << endl;
00226 }
00227 else if (1 != nu.iaction) {
00228
00229 if(isNuTau) {
00230 MAXMSG("NuTransition",Msg::kInfo,1) << "Removing NC events from tau file (nu.rw set to zero)" << endl;
00231 wTotal = 0;
00232 }
00233 MAXMSG("NuTransition",Msg::kInfo,1) << "Not oscillating NCs" << endl;
00234 }
00235 else if ( !(isNuMu || isNuTau) ) {
00236
00237 MAXMSG("NuTransition",Msg::kInfo,1)
00238 << "Not oscillating nue events (non-muon/tau (anti)neutinos)" << endl;
00239 }
00240 else if ( isNuTau && (nu.inunoosc == 12 || nu.inunoosc==-12) ) {
00241
00242 MAXMSG("NuTransition",Msg::kInfo,1)
00243 << "Removing beam nue events from tau file (nu.rw set to zero)" << endl;
00244 wTotal = 0;
00245 }
00246 else if (fxmlConfig->DM2Nu() < 0.0 ||
00247 fxmlConfig->SN2Nu() < 0.0 ||
00248 fxmlConfig->DM2Bar() < 0.0 ||
00249 fxmlConfig->SN2Bar() < 0.0){
00250 MAXMSG("NuTransition",Msg::kInfo,1)
00251 <<"Not applying fake oscillations due to xml configuration"<<endl;
00252 }
00253 else {
00254
00255 wTotal *= this->OscillationWeight(nu.neuEnMC, nu.inu);
00256 MAXMSG("NuTransition",Msg::kInfo,10)
00257 << "Oscillating with dm2=" << fxmlConfig->DM2Nu()
00258 << "; weight=" << this->OscillationWeight(nu.neuEnMC, nu.inu)
00259 << "; energy=" << nu.neuEnMC << endl;
00260
00261
00262 if (fxmlConfig->TransitionProb() > 0) {
00263 if (isNuTau) {
00264 MAXMSG("NuTransition",Msg::kInfo,1)
00265 << "Weighting down appeared NuTaus for transitions by "
00266 << (1.0 - fxmlConfig->TransitionProb()) << endl;
00267 wTotal *= (1.0 - fxmlConfig->TransitionProb());
00268 }
00269 else if (nu.inu == -14) {
00270 MAXMSG("NuTransition",Msg::kInfo,10) << "Getting a transitioned event" << endl;
00271
00272 if (firstRunTrans) {
00273 flux_weight->Divide(numu_flux, nubar_flux);
00274 firstRunTrans = false;
00275 }
00276
00277
00278 Double_t transitionWeight = 1.0 - this->OscillationWeight(nu.neuEnMC,nu.inu);
00279 transitionWeight *= fxmlConfig->TransitionProb();
00280 transitionWeight *= NuUtilities::ValueAt(flux_weight, nu.neuEnMC);
00281
00282
00283 wTotal += transitionWeight;
00284 }
00285 }
00286 }
00287
00288 nu.rw *= wTotal;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 void NuTransition::DoSystematicShifts(NuEvent& event)
00331 {
00332 MAXMSG("NuTransition",Msg::kInfo,5)
00333 << "Performing systematic shift "
00334 << fxmlConfig->FullTitle()
00335 << endl;
00336 fSyst->Shift(event);
00337 }
00338
00339
00340
00341 const Float_t NuTransition::OscillationWeight
00342 (const Float_t energy, const Int_t inu, const NuXMLConfig* lxmlConfig) const
00343 {
00344 const NuXMLConfig *xmlConfig;
00345 if (lxmlConfig) xmlConfig = lxmlConfig;
00346 else xmlConfig = fxmlConfig;
00347
00348 if (14==inu){
00349 return NuUtilities::OscillationWeight(energy,
00350 xmlConfig->DM2Nu(),
00351 xmlConfig->SN2Nu());
00352 }
00353 else if (-14==inu){
00354 return NuUtilities::OscillationWeight(energy,
00355 xmlConfig->DM2Bar(),
00356 xmlConfig->SN2Bar());
00357 }
00358 if (16==inu){
00359 return 1-NuUtilities::OscillationWeight(energy,
00360 xmlConfig->DM2Nu(),
00361 xmlConfig->SN2Nu());
00362 }
00363 else if (-16==inu){
00364 return 1-NuUtilities::OscillationWeight(energy,
00365 xmlConfig->DM2Bar(),
00366 xmlConfig->SN2Bar());
00367 }
00368 else return 1;
00369 }
00370
00371
00372
00373 Double_t NuTransition::GetXSecGraph(NuEvent& nu, bool opp_charge) const
00374 {
00375 Double_t nuBarXSec = fNuBarXGraph->Eval(nu.neuEnMC,0,"");
00376 Double_t nuMuXSec = fNuMuXGraph->Eval( nu.neuEnMC,0,"");
00377
00378 bool numu = (nu.inu > 0);
00379 if (opp_charge) numu = !numu;
00380
00381 if (numu) return nuMuXSec;
00382 else return nuBarXSec;
00383 }
00384
00385
00386 Double_t NuTransition::GetXSecGraph(NuMCEvent& nu, bool opp_charge) const
00387 {
00388 Double_t nuBarXSec = fNuBarXGraph->Eval(nu.neuEnMC,0,"");
00389 Double_t nuMuXSec = fNuMuXGraph->Eval( nu.neuEnMC,0,"");
00390
00391 bool numu = (nu.inu > 0);
00392 if (opp_charge) numu = !numu;
00393
00394 if (numu) return nuMuXSec;
00395 else return nuBarXSec;
00396 }
00397
00398
00399
00400 Double_t NuTransition::GetXSecNeugen(NuEvent& nu, bool opp_charge) const
00401 {
00403
00405
00406 static neugen_wrapper *fNuWrap = 0;
00407
00408 static neugen_config *std_config = 0;
00409
00410 if (!fNuWrap) {
00411
00412
00413
00414
00415
00416 std_config = new neugen_config("stdNeuConfig");
00417 std_config->set_best_parameters();
00418
00419
00420 fNuWrap = new neugen_wrapper(std_config);
00421 }
00422
00423
00424 double kval[5] = {0,0,0,0,0};
00425 int kid1 = -1;
00426 int kid2 = -1;
00427 kval[1] = nu.q2MC;
00428 kval[2] = nu.w2MC;
00429 kval[3] = nu.xMC;
00430 kval[4] = nu.yMC;
00431
00432
00433 int flavor = 4;
00434 if(abs(nu.inu)==12) flavor = 1;
00435 else if(abs(nu.inu)==14) flavor = 2;
00436 else if(abs(nu.inu)==16) flavor = 3;
00437 else if(abs(nu.inu)==1 || abs(nu.inu)==2 || abs(nu.inu)==3) flavor = abs(nu.inu);
00438 else {
00439 MSG("NuTransition",Msg::kError) << "Invalid event:inu value " << nu.inu << endl;
00440 return 0;
00441 }
00442
00443 int ccnc = nu.iaction;
00444 if(ccnc==0) ccnc = 2;
00445 if(!(ccnc==1||ccnc==2)) {
00446 MSG("NuTransition",Msg::kError) << "Invalid event:iaction value "
00447 << nu.iaction << endl;
00448 return 0;
00449 }
00450
00451 int process = 0;
00452 if(nu.iresonance>=1001&&nu.iresonance<=1004) process = nu.iresonance - 1000;
00453 else if(nu.iresonance>=1&&nu.iresonance<=4) process = nu.iresonance;
00454 else {
00455 if(nu.iresonance==1005) MSG("NuTransition",Msg::kInfo)
00456 << "Event:iresonance value is 1005 "
00457 << "- no reweighting performed" << endl;
00458 else MSG("NeugenWC",Msg::kError)
00459 << "Invalid event:iresonance (or event:process) value "
00460 << nu.iresonance << endl;
00461 return 0;
00462 }
00463
00464
00465 if(process==1) {
00466 kid1=1;
00467 kid2=0;
00468 if(kval[1]==999999) {
00469 MSG("NuTransition",Msg::kWarning)
00470 << "Current event is QEL: q^2 kinematic variable not set!"
00471 << " Returning weight of 1." << endl;
00472 return 0;
00473 }
00474 }
00475 else if(process==2) {
00476 kid1=1;
00477 kid2=2;
00478 if(kval[1]==999999) {
00479 MSG("NuTransition",Msg::kWarning)
00480 << "Current event is RES: q^2 kinematic variable not set!"
00481 << " Returning weight of 1." << endl;
00482 return 0;
00483 }
00484 if(kval[2]==999999) {
00485 MSG("NuTransition",Msg::kWarning)
00486 << "Current event is RES: w^2 kinematic variable not set!"
00487 << " Returning weight of 1." << endl;
00488 return 0;
00489 }
00490
00491 if(kval[2]>0) kval[2]=sqrt(kval[2]);
00492 else {
00493 MSG("NuTransition",Msg::kWarning)
00494 << "w^2 kinematic variable is negative!"
00495 << " Returning weight of 1." << endl;
00496 return 0;
00497 }
00498 }
00499 else if(process==3) {
00500 kid1=3;
00501 kid2=4;
00502 if(kval[3]==999999) {
00503 MSG("NuTransition",Msg::kWarning)
00504 << "Current event is DIS: x kinematic variable not set!"
00505 << " Returning weight of 1." << endl;
00506 return 0;
00507 }
00508 if(kval[4]==999999) {
00509 MSG("NuTransition",Msg::kWarning)
00510 << "Current event is DIS: y kinematic variable not set!"
00511 << " Returning weight of 1." << endl;
00512 return 0;
00513 }
00514 }
00515 else if(process==4) {
00516
00517 return 0;
00518 }
00519
00520
00521 TLorentzVector *nu_lv = new TLorentzVector(nu.neuPxMC,nu.neuPyMC,nu.neuPzMC,nu.neuEnMC);
00522 TLorentzVector *tar_lv = new TLorentzVector(nu.tgtPxMC,nu.tgtPyMC,nu.tgtPzMC,nu.tgtEnMC);
00523
00524 init_state_t init = init_state_enum(nu.initialStateMC);
00525
00526 if (opp_charge) {
00527 using namespace init_state;
00528 switch(init) {
00529 case e_vN: init = e_vbN; break;
00530 case e_vbN: init = e_vN; break;
00531
00532 case e_vA: init = e_vbA; break;
00533 case e_vbA: init = e_vA; break;
00534
00535 case e_vp: init = e_vbp; break;
00536 case e_vbp: init = e_vp; break;
00537
00538 case e_vn: init = e_vbn; break;
00539 case e_vbn: init = e_vn; break;
00540
00541 case e_undefined_init_state:
00542 default:
00543 MSG("NuTransition",Msg::kWarning) << "Unknown initial state" << endl;
00544 return 0;
00545 }
00546
00547 if (process == 1) {
00548 if (init == e_vbn) init = e_vbp;
00549 if (init == e_vp) init = e_vn;
00550 }
00551 }
00552
00553 interaction *iact = new interaction(flavor_enum(flavor),
00554 nucleus_enum(nu.nucleusMC),
00555 ccnc_enum(ccnc),
00556 init);
00557
00558 final_state *fs = new final_state(nu.hadronicFinalStateMC);
00559
00560
00561
00562 Double_t sigma = fNuWrap->offshell_diff_xsec(nu_lv,tar_lv,
00563 iact,process_enum(process),fs,
00564 kinematic_variable_enum(kid1),float(kval[kid1]),
00565 kinematic_variable_enum(kid2),float(kval[kid2]));
00566
00567
00568 delete nu_lv;
00569 delete tar_lv;
00570 delete iact;
00571 delete fs;
00572
00573
00574 return sigma;
00575 }
00576
00577