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

NuCrossSectionFitter.cxx

Go to the documentation of this file.
00001 
00002 // $Id: NuCrossSectionFitter.cxx,v 1.10 2008/05/02 19:36:16 evans Exp $
00003 //
00004 // Combined numu & numubar extrapolation by cross-section fitting
00005 //
00006 // Justin Evans
00007 // j.evans2@physics.ox.ac.uk
00008 //
00009 //
00010 // $Log: NuCrossSectionFitter.cxx,v $
00011 // Revision 1.10  2008/05/02 19:36:16  evans
00012 // Correcting a comment.
00013 //
00014 // Revision 1.9  2008/01/11 00:12:52  hartnell
00015 //
00016 // Have to be careful not to confuse hist->Reset() with hist->Clear().
00017 //
00018 // Change comment from:
00019 //
00020 // //Clear recoE histograms
00021 //
00022 // to
00023 //
00024 // //Reset recoE histograms (removes bin contents and errors)
00025 //
00026 // to reflect what is done. Just a little paranoia...
00027 //
00028 // Revision 1.8  2008/01/10 17:58:33  evans
00029 // Adding IsGoodMajorityCurvature to the list of selection cuts.
00030 //
00031 // Revision 1.7  2007/12/21 17:41:18  evans
00032 // Debugging and creating a FD output file for the XFit CPT analysis.
00033 //
00034 // Revision 1.6  2007/12/20 19:12:46  evans
00035 // Enabling the XFit analysis to receive its input data as a
00036 // reconstructed histogram (as well as a NuDST: you can do either). This
00037 // means it can fit the output of the Fluctuator in either the ND or FD
00038 // (or both).
00039 //
00040 // Revision 1.5  2007/12/07 14:53:15  evans
00041 // Adding protection against uninitialised variables found by Robert
00042 // Hatcher when compiling with gcc+optimization.
00043 //
00044 // Revision 1.4  2007/12/04 12:03:07  evans
00045 // Removing double construnction of NuSystematic object.
00046 //
00047 // Revision 1.3  2007/12/03 17:10:19  evans
00048 // Adding code to do a numu->numubar transition analysis withtruth
00049 // fitting. Also added the ability to do a stystematics study with the
00050 // NuSystematic class.
00051 //
00052 // Revision 1.2  2007/11/15 13:58:15  evans
00053 // Removing three unused parameters.
00054 //
00055 // Revision 1.1  2007/11/15 13:45:25  evans
00056 // The class to do the NDFit part of my cross-section fitting extrapolation.
00057 //
00058 //
00060 
00061 #include "Minuit2/MinuitParameter.h"
00062 #include "TFile.h"
00063 #include "TH1D.h"
00064 #include "TH1F.h"
00065 #include "TMinuit.h"
00066 
00067 #include "MessageService/MsgService.h"
00068 #include "NtupleUtils/NuCrossSectionFitter.h"
00069 #include "NtupleUtils/NuCuts.h"
00070 #include "NtupleUtils/NuSystematic.h"
00071 #include "NtupleUtils/NuTreeWrapper.h"
00072 #include "NtupleUtils/NuXMLConfig.h"
00073 
00074 ClassImp(NuCrossSectionFitter)
00075 
00076 CVSID("$Id: NuCrossSectionFitter.cxx,v 1.10 2008/05/02 19:36:16 evans Exp $");
00077 
00078 using namespace NuXSecFit;
00079 
00080 using std::string;
00081 using std::vector;
00082 using ROOT::Minuit2::MinuitParameter;
00083 using ROOT::Minuit2::MnUserParameterState;
00084 
00085 //____________________________________________________________________72
00086 NuCrossSectionFitter::NuCrossSectionFitter()
00087   : fndDataPoT(0.0),
00088     fndMCPoT(0.0)
00089 {
00090 //   fanaVersion = NuCuts::kCC0250Std;
00091   fanaVersion = NuCuts::kJJE1;
00092 
00093   fnuSystematic = new NuSystematic();
00094 
00095   fhNDMCRecoENuMuCC = 0;
00096   fhNDMCRecoENuMuBarCC = 0;
00097   fhNDDataRecoENuMuCC = 0;
00098   fhNDDataRecoENuMuBarCC = 0;
00099   fhNDRawMCTrueECCNuMu = 0;
00100   fhNDRawMCTrueECCNuMuBar = 0;
00101   fhNDRawMCRecoECCNuMu = 0;
00102   fhNDRawMCRecoECCNuMuBar = 0;
00103 
00104   fhNDNuMuCCDataFromFile = 0;
00105   fhNDNuMuBarCCDataFromFile = 0;
00106 
00107   fOutputFile = 0;
00108 
00109   ftNDDataTree = 0;
00110   ftNDMCTree = 0;
00111 
00112   fFitter = new TFitterMinuit();
00113   fFitter->CreateMinimizer();
00114   fFitter->SetMinuitFCN(this);
00115   
00116   //ND fake parameters (set to 1.0)
00117   fvNDFakeTrueENuMuCCBins.push_back(30.0);
00118   fvNDFakeTrueENuMuBarCCBins.push_back(30.0);
00119   for (Int_t counter=0; counter<10; ++counter){
00120     fvfakepars.push_back(1.0);
00121   }
00122 }
00123 
00124 //____________________________________________________________________72
00125 NuCrossSectionFitter::NuCrossSectionFitter(const NuXMLConfig& xmlConfig)
00126   : fndDataPoT(0.0),
00127     fndMCPoT(0.0)
00128 {
00129 //   fanaVersion = NuCuts::kCC0250Std;
00130   fanaVersion = NuCuts::kJJE1;
00131 
00132   fnuSystematic = new NuSystematic(xmlConfig);
00133 
00134   fhNDMCRecoENuMuCC = 0;
00135   fhNDMCRecoENuMuBarCC = 0;
00136   fhNDDataRecoENuMuCC = 0;
00137   fhNDDataRecoENuMuBarCC = 0;
00138   fhNDRawMCTrueECCNuMu = 0;
00139   fhNDRawMCTrueECCNuMuBar = 0;
00140   fhNDRawMCRecoECCNuMu = 0;
00141   fhNDRawMCRecoECCNuMuBar = 0;
00142 
00143   fhNDNuMuCCDataFromFile = 0;
00144   fhNDNuMuBarCCDataFromFile = 0;
00145 
00146   fOutputFile = 0;
00147 
00148   ftNDDataTree = 0;
00149   ftNDMCTree = 0;
00150 
00151   fFitter = new TFitterMinuit();
00152   fFitter->CreateMinimizer();
00153   fFitter->SetMinuitFCN(this);
00154   
00155   //ND fake parameters (set to 1.0)
00156   fvNDFakeTrueENuMuCCBins.push_back(30.0);
00157   fvNDFakeTrueENuMuBarCCBins.push_back(30.0);
00158   for (Int_t counter=0; counter<10; ++counter){
00159     fvfakepars.push_back(1.0);
00160   }
00161 }
00162 
00163 //____________________________________________________________________72
00164 NuCrossSectionFitter::~NuCrossSectionFitter()
00165 {
00166   if (fOutputFile){
00167     fOutputFile->Close();
00168     delete fOutputFile;
00169     fOutputFile = 0;
00170   }
00171   if (fhNDMCRecoENuMuCC){delete fhNDMCRecoENuMuCC; fhNDMCRecoENuMuCC=0;}
00172   if (fhNDMCRecoENuMuBarCC){
00173     delete fhNDMCRecoENuMuBarCC; fhNDMCRecoENuMuBarCC = 0;
00174   }
00175   if (fhNDDataRecoENuMuCC){
00176     delete fhNDDataRecoENuMuCC; fhNDDataRecoENuMuCC = 0;
00177   }
00178   if (fhNDDataRecoENuMuBarCC){
00179     delete fhNDDataRecoENuMuBarCC; fhNDDataRecoENuMuBarCC = 0;
00180   }
00181   if (fhNDRawMCTrueECCNuMu){
00182     delete fhNDRawMCTrueECCNuMu; fhNDRawMCTrueECCNuMu = 0;
00183   }
00184   if (fhNDRawMCTrueECCNuMuBar){
00185     delete fhNDRawMCTrueECCNuMuBar; fhNDRawMCTrueECCNuMuBar = 0;
00186   }
00187   if (fhNDRawMCRecoECCNuMu){
00188     delete fhNDRawMCRecoECCNuMu; fhNDRawMCRecoECCNuMu = 0;
00189   }
00190   if (fhNDRawMCRecoECCNuMuBar){
00191     delete fhNDRawMCRecoECCNuMuBar; fhNDRawMCRecoECCNuMuBar = 0;
00192   }
00193 
00194   if (fhNDNuMuCCDataFromFile){
00195     delete fhNDNuMuCCDataFromFile; fhNDNuMuCCDataFromFile = 0;
00196   }
00197   if (fhNDNuMuBarCCDataFromFile){
00198     delete fhNDNuMuBarCCDataFromFile; fhNDNuMuBarCCDataFromFile = 0;
00199   }
00200 
00201   if (ftNDDataTree){
00202     delete ftNDDataTree; ftNDDataTree = 0;
00203   }
00204 
00205   //Note that the object fFitter newed in the constructor is never
00206   //deleted. This is an intentional memory leak to hack my way around
00207   //typical ROOT stupidity. I have to pass fFitter a this pointer to
00208   //tell it to use this object for its minimisation. If I delete
00209   //fFitter, it promptly runs the destructor of this. This causes an
00210   //infinite chain of destructors which, unsurprisingy, causes a seg
00211   //fault.
00212 }
00213 
00214 //____________________________________________________________________72
00215 void NuCrossSectionFitter::OutputFileName(const string outFile)
00216 {
00217   if (fOutputFile){
00218     fOutputFile->Close();
00219     delete fOutputFile;
00220     fOutputFile = 0;
00221   }
00222   fOutputFile = new TFile(outFile.c_str(),"RECREATE");
00223 }
00224 
00225 //____________________________________________________________________72
00226 double NuCrossSectionFitter::operator () (const vector<double>& pars) const
00227 {
00228   static Int_t fitcounter = 0;
00229   if (!(fitcounter%50)){
00230     cout << "Minuit TF call " << fitcounter << endl;
00231   }
00232   ++fitcounter;
00233   this->FillTruthWeightedHistograms(pars);
00234   return this->CalculateLikelihood();
00235 }
00236 
00237 //____________________________________________________________________72
00238 const Double_t NuCrossSectionFitter::CalculateLikelihood() const
00239 {
00240   //Aim to minimise -2lnL. That's what I'm returning.
00241 
00242   Double_t like = 0;
00243 
00244   for (Int_t i=1; i<=fhNDMCRecoENuMuCC->GetNbinsX(); ++i){
00245     //Bizarre limits because root histograms are silly
00246     Double_t mnu = fhNDMCRecoENuMuCC->GetBinContent(i);
00247     Double_t dnu = fhNDDataRecoENuMuCC->GetBinContent(i);
00248     if (mnu<0.0001){mnu = 0.0001;}
00249     if (dnu){
00250       like += 2*(mnu - dnu + dnu*log(dnu/mnu));
00251     }
00252     else{like += 2*(mnu - dnu);}
00253   }
00254 
00255   for (Int_t i=1; i<=fhNDMCRecoENuMuBarCC->GetNbinsX(); ++i){
00256     Double_t mbar = fhNDMCRecoENuMuBarCC->GetBinContent(i);
00257     Double_t dbar = fhNDDataRecoENuMuBarCC->GetBinContent(i);
00258     if (mbar<0.0001){mbar = 0.0001;}
00259     if (dbar){
00260       like += 2*(mbar - dbar + dbar*log(dbar/mbar));
00261     }
00262     else{like += 2*(mbar - dbar);}
00263   }
00264 //   cout << "Like = " << like << endl;
00265   return like;
00266 }
00267 
00268 //____________________________________________________________________72
00269 void NuCrossSectionFitter::FillTruthWeightedHistograms
00270 (const vector<double>& par) const
00271 {
00272   //Reset recoE histograms (removes bin contents and errors)
00273   fhNDMCRecoENuMuCC->Reset();
00274   fhNDMCRecoENuMuBarCC->Reset();
00275 
00276   Int_t numnubins = fvNDTrueENuMuCCBins.size();
00277   Int_t numbarbins = fvNDTrueENuMuBarCCBins.size();
00278   //NDFit parameters:
00279   Int_t shwEpar = numnubins + numbarbins + 1;
00280   Double_t shwEShift = par[shwEpar];
00281   Int_t trkEpar = numnubins + numbarbins + 2;
00282   Double_t trkEShift = par[trkEpar];
00283 
00284   //Fill the nubar histogram, weighted with truth parameters
00285   for (vector<NuEvent>::const_iterator itBar
00286          = fvNDMCCCNuMuBarEvents.begin();
00287        itBar!=fvNDMCCCNuMuBarEvents.end();
00288        ++itBar){
00289     NuEvent barEvent = *itBar;
00290     Int_t truthpar = this->TruthIndex(barEvent);
00291     Double_t barweight = 1.0;
00292     barweight *= barEvent.rw;
00293     if (truthpar>=0){
00294       barweight *= par[truthpar];
00295     }
00296 
00297     Double_t recoNuE = shwEShift*(barEvent.shwEn)
00298       + trkEShift*(barEvent.trkEn);
00299     fhNDMCRecoENuMuBarCC->Fill(recoNuE,barweight);
00300   }
00301   if (fndMCPoT){fhNDMCRecoENuMuBarCC->Scale(fndDataPoT/fndMCPoT);}
00302 
00303   //Fill the numu histogram, weighted with truth parameters
00304   for (vector<NuEvent>::const_iterator itNu
00305          = fvNDMCCCNuMuEvents.begin();
00306        itNu!=fvNDMCCCNuMuEvents.end();
00307        ++itNu){
00308     NuEvent nuEvent = *itNu;
00309     Int_t truthpar = this->TruthIndex(nuEvent);
00310     Double_t nuweight = 1.0;
00311     nuweight *= nuEvent.rw;
00312     if (truthpar>=0){
00313       nuweight *= par[truthpar];
00314     }
00315 
00316     Double_t recoNuE = shwEShift*(nuEvent.shwEn)
00317       + trkEShift*(nuEvent.trkEn);
00318     fhNDMCRecoENuMuCC->Fill(recoNuE,nuweight);
00319   }
00320   if (fndMCPoT){fhNDMCRecoENuMuCC->Scale(fndDataPoT/fndMCPoT);}
00321 }
00322 
00323 //____________________________________________________________________72
00324 void NuCrossSectionFitter::FillTruthWeightedHistogramsSmooth
00325 (const vector<double>& par) const
00326 {
00327   //Reset recoE histograms
00328   fhNDMCRecoENuMuCC->Reset();
00329   fhNDMCRecoENuMuBarCC->Reset();
00330 
00331   Int_t numnubins = fvNDTrueENuMuCCBins.size();
00332   Int_t numbarbins = fvNDTrueENuMuBarCCBins.size();
00333   //NDFit parameters:
00334   Int_t shwEpar = numnubins + numbarbins + 1;
00335   Double_t shwEShift = par[shwEpar];
00336   Int_t trkEpar = numnubins + numbarbins + 2;
00337   Double_t trkEShift = par[trkEpar];
00338 
00339   //Fill the nubar histogram, weighted with truth parameters
00340   for (vector<NuEvent>::const_iterator itBar
00341          = fvNDMCCCNuMuBarEvents.begin();
00342        itBar!=fvNDMCCCNuMuBarEvents.end();
00343        ++itBar){
00344     NuEvent barEvent = *itBar;
00345     Int_t truthpar = this->TruthIndex(barEvent);
00346     Double_t barweight = 1.0;
00347     barweight *= barEvent.rw;
00348     if (truthpar>=0){
00349       barweight *= par[truthpar];
00350     }
00351 
00352     Double_t recoNuE = shwEShift*(barEvent.shwEn)
00353       + trkEShift*(barEvent.trkEn);
00354 
00355 
00356 
00357     //Which bin am I in?
00358     Int_t thisBin = fhNDMCRecoENuMuBarCC->GetXaxis()->FindFixBin(recoNuE);
00359     //What's the bin width?
00360     Double_t binWidth = fhNDMCRecoENuMuBarCC->GetXaxis()->GetBinWidth(thisBin);
00361     //Where's the bin center?
00362     Double_t binCenter = fhNDMCRecoENuMuBarCC->GetXaxis()->GetBinCenter(thisBin);
00363     //What fraction of me goes in this bin?
00364     Double_t fracThis = 
00365       1.0 - (fabs(recoNuE-binCenter))/binWidth;
00366     if ((fhNDMCRecoENuMuBarCC->GetXaxis()->GetNbins()+1)==thisBin){
00367       fracThis = 1.0;
00368     }
00369         if (fracThis<0.0){cout << "Too many bar events!!!!!!!!!!!!!!!" << fracThis << endl;}
00370     fhNDMCRecoENuMuBarCC->AddBinContent(thisBin,fracThis*barweight);
00371     //Am I above or below bin center?
00372     if (recoNuE>=binCenter){
00373       fhNDMCRecoENuMuBarCC->AddBinContent(thisBin+1,(1.0-fracThis)*barweight);
00374     }
00375     else{
00376       if (thisBin>1){
00377         fhNDMCRecoENuMuBarCC->AddBinContent(thisBin-1,(1.0-fracThis)*barweight);
00378       }
00379       else{
00380         fhNDMCRecoENuMuBarCC->AddBinContent(thisBin,(1.0-fracThis)*barweight);
00381       }
00382     }
00383 
00384 
00385 
00386     this->FillSmooth(fhNDMCRecoENuMuBarCC,recoNuE,barweight);
00387   }
00388   if (fndMCPoT){fhNDMCRecoENuMuBarCC->Scale(fndDataPoT/fndMCPoT);}
00389 
00390   //Fill the numu histogram, weighted with truth parameters
00391   for (vector<NuEvent>::const_iterator itNu
00392          = fvNDMCCCNuMuEvents.begin();
00393        itNu!=fvNDMCCCNuMuEvents.end();
00394        ++itNu){
00395     NuEvent nuEvent = *itNu;
00396     Int_t truthpar = this->TruthIndex(nuEvent);
00397     Double_t nuweight = 1.0;
00398     nuweight *= nuEvent.rw;
00399     if (truthpar>=0){
00400       nuweight *= par[truthpar];
00401     }
00402 
00403     Double_t recoNuE = shwEShift*(nuEvent.shwEn)
00404       + trkEShift*(nuEvent.trkEn);
00405     fhNDMCRecoENuMuCC->Fill(recoNuE,nuweight);
00406   }
00407   if (fndMCPoT){fhNDMCRecoENuMuCC->Scale(fndDataPoT/fndMCPoT);}
00408 }
00409 
00410 //____________________________________________________________________72
00411 void NuCrossSectionFitter::FillSmooth(const TH1D*/* histogram*/,
00412                                       Double_t /*energy*/,
00413                                       Double_t /*evtWeight*/) const
00414 {
00415 }
00416 
00417 //____________________________________________________________________72
00418 const Int_t NuCrossSectionFitter::TruthIndex(const NuEvent& info) const
00419 {
00420   Int_t numnubins = fvNDTrueENuMuCCBins.size();
00421   Int_t numbarbins = fvNDTrueENuMuBarCCBins.size();
00422 
00423   Int_t type = info.inu;
00424   const vector<Double_t>* truthbins;
00425   Int_t offset = 0;
00426   Int_t numbins = 0;
00427   if (14 == type){
00428     truthbins = &fvNDTrueENuMuCCBins;
00429     numbins = numnubins;
00430     offset = 0;
00431   }
00432   else if (-14 == type){
00433     truthbins = &fvNDTrueENuMuBarCCBins;
00434     numbins = numbarbins;
00435     offset = numnubins;
00436   }
00437   else{
00438     return numnubins + numbarbins;
00439   }
00440   for (Int_t i=1; i<numbins; ++i){
00441     if ((*truthbins)[i]>info.neuEnMC){
00442       return i - 1 + offset;
00443     }
00444   }
00445   if ((14 == type) || (-14 == type)){
00446     return (numbins + offset);
00447   }
00448   return numnubins + numbarbins;
00449 }
00450 
00451 //____________________________________________________________________72
00452 const Int_t NuCrossSectionFitter::FakeTruthIndex(const NuEvent& info) const
00453 {
00454   Int_t numnubins = fvNDFakeTrueENuMuCCBins.size();
00455   Int_t numbarbins = fvNDFakeTrueENuMuBarCCBins.size();
00456 
00457   Int_t type = info.inu;
00458   const vector<Double_t>* truthbins;
00459   Int_t offset = 0;
00460   Int_t numbins = 0;
00461   if (14 == type){
00462     truthbins = &fvNDFakeTrueENuMuCCBins;
00463     numbins = numnubins;
00464     offset = 0;
00465   }
00466   else if (-14 == type){
00467     truthbins = &fvNDFakeTrueENuMuBarCCBins;
00468     numbins = numbarbins;
00469     offset = numnubins;
00470   }
00471   else{
00472     return numnubins + numbarbins;
00473   }
00474   for (Int_t i=1; i<numbins; ++i){
00475     if ((*truthbins)[i]>info.neuEnMC){
00476       return i - 1 + offset;
00477     }
00478   }
00479   if ((14 == type) || (-14 == type)){
00480     return (numbins + offset);
00481   }
00482   return numnubins + numbarbins;
00483 }
00484 
00485 //____________________________________________________________________72
00486 void NuCrossSectionFitter::CalculateFDWeights()
00487 {
00488   const Bool_t goodConfig = this->Config();
00489   if (!goodConfig){
00490     MSG("NuCrossSectionFitter",Msg::kFatal)
00491       << "About to die due to bad config."
00492       << endl;
00493     return;
00494   }
00495   MSG("NuCrossSectionFitter",Msg::kInfo)
00496     << "Configured successfully. Starting XFit."
00497     << endl;
00498 
00499   this->DoNDFit();
00500 
00501   //  this->FillFDPrediction();
00502 }
00503 
00504 //____________________________________________________________________72
00505 void NuCrossSectionFitter::SetupPars()
00506 {
00507 
00508   //Set up parameters here
00509   Int_t parnum=0;
00510   for (UInt_t i=0; i<(fvNDTrueENuMuCCBins.size()); ++i,++parnum){
00511     if (fvNDTrueENuMuCCBins.size()-1 == i){
00512       fFitter->SetParameter(parnum,
00513                           Form("NuMuOverflow",i),
00514                           1.0,0.2,1.0,0.0);
00515       fFitter->FixParameter(parnum);
00516     }
00517     else{
00518       fFitter->SetParameter(parnum,Form("NuMu%d",i),1.0,0.2,1.0,0.0);
00519     }
00520   }
00521 
00522   for (UInt_t i=0; i<(fvNDTrueENuMuBarCCBins.size()); ++i,++parnum){
00523     if (fvNDTrueENuMuBarCCBins.size()-1 == i){
00524       fFitter->SetParameter(parnum,
00525                           Form("NuMuBarOverFlow",i),
00526                           1.0,0.2,1.0,0.0);
00527       fFitter->FixParameter(parnum);
00528     }
00529     else{
00530       fFitter->SetParameter(parnum,Form("NuMuBar%d",i),1.0,0.2,1.0,0.0);
00531     }
00532   }
00533   fFitter->SetParameter(parnum,"OtherPar",1.0,0.2,1.0,0.0);
00534   fFitter->FixParameter(parnum);
00535   parnum++;
00536   fFitter->SetParameter(parnum,"ShwEShift",1.0,0.0001,1.0,0.0);
00537   fFitter->FixParameter(parnum);
00538   parnum++;
00539   fFitter->SetParameter(parnum,"TrkEShift",1.0,0.2,1.0,0.0);
00540   fFitter->FixParameter(parnum);
00541 
00542   return;
00543 }
00544 
00545 //____________________________________________________________________72
00546 void NuCrossSectionFitter::ReleaseNonOverflowNonNDFitPars()
00547 {
00548   const TFitterMinuit* stupidRoot = fFitter;
00549   const vector<MinuitParameter>& vMinuitPars =
00550     stupidRoot->State().MinuitParameters();
00551   
00552   Int_t parnum=0;
00553   for (UInt_t i=0; i<(fvNDTrueENuMuCCBins.size()); ++i,++parnum){
00554     if (fvNDTrueENuMuCCBins.size()-1 == i){
00555       if (!vMinuitPars[parnum].IsFixed()){
00556         fFitter->FixParameter(parnum);
00557       }
00558     }
00559     else{
00560       if (vMinuitPars[parnum].IsFixed()){
00561         fFitter->ReleaseParameter(parnum);
00562       }
00563     }
00564   }
00565   for (UInt_t i=0; i<(fvNDTrueENuMuBarCCBins.size()); ++i,++parnum){
00566     if (fvNDTrueENuMuBarCCBins.size()-1 == i){
00567       if (!vMinuitPars[parnum].IsFixed()){
00568         fFitter->FixParameter(parnum);
00569       }
00570     }
00571     else{
00572       if (vMinuitPars[parnum].IsFixed()){
00573         fFitter->ReleaseParameter(parnum);
00574       }
00575     }
00576   }
00577   if (!vMinuitPars[parnum].IsFixed()){
00578     fFitter->FixParameter(parnum);
00579   }
00580   parnum++;
00581   if (!vMinuitPars[parnum].IsFixed()){
00582     fFitter->FixParameter(parnum);
00583   }
00584   parnum++;
00585   if (!vMinuitPars[parnum].IsFixed()){
00586     fFitter->FixParameter(parnum);
00587   }
00588 
00589   return;
00590 }
00591 
00592 //____________________________________________________________________72
00593 void NuCrossSectionFitter::ReleaseNonOverflowPars()
00594 {
00595   const TFitterMinuit* stupidRoot = fFitter;
00596   const vector<MinuitParameter>& vMinuitPars =
00597     stupidRoot->State().MinuitParameters();
00598   
00599   Int_t parnum=0;
00600   for (UInt_t i=0; i<(fvNDTrueENuMuCCBins.size()); ++i,++parnum){
00601     if (fvNDTrueENuMuCCBins.size()-1 == i){
00602       if (!vMinuitPars[parnum].IsFixed()){
00603         fFitter->FixParameter(parnum);
00604       }
00605     }
00606     else{
00607       if (vMinuitPars[parnum].IsFixed()){
00608         fFitter->ReleaseParameter(parnum);
00609       }
00610     }
00611   }
00612   for (UInt_t i=0; i<(fvNDTrueENuMuBarCCBins.size()); ++i,++parnum){
00613     if (fvNDTrueENuMuBarCCBins.size()-1 == i){
00614       if (!vMinuitPars[parnum].IsFixed()){
00615         fFitter->FixParameter(parnum);
00616       }
00617     }
00618     else{
00619       if (vMinuitPars[parnum].IsFixed()){
00620         fFitter->ReleaseParameter(parnum);
00621       }
00622     }
00623   }
00624   if (!vMinuitPars[parnum].IsFixed()){
00625     fFitter->FixParameter(parnum);
00626   }
00627   parnum++;
00628   if (vMinuitPars[parnum].IsFixed()){
00629     fFitter->ReleaseParameter(parnum);
00630   }
00631   parnum++;
00632   if (vMinuitPars[parnum].IsFixed()){
00633     fFitter->ReleaseParameter(parnum);
00634   }
00635 
00636   return;
00637 }
00638 
00639 //____________________________________________________________________72
00640 void NuCrossSectionFitter::FixAllParsExcept(const Int_t freeparnum)
00641 {
00642   const TFitterMinuit* stupidRoot = fFitter;
00643   const vector<MinuitParameter>& vMinuitPars =
00644     stupidRoot->State().MinuitParameters();
00645   
00646   Int_t parnum=0;
00647   for (UInt_t i=0; i<(fvNDTrueENuMuCCBins.size()); ++i,++parnum){
00648     if (!vMinuitPars[parnum].IsFixed()){
00649       fFitter->FixParameter(parnum);
00650     }
00651   }
00652   for (UInt_t i=0; i<(fvNDTrueENuMuBarCCBins.size()); ++i,++parnum){
00653     if (!vMinuitPars[parnum].IsFixed()){
00654       fFitter->FixParameter(parnum);
00655     }
00656   }
00657   if (!vMinuitPars[parnum].IsFixed()){
00658     fFitter->FixParameter(parnum);
00659   }
00660   parnum++;
00661   if (!vMinuitPars[parnum].IsFixed()){
00662     fFitter->FixParameter(parnum);
00663   }
00664   parnum++;
00665   if (!vMinuitPars[parnum].IsFixed()){
00666     fFitter->FixParameter(parnum);
00667   }
00668   
00669   fFitter->ReleaseParameter(freeparnum);
00670 
00671   return;
00672 }
00673 
00674 //____________________________________________________________________72
00675 const Bool_t NuCrossSectionFitter::DoNDFit()
00676 {  
00677   this->SetupPars();
00678 
00679   this->FixAllParsExcept(0);
00680   //Do the fit
00681   fFitter->Minimize();
00682   fFitter->PrintResults(0,0);
00683   
00684   this->FixAllParsExcept(1);
00685   //Do the fit
00686   fFitter->Minimize();
00687   fFitter->PrintResults(0,0);
00688   
00689   this->ReleaseNonOverflowNonNDFitPars();
00690   fFitter->Minimize();
00691   fFitter->PrintResults(0,0);
00692   /*
00693   this->ReleaseNonOverflowPars();
00694   fFitter->Minimize();
00695   fFitter->PrintResults(0,0);
00696   */
00697   const vector<Double_t> vBestFit = this->GetBestFitPars();
00698   this->FillTruthWeightedHistograms(vBestFit);
00699   fOutputFile->cd();
00700   fhNDMCRecoENuMuCC->Write("BestFitNDMCRecoENuMuCC");
00701   fhNDMCRecoENuMuBarCC->Write("BestFitNDMCRecoENuMuBarCC");
00702   return true;
00703 }
00704 
00705 //____________________________________________________________________72
00706 const vector<Double_t> NuCrossSectionFitter::GetBestFitPars() const
00707 {  
00708   vector<Double_t> vbestfit;
00709   Int_t parnum=0;
00710   for (UInt_t i=0; i<(fvNDTrueENuMuCCBins.size()); ++i,++parnum){
00711     vbestfit.push_back(fFitter->GetParameter(parnum));
00712   }
00713   for (UInt_t i=0; i<(fvNDTrueENuMuBarCCBins.size()); ++i,++parnum){
00714     vbestfit.push_back(fFitter->GetParameter(parnum));
00715   }
00716   vbestfit.push_back(fFitter->GetParameter(parnum));
00717   parnum++;
00718   vbestfit.push_back(fFitter->GetParameter(parnum));
00719   parnum++;
00720   vbestfit.push_back(fFitter->GetParameter(parnum));
00721 
00722   return vbestfit;
00723 }
00724 
00725 //____________________________________________________________________72
00726 const Bool_t NuCrossSectionFitter::Config()
00727 {
00728   Bool_t goodConfig = true;
00729   if (!this->ConfigND()) goodConfig = false;
00730   if (!this->ConfigFD()) goodConfig = false;
00731   return goodConfig;
00732 }
00733 
00734 //____________________________________________________________________72
00735 const Bool_t NuCrossSectionFitter::ConfigND()
00736 {
00737   Bool_t goodConfig = true;
00738   if (!this->CreateNDHistograms()) goodConfig = false;
00739 
00740   MSG("NuCrossSectionFitter",Msg::kInfo)
00741     << "NDHistograms created"
00742     << endl;
00743 
00744   if (!this->FillNDDataHistograms()) goodConfig = false;
00745 
00746   MSG("NuCrossSectionFitter",Msg::kInfo)
00747     << "NDHistograms filled"
00748     << endl;
00749 
00750   if (!this->CacheNDMCEvents()) goodConfig = false;
00751 
00752   MSG("NuCrossSectionFitter",Msg::kInfo)
00753     << "ND MC events cached"
00754     << endl;
00755 
00756   return goodConfig;
00757 }
00758 
00759 //____________________________________________________________________72
00760 const Bool_t NuCrossSectionFitter::ConfigFD()
00761 {
00762   return true;
00763 }
00764 
00765 //____________________________________________________________________72
00766 const Bool_t NuCrossSectionFitter::CreateNDHistograms()
00767 {
00768   Bool_t goodConfig = true;
00769   if (!this->CreateNDNuMuCCDataHisto()) goodConfig = false;
00770   if (!this->CreateNDNuMuBarCCDataHisto()) goodConfig = false;
00771   if (!this->CreateNDNuMuCCMCHisto()) goodConfig = false;
00772   if (!this->CreateNDNuMuBarCCMCHisto()) goodConfig = false;
00773   if (!this->CreateNDRawMCRecoECCNuMuHisto()) goodConfig = false;
00774   if (!this->CreateNDRawMCRecoECCNuMuBarHisto()) goodConfig = false;
00775   if (!this->CreateNDRawMCTrueECCNuMuHisto()) goodConfig = false;
00776   if (!this->CreateNDRawMCTrueECCNuMuBarHisto()) goodConfig = false;
00777   return goodConfig;
00778 }
00779 
00780 //____________________________________________________________________72
00781 const Bool_t NuCrossSectionFitter::CreateNDNuMuCCMCHisto()
00782 {
00783   if (fhNDMCRecoENuMuCC) {
00784     delete fhNDMCRecoENuMuCC; fhNDMCRecoENuMuCC = 0;
00785   }
00786 
00787   if (fhNDNuMuCCDataFromFile && fhNDNuMuBarCCDataFromFile){
00788     fhNDMCRecoENuMuCC = new TH1D(*fhNDNuMuCCDataFromFile);
00789     fhNDMCRecoENuMuCC->Reset();
00790     return true;
00791   }
00792 
00793   Int_t size = fvNDRecoENuMuCCBins.size();
00794   if (!size){
00795     MSG("NuCrossSectionFitter",Msg::kWarning)
00796       << "ND reconstructed energy binning not supplied."
00797       << endl;
00798     return false;
00799   }
00800 
00801   Double_t* recoEBinEdges = new Double_t[size];
00802 
00803   Int_t i=0;
00804   for (vector<Double_t>::const_iterator it =
00805          fvNDRecoENuMuCCBins.begin();
00806        it != fvNDRecoENuMuCCBins.end();
00807        ++it, ++i){
00808     recoEBinEdges[i] = *it;
00809   }
00810 
00811   fhNDMCRecoENuMuCC = new TH1D("fhNDMCRecoENuMuCC",
00812                                "",
00813                                size-1,
00814                                recoEBinEdges);
00815 
00816   if (!fhNDMCRecoENuMuCC) return false;
00817   return true;
00818 }
00819 
00820 //____________________________________________________________________72
00821 const Bool_t NuCrossSectionFitter::CreateNDRawMCRecoECCNuMuHisto()
00822 {
00823   if (fhNDRawMCRecoECCNuMu) {
00824     delete fhNDRawMCRecoECCNuMu; fhNDRawMCRecoECCNuMu = 0;
00825   }
00826 
00827   if (fhNDNuMuCCDataFromFile && fhNDNuMuBarCCDataFromFile){
00828     fhNDRawMCRecoECCNuMu = new TH1D(*fhNDNuMuCCDataFromFile);
00829     fhNDRawMCRecoECCNuMu->Reset();
00830     return true;
00831   }
00832 
00833   Int_t size = fvNDRecoENuMuCCBins.size();
00834   if (!size){
00835     MSG("NuCrossSectionFitter",Msg::kWarning)
00836       << "ND reconstructed energy binning not supplied."
00837       << endl;
00838     return false;
00839   }
00840 
00841   Double_t* recoEBinEdges = new Double_t[size];
00842 
00843   Int_t i=0;
00844   for (vector<Double_t>::const_iterator it =
00845          fvNDRecoENuMuCCBins.begin();
00846        it != fvNDRecoENuMuCCBins.end();
00847        ++it, ++i){
00848     recoEBinEdges[i] = *it;
00849   }
00850   
00851   fhNDRawMCRecoECCNuMu = new TH1D("fhNDRawMCRecoECCNuMu",
00852                                   "",
00853                                   size-1,
00854                                   recoEBinEdges);
00855   
00856   if (!fhNDRawMCRecoECCNuMu) return false;
00857   return true;
00858 }
00859 
00860 //____________________________________________________________________72
00861 const Bool_t NuCrossSectionFitter::CreateNDRawMCRecoECCNuMuBarHisto()
00862 {
00863   if (fhNDRawMCRecoECCNuMuBar) {
00864     delete fhNDRawMCRecoECCNuMuBar; fhNDRawMCRecoECCNuMuBar = 0;
00865   }
00866 
00867   if (fhNDNuMuCCDataFromFile && fhNDNuMuBarCCDataFromFile){
00868     fhNDRawMCRecoECCNuMuBar = new TH1D(*fhNDNuMuBarCCDataFromFile);
00869     fhNDRawMCRecoECCNuMuBar->Reset();
00870     return true;
00871   }
00872 
00873   Int_t size = fvNDRecoENuMuBarCCBins.size();
00874   if (!size){
00875     MSG("NuCrossSectionFitter",Msg::kWarning)
00876       << "ND reconstructed energy binning not supplied."
00877       << endl;
00878     return false;
00879   }
00880 
00881   Double_t* recoEBinEdges = new Double_t[size];
00882 
00883   Int_t i=0;
00884   for (vector<Double_t>::const_iterator it =
00885          fvNDRecoENuMuBarCCBins.begin();
00886        it != fvNDRecoENuMuBarCCBins.end();
00887        ++it, ++i){
00888     recoEBinEdges[i] = *it;
00889   }
00890   
00891   fhNDRawMCRecoECCNuMuBar = new TH1D("fhNDRawMCRecoECCNuMuBar",
00892                                   "",
00893                                   size-1,
00894                                   recoEBinEdges);
00895   
00896   if (!fhNDRawMCRecoECCNuMuBar) return false;
00897   return true;
00898 }
00899 
00900 //____________________________________________________________________72
00901 const Bool_t NuCrossSectionFitter::CreateNDRawMCTrueECCNuMuHisto()
00902 {
00903   if (fhNDRawMCTrueECCNuMu) {
00904     delete fhNDRawMCTrueECCNuMu; fhNDRawMCTrueECCNuMu = 0;
00905   }
00906 
00907   Int_t size = fvNDTrueENuMuCCBins.size();
00908   if (!size){
00909     MSG("NuCrossSectionFitter",Msg::kWarning)
00910       << "ND true energy binning not supplied."
00911       << endl;
00912     return false;
00913   }
00914 
00915   Double_t* recoEBinEdges = new Double_t[size];
00916 
00917   Int_t i=0;
00918   for (vector<Double_t>::const_iterator it =
00919          fvNDTrueENuMuCCBins.begin();
00920        it != fvNDTrueENuMuCCBins.end();
00921        ++it, ++i){
00922     recoEBinEdges[i] = *it;
00923   }
00924   
00925   fhNDRawMCTrueECCNuMu = new TH1D("fhNDRawMCTrueECCNuMu",
00926                                   "",
00927                                   size-1,
00928                                   recoEBinEdges);
00929   
00930   if (!fhNDRawMCTrueECCNuMu) return false;
00931   return true;
00932 }
00933 
00934 //____________________________________________________________________72
00935 const Bool_t NuCrossSectionFitter::CreateNDRawMCTrueECCNuMuBarHisto()
00936 {
00937   if (fhNDRawMCTrueECCNuMuBar) {
00938     delete fhNDRawMCTrueECCNuMuBar; fhNDRawMCTrueECCNuMuBar = 0;
00939   }
00940 
00941   Int_t size = fvNDTrueENuMuBarCCBins.size();
00942   if (!size){
00943     MSG("NuCrossSectionFitter",Msg::kWarning)
00944       << "ND true energy binning not supplied."
00945       << endl;
00946     return false;
00947   }
00948 
00949   Double_t* recoEBinEdges = new Double_t[size];
00950 
00951   Int_t i=0;
00952   for (vector<Double_t>::const_iterator it =
00953          fvNDTrueENuMuBarCCBins.begin();
00954        it != fvNDTrueENuMuBarCCBins.end();
00955        ++it, ++i){
00956     recoEBinEdges[i] = *it;
00957   }
00958   
00959   fhNDRawMCTrueECCNuMuBar = new TH1D("fhNDRawMCTrueECCNuMuBar",
00960                                   "",
00961                                   size-1,
00962                                   recoEBinEdges);
00963   
00964   if (!fhNDRawMCTrueECCNuMuBar) return false;
00965   return true;
00966 }
00967 
00968 //____________________________________________________________________72
00969 const Bool_t NuCrossSectionFitter::CreateNDNuMuBarCCMCHisto()
00970 {
00971   if (fhNDMCRecoENuMuBarCC){
00972     delete fhNDMCRecoENuMuBarCC; fhNDMCRecoENuMuBarCC = 0;
00973   }
00974 
00975   if (fhNDNuMuCCDataFromFile && fhNDNuMuBarCCDataFromFile){
00976     fhNDMCRecoENuMuBarCC = new TH1D(*fhNDNuMuBarCCDataFromFile);
00977     fhNDMCRecoENuMuBarCC->Reset();
00978     return true;
00979   }
00980 
00981   Int_t size = fvNDRecoENuMuBarCCBins.size();
00982   if (!size){
00983     MSG("NuCrossSectionFitter",Msg::kWarning)
00984       << "ND reconstructed energy binning not supplied."
00985       << endl;
00986     return false;
00987   }
00988 
00989   Double_t* recoEBinEdges = new Double_t[size];
00990 
00991   Int_t i=0;
00992   for (vector<Double_t>::const_iterator it =
00993          fvNDRecoENuMuBarCCBins.begin();
00994        it != fvNDRecoENuMuBarCCBins.end();
00995        ++it, ++i){
00996     recoEBinEdges[i] = *it;
00997   }
00998   
00999   fhNDMCRecoENuMuBarCC = new TH1D("fhNDMCRecoENuMuBarCC",
01000                                   "",
01001                                   size-1,
01002                                   recoEBinEdges);
01003 
01004   if (!fhNDMCRecoENuMuBarCC){return false;}
01005   return true;
01006 }
01007 
01008 //____________________________________________________________________72
01009 const Bool_t NuCrossSectionFitter::CreateNDNuMuCCDataHisto()
01010 {
01011   if (fhNDDataRecoENuMuCC) {
01012     delete fhNDDataRecoENuMuCC; fhNDDataRecoENuMuCC = 0;
01013   }
01014 
01015   Int_t size = fvNDRecoENuMuCCBins.size();
01016   if (!size){
01017     MSG("NuCrossSectionFitter",Msg::kWarning)
01018       << "ND reconstructed energy binning not supplied."
01019       << endl;
01020     return false;
01021   }
01022 
01023   Double_t* recoEBinEdges = new Double_t[size];
01024 
01025   Int_t i=0;
01026   for (vector<Double_t>::const_iterator it =
01027          fvNDRecoENuMuCCBins.begin();
01028        it != fvNDRecoENuMuCCBins.end();
01029        ++it, ++i){
01030     recoEBinEdges[i] = *it;
01031   }
01032 
01033   fhNDDataRecoENuMuCC = new TH1D("fhNDDataRecoENuMuCC",
01034                                "",
01035                                  size-1,
01036                                recoEBinEdges);
01037 
01038   if (!fhNDDataRecoENuMuCC) return false;
01039   return true;
01040 }
01041 
01042 //____________________________________________________________________72
01043 const Bool_t NuCrossSectionFitter::CreateNDNuMuBarCCDataHisto()
01044 {
01045   if (fhNDDataRecoENuMuBarCC){
01046     delete fhNDDataRecoENuMuBarCC; fhNDDataRecoENuMuBarCC = 0;
01047   }
01048 
01049   Int_t size = fvNDRecoENuMuBarCCBins.size();
01050   if (!size){
01051     MSG("NuCrossSectionFitter",Msg::kWarning)
01052       << "ND reconstructed energy binning not supplied."
01053       << endl;
01054     return false;
01055   }
01056 
01057   Double_t* recoEBinEdges = new Double_t[size];
01058 
01059   Int_t i = 0;
01060   for (vector<Double_t>::const_iterator it =
01061          fvNDRecoENuMuBarCCBins.begin();
01062        it != fvNDRecoENuMuBarCCBins.end();
01063        ++it, ++i){
01064     recoEBinEdges[i] = *it;
01065   }
01066   
01067   fhNDDataRecoENuMuBarCC = new TH1D("fhNDDataRecoENuMuBarCC",
01068                                   "",
01069                                   size-1,
01070                                   recoEBinEdges);
01071 
01072   if (!fhNDDataRecoENuMuBarCC){return false;}
01073   return true;
01074 }
01075 
01076 //____________________________________________________________________72
01077 void NuCrossSectionFitter::NDData(const string ndDataFileName)
01078 {
01079   if (ftNDDataTree){delete ftNDDataTree; ftNDDataTree = 0;}
01080   ftNDDataTree = new NuTreeWrapper(ndDataFileName);
01081 
01082   //Get the total PoT
01083   fndDataPoT = ftNDDataTree->GetPoT();
01084   //fndDataPoT = 1.0;
01085   MSG("NuCrossSectionFitter",Msg::kInfo)
01086     << "ndDataPoT: " << fndDataPoT
01087     << endl;
01088 }
01089 
01090 //____________________________________________________________________72
01091 void NuCrossSectionFitter::NDNuMuBarCCData(const TH1D& ndData)
01092 {
01093   if (fhNDNuMuBarCCDataFromFile){
01094     delete fhNDNuMuBarCCDataFromFile; fhNDNuMuBarCCDataFromFile = 0;
01095   }
01096   fhNDNuMuBarCCDataFromFile = new TH1D(ndData);
01097   fhNDNuMuBarCCDataFromFile->SetDirectory(0);
01098 }
01099 
01100 //____________________________________________________________________72
01101 void NuCrossSectionFitter::NDNuMuCCData(const TH1D& ndData)
01102 {
01103   if (fhNDNuMuCCDataFromFile){
01104     delete fhNDNuMuCCDataFromFile; fhNDNuMuCCDataFromFile = 0;
01105   }
01106   fhNDNuMuCCDataFromFile = new TH1D(ndData);
01107   fhNDNuMuCCDataFromFile->SetDirectory(0);
01108 }
01109 
01110 //____________________________________________________________________72
01111 void NuCrossSectionFitter::NDMC(const string ndMCFileName)
01112 {
01113   if (ftNDMCTree){delete ftNDMCTree; ftNDMCTree = 0;}
01114   ftNDMCTree = new NuTreeWrapper(ndMCFileName);
01115 
01116   //Get the total PoT
01117   fndMCPoT = ftNDMCTree->GetPoT();
01118   
01119   //fndMCPoT = 1.0;
01120   MSG("NuCrossSectionFitter",Msg::kInfo)
01121     << "ndMCPoT: " << fndMCPoT
01122     << endl;
01123 }
01124 
01125 //____________________________________________________________________72
01126 const Bool_t NuCrossSectionFitter::CacheNDMCEvents()
01127 {
01128   if (!ftNDMCTree){
01129     MSG("NuCrossSectionFitter",Msg::kWarning)
01130       << "ND MC not supplied"
01131       << endl;
01132     return false;
01133   }
01134 
01135   fvNDMCCCNuMuEvents.clear();
01136   fvNDMCCCNuMuBarEvents.clear();
01137 
01138   MSG("NuCrossSectionFitter",Msg::kInfo)
01139     << "Looping over ND MC:"
01140     << endl;
01141   Int_t mcEntries = ftNDMCTree->GetEntries();
01142   for (Int_t counter = 0;
01143        counter < mcEntries;
01144        ++counter){
01145     if (!(counter%10000)){
01146       MSG("NuCrossSectionFitter",Msg::kInfo)
01147         << counter << " of " << mcEntries
01148         << endl;
01149     }
01150     NuEvent currentEvent = ftNDMCTree->GetInfoObject(counter);
01151     fnuSystematic->Shift(currentEvent);
01152     NuSelectionResult_t recoType = this->SelectedAs(currentEvent);
01153     Double_t eventWeight = currentEvent.rw;
01154     if (NuXSecFit::kCCNuMu==recoType){
01155       fvNDMCCCNuMuEvents.push_back(currentEvent);
01156       fhNDRawMCRecoECCNuMu->Fill(currentEvent.energy,eventWeight);
01157       fhNDRawMCTrueECCNuMu->Fill(currentEvent.neuEnMC,eventWeight);
01158     }
01159     if (NuXSecFit::kCCNuMuBar==recoType){
01160       fvNDMCCCNuMuBarEvents.push_back(currentEvent);
01161       fhNDRawMCRecoECCNuMuBar->Fill(currentEvent.energy,eventWeight);
01162       fhNDRawMCTrueECCNuMuBar->Fill(currentEvent.neuEnMC,eventWeight);
01163     }
01164   }
01165 
01166   if (fndMCPoT){
01167     fhNDRawMCRecoECCNuMu->Scale(fndDataPoT/fndMCPoT);
01168     fhNDRawMCRecoECCNuMuBar->Scale(fndDataPoT/fndMCPoT);
01169     fhNDRawMCTrueECCNuMu->Scale(fndDataPoT/fndMCPoT);
01170     fhNDRawMCTrueECCNuMuBar->Scale(fndDataPoT/fndMCPoT);
01171   }
01172 
01173   fOutputFile->cd();
01174   fhNDRawMCRecoECCNuMu->Write("NDRawMCRecoECCNuMu");
01175   fhNDRawMCTrueECCNuMu->Write("NDRawMCTrueECCNuMu");
01176   fhNDRawMCRecoECCNuMuBar->Write("NDRawMCRecoECCNuMuBar");
01177   fhNDRawMCTrueECCNuMuBar->Write("NDRawMCTrueECCNuMuBar");
01178 
01179   return true;
01180 }
01181 
01182 //____________________________________________________________________72
01183 const Bool_t NuCrossSectionFitter::FillNDDataHistograms()
01184 {
01185   //Preferentially take data from histograms if they've been supplied
01186   if (fhNDNuMuCCDataFromFile && fhNDNuMuBarCCDataFromFile){
01187     if (fhNDDataRecoENuMuCC){
01188       delete fhNDDataRecoENuMuCC; fhNDDataRecoENuMuCC = 0;
01189     }
01190     if (fhNDDataRecoENuMuBarCC){
01191       delete fhNDDataRecoENuMuBarCC; fhNDDataRecoENuMuBarCC = 0;;
01192     }
01193     fhNDDataRecoENuMuCC = new TH1D(*fhNDNuMuCCDataFromFile);
01194     fhNDDataRecoENuMuBarCC = new TH1D(*fhNDNuMuBarCCDataFromFile);
01195 
01196     fOutputFile->cd();
01197     fhNDDataRecoENuMuCC->Write("InputNDNuMuCCData");
01198     fhNDDataRecoENuMuBarCC->Write("InputNDNuMuBarCCData");
01199     return true;
01200   }
01201 
01202   if (!fhNDDataRecoENuMuCC){
01203     MSG("NuCrossSectionFitter",Msg::kWarning)
01204       << "ND numu data histogram not created"
01205       << endl;
01206     return false;
01207   }
01208   if (!fhNDDataRecoENuMuBarCC){
01209     MSG("NuCrossSectionFitter",Msg::kWarning)
01210       << "ND numubar data histogram not created"
01211       << endl;
01212     return false;
01213   }
01214   if (!ftNDDataTree){
01215     MSG("NuCrossSectionFitter",Msg::kWarning)
01216       << "ND data not supplied"
01217       << endl;
01218     return false;
01219   }
01220 
01221   fhNDDataRecoENuMuCC->Reset();
01222   fhNDDataRecoENuMuBarCC->Reset();
01223 
01224   MSG("NuCrossSectionFitter",Msg::kInfo)
01225     << "Looping over ND data:"
01226     << endl;
01227   Int_t dataEntries = ftNDDataTree->GetEntries();
01228   for (Int_t counter = 0;
01229        counter < dataEntries;
01230        ++counter){
01231     if (!(counter%10000)){
01232       MSG("NuCrossSectionFitter",Msg::kInfo)
01233         << counter << " of " << dataEntries
01234         << endl;
01235     }
01236     NuEvent currentEvent = ftNDDataTree->GetInfoObject(counter);
01237     NuSelectionResult_t recoType = this->SelectedAs(currentEvent);
01238     Double_t recoEnergy = currentEvent.energy;
01239     
01240     Int_t truthpar = this->FakeTruthIndex(currentEvent);
01241     Double_t nuweight = 1.0;
01242     nuweight *= currentEvent.rw;
01243     if (truthpar>=0){
01244       nuweight *= fvfakepars[truthpar];
01245     }
01246 
01247     if (recoType==NuXSecFit::kCCNuMu){
01248       fhNDDataRecoENuMuCC->Fill(recoEnergy,nuweight);
01249     }
01250     if (recoType==NuXSecFit::kCCNuMuBar){
01251       fhNDDataRecoENuMuBarCC->Fill(recoEnergy,nuweight);
01252     }
01253   }
01254 
01255   fOutputFile->cd();
01256   fhNDDataRecoENuMuCC->Write("InputNDNuMuCCData");
01257   fhNDDataRecoENuMuBarCC->Write("InputNDNuMuBarCCData");
01258 
01259   return true;
01260 }
01261 
01262 //____________________________________________________________________72
01263 const NuSelectionResult_t
01264 NuCrossSectionFitter::SelectedAs(NuEvent& nuEvent) const
01265 {
01266   NuCuts nuCuts;
01267   nuEvent.anaVersion = this->SelectionScheme();
01268   
01269   //cut on LI
01270   if (nuCuts.IsLI(nuEvent)) return NuXSecFit::kUnknown;
01271   //cut on the data quality
01272   if (!nuCuts.IsGoodDataQuality(nuEvent)) return NuXSecFit::kUnknown;
01273   //cut on the spill time
01274   if (!nuCuts.IsGoodTimeToNearestSpill(nuEvent)) return NuXSecFit::kUnknown;
01275   //cut on the beam
01276   if (!nuCuts.IsGoodBeam(nuEvent)) return NuXSecFit::kUnknown;
01277   
01278   //cut on whether event vtx is in fid vol (does nothing for CC ana)
01279   //    if (!nuCuts.IsInFidVol(evt,nu)) continue;
01280   //ensure good number of tracks in event (note preselection above)
01281   if (!nuCuts.IsGoodNumberOfTracks(nuEvent)) return NuXSecFit::kUnknown;
01282   //check trk is in fiducial volume (note preselection above)
01283   if (!nuCuts.IsInFidVolTrk(nuEvent)) return NuXSecFit::kUnknown;
01284   
01285   //require a good trk fit
01286   if (!nuCuts.IsGoodTrackFitPass(nuEvent)) return NuXSecFit::kUnknown;
01287   //require a forward going neutrino about beam direction
01288   if (!nuCuts.IsGoodDirCos(nuEvent)) return NuXSecFit::kUnknown;
01289   
01290   //cut on the PID
01291   if (!nuCuts.IsGoodPID(nuEvent)) {
01292     return NuXSecFit::kUnknown;
01293   }
01294   //cut on the fractional track momentum and sign error      
01295   if (!nuCuts.IsGoodSigmaQP_QP(nuEvent)) {
01296     return NuXSecFit::kUnknown;
01297   }
01298   //cut on the track fit probability      
01299   if (!nuCuts.IsGoodFitProb(nuEvent)) {
01300     return NuXSecFit::kUnknown;
01301   }
01302   if (!nuCuts.IsGoodMajorityCurvature(nuEvent)){
01303     return NuXSecFit::kUnknown;
01304   }
01305   
01306   if (-1==nuEvent.charge){return NuXSecFit::kCCNuMu;}
01307   if (1==nuEvent.charge){return NuXSecFit::kCCNuMuBar;}
01308   return NuXSecFit::kUnknown;
01309 }

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