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

NCExtrapolationRS.cxx

Go to the documentation of this file.
00001 
00002 // $Id: NCExtrapolationRS.cxx,v 1.31 2008/01/11 15:53:31 bckhouse Exp $
00003 //
00004 // A class to implement Tobi's x-section NearFit and use the results to
00005 // produce FD predictions near to far extrapolations
00006 //
00007 // A. Sousa 5/2007
00009 
00010 #include "NCUtils/Extrapolation/NCExtrapolationRS.h"
00011 #include "NCUtils/Extrapolation/NCEnergyBin.h"
00012 #include "MessageService/MsgService.h"
00013 #include "MCReweight/ReweightHelpers.h"
00014 #include "AnalysisNtuples/ANtpAnalysisInfo.h"
00015 #include "AnalysisNtuples/ANtpBeamInfo.h"
00016 #include "AnalysisNtuples/ANtpRecoInfo.h"
00017 #include "AnalysisNtuples/ANtpHeaderInfo.h"
00018 #include "AnalysisNtuples/ANtpTruthInfoBeam.h"
00019 
00020 #include "TCanvas.h"
00021 #include "TGraphErrors.h"
00022 #include "TMath.h"
00023 #include "TMinuit.h"
00024 #include "TLegend.h"
00025 #include "TLine.h"
00026 
00027 #include <cassert>
00028 
00029 CVSID("$Id: NCExtrapolationRS.cxx,v 1.31 2008/01/11 15:53:31 bckhouse Exp $");
00030 
00031 NCExtrapolationRS* NCExtrapolationRS::sFit = NULL;
00032 
00033 //......................................................................
00034 NCExtrapolationRS::NCExtrapolationRS() :
00035   NCExtrapolation::NCExtrapolation()
00036 {
00037 
00038 }
00039 
00040 //.......................................................................
00041 NCExtrapolationRS::NCExtrapolationRS(NCAnalysisUtils *utils,
00042                                      std::map<Int_t,double>& dataNear,
00043                                      std::map<Int_t,double>& mcNear,
00044                                      std::map<Int_t,double>& dataFar,
00045                                      std::map<Int_t,double>& mcFar,
00046                                      bool useCC,
00047                                      bool useNC) :
00048   NCExtrapolation(utils, dataNear, mcNear, dataFar, mcFar, useCC, useNC),
00049   fUseChi2Function(false),
00050   fAnnCutMC(0.675),
00051   fAnnCutData(0.675),
00052   fCutLowBins(false),
00053   fMoveMinStrip(0),
00054   fRandom(0)
00055 {
00056   MSG("NCExtrapolationRS",Msg::kDebug) << "NCExtrapolationRS constructor"
00057                                        << endl;
00058   fExtrapolationType = NCType::kExtrapolationRS;
00059 
00060   //fill the map of data to pot ratios for the near detector
00061   std::map<Int_t, Double_t>::const_iterator potItr = dataNear.begin();
00062   fDataFraction.clear();
00063   while(potItr != dataNear.end()){
00064     fDataFraction[potItr->first] = potItr->second;
00065     ++potItr;
00066   }
00067 
00068   potItr = mcNear.begin();
00069   while(potItr != mcNear.end()){
00070     if(potItr->second == 0.)
00071       fDataFraction[potItr->first] *= 0.;
00072     else
00073       fDataFraction[potItr->first] /= potItr->second;
00074 
00075     ++potItr;
00076   }
00077 
00078   // book all the necessary histograms
00079   this->BookHistograms();
00080 
00081   //fBeams is not yet created, so use scaleFactor maps instead.
00082   for (UInt_t i=0; i<fDataFraction.size(); i++) {  // loop over different
00083                                                       // beams
00084     // create vectors to hold MC and Data events
00085     fMCListNear.push_back  ( new std::vector<MCEvent> );
00086     fDataListNear.push_back( new std::vector<MCEvent> );
00087     fMCListFar.push_back   ( new std::vector<MCEvent> );
00088     fDataListFar.push_back ( new std::vector<MCEvent> );
00089 
00090     fScaleToData.push_back(true);
00091 
00092   } // end beams loop
00093 
00094   // this is needed for fit and static fit function.
00095   sFit = this;
00096 }
00097 
00098 //----------------------------------------------------------------------
00099 NCExtrapolationRS::~NCExtrapolationRS()
00100 {
00101 }
00102 
00103 //----------------------------------------------------------------------
00104 //this method allows the user to pass in appropriate settings for the
00105 //extrapolation such as locations of files, whether to generate the files
00106 //again, etc.  the registry comes from the job module GetConfig method
00107 void NCExtrapolationRS::Prepare(const Registry& r)
00108 {
00109   MSG("NCExtrapolationRS", Msg::kWarning)
00110     << "NCExtrapolationRS::Prepare(const Registry& r)" << endl;
00111 //   int         tmpb;  // a temp bool. See comment under DefaultConfig...
00112 //   int         tmpi;  // a temp int.
00113 //   double      tmpd;  // a temp double.
00114 //   const char* tmps;  // a temp string
00115 
00116   NCExtrapolation::Prepare(r);
00117 
00118   int tmpb;
00119   const char* tmps;  // a temp string
00120 
00121   // check if we are running on a limited number of test events
00122   // --> don't scale with total POT in this case
00123   r.Get("CountChainEntries",tmpb);
00124   if (!tmpb) {
00125     for (uint i=0; i< fScaleToData.size(); ++i)
00126       fScaleToData.at(i) = false;
00127   }
00128 
00129   //Logfile
00130   r.Get("FileName",tmps);
00131   string outFile(tmps);
00132   string::size_type start = outFile.rfind("/") + 1;
00133   outFile.erase(start,outFile.size());
00134   outFile += "ExtrapolationRSFit.log";
00135   logFile = new ofstream(outFile.c_str(),ios::out | ios::app);
00136 
00137   return;
00138 }
00139 
00140 //----------------------------------------------------------------------
00141 void NCExtrapolationRS::AddEvent(ANtpHeaderInfo *headerInfo,
00142                                  ANtpBeamInfo *beamInfo,
00143                                  ANtpRecoInfo *recoInfo,
00144                                  ANtpAnalysisInfo *analysisInfo,
00145                                  ANtpTruthInfoBeam *truthInfo,
00146                                  int runType,
00147                                  bool useMCAsData,
00148                                  int fileType)
00149 {
00150 
00151   if(headerInfo->detector == (int)Detector::kNear)
00152     AddNearEvent(headerInfo, beamInfo, recoInfo, analysisInfo,
00153                  truthInfo, runType, useMCAsData, fileType);
00154 
00155   if(headerInfo->detector == (int)Detector::kFar)
00156     AddFarEvent(headerInfo, beamInfo, recoInfo, analysisInfo,
00157                 truthInfo, runType, useMCAsData, fileType);
00158 
00159   return;
00160 }
00161 
00162 //----------------------------------------------------------------------
00163 void NCExtrapolationRS::AddNearEvent(ANtpHeaderInfo *headerInfo,
00164                                      ANtpBeamInfo *beamInfo,
00165                                      ANtpRecoInfo *recoInfo,
00166                                      ANtpAnalysisInfo *analysisInfo,
00167                                      ANtpTruthInfoBeam *truthInfo,
00168                                      int runType,
00169                                      bool useMCAsData,
00170                                      int fileType)
00171 {
00172   BeamType::BeamType_t beamType = BeamType::FromZarko(beamInfo->beamType);
00173   NCExtrapolation::AddEvent(headerInfo, beamInfo, recoInfo, analysisInfo,
00174                             truthInfo, runType, useMCAsData, fileType);
00175   int beam = NCExtrapolation::FindBeamIndex(Detector::kNear, beamType, runType);
00176 
00177   if (HistEvisNCd.at(beam)==0) {
00178     MSG("NCExtrapolationRS",Msg::kError) << "Histograms with index "
00179                                          << beam << ", Beam "
00180                                          << BeamType::AsString(beamType)
00181                                          << ", don't exist. Exiting..."
00182                                          << endl;
00183     exit(1);
00184   }else{
00185     MCEvent event;
00186 
00187 //  event.Evis   = recoInfo->nuEnergyNC; // reconstructed energy
00188 //  event.EvisMc = recoInfo->nuEnergyNC;
00189     event.Evis   = recoInfo->nuEnergy; // reconstructed energy
00190     event.EvisMc = recoInfo->nuEnergy;
00191 
00192     event.EvisCC = recoInfo->nuEnergy;   // CC energy incl. track
00193     event.EshowerCC = recoInfo->showerEnergyCC;
00194     event.EshowerNC = recoInfo->showerEnergyNC;
00195     event.Etrack = recoInfo->muEnergy;   // track energy
00196     if (event.Etrack<0) event.Etrack = 0;
00197 
00198     event.Weight = 1.;          // this is a systematic weight
00199     // for the event
00200 
00201     if (truthInfo) event.BeamWeight=recoInfo->weight;
00202     else event.BeamWeight=1.0;
00203 
00204     //Handle MC event
00205     if(truthInfo && !useMCAsData) {
00206       event.Enu    = truthInfo->nuEnergy;    // neutrino energy
00207       event.McType = truthInfo->interactionType;
00208       event.nuDCosX = truthInfo->nuDCosX;
00209       event.nuDCosY = truthInfo->nuDCosY;
00210       event.nuDCosZ = truthInfo->nuDCosZ;
00211       event.targetEnergy = truthInfo->targetEnergy;
00212       event.targetPX = truthInfo->targetPX;
00213       event.targetPY = truthInfo->targetPY;
00214       event.targetPZ = truthInfo->targetPZ;
00215       event.nuFlavor = truthInfo->nuFlavor;
00216       event.interactionType = truthInfo->interactionType;
00217       event.iresonance = truthInfo->resonanceCode;
00218       event.hadronicY = truthInfo->hadronicY;
00219       event.X = truthInfo->bjorkenX;
00220       event.q2 = truthInfo->q2;
00221       event.w2 = truthInfo->w2;
00222 
00223       Int_t nucleus = ReweightHelpers::FindNucleusNumber(
00224         static_cast<Int_t>(truthInfo->atomicNumber),
00225         static_cast<Int_t>(truthInfo->atomicWeight)
00226         );
00227       event.nucleus = nucleus;
00228       event.mcstate = truthInfo->initialState;
00229       event.hadronicFinalState = truthInfo->hadronicFinalState;
00230 
00231     }//if(truthInfo)
00232 
00233     // it is not due to oscillation
00234     //    event.SelType = analysisTRann->isCC;
00235     // by moving fANNCutMC, we investigate systematics
00236     //if (analysisTRann->separationParameter < fAnnCutData)
00237     if(analysisInfo->isNC > 0)
00238       event.SelType = 0;      // this is NC
00239     else if (analysisInfo->isCC > 0)
00240       event.SelType = 1;      // this is CC
00241     else
00242       event.SelType = -1;
00243     // cut out non-fid and un-clean events  --> selType = -1
00244     if (recoInfo->inFiducialVolume==0 || recoInfo->isCleanHighMultSnarl==0)
00245       event.SelType = -1;
00246 
00247     // now fill histograms with real data or MC
00248 
00249     if (truthInfo && !useMCAsData){
00250 
00251       if (event.SelType!=-1) {         //fiducial and cleaning
00252         HistEnu.at(beam)->Fill(event.Enu);
00253 
00254         if (event.SelType==1)  {            // selected as CC
00255           HistEvisCC.at(beam)->Fill(event.EvisCC);
00256           HistEvisCCwt.at(beam)->Fill(event.EvisCC,event.BeamWeight);
00257 
00258           if (event.McType==0) {
00259             HistEvisCCb.at(beam)->Fill(event.EvisCC, event.BeamWeight);
00260           }
00261         }
00262         else if (event.SelType==0){         // selected as NC
00263           HistEvisNC.at(beam)->Fill(event.Evis);
00264           HistEvisNCwt.at(beam)->Fill(event.Evis,event.BeamWeight);
00265 
00266           if (event.McType==1) {
00267             HistEvisNCb.at(beam)->Fill(event.Evis, event.BeamWeight);
00268           }
00269         }
00270         fMCListNear.at(beam)->push_back(event);
00271       }
00272     }//if(truthInfo && !useMCAsData)
00273     else{ //data event
00274 
00275       if (event.SelType!=-1) {
00276         if (event.SelType==0) {
00277           MAXMSG("NCExtrapolationRS",Msg::kInfo,5) << "BeamWeight: "
00278                                                    << event.BeamWeight
00279                                                    << endl;
00280           HistEvisNCd.at(beam)->Fill(event.Evis, event.BeamWeight);
00281         }
00282         if (event.SelType==1){
00283           HistEvisCCd.at(beam)->Fill(event.EvisCC, event.BeamWeight);
00284         }
00285       }
00286 
00287       fDataListNear.at(beam)->push_back(event);
00288 
00289     }//else(truthInfo)
00290 
00291   } //else(HistEvis)
00292 
00293 
00294   return;
00295 }
00296 //----------------------------------------------------------------------
00297 void NCExtrapolationRS::AddFarEvent(ANtpHeaderInfo *headerInfo,
00298                                     ANtpBeamInfo *beamInfo,
00299                                     ANtpRecoInfo *recoInfo,
00300                                     ANtpAnalysisInfo *analysisInfo,
00301                                     ANtpTruthInfoBeam *truthInfo,
00302                                     int runType,
00303                                     bool useMCAsData,
00304                                     int fileType)
00305 {
00306   MAXMSG("NCExtrapolationRS",Msg::kInfo,1) << "Running AddFarEvent()..."
00307                                            << endl;
00308 
00309   // find correct trueBin to apply fit result scale factor;
00310   Int_t trueBin = -1;
00311   if (truthInfo) {
00312     Float_t Enu = truthInfo->nuEnergy;
00313     if (Enu < 4)
00314       trueBin = 0;
00315     else if (Enu < 8)
00316       trueBin = 1;
00317     else if (Enu < 15)
00318       trueBin = 2;
00319     else if (Enu < 120)
00320       trueBin = 3;
00321     else
00322       trueBin = 99;
00323   }
00324 
00325   if(truthInfo && !useMCAsData && fileType != NCType::kTauFile) {
00326     if (analysisInfo->isNC > 0) {
00327       fNCVecFar.push_back(recoInfo->showerEnergy);
00328 
00329 //       now filled in NCBeam::AddEvent() method
00330 //       fBeams[beam].GetDefaultMCHistogram(NCType::kNC)->Fill(recoInfo->nuEnergy,
00331 //                                                          recoInfo->weight);
00332 
00333       // scale FD monte carlo by ND fit results
00334       if (truthInfo->interactionType==0 && trueBin!=99) {
00335         recoInfo->weight *= mScaleNC.at(trueBin);
00336 
00337         if (mScaleNC.at(trueBin)!= 1)
00338           cout << "Scale factor: " << mScaleNC.at(trueBin) << endl;
00339       }
00340       fNCWeightFar.push_back(recoInfo->weight);
00341     }
00342     else if(analysisInfo->isCC > 0) {
00343       fCCVecFar.push_back(recoInfo->showerEnergy + recoInfo->muEnergy);
00344 
00345 //       now filled in NCBeam::AddEvent() method
00346 //       fBeams[beam].GetDefaultMCHistogram(NCType::kCC)->Fill(recoInfo->nuEnergy,
00347 //                                                          recoInfo->weight);
00348 
00349       // scale FD monte carlo by ND fit results
00350       Double_t weight = recoInfo->weight;
00351       if (truthInfo->interactionType==0 && trueBin!=99)
00352         recoInfo->weight *= mScaleNC.at(trueBin);
00353       fCCWeightFar.push_back(weight);
00354 
00355     }
00356   }
00357 
00358   NCExtrapolation::AddEvent(headerInfo, beamInfo, recoInfo, analysisInfo,
00359                             truthInfo, runType, useMCAsData, fileType);
00360 
00361   return;
00362 }
00363 
00364 //----------------------------------------------------------------------
00365 //Book histograms to be used in fit.
00366 void NCExtrapolationRS::BookHistograms()
00367 {
00368 
00369   TFile *nu = new TFile("$SRT_LOCAL/NCUtils/data/FluxErrorHistos14.root",
00370                         "READ");
00371   TFile *nubar = new TFile("$SRT_LOCAL/NCUtils/data/FluxErrorHistos-14.root",
00372                            "READ");
00373 
00374   if(!nu->IsOpen() || !nubar->IsOpen()){
00375     MAXMSG("NCExtrapolationRS",Msg::kInfo, 20)<< "SKZP error files "
00376                                            << "not found! "
00377                                            << "Not filling SKZP histos..."
00378                                            << endl;
00379   }
00380 
00381   std::vector<TH1D*> HistCCArray;
00382   std::vector<TH1D*> HistNCArray;
00383 
00384   MSG("NCExtrapolationRS",Msg::kDebug) << "fDataFraction.size(): "
00385                                        << fDataFraction.size()
00386                                        << endl;
00387 
00388   gROOT->cd();
00389   for(uint i = 0; i < fDataFraction.size(); ++i){
00390     string name = (string) Form("HistEnu_%i",i);
00391     HistEnu.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00392 
00393     name = (string) Form("HistEvisCC_%i", i);
00394     HistEvisCC.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00395 
00396     name = (string) Form("HistEvisNC_%i", i);
00397     HistEvisNC.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00398 
00399     name = (string) Form("HistEvisCCwt_%i", i);
00400     HistEvisCCwt.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00401 
00402     name = (string) Form("HistEvisNCwt_%i", i);
00403     HistEvisNCwt.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00404 
00405     name = (string) Form("HistEvisCCrew_%i", i);
00406     HistEvisCCrew.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00407 
00408     name = (string) Form("HistEvisNCrew_%i", i);
00409     HistEvisNCrew.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00410 
00411     name = (string) Form("HistEvisCCb_%i", i);
00412     HistEvisCCb.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00413 
00414     name = (string) Form("HistEvisNCb_%i", i);
00415     HistEvisNCb.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00416 
00417     name = (string) Form("HistEvisCCd_%i", i);
00418     HistEvisCCd.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00419 
00420     name = (string) Form("HistEvisNCd_%i", i);
00421     HistEvisNCd.push_back( new TH1D(name.c_str(), name.c_str(), 60, 0., 30.) );
00422 
00423     for (Int_t trueBin = 0; trueBin<4; trueBin++) {
00424 
00425       name = (string) Form("HistEvisCCtrueBin_%i_%i", i, trueBin);
00426       HistCCArray.push_back( new TH1D(name.c_str(), name.c_str(),
00427                                       60, 0., 30.) );
00428 
00429       name = (string) Form("HistEvisNCtrueBin_%i_%i", i, trueBin);
00430       HistNCArray.push_back( new TH1D(name.c_str(), name.c_str(),
00431                                       60, 0., 30.) );
00432 
00433       // also set scale factors to 1 here -- this is the default
00434       mInputScale.push_back(1.0);
00435     }
00436 
00437     HistEvisCCtrueBin.push_back(HistCCArray);
00438     HistEvisNCtrueBin.push_back(HistNCArray);
00439 
00440     HistCCArray.clear();
00441     HistNCArray.clear();
00442 
00443     // SKZP flux error histograms
00444     name = (string) Form("HistCCFluxErrorMinus_%i", i);
00445     HistCCFluxErrorMinus.push_back( new TH1D(name.c_str(), name.c_str(),
00446                                              60, 0., 30.) );
00447     name = (string) Form("HistNCFluxErrorMinus_%i", i);
00448     HistNCFluxErrorMinus.push_back( new TH1D(name.c_str(), name.c_str(),
00449                                              60, 0., 30.) );
00450     name = (string) Form("HistCCFluxErrorPlus_%i", i);
00451     HistCCFluxErrorPlus.push_back( new TH1D(name.c_str(), name.c_str(),
00452                                             60, 0., 30.) );
00453     name = (string) Form("HistNCFluxErrorPlus_%i", i);
00454     HistNCFluxErrorPlus.push_back( new TH1D(name.c_str(), name.c_str(),
00455                                             60, 0., 30.) );
00456 
00457     if(nu->IsOpen() && nubar->IsOpen()){
00458       //read SKZP flux error histograms from file
00459       name = (string) Form("HistTrueEFluxErrPlus_nu_%i", i);
00460       HistTrueEFluxErrPlus_nu.push_back( dynamic_cast<TH1D*>
00461                                          ( nu->Get(name.c_str() )) );
00462       if (! HistTrueEFluxErrPlus_nu[i]) {
00463         MSG("NExtrapolationRS",Msg::kError) << "Histogram "
00464                                             << name
00465                                             << " not found!"
00466                                             << endl;
00467         exit(1);
00468       }
00469       name = (string) Form("HistTrueEFluxErrMinus_nu_%i", i);
00470       HistTrueEFluxErrMinus_nu.push_back( dynamic_cast<TH1D*>
00471                                           ( nu->Get(name.c_str())) );
00472       if (! HistTrueEFluxErrMinus_nu[i]) {
00473         MSG("NCextrapolationRS",Msg::kError) << "Histogram "
00474                                              << name
00475                                              << " not found!"
00476                                              << endl;
00477         exit(1);
00478       }
00479 
00480       name = (string) Form("HistTrueEFluxErrPlus_nubar_%i", i);
00481       HistTrueEFluxErrPlus_nubar.push_back( dynamic_cast<TH1D*>
00482                                             ( nubar->Get(name.c_str())) );
00483       if (! HistTrueEFluxErrPlus_nubar[i]) {
00484         MSG("NCExtrapolationRS",Msg::kError) << "Histogram "
00485                                              << name
00486                                              << " not found!"
00487                                              << endl;
00488         exit(1);
00489       }
00490 
00491       name = (string) Form("HistTrueEFluxErrMinus_nubar_%i", i);
00492       HistTrueEFluxErrMinus_nubar.push_back( dynamic_cast<TH1D*>
00493                                              (nubar->Get(name.c_str())) );
00494       if (! HistTrueEFluxErrMinus_nubar[i]) {
00495         MSG("NCExtrapolationRS",Msg::kError) << "Histogram "
00496                                              << name
00497                                              << " not found!"
00498                                              << endl;
00499         exit(1);
00500       }
00501     }//if skzp file open
00502 
00503   } // fBeams.size();
00504 
00505   return;
00506 }
00507 
00508 //----------------------------------------------------------------------
00509 void NCExtrapolationRS::DoFit(Int_t PrintLevel)
00510 {
00511 //  PlotData();
00512 
00513   // give start values and errors for fit
00514   // parameters to scale the NC xsec -- use 4 bins
00515   // initialize the vector for final numbers "mScaleNC" and "mScaleNCErr"
00516   // with starting values as well
00517   for (Int_t i=0; i<4; i++) {
00518     m0ScaleNC.push_back(1.0);
00519 //    m0ScaleNCErr.push_back(0.005);
00520     m0ScaleNCErr.push_back(0.);
00521     mScaleNC.push_back(1.0);
00522 //    mScaleNCErr.push_back(0.005);
00523     mScaleNCErr.push_back(0.);
00524   }
00525   // and now do the fit
00526   Fit(PrintLevel);
00527 
00528   // result of fit is now in mXxx and mXxxErr
00529 
00530   return;
00531 }
00532 
00533 //----------------------------------------------------------------------
00534 void NCExtrapolationRS::Fit(Int_t PrintLevel)
00535 {
00536 
00537   // set up a Minuit to simultanisouly fit CC & NC spectra
00538 
00539   Double_t arglist[10];
00540   Int_t    ierr;
00541 
00542   TMinuit* gMinuit = new TMinuit(4);
00543 
00544   gMinuit->SetFCN(LogLikelihoodFunc); // Likelihood fit
00545 
00546   arglist[0] = PrintLevel;
00547   gMinuit->mnexcm("SET PRInt",arglist,1,ierr);
00548   if ( PrintLevel<-1 )
00549     gMinuit->mnexcm("SET NOWarning",arglist,0,ierr);
00550 //  arglist.at(0) = 0.5;
00551   arglist[0] = 1; // added a factor 2 to the likelihood function
00552   gMinuit->mnexcm("SET ERRor",arglist,1,ierr);
00553   //arglist.at(0) = 1e-5; // precision of function
00554   //gMinuit->mnexcm("SET EPS",arglist,1,ierr);
00555   arglist[0] = 1; // minimization strategy
00556   gMinuit->mnexcm("SET STR",arglist,1,ierr);
00557 
00558   // Set starting values
00559   Double_t par[4];
00560   for (Int_t i=0; i<4; i++)
00561     par[i] = m0ScaleNC.at(i);
00562 
00563   // set starting error
00564   Double_t step[4];
00565   for (Int_t i=0; i<4; i++)
00566     step[i] = m0ScaleNCErr.at(i);
00567 
00568   // define parameters
00569   for (Int_t i=0; i<4; i++) {
00570     char* name = Form("scaleNC_%i",i);
00571     gMinuit->DefineParameter(i,name, par[i], step[i],0., 0.); // unbounded
00572   }
00573   // start restricted fit first
00574 
00575   gMinuit->FixParameter(0);
00576   gMinuit->FixParameter(1);
00577   gMinuit->FixParameter(2);
00578 
00579   // do a scan
00580  //  arglist[0] = 5; // scan parameter no 4+1
00581 //   arglist[1] = 40;
00582 //   arglist[2] = 0.8;
00583 //   arglist[3] = 1.0;
00584 //   gMinuit->mnexcm("SCAn",arglist,4,ierr);
00585 //   TCanvas *cnew = new TCanvas("cnew","cnew");
00586 //   TGraph *gr = (TGraph*)gMinuit->GetPlot();
00587 //   cnew->cd();
00588 //   gr->Draw("ap");
00589 
00590   gMinuit->Migrad();
00591 
00592   gMinuit->Release(2);
00593   gMinuit->Migrad();
00594 
00595   gMinuit->Release(1);
00596   gMinuit->Migrad();
00597 
00598   gMinuit->Release(0);
00599   gMinuit->Migrad();
00600 
00601   // do MINOS error analysis
00602   gMinuit->mnmnos();
00603 
00604   // check convergence (still to do)
00605   TString convergence = gMinuit->fCstatu;
00606   MSG("NCExtrapolationRS",Msg::kInfo) << "Convergence status: "
00607                             << convergence << endl;
00608 
00609   // get result
00610   for (Int_t i=0; i<4; i++)
00611     gMinuit->GetParameter( i, mScaleNC.at(i),  mScaleNCErr.at(i) );
00612 
00613   Double_t mScaleNeg[4]; // positive and negative errors
00614                                           // from MINOS
00615   Double_t mScalePos[4];
00616   Double_t corr[4];
00617   // get proper asymmetric errors from MINOS fit
00618   for (Int_t i=0; i<4; i++)
00619     gMinuit->mnerrs(i,mScalePos[i], mScaleNeg[i],
00620                     mScaleNCErr[i],
00621                     corr[i] );
00622 
00623   // plot result
00624 
00625   if ( PrintLevel >-2 ) {
00626 
00627     Double_t LL;
00628     Double_t pars[4];
00629     Int_t    npar = 4;
00630 
00631     for (Int_t i=0; i<4; i++)
00632       pars[i] = mScaleNC.at(i);
00633 
00634     LogLikelihoodFunc(npar, pars, LL, pars, 0);
00635 
00636 
00637     std::vector<TH1D*> ratCC(fDataFraction.size(),0); // pointers for ratio
00638                                                       //  histogram
00639     std::vector<TH1D*> ratCCfit(fDataFraction.size(),0);
00640     std::vector<TH1D*> ratNC(fDataFraction.size(),0);
00641     std::vector<TH1D*> ratNCfit(fDataFraction.size(),0);
00642 
00643     for (UInt_t i=0; i<fDataFraction.size(); i++) {
00644       gROOT->cd();
00645       // Draw the best fit spectrum
00646       string canvas_name = (string) Form("cSpec_%i",i);
00647       TCanvas* cSpec = dynamic_cast<TCanvas*>
00648         ( gROOT->FindObjectAny(canvas_name.c_str()) );
00649       if (!cSpec) cSpec = new TCanvas(canvas_name.c_str(),canvas_name.c_str(),
00650                                       40,40,500,700);
00651       cSpec->Divide(1,2);
00652       cSpec->cd(1);
00653       HistEvisCCwt.at(i)->Draw();
00654       HistEvisCCrew.at(i)->SetLineColor(6);
00655       HistEvisCCrew.at(i)->Draw("sames");
00656       HistEvisCCd.at(i)->Draw("samepe");
00657 
00658       cSpec->cd(2);
00659       HistEvisNCwt.at(i)->Draw();
00660       HistEvisNCrew.at(i)->SetLineColor(6);
00661       HistEvisNCrew.at(i)->Draw("sames");
00662       HistEvisNCd.at(i)->Draw("samepe");
00663 
00664       // Draw the best fit mc/data ration
00665       canvas_name = (string) Form("cRat_%i",i);
00666       TCanvas* cRat = dynamic_cast<TCanvas*>
00667         ( gROOT->FindObjectAny(canvas_name.c_str()) );
00668       if (!cRat)  cRat = new TCanvas(canvas_name.c_str(),canvas_name.c_str(),
00669                                      40,40,500,700);
00670       cRat->Divide(1,2);
00671       ratCC.at(i) = dynamic_cast<TH1D*>( HistEvisCCd.at(i)->Clone("ratCC") );
00672       ratCCfit.at(i) = dynamic_cast<TH1D*>(
00673         HistEvisCCd.at(i)->Clone("ratCCfit") );
00674       ratCC.at(i)->Divide( HistEvisCCwt.at(i) );
00675       ratCCfit.at(i)->Divide( HistEvisCCrew.at(i) );
00676       ratNC.at(i) = dynamic_cast<TH1D*>( HistEvisNCd.at(i)->Clone("ratNC") );
00677       ratNCfit.at(i) = dynamic_cast<TH1D*>(
00678         HistEvisNCd.at(i)->Clone("ratNCfit") );
00679       ratNC.at(i)->Divide( HistEvisNCwt.at(i) );
00680       ratNCfit.at(i)->Divide( HistEvisNCrew.at(i) );
00681 
00682       cRat->cd(1);
00683       ratCC.at(i)->Draw();
00684       ratCCfit.at(i)->SetLineColor(6);
00685       ratCCfit.at(i)->GetYaxis()->SetRangeUser(0.5,1.5);
00686       ratCCfit.at(i)->Draw("sames");
00687       TLine *line = new TLine(0,1.0,30,1.0);
00688       line->Draw("same");
00689       cRat->cd(2);
00690       ratNC.at(i)->Draw();
00691       ratNCfit.at(i)->SetLineColor(6);
00692       ratNCfit.at(i)->GetYaxis()->SetRangeUser(0.5,1.5);
00693       ratNCfit.at(i)->Draw("sames");
00694       line->Draw("same");
00695     }
00696 
00697     MSG("NCExtrapolationRS",Msg::kInfo)
00698       << "The final likelihood is: LL=" << setprecision(10) << LL << endl;
00699 
00700     // write some stuff to a log file
00701     *logFile << "Fit results:" << endl;
00702     logFile->setf(ios::fixed);
00703     logFile->precision(5);
00704     for (Int_t i=0; i<4; i++)
00705       *logFile << "Par " << i << ": " << mScaleNC[i] << " +"
00706                << mScalePos[i] << " " << mScaleNeg[i] << " +/- "
00707                << mScaleNCErr.at(i) << ", Corr: " << corr[i] << endl;
00708 
00709     *logFile << "Convergence Status: " << convergence << endl
00710              << "Final Likelihood LL=" << LL << endl;
00711       // << "Written histograms to " << histofile->GetName() << endl;
00712     logFile->unsetf(ios::fixed);
00713 
00714 
00715     // get the number of d.o.f. from chi2 fit
00716     Int_t dof = 0;
00717     if (fUseChi2Function) {
00718       for (UInt_t i = 0; i<fDataFraction.size(); ++i ) {
00719         Double_t chi2 = -1;
00720         Int_t ndf =  -1;
00721         Int_t igood = 0;
00722         HistEvisNCd.at(i)->Chi2TestX(HistEvisNCrew.at(i),chi2,ndf,igood,
00723                                      "UUCHI2");
00724         dof += ndf;
00725         MSG("NCExtrapolationRS",Msg::kDebug) << "Ndf for beam " << i << ": "
00726                                              << ndf << endl;
00727         if (igood != 0)
00728           MSG("NCExtrapolationRS",Msg::kWarning) << "Chi2 igood parameter"
00729                                                  <<" is non-zero: "
00730                                        << igood << endl;
00731       }
00732     }
00733 
00734 
00735     //This bit of code may be useful if one wants to write out a result tree
00736 
00737     // write same info to fit tree
00738     //    fFitRes.likelihood = LL;
00739     //     for (Int_t i=0; i<4; i++) {
00740     //       fFitRes.parNo = i;
00741     //       fFitRes.inputScale = mInputScale[i];
00742     //       fFitRes.par = (Float_t) mScaleNC[i];
00743     //       fFitRes.err = (Float_t) mScaleNCErr[i];
00744     //       fFitRes.errPos = (Float_t) mScalePos[i];
00745     //       fFitRes.errNeg = (Float_t) mScaleNeg[i];
00746     //       fFitRes.dof = dof;
00747     //       fFitResTree->Fill();
00748     //     }
00749   }
00750 
00751   return;
00752 }
00753 //----------------------------------------------------------------------
00754 void NCExtrapolationRS::FillFluxRecoHists(Int_t i, MCEvent event) {
00755 
00756   // get SKZP error from relevant histograms
00757   Double_t errPlus, errMinus;
00758   Int_t maxBin = HistTrueEFluxErrPlus_nu.at(i)->GetNbinsX();
00759   Int_t EtrueBin = HistTrueEFluxErrPlus_nu.at(i)->FindBin(event.Enu);
00760   // energies higher than 20GeV get the value for 20 GeV
00761   EtrueBin = min(EtrueBin, maxBin);
00762 
00763   if (event.nuFlavor==14) {
00764     errPlus = HistTrueEFluxErrPlus_nu.at(i)->GetBinContent(EtrueBin);
00765     errMinus = HistTrueEFluxErrMinus_nu.at(i)->GetBinContent(EtrueBin);
00766   }
00767   else if (event.nuFlavor==-14) {
00768     errPlus = HistTrueEFluxErrPlus_nubar.at(i)->GetBinContent(EtrueBin);
00769     errMinus = HistTrueEFluxErrMinus_nubar.at(i)->GetBinContent(EtrueBin);
00770   }
00771   else
00772     errPlus = errMinus = 1.0;
00773 
00774   if (event.SelType==1) {
00775     HistCCFluxErrorPlus.at(i)->Fill(event.EvisCC,event.Weight*
00776                                     errPlus*event.BeamWeight);
00777     HistCCFluxErrorMinus.at(i)->Fill(event.EvisCC,event.Weight*
00778                                      errMinus*event.BeamWeight);
00779   }
00780   else if (event.SelType==0) {
00781     HistNCFluxErrorPlus.at(i)->Fill(event.Evis, event.Weight*
00782                                     errPlus*event.BeamWeight);
00783     HistNCFluxErrorMinus.at(i)->Fill(event.Evis, event.Weight*
00784                                      errMinus*event.BeamWeight);
00785   }
00786 
00787   return;
00788 }
00789 //----------------------------------------------------------------------
00790 
00791 Double_t NCExtrapolationRS::GetChiSquare(Int_t selection, Int_t beam) {
00792 
00793   // simple ChiSquare test of agreement between MC and data
00794 
00795   Double_t chi2 = 0;
00796   Int_t dof = 0;
00797 
00798   if (selection==1) {
00799     dof  = sFit->HistEvisCCd.at(beam)->GetNbinsX();
00800 
00801     for (Int_t i=1; i<=(dof+1); i++) {   //include overflow
00802       Double_t data = sFit->HistEvisCCd.at(beam)->GetBinContent(i);
00803       Double_t mc = sFit->HistEvisCCrew.at(beam)->GetBinContent(i);
00804       Double_t diff = data - mc;
00805       if ((mc > 5) && (data>0)) {
00806         chi2 += diff*diff/data;
00807       }
00808       else {
00809         MSG("NCExtrapolationRS",Msg::kWarning) << "Too few entries in bin "
00810                                                << i << ", beam " << beam
00811                                                << endl;
00812         dof--;
00813       }
00814     }
00815   }
00816 
00817   else if (selection==0) {
00818     dof  = sFit->HistEvisNCd.at(beam)->GetNbinsX();
00819 
00820     for (Int_t i=1; i<=(dof+1); i++) { // include overflow
00821       Double_t data = sFit->HistEvisNCd.at(beam)->GetBinContent(i);
00822       Double_t mc = sFit->HistEvisNCrew.at(beam)->GetBinContent(i);
00823       Double_t diff = data - mc;
00824       if ((mc > 5) && (data>0)) {
00825         chi2 += diff*diff/data;
00826       }
00827       else {
00828         MSG("NCExtrapolationRS",Msg::kWarning) << "Too few entries in bin "
00829                                                << i << ", beam " << beam
00830                                                << endl;
00831         dof--;
00832       }
00833     }
00834   }
00835   else {
00836     MSG("NCExtrapolationRS",Msg::kInfo)
00837       << "Invalid selection type. Chose 0==NC or 1==CC." << endl;
00838     return 0;
00839   }
00840 
00841   MSG("NCExtrapolationRS",Msg::kDebug)
00842     << "Calculated Chi2 " << chi2 << " for " << dof << " d.o.f."
00843     << endl;
00844 
00845   return chi2;
00846 }
00847 
00848 //----------------------------------------------------------------------
00849 
00850 //LogLikelihood fit function.
00851 void NCExtrapolationRS::LogLikelihoodFunc(Int_t &npar,
00852                                           Double_t *gin,
00853                                           Double_t &f,
00854                                           Double_t *pars,
00855                                           Int_t iflag)
00856 {
00857   iflag++; // NOT USED FOR ANYTHING, JUST TO QUIET THE COMPILER
00858   if (0)  cout << gin << npar << endl;
00859 
00860   f = 0;
00861 
00862 //   //  cout << "Parameter 5: " << pars[4];
00863 
00864 //   // cross section reweighting MC using neugen parameters
00865 //   //  sFit->Reweight(ma_qe,ma_res,kno112,kno122,kno113,kno123,false);
00866 
00867   for(uint i = 0; i < (sFit->fDataFraction).size(); ++i){
00868     sFit->HistEvisNCrew.at(i)->Reset();
00869     sFit->HistEvisCCrew.at(i)->Reset();
00870   }
00871 
00872   // now fill Reweighted Histograms
00873   // do something faster than histogram filling
00874 
00875   for(uint i = 0; i < (sFit->fBeams).size(); ++i){
00876 
00877     // do not use FD events in NearFit -- FD are also in fBeams vector
00878     if ((sFit->fBeams).at(i).GetDetector()!= Detector::kNear)
00879       continue;
00880 
00881     Int_t    CCStartBin = 0;
00882     Int_t    CCStopBin  = sFit->HistEvisCC.at(i)->GetNbinsX()+1;
00883     Double_t CCEmin     = sFit->HistEvisCC.at(i)->GetBinLowEdge(1);
00884     Double_t CCDeltaE   = sFit->HistEvisCC.at(i)->GetBinWidth(1);
00885     std::vector<Double_t> CCSignal(CCStopBin+1,0.);
00886     std::vector<Double_t> CCBackground(CCStopBin+1,0.);
00887 
00888     Int_t    NCStartBin = 0;
00889     Int_t    NCStopBin  = sFit->HistEvisNC.at(i)->GetNbinsX()+1;
00890     Double_t NCEmin     = sFit->HistEvisNC.at(i)->GetBinLowEdge(1);
00891     Double_t NCDeltaE   = sFit->HistEvisNC.at(i)->GetBinWidth(1);
00892     std::vector<Double_t> NCSignal(NCStopBin+1,0.);
00893     std::vector<Double_t> NCBackground(NCStopBin+1,0.);
00894 
00895     Int_t index = 0;
00896 
00897     std::vector<MCEvent>::iterator mcIt;
00898     for (mcIt=sFit->fMCListNear.at(i)->begin();
00899          mcIt<sFit->fMCListNear.at(i)->end(); mcIt++) {
00900 
00901       MCEvent event = (*mcIt);
00902       // use four wide bins in true E
00903       Int_t trueBin = -1;
00904       if (event.Enu < 4)
00905         trueBin = 0;
00906       else if (event.Enu < 8)
00907         trueBin = 1;
00908       else if (event.Enu < 15)
00909         trueBin = 2;
00910       else if (event.Enu < 120)
00911         trueBin = 3;
00912       else
00913         trueBin = 99;
00914 
00915       // include SKZP reweighting
00916       Double_t weight = event.BeamWeight*event.Weight;
00917       //Double_t weight = 1.0;
00918 
00919       if ( event.SelType==0 ) {
00920         // this is NC selected
00921         Double_t evis = event.Evis; // total calorimetric energy
00922         if (evis>100) index = NCStopBin;
00923         else {
00924           index = static_cast<Int_t>( ( evis-NCEmin )/ NCDeltaE ) + 1 ;
00925           index = min(index,NCStopBin);
00926           index = max(index,NCStartBin);
00927         }
00928         // do the scaling on true energy here
00929         if (event.McType==0 && trueBin<4)
00930           weight *= pars[trueBin];
00931 
00932         NCSignal.at(index) += weight;
00933 
00934         if (event.McType==1 ) {
00935           NCBackground.at(index) += weight;
00936         }
00937       }
00938       else if (event.SelType==1){
00939         // this in CC selected
00940         Double_t evis = event.EvisCC; // track+shower energy
00941         if (evis>100) index = CCStopBin;
00942         else {
00943           index = (Int_t) ( ( evis-CCEmin )/ CCDeltaE ) + 1;
00944           index = min(index,CCStopBin);
00945           index = max(index,CCStartBin);
00946         }
00947         if (event.McType==0 && trueBin<5) {
00948           // do the scaling on true energy here
00949           weight *= pars[trueBin];
00950         }
00951         CCSignal.at(index) += weight;
00952 
00953         if (event.McType ==0 ) {
00954           CCBackground.at(index) += weight;
00955         }
00956       }
00957     }
00958 
00959     Double_t CCInt     = 0.;
00960     Double_t NCInt     = 0.;
00961     Double_t CCdInt     = 0.;
00962     Double_t NCdInt     = 0.;
00963     Double_t binContent = 0.;
00964     //    Double_t scale = sFit->fDataFraction.at(i);
00965     Double_t scale =
00966       sFit->fDataFraction[BeamType::ToZarko((sFit->fBeams[i]).GetBeamType())];
00967     // decide whether data is scaled to MC or vice versa
00968     if (!sFit->fScaleToData.at(i))
00969       scale = 1.0;
00970 
00971     const Double_t minContent = .001;
00972 
00973     // fill histograms from arrays
00974     for (Int_t ibin = CCStartBin; ibin<=CCStopBin; ibin++) {
00975       binContent = max(minContent,CCSignal[ibin])*scale;
00976       sFit->HistEvisCCrew.at(i)->SetBinContent(ibin,binContent);
00977       CCInt += binContent;
00978 
00979       // sum up all data events
00980       CCdInt += sFit->HistEvisCCd.at(i)->GetBinContent(ibin);
00981     }
00982 
00983     for (Int_t ibin = NCStartBin; ibin<=NCStopBin; ibin++) {
00984       binContent = max( minContent,NCSignal.at(ibin) )*scale;
00985       sFit->HistEvisNCrew.at(i)->SetBinContent(ibin,binContent);
00986 
00987       if (sFit->fCutLowBins) { // cut out bins 0-2
00988         if (ibin>2)
00989           NCInt += binContent;
00990       }
00991       else
00992         NCInt += binContent;
00993       NCdInt += sFit->HistEvisNCd.at(i)->GetBinContent(ibin);
00994     }
00995 
00996     // now calculate the LL contributions (including under and overflows
00997 
00998     // fitting with Maximum Likelihood
00999     if (!sFit->fUseChi2Function) {
01000       MAXMSG("NCExtrapolationRS",Msg::kInfo,1) << "Using LL test..." << endl;
01001 
01002       // this is for fitting without the bottom two bins
01003       if (sFit->fCutLowBins)
01004         NCStartBin +=3; // cut out bins 0-2
01005 
01006       // contribution from NC shape
01007       for(Int_t ibin = NCStartBin; ibin<=NCStopBin; ibin++) {
01008         f -= sFit->HistEvisNCd.at(i)->GetBinContent(ibin)
01009           * log( sFit->HistEvisNCrew.at(i)->GetBinContent(ibin) );
01010       }
01011       // contribution from NC normalisation
01012       f += NCInt;
01013     }
01014     else {
01015       // fitting with a Chi2 function
01016       MAXMSG("NCExtrapolationRS",Msg::kInfo,1) << "Using Chi2 test..." << endl;
01017       f += sFit->GetChiSquare(0,i); // add chi2 for NC histos
01018     }
01019 
01020   }  // loop over fBeams.size()
01021 
01022   f *= 2; // include factor 2 in order to keep error definitions
01023   // as in a chi2 function
01024   // this also means, the UP value for errors is 1 (not 0.5)
01025 
01026   return;
01027 }
01028 //----------------------------------------------------------------------
01029 //this method does the fit based on events in the near detector
01030 void NCExtrapolationRS::PrepareNearDetector()
01031 {
01032   //Fit happens here
01033   //MSG("NCExtrapolationRS",Msg::kInfo)
01034   //  << "Not doing fit now. Just debugging histos" << endl;
01035 
01036   DoFit(1);
01037   return;
01038 }
01039 
01040 //----------------------------------------------------------------------
01041 //this method does the fit in the far detector
01042 void NCExtrapolationRS::PredictSpectrum()
01043 {
01044   PlotFinalDists();
01045 
01046   OscillationFit();
01047 
01048   return;
01049 }
01050 //----------------------------------------------------------------------
01051 void NCExtrapolationRS::UseFakeData(Bool_t fake) {
01052   fFakeData = fake;
01053   if (fake) {
01054     for (UInt_t i=0; i<fDataFraction.size(); ++i){
01055       fDataFraction[BeamType::ToZarko(fBeams[i].GetBeamType())] = 1.0;
01056     }
01057 
01058     MSG("NCExtrapolationRS",Msg::kInfo) << "Running on fake data" << endl
01059                                         << "Setting data fraction to 1.0"
01060                                         << endl;
01061     *logFile << "Running on fake data." << endl;
01062   }
01063   else
01064     *logFile << "Running on REAL data." << endl;
01065 
01066   return;
01067 }
01068 
01069 //----------------------------------------------------------------------
01070 //this method writes out fit results
01071 void NCExtrapolationRS::WriteResources()
01072 {
01073   // scale default MC histograms by bin width in order to compare to others
01074   for(uint i = 0; i < fBeams.size(); ++i){
01075     // only deal with FD
01076     if (fBeams[i].GetDetector() != Detector::kFar) continue;
01077 
01078     TH1 *defCC = fBeams[i].GetDefaultMCHistogram(NCType::kCC);
01079     for (int bin = 1; bin <= defCC->GetNbinsX(); ++bin) {
01080       Double_t val = defCC->GetBinContent(bin);
01081       Double_t err = defCC->GetBinError(bin);
01082       Double_t width = defCC->GetBinWidth(bin);
01083       defCC->SetBinContent(bin, val/width);
01084       defCC->SetBinError(bin, err/width);
01085     } // CC bins
01086     TH1 *defNC = fBeams[i].GetDefaultMCHistogram(NCType::kNC);
01087     for (int bin = 1; bin <= defNC->GetNbinsX(); ++bin) {
01088       Double_t val = defNC->GetBinContent(bin);
01089       Double_t err = defNC->GetBinError(bin);
01090       Double_t width = defNC->GetBinWidth(bin);
01091       defNC->SetBinContent(bin, val/width);
01092       defNC->SetBinError(bin, err/width);
01093     }  // NC bins
01094   } // fBeams
01095 
01096   NCExtrapolation::WriteResources();
01097 
01098   MSG("NCExtrapolationRS", Msg::kInfo)
01099     << "NCExtrapolationRS::WriteResources()" << endl;
01100 
01101   // get a pointer to the current directory
01102   // this is one of the output files
01103   TDirectory* saveDir = gDirectory;
01104   TString plotsDirName = "plots"
01105     +NCType::kExtrapolationNames[fExtrapolationType];
01106 
01107   TDirectory* plotsDir = (TDirectory*) gROOT->FindObjectAny(plotsDirName.Data());
01108   if (plotsDir)
01109     plotsDir->cd();
01110   else
01111     MSG("NCExtrapolationRS", Msg::kError) << "Cannot find directory "
01112                                           << plotsDirName << endl;
01113 
01114   for(uint i = 0; i < fDataFraction.size(); ++i){
01115     HistEnu.at(i)->Write();
01116     HistEvisCC.at(i)->Write();
01117     HistEvisCCwt.at(i)->Write();
01118     HistEvisCCrew.at(i)->Write();
01119     HistEvisCCb.at(i)->Write();
01120     HistEvisCCd.at(i)->Write();
01121     HistEvisNC.at(i)->Write();
01122     HistEvisNCwt.at(i)->Write();
01123     HistEvisNCrew.at(i)->Write();
01124     HistEvisNCb.at(i)->Write();
01125     HistEvisNCd.at(i)->Write();
01126 
01127     for (uint bin = 0; bin < HistEvisCCtrueBin.at(i).size(); ++bin) {
01128       HistEvisCCtrueBin.at(i).at(bin)->Write();
01129       HistEvisNCtrueBin.at(i).at(bin)->Write();
01130     }
01131     string cName = (string) Form("cSpec_%i",i);
01132     TCanvas* canv =
01133       dynamic_cast<TCanvas*>( gROOT->FindObjectAny(cName.c_str()) );
01134     if (canv) canv->Write();
01135     else MSG("NCExtrapolationRS",Msg::kWarning) << "Can't find canvas "
01136                                                 << cName.c_str() << endl;
01137     cName = (string) Form("cRat_%i",i);
01138     canv =
01139       dynamic_cast<TCanvas*>( gROOT->FindObjectAny(cName.c_str()) );
01140     if (canv) canv->Write();
01141     else MSG("NCExtrapolationRS",Msg::kWarning) << "Can't find canvas "
01142                                                 << cName.c_str() << endl;
01143     cName = (string) Form("cFinalDists_%i",i);
01144     canv =
01145       dynamic_cast<TCanvas*>( gROOT->FindObjectAny(cName.c_str()) );
01146     if (canv) canv->Write();
01147     else MSG("NCExtrapolationRS",Msg::kWarning) << "Can't find canvas "
01148                                                 << cName.c_str() << endl;
01149 
01150 
01151   }
01152   saveDir->cd();
01153 
01154   return;
01155 
01156 }
01157 //----------------------------------------------------------------------
01158 // this method makes the coloured contributions-to-the-spectrum plots
01159 void NCExtrapolationRS::PlotFinalDists() {
01160   MSG("NCExtrapolationRS",Msg::kDebug) << "Running PlotFinalDists()..."
01161                                        << endl;
01162 
01163   for(uint i = 0; i < fBeams.size(); ++i){
01164 
01165     // only plot stuff for ND for the moment
01166     if (fBeams.at(i).GetDetector()!= Detector::kNear)
01167       continue;
01168 
01169     std::vector<MCEvent>::iterator mcIt;
01170     for (mcIt=sFit->fMCListNear.at(i)->begin();
01171          mcIt<sFit->fMCListNear.at(i)->end(); mcIt++) {
01172 
01173       MCEvent event = (*mcIt);
01174       // use four wide bins in true E
01175       Int_t trueBin = -1;
01176       if (event.Enu < 4)
01177         trueBin = 0;
01178       else if (event.Enu < 8)
01179         trueBin = 1;
01180       else if (event.Enu < 15)
01181         trueBin = 2;
01182       else if (event.Enu < 120)
01183         trueBin = 3;
01184       else
01185         trueBin = 99;
01186 
01187       // include SKZP reweighting
01188       Double_t weight = event.BeamWeight*event.Weight;
01189 
01190       // do the scaling on true energy here
01191       if (event.McType==0 && trueBin<5)
01192         weight *= mScaleNC.at(trueBin);
01193 
01194       if ( event.SelType==0 ) {
01195         // this is NC selected
01196 
01197         HistEvisNCtrueBin.at(i).at(trueBin) -> Fill(event.Evis,weight);
01198       }
01199       else if (event.SelType==1){
01200         // this in CC selected
01201 
01202         HistEvisCCtrueBin.at(i).at(trueBin) -> Fill(event.EvisCC,weight);
01203       }
01204     } // event vector
01205 
01206     string canvName = (string)Form("cFinalDists_%i",i);
01207     TCanvas* cFinal = new TCanvas(canvName.c_str(),canvName.c_str(),
01208                                   40,40,500,700);
01209     cFinal->Divide(1,2);
01210     cFinal->cd(1);
01211     gPad->SetLogy();
01212 
01213     // scale according to fDataFraction and draw
01214     Double_t dataFrac = fDataFraction[BeamType::ToZarko(
01215                                         fBeams[i].GetBeamType())];
01216     HistEvisCCwt.at(i)->SetLineColor(2);
01217     if (fScaleToData.at(i)) HistEvisCCwt.at(i)->Scale(dataFrac);
01218     HistEvisCCwt.at(i)->Draw();
01219     HistEvisCCwt.at(i)->SetTitle(";E_{vis} (GeV);Events");
01220     HistEvisCCrew.at(i)->Draw("same");
01221     HistEvisCCd.at(i)->Draw("samepe");
01222     cFinal->cd(2);
01223     gPad->SetLogy();
01224     HistEvisNCwt.at(i)->SetLineColor(2);
01225     if (fScaleToData.at(i)) HistEvisNCwt.at(i)->Scale(dataFrac);
01226     HistEvisNCwt.at(i)->Draw();
01227     HistEvisNCwt.at(i)->SetTitle(";E_{vis} (GeV);Events");
01228     HistEvisNCrew.at(i)->Draw("same");
01229     HistEvisNCd.at(i)->Draw("samepe");
01230 
01231     TLegend *leg = new TLegend(0.6,0.6,0.9,0.9);
01232     leg->SetBorderSize(0);
01233 
01234     for (uint bin = 0; bin < HistEvisCCtrueBin.at(i).size();
01235          ++bin) {
01236       if (fScaleToData.at(i)) {
01237         HistEvisNCtrueBin.at(i).at(bin)->Scale(dataFrac);
01238         HistEvisCCtrueBin.at(i).at(bin)->Scale(dataFrac);
01239       }
01240       HistEvisNCtrueBin.at(i).at(bin)->SetLineColor(2*bin+2);
01241       HistEvisCCtrueBin.at(i).at(bin)->SetLineColor(2*bin+2);
01242 
01243       cFinal->cd(1);
01244       HistEvisCCtrueBin.at(i).at(bin)->Draw("same");
01245       cFinal->cd(2);
01246       HistEvisNCtrueBin.at(i).at(bin)->Draw("same");
01247     }
01248 
01249     leg->AddEntry(HistEvisNCtrueBin.at(i).at(0),"0-4  GeV","l");
01250     leg->AddEntry(HistEvisNCtrueBin.at(i).at(1),"4-8  GeV","l");
01251     leg->AddEntry(HistEvisNCtrueBin.at(i).at(2),"8-15 GeV","l");
01252     leg->AddEntry(HistEvisNCtrueBin.at(i).at(3),">15  GeV","l");
01253     leg->Draw();
01254 
01255   } //NBEAMS
01256 
01257   MSG("NCExtrapolationRS",Msg::kDebug) << "Finished PlotFinalDists()"
01258                                        << endl;
01259 }
01260 
01261 //----------------------------------------------------------------------
01262 // this method does a grid-search oscillation fit, using the predicted
01263 // spectrum
01264 void NCExtrapolationRS::OscillationFit() {
01265 
01266   MSG("NCExtrapolationRS",Msg::kDebug) << "Running OscillationFit()..."
01267                                        << endl;
01268 
01269   // check whether we have FD beam
01270   Bool_t farBeamPresent = false;
01271   Int_t farIndex = -1;
01272 
01273   for(uint i = 0; i < fBeams.size(); ++i){
01274     if(fBeams[i].GetDetector() == Detector::kFar) {
01275       farBeamPresent = true;
01276       farIndex = i;
01277     }
01278   }
01279 
01280   if (!farBeamPresent) {
01281     MSG("NCExtrapolationRS",Msg::kError)
01282       << "No FD beam; not doing oscillation fit." << endl;
01283     return;
01284 
01285   }
01286 
01287   double chiSqr = 1.e12;
01288 
01289   double minChiSqr = 1.e12;
01290   double bestDeltaMSqr = 0.;
01291   double bestUMu3Sqr2Theta = 0.;
01292   double bestUS3Sqr = 0.;
01293 
01294   //get the values on the boundary
01295   double minBoundChiSqr = 1.e12;
01296   double bestBoundSterile = 0.;
01297   double bestBoundDeltaMSqr = 0.;
01298 
01299   MSG("NCExtrapolationRS", Msg::kInfo) << "NCType::kNumDeltaMSqrBins = "
01300                                        << NCType::kNumDeltaMSqrBins << endl;
01301   MSG("NCExtrapolationRS", Msg::kInfo) << "NCType::kNumUS3SqrBins = "
01302                                        << NCType::kNumUS3SqrBins << endl;
01303   MSG("NCExtrapolationRS", Msg::kInfo) << "NCType::kNumUMu3SqrBins = "
01304                                        << NCType::kNumUMu3SqrBins << endl;
01305 
01306   //store the chi^2 values in delta m^2, fs
01307   //to make the contour you need to find delta chi^2 for the pairs of delta m^2
01308   //and fs.  minimize for the systematic parameters and sin^2 2theta at each
01309   //pair in delta m^2 - fs space - see bevington for justification
01310 
01311   vector <vector <vector <double> > > chiSqrPnts;
01312   chiSqrPnts.resize(NCType::kNumDeltaMSqrBins);
01313   for(int i=0; i<NCType::kNumDeltaMSqrBins; i++) {
01314     chiSqrPnts[i].resize(NCType::kNumUS3SqrBins);
01315     for(int j=0; j < NCType::kNumUS3SqrBins; j++) {
01316       chiSqrPnts[i][j].resize(NCType::kNumUMu3SqrBins);
01317       for(int k=0; k<NCType::kNumUMu3SqrBins; k++) {
01318         chiSqrPnts[i][j][k] = 0.0;
01319       }
01320     }
01321   }
01322 
01323   double dmPnts[NCType::kNumDeltaMSqrBins] = {0.};
01324   double fsPnts[NCType::kNumUS3SqrBins] = {0.};
01325   double ssPnts[NCType::kNumUMu3SqrBins] = {0.};
01326 
01327   double DeltaMSqrWidth   = (NCType::kDeltaMSqrEnd - NCType::kDeltaMSqrStart)
01328     / double(NCType::kNumDeltaMSqrBins);
01329   double UMu3SqrWidth      = (NCType::kUMu3SqrEnd - NCType::kUMu3SqrStart)
01330     / double(NCType::kNumUMu3SqrBins);
01331   double US3SqrWidth    = (NCType::kUS3SqrEnd - NCType::kUS3SqrStart)
01332     / double(NCType::kNumUS3SqrBins);
01333 
01334   // grid-search loops
01335   for(int dm = 0; dm < NCType::kNumDeltaMSqrBins; ++dm) {
01336     dmPnts[dm] = (NCType::kDeltaMSqrStart + (float(dm+1)*DeltaMSqrWidth)
01337                   - DeltaMSqrWidth/2.0) * 1.0e-3;
01338     MSG("NCExtrapolationRS",Msg::kVerbose) << "dm = " << dmPnts[dm]
01339                                            << " chiSqr = " << chiSqr
01340                                            << " minChiSqr = " << minChiSqr
01341                                            << endl;
01342 
01343     for(int fs = 0; fs < NCType::kNumUS3SqrBins; ++fs) {
01344       fsPnts[fs] = NCType::kUS3SqrStart + (float(fs+1)*US3SqrWidth
01345                                              - US3SqrWidth/2.0);
01346       MSG("NCExtrapolationRS",Msg::kVerbose) << "   fs = " << fsPnts[fs]
01347                                              << " chiSqr = " << chiSqr
01348                                              << " minChiSqr = " << minChiSqr
01349                                              << endl;
01350 
01351       for(int ss = 0; ss < NCType::kNumUMu3SqrBins; ++ss){
01352         ssPnts[ss] = NCType::kUMu3SqrStart + (float(ss+1)*UMu3SqrWidth
01353                                              - UMu3SqrWidth/2.0);
01354         MSG("NCExtrapolationRS",Msg::kVerbose) << "      ss = " << ssPnts[ss]
01355                                                << " chiSqr = " << chiSqr
01356                                                << " minChiSqr = " << minChiSqr
01357                                                << endl;
01358 
01359         // put in oscillation parameters for energy bins here
01360 //      fBeams[farIndex].SetOscillationParameters(ssPnts[ss],dmPnts[dm],
01361 //                                                fsPnts[fs]);
01362 
01363         chiSqr = this->GetChiSqr(fBeams[farIndex]);
01364         chiSqrPnts[dm][fs][ss] = chiSqr;
01365 
01366         if(chiSqr < minChiSqr){
01367           minChiSqr = chiSqr;
01368           bestDeltaMSqr = dmPnts[dm];
01369           bestUMu3Sqr2Theta = ssPnts[ss];
01370           bestUS3Sqr = fsPnts[fs];
01371         }
01372 
01373         //get the best fit on the boundary
01374         if(fs == 0 && chiSqr < minBoundChiSqr){
01375           minBoundChiSqr = chiSqr;
01376           bestBoundSterile =  fsPnts[fs];
01377           bestBoundDeltaMSqr = dmPnts[dm];
01378         }
01379 
01380       }//end loop over sin^2 values
01381     }//end loop over sterile fractions
01382   }//end loop over delta m^2
01383 
01384   // set NCExtrapolation data members to best fit values
01385   // and oscillation parameters for NCEnergyBins to best fit
01386   BestDeltaMSqr() = bestDeltaMSqr;
01387   BestUMu3Sqr() = bestUMu3Sqr2Theta;
01388   BestUS3Sqr() = bestUS3Sqr;
01389 //   fBeams[farIndex].SetOscillationParameters(fBestUMu3Sqr,fBestDeltaMSqr,
01390 //                                          fBestUS3Sqr);
01391 
01392   double delta = 1.0e10;
01393   //double confidenceLevel = 0.;
01394   double minUMu3SqrChiSqr = 0., minUS3SqrChiSqr = 0.;
01395   int minUMu3SqrIndex = 0, minUS3SqrIndex = 0;
01396 
01397   //Produce Delta Chi^2 for dm2 vs fsterile
01398   for(int dm = 0; dm < NCType::kNumDeltaMSqrBins; ++dm){
01399     for(int fs = 0; fs < NCType::kNumUS3SqrBins; ++fs){
01400       minUMu3SqrChiSqr = 1.0e10;
01401       for(int ss = 0; ss < NCType::kNumUMu3SqrBins; ++ss) {
01402         if(chiSqrPnts[dm][fs][ss] < minUMu3SqrChiSqr) {
01403           minUMu3SqrChiSqr = chiSqrPnts[dm][fs][ss];
01404           minUMu3SqrIndex = ss;
01405         }
01406       }
01407       fDeltaChiSqrDeltaMVsUS3Sqr->Fill(fsPnts[fs],dmPnts[dm]*1000.0,
01408                                          chiSqrPnts[dm][fs][minUMu3SqrIndex]);
01409       if(chiSqrPnts[dm][fs][minUMu3SqrIndex] < delta) {
01410         delta = chiSqrPnts[dm][fs][minUMu3SqrIndex];
01411       }
01412     }
01413   }
01414   // subtract minimum chi2 -- thus getting a DeltaChi2 surface
01415   for(int dm = 0; dm < NCType::kNumDeltaMSqrBins; ++dm){
01416     for(int fs = 0; fs < NCType::kNumUS3SqrBins; ++fs){
01417       fDeltaChiSqrDeltaMVsUS3Sqr->SetBinContent(fs+1, dm+1,
01418                                               fDeltaChiSqrDeltaMVsUS3Sqr
01419                                                   ->GetBinContent(fs+1, dm+1)
01420                                                   - delta);
01421     }
01422   }
01423 
01424   //Produce Delta Chi^2 for dm2 vs sin2
01425   delta = 1.0e10;
01426   for(int dm = 0; dm < NCType::kNumDeltaMSqrBins; ++dm){
01427     for(int ss = 0; ss < NCType::kNumUMu3SqrBins; ++ss){
01428       minUS3SqrChiSqr = 1.0e10;
01429       for(int fs = 0; fs < NCType::kNumUS3SqrBins; ++fs) {
01430         if(chiSqrPnts[dm][fs][ss] < minUS3SqrChiSqr) {
01431           minUS3SqrChiSqr = chiSqrPnts[dm][fs][ss];
01432           minUS3SqrIndex = fs;
01433         }
01434       }
01435       fDeltaChiSqrDeltaMVsUMu3Sqr->Fill(ssPnts[ss], dmPnts[dm]*1000.0,
01436                                        chiSqrPnts[dm][minUS3SqrIndex][ss]);
01437       if(chiSqrPnts[dm][minUS3SqrIndex][ss] < delta) {
01438         delta = chiSqrPnts[dm][minUS3SqrIndex][ss];
01439       }
01440     }
01441   }
01442   // subtract minimum chi2 -- thus getting a DeltaChi2 surface
01443   for(int dm = 0; dm < NCType::kNumDeltaMSqrBins; ++dm){
01444     for(int ss = 0; ss < NCType::kNumUMu3SqrBins; ++ss){
01445       fDeltaChiSqrDeltaMVsUMu3Sqr->SetBinContent(ss+1, dm+1,
01446                                               fDeltaChiSqrDeltaMVsUMu3Sqr
01447                                                 ->GetBinContent(ss+1, dm+1)
01448                                                 - delta);
01449     }
01450   }
01451 
01452 
01453   MSG("NCExtrapolationRS", Msg::kInfo) << "best fit (f_{s},sin^2(2theta),"
01454                                        << "Delta m^{2}) =  ("
01455                                        << bestUS3Sqr
01456                                        << "," << bestUMu3Sqr2Theta
01457                                        << "," << bestDeltaMSqr
01458                                        << "), chi^{2} = " << minChiSqr << endl;
01459 
01460 
01461 
01462 }
01463 
01464 //----------------------------------------------------------------------
01465 // this method returns the chi2 for the FD oscillation fit
01466 double NCExtrapolationRS::GetChiSqr(NCBeam& farBeam) {
01467 
01468   MSG("NCExtrapolationRS",Msg::kVerbose) << "Running GetChiSqr()"
01469                                          << endl;
01470 
01471   double chiSqr = 0.;
01472   //  double bg = 0.;
01473   double mc = 0.;
01474   double signal = 0.;
01475   double signalError = 0.;
01476 
01477   //loop over the bins to find the chisqr
01478   for(int j = 0; j < farBeam.GetNumberEnergyBins(NCType::kCC); ++j) {
01479 
01480     NCEnergyBin* energyBin = farBeam.GetEnergyBin(j, NCType::kCC);
01481     signal = energyBin->GetSignal();
01482     signalError = energyBin->GetSignalError();
01483 
01484     //mc already contains the value of the background as the
01485     //GetMCExpectationForBin returns the sum of MC signal and
01486     //background
01487     mc = energyBin->GetTotalMC();
01488 //     bg = energyBin->GetMCBackground() + energyBin->GetMCTau() + energyBin->GetMCElectron();
01489 
01490     //the following is the chi^2 for poisson distributed data:
01491     if(mc <= 0.) mc = 1.e-3;
01492 
01493     if(mc > 0.){
01494       chiSqr += mc;
01495       if(signal > 0.) chiSqr += signal*(TMath::Log( signal/mc ) - 1.);
01496       if (signal == 0.) chiSqr += -1*signal;
01497     }
01498   } // CC loop
01499 
01500   // NC loop
01501   for(int j = 0; j < farBeam.GetNumberEnergyBins(NCType::kNC); ++j) {
01502 
01503     NCEnergyBin* energyBin = farBeam.GetEnergyBin(j, NCType::kNC);
01504     signal = energyBin->GetSignal();
01505     signalError = energyBin->GetSignalError();
01506 
01507     //mc already contains the value of the background as the
01508     //GetMCExpectationForBin returns the sum of MC signal and
01509     //background
01510     mc = energyBin->GetTotalMC();
01511 //     bg = energyBin->GetMCBackground() + energyBin->GetMCTau() + energyBin->GetMCElectron();
01512 
01513     //the following is the chi^2 for poisson distributed data:
01514     if(mc < 0.) mc = 1.e-3;
01515 
01516     if(mc > 0.){
01517       chiSqr += mc;
01518       if(signal > 0.) chiSqr += signal*(TMath::Log( signal/mc ) - 1.);
01519 
01520     }
01521   } // NC loop
01522 
01523   //have to multiply by 2
01524   chiSqr *= 2.;
01525 
01526   MSG("NCExtrapolationRS", Msg::kVerbose) << "chi^2 = " << chiSqr << endl;
01527 
01528 
01529 
01530 
01531 
01532 /*
01533 
01534   //add in the penalty terms
01535 
01536   for(uint i = 0; i < fParameters.size(); ++i){
01537     if(fFitParameters[i]){
01538       chiSqr += (fParameters[i]*fParameters[i])/(fParameterSigmas[i]*fParameterSigmas[i]);
01539 
01540       MSG("NCExtrapolationRS", Msg::kDebug) << i << " "
01541                                             <<  fParameters[i] << " "
01542                                             << fParameterSigmas[i] << " "
01543                                             << chiSqr << endl;
01544     }
01545   }
01546 
01547   if(fFittingShower) chiSqr += ((kChangeValuesShower[fShowerSystematic]*kChangeValuesShower[fShowerSystematic]) /
01548                                 (fParameterSigmas[NCType::kShowerEnergy]*fParameterSigmas[NCType::kShowerEnergy]));
01549   if(fFittingTrack) chiSqr += ((kChangeValuesTrack[fTrackSystematic]*kChangeValuesTrack[fTrackSystematic]) /
01550                                 (fParameterSigmas[NCType::kTrackEnergy]*fParameterSigmas[NCType::kTrackEnergy]));
01551 */
01552 
01553   return chiSqr;
01554 }

Generated on Mon Jun 16 14:57:51 2008 for loon by  doxygen 1.3.9.1