Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

NuFCExperimentFactory.cxx

Go to the documentation of this file.
00001 #include <string>
00002 #include <sstream>
00003 #include <vector>
00004 #include <cstdlib>
00005 #include <stdexcept>
00006 #include <map>
00007 
00008 using namespace std;
00009 
00010 #include "TROOT.h"
00011 #include "TH1.h"
00012 #include "TH1D.h"
00013 #include "TRandom3.h"
00014 #include "TTree.h"
00015 #include "TFile.h"
00016 
00017 #include "MessageService/MsgService.h"
00018 #include "NtupleUtils/NuFCExperimentFactory.h"
00019 #include "NtupleUtils/NuMMParameters.h"
00020 #include "NtupleUtils/NuInputEvents.h"
00021 #include "NtupleUtils/NuLibrary.h"
00022 #include "NtupleUtils/NuFCEvent.h"
00023 #include "NtupleUtils/NuMMRunNuBar.h"
00024 
00025 
00026 CVSID("$Id: NuFCExperimentFactory.cxx,v 1.26 2010/01/26 11:56:23 bckhouse Exp $");
00027 
00028 using namespace Sample;
00029 
00044 NuFCExperimentFactory::NuFCExperimentFactory(TRandom3 *rgen, TString nd_path, TString fd_path, TString tau_path)
00045   : IntND(0), ndPoT(0), 
00046     fPQHist(), fNQHist(), fPQHistND(), fNQHistND(), 
00047     fRandy(rgen), 
00048     counter(0), 
00049     fixedSyst(false), gausSyst(false), dp_corr(false), dp_old(false)
00050 {
00051   // Check if our random number generator is correctly setup
00052   if (!fRandy) {
00053     // If not, just use gRandom
00054     fRandy = gRandom;
00055   }
00056   noND = false;
00057   
00058   norm_size    = 0.04;
00059 
00060   curv_size    = 0.02;
00061   relcurv_size = 0.04;
00062   range_size   = 0.02;
00063   shower_size  = 0.10;
00064   relshow_size = 0.033;
00065   
00066   dp_size      = 0.80;
00067   bg_size      = 0.50;
00068   
00069   xsec_size    = 1;
00070   skzp_size    = 1;
00071 
00072   // Get the binning scheme set up
00073   const NuUtilities cuts;
00074   NuBinningScheme::NuBinningScheme_t binningScheme =
00075   static_cast<NuBinningScheme::NuBinningScheme_t>(4);
00076   vReco = cuts.RecoBins(binningScheme);
00077   vTrue = cuts.TrueBins(binningScheme);
00078   
00079   numRecoBins = vReco.size() - 1;
00080   numTrueBins = vTrue.size() - 1;
00081   //recoBinsArray = &(vReco[0]);
00082   //trueBinsArray = &(vTrue[0]);
00083 
00084   Distro(kSignalPQ, "signalSpect", "Signal Distro");
00085   Distro(kWrongSignPQ, "wsSpect", "Wrong Sign Distro");
00086   Distro(kNCPQ, "ncSpect", "NC Distro");
00087   Distro(kTauPQ, "tauSpect", "Tau Distro");
00088   Distro(kAppearedPQ, "appearedSpect", "Appeared Distro");
00089   
00090   // Set up the FD MC chain
00091   FillMCEvents(nd_path);
00092   FillMCEvents(fd_path);
00093   FillMCEvents(tau_path);
00094 }
00095 
00096 
00107 void NuFCExperimentFactory::GenerateNewExperiment(NuMMRunNuBar * mmRunSource, const NuMMParameters& mmPars, bool reroll)
00108 {
00109   MAXMSG("NuFCExperimentFactory",Msg::kInfo,1) << "Entering GenerateNewExperiment" << endl;
00110   
00111   TString name = "fdExp";
00112   name += (counter++);
00113   TH1D *fdExp = new TH1D(name,"Single FC Experiment", numRecoBins, &(vReco[0]));
00114 
00115   NuMatrixSpectrum fdBar;
00116   mmRunSource->QuietModeOn();
00117 
00118   if (reroll) RollSystematics();
00119   GenerateND(mmRunSource);
00120   
00121   for (int i = 1; i <= 5; i++) {
00122     Sample_t s = (Sample_t)i;
00123     
00124     fdBar = mmRunSource->TrueComponents(mmPars, s);
00125     
00126     // Apply Normalization to the Prediction
00127     fdBar.Multiply(GetNormShift());
00128     fdBar.Multiply(GetBGShift(s));
00129     
00130     // Get the average events by integrating the PDF
00131     Double_t average_events = fdBar.Spectrum()->Integral();
00132     counts[Int(s)] = 0;
00133     if (average_events == 0) continue;
00134     
00135     // Get the number of events to generate
00136     Int_t nevents = fRandy->Poisson(average_events);
00137 
00138     // Create sampling distribution
00139     MakeSampler(s, fdBar);
00140     
00141     double numdraws = 0;
00142 
00143     // Now start sampling
00144     int ev;
00145     double rand, reject, E;
00146     bool seeking;
00147     
00148     while (nevents > 0) {
00149       // Get an event -- takes care of rejection sampling
00150       seeking = true;
00151       while (seeking) {
00152         ev = fRandy->Integer(N(s));
00153         ++numdraws;
00154         
00155         rand = fRandy->Uniform();
00156         reject = GetReject(s, ev);       
00157         
00158         if (s != kAppearedPQ) {
00159           ScaleRejection(reject, nevents, rand, GetDPShift(events[Int(s)][ev]));
00160         }
00161         if (s != kWrongSignPQ) {
00162           ScaleRejection(reject, nevents, rand, GetXSecShift(events[Int(s)][ev]));
00163         }
00164         ScaleRejection(reject, nevents, rand, GetSKZPShift(events[Int(s)][ev]));
00165 
00166         
00167         seeking = rand > reject;
00168       }
00169 
00170       // Get the new reco energy -- apply the systematic
00171       E = GetTrkEnergy(events[Int(s)][ev]) + GetShowerEnergy(events[Int(s)][ev]);
00172 
00173       // Fill our final reco spectrum
00174       fdExp->Fill(E);
00175       ++counts[Int(s)];
00176       
00177       --nevents;
00178     }
00179   }
00180   
00181   fNQHist.ResetPoT(fdBar.PoT());
00182   fPQHist.ResetPoT(fdBar.PoT());
00183   fPQHist.ResetSpectrum(*fdExp);
00184 
00185   delete fdExp;
00186   
00187   MAXMSG("NuFCExperimentFactory",Msg::kInfo,1) << "Leaving GenerateNewExperiment" << endl;
00188 }
00189 
00190 
00203 void NuFCExperimentFactory::ScaleRejection(double &reject, int &nevents, double rand, double shift)
00204 { 
00205   double reject_new = reject*shift;
00206   if (rand > reject && rand < reject_new) nevents++;
00207   if (rand < reject && rand > reject_new) nevents--;
00208   
00209   reject = reject_new;
00210 }
00211 
00212 
00217 void NuFCExperimentFactory::FillMCEvents(TString mc_path)
00218 {
00219   MSG("NuFCExperimentFactory",Msg::kInfo) << "Entering FillMCEvents(\"" << mc_path << "\")" << endl;
00220   TFile *fin = new TFile(mc_path,"READ");
00221 
00222   // Test the file opened, and fail otherwise
00223   if (fin->IsZombie()) {
00224     MSG("NuFCExperimentFactory",Msg::kError) << "Failed to read in events file " << mc_path << endl;
00225     throw runtime_error("Failed to read MC events file");
00226   }
00227   
00228   // Determine which Detector this file is for
00229   TH1D *hDetector = (TH1D*)gROOT->FindObject("hDetector");
00230   int det = (int)hDetector->GetMean();
00231  
00232   // Get the ND Pot
00233   if (det == 1) {
00234     TH1D *hTotalPot = (TH1D*)gROOT->FindObject("hTotalPot");
00235     ndPoT += hTotalPot->Integral();
00236   }
00237   
00238   // Attempt to load the known tree types
00239   TTree *t1 = (TTree*)fin->Get("FDFilter");
00240   TTree *t2 = (TTree*)fin->Get("TAUFilter");
00241   TTree *t3 = (TTree*)fin->Get("NDFilter");
00242   TTree *t4 = (TTree*)fin->Get("FCTree");
00243   TTree *t5 = (TTree*)fin->Get("s");
00244 
00245   // If the tree exists in the file, load it
00246   if (t1)      FillFromFilter(t1, det);
00247   else if (t2) FillFromFilter(t2, det);
00248   else if (t3) FillFromFilter(t3, det);
00249   else if (t4) FillFromFCTree(t4, det);
00250   else if (t5) FillFromDST(mc_path, det);
00251   else {
00252     MSG("NuFCExperimentFactory",Msg::kError) << "No recognized tree in file: " << mc_path << endl;      
00253   }
00254   
00255   MSG("NuFCExperimentFactory",Msg::kInfo) << "Leaving FillMCEvents" << endl;  
00256 }  
00257 
00258 
00262 void NuFCExperimentFactory::FillFromFilter(TTree *tin, int det)
00263 {
00264   MSG("NuFCExperimentFactory",Msg::kInfo) << "Entering FillFromFilter" << endl;
00265   
00266   Float_t energy;       tin->SetBranchAddress("energy",       &energy);
00267   Float_t trkEn;        tin->SetBranchAddress("trkEn",        &trkEn);
00268   Float_t shwEn;        tin->SetBranchAddress("shwEn",        &shwEn);
00269   Float_t neuEnMC;      tin->SetBranchAddress("neuEnMC",      &neuEnMC);  
00270   Int_t   iaction;      tin->SetBranchAddress("iaction",      &iaction);    
00271   Int_t   inu;          tin->SetBranchAddress("inu",          &inu);
00272   Float_t charge;       tin->SetBranchAddress("charge",       &charge);
00273   Float_t ppvz;         tin->SetBranchAddress("ppvz",         &ppvz); 
00274   Int_t   containedTrk; tin->SetBranchAddress("containedTrk", &containedTrk); 
00275   Float_t fluxErr;      tin->SetBranchAddress("fluxErr",      &fluxErr); 
00276   
00277   float vals[10];
00278   for (Int_t i=0; i < tin->GetEntries(); ++i) {
00279     tin->GetEntry(i);
00280     this->PrintLoopProgress(i,tin->GetEntries());
00281    
00282     vals[0] = energy;
00283     vals[1] = trkEn;
00284     vals[2] = shwEn;
00285     vals[3] = neuEnMC;
00286     vals[4] = (float)iaction;
00287     vals[5] = (float)inu;
00288     vals[6] = charge;
00289     vals[7] = ppvz;    
00290     vals[8] = (float)containedTrk;
00291     vals[9] = fluxErr;
00292     
00293     if (inu == 16 || inu == -16) {
00294       // Ignore taus from Nue's, NC's
00295 //      if (nu->inunoosc == 12 || nu->inunoosc==-12 || nu->iaction == 0) continue;
00296       if (iaction == 0) continue;
00297       StoreEvent(kTauPQ, vals, det);
00298     }
00299     else if (iaction == 0) StoreEvent(kNCPQ, vals, det);
00300     else if (inu == -14)   {
00301       StoreEvent(kAppearedPQ, vals, det);
00302       StoreEvent(kSignalPQ, vals, det);
00303     }
00304     else StoreEvent(kWrongSignPQ, vals, det);
00305   }
00306   MSG("NuFCExperimentFactory",Msg::kInfo) << "Leaving FillFromFilter" << endl;  
00307 }
00308  
00309 
00313 void NuFCExperimentFactory::FillFromFCTree(TTree *tin, int det)
00314 {
00315   MSG("NuFCExperimentFactory",Msg::kInfo) << "Entering FillFromFCTree" << endl;
00316   
00317   NuFCEvent *nu = new NuFCEvent();
00318   tin->SetBranchAddress("NuFCEvent", &nu);
00319 
00320   for (Int_t i=0; i < tin->GetEntries(); ++i) {
00321     tin->GetEntry(i);
00322     this->PrintLoopProgress(i,tin->GetEntries());
00323 
00324     if (nu->inu == 16 || nu->inu == -16) {
00325       // Ignore taus from Nue's, NC's
00326       if (nu->inunoosc == 12 || nu->inunoosc==-12 || nu->iaction == 0) continue;
00327       StoreEvent(kTauPQ, *nu, det);
00328     }
00329     else if (nu->iaction == 0) StoreEvent(kNCPQ, *nu, det);
00330     else if (nu->inu == -14)   {
00331       StoreEvent(kAppearedPQ, *nu, det);
00332       StoreEvent(kSignalPQ, *nu, det);
00333     }
00334     else StoreEvent(kWrongSignPQ, *nu, det);
00335   }
00336   MSG("NuFCExperimentFactory",Msg::kInfo) << "Leaving FillFromFCTree" << endl;  
00337 }
00338 
00339 
00343 void NuFCExperimentFactory::FillFromDST(TString mc_path, int det)
00344 {
00345   MSG("NuFCExperimentFactory",Msg::kInfo) << "Entering FillFromDST(" << mc_path << ")" << endl;
00346   
00347   // TChain holding all the FD MC
00348   NuInputEvents* mc_input = new NuInputEvents();
00349   mc_input->InputFileName(mc_path.Data());
00350   mc_input->InitialiseChains();
00351   mc_input->InitialiseNuEventBranch();  
00352   mc_input->ResetNuEventLoopPositionToStart();
00353   
00354   for (Int_t i=0; i < mc_input->GetEntriesNuEvent(); ++i) {
00355     NuEvent &nu=const_cast<NuEvent&>(mc_input->GetNextNuEvent(Msg::kInfo));
00356     
00357     //this->PrintLoopProgress(i,mc_input->GetEntriesNuEvent());
00358     
00359     if (!IsGoodStdCuts(nu)) continue;
00360     
00361     if (nu.inu == 16 || nu.inu == -16) {
00362       // Ignore taus from Nue's, NC's
00363       if (nu.inunoosc == 12 || nu.inunoosc==-12 || nu.iaction == 0) continue;
00364       StoreEvent(kTauPQ, nu, det);
00365     }
00366     else if (nu.iaction == 0) StoreEvent(kNCPQ, nu, det);
00367     else if (nu.inu == -14)   {
00368       StoreEvent(kAppearedPQ, nu, det);
00369       StoreEvent(kSignalPQ, nu, det);
00370     }
00371     else StoreEvent(kWrongSignPQ, nu, det);
00372   }
00373   
00374   MSG("NuFCExperimentFactory",Msg::kInfo) << "Leaving FillFromDST" << endl;  
00375 }
00376 
00377 
00382 Bool_t NuFCExperimentFactory::IsGoodStdCuts(const NuEvent& nu) const
00383 {
00384   // Only keep reconstructed NuBars
00385   if (nu.charge == -1) return false;
00386     
00387   //get an instance of the code library
00388   NuLibrary& lib=NuLibrary::Instance();
00389   
00390   //cut on the sntp good beam and that coil is on
00391   if (!lib.cuts.IsGoodBeamDetPOTCountingStage(nu)) return false;
00392   //lib.cnt.goodBeamDetPOTCountingStage++;
00393   
00394   //ensure good number of tracks in the event
00395   if (!lib.cuts.IsGoodNumberOfTracks(nu)) return false;
00396   lib.cnt.evtWithTrkCounter++;
00397   
00398   //check if the trk is in the fiducial volume
00399   if (!lib.cuts.IsInFidVolTrk(nu)) return false;
00400   lib.cnt.trkInFidVolCounter++;
00401   
00402   //cut on LI
00403   if (lib.cuts.IsLI(nu)) return false;
00404   lib.cnt.evtNotIsLI++;
00405   
00406   //cut on the data quality
00407   if (!lib.cuts.IsGoodDataQuality(nu)) return false;
00408   lib.cnt.goodDataQualityCounter++;
00409   
00410   //cut on the spill time
00411   if (!lib.cuts.IsGoodTimeToNearestSpill(nu)) return false;
00412   lib.cnt.goodTimeToNearestSpillCounter++;
00413   
00414   //cut on the beam
00415   if (!lib.cuts.IsGoodBeam(nu)) return false;
00416   lib.cnt.goodBeamInfoDBCounter++;
00417   
00418   //require a good trk fit
00419   if (!lib.cuts.IsGoodTrackFitPass(nu)) return false;
00420   lib.cnt.goodTrkPassCounter++;
00421   
00422   //require a forward going neutrino about beam direction
00423   if (!lib.cuts.IsGoodDirCos(nu)) return false;
00424   lib.cnt.goodDirectionCosineCounter++;
00425   
00426   //cut on the PID
00427   if (!lib.cuts.IsGoodPID(nu)) return false;
00428   lib.cnt.goodPIDCounter++;   
00429   
00430   //cut on the fractional track momentum and sign error      
00431   if (!lib.cuts.IsGoodSigmaQP_QP(nu)) return false;
00432   lib.cnt.goodFitSigQPCounter++;
00433   
00434   //cut on the track fit probability      
00435   if (!lib.cuts.IsGoodFitProb(nu)) return false;
00436   lib.cnt.goodFitProbCounter++;    
00437   
00438   //cut on majority curvature
00439   if (!lib.cuts.IsGoodMajorityCurvature(nu)) return false;
00440   
00441   // Cut on the track length
00442   if (!lib.cuts.IsGoodTrackLength(nu)) return false;
00443   
00444   // Cut on the relative angle
00445   if (!lib.cuts.IsGoodRelAngle(nu)) return false;
00446   
00447   return true;
00448 }
00449 
00450 
00455 void NuFCExperimentFactory::GenerateND(NuMMRunNuBar * mmRunSource)
00456 {
00457   if (noND) {
00458     MAXMSG("NuFCExperimentFactory",Msg::kInfo,1) << "Not Generating the ND" << endl;
00459     fPQHistND = *(mmRunSource->GetNDBarData());
00460   }
00461   else {  
00462     MAXMSG("NuFCExperimentFactory",Msg::kInfo,1) << "Entering GenerateND" << endl;
00463     TString name = "ndSpect";
00464     name += counter;
00465     TH1D newND(name,"ND Spect", numRecoBins, &(vReco[0]));
00466     TH1D newDP(name+"_dp","ND Spect, DP", numRecoBins, &(vReco[0]));      
00467     /*
00468      unsigned int max = event[IntND].size();
00469      if (max == 0) {
00470      MSG("NuFCExperimentFactor",Msg::kError) << "No ND events loaded.  Cannot make an ND spectrum."
00471      }
00472      */
00473     
00474     double E;
00475     double rw;
00476     vector<NuFCEvent*>::const_iterator it;
00477     for (it = events[IntND].begin(); it != events[IntND].end(); ++it) {
00478       E = GetTrkEnergy(*it) + GetShowerEnergy(*it);
00479       rw = (*it)->rw;
00480       rw *= GetBGShift(*it);
00481       rw *= GetXSecShift(*it);
00482       rw *= GetSKZPShift(*it);
00483       
00484       if (dp_corr) {
00485         if (IsDP(*it)) newDP.AddBinContent(EBin(E), rw);
00486         else           newND.AddBinContent(EBin(E), rw);
00487       }
00488       else {
00489         rw *= GetDPShift(*it);
00490         newND.AddBinContent(EBin(E), rw);
00491       }
00492     }
00493     
00494     if (dp_corr) {
00495       // Set the decay pipe systematic size
00496       int lowb = 1;
00497       int highb = newND.GetXaxis()->FindFixBin(13.0);
00498       double U = newND.Integral(lowb, highb) / ndPoT * 2.92878e+20;
00499       double D = newDP.Integral(lowb, highb)/ ndPoT * 2.92878e+20;
00500       double N = 198064.;
00501       dp_shift = (N - U) / D;
00502       if (dp_shift < 0) dp_shift = 0;
00503       newDP.Scale(dp_shift);
00504       newND.Add(&newDP);
00505     }
00506     
00507     fPQHistND.ResetSpectrum(newND);
00508     fPQHistND.ResetPoT(ndPoT);
00509     MAXMSG("NuFCExperimentFactory",Msg::kInfo,1) << "Leaving GenerateND" << endl;
00510   }
00511 
00512   fNQHistND = *(mmRunSource->GetNDNuData());
00513 }
00514 
00515 
00521 int NuFCExperimentFactory::EBin(double E) const
00522 {
00523   if (E < 0) return 0;
00524   if (E < 0.5) return 1;
00525   if (E < 20.) return static_cast<int>(E*4.);
00526   if (E < 30.) return static_cast<int>(E)+60;
00527   if (E < 50.) return static_cast<int>(E)/2+75;
00528   return 100;
00529 }
00530 
00531 
00532 
00539 void NuFCExperimentFactory::PrintLoopProgress(Int_t entry,Float_t nEntries) const
00540 {
00541   Float_t fract=ceil(nEntries/20.);  
00542   if (ceil(((Float_t)entry)/fract)==((Float_t)entry)/fract){
00543     MSG("NuFCExperimentFactory",Msg::kInfo) 
00544     <<"Fraction of loop complete: "<<entry 
00545     <<"/"<<nEntries<<"  ("
00546     <<(Int_t)(100.*entry/nEntries)<<"%)"<<endl;
00547   }
00548 }
00549 
00550   
00551 
00552 
00557 int NuFCExperimentFactory::Int(Sample_t s) const
00558 {
00559   switch (s) {
00560       case kSignalPQ:
00561         return 1;
00562       case kWrongSignPQ:
00563         return 2;
00564       case kNCPQ:
00565         return 3;
00566       case kTauPQ:
00567         return 4;
00568       case kAppearedPQ:
00569         return 5;
00570       default:
00571         MSG("NuFCExperimentFactor",Msg::kError) << s << " is not a known Sample_t.  Returning -1" << endl;
00572         return -1;
00573   }
00574 }
00575 
00576 
00581 void NuFCExperimentFactory::Distro(Sample_t s, TString name, TString title) 
00582 {
00583   spect[Int(s)] = new TH1D(name, title, numTrueBins, &(vTrue[0]));
00584   hSampler[Int(s)] = new TH1D();  // Prevents seg faults
00585 }
00586 
00587 
00591 TH1D * NuFCExperimentFactory::Distro(Sample_t s) const
00592 {
00593   return spect[Int(s)];
00594 }
00595 
00596 
00602 void NuFCExperimentFactory::StoreEvent(Sample_t s, float *vals, int det)
00603 {
00604   NuFCEvent loc;
00605   loc.energy       = vals[0];
00606   loc.trkEn        = vals[1];
00607   loc.shwEn        = vals[2];
00608   loc.neuEnMC      = vals[3];
00609   loc.iaction      = (Int_t)vals[4];
00610   loc.inu          = (Int_t)vals[5];
00611   loc.charge       = (Int_t)vals[6];
00612   loc.ppvz         = vals[7];
00613   loc.containedTrk = (Int_t)vals[8];
00614   loc.fluxErr      = vals[9];    
00615   
00616   StoreEvent(s, loc, det);
00617 }
00618 
00619 
00624 void NuFCExperimentFactory::StoreEvent(Sample_t s, NuEvent ev, int det)
00625 {
00626   NuFCEvent loc(ev);
00627   StoreEvent(s, loc, det);
00628 }
00629 
00630 
00635 void NuFCExperimentFactory::StoreEvent(Sample_t s, NuFCEvent ev, int det)
00636 {
00637   NuFCEvent * loc = new NuFCEvent(ev);
00638   loc->detector = det;
00639   
00640   if (loc->detector == 2) { // Far Det and Taus
00641     events[Int(s)].push_back(loc);
00642     
00643     double E;
00644     if (s == kNCPQ) E = loc->energy;
00645     else            E = loc->neuEnMC;
00646     
00647     Distro(s)->Fill(E);
00648   }
00649   else if (loc->detector == 1) {
00650     // Prevent double counting the appeared events.
00651     if (s != kAppearedPQ) events[IntND].push_back(loc);
00652   }
00653   else {
00654     MSG("NuFCExperimentFactory",Msg::kWarning) << "Detector " << det << " not recognized.  Event not stored." << endl;
00655   }
00656 }
00657 
00658 
00669 double NuFCExperimentFactory::GetReject(Sample_t s, int i) const
00670 {
00671   double Esel, reject;
00672   if (s == kNCPQ) Esel = events[Int(s)][i]->energy;
00673   else            Esel = events[Int(s)][i]->neuEnMC;
00674   
00675   int bin = hSampler[Int(s)]->GetXaxis()->FindFixBin(Esel);
00676   reject = hSampler[Int(s)]->GetBinContent(bin);
00677   return reject;
00678 }
00679 
00680 
00689 void NuFCExperimentFactory::MakeSampler(Sample_t s, NuMatrixSpectrum pred)
00690 {
00691   if (hSampler[Int(s)]) delete hSampler[Int(s)];
00692   hSampler[Int(s)] = new TH1D(*(pred.Spectrum()));
00693   hSampler[Int(s)]->Divide(Distro(s));
00694   hSampler[Int(s)]->Scale(1./hSampler[Int(s)]->GetMaximum());
00695 }
00696 
00697 
00706 void NuFCExperimentFactory::DebugMode(bool deb)
00707 {
00708   fixedSyst = deb;
00709   
00710   if (fixedSyst) {
00711     MSG("NuFCExperimentFactory",Msg::kInfo) << "Now in debugging mode.  Systematics are not random -- they are fixed at the input values." << endl;
00712   }
00713   else {
00714     MSG("NuFCExperimentFactory",Msg::kInfo) << "Now out of debugging mode.  Systematics are randomly chosen based on input values." << endl;
00715   }
00716 }
00717 
00718 
00726 void NuFCExperimentFactory::NoSystematics()
00727 {
00728   norm_size = 0;
00729   
00730   curv_size = 0;
00731   relcurv_size = 0;
00732   range_size = 0;
00733   shower_size = 0;
00734   relshow_size = 0;
00735   
00736   dp_size = 0;
00737   bg_size = 0;
00738   
00739   xsec_size = 0;
00740   skzp_size = 0;
00741   
00742   // Zero out the shifts
00743   RollSystematics();
00744 }
00745 
00746 
00751 double NuFCExperimentFactory::GetShift(double size) const
00752 { 
00753   if (fixedSyst)     return size;
00754   else if (gausSyst) return fRandy->Gaus(0, size);
00755   else               return fRandy->Uniform(-size, size); 
00756 }
00757 
00758 
00762 void NuFCExperimentFactory::RollSystematics()
00763 {
00764   // Get a single copy of these systematics
00765   norm_shift = 1 + GetShift(norm_size);
00766   
00767   curv_shift = 1 + GetShift(curv_size);
00768   relcurv_shift = 1 + GetShift(relcurv_size);
00769   range_shift = 1 + GetShift(range_size);
00770   shower_shift = 1 + GetShift(shower_size);
00771   relshow_shift = 1 + GetShift(relshow_size);
00772 
00773   if (!dp_corr) {
00774     if (dp_size == 0) dp_shift = 1;
00775     else if (dp_old)  dp_shift = 1.0 + GetShift(dp_size);
00776     else              dp_shift = 0.8 + GetShift(dp_size);
00777     if (dp_shift < 0) dp_shift = 0;
00778   }
00779   bg_shift = 1 + GetShift(bg_size);
00780   
00781   xsec_shift = GetShift(xsec_size);
00782   skzp_shift = GetShift(skzp_size);
00783 }
00784 
00785 
00789 void NuFCExperimentFactory::InvertShifts()
00790 {
00791   // Get a single copy of these systematics
00792   norm_shift = 2 - norm_shift;
00793   
00794   curv_shift = 2 - curv_shift;
00795   relcurv_shift = 2 - curv_shift;
00796   range_shift = 2 - range_shift;
00797   shower_shift = 2 - shower_shift;
00798   relshow_shift = 2 - relshow_shift;
00799   
00800   dp_shift = 2 - dp_shift;
00801   bg_shift = 2 - bg_shift;
00802   
00803   xsec_shift *= -1;
00804   skzp_shift *= -1;
00805 }
00806 
00811 double NuFCExperimentFactory::GetNormShift() const
00812 {
00813   return norm_shift;
00814 }
00815 
00820 double NuFCExperimentFactory::GetTrkEnergy(const NuFCEvent* nu) const
00821 {
00822   double E = nu->trkEn;
00823   if (nu->containedTrk == 1) E *= range_shift;
00824   else {
00825     E *= curv_shift;
00826     if (nu->detector == 2) E *= relcurv_shift;
00827   }
00828   return E;
00829 }
00830 
00835 double NuFCExperimentFactory::GetShowerEnergy(const NuFCEvent* nu) const
00836 {
00837   double E = nu->shwEn * shower_shift;
00838   if (nu->detector == 2) E *= relshow_shift;
00839   return E;
00840 }
00841 
00842 
00846 bool NuFCExperimentFactory::IsDP(const NuFCEvent* nu) const
00847 {
00848   if (nu->ppvz < 4500) return false;
00849   if (abs(nu->ptype) == 13) return false;
00850   return true;
00851   
00852 }
00853 
00858 double NuFCExperimentFactory::GetDPShift(const NuFCEvent* nu) const
00859 {
00860   if (IsDP(nu)) return dp_shift;
00861   return 1;  
00862 }
00863 
00868 double NuFCExperimentFactory::GetBGShift(const NuFCEvent* nu) const
00869 {
00870   if (nu->iaction == 0 || nu->inu == 14) return bg_shift;
00871   return 1;
00872 }
00873 
00879 double NuFCExperimentFactory::GetBGShift(const Sample_t s) const
00880 {
00881   if (s == kWrongSignPQ || s == kNCPQ) return bg_shift;
00882   return 1;
00883 }
00884       
00889 double NuFCExperimentFactory::GetXSecShift(const NuFCEvent* ev) const
00890 {
00891   if (ev->iaction != 1) return 1;
00892   
00893   static double xp = 25.;
00894   static double a = 0.895;
00895   static double xc = 4.0;
00896   static double b = 7.59e-3;
00897   static double c = -8.05e-4;
00898   double E = ev->neuEnMC;
00899   double shift = -0.0617;
00900   
00901   if (E < 25) shift += a - 1 + 2.*(1.-a)*E/xp + (a - 1.)*E*E/(xp*xp);
00902   if (E < xc) shift += (c*(xc-E)*(xc-E)*(xc-E)+b*(xc-E)*(xc-E));
00903   
00904   shift = 1 + xsec_shift * shift;
00905   return shift;
00906 }
00907 
00912 double NuFCExperimentFactory::GetSKZPShift(const NuFCEvent* nu) const
00913 {
00914   return 1. + skzp_shift*(nu->fluxErr - 1.);
00915 }

Generated on Mon Feb 15 11:07:13 2010 for loon by  doxygen 1.3.9.1