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

NuTransitionFitterMinuit.cxx

Go to the documentation of this file.
00001 
00002 // $Id: NuTransitionFitterMinuit.cxx,v 1.4 2008/03/18 21:14:22 ahimmel Exp $
00003 //
00004 // Performs Matrix Method analyses using Minuit2.
00005 //
00006 // Alexander Himmel
00007 // ahimmel@caltech.edu
00008 //
00009 // $Log: NuTransitionFitterMinuit.cxx,v $
00010 // Revision 1.4  2008/03/18 21:14:22  ahimmel
00011 //
00012 //
00013 // Some small changes to make the fitter happy.
00014 //
00015 // Revision 1.3  2008/03/07 23:51:07  ahimmel
00016 //
00017 //
00018 // Minor changes to keep Minuit happy.
00019 //
00020 // Revision 1.2  2008/03/03 22:05:00  ahimmel
00021 //
00022 //
00023 // Some bug fixes.
00024 //
00025 // Revision 1.1  2008/03/01 00:29:33  ahimmel
00026 //
00027 //
00028 // A minuit fitter for transitions.  Should speed up the fitting stage.  Also, more careful memory management should increase the maximum number of trial experiments.
00029 //
00031 
00032 #include "TFile.h"
00033 #include "TFitterMinuit.h"
00034 #include "TH1D.h"
00035 #include "TH1F.h"
00036 #include "TMath.h"
00037 #include "TROOT.h"
00038 
00039 #include "Conventions/Munits.h"
00040 #include "MessageService/MsgService.h"
00041 #include "NtupleUtils/NuTransitionFitterMinuit.h"
00042 #include "NtupleUtils/NuMatrixInput.h"
00043 #include "NtupleUtils/NuMatrixOutput.h"
00044 #include "NtupleUtils/NuFluctuator.h"
00045 #include "NtupleUtils/NuXMLConfig.h"
00046 
00047 ClassImp(NuTransitionFitterMinuit)
00048 
00049 CVSID("$Id: NuTransitionFitterMinuit.cxx,v 1.4 2008/03/18 21:14:22 ahimmel Exp $");
00050 
00051 
00055 NuTransitionFitterMinuit::NuTransitionFitterMinuit()
00056 {
00057     mmInput = 0;
00058     fdData = 0;
00059     fdFitData = 0;
00060     fxml = 0;
00061     
00062     outputFileName = "";
00063     
00064     fFitter = new TFitterMinuit();
00065     fFitter->CreateMinimizer();
00066     fFitter->SetMinuitFCN(this);
00067 }
00068 
00069 
00074 NuTransitionFitterMinuit::NuTransitionFitterMinuit(const TString mmFile, 
00075                                                    const TString fdFile, 
00076                                                    const TString outFile)
00077 {   
00078     // mmInput, fxml
00079     TFile *infile = new TFile(mmFile);
00080     mmInput = new NuMatrixInput(infile);
00081     TString objName = "NuMatrixOutput";
00082     fxml = (NuXMLConfig*)gROOT->FindObject("NuXMLConfig");
00083     infile->Close();   
00084     
00085     // fdData
00086     TFile *fdDataFile = new TFile(fdFile,"READ");
00087     fdData = (TH1D*) fdDataFile->Get("RecoEnergyPQ_FD");
00088     fdData->SetDirectory(0);
00089     fdData->Sumw2();
00090     fdDataFile->Close();
00091     
00092     outputFileName = outFile;
00093     
00094     fdFitData = 0;
00095     
00096     fFitter = new TFitterMinuit();
00097     fFitter->CreateMinimizer();
00098     fFitter->SetMinuitFCN(this);
00099 }
00100 
00101 
00105 NuTransitionFitterMinuit::~NuTransitionFitterMinuit()
00106 {
00107     if (mmInput) delete mmInput;
00108     if (fdData) delete fdData;
00109     if (fdFitData) delete fdFitData;
00110     if (fxml) delete fxml;    
00111     
00112     if (fFitter) delete fFitter;
00113 }
00114 
00115 
00121 void NuTransitionFitterMinuit::SetupPars()
00122 {
00123     // Fitted Physics Parameters
00124     fFitter->SetParameter(0, "prob", 
00125                           0.1, 0.01, 
00126                           1.0, 0.0);
00127     
00128     // Fixed Physics Parameters
00129     fFitter->SetParameter(1, "dm2", 
00130                           fxml->DM2Nu(), 0.1,
00131                           1.0, 0.0);
00132     if (!fFitter->IsFixed(1)) fFitter->FixParameter(1);  
00133     
00134     fFitter->SetParameter(2, "sn2", 
00135                           fxml->SN2Nu(), 0.01,
00136                           1.0,0.0);
00137     if (!fFitter->IsFixed(2)) fFitter->FixParameter(2);
00138     
00139     if (fxml->DM2Nu() !=  fxml->DM2Bar() || fxml->SN2Nu() !=  fxml->SN2Bar()) {
00140         MAXMSG("NuTransitionFitterMinuit",Msg::kWarning,1) 
00141         << "Nu and NuBar oscillation parameters don't match.  This is not accounted for." << endl;
00142     }
00143     
00144     /*
00145     // Systematic Parameters (fixed for now)
00146     fFitter->SetParameter(3, "Normalisation", 
00147                           1.0, 0.01,
00148                           1.0, 0.0);
00149     if (!fFitter->IsFixed(3)) fFitter->FixParameter(3);
00150     */
00151 }
00152 
00153 
00157 const Double_t NuTransitionFitterMinuit::CalculateChi2(const TH1D* fdPred, const TH1D* fdData) const
00158 {
00159     Double_t chi2 = 0;
00160     Double_t mnu, dnu;
00161     for (Int_t i=1; i<=fdPred->GetNbinsX(); ++i){
00162         mnu = fdPred->GetBinContent(i);
00163         dnu = fdData->GetBinContent(i);
00164         if (mnu<0.0001) mnu = 0.0001;
00165         chi2 += (dnu-mnu)*(dnu-mnu)/mnu;
00166     }
00167     return chi2;
00168 }
00169 
00170 
00175 const Double_t NuTransitionFitterMinuit::CalculateLikelihood(const TH1D* fdPred, const TH1D* fdData) const
00176 {
00177     Double_t like = 0;   
00178     Double_t mnu, dnu;
00179     for (Int_t i=6; i<=fdPred->GetNbinsX(); ++i){
00180         mnu = fdPred->GetBinContent(i);
00181         dnu = fdData->GetBinContent(i);
00182         if (mnu<0.0001) mnu = 0.0001;
00183         like += 2*(mnu - dnu);
00184         if (dnu) like += 2*dnu*log(dnu/mnu);
00185     }
00186     return like;
00187 }
00188 
00189 
00194 /*
00195 const Double_t NuTransitionFitterMinuit::CalculateUnbinnedLikelihood(const TH1D* fdPred, vector<double> fdData) const
00196 {
00197     // Just a placeholder right now
00198 }
00199 */
00200 
00201 
00206 void NuTransitionFitterMinuit::TransitionFit(const Int_t experiments)
00207 {
00208   // Initialize
00209     TString name = "";
00210     TString objName = "NuMatrixOutput";
00211     
00212     MSG("NuTransitionFitterMinuit",Msg::kInfo) << "Recreating file " << outputFileName << endl;
00213     TFile *outputFile = new TFile(outputFileName,"RECREATE");
00214     
00215     NuMatrixOutput *mmOutput = 0;
00216     NuFluctuator *fl = new NuFluctuator();
00217     
00218     TH1F *bestFits = new TH1F("bestFits","Best Fit Points",175,-0.5,1.25);
00219     
00220     
00221     // Perform an unfluctuated fit
00222     mmOutput = DoTransitionFit(*fdData);
00223     
00224     if (fxml) mmOutput->XMLConfig(fxml);    
00225     name = objName + "_";
00226     name += "nofluct";
00227     outputFile->WriteObject(mmOutput,name);
00228     
00229     delete mmOutput;
00230     
00231     // Perform fluctuated fits
00232     for (int i = 0; i < experiments; i++) {
00233         mmOutput = DoTransitionFit(fl->Fluctuate(fdData));
00234 
00235         bestFits->Fill(mmOutput->bestTransitionProb);
00236         
00237         if (fxml) mmOutput->XMLConfig(fxml);
00238         name = objName + "_";
00239         name += i;
00240         outputFile->WriteObject(mmOutput,name);
00241         
00242         delete mmOutput;
00243     }
00244     
00245     // Write Best Fits and close the file
00246     outputFile->WriteObject(bestFits,bestFits->GetName());
00247     outputFile->Close();
00248     MSG("NuTransitionFitterMinuit",Msg::kInfo) 
00249     << "Don't mind the segfault.  Everything is done and it appears to be harmless." << endl;
00250 }
00251 
00252 
00257 NuMatrixOutput* NuTransitionFitterMinuit::DoTransitionFit(const TH1D &hDataToFit)
00258 {
00259     // Setup
00260     this->SetupPars();
00261     fdFitData = new TH1D(hDataToFit);
00262     
00263     for (int i = 1; i < 3; i++) {
00264         if (!fFitter->IsFixed(i)) {
00265             cout << "Refixing parameter " << i << endl;
00266             fFitter->FixParameter(i);
00267         }
00268     }
00269 
00270     // Perform Fit
00271     fFitter->Minimize();
00272     
00273     // Get Results
00274     //fFitter->PrintResults(0,0);
00275     
00276     Double_t prob = fFitter->GetParameter(0);
00277     Double_t dm2 = fFitter->GetParameter(1);
00278     Double_t sn2 = fFitter->GetParameter(2);
00279 
00280     // Create Output Object
00281     NuMatrixOutput *mmOutput = new NuMatrixOutput();
00282     mmOutput->NuMuBarFDData(fdFitData);    
00283     mmOutput->NuMuBarBestFitFDPrediction(*mmInput->PredictFDSpectrumTransition(dm2, sn2, prob));
00284     mmOutput->NuMuBarNoTransPrediction(*mmInput->PredictFDSpectrumTransition(dm2, sn2, 0.));
00285     mmOutput->NuMuBarNoOscPrediction(*mmInput->PredictFDSpectrumTransition(0., 0., 0.));
00286     mmOutput->BestFitPoint(sn2, dm2, prob);
00287     
00288     // Clean up and return
00289     delete fdFitData; fdFitData = 0;
00290     return mmOutput;
00291 }
00292 
00293 
00297 double NuTransitionFitterMinuit::operator () (const vector<double>& pars) const
00298 {
00299     // Track Fitter Calls
00300     static Int_t fitcounter = 0;
00301     if (!(fitcounter%50)){
00302         MSG("NuTransitionFitterMinuit",Msg::kDebug) << "Minuit TF call " << fitcounter << endl;
00303     }
00304     ++fitcounter;
00305 
00306     // Get Current Parameters
00307     Double_t prob = pars[0];
00308     Double_t dm2 = pars[1];
00309     Double_t sn2 = pars[2];
00310     //Double_t normalisation = pars[3];
00311     
00312     // Predict the FD Spectrum for these parameters
00313     TH1D *fdFitPred = mmInput->PredictFDSpectrumTransition(dm2, sn2, prob);
00314     
00315     // Apply systematics
00316     // fdFitPred->Scale(normalisation);
00317 
00318     // Calculate our goodness-of-fit test, T
00319     double T = this->CalculateLikelihood(fdFitPred,fdFitData);
00320     
00321     // Apply penalty terms
00322     // Example of normalisation penalty term for center = 1, error = 0.04
00323     // T += (normalisation - 1)*(normalisation - 1) / (0.04 * 0.04); 
00324     
00325     // Clean Up
00326     delete fdFitPred; fdFitPred = 0;
00327 
00328     return T;
00329 }
00330 
00331 

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