00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
00124 fFitter->SetParameter(0, "prob",
00125 0.1, 0.01,
00126 1.0, 0.0);
00127
00128
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
00146
00147
00148
00149
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
00196
00197
00198
00199
00200
00201
00206 void NuTransitionFitterMinuit::TransitionFit(const Int_t experiments)
00207 {
00208
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
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
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
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
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
00271 fFitter->Minimize();
00272
00273
00274
00275
00276 Double_t prob = fFitter->GetParameter(0);
00277 Double_t dm2 = fFitter->GetParameter(1);
00278 Double_t sn2 = fFitter->GetParameter(2);
00279
00280
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
00289 delete fdFitData; fdFitData = 0;
00290 return mmOutput;
00291 }
00292
00293
00297 double NuTransitionFitterMinuit::operator () (const vector<double>& pars) const
00298 {
00299
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
00307 Double_t prob = pars[0];
00308 Double_t dm2 = pars[1];
00309 Double_t sn2 = pars[2];
00310
00311
00312
00313 TH1D *fdFitPred = mmInput->PredictFDSpectrumTransition(dm2, sn2, prob);
00314
00315
00316
00317
00318
00319 double T = this->CalculateLikelihood(fdFitPred,fdFitData);
00320
00321
00322
00323
00324
00325
00326 delete fdFitPred; fdFitPred = 0;
00327
00328 return T;
00329 }
00330
00331