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

NCExtrapolationFarNear.cxx

Go to the documentation of this file.
00001 
00002 //
00003 // NCExtrapolationFarNear.cxx
00004 //
00005 //
00006 // J. Koskinen 6/2007
00007 //
00008 // $Id: NCExtrapolationFarNear.cxx,v 1.48 2009/11/26 12:03:29 bckhouse Exp $
00010 
00011 #include "NCUtils/Extrapolation/NCExtrapolationFarNear.h"
00012 #include "NCUtils/Extrapolation/NCEnergyBin.h"
00013 
00014 #include "MessageService/MsgService.h"
00015 
00016 #include "AnalysisNtuples/ANtpAnalysisInfo.h"
00017 #include "AnalysisNtuples/ANtpBeamInfo.h"
00018 #include "AnalysisNtuples/ANtpRecoInfo.h"
00019 #include "AnalysisNtuples/ANtpHeaderInfo.h"
00020 #include "AnalysisNtuples/ANtpTruthInfoBeam.h"
00021 
00022 #include "TCanvas.h"
00023 #include "TDirectory.h"
00024 #include "TGraphErrors.h"
00025 #include "TMath.h"
00026 
00027 #include <fstream>
00028 #include <cassert>
00029 #include <cmath>
00030 
00031 CVSID("$Id: NCExtrapolationFarNear.cxx,v 1.48 2009/11/26 12:03:29 bckhouse Exp $");
00032 
00033 #include "NCExtrapolationModule.h"
00034 #include "NCSpectrumInterpolator.h"
00035 
00036 REGISTER_NCEXTRAPOLATION(NCExtrapolationFarNear, FarNear)
00037 
00038 
00039 static const int kNCSig     = 0; //NC spectrum
00040 static const int kCCSig     = 1; //CC spectrum
00041 static const int kNCBkg     = 2; //CC background in NC spectrum
00042 static const int kCCBkg     = 3; //NC background in CC spectrum
00043 static const int kNCTau     = 4; //CC tau background in NC spectrum
00044 static const int kCCTau     = 5; //CC tau background in CC spectrum
00045 static const int kNCBeamNue = 6; //CC nue background in NC spectrum
00046 static const int kCCBeamNue = 7; //CC nue background in CC spectrum
00047 static const int kNCOscNue  = 8; //CC nue background in NC spectrum
00048 static const int kCCOscNue  = 9; //CC nue background in CC spectrum
00049 
00050 //......................................................................
00051 NCExtrapolationFarNear::NCExtrapolationFarNear()
00052 {
00053   fNCalls = 0;
00054   fDoExtrapolation = true;
00055 
00056   int numBins = kNumEnergyBinsFar;
00057   double bins[kNumEnergyBinsFar+1];
00058 
00059   //use NCType to fill array of bins as it has the right binning already
00060   for( int i = 0; i < numBins+1; ++i ){
00061     bins[i] = kEnergyBinsFar[i];
00062   }
00063 
00064   // Create a true energy binning scheme for the
00065   // F/N matrix
00066 
00067   fTrue_bin_width = bins[numBins]/double(kNumTrueEnergyBins);
00068   vector<double> true_bins(kNumTrueEnergyBins+1, 0);
00069 
00070   for( int i = 0; i < kNumTrueEnergyBins+1; ++i )
00071     true_bins[i] = i*fTrue_bin_width;
00072 
00073 
00074   //--------------------------------------------------
00075   // Far Detector Histograms
00076 
00077   fNom_true_vs_reco.push_back(new TH2D ( "NCNomtruevsreco", "NC True vs. Reco (Nom)",
00078                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00079   fNom_true_vs_reco.push_back(new TH2D ( "CCNomtruevsreco", "CC True vs. Reco (Nom)",
00080                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00081   fNom_true_vs_reco.push_back(new TH2D ( "NCNomtruevsreco_bkg", "NC True vs. Reco (Nom)bkg",
00082                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00083   fNom_true_vs_reco.push_back(new TH2D ( "CCNomtruevsreco_bkg", "CC True vs. Reco (Nom)bkg",
00084                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00085   fNom_true_vs_reco.push_back(new TH2D ( "NCNomtruevsreco_tau", "NC True vs. Reco (Nom)tau",
00086                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00087   fNom_true_vs_reco.push_back(new TH2D ( "CCNomtruevsreco_tau", "CC True vs. Reco (Nom)tau",
00088                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00089   fNom_true_vs_reco.push_back(new TH2D ( "NCNomtruevsreco_beamnue", "NC True vs. Reco (Nom)beamnue",
00090                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00091   fNom_true_vs_reco.push_back(new TH2D ( "CCNomtruevsreco_beamnue", "CC True vs. Reco (Nom)beamnue",
00092                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00093   fNom_true_vs_reco.push_back(new TH2D ( "NCNomtruevsreco_oscnue", "NC True vs. Reco (Nom)oscnue",
00094                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00095   fNom_true_vs_reco.push_back(new TH2D ( "CCNomtruevsreco_oscnue", "CC True vs. Reco (Nom)oscnue",
00096                                          numBins, bins, kNumTrueEnergyBins, &true_bins.at(0) ));
00097 
00098   fFN.push_back( new TH1D( "FNNC" , "FN NC", numBins, bins ) );
00099   fFN.push_back( new TH1D( "FNCC" , "FN CC", numBins, bins ) );
00100 
00101   fFD_fit.push_back( new TH1D( "FD_fit_nc" , "FD_fit NC", numBins, bins ) );
00102   fFD_fit.push_back( new TH1D( "FD_fit_cc" , "FD_fit CC", numBins, bins ) );
00103 
00104   //--------------------------------------------------
00105   // Near Detector Histograms
00106 
00107   fND_data.push_back( new TH1D( "ND_data_NC" , "ND_data_NC", numBins, bins ) );
00108   fND_data.push_back( new TH1D( "ND_data_CC" , "ND_data_CC", numBins, bins ) );
00109 
00110   //------------------------------
00111   // muon neutrinos
00112 
00113   fND_MC.push_back( new TH1D( "ND_MC_NC" , "ND_MC_NC", numBins, bins ) );
00114   fND_MC.push_back( new TH1D( "ND_MC_CC" , "ND_MC_CC", numBins, bins ) );
00115   fND_MC.push_back( new TH1D( "ND_MC_NC_ccbkg" , "ND_MC_NC-ccbkg", numBins, bins ) );
00116   fND_MC.push_back( new TH1D( "ND_MC_CC_ncbkg" , "ND_MC_CC-ncbkg", numBins, bins ) );
00117 
00118   fND_MC.push_back( new TH1D( "ND_MC_NC_tau" , "ND_MC_NC-tau", numBins, bins ) );
00119   fND_MC.push_back( new TH1D( "ND_MC_CC_tau" , "ND_MC_CC-tau", numBins, bins ) );
00120 
00121   fND_MC.push_back( new TH1D( "ND_MC_NC_beamnue" , "ND_MC_NC-beamnue", numBins, bins ) );
00122   fND_MC.push_back( new TH1D( "ND_MC_CC_beamnue" , "ND_MC_CC-beamnue", numBins, bins ) );
00123   fND_MC.push_back( new TH1D( "ND_MC_NC_oscnue" , "ND_MC_NC-oscnue", numBins, bins ) );
00124   fND_MC.push_back( new TH1D( "ND_MC_CC_oscnue" , "ND_MC_CC-oscnue", numBins, bins ) );
00125 
00126   fFD_data[kNCSig] = new TH1D("FD_data_NC", "FD data NC", kNumEnergyBinsFar, kEnergyBinsFar);
00127   fFD_data[kCCSig] = new TH1D("FD_data_CC", "FD data CC", kNumEnergyBinsFar, kEnergyBinsFar);
00128 
00129   fSmoothWidth = 0; // Don't do any smoothing
00130 }
00131 //----------------------------------------------------------------------
00132 
00133 
00134 
00135 //......................................................................
00136 NCExtrapolationFarNear::~NCExtrapolationFarNear(){}
00137 
00138 
00139 const Registry& NCExtrapolationFarNear::DefaultConfig()
00140 {
00141   static Registry r;
00142 
00143   r.UnLockValues();
00144 
00145   r.Set("FarNearSmoothingWidth", 0.05);
00146 
00147   r.LockValues();
00148   return r;
00149 }
00150 
00151 
00152 //----------------------------------------------------------------------
00153 //this method allows the user to pass in appropriate settings for the
00154 //extrapolation such as fLocations of files, whether to generate the files
00155 //again, etc.  the registry comes from the job module GetConfig method
00156 void NCExtrapolationFarNear::Prepare(const Registry& r)
00157 {
00158   MSG("NCExtrapolationFarNear", Msg::kInfo) <<  "PREPARING F/N EXTRAPOLATION" << endl;
00159 
00160   // the base class takes care of turning the systematic parameters on/off
00161   // and setting their adjusted values if any
00162 
00163   NCExtrapolation::Prepare(r);
00164 
00165   double      tmpd;
00166 
00167   //  if(r.Get("UE3SqrVal",             tmpd)) fUE3Sqr                     = tmpd;
00168 
00169   if(r.Get("FarNearSmoothingWidth", tmpd)) fSmoothWidth = tmpd;
00170 }
00171 
00172 
00173 //----------------------------------------------------------------------
00174 template<class T> void NCExtrapolationFarNear::
00175 HistSmoothHelper(T* h, bool is2D, double weight, double x, double y)
00176 {
00177   if(fSmoothWidth == 0){
00178     // Shortcut all the below and just fill the histogram
00179     if(is2D)
00180       ((TH2D*)h)->Fill(x, y, weight);
00181     else
00182       h->Fill(x, weight);
00183     return;
00184   }
00185 
00186   // Paranoia over some scary text in the documentation for TAxis::GetBin
00187   h->SetBit(TH1::kCanRebin, false);
00188 
00189   TAxis* xaxis = h->GetXaxis();
00190   const int nbinsx = xaxis->GetNbins();
00191 
00192   // Warning - this number will only work in axis calls, not histogram calls
00193   const int xbin = xaxis->FindBin(x);
00194   const double lo = xaxis->GetBinLowEdge(xbin);
00195   const double hi = xaxis->GetBinUpEdge(xbin);
00196 
00197   const int ybin = is2D ? h->GetYaxis()->FindBin(y) : 0;
00198 
00199   const int histBin = xbin + (nbinsx+2)*ybin;
00200 
00201   const double dist_lo = x-lo;
00202   const double dist_hi = hi-x;
00203 
00204   // Don't smear events into the underflow bin
00205   const bool do_lo = xbin > 1 && dist_lo < fSmoothWidth*x;
00206   // Don't smear events into the overflow bin
00207   const bool do_hi = xbin < nbinsx && dist_hi < fSmoothWidth*x;
00208 
00209   double weight_here = 1;
00210   double weight_lo = 0;
00211   double weight_hi = 0;
00212 
00213   if(do_lo){
00214     const double transfer = .5*(1-dist_lo/(fSmoothWidth*x));
00215     weight_here -= transfer;
00216     weight_lo += transfer;
00217   }
00218   if(do_hi){
00219     const double transfer = .5*(1-dist_hi/(fSmoothWidth*x));
00220     weight_here -= transfer;
00221     weight_hi += transfer;
00222   }
00223 
00224   assert(weight_here >= .499);
00225   assert(weight_lo <= .501);
00226   assert(weight_hi <= .501);
00227   assert(weight_here <= 1);
00228   assert(weight_lo >= 0);
00229   assert(weight_hi >= 0);
00230   assert(fabs(weight_here+weight_lo+weight_hi-1) < .001);
00231 
00232   h->fArray[histBin] += weight*weight_here;
00233 
00234   if(do_lo){
00235     h->fArray[histBin-1] += weight*weight_lo;
00236   }
00237   if(do_hi){
00238     h->fArray[histBin+1] += weight*weight_hi;
00239   }
00240 }
00241 
00242 template void NCExtrapolationFarNear::
00243 HistSmoothHelper<TH1D>(TH1D*, bool, double, double, double);
00244 template void NCExtrapolationFarNear::
00245 HistSmoothHelper<TH2D>(TH2D*, bool, double, double, double);
00246 
00247 void NCExtrapolationFarNear::FillHistogramSmoothed(TH1D* h, double x, double weight)
00248 {
00249   HistSmoothHelper(h, false, weight, x);
00250 }
00251 
00252 
00253 void NCExtrapolationFarNear::FillHistogramSmoothed2D(TH2D* h, double x, double y, double weight)
00254 {
00255   HistSmoothHelper(h, true, weight, x, y);
00256 }
00257 
00258 
00259 //----------------------------------------------------------------------
00260 void NCExtrapolationFarNear::FillDataMCHistogramsNear(NCBeam* beam,
00261                                                       NCType::EEventType nccc,
00262                                                       NC::SystPars systPars)
00263 {
00264   using Detector::kNear;
00265 
00266   //loop over NCEnergy bin objects in the near detector
00267   //to get the energies from the data events in each bin
00268   //and fill the fND_data histogram
00269 
00270 
00271   // Alters the systematics 'weights' to reflect the current
00272   // value returned by the fitter.
00273 
00274   int sig         = kNCSig;
00275   int bkg         = kNCBkg;
00276   int tau         = kNCTau;
00277   int beamnue     = kNCBeamNue;
00278   int oscnue      = kNCOscNue;
00279   double bkgShift = systPars.CCBkgScale();
00280   double cleanShift = 1.;
00281 
00282   if(nccc == NCType::kCC){
00283     sig      = kCCSig;
00284     bkg      = kCCBkg;
00285     tau      = kCCTau;
00286     beamnue  = kCCBeamNue;
00287     oscnue   = kCCOscNue;
00288     bkgShift = systPars.NCBkgScale();
00289   }
00290 
00291   fND_data[sig]->Reset( "ICE" );
00292   fND_MC[sig]->Reset( "ICE" );
00293   fND_MC[bkg]->Reset( "ICE" );
00294   fND_MC[tau]->Reset( "ICE" );
00295   fND_MC[beamnue]->Reset( "ICE" );
00296   fND_MC[oscnue]->Reset( "ICE" );
00297 
00298   for(int b  = 0; b < beam->GetNumberEnergyBins(nccc); ++b){
00299     NCEnergyBin* bin = beam->GetEnergyBin(b, nccc);
00300 
00301     const int dataSize       = bin->GetDataVectorSize();
00302     const int mcSize         = bin->GetMCSignalVectorSize();
00303     const int mcSize_bkg     = bin->GetMCBackgroundVectorSize();
00304     const int mcSize_tau     = bin->GetMCNuTauVectorSize();
00305     const int mcSize_beamnue = bin->GetMCBeamNuEVectorSize();
00306     const int mcSize_oscnue  = bin->GetMCOscNuEVectorSize();
00307 
00308     // The variables that get filled with event information
00309     double trueEnergy    = 0;
00310     double recoShowerE   = 0;
00311     double recoMuonE     = 0;
00312     double energy        = 0;
00313     double weight        = 0;
00314     int    flavor        = 0;
00315 
00316     for(int e = 0; e < dataSize; ++e){
00317       bin->GetDataInformation(energy, weight, e);
00318       fND_data[sig]->Fill(energy, weight);
00319     }
00320 
00321     //------------------------------
00322     // numu
00323     for(int e = 0; e < mcSize; ++e){
00324       bin->GetMCInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00325       if(nccc == NCType::kNC) recoMuonE = 0;
00326       cleanShift = systPars.NDCleaningScale(nccc, recoShowerE);
00327       FillHistogramSmoothed(fND_MC[sig], recoShowerE*systPars.ShowerScale(kNear) + recoMuonE*systPars.TrackScale(), weight*cleanShift);
00328     }
00329 
00330     for(int e = 0; e < mcSize_bkg; ++e){
00331       bin->GetMCBackgroundInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00332       if(nccc == NCType::kNC) recoMuonE = 0;
00333       cleanShift = systPars.NDCleaningScale(nccc, recoShowerE);
00334       FillHistogramSmoothed(fND_MC[bkg], recoShowerE*systPars.ShowerScale(kNear) + recoMuonE*systPars.TrackScale(), weight*bkgShift*cleanShift);
00335     }
00336 
00337     //------------------------------
00338     // nutau
00339     for(int e = 0; e < mcSize_tau; ++e){
00340       bin->GetMCNuTauInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00341       if(nccc == NCType::kNC) recoMuonE = 0;
00342       cleanShift = systPars.NDCleaningScale(nccc, recoShowerE);
00343       FillHistogramSmoothed(fND_MC[tau], recoShowerE*systPars.ShowerScale(kNear) + recoMuonE*systPars.TrackScale(), weight*cleanShift);
00344     }
00345 
00346     //------------------------------
00347     // beam nue
00348     for(int e = 0; e < mcSize_beamnue; ++e){
00349       bin->GetMCBeamNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00350       if(nccc == NCType::kNC) recoMuonE = 0;
00351       cleanShift = systPars.NDCleaningScale(nccc, recoShowerE);
00352       FillHistogramSmoothed(fND_MC[beamnue], recoShowerE*systPars.ShowerScale(kNear) + recoMuonE*systPars.TrackScale(), weight*cleanShift);
00353     }
00354 
00355     //------------------------------
00356     // oscillated nue
00357     for(int e = 0; e < mcSize_oscnue; ++e){
00358       bin->GetMCOscNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00359       if(nccc == NCType::kNC) recoMuonE = 0;
00360       cleanShift = systPars.NDCleaningScale(nccc, recoShowerE);
00361       FillHistogramSmoothed(fND_MC[oscnue], recoShowerE*systPars.ShowerScale(kNear) + recoMuonE*systPars.TrackScale(), weight*cleanShift);
00362     }
00363 
00364   } // end for b
00365 }
00366 
00367 //----------------------------------------------------------------------
00368 void NCExtrapolationFarNear::FillDataMCHistogramsFar(NCBeam* beam,
00369                                                      NCType::EEventType nccc,
00370                                                      NC::SystPars systPars)
00371 {
00372   using Detector::kFar;
00373 
00374   //loop over NCEnergy bin objects in the near detector
00375   //to get the energies from the data events in each bin
00376   //and fill the fFD_data histogram
00377   double trueEnergy    = 0.;
00378   double recoShowerE   = 0.;
00379   double recoMuonE     = 0.;
00380   double weight        = 0.;
00381   int    flavor        = 0;
00382 
00383   int sig         = kNCSig;
00384   int bkg         = kNCBkg;
00385   int tau         = kNCTau;
00386   int beamnue     = kNCBeamNue;
00387   int oscnue      = kNCOscNue;
00388   double bkgShift = systPars.CCBkgScale();
00389 
00390   if(nccc == NCType::kCC){
00391     sig      = kCCSig;
00392     bkg      = kCCBkg;
00393     tau      = kCCTau;
00394     beamnue  = kCCBeamNue;
00395     oscnue   = kCCOscNue;
00396     bkgShift = systPars.NCBkgScale();
00397   }
00398 
00399   fNom_true_vs_reco[sig]->Reset( "ICE" );
00400   fNom_true_vs_reco[bkg]->Reset( "ICE" );
00401   fNom_true_vs_reco[tau]->Reset( "ICE" );
00402   fNom_true_vs_reco[beamnue]->Reset( "ICE" );
00403   fNom_true_vs_reco[oscnue]->Reset( "ICE" );
00404 
00405 
00406   const int B = beam->GetNumberEnergyBins(nccc);
00407   for(int b = 0; b < B; ++b){
00408     const NCEnergyBin* bin = beam->GetEnergyBin(b, nccc);
00409 
00410     const int mcSize         = bin->GetMCSignalVectorSize();
00411     const int mcSize_bkg     = bin->GetMCBackgroundVectorSize();
00412     const int mcSize_tau     = bin->GetMCNuTauVectorSize();
00413     const int mcSize_beamnue = bin->GetMCBeamNuEVectorSize();
00414     const int mcSize_oscnue  = bin->GetMCOscNuEVectorSize();
00415 
00416     //numu
00417     for(int e = 0; e < mcSize; ++e){
00418       bin->GetMCInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00419       if(nccc == NCType::kNC) recoMuonE = 0;
00420       FillHistogramSmoothed2D(fNom_true_vs_reco[sig], recoShowerE*systPars.ShowerScale(kFar) + recoMuonE*systPars.TrackScale(), trueEnergy, weight*systPars.NormScale());
00421     }
00422 
00423     for(int e = 0; e < mcSize_bkg; ++e){
00424       bin->GetMCBackgroundInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00425       if(nccc == NCType::kNC) recoMuonE = 0;
00426       FillHistogramSmoothed2D(fNom_true_vs_reco[bkg], recoShowerE*systPars.ShowerScale(kFar) + recoMuonE*systPars.TrackScale(), trueEnergy, weight*systPars.NormScale()*bkgShift);
00427     }
00428 
00429     //nutau
00430     for(int e = 0; e < mcSize_tau; ++e){
00431       bin->GetMCNuTauInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00432       if(nccc == NCType::kNC) recoMuonE = 0;
00433       FillHistogramSmoothed2D(fNom_true_vs_reco[tau], recoShowerE*systPars.ShowerScale(kFar) + recoMuonE*systPars.TrackScale(), trueEnergy, weight*systPars.NormScale());
00434     }
00435 
00436     //beamnue
00437     for(int e = 0; e < mcSize_beamnue; ++e){
00438       bin->GetMCBeamNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00439       if(nccc == NCType::kNC) recoMuonE = 0;
00440       FillHistogramSmoothed2D(fNom_true_vs_reco[beamnue], recoShowerE*systPars.ShowerScale(kFar) + recoMuonE*systPars.TrackScale(), trueEnergy, weight*systPars.NormScale());
00441     }
00442 
00443     //oscnue
00444     for(int e = 0; e < mcSize_oscnue; ++e){
00445       bin->GetMCOscNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00446       if(nccc == NCType::kNC) recoMuonE = 0;
00447       FillHistogramSmoothed2D(fNom_true_vs_reco[oscnue], recoShowerE*systPars.ShowerScale(kFar) + recoMuonE*systPars.TrackScale(), trueEnergy, weight*systPars.NormScale());
00448     }
00449 
00450     const int N = bin->GetDataVectorSize();
00451     for(int n = 0; n < N; ++n){
00452       double energy, weight;
00453       bin->GetDataInformation(energy, weight, n);
00454       fFD_data[sig]->Fill(energy, weight);
00455     } // end for n
00456   } // end for b
00457 }
00458 //----------------------------------------------------------------------
00459 
00460 
00461 //----------------------------------------------------------------------
00462 void NCExtrapolationFarNear::
00463 ConstructFarSpectrum(const NC::OscProb::OscPars* pars)
00464 {
00465   static vector<double*> survivalProbability;
00466 
00467   static bool first = true;
00468   if(first){
00469     first = false;
00470 
00471     fNominal.resize(fNom_true_vs_reco.size());
00472     fOsc.resize(fNom_true_vs_reco.size());
00473 
00474     for(unsigned int h = 0; h < fNom_true_vs_reco.size(); ++h){
00475       fNominal[h].resize(kNumEnergyBinsFar);
00476       fOsc[h].resize(kNumEnergyBinsFar);
00477     }
00478 
00479     survivalProbability.resize(fNom_true_vs_reco.size());
00480     for(unsigned int n = 0; n < fNom_true_vs_reco.size(); ++n)
00481       survivalProbability[n] = new double[kNumTrueEnergyBins];
00482   }
00483 
00484   static const NC::OscProb::OscPars* prevpars = 0;
00485 
00486   // Transition probability does not depend on reco energy - so we
00487   // can precalculate it out here.
00488   // Reuse the calculations from last time round if the oscillations
00489   // parameters haven't changed since then.
00490   if(!prevpars || !pars->IsEquiv(prevpars)){
00491     for(int h = 0; h < int(fNom_true_vs_reco.size()); ++h){
00492       NCType::EOscMode oscType;
00493       NCType::EEventType interaction;
00494 
00495       switch(h){
00496       case kNCSig:
00497       case kCCBkg:
00498         interaction = NCType::kNC;
00499         oscType     = NCType::kNuMuToNuMu;
00500         break;
00501       case kCCSig:
00502       case kNCBkg:
00503         interaction = NCType::kCC;
00504         oscType     = NCType::kNuMuToNuMu;
00505         break;
00506       case kNCTau:
00507       case kCCTau:
00508         interaction = NCType::kCC;
00509         oscType     = NCType::kNuMuToNuTau;
00510         break;
00511       case kNCBeamNue:
00512       case kCCBeamNue:
00513         interaction = NCType::kCC;
00514         oscType     = NCType::kNuEToNuE;
00515         break;
00516       case kNCOscNue:
00517       case kCCOscNue:
00518         interaction = NCType::kCC;
00519         oscType     = NCType::kNuMuToNuE;
00520         break;
00521       default:
00522         MSG("NCExtrapolationFarNear", Msg::kError) << "Interaction type or flavor is incorrect" << endl;
00523         return;
00524       }
00525 
00526       double* sph = survivalProbability[h];
00527       for(int j = 0; j < kNumTrueEnergyBins; ++j){
00528         sph[j] = pars->TransitionProbability(oscType,
00529                                              interaction,
00530                                              NCType::kBaseLineFar,
00531                                              (j+0.5)*fTrue_bin_width);
00532       } // end for j
00533     } // end for h
00534   } // end if
00535 
00536 
00537   delete prevpars;
00538   // Sadly OscPars::Clone isn't labelled const for technical reasons.
00539   // Need to cast away constness so that we can call it.
00540   prevpars = const_cast<NC::OscProb::OscPars*>(pars)->Clone();
00541 
00542 
00543   const int nx = kNumEnergyBinsFar+2;
00544   for(unsigned int h = 0; h < fNom_true_vs_reco.size(); ++h){
00545     const double* t2ra = fNom_true_vs_reco[h]->fArray;
00546     vector<double>& nh = fNominal[h];
00547     vector<double>& oh = fOsc[h];
00548     for(int i = 0; i < kNumEnergyBinsFar; ++i){
00549       double& nhi = nh[i];
00550       double& ohi = oh[i];
00551       nhi = 0;
00552       ohi = 0;
00553       const double* sph = survivalProbability[h];
00554       const int oset = i+1+nx;
00555       for(int j = 0; j < kNumTrueEnergyBins; ++j){
00556         //      const double tmpd = t2r->GetCellContent(i+1, j+1);
00557         const double tmpd = t2ra[nx*j+oset];
00558         nhi += tmpd;
00559         ohi += sph[j]*tmpd;
00560       }//end loop over true bins
00561     } // end for i
00562   }//end loop over histograms
00563 
00564   for(int i = 0; i < kNumEnergyBinsFar; ++i){
00565     const double totalMCNC_fd = fOsc[kNCSig][i]
00566       + fOsc[kNCBkg][i]
00567       + fOsc[kNCTau][i]
00568       + fOsc[kNCBeamNue][i]
00569       + fOsc[kNCOscNue][i];
00570 
00571     const double totalMCCC_fd = fOsc[kCCSig][i]
00572       + fOsc[kCCBkg][i]
00573       + fOsc[kCCTau][i]
00574       + fOsc[kCCBeamNue][i]
00575       + fOsc[kCCOscNue][i];
00576 
00577     // TODO - implement this bit in terms of GetNearMCSpectra. Needs some
00578     // work to keep the cacheing correct.
00579     const double totalMCNC_nd = fND_MC.at(kNCSig)->GetBinContent(i+1)
00580       + fND_MC.at(kNCBkg)->GetBinContent(i+1)      // numu
00581       + fND_MC.at(kNCTau)->GetBinContent(i+1)      // nutau
00582       + fND_MC.at(kNCBeamNue)->GetBinContent(i+1)  // beamnue
00583       + fND_MC.at(kNCOscNue)->GetBinContent(i+1);  // oscnue
00584 
00585     const double totalMCCC_nd = fND_MC.at(kCCSig)->GetBinContent(i+1)
00586       + fND_MC.at(kCCBkg)->GetBinContent(i+1)      // numu
00587       + fND_MC.at(kCCTau)->GetBinContent(i+1)      // nutau
00588       + fND_MC.at(kCCBeamNue)->GetBinContent(i+1)  // beamnue
00589       + fND_MC.at(kCCOscNue)->GetBinContent(i+1);  // oscnue
00590 
00591     if(totalMCNC_nd > 0){
00592       fFN[kNCSig]->SetBinContent(i+1, totalMCNC_fd/totalMCNC_nd);
00593       // Set this spectrum up without F/N correction. Will be overwritten if
00594       // fDoExtrapolation. If not then we need it done this way.
00595       fFD_fit[kNCSig]->SetBinContent(i+1, totalMCNC_fd);
00596     }
00597     else if(totalMCNC_nd == 0 && fUseNC){
00598       MSG("NCExtrapolationFarNear", Msg::kInfo) << "MC ND NC HISTO "
00599                                                << "HAS ZERO BIN:"
00600                                                << i+1 << ". PLEASE FIX IT"
00601                                                << endl;
00602     }
00603 
00604     if(totalMCCC_nd > 0){
00605       fFN[kCCSig]->SetBinContent(i+1, totalMCCC_fd/totalMCCC_nd);
00606       // Set this spectrum up without F/N correction. Will be overwritten if
00607       // fDoExtrapolation. If not then we need it done this way.
00608       fFD_fit[kCCSig]->SetBinContent(i+1, totalMCCC_fd);
00609     }
00610     else if(totalMCCC_nd == 0. && fUseCC){
00611       MSG("NCExtrapolationFarNear", Msg::kInfo) << "MC ND CC HISTO "
00612                                                << "HAS ZERO BIN:"
00613                                                << i+1 << ". PLEASE FIX IT"
00614                                                << endl;
00615     }
00616   }//end loop over reco energy bins
00617 
00618   if(fDoExtrapolation){
00619     fFD_fit[kNCSig]->Multiply(fND_data.at(kNCSig), fFN.at(kNCSig));
00620     fFD_fit[kCCSig]->Multiply(fND_data.at(kCCSig), fFN.at(kCCSig));
00621   }
00622 }
00623 //----------------------------------------------------------------------
00624 
00625 
00626 //----------------------------------------------------------------------
00627 void NCExtrapolationFarNear::
00628 FindSpectraForPars(const NC::OscProb::OscPars* oscPars,
00629                    const NC::SystPars& systPars_org,
00630                    vector<NCBeam::Info> beamsToUse,
00631                    vector<TH1*>& expvec,
00632                    vector<TH1*>& obsvec)
00633 {
00634   for(int n = 0; n < NCType::kNumSystematicParameters; ++n){
00635     if(n == NCType::kNormalization) continue;
00636     if(n == NCType::kRelativeHadronicCalibration) continue;
00637     if(n == NCType::kAbsoluteHadronicCalibration) continue;
00638     if(n == NCType::kNCNearClean) continue;
00639     if(n == NCType::kCCBackground) continue;
00640     if(n == NCType::kTrackEnergy) continue;
00641     if(fCoordConv.IsFit(NCType::EFitParam(n))){
00642       MAXMSG("NCExtrapolationFarNear", Msg::kError, 10)
00643         << "Trying to fit systematic " << NCType::kParams[n].name
00644         << " (" << n << ") but FarNear doesn't know how."
00645         << " Systematic will essentially be ignored" << endl;
00646     }
00647   }
00648 
00649   if(fDoSystematicInterpolation) InitializeInterpolator(oscPars);
00650 
00651   /*
00652   // We definitely aren't smart enough to do more than one beam at a time
00653   assert(beamsToUse.size() == 1);
00654   const NCBeam::Info beamInfo = beamsToUse[0];
00655   */
00656 
00657   // This is a hack to make FarNear ~ work with interpolator. Since we ignore
00658   // beamsToUse and just do RunAll, then we should only send spectra back for
00659   // one run - arbitrarily RunI.
00660   if(fDoSystematicInterpolation &&
00661      beamsToUse[0].GetRunType() != NC::RunUtil::kRunI) return;
00662 
00663   NCBeam::Info beamInfo = NCBeam::Info(BeamType::kL010z185i,
00664                                        NC::RunUtil::kRunAll);
00665   vector<NCType::EFitParam> adj; vector<double> shift;
00666   beamsToUse[0].GetSystShifts(adj, shift);
00667   beamInfo.SetSystShifts(adj, shift);
00668 
00669   // Need a mutable copy
00670   NC::SystPars systPars = systPars_org;
00671 
00672   NCBeam* beam_fd = GetBeam(Detector::kFar, beamInfo);
00673   NCBeam* beam_nd = GetBeam(Detector::kNear, beamInfo);
00674 
00675   assert(beam_fd);
00676   assert(beam_nd);
00677 
00678 
00679   // These checks don't really belong here, but the fitter code is too stupid
00680   // to understand one-sided limits (and indeed limits that are different to
00681   // the one-sigma ranges) Until it's fixed just do it here.
00682 
00683   // TODO - these limits should go somewhere
00684   /*
00685   if(fCoordConv.IsFit(NCType::kNormalization)){
00686     double& norm = coords[fCoordConv.FitterIndex(NCType::kNormalization)];
00687     if(norm < -1){
00688       chisqr += 1e3*(norm+1)*(norm+1);
00689       norm = -1;
00690     }
00691   }
00692   if(fCoordConv.IsFit(NCType::kRelativeHadronicCalibration)){
00693     double& relhadr = coords[fCoordConv.FitterIndex(NCType::kRelativeHadronicCalibration)];
00694     if(relhadr < -1){
00695       chisqr += 1e3*(relhadr+1)*(relhadr+1);
00696       relhadr = -1;
00697     }
00698   }
00699   if(fCoordConv.IsFit(NCType::kAbsoluteHadronicCalibration)){
00700     double& abshadr = coords[fCoordConv.FitterIndex(NCType::kAbsoluteHadronicCalibration)];
00701     if(abshadr < -1){
00702       chisqr += 1e3*(abshadr+1)*(abshadr+1);
00703       abshadr = -1;
00704     }
00705   }
00706   */
00707 
00708   // TODO - THIS UNITARITY STUFF SERIOUSLY NEEDS TO BE DONE A LOT BETTER
00709   /*
00710   // 4 Flavour models unitarity constraints:
00711   //     |U_{mu1}|^{2} + |U_{mu2}|^{2} + |U_{mu3}|^{2}  + |U_{mu4}|^{2} > 1.0
00712   //  or |U_{e3}|^{2}  + |U_{mu3}|^{2} + |U_{tau3}|^{2} + |U_{s3}|^{2}  > 1.0
00713 
00714   // SterileFraction unitarity constraint:
00715   //     |U_mu3|^2 + f_s*(1-|U_mu3|^2) + |U_e3|^2 < 1
00716 
00717   if(fOscillationModel == NCType::kSterileFraction){
00718     const double umu3 = coords.at(fCoordConv.FitterIndex(NCType::kUMu3Sqr));
00719     const double ue3 = fUE3Sqr;
00720     const double fs = coords.at(fCoordConv.FitterIndex(NCType::kUS3Sqr));
00721 
00722     if(umu3+fs*(1-umu3)+ue3 > 1.001){
00723       if(!fSoftPenalty){
00724         MSG("NCExtrapolationFarNear", Msg::kVerbose) << "Unitarity violation - returning 1e6 fs=" << fs << " umu3=" << umu3 << " ue3=" << ue3 << endl;
00725         return 1.e6;
00726       }
00727       else{
00728         if(fs >= 1) return 1e6; // I don't think this can happen, but don't want to divide by zero if it does
00729         const double muproj = (1-ue3-fs)/(1-fs);
00730         const double dist = umu3-muproj;
00731 
00732         coords[NCType::kUMu3Sqr] = muproj;
00733 
00734         chisqr += dist*dist*1e3;
00735 
00736         MSG("NCExtrapolationFarNear", Msg::kVerbose) << "Unitarity violation - penalizing " << chisqr << " fs=" << fs << " umu3=" << umu3 << " ue3=" << ue3 << endl;
00737       }
00738     }
00739   }
00740   else if(fOscillationModel == NCType::k4Flavor ||
00741           fOscillationModel == NCType::k4FlavorDelta43Is0 ||
00742           fOscillationModel == NCType::k4FlavorDelta41Is0 ||
00743           fOscillationModel == NCType::kSterileFraction){
00744     double umu3 = coords.at(fCoordConv.FitterIndex(NCType::kUMu3Sqr));
00745 //     if(fCoordConv.fLocUMu4Sqr > 0) umu3 += coords.at(fCoordConv.fLocUMu4Sqr);
00746     double us3 = coords.at(fCoordConv.FitterIndex(NCType::kUS3Sqr));
00747     double ue3 = fUE3Sqr;
00748     if(fOscillationModel == NCType::k4FlavorDelta41Is0
00749        && (us3 + umu3 + ue3) > 1.001){
00750       if(!fSoftPenalty){
00751         MSG("NCExtrapolationFarNear", Msg::kVerbose) << "Unitarity violation - returning 1e6 us3=" << us3 << " umu3=" << umu3 << " ue3=" << ue3 << endl;
00752         return 1.e6;
00753       }
00754 
00755       const double root2 = sqrt(2.0);
00756       const double dist = (us3+umu3+fUE3Sqr-1)/root2;
00757       const double sproj = us3-dist/root2;
00758       const double muproj = umu3-dist/root2;
00759 
00760       coords[NCType::kUMu3Sqr] = muproj;
00761       coords[NCType::kUS3Sqr] = sproj;
00762 
00763       chisqr = dist*dist*1e3;
00764 
00765       MSG("NCExtrapolationFarNear", Msg::kVerbose) << "Unitarity violation - penalizing " << chisqr << " us3=" << us3 << " umu3=" << umu3 << " ue3=" << ue3 << endl;
00766     }
00767   }//end checks of unitarity
00768   */
00769 
00770   // If none of the systematic shifts have changed since last time
00771   // we were called then there's no need to redo all the
00772   // FillDataMCHistograms() calls. The actual oscillation happens
00773   // in ConstructFarSpectrum()
00774 
00775   // TODO - there is no reason to refill the data histograms when
00776   // systematics change.
00777 
00778   vector<TH1*> nd_ratios, fd_ratios;
00779 
00780   if(fInterpolator){
00781     const vector<double> shift = fCoordConv.VectorFromSystPars(systPars);
00782 
00783     vector<TH1*> interp = fInterpolator->GetInterpolatedSpectra(shift);
00784 
00785     assert(interp.size()%2 == 0); // Every FD has a corresponding ND
00786     // The ND ratios are the odd elements of the vector. Copy them out.
00787     for(unsigned int n = 1; n < interp.size(); n += 2)
00788       nd_ratios.push_back(interp[n]);
00789     // The FD ratios are the even elements of the vector. Copy them out.
00790     for(unsigned int n = 0; n < interp.size(); n += 2)
00791       fd_ratios.push_back(interp[n]);
00792 
00793     systPars = NC::SystPars(); // Turn off all the systematic shifts
00794   }
00795 
00796 
00797 
00798 
00799 
00800   static NC::SystPars oldsyst;
00801   static NCBeam::Info oldinfo;
00802   static bool firstTime = true;
00803 
00804   if(systPars != oldsyst || !(beamsToUse[0] == oldinfo) ||  firstTime){
00805     oldsyst = systPars;
00806     oldinfo = beamsToUse[0];
00807     firstTime = false;
00808 
00809     fFD_fit.at(kNCSig)->Reset("ICE"); //integral contents error
00810     fFD_fit.at(kCCSig)->Reset("ICE");
00811 
00812     if(fUseNC) FillDataMCHistogramsNear(beam_nd, NCType::kNC, systPars);
00813     if(fUseCC) FillDataMCHistogramsNear(beam_nd, NCType::kCC, systPars);
00814 
00815     fFD_data[kNCSig]->Reset("ICE");
00816     fFD_data[kCCSig]->Reset("ICE");
00817 
00818     if(fUseNC) FillDataMCHistogramsFar(beam_fd, NCType::kNC, systPars);
00819     if(fUseCC) FillDataMCHistogramsFar(beam_fd, NCType::kCC, systPars);
00820   }
00821 
00822   ConstructFarSpectrum(oscPars);
00823 
00824   if(fUseNC){
00825     expvec.push_back(fFD_fit[kNCSig]);
00826     obsvec.push_back(fFD_data[kNCSig]);
00827   }
00828 
00829   if(fUseCC){
00830     expvec.push_back(fFD_fit[kCCSig]);
00831     obsvec.push_back(fFD_data[kCCSig]);
00832   }
00833 
00834   if(!fd_ratios.empty()){
00835     assert(nd_ratios.size() == expvec.size());
00836     assert(fd_ratios.size() == expvec.size());
00837     for(unsigned int n = 0; n < expvec.size(); ++n){
00838       // The ND systematic shifts end up on the bottom of the F/N ratio
00839       // and hence we can just divide by them at the FD.
00840       if(fDoExtrapolation) expvec[n]->Divide(nd_ratios[n]);
00841       expvec[n]->Multiply(fd_ratios[n]);
00842     }
00843   }
00844 
00845   ++fNCalls;
00846 }
00847 //----------------------------------------------------------------------
00848 
00849 
00850 //----------------------------------------------------------------------
00851 void NCExtrapolationFarNear::CleanupSpectra(vector<TH1*> /*exps*/,
00852                                             vector<TH1*> /*obss*/)
00853 {
00854   // No need to clear anything. We don't allocate anything new each time
00855 }
00856 //----------------------------------------------------------------------
00857 
00858 
00859 //----------------------------------------------------------------------
00860 void NCExtrapolationFarNear::
00861 WriteResources(const NC::OscProb::OscPars* trueOscPars)
00862 {
00863   MSG("NCExtrapolationFarNear", Msg::kInfo) << "nCalls: " << fNCalls << endl;
00864 
00865   NCBeam* beam = GetBeam(Detector::kFar,
00866                          NCBeam::Info(BeamType::kL010z185i,
00867                                       NC::RunUtil::kRunAll));
00868   NCBeam* beam_nd = GetBeam(Detector::kNear,
00869                             NCBeam::Info(BeamType::kL010z185i,
00870                                          NC::RunUtil::kRunAll));
00871 
00872 
00873   NC::SystPars systPars = GetBestFitSysts();
00874   const NC::OscProb::OscPars* oscPars = GetBestFitOscPars();
00875 
00876   if(fUseNC) FillDataMCHistogramsNear(beam_nd, NCType::kNC, systPars);
00877   if(fUseCC) FillDataMCHistogramsNear(beam_nd, NCType::kCC, systPars);
00878 
00879   fFD_data[kNCSig]->Reset("ICE");
00880   fFD_data[kCCSig]->Reset("ICE");
00881 
00882   if(fUseNC) FillDataMCHistogramsFar(beam, NCType::kNC, systPars);
00883   if(fUseCC) FillDataMCHistogramsFar(beam, NCType::kCC, systPars);
00884 
00885   //resets the histograms - integral contents error
00886   fFD_fit.at(kNCSig)->Reset("ICE");
00887   fFD_fit.at(kCCSig)->Reset("ICE");
00888 
00889   if(oscPars) ConstructFarSpectrum(oscPars);
00890 
00891   delete oscPars;
00892 
00893   // We need the near detector spectrum to be set up so we can extrapolate it
00894   NCExtrapolation::FillResultHistograms(beam_nd);
00895 
00896   // these calls fill the NCBeam histograms using our calculation, which
00897   // allows for Far/Near ratio to be used. NB that 'beam' is only kRunAll
00898   // which means that the RunI plots in NCBeam come out without extrapolation.
00899   if(fUseNC) FillResultHistograms(beam, NCType::kNC, fNominal, fOsc);
00900   if(fUseCC) FillResultHistograms(beam, NCType::kCC, fNominal, fOsc);
00901 
00902   // Now that the beams should be ready, call up to NCExtrapolation
00903 
00904   NCExtrapolation::WriteResources(trueOscPars);
00905 
00906   // get a pointer to the current directory
00907   // this is one of the output files
00908 
00909   TDirectory* saveDir = gDirectory;
00910 
00911   for(unsigned int i = 0; i < fFD_fit.size();  ++i)  fFD_fit[i]->Write();
00912   for(unsigned int i = 0; i < fFN.size();      ++i)      fFN[i]->Write();
00913   for(unsigned int i = 0; i < fND_data.size(); ++i) fND_data[i]->Write();
00914   for(unsigned int i = 0; i < fND_MC.size();   ++i)   fND_MC[i]->Write();
00915   for(unsigned int i = 0; i < fNom_true_vs_reco.size();++i)
00916     fNom_true_vs_reco[i]->Write();
00917 
00918   saveDir->cd();
00919 }
00920 //----------------------------------------------------------------------
00921 
00922 
00923 //----------------------------------------------------------------------
00924 void NCExtrapolationFarNear::
00925 FillResultHistograms(NCBeam* beam,
00926                      NCType::EEventType nccc,
00927                      vector<vector<double> >& nominal,
00928                      vector<vector<double> >& osc)
00929 {
00930   int sig     = kNCSig;
00931   int bkg     = kNCBkg;
00932   int tau     = kNCTau;
00933   int beamnue = kNCBeamNue;
00934   int oscnue  = kNCOscNue;
00935 
00936   if(nccc == NCType::kCC){
00937     sig     = kCCSig;
00938     bkg     = kCCBkg;
00939     tau     = kCCTau;
00940     beamnue = kCCBeamNue;
00941     oscnue  = kCCOscNue;
00942   }
00943 
00944   for(int i = 0; i < kNumEnergyBinsFar; ++i){
00945 
00946     double totalNDMC = fND_MC.at(sig)->GetBinContent(i+1)
00947       + fND_MC.at(bkg)->GetBinContent(i+1)      // numu
00948       + fND_MC.at(tau)->GetBinContent(i+1)      // nutau
00949       + fND_MC.at(beamnue)->GetBinContent(i+1); // nue
00950 
00951     double ndRatio = totalNDMC ? fND_data.at(sig)->GetBinContent(i+1)/totalNDMC : 0;
00952     double eBeamVal = nominal[beamnue][i];
00953     double nooscVal = nominal[sig][i] + nominal[bkg][i] + eBeamVal;
00954     double fitVal   = fFD_fit[sig]->GetBinContent(i+1);
00955     double bkgVal   = osc[bkg][i];
00956     double tauVal   = osc[tau][i];
00957     double eOscVal  = osc[oscnue][i];
00958 
00959     beam->GetMCHistogram(nccc)->SetBinContent(i+1, nooscVal*ndRatio);
00960     beam->GetMCFitHistogram(nccc)->SetBinContent(i+1, fitVal);//already had ndRatio
00961     beam->GetMCBackgroundHistogram(nccc)->SetBinContent(i+1, bkgVal*ndRatio);
00962     beam->GetMCFitNuMuToNuTauHistogram(nccc)->SetBinContent(i+1, tauVal*ndRatio);
00963     beam->GetMCFitNuEToNuEHistogram(nccc)->SetBinContent(i+1, eBeamVal*ndRatio);
00964     beam->GetMCFitNuMuToNuEHistogram(nccc)->SetBinContent(i+1, eOscVal*ndRatio);
00965   }
00966 
00967   // We filled the histograms manually, and don't need NCBeam's automatic stuff
00968   // to happen. So inform it of that fact.
00969   beam->MarkHistogramsFilled();
00970 }
00971 //----------------------------------------------------------------------
00972 
00973 
00974 //----------------------------------------------------------------------
00975 bool NCExtrapolationFarNear::EnableNearToFarExtrapolation(bool enable)
00976 {
00977   const bool ret = fDoExtrapolation;
00978   fDoExtrapolation = enable;
00979   return ret;
00980 }
00981 //----------------------------------------------------------------------
00982 
00983 
00984 //----------------------------------------------------------------------
00985 // This interface is most convenient for internal use
00986 void NCExtrapolationFarNear::GetNearMCSpectra(NCBeam* beam, NC::SystPars systs,
00987                                               TH1** nc, TH1** cc)
00988 {
00989   if(nc){
00990     FillDataMCHistogramsNear(beam, NCType::kNC, systs);
00991 
00992     *nc = new TH1D("", "", kNumEnergyBinsFar, kEnergyBinsFar);
00993 
00994     for(int i = 1; i <= kNumEnergyBinsFar; ++i){
00995       const double totalMCNC_nd = fND_MC.at(kNCSig)->GetBinContent(i)
00996         + fND_MC.at(kNCBkg)->GetBinContent(i)      // numu
00997         + fND_MC.at(kNCTau)->GetBinContent(i)      // nutau
00998         + fND_MC.at(kNCBeamNue)->GetBinContent(i)  // beamnue
00999         + fND_MC.at(kNCOscNue)->GetBinContent(i);  // oscnue
01000 
01001       (*nc)->SetBinContent(i, totalMCNC_nd);
01002     } // end for i
01003   }
01004   if(cc){
01005     FillDataMCHistogramsNear(beam, NCType::kCC, systs);
01006 
01007     *cc = new TH1D("", "", kNumEnergyBinsFar, kEnergyBinsFar);
01008 
01009     for(int i = 1; i <= kNumEnergyBinsFar; ++i){
01010       const double totalMCCC_nd = fND_MC.at(kCCSig)->GetBinContent(i)
01011         + fND_MC.at(kCCBkg)->GetBinContent(i)      // numu
01012         + fND_MC.at(kCCTau)->GetBinContent(i)      // nutau
01013         + fND_MC.at(kCCBeamNue)->GetBinContent(i)  // beamnue
01014         + fND_MC.at(kCCOscNue)->GetBinContent(i);  // oscnue
01015 
01016       (*cc)->SetBinContent(i, totalMCCC_nd);
01017     } // end for i
01018   }
01019 }
01020 //----------------------------------------------------------------------
01021 
01022 
01023 //----------------------------------------------------------------------
01024 // This is the interface we need to implement to keep the interpolator happy
01025 vector<const TH1*> NCExtrapolationFarNear::
01026 GetNearMCSpectra(vector<NCBeam::Info> beamsToUse)
01027 {
01028   // We're too stupid to handle anything else
01029   //  assert(beamsToUse.size() == 1);
01030 
01031   vector<const TH1*> ret;
01032 
01033   // This is a hack to make FarNear ~ work with interpolator. Since we ignore
01034   // beamsToUse and just do RunAll, then we should only send spectra back for
01035   // one run - arbitrarily RunI.
01036   if(fDoSystematicInterpolation &&
01037      beamsToUse[0].GetRunType() != NC::RunUtil::kRunI) return ret;
01038 
01039   NCBeam* beam = GetBeam(Detector::kNear, beamsToUse[0]);
01040   assert(beam);
01041 
01042   NC::SystPars systs; // no systematic shifts to be applied
01043 
01044   TH1 *nc, *cc;
01045   GetNearMCSpectra(beam, systs, fUseNC ? &nc : 0, fUseCC ? &cc : 0);
01046 
01047   if(fUseNC) ret.push_back(nc);
01048   if(fUseCC) ret.push_back(cc);
01049   return ret;
01050 }
01051 //----------------------------------------------------------------------

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