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

NCExtrapolationBeamMatrix.cxx

Go to the documentation of this file.
00001 
00002 //
00003 // NCExtrapolationBeamMatrix.cxx
00004 //
00005 //
00006 // R. Pittam 10/2008
00007 //
00008 // $Id: NCExtrapolationBeamMatrix.cxx,v 1.7 2009/12/10 17:07:06 gmieg Exp $
00010 
00011 #include "NCUtils/Extrapolation/NCExtrapolationBeamMatrix.h"
00012 #include "NCUtils/Extrapolation/NCEnergyBin.h"
00013 #include "NCUtils/Extrapolation/NCPOTCounter.h"
00014 #include "NCUtils/NCUtility.h"
00015 
00016 #include "MessageService/MsgService.h"
00017 
00018 #include "AnalysisNtuples/ANtpAnalysisInfo.h"
00019 #include "AnalysisNtuples/ANtpBeamInfo.h"
00020 #include "AnalysisNtuples/ANtpRecoInfo.h"
00021 #include "AnalysisNtuples/ANtpHeaderInfo.h"
00022 #include "AnalysisNtuples/ANtpTruthInfoBeam.h"
00023 
00024 #include "TCanvas.h"
00025 #include "TDirectory.h"
00026 #include "TGraphErrors.h"
00027 #include "TMath.h"
00028 #include "TMinuit.h"
00029 
00030 #include <fstream>
00031 #include <cassert>
00032 #include <cmath>
00033 
00034 CVSID("$Id: NCExtrapolationBeamMatrix.cxx,v 1.7 2009/12/10 17:07:06 gmieg Exp $");
00035 
00036 #include "NCExtrapolationModule.h"
00037 #include "NCSpectrumInterpolator.h"
00038 
00039 REGISTER_NCEXTRAPOLATION(NCExtrapolationBeamMatrix, BeamMatrix)
00040 
00041 NCExtrapolationBeamMatrix* NCExtrapolationBeamMatrix::bmFit = NULL;
00042 
00043 using namespace NC::Utility;
00044 
00045 const int kNumTrueEnergyBins = 1000;
00046 
00047 enum EBeamMatrixEventType{
00048   kNCSig     = 0, //NC spectrum
00049   kCCSig     = 1, //CC spectrum
00050   kNCBkg     = 2, //NC background in NC spectrum
00051   kCCBkg     = 3, //CC background in CC spectrum
00052   kNCTau     = 4, //NC tau background in NC spectrum
00053   kCCTau     = 5, //CC tau background in CC spectrum
00054   kNCBeamNue = 6, //NC nue background in NC spectrum
00055   kCCBeamNue = 7, //CC nue background in CC spectrum
00056   kNCOscNue  = 8, //NC oscillated nue background in NC spectrum
00057   kCCOscNue  = 9, //CC oscillated nue background in CC spectrum
00058   kNCWrongSignBkg  = 10, //NC wrong sign background in NC spectrum
00059   kCCWrongSignBkg  = 11 //CC wrong sign background in CC spectrum
00060 };
00061 
00062 enum EBeamMatrixHistoType{
00063   kNCRecoEnergy_ND  = 0, // NC Histogram for Reco Spectrum in the ND
00064   kCCRecoEnergy_ND  = 1, // CC Histogram for Reco Spectrum in the ND
00065   kNCRecoBkg_ND  = 2, // NC Background in Reco Energy in the ND
00066   kCCRecoBkg_ND  = 3, // CC Background in Reco Energy in the ND
00067   kNCPurity_ND  = 4, // NC Histogram for Purity correction in the ND
00068   kCCPurity_ND  = 5, // CC Histogram for Purity correction in the ND
00069   kNCRecoEnergyPurCorr_ND  = 6, // NC Histogram for Purity corrected Reco Spectrum in the ND
00070   kCCRecoEnergyPurCorr_ND  = 7, // CC Histogram for Purity corrected Reco Spectrum in the ND
00071   kNCTrueEnergyPurCorr_ND  = 8, // NC Histogram for Purity corrected True Spectrum in the ND
00072   kCCTrueEnergyPurCorr_ND  = 9, // CC Histogram for Purity corrected True Spectrum in the ND
00073   kNCTrueSelEfficiency_ND  = 10, // NC Histogram for Selection Efficency correction in the ND (done in true energy)
00074   kCCTrueSelEfficiency_ND  = 11, // CC Histogram for Selection Efficency correction in the ND (done in true energy)
00075   kNCTrueEnergySelEffCorr_ND  = 12, // NC Histogram for Purity and Selection Efficiency corrected True Spectrum in the ND
00076   kCCTrueEnergySelEffCorr_ND  = 13, // CC Histogram for Purity and Selection Efficiency corrected True Spectrum in the ND
00077   kNCTrueRecoEfficiency_ND  = 14, // NC Histogram for Reconstruction Efficiency correction in the ND (done in true energy)
00078   kCCTrueRecoEfficiency_ND  = 15, // CC Histogram for Reconstruction Efficency correction in the ND (done in true energy)
00079   kNCTrueEnergyEffCorr_ND  = 16, // NC Histogram for Purity, Selection & Reconstruction Efficiency correction in the ND (done in true energy)
00080   kCCTrueEnergyEffCorr_ND  = 17, // CC Histogram for Purity, Selection & Reconstruction Efficiency correction in the ND (done in true energy)
00081   kNCTrueEnergy_ND  = 18, // NC Histogram for the ACTUAL (From MC) Purity and Efficiency corrected True Spectrum in the ND needed to make efficiency histogram
00082   kCCTrueEnergy_ND  = 19, // CC Histogram for the ACTUAL (From MC) Purity and Efficiency corrected True Spectrum in the ND needed to make efficiency histogram
00083   kNCTrueEnergyBkg_ND  = 20, // NC Histogram for the Background from MC   
00084   kCCTrueEnergyBkg_ND  = 21, // CC Histogram for the Background from MC
00085   kNCTrueEnergyFlux_ND  = 22, // NC Histogram for the ND Neutrino Flux after pot mass and x-section corrections
00086   kCCTrueEnergyFlux_ND  = 23, // CC Histogram for the ND Neutrino Flux after pot mass and x-section corrections
00087   kNCTrueEnergyMatrix_FD  = 24, // NC Histogram for the FD prediction after the Beam Matrix
00088   kCCTrueEnergyMatrix_FD  = 25, // CC Histogram for the FD prediction aftet the Beam Matrix
00089   kNCTrueEnergyFlux_FD  = 26, // NC Histogram for the FD Neutrino Flux after pot mass and x-section corrections
00090   kCCTrueEnergyFlux_FD  = 27, // CC Histogram for the FD Neutrino Flux after pot mass and x-section corrections
00091   kNCTrueSelEfficiency_FD  = 28, // NC Histogram for Selection Efficency correction in the ND (done in true energy)
00092   kCCTrueSelEfficiency_FD  = 29, // CC Histogram for Selection Efficency correction in the ND (done in true energy)
00093   kNCTrueEnergySelEffCorr_FD  = 30, // NC Histogram for Purity and Selection Efficiency corrected True Spectrum in the ND
00094   kCCTrueEnergySelEffCorr_FD  = 31, // CC Histogram for Purity and Selection Efficiency corrected True Spectrum in the ND
00095   kNCTrueRecoEfficiency_FD  = 32, // NC Histogram for Reconstruction Efficiency correction in the ND (done in true energy)
00096   kCCTrueRecoEfficiency_FD  = 33, // CC Histogram for Reconstruction Efficiency correction in the ND (done in true energy)
00097   kNCTrueEnergyEffCorr_FD  = 34, // NC Histogram for Purity and Efficiency corrected True Spectrum in the ND
00098   kCCTrueEnergyEffCorr_FD  = 35, // CC Histogram for Purity and Efficiency corrected True Spectrum in the ND
00099   kNCTrueEnergy_FD  = 36, // NC Histogram for the ACTUAL Purity and Efficiency corrected True Spectrum in the FD used as nominal MC
00100   kCCTrueEnergy_FD  = 37, // CC Histogram for the ACTUAL Purity and Efficiency corrected True Spectrum in the FD used as nominal MC
00101   kNCTrueEnergyXsecFit_FD  = 38, // NC Histogram for the ACTUAL Purity and Efficiency corrected True Spectrum in the FD needed normalise FD TrueToReco
00102   kCCTrueEnergyXsecFit_FD  = 39, // CC Histogram for the ACTUAL Purity and Efficiency corrected True Spectrum in the FD needed normalise FD TrueToReco
00103   kNCTrueEnergyBkg_FD  = 40, // NC Histogram for the Background to make above 2 histograms needed to make efficiency histogram 
00104   kCCTrueEnergyBkg_FD  = 41, // CC Histogram for the Background to make above 2 histograms needed to make efficiency histogram
00105   kNCRecoEnergy_FD = 42, // NC Histogram for Reco Spectrum in the FD
00106   kCCRecoEnergy_FD = 43, // CC Histogram for Reco Spectrum in the FD
00107   kNCRecoEnergyPurCorr_FD  = 44, // NC Histogram for Purity corrected Reco Spectrum in the FD
00108   kCCRecoEnergyPurCorr_FD  = 45, // CC Histogram for Purity corrected Reco Spectrum in the FD
00109   kNCPurity_FD  = 46, // NC Histogram for Purity correction in the FD
00110   kCCPurity_FD  = 47, // CC Histogram for Purity correction in the FD
00111   kNCRecoBkg_FD  = 48, // NC Histogram for background in reco energy
00112   kCCRecoBkg_FD  = 49, // CC Histogram for background in reco energy
00113   kNCRecoEnergyPred_FD = 50, // NC BM prediction in the FD
00114   kCCRecoEnergyPred_FD = 51, // CC BM prediction in the FD
00115   kNCRecoEnergyBeamNueBkg_FD = 52, // CC Histogram for Reco Spectrum in the FD
00116   kCCRecoEnergyBeamNueBkg_FD = 53, // CC Histogram for Reco Spectrum in the FD
00117   kNCRecoEnergyBeamNueBkg_ND = 54, // CC Histogram for Reco Spectrum in the ND
00118   kCCRecoEnergyBeamNueBkg_ND = 55, // CC Histogram for Reco Spectrum in the ND
00119   kNCRecoEnergyTau_ND = 56, // CC Histogram for Reco Spectrum in the ND
00120   kCCRecoEnergyTau_ND = 57, // CC Histogram for Reco Spectrum in the ND
00121   kNCRecoEnergyOscNue_ND = 58, // CC Histogram for Reco Spectrum in the ND
00122   kCCRecoEnergyOscNue_ND = 59, // CC Histogram for Reco Spectrum in the ND
00123   kNCSelRecoEnergy_ND  = 60, // NC Histogram for Reco Spectrum in the ND
00124   kCCSelRecoEnergy_ND  = 61, // CC Histogram for Reco Spectrum in the ND
00125   kNCSelRecoEnergy_FD  = 62, // NC Histogram for Reco Spectrum in the FD
00126   kCCSelRecoEnergy_FD  = 63 // CC Histogram for Reco Spectrum in the FD
00127 };
00128 
00129 enum EBeamMatrixDataHistoType{
00130   kNCDataRecoEnergy_ND  = 0, //NC Histogram for Reco Spectrum in the ND
00131   kCCDataRecoEnergy_ND  = 1, //CC Histogram for Reco Spectrum in the ND
00132   kNCDataRecoEnergyPurCorr_ND  = 2, //NC Histogram for Purity corrected Reco Spectrum in the ND
00133   kCCDataRecoEnergyPurCorr_ND  = 3, //CC Histogram for Purity corrected Reco Spectrum in the ND
00134   kNCDataTrueEnergyPurCorr_ND  = 4, //NC Histogram for Purity corrected True Spectrum in the ND
00135   kCCDataTrueEnergyPurCorr_ND  = 5, //CC Histogram for Purity corrected True Spectrum in the ND
00136   kNCDataTrueEnergySelEffCorr_ND  = 6, //NC Histogram for Purity and  selection Efficiency corrected True Spectrum in the ND
00137   kCCDataTrueEnergySelEffCorr_ND  = 7, //CC Histogram for Purity and selection Efficiency corrected True Spectrum in the ND
00138   kNCDataTrueEnergyEffCorr_ND  = 8, //NC Histogram for Purity and selection Efficiency corrected True Spectrum in the ND
00139   kCCDataTrueEnergyEffCorr_ND  = 9, //CC Histogram for Purity and selection Efficiency corrected True Spectrum in the ND
00140   kNCDataTrueEnergyFlux_ND  = 10, // NC Histogram for the ND Flux after pot mass and x-section corrections
00141   kCCDataTrueEnergyFlux_ND  = 11, // CC Histogram for the ND Flux after pot mass and x-section corrections
00142   kNCDataTrueEnergyMatrix_FD  = 12, // NC Histogram for the FD prediction after the Beam Matrix
00143   kCCDataTrueEnergyMatrix_FD  = 13, // CC Histogram for the FD prediction aftet the Beam Matrix
00144   kNCDataTrueEnergyFlux_FD  = 14, // NC Histogram for the FD Flux after pot mass and x-section corrections
00145   kCCDataTrueEnergyFlux_FD  = 15, // CC Histogram for the FD Flux aftet pot mass and x-section corrections
00146   kNCDataTrueEnergySelEffCorr_FD  = 16, //NC Histogram for Purity and selection Efficiency corrected True Spectrum in the ND
00147   kCCDataTrueEnergySelEffCorr_FD  = 17, //CC Histogram for Purity and selection Efficiency corrected True Spectrum in the ND
00148   kNCDataTrueEnergyEffCorr_FD  = 18, //NC Histogram for Purity and selection and reconstruction Efficiency corrected True Spectrum in the ND
00149   kCCDataTrueEnergyEffCorr_FD  = 19, //CC Histogram for Purity and selection and reconstruction Efficiency corrected True Spectrum in the ND
00150   kNCDataRecoEnergyPurCorr_FD = 20, // NC Histogram for Purity corrected Reco Spectrum in the FD
00151   kCCDataRecoEnergyPurCorr_FD = 21, //CC Histogram for Purity corrected Reco Spectrum in the FD
00152   kNCDataRecoEnergyPred_FD = 22,  // NC BM prediction in the FD
00153   kCCDataRecoEnergyPred_FD = 23, // CC BM prediction in the FD
00154   kNCDataRecoEnergySig_FD = 24, // NC BM predicted signal only part all the others can be got from the canvases
00155   kCCDataRecoEnergySig_FD = 25, // CC BM predicted signal only part all the others can be got from the canvases
00156   kNCDataRecoEnergyWrongSignBkg_FD = 26, // NC BM predicted wrong sign bkg all the others can be got from the canvases
00157   kCCDataRecoEnergyWrongSignBkg_FD = 27 // CC BM predicted wrong sign bkg all the others can be got from the canvases
00158 };
00159 
00160 enum EBeamMatrixTruthHistoType{
00161   kNCRecoTrueSig_ND = 0, // NC Reco to true matrix flavour corrected in the ND
00162   kCCRecoTrueSig_ND = 1, // CC Reco to true matrix flavour corrected in the ND
00163   kNCRecoTrueBkg_ND = 2, // NC Reco to true matrix flavour corrected wrong type in the ND
00164   kCCRecoTrueBkg_ND = 3, // CC Reco to true matrix flavour corrected wrong type in the ND
00165   kNCRecoTrueNorm_ND = 4, // NC Reco to true matrix Normalised in the ND
00166   kCCRecoTrueNorm_ND = 5, // CC Reco to true matrix Normalised in the ND
00167 
00168   kNCTrueRecoSig_FD = 6, // NC Reco to true matrix flavour corrected in the FD
00169   kCCTrueRecoSig_FD = 7, // CC Reco to true matrix flavour corrected in the FD
00170   kNCTrueRecoBkg_FD = 8, // NC Reco to true matrix flavour corrected wrong type in the FD
00171   kCCTrueRecoBkg_FD = 9, // CC Reco to true matrix flavour corrected wrong type in the FD
00172   kNCTrueRecoNorm_FD = 10, // NC Reco to true matrix flavour corrected in the FD
00173   kCCTrueRecoNorm_FD = 11 // CC Reco to true matrix flavour corrected in the FD
00174 };
00175 
00176 enum EBeamMatrixFitXsecType{
00177   kNCDataLE = 0, 
00178   kNCMCLE = 1, 
00179   kNCDataME = 2, 
00180   kNCMCME = 3, 
00181   kNCDataHE = 4, 
00182   kNCMCHE = 5, 
00183   kCCDataLE = 6, 
00184   kCCMCLE = 7, 
00185   kCCDataME = 8, 
00186   kCCMCME = 9, 
00187   kCCDataHE = 10, 
00188   kCCMCHE = 11 
00189 };
00190 
00191 int bmeqold = -1 ;
00192 
00193 //......................................................................
00194 NCExtrapolationBeamMatrix::NCExtrapolationBeamMatrix()
00195 {
00196   fNCalls = 0;
00197   fDoExtrapolation = true;
00198   
00199   int numBins = kNumEnergyBinsFar;
00200   double bins[kNumEnergyBinsFar+1];
00201   
00202   
00203   //use NCType to fill array of bins as it has the right binning already
00204   for( int i = 0; i < numBins+1; ++i ){
00205     bins[i] = kEnergyBinsFar[i];
00206   }
00207   
00208   // Create a true energy binning scheme for the
00209   // FD prediction to oscillate
00210   
00211   //1000
00212   for( int i = 0; i < 200; ++i )
00213     true_bins.push_back(i*0.01);
00214   for( int i = 80; i < 801; ++i )
00215     true_bins.push_back(i*0.025);
00216   for( int i = 41; i < 81; ++i )
00217     true_bins.push_back(i*0.5);
00218   for( int i = 42; i < 120; i+=2 )
00219     true_bins.push_back(i);
00220   true_bins.push_back(120) ;
00221   
00222   
00223   // needed for ND fitting
00224   std::vector< TH1D* > NDByEnergyForXsecLE; 
00225   NDByEnergyForXsecLE.push_back(new TH1D(" NC0to4LE" , " NC0to4LE" , numBins, bins) );
00226   NDByEnergyForXsecLE.push_back(new TH1D(" NC5to8LE" , " NC5to8LE" , numBins, bins) );
00227   NDByEnergyForXsecLE.push_back(new TH1D(" NC8to15LE" , "NC8to15LE" , numBins, bins) );
00228   NDByEnergyForXsecLE.push_back(new TH1D(" NCover15LE" , "NCover15LE" , numBins, bins) );
00229   NDByEnergyForXsecLE.push_back(new TH1D(" NCnotMuLE" , "NCnotMuLE" , numBins, bins) );
00230 
00231   std::vector< TH1D* > NDByEnergyForXsecME; 
00232   NDByEnergyForXsecME.push_back(new TH1D(" NC0to4ME" , " NC0to4ME" , numBins, bins) );
00233   NDByEnergyForXsecME.push_back(new TH1D(" NC5to8ME" , " NC5to8ME" , numBins, bins) );
00234   NDByEnergyForXsecME.push_back(new TH1D(" NC8to15ME" , "NC8to15ME" , numBins, bins) );
00235   NDByEnergyForXsecME.push_back(new TH1D(" NCover15ME" , "NCover15ME" , numBins, bins) );
00236   NDByEnergyForXsecME.push_back(new TH1D(" NCnotMuME" , "NCnotMuME" , numBins, bins) );
00237   
00238   std::vector< TH1D* > NDByEnergyForXsecHE; 
00239   NDByEnergyForXsecHE.push_back(new TH1D(" NC0to4HE" , " NC0to4HE" , numBins, bins) );
00240   NDByEnergyForXsecHE.push_back(new TH1D(" NC5to8HE" , " NC5to8HE" , numBins, bins) );
00241   NDByEnergyForXsecHE.push_back(new TH1D(" NC8to15HE" , "NC8to15HE" , numBins, bins) );
00242   NDByEnergyForXsecHE.push_back(new TH1D(" NCover15HE" , "NCover15HE" , numBins, bins) );
00243   NDByEnergyForXsecHE.push_back(new TH1D(" NCnotMuHE" , "NCnotMuHE" , numBins, bins) );
00244   
00245   ND_XsecByParams.push_back(NDByEnergyForXsecLE);
00246   ND_XsecByParams.push_back(NDByEnergyForXsecME);
00247   ND_XsecByParams.push_back(NDByEnergyForXsecHE);
00248 
00249 
00250   ND_XSectionFitRew.push_back(new TH1D("NCDataLE" , "NCDataLE" , numBins, bins) );
00251   ND_XSectionFitRew.push_back(new TH1D("NCMCLE" , "NCMCLE" , numBins, bins) );
00252   ND_XSectionFitRew.push_back(new TH1D("NCDataME" , "NCDataME" , numBins, bins) );
00253   ND_XSectionFitRew.push_back(new TH1D("NCMCME" , "NCMCME" , numBins, bins) );
00254   ND_XSectionFitRew.push_back(new TH1D("NCDataHE" , "NCDataHE" , numBins, bins) );
00255   ND_XSectionFitRew.push_back(new TH1D("NCMCHE" , "NCMCHE" , numBins, bins) );
00256   ND_XSectionFitRew.push_back(new TH1D("CCDataLE" , "CCDataLE" , numBins, bins) );
00257   ND_XSectionFitRew.push_back(new TH1D("CCMCLE" , "CCMCLE" , numBins, bins) );
00258   ND_XSectionFitRew.push_back(new TH1D("CCDataME" , "CCDataME" , numBins, bins) );
00259   ND_XSectionFitRew.push_back(new TH1D("CCMCME" , "CCMCME" , numBins, bins) );
00260   ND_XSectionFitRew.push_back(new TH1D("CCDataHE" , "CCDataHE" , numBins, bins) );
00261   ND_XSectionFitRew.push_back(new TH1D("CCMCHE" , "CCMCHE" , numBins, bins) );
00262 
00263   ND_XSectionFit.push_back(new TH1D("NCDataLEOrig" , "NCDataLEOrig" , numBins, bins) );
00264   ND_XSectionFit.push_back(new TH1D("NCMCLEOrig" , "NCMCLEOrig" , numBins, bins) );
00265   ND_XSectionFit.push_back(new TH1D("NCDataMEOrig" , "NCDataMEOrig" , numBins, bins) );
00266   ND_XSectionFit.push_back(new TH1D("NCMCMEOrig" , "NCMCMEOrig" , numBins, bins) );
00267   ND_XSectionFit.push_back(new TH1D("NCDataHEOrig" , "NCDataHEOrig" , numBins, bins) );
00268   ND_XSectionFit.push_back(new TH1D("NCMCHEOrig" , "NCMCHEOrig" , numBins, bins) );
00269   ND_XSectionFit.push_back(new TH1D("CCDataLEOrig" , "CCDataLEOrig" , numBins, bins) );
00270   ND_XSectionFit.push_back(new TH1D("CCMCLEOrig" , "CCMCLEOrig" , numBins, bins) );
00271   ND_XSectionFit.push_back(new TH1D("CCDataMEOrig" , "CCDataMEOrig" , numBins, bins) );
00272   ND_XSectionFit.push_back(new TH1D("CCMCMEOrig" , "CCMCMEOrig" , numBins, bins) );
00273   ND_XSectionFit.push_back(new TH1D("CCDataHEOrig" , "CCDataHEOrig" , numBins, bins) );
00274   ND_XSectionFit.push_back(new TH1D("CCMCHEOrig" , "CCMCHEOrig" , numBins, bins) );
00275 
00276 
00277   dataNDhistLE = new TH1D("dataNDhistLE","dataNDhistLE", numBins, bins);
00278   dataNDhistME = new TH1D("dataNDhistME","dataNDhistME", numBins, bins);
00279   dataNDhistHE = new TH1D("dataNDhistHE","dataNDhistHE", numBins, bins);
00280   
00281   //Efficency histograms read from file
00282   selEffNDHist =  new TH1D();
00283   selCCEffFDHist =  new TH1D();
00284   selNCEffFDHist =  new TH1D();
00285   recoEffNDHist = new TH1D();
00286   recoCCEffFDHist = new TH1D();
00287   recoNCEffFDHist = new TH1D();
00288   extractNCFromCCFlux = new TH1D();
00289   fBeamMatrix =   new TH2D();
00290   
00291   //temporary histograms needed for true to reco 
00292   t2rCCnd = new TH2D("t2rCCnd","t2rCCnd", numBins, bins, numBins, bins );
00293 
00294   t2rCC = new TH2D("t2rCC","t2rCC",kNumTrueEnergyBins, &true_bins.at(0) , numBins, bins );
00295   t2rNC = new TH2D("t2rNC","t2rNC",kNumTrueEnergyBins, &true_bins.at(0) , numBins, bins );
00296 
00297   t2rCCRebin = new TH2D("t2rCCRebin","t2rCCRebin",numBins, bins , numBins, bins );
00298   t2rNCRebin = new TH2D("t2rNCRebin","t2rNCRebin",numBins, bins , numBins, bins );
00299   
00300   fSmoothWidth = 0; // Don't do any smoothing
00301   
00302   //needed for x section fitting
00303   bmFit = this ;
00304 }
00305 //----------------------------------------------------------------------
00306 
00307 
00308 
00309 //......................................................................
00310 NCExtrapolationBeamMatrix::~NCExtrapolationBeamMatrix(){}
00311 
00312 
00313 const Registry& NCExtrapolationBeamMatrix::DefaultConfig()
00314 {
00315   static Registry r;
00316 
00317   r.UnLockValues();
00318 
00319   r.Set("FarNearSmoothingWidth", 0.00);
00320   r.Set("BeamMatrixFileLocation","/data/minos/pittam/beamdata/NewFluxHelpersRunIAllSkzpPiMinusNCUtilsBin.root");
00321   r.Set("SelectionEfficiencyFileLocation","/home/pittam/minos/devtest/EffMomCorrectionsWithNCNCUtilsBin.root");
00322 
00323   r.LockValues();
00324   return r;
00325 }
00326 
00327 
00328 //----------------------------------------------------------------------
00329 //this method allows the user to pass in appropriate settings for the
00330 //extrapolation such as fLocations of files, whether to generate the files
00331 //again, etc.  the registry comes from the job module GetConfig method
00332 void NCExtrapolationBeamMatrix::Prepare(const Registry& r)
00333 {
00334   MSG("NCExtrapolationBeamMatrix", Msg::kInfo) <<  "PREPARING BEAM MATRIX EXTRAPOLATION" << endl;
00335 
00336   // the base class takes care of turning the systematic parameters on/off
00337   // and setting their adjusted values if any
00338 
00339   //might need to change this to be passed in as part of the registry
00340   NCType::ECuts cutsType ;
00341   cutsType = NCType::kNCCuts ;
00342   SetFiducialMasses(cutsType) ;
00343     
00344   NCExtrapolation::Prepare(r);  
00345 
00346   int         tmpi;
00347   double      tmpd;
00348   const char* tmps;
00349 
00350   //  if(r.Get("UE3SqrVal",             tmpd)) fUE3Sqr                     = tmpd;
00351 
00352   if (r.Get("ExtractionType", tmpi)) fExtractionType=tmpi;
00353 
00354   // get location of beam matrix helpers
00355   if (r.Get("BeamMatrixFileLocation", tmps)) fBeamMatrixPath=tmps;
00356   GetBeamMatrix();
00357   // get selection and reconstruction efficiency histograms
00358   if (r.Get("SelectionEfficiencyFileLocation", tmps)) fSelEffFilePath=tmps;
00359   GetEfficiencyHistograms();
00360   if(r.Get("FarNearSmoothingWidth", tmpd)) fSmoothWidth = tmpd;
00361 
00362   //Logfile
00363   r.Get("FileName",tmps);
00364   string outFile(tmps);
00365   string::size_type start = outFile.rfind("/") + 1;
00366   outFile.erase(start,outFile.size());
00367   outFile += "ExtrapolationBeamMatrixFit.log"; 
00368   logFile = new ofstream(outFile.c_str(),ios::out | ios::app);
00369   
00370 }
00371 
00372 
00373 //----------------------------------------------------------------------
00374 template<class T> void NCExtrapolationBeamMatrix::
00375 HistSmoothHelper(T* h, bool is2D, double weight, double x, double y)
00376 {
00377   if(fSmoothWidth == 0){
00378     // Shortcut all the below and just fill the histogram
00379     if(is2D)
00380       ((TH2D*)h)->Fill(x, y, weight);
00381     else
00382       h->Fill(x, weight);
00383     return;
00384   }
00385 
00386   // Paranoia over some scary text in the documentation for TAxis::GetBin
00387   h->SetBit(TH1::kCanRebin, false);
00388 
00389   TAxis* xaxis = h->GetXaxis();
00390   const int nbinsx = xaxis->GetNbins();
00391 
00392   // Warning - this number will only work in axis calls, not histogram calls
00393   const int xbin = xaxis->FindBin(x);
00394   const double lo = xaxis->GetBinLowEdge(xbin);
00395   const double hi = xaxis->GetBinUpEdge(xbin);
00396 
00397   const int ybin = is2D ? h->GetYaxis()->FindBin(y) : 0;
00398 
00399   const int histBin = xbin + (nbinsx+2)*ybin;
00400 
00401   const double dist_lo = x-lo;
00402   const double dist_hi = hi-x;
00403 
00404   // Don't smear events into the underflow bin
00405   const bool do_lo = xbin > 1 && dist_lo < fSmoothWidth*x;
00406   // Don't smear events into the overflow bin
00407   const bool do_hi = xbin < nbinsx && dist_hi < fSmoothWidth*x;
00408 
00409   double weight_here = 1;
00410   double weight_lo = 0;
00411   double weight_hi = 0;
00412 
00413   if(do_lo){
00414     const double transfer = .5*(1-dist_lo/(fSmoothWidth*x));
00415     weight_here -= transfer;
00416     weight_lo += transfer;
00417   }
00418   if(do_hi){
00419     const double transfer = .5*(1-dist_hi/(fSmoothWidth*x));
00420     weight_here -= transfer;
00421     weight_hi += transfer;
00422   }
00423 
00424   assert(weight_here >= .499);
00425   assert(weight_lo <= .501);
00426   assert(weight_hi <= .501);
00427   assert(weight_here <= 1);
00428   assert(weight_lo >= 0);
00429   assert(weight_hi >= 0);
00430   assert(fabs(weight_here+weight_lo+weight_hi-1) < .001);
00431 
00432   h->fArray[histBin] += weight*weight_here;
00433 
00434   if(do_lo){
00435     h->fArray[histBin-1] += weight*weight_lo;
00436   }
00437   if(do_hi){
00438     h->fArray[histBin+1] += weight*weight_hi;
00439   }
00440 }
00441 
00442 template void NCExtrapolationBeamMatrix::
00443 HistSmoothHelper<TH1D>(TH1D*, bool, double, double, double);
00444 template void NCExtrapolationBeamMatrix::
00445 HistSmoothHelper<TH2D>(TH2D*, bool, double, double, double);
00446 
00447 void NCExtrapolationBeamMatrix::FillHistogramSmoothed(TH1D* h, double x, double weight)
00448 {
00449   HistSmoothHelper(h, false, weight, x);
00450 }
00451 
00452 
00453 void NCExtrapolationBeamMatrix::FillHistogramSmoothed2D(TH2D* h, double x, double y, double weight)
00454 {
00455   HistSmoothHelper(h, true, weight, x, y);
00456 }
00457 
00458 
00459 //----------------------------------------------------------------------
00460 void NCExtrapolationBeamMatrix::FillDataMCHistogramsNear(NCBeam* beam,
00461                                                          NCType::EEventType nccc,
00462                                                          int beamToUse)
00463 {
00464   using Detector::kNear;
00465 
00466   //loop over NCEnergy bin objects in the near detector
00467   //to get the energies from the data events in each bin
00468   //and fill the fND_data histogram
00469 
00470   int selreco_ND = kNCSelRecoEnergy_ND;
00471   int reco_ND = kNCRecoEnergy_ND;
00472   int recoBkg = kNCRecoBkg_ND;
00473   int purity = kNCPurity_ND;
00474   int tau = kNCRecoEnergyTau_ND;
00475   int oscnue =  kNCRecoEnergyOscNue_ND ;
00476   int beamnue = kNCRecoEnergyBeamNueBkg_ND;
00477 
00478   int recototrue = kNCRecoTrueSig_ND;
00479   int recototrueBkg = kNCRecoTrueBkg_ND; 
00480 
00481   int recoData_ND = kNCDataRecoEnergy_ND;
00482   int trueE = kNCTrueEnergy_ND;
00483   int trueEBkg = kNCTrueEnergyBkg_ND;
00484 
00485   if(nccc == NCType::kCC){
00486 
00487     selreco_ND = kCCSelRecoEnergy_ND;
00488     reco_ND = kCCRecoEnergy_ND;
00489     recoBkg = kCCRecoBkg_ND;
00490     purity = kCCPurity_ND;
00491     tau = kCCRecoEnergyTau_ND;
00492     oscnue =  kCCRecoEnergyOscNue_ND ;
00493     beamnue = kCCRecoEnergyBeamNueBkg_ND;
00494 
00495     recototrue =  kCCRecoTrueSig_ND;
00496     recototrueBkg = kCCRecoTrueBkg_ND; 
00497 
00498     recoData_ND = kCCDataRecoEnergy_ND;
00499     trueE =  kCCTrueEnergy_ND;
00500     trueEBkg = kCCTrueEnergyBkg_ND;
00501 
00502   }
00503   
00504   //
00505   //Turns out that reseting is important
00506   //otherwise histograms pile up on each other
00507   //
00508   
00509   BMbybeams[beamToUse]->GetMCHists()[selreco_ND]->Reset( "ICE" );
00510   BMbybeams[beamToUse]->GetMCHists()[reco_ND]->Reset( "ICE" );
00511   BMbybeams[beamToUse]->GetMCHists()[recoBkg]->Reset( "ICE" );
00512   BMbybeams[beamToUse]->GetMCHists()[purity]->Reset( "ICE" );
00513   BMbybeams[beamToUse]->GetMCHists()[tau]->Reset( "ICE" );
00514   BMbybeams[beamToUse]->GetMCHists()[beamnue]->Reset( "ICE" );
00515   BMbybeams[beamToUse]->GetMCHists()[oscnue]->Reset( "ICE" );
00516   
00517   BMbybeams[beamToUse]->GetMCHists()[trueE]->Reset( "ICE" );
00518   BMbybeams[beamToUse]->GetMCHists()[trueEBkg]->Reset( "ICE" );
00519   
00520   BMbybeams[beamToUse]->Get2DHists()[recototrue]->Reset( "ICE" );
00521   BMbybeams[beamToUse]->Get2DHists()[recototrueBkg]->Reset( "ICE" );
00522   
00523   BMbybeams[beamToUse]->GetDataPredHists()[recoData_ND]->Reset( "ICE" );
00524 
00525   for(int b  = 0; b < beam->GetNumberEnergyBins(nccc); ++b){
00526     NCEnergyBin* bin = beam->GetEnergyBin(b, nccc);
00527 
00528     const int dataSize       = bin->GetDataVectorSize();
00529     const int mcSize         = bin->GetMCSignalVectorSize();
00530     const int mcSize_bkg     = bin->GetMCBackgroundVectorSize();
00531     const int mcSize_tau     = bin->GetMCNuTauVectorSize();
00532     const int mcSize_beamnue = bin->GetMCBeamNuEVectorSize();
00533     const int mcSize_oscnue  = bin->GetMCOscNuEVectorSize();
00534         
00535     // The variables that get filled with event information
00536     double trueEnergy    = 0;
00537     double recoShowerE   = 0;
00538     double recoMuonE     = 0;
00539     double energy        = 0;
00540     double weight        = 0;
00541     int    flavor        = 0;
00542 
00543     for(int e = 0; e < dataSize; ++e){
00544       bin->GetDataInformation(energy, weight, e);
00545       FillHistogramSmoothed(BMbybeams[beamToUse]->GetDataPredHists()[recoData_ND], energy, weight);
00546     }
00547 
00548     //------------------------------
00549     // numu
00550     //no nc weights * here as it doesn't matter only need CC spectrum to look right
00551     for(int e = 0; e < mcSize; ++e){
00552       bin->GetMCInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00553       if(nccc == NCType::kNC) recoMuonE = 0;
00554       FillHistogramSmoothed( BMbybeams[beamToUse]->GetMCHists()[reco_ND], recoShowerE + recoMuonE, weight);
00555       if(flavor == 14) FillHistogramSmoothed( BMbybeams[beamToUse]->GetMCHists()[purity], recoShowerE + recoMuonE, weight);    
00556       if(flavor == 14) FillHistogramSmoothed( BMbybeams[beamToUse]->GetMCHists()[trueE], trueEnergy, weight);    
00557       if(flavor == 14) FillHistogramSmoothed2D(BMbybeams[beamToUse]->Get2DHists()[recototrue], trueEnergy, recoShowerE + recoMuonE, weight);
00558     }
00559 
00560     for(int e = 0; e < mcSize_bkg; ++e){
00561       bin->GetMCBackgroundInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00562       if(nccc == NCType::kNC) recoMuonE = 0;
00563       if(nccc == NCType::kCC) weight *= BMbybeams[beamToUse]->GetmScaleNC().at(WhichFitParam(trueEnergy)) ;      
00564       // need to adjust CCBkg by the nd xsections... lets do this using only 1 2d histogram... meaning this gets made at the end of this method for the CC.
00565       // NC is fine as it is. Actually it doesn't even matter doesn't get used for anything.
00566       if(flavor == 14) FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[trueEBkg], trueEnergy, weight);    
00567       //need to add background to above histogram not subtract it. Including wrong sign in this one     
00568       FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[recoBkg], recoShowerE + recoMuonE, weight);             
00569       FillHistogramSmoothed2D(BMbybeams[beamToUse]->Get2DHists()[recototrueBkg], trueEnergy, recoShowerE + recoMuonE ,weight);
00570     }
00571   
00572 
00573     //------------------------------
00574     // nutau
00575     for(int e = 0; e < mcSize_tau; ++e){
00576       bin->GetMCNuTauInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00577       if(nccc == NCType::kNC) recoMuonE = 0;
00578       FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[tau], recoShowerE + recoMuonE, weight);
00579     }
00580 
00581     //------------------------------
00582     // beam nue
00583     for(int e = 0; e < mcSize_beamnue; ++e){
00584       bin->GetMCBeamNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00585       if(nccc == NCType::kNC) recoMuonE = 0;
00586       FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[beamnue], recoShowerE + recoMuonE, weight);
00587     }
00588 
00589     //------------------------------
00590     // oscillated nue
00591     for(int e = 0; e < mcSize_oscnue; ++e){
00592       bin->GetMCOscNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00593       if(nccc == NCType::kNC) recoMuonE = 0;
00594       FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[oscnue], recoShowerE + recoMuonE, weight);
00595     }
00596   } // end for b
00597   
00598   
00599   // putting the data into the systematic beamTypes. Only needed for the LE beams. TODO change to correct runtype
00600   const NCBeam::Info beamInfoLEEEE = NCBeam::Info(BeamType::kL010z185i, NC::RunUtil::kRunAll);
00601   int nomBeamLE = fBMbybeams.find(beamInfoLEEEE)->second ;
00602   if(beam->GetBeamType() == BeamType::kL010z185i){
00603     for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
00604       BMbybeams[beamToUse]->GetDataPredHists()[recoData_ND]->SetBinContent(i,BMbybeams[nomBeamLE]->GetDataPredHists()[recoData_ND]->GetBinContent(i));
00605     }    
00606   }
00607   
00608   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
00609     // purity correction histogram
00610     double denom = BMbybeams[beamToUse]->GetMCHists().at(reco_ND)->GetBinContent(i) + BMbybeams[beamToUse]->GetMCHists().at(recoBkg)->GetBinContent(i) + BMbybeams[beamToUse]->GetMCHists().at(beamnue)->GetBinContent(i);
00611     //make NC/cc selected histos
00612     BMbybeams[beamToUse]->GetMCHists().at(selreco_ND)->SetBinContent(i, denom ) ;
00613     if(denom > 0)
00614       BMbybeams[beamToUse]->GetMCHists().at(purity)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(purity)->GetBinContent(i) / denom ) ;
00615     else BMbybeams[beamToUse]->GetMCHists().at(purity)->SetBinContent(i,0);
00616   }
00617 }
00618 
00619 //----------------------------------------------------------------------
00620 void NCExtrapolationBeamMatrix::FillDataMCHistogramsFar(NCBeam* beam,
00621                                                         NCType::EEventType nccc,
00622                                                         int beamToUse)
00623 {
00624   using Detector::kFar;
00625 
00626   //loop over NCEnergy bin objects in the far detector
00627   double trueEnergy    = 0.;
00628   double recoShowerE   = 0.;
00629   double recoMuonE     = 0.;
00630   double weight        = 0.;
00631   int    flavor        = 0;
00632 
00633   int sig         = kNCSig;
00634   int bkg         = kNCBkg;
00635   int tau         = kNCTau;
00636   int beamnue     = kNCBeamNue;
00637   int oscnue      = kNCOscNue;
00638   int wrongsignbkg = kNCWrongSignBkg;
00639 
00640   int selreco_FD = kNCSelRecoEnergy_FD;
00641   int reco_FD = kNCRecoEnergy_FD;
00642   
00643   int trueE = kNCTrueEnergy_FD;
00644   int trueExsec = kNCTrueEnergyXsecFit_FD;
00645   int trueEBkg = kNCTrueEnergyBkg_FD;
00646 
00647   int recototrue = kNCTrueRecoSig_FD;
00648   int recototrueBkg = kNCTrueRecoBkg_FD; 
00649   
00650   int recoBkg = kNCRecoBkg_FD;
00651   int purity = kNCPurity_FD;
00652 
00653   int nue = kNCRecoEnergyBeamNueBkg_FD ;
00654 
00655   if(nccc == NCType::kCC){
00656     sig      = kCCSig;
00657     bkg      = kCCBkg;
00658     tau      = kCCTau;
00659     beamnue  = kCCBeamNue;
00660     oscnue   = kCCOscNue;
00661     wrongsignbkg = kCCWrongSignBkg;
00662   
00663     selreco_FD = kCCSelRecoEnergy_FD;
00664     reco_FD = kCCRecoEnergy_FD;
00665     
00666     trueE = kCCTrueEnergy_FD;
00667     trueExsec = kCCTrueEnergyXsecFit_FD;
00668     trueEBkg = kCCTrueEnergyBkg_FD;
00669 
00670     recototrue = kCCTrueRecoSig_FD;
00671     recototrueBkg = kCCTrueRecoBkg_FD; 
00672 
00673     recoBkg = kCCRecoBkg_FD;
00674     purity = kCCPurity_FD;
00675 
00676     nue = kCCRecoEnergyBeamNueBkg_FD ;
00677 }
00678 
00679    BMbybeams[beamToUse]->Get2DOscHists()[sig]->Reset( "ICE" );
00680    BMbybeams[beamToUse]->Get2DOscHists()[bkg]->Reset( "ICE" );
00681    BMbybeams[beamToUse]->Get2DOscHists()[tau]->Reset( "ICE" );
00682    BMbybeams[beamToUse]->Get2DOscHists()[beamnue]->Reset( "ICE" );
00683    BMbybeams[beamToUse]->Get2DOscHists()[oscnue]->Reset( "ICE" );
00684    BMbybeams[beamToUse]->Get2DOscHists()[wrongsignbkg]->Reset( "ICE" );
00685 
00686    BMbybeams[beamToUse]->GetMCHists()[selreco_FD]->Reset( "ICE" );
00687    BMbybeams[beamToUse]->GetMCHists()[reco_FD]->Reset( "ICE" );
00688    
00689    BMbybeams[beamToUse]->GetMCHists()[trueE]->Reset( "ICE" );
00690    BMbybeams[beamToUse]->GetMCHists()[trueExsec]->Reset( "ICE" );
00691    BMbybeams[beamToUse]->GetMCHists()[trueEBkg]->Reset( "ICE" );
00692    
00693    BMbybeams[beamToUse]->Get2DHists()[recototrue]->Reset( "ICE" );
00694    BMbybeams[beamToUse]->Get2DHists()[recototrueBkg]->Reset( "ICE" );
00695 
00696    BMbybeams[beamToUse]->GetMCHists()[recoBkg]->Reset( "ICE" );
00697    BMbybeams[beamToUse]->GetMCHists()[purity]->Reset( "ICE" );
00698    
00699    BMbybeams[beamToUse]->GetMCHists()[nue]->Reset( "ICE" );
00700 
00701    const int B = beam->GetNumberEnergyBins(nccc);
00702    for(int b = 0; b < B; ++b){
00703      NCEnergyBin* bin = beam->GetEnergyBin(b, nccc);
00704 
00705      const int mcSize         = bin->GetMCSignalVectorSize();
00706      const int mcSize_bkg     = bin->GetMCBackgroundVectorSize();
00707      const int mcSize_tau     = bin->GetMCNuTauVectorSize();
00708      const int mcSize_beamnue = bin->GetMCBeamNuEVectorSize();
00709      const int mcSize_oscnue  = bin->GetMCOscNuEVectorSize();
00710      
00711      //numu
00712      for(int e = 0; e < mcSize; ++e){
00713        bin->GetMCInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00714        if(nccc == NCType::kNC) recoMuonE = 0;
00715        if(flavor == 14) FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[trueE], trueEnergy, weight);           
00716        //The weights for the xsection go into the true to reco histogram and are applied at the true to reco stage. 
00717        //don't need to do the other 2d ones as they are done on the nominal mc. The purity hist is only used in the unosc prediction at the moment. Will need to be adjusted if not though
00718        //Relevant Backgrounds are adjusted for xsecs in the DoOscillations method
00719        //When fitting for a NC Clean systematic it only shifts the nc selected and wrong sign bkg NOT cc bkg... small effect.
00720              
00721       if(flavor == 14)FillHistogramSmoothed2D( BMbybeams[beamToUse]->Get2DOscHists()[sig], recoShowerE + recoMuonE, trueEnergy, weight);      
00722       if(flavor != 14)FillHistogramSmoothed2D( BMbybeams[beamToUse]->Get2DOscHists()[wrongsignbkg], recoShowerE + recoMuonE, trueEnergy, weight);
00723       if(nccc == NCType::kNC) weight *= BMbybeams[beamToUse]->GetmScaleNC().at(WhichFitParam(trueEnergy));
00724       if(flavor == 14) FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[purity], recoShowerE + recoMuonE, weight);    
00725       FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[reco_FD], recoShowerE + recoMuonE, weight);
00726       if(flavor == 14) FillHistogramSmoothed2D(BMbybeams[beamToUse]->Get2DHists()[recototrue], trueEnergy, recoShowerE + recoMuonE, weight);
00727       if(flavor == 14) FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[trueExsec], trueEnergy, weight);           
00728       
00729 
00730     }
00731 
00732     for(int e = 0; e < mcSize_bkg; ++e){
00733       bin->GetMCBackgroundInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00734       if(nccc == NCType::kNC) recoMuonE = 0;
00735       if(flavor == 14) FillHistogramSmoothed2D(BMbybeams[beamToUse]->Get2DHists()[recototrueBkg], trueEnergy, recoShowerE + recoMuonE, weight);
00736       if(flavor == 14) FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[trueEBkg], trueEnergy, weight);     
00737       if(nccc == NCType::kCC) weight *= BMbybeams[beamToUse]->GetmScaleNC().at(WhichFitParam(trueEnergy));
00738       FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[recoBkg], recoShowerE + recoMuonE, weight);      
00739       //Weighting this here rather than DoOsc method
00740       FillHistogramSmoothed2D( BMbybeams[beamToUse]->Get2DOscHists()[bkg], recoShowerE + recoMuonE, trueEnergy, weight);
00741     }
00742     
00743     //nutau
00744     for(int e = 0; e < mcSize_tau; ++e){
00745       bin->GetMCNuTauInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00746       if(nccc == NCType::kNC) recoMuonE = 0;
00747       FillHistogramSmoothed2D( BMbybeams[beamToUse]->Get2DOscHists()[tau], recoShowerE + recoMuonE, trueEnergy, weight);
00748     }
00749 
00750     //beamnue
00751     for(int e = 0; e < mcSize_beamnue; ++e){
00752       bin->GetMCBeamNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00753       if(nccc == NCType::kNC) recoMuonE = 0;
00754       FillHistogramSmoothed(BMbybeams[beamToUse]->GetMCHists()[nue], recoShowerE + recoMuonE, weight);
00755       FillHistogramSmoothed2D( BMbybeams[beamToUse]->Get2DOscHists()[beamnue], recoShowerE + recoMuonE, trueEnergy, weight);
00756 
00757     }
00758     
00759     //oscnue
00760     for(int e = 0; e < mcSize_oscnue; ++e){
00761       bin->GetMCOscNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
00762       if(nccc == NCType::kNC) recoMuonE = 0;
00763       FillHistogramSmoothed2D( BMbybeams[beamToUse]->Get2DOscHists()[oscnue], recoShowerE + recoMuonE, trueEnergy, weight);
00764     }
00765     
00766     const int N = bin->GetDataVectorSize();
00767     for(int n = 0; n < N; ++n){
00768       double energy, weight;
00769       bin->GetDataInformation(energy, weight, n);
00770       FillHistogramSmoothed(BMbybeams[beamToUse]->GetFDDataHists()[sig], energy, weight);
00771     } // end for n
00772   } // end for b
00773 
00774   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
00775     double denom = BMbybeams[beamToUse]->GetMCHists().at(reco_FD)->GetBinContent(i) + BMbybeams[beamToUse]->GetMCHists().at(recoBkg)->GetBinContent(i) + BMbybeams[beamToUse]->GetMCHists().at(nue)->GetBinContent(i) ;
00776     BMbybeams[beamToUse]->GetMCHists().at(selreco_FD)->SetBinContent(i, denom ) ;    
00777     if(denom > 0)
00778       BMbybeams[beamToUse]->GetMCHists().at(purity)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(purity)->GetBinContent(i) / denom ) ;
00779     else BMbybeams[beamToUse]->GetMCHists().at(purity)->SetBinContent(i,0);
00780   }
00781 
00782 
00783 }
00784 //----------------------------------------------------------------------
00785 
00786 
00787 //----------------------------------------------------------------------
00788 void NCExtrapolationBeamMatrix::
00789 ConstructFarSpectrum(const NC::OscProb::OscPars* pars, int beamsToUse)
00790 {
00791   DoPurityCorrectionND(beamsToUse);
00792   DoRecoToTrueND(beamsToUse);
00793   DoEfficencyCorrectionND(beamsToUse);
00794   DoXsectionCorrectionND(beamsToUse);
00795   DoBeamMatrixExtrapolation(beamsToUse);
00796   GetNCFromCCFlux(beamsToUse);
00797   DoXsectionCorrectionFD(beamsToUse);
00798   DoEfficencyCorrectionFD(beamsToUse);
00799   DoUnoscTrueToRecoFD(beamsToUse);
00800   DoUnoscPurityCorrectionFD(beamsToUse);
00801   //need to call unosc before oscillations
00802   DoOscillations(pars, beamsToUse);
00803 }
00804 //----------------------------------------------------------------------
00805 void NCExtrapolationBeamMatrix::
00806 FindSpectraForPars(const NC::OscProb::OscPars* oscPars,
00807                    const NC::SystPars& systPars_org,
00808                    vector<NCBeam::Info> beamsToUse,
00809                    vector<TH1*>& expvec,
00810                    vector<TH1*>& obsvec)
00811 {
00812 
00813 
00814   //not sure where to put this...
00815   //has to be before first call to filldatamchistograms
00816   //but after addevent loops
00817 
00818   // these are taken care of by clever weighting of NCBeams
00819   fFDPOTData = 1.0 ;
00820   fFDPOTMC = 1.0 ;
00821   
00822   fNDPOTData = 1.0 ;
00823   fNDPOTMC =  1.0 ;
00824 
00825   int icount = 0;  
00826   int ibm = 0;
00827 
00828   static bool doneFillHists = false ;
00829   if(!doneFillHists) {
00830 
00831     for (Int_t i=0; i<4; i++) {
00832       m0ScaleNC.push_back(1.0);
00833       m0ScaleNCErr.push_back(0.005);
00834 
00835       mScaleNC.push_back(1.0);
00836       mScaleNCErr.push_back(0.005);
00837 
00838     }
00839     //this is for use in the nd xsection fitting
00840     for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00841       const pair<NCBeam::Info, Detector::Detector_t> key = it->first;
00842       const NCBeam::Info beamInfo = key.first;
00843       const Detector::Detector_t det = key.second;    
00844       NCBeam* beam = it->second;        
00845       if(det == Detector::kNear) beamsNear.push_back(beam); 
00846       MSG("NCExtrapolationBeamMatrix", Msg::kInfo) << "Beam Description " << beamInfo.GetDescription() << " det " <<  beam->GetDetector() <<endl;
00847 
00848     }
00849 
00850     //filling the vector of BeamMatrix Objects ibm is index for Map
00851     for(fBeams_t::iterator it = fBeams.begin(); it != fBeams.end(); ++it){
00852       
00853       const pair<NCBeam::Info, Detector::Detector_t> key = it->first;
00854       const NCBeam::Info beamInfo = key.first;
00855       const Detector::Detector_t det = key.second;
00856 
00857       NCBeam* beam = it->second;        
00858       
00859       string name = (string)beam->GetInfo().GetDescription();
00860       string title = "title_"+name;
00861       string bmname = "beamMatrix_"+name;
00862       
00863       //only 1 BeamMatrix object for ND and FD
00864       if(icount%2 == 0){ 
00865         BMbybeams.push_back(new BeamMatrix(bmname,title,name));
00866         fBMbybeams[beamInfo] = ibm;
00867       }
00868       
00869       if( beam->GetDetector() == Detector::kNear){
00870         //xsection fit is done here before FillDataMCHistograms
00871         if(beam->GetBeamType() == BeamType::kL010z185i) doNDXsectionFit(1, beam, ibm);
00872         if(fUseNC) FillDataMCHistogramsNear(beam, NCType::kNC, ibm);
00873         if(fUseCC) FillDataMCHistogramsNear(beam, NCType::kCC, ibm);
00874         MSG("NCExtrapolationBeamMatrix", Msg::kInfo) << "Filled Beam with Description " << name << " det  " << det << " ibm " << ibm 
00875                                                      << " BeamsNear.at(ibm)->GetDescription() " << beamsNear.at(ibm)->GetInfo().GetDescription() << endl;
00876       }
00877         
00878       if( beam->GetDetector() == Detector::kFar){
00879         BMbybeams[ibm]->GetFDDataHists().at(kNCSig)->Reset("ICE");
00880         BMbybeams[ibm]->GetFDDataHists().at(kCCSig)->Reset("ICE");
00881         if(fUseNC) FillDataMCHistogramsFar(beam, NCType::kNC, ibm);
00882         if(fUseCC) FillDataMCHistogramsFar(beam, NCType::kCC, ibm);
00883         
00884         MSG("NCExtrapolationBeamMatrix", Msg::kInfo) << "Filled Beam with Description " << name << " det  " << det << " ibm " << ibm <<endl ;     
00885       }
00886       
00887       if(icount%2 == 1) ibm++; 
00888       icount++ ;
00889     }
00890   
00891   }
00892   //only need to do nd xsec fit and fill hists once
00893   doneFillHists = true ;
00894 
00895   // making fd prediciton for beams asked for
00896   for (int i=0; i<(int)beamsToUse.size(); ++i) {
00897     
00898     NCBeam::Info beamInfo = beamsToUse[i];
00899     
00900     //getting beams and index for BeamMatrix object that correpsonds to those beams
00901     int bmeq = fBMbybeams.find(beamInfo)->second;
00902     
00903     NCBeam* beam_fd = GetBeam(Detector::kFar , beamInfo);
00904     NCBeam* beam_nd = GetBeam(Detector::kNear, beamInfo);
00905 
00906     assert(beam_fd);
00907     assert(beam_nd);
00908     
00909     //only want to extrapolate LE beams. Others are only used for ND fitting
00910     if(beam_fd->GetBeamType() !=  BeamType::kL010z185i) continue ;
00911 
00912     if(fDoSystematicInterpolation){
00913       InitializeInterpolator(oscPars);
00914     }
00915     
00916     if(!fInterpolator){
00917       
00918       BMbybeams[bmeq]->GetFitHists().at(kNCSig)->Reset("ICE"); //integral contents error
00919       BMbybeams[bmeq]->GetFitHists().at(kCCSig)->Reset("ICE");
00920       
00921       ConstructFarSpectrum(oscPars,bmeq);
00922       
00923       if(fUseNC){
00924         expvec.push_back(BMbybeams[bmeq]->GetFitHists()[kNCSig]);
00925         obsvec.push_back(BMbybeams[bmeq]->GetFDDataHists()[kNCSig]);
00926       }
00927       
00928       if(fUseCC){
00929         expvec.push_back(BMbybeams[bmeq]->GetFitHists()[kCCSig]);
00930         obsvec.push_back(BMbybeams[bmeq]->GetFDDataHists()[kCCSig]);
00931       }      
00932       return ;
00933     }
00934    
00935     const vector<double> shift = fCoordConv.VectorFromSystPars(systPars_org);
00936     vector<TH1*> interp = fInterpolator->GetInterpolatedSpectra(shift);
00937     
00938     BMbybeams[i]->GetFitHists().at(kNCSig)->Reset("ICE"); //integral contents error
00939     BMbybeams[i]->GetFitHists().at(kCCSig)->Reset("ICE");
00940 
00941     ConstructFarSpectrum(oscPars ,bmeq);    
00942     
00943     MultiplyFast(BMbybeams[bmeq]->GetFitHists()[kNCSig], interp[0]);
00944     MultiplyFast(BMbybeams[bmeq]->GetFitHists()[kCCSig], interp[2]);
00945     
00946     if(fUseNC){
00947       expvec.push_back(BMbybeams[bmeq]->GetFitHists()[kNCSig]);
00948       obsvec.push_back(BMbybeams[bmeq]->GetFDDataHists()[kNCSig]);
00949     }
00950     
00951     if(fUseCC){
00952       expvec.push_back(BMbybeams[bmeq]->GetFitHists()[kCCSig]);
00953       obsvec.push_back(BMbybeams[bmeq]->GetFDDataHists()[kCCSig]);
00954     }
00955   }
00956   ++fNCalls;
00957   return;
00958 }
00959 //----------------------------------------------------------------------
00960 
00961 
00962 //----------------------------------------------------------------------
00963 void NCExtrapolationBeamMatrix::CleanupSpectra(vector<TH1*> /*exps*/,
00964                                             vector<TH1*> /*obss*/)
00965 {
00966   // No need to clear anything. We don't allocate anything new each time
00967 }
00968 //----------------------------------------------------------------------
00969 
00970 
00971 //----------------------------------------------------------------------
00972 void NCExtrapolationBeamMatrix::
00973 WriteResources(const NC::OscProb::OscPars* trueOscPars)
00974 {
00975   MSG("NCExtrapolationBeamMatrix", Msg::kInfo) << "nCalls: " << fNCalls << endl;
00976 
00977   // only writing out RunI at the moment
00978   NCBeam::Info bmInfo  = NCBeam::Info(BeamType::kL010z185i,NC::RunUtil::kRunI) ;
00979   int bmequiv = fBMbybeams.find(bmInfo)->second;
00980   
00981   NC::SystPars systPars = GetBestFitSysts();
00982   const NC::OscProb::OscPars* oscPars = GetBestFitOscPars();
00983   
00984   if(fDoSystematicInterpolation){
00985     const vector<double> shift = fCoordConv.VectorFromSystPars(systPars);
00986     vector<TH1*> interp = fInterpolator->GetInterpolatedSpectra(shift);
00987     
00988     ConstructFarSpectrum(oscPars, bmequiv);    
00989     
00990     MultiplyFast(BMbybeams[bmequiv]->GetFitHists()[kNCSig], interp[0]);
00991     MultiplyFast(BMbybeams[bmequiv]->GetFitHists()[kCCSig], interp[2]);
00992     
00993   }
00994   
00995   else ConstructFarSpectrum(oscPars, bmequiv);
00996 
00997   delete oscPars;
00998     
00999   if(fUseNC) FillResultHistograms(bmInfo, NCType::kNC, fNominalBM, fOscBM);
01000   if(fUseCC) FillResultHistograms(bmInfo, NCType::kCC, fNominalBM, fOscBM);  
01001 
01002   NCExtrapolation::WriteResources(trueOscPars);
01003   // get a pointer to the current directory
01004   // this is one of the output files
01005 
01006   TDirectory* saveDir = gDirectory;
01007 
01008   //writing out histograms. Any others wanted can be easily added ME or HE beam for example
01009   for(unsigned int i = 0; i < 2; ++i) BMbybeams[bmequiv]->GetFDDataHists()[i]->Write();
01010   for(unsigned int i = 0; i < BMbybeams[bmequiv]->GetMCHists().size(); ++i) BMbybeams[bmequiv]->GetMCHists().at(i)->Write();
01011   for(unsigned int i = 0; i < BMbybeams[bmequiv]->GetDataPredHists().size(); ++i) BMbybeams[bmequiv]->GetDataPredHists().at(i)->Write();
01012   for(unsigned int i = 0; i < BMbybeams[bmequiv]->Get2DHists().size(); ++i)  BMbybeams[bmequiv]->Get2DHists().at(i)->Write();
01013   for(unsigned int i = 0; i < BMbybeams[bmequiv]->GetFitHists().size();  ++i)  BMbybeams[bmequiv]->GetFitHists().at(i)->Write();
01014   for(unsigned int i = 0; i < ND_XSectionFitRew.size();  ++i)  ND_XSectionFitRew[i]->Write();
01015   for(unsigned int i = 0; i < ND_XSectionFit.size();  ++i)  ND_XSectionFit[i]->Write();
01016   
01017   selEffNDHist->Write() ;
01018   selCCEffFDHist->Write() ;
01019   selNCEffFDHist->Write() ;
01020   recoEffNDHist->Write() ;
01021   recoCCEffFDHist->Write() ;
01022   recoNCEffFDHist->Write() ;
01023   extractNCFromCCFlux->Write() ;
01024   saveDir->cd();
01025 
01026   //writing the result of the x-section fit written into the file
01027   TString parname ;
01028   TString parout ;
01029   gDirectory->mkdir("xSecFit", "xSecFit")->cd();
01030   Registry* xsecFit = new Registry;
01031   xsecFit->SetName("xSecFit_registry");
01032   xsecFit->UnLockKeys();
01033   xsecFit->UnLockValues();
01034   for (Int_t i=0; i<4; i++){ 
01035     parname = (TString) Form("Par %i: ",i);
01036     parout = (TString) Form("%e +%e %e +/- %e, Corr: %e",mScaleNC[i],mScalePos[i],mScaleNeg[i],mScaleNCErr[i],corr[i]);
01037     xsecFit->Set(parname,parout);
01038   }
01039   xsecFit->Write();
01040   saveDir->cd();
01041   delete xsecFit;
01042 }
01043 //----------------------------------------------------------------------
01044 
01045 
01046 //----------------------------------------------------------------------
01047 
01048 void NCExtrapolationBeamMatrix::
01049 FillResultHistograms(NCBeam::Info beamInfo,
01050                      NCType::EEventType nccc,
01051                      vector<vector<double> >& nominal,
01052                      vector<vector<double> >& osc){
01053   
01054   NCBeam* beam = GetBeam(Detector::kFar, beamInfo);
01055   int bmequiv = fBMbybeams.find(beamInfo)->second;
01056 
01057   int sig     = kNCSig;
01058   int bkg     = kNCBkg;
01059   int tau     = kNCTau;
01060   int beamnue = kNCBeamNue;
01061   int oscnue  = kNCOscNue;
01062   int wrongsignbkg = kNCWrongSignBkg;
01063 
01064   if(nccc == NCType::kCC){
01065     sig     = kCCSig;
01066     bkg     = kCCBkg;
01067     tau     = kCCTau;
01068     beamnue = kCCBeamNue;
01069     oscnue  = kCCOscNue;
01070     wrongsignbkg = kCCWrongSignBkg;
01071   }
01072 
01073   for(int i = 0; i < kNumEnergyBinsFar; ++i){
01074 
01075     double eBeamVal = nominal[beamnue][i];
01076     double nooscVal = nominal[sig][i] + nominal[bkg][i] + nominal[wrongsignbkg][i] + eBeamVal;
01077     double fitVal   = BMbybeams[bmequiv]->GetFitHists()[sig]->GetBinContent(i+1);
01078     double bkgVal   = osc[bkg][i] ;
01079     double tauVal   = osc[tau][i];
01080     double eOscVal  = osc[oscnue][i]  ;
01081 
01082     if(nooscVal > 0 )
01083       beam->GetMCHistogram(nccc)->SetBinContent(i+1, nooscVal);
01084     else beam->GetMCHistogram(nccc)->SetBinContent(i+1, 0);
01085     if(fitVal > 0)
01086       beam->GetMCFitHistogram(nccc)->SetBinContent(i+1, fitVal);
01087     else beam->GetMCFitHistogram(nccc)->SetBinContent(i+1, 0);
01088     if(bkgVal > 0){
01089       beam->GetMCBackgroundHistogram(nccc)->SetBinContent(i+1, bkgVal);
01090     }
01091     else  beam->GetMCBackgroundHistogram(nccc)->SetBinContent(i+1, 0);
01092     if(tauVal > 0)
01093       beam->GetMCFitNuMuToNuTauHistogram(nccc)->SetBinContent(i+1, tauVal);
01094     else beam->GetMCFitNuMuToNuTauHistogram(nccc)->SetBinContent(i+1,0);
01095     if(eBeamVal > 0)
01096       beam->GetMCFitNuEToNuEHistogram(nccc)->SetBinContent(i+1, eBeamVal);
01097     else beam->GetMCFitNuEToNuEHistogram(nccc)->SetBinContent(i+1, 0);
01098     if( eOscVal > 0)
01099       beam->GetMCFitNuMuToNuEHistogram(nccc)->SetBinContent(i+1, eOscVal);
01100     else  beam->GetMCFitNuMuToNuEHistogram(nccc)->SetBinContent(i+1, 0);
01101 
01102     double bkgValnofit   = nominal[bkg][i];
01103     double tauValnofit   = nominal[tau][i];
01104     double eOscValnofit  = nominal[oscnue][i];
01105     double eBeamValnofit = osc[beamnue][i];
01106 
01107     if(bkgValnofit > 0)
01108       beam->GetMCNoFitBackgroundHistogram(nccc)->SetBinContent(i+1,bkgValnofit);
01109     else beam->GetMCNoFitBackgroundHistogram(nccc)->SetBinContent(i+1,0);
01110     
01111     if( tauValnofit > 0)
01112       beam->GetMCNoFitNuMuToNuTauHistogram(nccc)->SetBinContent(i+1,tauValnofit);
01113     else  beam->GetMCNoFitNuMuToNuTauHistogram(nccc)->SetBinContent(i+1,0);
01114     
01115     if(eOscValnofit > 0)
01116       beam->GetMCNoFitNuMuToNuEHistogram(nccc)->SetBinContent(i+1,tauValnofit);
01117     else  beam->GetMCNoFitNuMuToNuEHistogram(nccc)->SetBinContent(i+1,0);
01118     
01119     if(eBeamValnofit > 0)
01120       beam->GetMCNoFitNuEToNuEHistogram(nccc)->SetBinContent(i+1,eBeamValnofit);
01121     else  beam->GetMCNoFitNuEToNuEHistogram(nccc)->SetBinContent(i+1,0);
01122     
01123   }
01124 
01125   // We filled the histograms manually, and don't need NCBeam's automatic stuff
01126   // to happen. So inform it of that fact.
01127   beam->MarkHistogramsFilled();
01128 }
01129 //----------------------------------------------------------------------
01130 
01131 //----------------------------------------------------------------------
01132 bool NCExtrapolationBeamMatrix::EnableNearToFarExtrapolation(bool enable)
01133 {
01134   const bool ret = fDoExtrapolation;
01135   fDoExtrapolation = enable;
01136   return ret;
01137 }
01138 //----------------------------------------------------------------------
01139 
01140 
01141 //----------------------------------------------------------------------
01142 // This interface is most convenient for internal use
01143 // I don't know what I need this for...
01144 // It certainly doesn't return the NearSpectra
01145 vector<const TH1*> NCExtrapolationBeamMatrix::
01146 GetNearMCSpectra(vector<NCBeam::Info> beamsToUse)
01147 {
01148   
01149   vector<const TH1*> ret;
01150   for (int i=0; i<(int)beamsToUse.size(); ++i) {
01151     NCBeam::Info beamInfo = beamsToUse[i];
01152     
01153     int bmequiv = fBMbybeams.find(beamInfo)->second;
01154     NCBeam* beam_nd= GetBeam(Detector::kNear, beamInfo);
01155     
01156     if(beam_nd->GetBeamType() !=  BeamType::kL010z185i) continue ;
01157 
01158     // I suspect that what you return here makes no difference. 
01159     //It does have to be return the correct number of histograms though otherwise seg faults
01160     
01161     if(fUseNC) ret.push_back(BMbybeams[bmequiv]->GetMCHists().at(kNCSelRecoEnergy_ND));
01162     if(fUseCC) ret.push_back(BMbybeams[bmequiv]->GetMCHists().at(kCCSelRecoEnergy_ND));
01163    
01164   }
01165   return ret;
01166   
01167 }
01168 //----------------------------------------------------------------------
01169 
01170 //----------------------------------------------------------------------
01171 void NCExtrapolationBeamMatrix::
01172 DoPurityCorrectionND(int beamToUse){
01173  
01174   for(int i = 0; i < kNumEnergyBinsFar+1; ++i ){
01175     BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPurCorr_ND)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kCCSelRecoEnergy_ND)->GetBinContent(i)
01176                                                                                   * BMbybeams[beamToUse]->GetMCHists().at(kCCPurity_ND)->GetBinContent(i));
01177     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyPurCorr_ND)->SetBinContent(i, BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergy_ND)->GetBinContent(i) 
01178                                                                                             * BMbybeams[beamToUse]->GetMCHists().at(kCCPurity_ND)->GetBinContent(i));
01179 
01180   }
01181   return;  
01182 }
01183 
01184 void NCExtrapolationBeamMatrix::
01185 DoRecoToTrueND(int beamToUse){
01186 
01187   vector<double> tempMC(kNumEnergyBinsFar+1,0) ;
01188   vector<double> tempData(kNumEnergyBinsFar+1,0) ;
01189   
01190   t2rCCnd = (TH2D*)CloneFast(BMbybeams[beamToUse]->Get2DHists()[kCCRecoTrueSig_ND]);
01191 
01192   double bincontent = 0;  
01193   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){//reco
01194     for(int j = 1; j < kNumEnergyBinsFar+1; ++j ){//true
01195       // I think I want to use the ndmc to normalise to get cancellations 
01196       // Normalise reco to true matrix
01197       if( BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPurCorr_ND)->GetBinContent(i) > 0){
01198         bincontent = (t2rCCnd->GetBinContent(j,i) / BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPurCorr_ND)->GetBinContent(i));
01199         t2rCCnd->SetBinContent(j,i, bincontent);
01200       }
01201       else t2rCCnd->SetBinContent(j,i,0);
01202     }
01203   }
01204   
01205   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){//reco
01206     for(int j = 1; j < kNumEnergyBinsFar+1; ++j ){//true
01207       // correct reco to true
01208       tempMC[j-1] += (BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPurCorr_ND)->GetBinContent(i) * t2rCCnd->GetBinContent(j,i) );
01209       tempData[j-1] += (BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyPurCorr_ND)->GetBinContent(i) * t2rCCnd->GetBinContent(j,i) );
01210     }
01211   }
01212   
01213   for(int i=1;i<=kNumEnergyBinsFar;i++){
01214     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyPurCorr_ND)->SetBinContent(i,tempMC[i-1]);
01215     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyPurCorr_ND)->SetBinContent(i,tempData[i-1]);
01216     
01217   }
01218 
01219   delete t2rCCnd ;
01220   tempMC.clear() ;
01221   tempData.clear() ;
01222   return;  
01223 }
01224 
01225 void NCExtrapolationBeamMatrix::
01226 GetEfficiencyHistograms(){
01227 
01228   MSG("NCExtrapolationBeamMatrix", Msg::kInfo) << "Getting Efficiency Histograms from: " << fSelEffFilePath << " Extraction Type " << fExtractionType << endl;
01229   TFile* selEffFile = new TFile(fSelEffFilePath,"READ");
01230   if(selEffFile){
01231     
01232     extractNCFromCCFlux = (TH1D*)selEffFile->Get("extractNCFromCCFlux");
01233     
01234     recoEffNDHist = (TH1D*)selEffFile->Get("recoEffHistND");
01235     recoCCEffFDHist = (TH1D*)selEffFile->Get("recoCCEffHistFD");
01236     recoNCEffFDHist = (TH1D*)selEffFile->Get("recoNCEffHistFD");
01237 
01238     switch( fExtractionType){
01239     case NCType::kNCCCExtractionCuts:
01240       selEffNDHist = (TH1D*)selEffFile->Get("selCorrectionTOmND");
01241       selCCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionCCTOmFD"); 
01242       selNCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionNCTOmFD"); 
01243       break;
01244     case NCType::kNCCCExtractionANN:
01245     case NCType::kNCCCExtractionANNNear:
01246     case NCType::kNCCCExtractionANNFar:
01247       selEffNDHist = (TH1D*)selEffFile->Get("selCorrectionRPannND"); 
01248       selCCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionCCRPannFD"); 
01249       selNCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionNCRPannFD"); 
01250       break;
01251     case NCType::kNCCCExtractionkNN:
01252       selEffNDHist = (TH1D*)selEffFile->Get("selCorrectionROND"); 
01253       selCCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionCCROFD"); 
01254       selNCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionNCROFD"); 
01255       break;
01256     case NCType::kNCCCExtractionMDA:
01257       selEffNDHist = (TH1D*)selEffFile->Get("selCorrectionASND"); 
01258       selCCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionCCASFD"); 
01259       selNCEffFDHist = (TH1D*)selEffFile->Get("selCorrectionNCASFD"); 
01260       break;
01261     default:
01262       selEffNDHist = 0 ;
01263       selCCEffFDHist = 0;
01264       selNCEffFDHist = 0;
01265     }    
01266   }
01267   
01268   else{ 
01269     MSG("NCExtrapolationBeamMatrix", Msg::kError) <<  "Can't get Selection Efficiency Histograms from " << fSelEffFilePath  <<  " Extraction Type " <<  fExtractionType << endl;
01270   }
01271   
01272 }
01273 
01274 void NCExtrapolationBeamMatrix::
01275 DoEfficencyCorrectionND(int beamToUse){
01276   
01277   //do selection then reconstruction in the ND
01278      
01279   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
01280     
01281     // selection efficiency correction
01282 
01283     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_ND)->SetBinContent(i,selEffNDHist->GetBinContent(i));
01284         
01285     if(BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_ND)->GetBinContent(i) > 0){
01286       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergySelEffCorr_ND)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyPurCorr_ND)->GetBinContent(i) / BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_ND)->GetBinContent(i));
01287       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergySelEffCorr_ND)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyPurCorr_ND)->GetBinContent(i) / BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_ND)->GetBinContent(i));
01288     }
01289     else{
01290       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergySelEffCorr_ND)->SetBinContent(i,0);
01291       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergySelEffCorr_ND)->SetBinContent(i,0);
01292     }
01293 
01294 
01295   // reconstruction efficiency correction    
01296     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_ND)->SetBinContent(i,recoEffNDHist->GetBinContent(i));
01297     
01298     if(BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_ND)->GetBinContent(i) > 0){
01299       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyEffCorr_ND)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergySelEffCorr_ND)->GetBinContent(i) / BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_ND)->GetBinContent(i));
01300       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyEffCorr_ND)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergySelEffCorr_ND)->GetBinContent(i) / BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_ND)->GetBinContent(i));
01301     }
01302     else{
01303       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyEffCorr_ND)->SetBinContent(i,0);
01304       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyEffCorr_ND)->SetBinContent(i,0);
01305     }
01306     
01307 
01308   }
01309 }
01310 void NCExtrapolationBeamMatrix::
01311 DoXsectionCorrectionND(int beamToUse){
01312   
01313   // Doesn't actually do Xsections as they are folded into the BeamMatrix
01314   // it does do the fiducial mass and pot correction
01315 
01316   MAXMSG("NCExtrapolationBeamMatrix", Msg::kInfo, 1) << "ND Fid Vol " << fNDFidVolMass 
01317                                                << " ND POT MC " << fNDPOTMC
01318                                                << " ND POT Data " << fNDPOTData
01319                                                << endl;
01320 
01321   
01322   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
01323     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyFlux_ND)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyEffCorr_ND)->GetBinContent(i)*fFluxPOT/(fNDFidVolMass*fNDPOTMC));
01324     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyFlux_ND)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyEffCorr_ND)->GetBinContent(i)/(fNDFidVolMass*fNDPOTData));
01325   }
01326 }
01327 
01328 void NCExtrapolationBeamMatrix::
01329 GetBeamMatrix(){
01330 
01331   MSG("NCExtrapolationBeamMatrix", Msg::kInfo) <<  "Getting Beam Matrix from: " << fBeamMatrixPath << endl;
01332   TFile* beamMatrixFile = new TFile(fBeamMatrixPath,"READ");
01333   if(beamMatrixFile){
01334     fBeamMatrix =  (TH2D*)beamMatrixFile->Get("FDVsNDMatrixXSecRW");
01335   }
01336   
01337   else{ 
01338     MSG("NCExtrapolationBeamMatrix", Msg::kError) <<  "Can't get BeamMatrix from " << fBeamMatrixPath  << endl;
01339   }
01340 }
01341 
01342 void NCExtrapolationBeamMatrix::
01343 DoBeamMatrixExtrapolation(int beamToUse){
01344 
01345   int beamMatrixNearBins = fBeamMatrix->GetXaxis()->GetNbins();
01346   int beamMatrixFarBins = fBeamMatrix->GetYaxis()->GetNbins();
01347 
01348   vector<double> temp(beamMatrixNearBins+1,0) ;
01349   vector<double> tempData(beamMatrixNearBins+1,0) ;
01350   
01351   for(int i = 1; i < beamMatrixNearBins+1; ++i ){
01352     for(int j = 1; j <beamMatrixFarBins+1 ; ++j ){      
01353       temp[j] += (BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyFlux_ND)->GetBinContent(i) * fBeamMatrix->GetCellContent( i,j ));
01354       tempData[j] += (BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyFlux_ND)->GetBinContent(i) * fBeamMatrix->GetCellContent( i,j ));
01355     }
01356   }
01357 
01358   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
01359     
01360     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyMatrix_FD)->SetBinContent(i,temp[i]);
01361     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyMatrix_FD)->SetBinContent(i,tempData[i]);
01362 
01363     
01364   }  
01365   temp.clear() ;
01366   tempData.clear() ;
01367 }
01368 
01369 void NCExtrapolationBeamMatrix::
01370 GetNCFromCCFlux(int beamToUse){
01371   
01372   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
01373 
01374     //not really sure where to put this either here or any of the following steps.
01375     //But the histograms already exist so it may as well be here. 
01376     BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergyMatrix_FD)->SetBinContent(i, BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyMatrix_FD)->GetBinContent(i) 
01377                                                                                  * extractNCFromCCFlux->GetBinContent(i));
01378     BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergyMatrix_FD)->SetBinContent(i, BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyMatrix_FD)->GetBinContent(i) 
01379                                                                                            * extractNCFromCCFlux->GetBinContent(i));    
01380   }
01381 }
01382 void NCExtrapolationBeamMatrix::
01383 SetFiducialMasses(NCType::ECuts cutsType){
01384   
01385   fFluxPOT = 1.0;
01386   
01387   switch(cutsType){
01388   case NCType::kCCCuts:
01389     fNDFidVolMass = -9999.9 ;
01390     fFDFidVolMass = -9999.9 ;
01391     break;
01392   case NCType::kNCCuts:
01393     fNDFidVolMass = 26874.0; //kg
01394     fFDFidVolMass = 3726961.; //kg
01395     break;
01396   case NCType::kNCCCFidCuts:
01397     fNDFidVolMass = -9999.9 ;
01398     fFDFidVolMass = -9999.9 ;   
01399     break;
01400   default:
01401     fNDFidVolMass = -9999.9 ;
01402     fFDFidVolMass = -9999.9 ;   
01403   }
01404 }
01405 
01406 void NCExtrapolationBeamMatrix::
01407 DoXsectionCorrectionFD(int beamToUse){
01408 
01409   // Doesn't actually do Xsections as they are folded into the BeamMatrix
01410   // it does do the fiducial mass and pot correction
01411   
01412   MAXMSG("NCExtrapolationBeamMatrix", Msg::kInfo, 1) << "FD Fid Vol " << fFDFidVolMass 
01413                                                       << " FD POT MC " << fFDPOTMC
01414                                                       << " FD POT Data " << fFDPOTData
01415                                                       << endl;  
01416   
01417 
01418   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
01419     
01420     //CC
01421     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyFlux_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyMatrix_FD)->GetBinContent(i)
01422                                                                                *(fFDFidVolMass*fFDPOTMC)/fFluxPOT);
01423     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyFlux_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyMatrix_FD)->GetBinContent(i)
01424                                                                                          *(fFDFidVolMass*fFDPOTData));
01425     
01426     //NC
01427     BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergyFlux_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergyMatrix_FD)->GetBinContent(i)
01428                                                                                *(fFDFidVolMass*fFDPOTMC)/fFluxPOT);
01429     BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergyFlux_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergyMatrix_FD)->GetBinContent(i)
01430                                                                                          *(fFDFidVolMass*fFDPOTData));
01431     
01432   }
01433 }
01434 
01435 void NCExtrapolationBeamMatrix::
01436 DoEfficencyCorrectionFD(int beamToUse){
01437  
01438   //
01439   // Do reconstruction then selection efficiency in the Far Detector
01440   //
01441   
01442   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){
01443     
01444    
01445     // reconstruction efficiency correction    
01446     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_FD)->SetBinContent(i,recoCCEffFDHist->GetBinContent(i));
01447     BMbybeams[beamToUse]->GetMCHists().at(kNCTrueRecoEfficiency_FD)->SetBinContent(i,recoNCEffFDHist->GetBinContent(i));    
01448 
01449     // CC correction
01450     if(BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_FD)->GetBinContent(i) > 0){
01451       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyFlux_FD)->GetBinContent(i) 
01452                                                                                     * BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_FD)->GetBinContent(i));
01453       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyFlux_FD)->GetBinContent(i) 
01454                                                                                               * BMbybeams[beamToUse]->GetMCHists().at(kCCTrueRecoEfficiency_FD)->GetBinContent(i));
01455     }
01456     else{
01457       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyEffCorr_FD)->SetBinContent(i,0);
01458       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyEffCorr_FD)->SetBinContent(i,0);
01459     }
01460     
01461     // NC correction
01462     if(BMbybeams[beamToUse]->GetMCHists().at(kNCTrueRecoEfficiency_FD)->GetBinContent(i) > 0){
01463       BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergyEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergyFlux_FD)->GetBinContent(i) 
01464                                                                                     * BMbybeams[beamToUse]->GetMCHists().at(kNCTrueRecoEfficiency_FD)->GetBinContent(i));
01465       BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergyEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergyFlux_FD)->GetBinContent(i) 
01466                                                                                               * BMbybeams[beamToUse]->GetMCHists().at(kNCTrueRecoEfficiency_FD)->GetBinContent(i));
01467     }
01468     else{
01469       BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergyEffCorr_FD)->SetBinContent(i,0);
01470       BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergyEffCorr_FD)->SetBinContent(i,0);
01471     }
01472 
01473     
01474     // selection efficiency correction
01475     BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_FD)->SetBinContent(i,selCCEffFDHist->GetBinContent(i));
01476     BMbybeams[beamToUse]->GetMCHists().at(kNCTrueSelEfficiency_FD)->SetBinContent(i,selNCEffFDHist->GetBinContent(i));
01477     
01478     //CC
01479     if(BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_FD)->GetBinContent(i) > 0){
01480       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergySelEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergyEffCorr_FD)->GetBinContent(i) 
01481                                                                                        * BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_FD)->GetBinContent(i));
01482       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergySelEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergyEffCorr_FD)->GetBinContent(i) 
01483                                                                                                  * BMbybeams[beamToUse]->GetMCHists().at(kCCTrueSelEfficiency_FD)->GetBinContent(i));
01484     }
01485     else{
01486       BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergySelEffCorr_FD)->SetBinContent(i,0);
01487       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergySelEffCorr_FD)->SetBinContent(i,0);
01488     }
01489   
01490     //NC
01491     if(BMbybeams[beamToUse]->GetMCHists().at(kNCTrueSelEfficiency_FD)->GetBinContent(i) > 0){
01492     BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergySelEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergyEffCorr_FD)->GetBinContent(i) 
01493                                                                                      * BMbybeams[beamToUse]->GetMCHists().at(kNCTrueSelEfficiency_FD)->GetBinContent(i) );
01494     BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergySelEffCorr_FD)->SetBinContent(i,BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergyEffCorr_FD)->GetBinContent(i) 
01495                                                                                                * BMbybeams[beamToUse]->GetMCHists().at(kNCTrueSelEfficiency_FD)->GetBinContent(i) );
01496     }
01497     else{
01498     BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergySelEffCorr_FD)->SetBinContent(i,0);
01499     BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergySelEffCorr_FD)->SetBinContent(i,0);
01500     }
01501 
01502   }  
01503 }
01504 
01505 void NCExtrapolationBeamMatrix::
01506 DoUnoscTrueToRecoFD(int beamToUse){
01507   
01508   
01509   vector<double> tempCCMC(kNumEnergyBinsFar+1,0) ;
01510   vector<double> tempNCMC(kNumEnergyBinsFar+1,0) ;
01511   vector<double> tempCCData(kNumEnergyBinsFar+1,0) ;
01512   vector<double> tempNCData(kNumEnergyBinsFar+1,0) ;
01513 
01514   //need to use nominal for normalisation or Systematics cancel at true to reco stage
01515   const NCBeam::Info beamInfoLE = NCBeam::Info(BeamType::kL010z185i, NC::RunUtil::kRunI);
01516   int leNomBeam = fBMbybeams.find(beamInfoLE)->second ;
01517 
01518   //should be ok to use these here
01519   t2rCCRebin->Reset("ICE");
01520   t2rNCRebin->Reset("ICE");
01521   
01522   t2rCC = (TH2D*)CloneFast(BMbybeams[beamToUse]->Get2DHists()[kCCTrueRecoSig_FD]);
01523   t2rNC = (TH2D*)CloneFast(BMbybeams[beamToUse]->Get2DHists()[kNCTrueRecoSig_FD]);
01524   
01525   //see DoOscillations for the 4 step plan
01526   //step 1
01527   //unosc so no need for this step
01528   //step 2
01529 
01530   rebinRecoTrueToRecoRecoHist(t2rCC, t2rCCRebin); 
01531   rebinRecoTrueToRecoRecoHist(t2rNC, t2rNCRebin); 
01532 
01533   //step 3
01534   normaliseRecoToTrue(t2rCCRebin,BMbybeams[leNomBeam]->GetMCHists().at( kCCTrueEnergy_FD ) );
01535   normaliseRecoToTrue(t2rNCRebin,BMbybeams[leNomBeam]->GetMCHists().at( kNCTrueEnergy_FD ) );
01536 
01537   //step 4
01538   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){//true
01539     for(int j = 1; j < kNumEnergyBinsFar+1; ++j ){//reco
01540       // correct reco to true CC
01541       tempCCMC[j-1] += (BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergySelEffCorr_FD)->GetBinContent(i) * t2rCCRebin->GetBinContent(i,j) );
01542       tempCCData[j-1] += (BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergySelEffCorr_FD)->GetBinContent(i) * t2rCCRebin->GetBinContent(i,j));
01543       
01544       // correct reco to true NC
01545       tempNCMC[j-1] += (BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergySelEffCorr_FD)->GetBinContent(i) * t2rNCRebin->GetBinContent(i,j) );
01546       tempNCData[j-1] += (BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergySelEffCorr_FD)->GetBinContent(i) * t2rNCRebin->GetBinContent(i,j) );
01547     }
01548   }
01549   
01550   for(int i = 0; i < kNumEnergyBinsFar; ++i ){//reco
01551     BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPurCorr_FD)->SetBinContent(i+1,tempCCMC[i]);
01552     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyPurCorr_FD)->SetBinContent(i+1,tempCCData[i]);
01553     
01554     // correct reco to true NC
01555     BMbybeams[beamToUse]->GetMCHists().at(kNCRecoEnergyPurCorr_FD)->SetBinContent(i+1,tempNCMC[i]);
01556     BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergyPurCorr_FD)->SetBinContent(i+1,tempNCData[i]);
01557   }
01558 
01559   tempCCMC.clear() ;
01560   tempCCData.clear() ;
01561   tempNCMC.clear() ;
01562   tempNCData.clear() ;
01563   
01564   delete t2rCC;
01565   delete t2rNC;
01566   
01567   return;  
01568 }
01569 
01570 void NCExtrapolationBeamMatrix::
01571 DoUnoscPurityCorrectionFD(int beamToUse){
01572  
01573   for(int i = 0; i < kNumEnergyBinsFar+1; ++i ){
01574     //CC
01575     if(BMbybeams[beamToUse]->GetMCHists().at(kCCPurity_FD)->GetBinContent(i) > 0 ){
01576       BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPred_FD)->SetBinContent(i, BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPurCorr_FD)->GetBinContent(i)
01577                                                                                  / BMbybeams[beamToUse]->GetMCHists().at(kCCPurity_FD)->GetBinContent(i));
01578       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyPred_FD)->SetBinContent(i, BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyPurCorr_FD)->GetBinContent(i)
01579                                                                                            / BMbybeams[beamToUse]->GetMCHists().at(kCCPurity_FD)->GetBinContent(i));
01580     }
01581     else{
01582       BMbybeams[beamToUse]->GetMCHists().at(kCCRecoEnergyPred_FD)->SetBinContent(i, 0);
01583       BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyPred_FD)->SetBinContent(i, 0);
01584     }  
01585   
01586     //NC
01587     if(BMbybeams[beamToUse]->GetMCHists().at(kNCPurity_FD)->GetBinContent(i) > 0 ){
01588       BMbybeams[beamToUse]->GetMCHists().at(kNCRecoEnergyPred_FD)->SetBinContent(i, BMbybeams[beamToUse]->GetMCHists().at(kNCRecoEnergyPurCorr_FD)->GetBinContent(i)
01589                                                                                  / BMbybeams[beamToUse]->GetMCHists().at(kNCPurity_FD)->GetBinContent(i));
01590       BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergyPred_FD)->SetBinContent(i, BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergyPurCorr_FD)->GetBinContent(i)
01591                                                                                            / BMbybeams[beamToUse]->GetMCHists().at(kNCPurity_FD)->GetBinContent(i));
01592     }
01593     else{
01594       BMbybeams[beamToUse]->GetMCHists().at(kNCRecoEnergyPred_FD)->SetBinContent(i, 0);
01595       BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergyPred_FD)->SetBinContent(i, 0);
01596     }  
01597   
01598   }
01599   return;  
01600 }
01601 
01602 void NCExtrapolationBeamMatrix::
01603 DoOscillations(const NC::OscProb::OscPars* pars, int beamToUse){
01604 
01605   
01606   //means a vector of arrays!
01607   static vector<double*> survivalProbability;
01608   
01609   //means a basic vector of doubles!
01610   vector<double> OscBeamMatrixCC(kNumEnergyBinsFar+1, 0.);  
01611   vector<double> OscBeamMatrixNC(kNumEnergyBinsFar+1, 0.);  
01612 
01613   static bool first = true;
01614   if(first){
01615     first = false;
01616     
01617     fNominalBM.resize(BMbybeams[beamToUse]->Get2DOscHists().size());
01618     fOscBM.resize(BMbybeams[beamToUse]->Get2DOscHists().size());
01619     survivalProbability.resize(BMbybeams[beamToUse]->Get2DOscHists().size());    
01620     
01621     for(unsigned int h = 0; h < BMbybeams[beamToUse]->Get2DOscHists().size(); ++h){
01622       fNominalBM[h].resize(kNumEnergyBinsFar);
01623       fOscBM[h].resize(kNumEnergyBinsFar);
01624       survivalProbability[h] = new double[kNumTrueEnergyBins];
01625     }
01626   }
01627     
01628   
01629   static const NC::OscProb::OscPars* prevpars = 0;
01630   
01631   // Transition probability does not depend on reco energy - so we
01632   // can precalculate it out here.
01633   // Reuse the calculations from last time round if the oscillations
01634   // parameters haven't changed since then.
01635   if(!prevpars || !pars->IsEquiv(prevpars)){
01636     for(int h = 0; h < int(BMbybeams[beamToUse]->Get2DOscHists().size()); ++h){
01637       NCType::EOscMode oscType;
01638       NCType::EEventType interaction;
01639       
01640       switch(h){
01641       case kNCSig:
01642       case kCCBkg:
01643       case kNCWrongSignBkg:
01644         interaction = NCType::kNC;
01645         oscType     = NCType::kNuMuToNuMu;
01646         break;
01647       case kCCSig:
01648       case kNCBkg:
01649       case kCCWrongSignBkg:
01650         interaction = NCType::kCC;
01651         oscType     = NCType::kNuMuToNuMu;
01652         break;
01653       case kNCTau:
01654       case kCCTau:
01655         interaction = NCType::kCC;
01656         oscType     = NCType::kNuMuToNuTau;
01657         break;
01658       case kNCBeamNue:
01659       case kCCBeamNue:
01660         interaction = NCType::kCC;
01661         oscType     = NCType::kNuEToNuE;
01662         break;
01663       case kNCOscNue:
01664       case kCCOscNue:
01665         interaction = NCType::kCC;
01666         oscType     = NCType::kNuMuToNuE;
01667         break;
01668       default:
01669         MSG("NCExtrapolationBeamMatrix", Msg::kError) << "Interaction type or flavor is incorrect" << endl;
01670         return;
01671       }
01672 
01673       double* sph = survivalProbability[h];
01674       for(int j = 0; j < kNumTrueEnergyBins; ++j){
01675         sph[j] = pars->TransitionProbability(oscType,
01676                                              interaction,
01677                                              NCType::kBaseLineFar,
01678                                              (true_bins[j+1] + true_bins[j]) /2.0 );
01679       } // end for j
01680     } // end for h
01681   } // end if
01682   
01683   delete prevpars;
01684   // Sadly OscPars::Clone isn't labelled const for technical reasons.
01685   // Need to cast away constness so that we can call it.
01686   prevpars = const_cast<NC::OscProb::OscPars*>(pars)->Clone();
01687   
01688   
01689   //This is the original simple version
01690   /*
01691   for(int i = 0; i < kNumEnergyBinsFar; ++i ){
01692     for(int h = 0; h < int(BMbybeams[beamToUse]->Get2DOscHists().size()); ++h){
01693       fNominalBM[h][i] = 0.;
01694       fOscBM[h][i] = 0.;
01695       for(int j = 0; j < kNumTrueEnergyBins; ++j){
01696         //double xsecFitParam = mScaleNC.at(WhichFitParam(j+1)) ;
01697         double xsecFitParam = 1.0 ;
01698         double jbineq = (true_bins[j+1] + true_bins[j]) /2.0 ; //(j+1)*0.1 ;// make binwidth
01699         //if(jbineq > 120.0) jbineq = 120.0 ;
01700         //if(h == kNCSig ) MSG("NCExtrapolationBeamMatrix",Msg::kInfo) << "PURITAN BIN j " << j << " jbineq " << jbineq << " mScaleNC.at(WhichFitParam(jbineq)) " << mScaleNC.at(WhichFitParam(jbineq)) << endl;
01701         if(h == kNCSig || h == kNCWrongSignBkg || h == kCCBkg) xsecFitParam = mScaleNC.at(WhichFitParam(jbineq)) ;  
01702         const double tmpd = BMbybeams[beamToUse]->Get2DOscHists()[h]->GetCellContent( i+1, j+1 );
01703         fNominalBM[h][i] += tmpd; // *xsecFitParam;
01704         fOscBM[h][i] += survivalProbability[j][h]*tmpd*xsecFitParam;;
01705       }//end loop over true bins
01706     }//end loop over histograms
01707 
01708   
01709     //MSG("NCExtrapolationBeamMatrix",Msg::kInfo) << "BIN i " << i-1 
01710     //                                  << " fOscBM[NC][i] " << fOscBM[0][i] 
01711     //                                  << " fOscBM[CC][i] " << fOscBM[1][i]
01712     //                                  << endl ;    
01713   }
01714   */
01715   // And this is the optimized version
01716   const int nx = kNumEnergyBinsFar+2;
01717   for(unsigned int h = 0; h < BMbybeams[beamToUse]->Get2DOscHists().size(); ++h){
01718     const double* t2ra =  BMbybeams[beamToUse]->Get2DOscHists()[h]->fArray;
01719     vector<double>& nh = fNominalBM[h];
01720     vector<double>& oh = fOscBM[h];
01721     for(int i = 0; i < kNumEnergyBinsFar; ++i){
01722       double& nhi = nh[i];
01723       double& ohi = oh[i];
01724       nhi = 0;
01725       ohi = 0;
01726       const double* sph = survivalProbability[h];
01727       const int oset = i+1+nx;
01728       for(int j = 0; j < kNumTrueEnergyBins; ++j){
01729         double xsecFitParam = 1.0 ;
01730         double jbineq = (true_bins[j+1] + true_bins[j]) /2.0 ;
01731         //using the nd xsecweights on the Wrong sign bkg and the nominal NC should you wish to study MC only
01732         if(h == kNCSig || h == kNCWrongSignBkg) xsecFitParam = BMbybeams[beamToUse]->GetmScaleNC().at(WhichFitParam(jbineq)) ;  
01733         //if(h == kNCSig || h == kNCWrongSignBkg || h == kCCBkg) xsecFitParam = BMbybeams[beamToUse]->GetmScaleNC().at(WhichFitParam(jbineq)) ;  
01734         const double tmpd = t2ra[nx*j+oset];
01735         nhi += tmpd;
01736         ohi += sph[j]*tmpd*xsecFitParam;
01737       }//end loop over true bins 
01738     } // end for i
01739   }//end loop over histograms
01740 
01741 
01742   //need to truetoreco the BM prediction.
01743   //4 step plan 
01744   //1. multiply oscs into true  
01745   //2. rebin 2d histogram to be farBinning by farBinning
01746   //3. normalise new 2d histogram
01747   //4. true to reco
01748   
01749   vector<double> tempOscCC(kNumEnergyBinsFar+1,0) ;
01750   vector<double> tempOscNC(kNumEnergyBinsFar+1,0) ;
01751 
01752   //need to use nominal for normalisation or Systematics cancel at true to reco stage
01753   const NCBeam::Info beamInfoLE = NCBeam::Info(BeamType::kL010z185i, NC::RunUtil::kRunI);
01754   int leNomBeam = fBMbybeams.find(beamInfoLE)->second ;
01755   
01756   t2rCCRebin->Reset("ICE");
01757   t2rNCRebin->Reset("ICE");
01758 
01759   t2rCC = (TH2D*)CloneFast(BMbybeams[beamToUse]->Get2DHists()[kCCTrueRecoSig_FD]);
01760   t2rNC = (TH2D*)CloneFast(BMbybeams[beamToUse]->Get2DHists()[kNCTrueRecoSig_FD]);
01761   
01762   //step 1
01763   for(int i = 1; i < kNumTrueEnergyBins+1; ++i ){//true
01764     for(int j = 1; j < kNumEnergyBinsFar+1; ++j ){//reco
01765       const double spCC = survivalProbability[kCCSig][i-1];
01766       const double spNC = survivalProbability[kNCSig][i-1];
01767       t2rCC->SetBinContent(i,j, spCC * t2rCC->GetBinContent(i,j) );
01768       t2rNC->SetBinContent(i,j, spNC * t2rNC->GetBinContent(i,j) );
01769     }
01770   }
01771   //step 2
01772 
01773   rebinRecoTrueToRecoRecoHist(t2rCC, t2rCCRebin); 
01774   rebinRecoTrueToRecoRecoHist(t2rNC, t2rNCRebin); 
01775 
01776   //step 3
01777   normaliseRecoToTrue(t2rCCRebin,BMbybeams[leNomBeam]->GetMCHists().at( kCCTrueEnergy_FD ) );
01778   normaliseRecoToTrue(t2rNCRebin,BMbybeams[leNomBeam]->GetMCHists().at( kNCTrueEnergy_FD ) );
01779   
01780   //step 4
01781   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){//true
01782     for(int j = 1; j < kNumEnergyBinsFar+1; ++j ){//reco
01783       //OscBeamMatrixCC[j-1] += ( BMbybeams[beamToUse]->GetMCHists().at(kCCTrueEnergy_FD)->GetBinContent(i) * t2rCCRebin->GetBinContent(i,j)) ; 
01784       //OscBeamMatrixNC[j-1] += ( BMbybeams[beamToUse]->GetMCHists().at(kNCTrueEnergy_FD)->GetBinContent(i) * t2rNCRebin->GetBinContent(i,j)) ; 
01785       
01786       OscBeamMatrixCC[j-1] += ( BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataTrueEnergySelEffCorr_FD)->GetBinContent(i) * t2rCCRebin->GetBinContent(i,j)) ; 
01787       OscBeamMatrixNC[j-1] += ( BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataTrueEnergySelEffCorr_FD)->GetBinContent(i) * t2rNCRebin->GetBinContent(i,j)) ; 
01788       
01789     }
01790   }
01791 
01792   BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergySig_FD)->Reset("ICE");
01793   BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergyWrongSignBkg_FD)->Reset("ICE");
01794   
01795   BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergySig_FD)->Reset("ICE");
01796   BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyWrongSignBkg_FD)->Reset("ICE");
01797 
01798   
01799   for(int i = 0; i < kNumEnergyBinsFar; ++i ){
01800     
01801     // might want the MC as well at some point
01802     
01803     BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergySig_FD)->SetBinContent(i+1,OscBeamMatrixNC[i] );
01804     BMbybeams[beamToUse]->GetDataPredHists().at(kNCDataRecoEnergyWrongSignBkg_FD)->SetBinContent(i+1,fOscBM[kNCWrongSignBkg][i] );
01805     
01806     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergySig_FD)->SetBinContent(i+1,OscBeamMatrixCC[i]);
01807     BMbybeams[beamToUse]->GetDataPredHists().at(kCCDataRecoEnergyWrongSignBkg_FD)->SetBinContent(i+1,fOscBM[kCCWrongSignBkg][i]);
01808 
01809 
01810     const double totalMCNCBM_fd = OscBeamMatrixNC[i] //fOscBM[kNCSig][i] //OscBeamMatrixNC[i]      
01811       + fOscBM[kNCWrongSignBkg][i] 
01812       + fOscBM[kNCBkg][i]
01813       + fOscBM[kNCTau][i]
01814       + fOscBM[kNCBeamNue][i]
01815       + fOscBM[kNCOscNue][i];
01816     
01817     const double totalMCCCBM_fd = OscBeamMatrixCC[i] //fOscBM[kCCSig][i] //OscBeamMatrixCC[i]    
01818       + fOscBM[kCCWrongSignBkg][i] 
01819       + fOscBM[kCCBkg][i]
01820       + fOscBM[kCCTau][i]
01821       + fOscBM[kCCBeamNue][i]
01822       + fOscBM[kCCOscNue][i];
01823     
01824     
01825     //if(fDoExtrapolation){
01826     BMbybeams[beamToUse]->GetFitHists()[kNCSig]->SetBinContent(i+1,totalMCNCBM_fd);
01827     BMbybeams[beamToUse]->GetFitHists()[kCCSig]->SetBinContent(i+1,totalMCCCBM_fd);
01828     //}
01829   }
01830 
01831   delete t2rNC ;
01832   delete t2rCC ;
01833   
01834   OscBeamMatrixNC.clear();
01835   OscBeamMatrixCC.clear();
01836 }
01837 //this will need to come AFTER the addevent loops
01838 //don't forget to check what is scaled to what... 
01839 void NCExtrapolationBeamMatrix::
01840 doNDXsectionFit(int PrintLevel, NCBeam* beam_ndLE, int bemequ){
01841 
01842   for (Int_t i=0; i<4; i++) {
01843     m0ScaleNC.at(i) = 1.0;
01844     m0ScaleNCErr.at(i) = 0.005;
01845     mScaleNC.at(i) = 1.0;
01846     mScaleNCErr.at(i) = 0.005;
01847     mScaleNeg[i] = 0.0 ;
01848     mScalePos[i] = 0.0 ;
01849     corr[i] = 0.0 ;
01850   }
01851   
01852   // no need to do fit for all energy types LE come first
01853   if(beam_ndLE->GetBeamType() != BeamType::kL010z185i){ 
01854     for(int i = 0 ; i < 4; i++)
01855       BMbybeams[bemequ]->GetmScaleNC().at(i) = mScaleNC.at(i);
01856     return;
01857   }
01858   //will need attending to need to when using more beams copy data into systbeams
01859   bool doSyst = true ;
01860   if(bemequ == 0) doSyst = false ;
01861 
01862   // the way the beams vector is constructed mean this will work
01863   int diff = beamsNear.size()/3 ;
01864   MSG("NCExtrapolationBeamMatrix",Msg::kDebug) << "LE beamsNear.size() " << beamsNear.size() << " bemequ " << bemequ << " diff " << diff <<endl;
01865   NCBeam* beam_ndME = beamsNear.at(bemequ+diff);
01866   NCBeam* beam_ndHE = beamsNear.at(bemequ+(2*diff));
01867  
01868   //might need to find a better place for this
01869   bmFit->beamsFit.clear();
01870   bmFit->beamsFit.push_back(beam_ndHE);
01871   bmFit->beamsFit.push_back(beam_ndME);
01872   bmFit->beamsFit.push_back(beam_ndLE);
01873 
01874   // may want to pass this in as part of the registry
01875   // fills the histogrmas and calsluates the scales needed. 
01876   ScaleBeamsToSameNumberOfEvents(kNCDataHE, doSyst);
01877 
01878   for(UInt_t i = 0; i < (bmFit->beamsFit).size(); ++i){
01879     //maybe some check on nd only here    
01880     int data = -1 ;
01881     int mc = -1;
01882     int beamindex = -1;
01883     
01884     if( bmFit->beamsFit.at(i)->GetBeamType() == BeamType::kL010z185i){
01885       data = kNCDataLE; 
01886       mc =  kNCMCLE;  
01887       MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "acquired LE beamtype data " << data << " mc " << mc <<endl;
01888       
01889     }
01890     
01891     if( bmFit->beamsFit.at(i)->GetBeamType() == BeamType::kL100z200i){
01892       data = kNCDataME; 
01893       mc =  kNCMCME;     
01894       MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "acquired ME beamtype data " << data << " mc " << mc << endl;
01895     }
01896     
01897     if( bmFit->beamsFit.at(i)->GetBeamType() == BeamType::kL250z200i){
01898       data = kNCDataHE; 
01899       mc =  kNCMCHE; 
01900       MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "acquired HE beamtype data " << data << " mc " << mc << endl;
01901     }
01902     beamindex = (mc-1)/2 ;   
01903     
01904     //scaling actually done here
01905     ND_XSectionFit.at(mc)->Scale(bmFit->mInputScale.at(mc));
01906     ND_XSectionFit.at(data)->Scale(bmFit->mInputScale.at(data));
01907     ND_XSectionFitRew.at(data)->Scale(bmFit->mInputScale.at(data));
01908     for(UInt_t ipar = 0 ; ipar < ND_XsecByParams.at(0).size() ; ipar++){
01909       ND_XsecByParams[beamindex][ipar]->Scale(bmFit->mInputScale.at(mc));
01910     }
01911   }
01912       
01913   //do the fit
01914   Fit(PrintLevel);
01915   for(int i = 0 ; i < 4; i++)
01916     BMbybeams[bemequ]->SetmScaleNCparam(i,mScaleNC.at(i));
01917   
01918   MSG("NCExtrapolationBeamMatrix",Msg::kInfo) 
01919     << "Fitted Parameters: 0-4 " << BMbybeams[bemequ]->GetmScaleNC().at(0)  
01920     << " 4-8 " << BMbybeams[bemequ]->GetmScaleNC().at(1)  
01921     << " 8-15 " << BMbybeams[bemequ]->GetmScaleNC().at(2) 
01922     << " over 15 " << BMbybeams[bemequ]->GetmScaleNC().at(3) 
01923     << " size " << BMbybeams[bemequ]->GetmScaleNC().size() 
01924     << endl;
01925   
01926 }
01927 //adapted from T Raufer
01928 void NCExtrapolationBeamMatrix::
01929 Fit(int PrintLevel){
01930 
01931   Double_t arglist[10];
01932   Int_t    ierr;
01933 
01934   TMinuit* gMinuit = new TMinuit(4);
01935 
01936   gMinuit->SetFCN(LogLikelihoodFunc); // Likelihood fit
01937 
01938   arglist[0] = PrintLevel;
01939   gMinuit->mnexcm("SET PRInt",arglist,1,ierr);
01940   if ( PrintLevel<-1 ) 
01941     gMinuit->mnexcm("SET NOWarning",arglist,0,ierr);
01942 
01943   arglist[0] = 1; // added a factor 2 to the likelihood function
01944   gMinuit->mnexcm("SET ERRor",arglist,1,ierr);
01945   
01946   arglist[0] = 1; // minimization strategy
01947   gMinuit->mnexcm("SET STR",arglist,1,ierr);
01948   
01949   // Set starting values
01950   Double_t par[4];
01951   for (Int_t i=0; i<4; i++)
01952     par[i] = m0ScaleNC.at(i);
01953 
01954   // set starting error
01955   Double_t step[4];
01956   for (Int_t i=0; i<4; i++)
01957     step[i] = m0ScaleNCErr.at(i);
01958 
01959   // define parameters
01960   for (Int_t i=0; i<4; i++) {
01961     char* name = Form("scaleNC_%i",i);
01962     //gMinuit->DefineParameter(i,name, par[i], step[i],0., 0.); // unbounded
01963     gMinuit->DefineParameter(i,name, par[i], step[i],0., 5.0); // bounded
01964   }
01965 
01966   MSG("NCExtrapolationBeamMatrix",Msg::kInfo) << "Doing BOUNDED FIT 0 to 5 " << endl;
01967   // start restricted fit first
01968  
01969   gMinuit->FixParameter(0);
01970   gMinuit->FixParameter(1);
01971   gMinuit->FixParameter(2);
01972 
01973   // do a scan
01974  //  arglist[0] = 5; // scan parameter no 4+1
01975 //   arglist[1] = 40;
01976 //   arglist[2] = 0.8;
01977 //   arglist[3] = 1.0;
01978 //   gMinuit->mnexcm("SCAn",arglist,4,ierr);
01979 //   TCanvas *cnew = new TCanvas("cnew","cnew");
01980 //   TGraph *gr = (TGraph*)gMinuit->GetPlot();
01981 //   cnew->cd();
01982 //   gr->Draw("ap");
01983   
01984   gMinuit->Migrad();
01985 
01986   gMinuit->Release(2);  
01987   gMinuit->Migrad();
01988 
01989   gMinuit->Release(1);  
01990   gMinuit->Migrad();
01991 
01992   gMinuit->Release(0);  
01993   gMinuit->Migrad();
01994 
01995   // do MINOS error analysis
01996   gMinuit->mnmnos();
01997 
01998   // check convergence (still to do)
01999   TString convergence = gMinuit->fCstatu; 
02000   MSG("NCExtrapolationBeamMatrix",Msg::kInfo) << "Convergence status: "
02001                             << convergence << endl;
02002 
02003   // get result
02004   for (Int_t i=0; i<4; i++)
02005     gMinuit->GetParameter( i, mScaleNC.at(i),  mScaleNCErr.at(i) );
02006 
02007   //Double_t mScaleNeg[4]; // positive and negative errors 
02008                                           // from MINOS
02009   //Double_t mScalePos[4];
02010   //Double_t corr[4];
02011   // get proper asymmetric errors from MINOS fit
02012   for (Int_t i=0; i<4; i++)
02013     gMinuit->mnerrs(i,mScalePos[i], mScaleNeg[i],
02014                     mScaleNCErr[i],
02015                     corr[i] );
02016 
02017   // plot result  
02018   
02019   if ( PrintLevel >-2 ) {
02020 
02021     Double_t LL;
02022     Double_t pars[4];
02023     Int_t    npar = 4;
02024 
02025     for (Int_t i=0; i<4; i++)
02026       pars[i] = mScaleNC.at(i);
02027     //should return what you put in
02028     LogLikelihoodFunc(npar, pars, LL, pars, 0);
02029 
02030 
02031     MSG("NCExtrapolationBeamMatrix",Msg::kInfo) 
02032       << "The final likelihood is: LL=" << setprecision(10) << LL << endl;
02033     MSG("NCExtrapolationBeamMatrix",Msg::kInfo) 
02034       << "Fitted Parameters: 0-4 " << mScaleNC.at(0)  
02035       << " 4-8 " << mScaleNC.at(1)  
02036       << " 8-15 " << mScaleNC.at(2) 
02037       << " over 15 " << mScaleNC.at(3) << endl;
02038 
02039     // write some stuff to a log file
02040     *logFile << "Fit results:" << endl;   
02041     logFile->setf(ios::fixed);
02042     logFile->precision(5);
02043     for (Int_t i=0; i<4; i++) 
02044       *logFile << "Par " << i << ": " << mScaleNC[i] << " +"
02045                << mScalePos[i] << " " << mScaleNeg[i] << " +/- "
02046                << mScaleNCErr.at(i) << ", Corr: " << corr[i] << endl;
02047   
02048     *logFile << "Convergence Status: " << convergence << endl
02049              << "Final Likelihood LL=" << LL << endl;
02050       // << "Written histograms to " << histofile->GetName() << endl;
02051     logFile->unsetf(ios::fixed);
02052     
02053     /*
02054     //not using yet...
02055     // get the number of d.o.f. from chi2 fit
02056     Int_t dof = 0;
02057     if (fUseChi2Function) {
02058       for (UInt_t i = 0; i<fDataFraction.size(); ++i ) {
02059         Double_t chi2 = -1;
02060         Int_t ndf   -1;
02061         Int_t igood = 0;
02062         HistEvisNCd.at(i)->Chi2TestX(HistEvisNCrew.at(i),chi2,ndf,igood, 
02063                                      "UUCHI2");
02064         dof += ndf;
02065         MSG("NCExtrapolationRS",Msg::kDebug) << "Ndf for beam " << i << ": " 
02066                                              << ndf << endl; 
02067         if (igood != 0)
02068           MSG("NCExtrapolationRS",Msg::kWarning) << "Chi2 igood parameter" 
02069                                                  <<" is non-zer: "
02070                                        << igood << endl;
02071       }
02072     }
02073     */
02074 
02075     //This bit of code may be useful if one wants to write out a result tree
02076 
02077     // write same info to fit tree
02078     //    fFitRes.likelihood = LL;
02079     //     for (Int_t i=0; i<4; i++) {
02080     //       fFitRes.parNo = i;
02081     //       fFitRes.inputScale = mInputScale[i];
02082     //       fFitRes.par = (Float_t) mScaleNC[i];
02083     //       fFitRes.err = (Float_t) mScaleNCErr[i];
02084     //       fFitRes.errPos = (Float_t) mScalePos[i];
02085     //       fFitRes.errNeg = (Float_t) mScaleNeg[i];
02086     //       fFitRes.dof = dof;
02087     //       fFitResTree->Fill();    
02088     //     }
02089   }  
02090 
02091   delete gMinuit;
02092 }
02093 //pars is fitpars here
02094 void NCExtrapolationBeamMatrix::
02095 FillNDHistsForXSectionFit(NCBeam* beam_nd,
02096                           NCType::EEventType nccc,
02097                           bool doSyst){//,
02098                           //                      NC::SystPars systPars){
02099 
02100   int data = -1; 
02101   int mc = -1;
02102   int beamindex = -1;
02103  
02104   if( beam_nd->GetBeamType() == BeamType::kL010z185i){
02105     data = kNCDataLE; 
02106     mc =  kNCMCLE;     
02107   }
02108  
02109   if( beam_nd->GetBeamType() == BeamType::kL100z200i){
02110     data = kNCDataME; 
02111     mc =  kNCMCME;     
02112   }
02113   
02114   if( beam_nd->GetBeamType() == BeamType::kL250z200i){
02115     data = kNCDataHE; 
02116     mc =  kNCMCHE; 
02117   }
02118   beamindex = (mc-1)/2;
02119   //no cc at the moment. May not need it.
02120 
02121   ND_XSectionFit[data]->Reset("ICE");
02122   ND_XSectionFitRew[data]->Reset("ICE");
02123   for(UInt_t ipar = 0 ; ipar < ND_XsecByParams.at(0).size() ; ipar++)
02124     ND_XsecByParams[beamindex][ipar]->Reset("ICE");
02125   
02126   ND_XSectionFit[mc]->Reset("ICE");
02127 
02128   for(int b  = 0; b < beam_nd->GetNumberEnergyBins(nccc); ++b){
02129     NCEnergyBin* bin = beam_nd->GetEnergyBin(b, nccc);
02130 
02131     const int dataSize       = bin->GetDataVectorSize();
02132     const int mcSize         = bin->GetMCSignalVectorSize();
02133     const int mcSize_bkg     = bin->GetMCBackgroundVectorSize();
02134     const int mcSize_tau     = bin->GetMCNuTauVectorSize();
02135     const int mcSize_beamnue = bin->GetMCBeamNuEVectorSize();
02136     const int mcSize_oscnue  = bin->GetMCOscNuEVectorSize();
02137     
02138     MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "data " << data << " data size " << dataSize  <<" mc  " << mc << " mc size" << mcSize << endl;
02139      
02140 
02141     // The variables that get filled with event information
02142     double trueEnergy    = 0;
02143     double recoShowerE   = 0;
02144     double recoMuonE     = 0;
02145     double energy        = 0;
02146     double weight        = 0;
02147     int flavor = 0;
02148     for(int e = 0; e < dataSize; ++e){
02149       bin->GetDataInformation(energy, weight, e);
02150       FillHistogramSmoothed(ND_XSectionFit[data], energy, weight);
02151       FillHistogramSmoothed(ND_XSectionFitRew[data], energy, weight);
02152     }
02153     //------------------------------
02154     // numu
02155     for(int e = 0; e < mcSize; ++e){ 
02156       bin->GetMCInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
02157       if(nccc == NCType::kNC) recoMuonE = 0;
02158       FillHistogramSmoothed(ND_XsecByParams[beamindex][WhichFitParam(trueEnergy)], recoShowerE + recoMuonE, weight);
02159     }
02160 
02161     for(int e = 0; e < mcSize_bkg; ++e){
02162       bin->GetMCBackgroundInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
02163       if(nccc == NCType::kNC) recoMuonE = 0;
02164       FillHistogramSmoothed(ND_XsecByParams[beamindex][4], recoShowerE + recoMuonE, weight) ;
02165  }
02166 
02167     //------------------------------
02168     // nutau
02169     for(int e = 0; e < mcSize_tau; ++e){
02170       bin->GetMCNuTauInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
02171       if(nccc == NCType::kNC) recoMuonE = 0;
02172       FillHistogramSmoothed(ND_XsecByParams[beamindex][4], recoShowerE + recoMuonE, weight) ;
02173     }
02174 
02175     //------------------------------
02176     // beam nue
02177     for(int e = 0; e < mcSize_beamnue; ++e){
02178       bin->GetMCBeamNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
02179       if(nccc == NCType::kNC) recoMuonE = 0;
02180       FillHistogramSmoothed(ND_XsecByParams[beamindex][4], recoShowerE + recoMuonE, weight) ;
02181     }
02182 
02183     //------------------------------
02184     // oscillated nue
02185     for(int e = 0; e < mcSize_oscnue; ++e){
02186       bin->GetMCOscNuEInformation(trueEnergy, recoShowerE, recoMuonE, weight, flavor, e);
02187       if(nccc == NCType::kNC) recoMuonE = 0;
02188       FillHistogramSmoothed(ND_XsecByParams[beamindex][4], recoShowerE + recoMuonE, weight) ;
02189     }
02190   } // end for b
02191 
02192   
02193   for(int i = 1 ; i < kNumEnergyBinsFar+1 ; i++){
02194     double binsum = 0.0;
02195     for(UInt_t ipar = 0 ; ipar < ND_XsecByParams.at(0).size() ; ipar++){
02196       binsum += ND_XsecByParams[beamindex][ipar]->GetBinContent(i);
02197     }
02198     
02199     ND_XSectionFit[mc]->SetBinContent(i,binsum);
02200     
02201     // this is a real beam and therefore has data in it. Copy to relevant dataNDHist
02202     if(!doSyst){  
02203 
02204       if(data == kNCDataLE)
02205         dataNDhistLE->SetBinContent(i,ND_XSectionFit[data]->GetBinContent(i));
02206       
02207       if(data == kNCDataME) 
02208         dataNDhistME->SetBinContent(i,ND_XSectionFit[data]->GetBinContent(i));
02209       
02210       if(data == kNCDataHE) 
02211         dataNDhistHE->SetBinContent(i,ND_XSectionFit[data]->GetBinContent(i));
02212       
02213     }
02214       
02215     //this is a systematically shifted beam and has no data in it. Copy from real beam
02216     if(doSyst){ 
02217       if(data == kNCDataLE){
02218         ND_XSectionFit[data]->SetBinContent(i,dataNDhistLE->GetBinContent(i));
02219         ND_XSectionFitRew[data]->SetBinContent(i,dataNDhistLE->GetBinContent(i));
02220           
02221         }      
02222         if(data == kNCDataME){ 
02223           ND_XSectionFit[data]->SetBinContent(i,dataNDhistME->GetBinContent(i));
02224           ND_XSectionFitRew[data]->SetBinContent(i,dataNDhistME->GetBinContent(i));
02225         }
02226         if(data == kNCDataHE){ 
02227           ND_XSectionFit[data]->SetBinContent(i,dataNDhistHE->GetBinContent(i));
02228           ND_XSectionFitRew[data]->SetBinContent(i,dataNDhistHE->GetBinContent(i));
02229         }
02230     } 
02231   }
02232 }
02233 int NCExtrapolationBeamMatrix::
02234 WhichFitParam(double trueEnergy){
02235   if(trueEnergy <=4.0) return 0;
02236   else if(trueEnergy <= 8.0) return 1;
02237   else if(trueEnergy <= 15.0) return 2;
02238   else if(trueEnergy <= 120.0) return 3;
02239   // will need to put errors in at some point
02240   else return 4;
02241 } 
02242 
02243 
02244 //code ripped straight from NCExtrapolationRS.cxx
02245 //inputs are minuit things I guess
02246 //
02247 void NCExtrapolationBeamMatrix::
02248 LogLikelihoodFunc(Int_t &npar, 
02249                   Double_t *gin, 
02250                   Double_t &f, 
02251                   Double_t *pars, 
02252                   Int_t iflag)
02253   {  
02254   iflag++; // NOT USED FOR ANYTHING, JUST TO QUIET THE COMPILER
02255   if (0)  cout << gin << npar << endl; 
02256 
02257   f = 0;
02258 
02259 //   //  cout << "Parameter 5: " << pars[4]; 
02260   
02261 //   // cross section reweighting MC using neugen parameters
02262 //   //  sFit->Reweight(ma_qe,ma_res,kno112,kno122,kno113,kno123,false);
02263   
02264 // reset reweighted histograms
02265   for(UInt_t i = 1; i < bmFit->ND_XSectionFitRew.size(); i+=2){
02266     bmFit->ND_XSectionFitRew.at(i)->Reset("ICE");
02267   }
02268   
02269   // now fill Reweighted Histograms
02270   // do something faster than histogram filling
02271   
02272   for(UInt_t i = 0; i < (bmFit->beamsFit).size(); ++i){
02273     //maybe some check on nd only here    
02274     int data = -1 ;
02275     int mc = -1;
02276     int beamindex = -1;
02277   
02278     if( bmFit->beamsFit.at(i)->GetBeamType() == BeamType::kL010z185i){
02279       data = kNCDataLE; 
02280       mc =  kNCMCLE;  
02281       MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "acquired LE beamtype data " << data << " mc " << mc << endl;
02282     
02283     }
02284     
02285     if( bmFit->beamsFit.at(i)->GetBeamType() == BeamType::kL100z200i){
02286       data = kNCDataME; 
02287       mc =  kNCMCME;     
02288       MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "acquired ME beamtype data " << data << " mc " << mc << endl;
02289     }
02290     
02291     if( bmFit->beamsFit.at(i)->GetBeamType() == BeamType::kL250z200i){
02292       data = kNCDataHE; 
02293       mc =  kNCMCHE; 
02294       MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "acquired HE beamtype data " << data << " mc " << mc << endl;
02295     }
02296     beamindex = (mc-1)/2 ;   
02297     
02298     // loop over the 4 energy ranges in the true NC selected spectrum
02299     for(int ibin = 1 ; ibin < kNumEnergyBinsFar+1 ; ibin++){
02300       double binsum = 0.0;
02301       for(UInt_t ipar = 0 ; ipar <  bmFit->ND_XsecByParams.at(0).size()-1 ; ipar++){
02302         binsum +=  bmFit->ND_XsecByParams[beamindex][ipar]->GetBinContent(ibin) * pars[ipar];
02303       }
02304       // add in the contribution from all the backgrounds
02305       binsum +=  bmFit->ND_XsecByParams[beamindex][bmFit->ND_XsecByParams.at(0).size()-1]->GetBinContent(ibin);
02306       bmFit->ND_XSectionFitRew.at(mc)->SetBinContent(ibin,binsum);
02307     }
02308   
02309     
02310     // now calculate the LL contributions (including under and overflows
02311     
02312     // fitting with Maximum Likelihood will revisit this if I need to
02313     //if (!sFit->fUseChi2Function) { 
02314     MAXMSG("NCExtrapolationBeamMatrix",Msg::kInfo,1) << "Using LL test..." << endl;
02315     
02316     // this is for fitting without the bottom two bins; again revisit if I need to...
02317     //if (sFit->fCutLowBins) 
02318     //NCStartBin +=3; // cut out bins 0-2
02319     // get the index right on these things...
02320     int startbin = 1;
02321     int endbin =  bmFit->ND_XSectionFitRew.at(mc)->GetNbinsX()+1 ;
02322     for(int ibin = startbin ; ibin < endbin; ibin++){
02323       if(bmFit->ND_XSectionFitRew.at(mc)->GetBinContent(ibin) < 0 ){
02324         MSG("NCExtrapolationBeamMatrix",Msg::kInfo) << "bmFit->ND_XSectionFitRew.at(mc)->GetBinContent("<<ibin<<") Gone Negative " 
02325                                                     << bmFit->ND_XSectionFitRew.at(mc)->GetBinContent(ibin) << " setting to 1.0 " << endl;
02326       }
02327       f -= bmFit->ND_XSectionFitRew.at(data)->GetBinContent(ibin)
02328         * log(bmFit->ND_XSectionFitRew.at(mc)->GetBinContent(ibin));
02329     }
02330     f +=  bmFit->ND_XSectionFitRew.at(mc)->Integral(startbin,endbin); 
02331   }
02332 //    else {
02333 // fitting with a Chi2 function
02334 //  MAXMSG("NCExtrapolationRS",Msg::kInfo,1) << "Using Chi2 test..." << endl;
02335 //  f += sFit->GetChiSquare(0,i); // add chi2 for NC histos  
02336 //}
02337 // loop over fBeams.size()
02338   
02339   f *= 2; // include factor 2 in order to keep error definitions 
02340   // as in a chi2 function
02341   // this also means, the UP value for errors is 1 (not 0.5)
02342   //reseting the ones that need resetting
02343   for(UInt_t i = 1; i < bmFit->ND_XSectionFitRew.size(); i+=2){
02344     bmFit->ND_XSectionFitRew.at(i)->Reset("ICE");
02345   }
02346 
02347   return;
02348   }
02349 void NCExtrapolationBeamMatrix::
02350 ScaleBeamsToSameNumberOfEvents(int beamType, bool doSyst){
02351 
02352   //need to scale all histograms to the same number of events. For now scale them to the HE MC stats? Its what Tobi did.
02353   // I guess it has the lowest stats when you get the full set.
02354 
02355   int other = beamType+1 ;
02356   if(beamType%1 == 0) other = beamType-1 ;
02357 
02358   MSG("NCExtrapolationBeamMatrix", Msg::kInfo) <<  "Scaling beams to beamType: " << beamType << " " <<  other <<endl;
02359  
02360  // set pars to 1.0 to get the unscaled histograms
02361  //double pars[4] = {1.0,1.0,1.0,1.0};
02362   for(UInt_t i = 0; i < (beamsFit).size(); ++i){
02363     FillNDHistsForXSectionFit(beamsFit.at(i), NCType::kNC, doSyst);
02364   }
02365   
02366   //can't reweight them all to the same histogram. loses POT weighting for a start.
02367   //need to reweight each data mc pair to the same. in this case to data exposure
02368  
02369  for(UInt_t i = 0; i <  ND_XSectionFit.size() ; i+=2){
02370 
02371    if(ND_XSectionFit.at(i)->Integral() > 0){
02372      double scale =  ND_XSectionFit.at(beamType)->Integral() / ND_XSectionFit.at(i)->Integral();
02373      //scale *= 0.001 ;
02374      mInputScale.push_back(scale);
02375      mInputScale.push_back(scale);
02376    }
02377    else{  
02378      mInputScale.push_back(0);
02379      mInputScale.push_back(0);
02380    }
02381 
02382 }
02383  
02384  MSG("NCExtrapolationBeamMatrix", Msg::kInfo) << "Scaling Beam Parameters  "
02385                                               <<  "mInputScale 0: " << mInputScale.at(0)
02386                                               <<  " mInputScale 1: " << mInputScale.at(1)
02387                                               <<  " mInputScale 2: " << mInputScale.at(2)
02388                                               <<  " mInputScale 3: " << mInputScale.at(3)
02389                                               <<  " mInputScale 4: " << mInputScale.at(4)
02390                                               <<  " mInputScale 5: " << mInputScale.at(5)
02391                                               <<  " mInputScale 6: " << mInputScale.at(6)
02392                                               <<  " mInputScale 7: " << mInputScale.at(7)
02393                                               <<  " mInputScale 8: " << mInputScale.at(8)
02394                                               <<  " mInputScale 9: " << mInputScale.at(9)
02395                                               <<  " mInputScale 10: " << mInputScale.at(10)
02396                                               <<  " mInputScale 11: " << mInputScale.at(11)
02397                                               << endl ;
02398 }
02399 void NCExtrapolationBeamMatrix::
02400 rebinRecoTrueToRecoRecoHist(TH2D *t2r, TH2D *t2rRebin){
02401 
02402   for(int y = 1; y < kNumEnergyBinsFar+1; ++y ){
02403     int x = 1;
02404     double trueAdd = 0.0 ;
02405     for(UInt_t curx = 1 ; curx <  kNumTrueEnergyBins+1 ; curx++){
02406       if(true_bins[curx] < kEnergyBinsFar[x]){
02407         trueAdd += t2r->GetBinContent(curx,y); 
02408       }      
02409       else{
02410         trueAdd += t2r->GetBinContent(curx,y); 
02411         t2rRebin->SetBinContent(x,y,trueAdd);
02412         trueAdd = 0.;
02413         x++;    
02414       }
02415     }
02416   }
02417 }
02418 void NCExtrapolationBeamMatrix::
02419 normaliseRecoToTrue(TH2D *t2rRebin, TH1D *norm){
02420 
02421   for(int i = 1; i < kNumEnergyBinsFar+1; ++i ){//reco
02422     for(int j = 1; j < kNumEnergyBinsFar+1; ++j ){//reco
02423       double trueEnergyBinValue = norm->GetBinContent(i) ;
02424       if( trueEnergyBinValue > 0) t2rRebin->SetBinContent(i,j, t2rRebin->GetBinContent(i,j)/trueEnergyBinValue );
02425       else t2rRebin->SetBinContent(i,j,0);
02426       
02427     }
02428   }
02429 }

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