implemented max log likelihood, and other things
This commit is contained in:
@ -60,9 +60,9 @@ LIBS = $(ROOTLIBS) -lXMLParser
|
|||||||
GLIBS = $(ROOTGLIBS) -lXMLParser
|
GLIBS = $(ROOTGLIBS) -lXMLParser
|
||||||
|
|
||||||
# PSI libs
|
# PSI libs
|
||||||
PSILIBS = -lTLemRunHeader -lPMusr
|
#PSILIBS = -lTLemRunHeader -lPMusr
|
||||||
# Minuit2 lib
|
# Minuit2 lib
|
||||||
MNLIB = -L$(ROOTSYS)/lib -lMinuit2
|
#MNLIB = -L$(ROOTSYS)/lib -lMinuit2
|
||||||
|
|
||||||
# Executable
|
# Executable
|
||||||
EXEC = msr2msr
|
EXEC = msr2msr
|
||||||
@ -78,7 +78,7 @@ all: $(EXEC)
|
|||||||
$(EXEC): $(OBJS)
|
$(EXEC): $(OBJS)
|
||||||
@echo "---> Building $(EXEC) ..."
|
@echo "---> Building $(EXEC) ..."
|
||||||
/bin/rm -f $(SHLIB)
|
/bin/rm -f $(SHLIB)
|
||||||
$(LD) $(OBJS) -o $(EXEC) $(GLIBS) $(PSILIBS) $(MNLIB)
|
$(LD) $(OBJS) -o $(EXEC) $(GLIBS)
|
||||||
@echo "done"
|
@echo "done"
|
||||||
|
|
||||||
# clean up: remove all object file (and core files)
|
# clean up: remove all object file (and core files)
|
||||||
|
11
src/ToDo.txt
11
src/ToDo.txt
@ -25,7 +25,7 @@ short term:
|
|||||||
|
|
||||||
* write a little standalone program which is converting the old msr-files to the new ones. **DONE** 08-01-04
|
* write a little standalone program which is converting the old msr-files to the new ones. **DONE** 08-01-04
|
||||||
|
|
||||||
* implement max.likelihood fits
|
* implement max.likelihood fits **DONE** 08-02-06 (for Single Histo only. For the others not clear how to do it)
|
||||||
|
|
||||||
* implement table based theory functions (LF stuff)
|
* implement table based theory functions (LF stuff)
|
||||||
|
|
||||||
@ -33,14 +33,15 @@ short term:
|
|||||||
intermediate term:
|
intermediate term:
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
* start writing docu, i.e. transfering WKM doc from German -> English and
|
* start writing docu, i.e. transferring WKM doc from German -> English and
|
||||||
describe new features with examples!
|
describe new features with examples!
|
||||||
|
* introduce error numbers with corresponding docu/explanation in the latex-docu.
|
||||||
* implement RRF stuff
|
* implement RRF stuff
|
||||||
* implement NonMuSR stuff
|
* implement NonMuSR stuff
|
||||||
* implement access to user-function, i.e. functions not
|
* implement access to user-function, i.e. functions not
|
||||||
defined within musrfit, using the ROOT dictionary feature
|
defined within musrfit, using the ROOT dictionary feature
|
||||||
to look for them and use them.
|
to look for them and use them.
|
||||||
* think about if it is worth to modifiy wkm in order to read
|
* think about if it is worth to modify wkm in order to read
|
||||||
the new msr-files, so that wkmview can be used for an intermediate
|
the new msr-files, so that wkmview can be used for an intermediate
|
||||||
time.
|
time.
|
||||||
|
|
||||||
@ -65,6 +66,8 @@ fixes:
|
|||||||
* Needed to change some part of the Minuit2 source code, otherwise I got a strange linker error message.
|
* Needed to change some part of the Minuit2 source code, otherwise I got a strange linker error message.
|
||||||
In MnMinos.h the constructors (3 overloaded versions) are defined implicitly. When linking against libPMusr.so
|
In MnMinos.h the constructors (3 overloaded versions) are defined implicitly. When linking against libPMusr.so
|
||||||
which is using libMinuit2Base.so, I got the error message from the linker that is cannot find the reference
|
which is using libMinuit2Base.so, I got the error message from the linker that is cannot find the reference
|
||||||
to the second constructor. When transfering the implicit definition from the header file to the cxx, the
|
to the second constructor. When transferring the implicit definition from the header file to the cxx, the
|
||||||
problem was gone. Since to fiddle in the Minuit2 source code directly is ugly, I should look for a way to
|
problem was gone. Since to fiddle in the Minuit2 source code directly is ugly, I should look for a way to
|
||||||
build libPMusr.so which doesn't have this problem.
|
build libPMusr.so which doesn't have this problem.
|
||||||
|
|
||||||
|
-> This problem has been resolved cleanly by using minuit2 delivered with root!
|
@ -178,7 +178,7 @@ bool PFitter::CheckCommands()
|
|||||||
continue;
|
continue;
|
||||||
} else if (it->fLine.Contains("CHI_SQUARE")) {
|
} else if (it->fLine.Contains("CHI_SQUARE")) {
|
||||||
fUseChi2 = true;
|
fUseChi2 = true;
|
||||||
} else if (it->fLine.Contains("MAX_LIKELYHOOD")) {
|
} else if (it->fLine.Contains("MAX_LIKELIHOOD")) {
|
||||||
fUseChi2 = false;
|
fUseChi2 = false;
|
||||||
} else if (it->fLine.Contains("INTERACTIVE")) {
|
} else if (it->fLine.Contains("INTERACTIVE")) {
|
||||||
fCmdList.push_back(PMN_INTERACTIVE);
|
fCmdList.push_back(PMN_INTERACTIVE);
|
||||||
|
@ -53,6 +53,19 @@ PFitterFcn::PFitterFcn(PRunListCollection *runList, bool useChi2)
|
|||||||
fUp = 0.5;
|
fUp = 0.5;
|
||||||
|
|
||||||
fRunListCollection = runList;
|
fRunListCollection = runList;
|
||||||
|
|
||||||
|
// check if max likelihood is used together with asymmetry/RRF/nonMusr data.
|
||||||
|
// if yes place a warning since this option is not implemented and a fall back
|
||||||
|
// to chi2 will be used.
|
||||||
|
if (!fUseChi2) {
|
||||||
|
if ((fRunListCollection->GetNoOfAsymmetry() > 0) ||
|
||||||
|
(fRunListCollection->GetNoOfRRF() > 0) ||
|
||||||
|
(fRunListCollection->GetNoOfNonMusr() > 0)) {
|
||||||
|
cout << endl << "**WARNING**: Maximum Log Likelihood Fit is only implemented for Single Histogram Fit";
|
||||||
|
cout << endl << " Will fall back to Chi Square Fit.";
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@ -80,7 +93,7 @@ double PFitterFcn::operator()(const std::vector<double>& par) const
|
|||||||
value += fRunListCollection->GetAsymmetryChisq(par);
|
value += fRunListCollection->GetAsymmetryChisq(par);
|
||||||
value += fRunListCollection->GetRRFChisq(par);
|
value += fRunListCollection->GetRRFChisq(par);
|
||||||
value += fRunListCollection->GetNonMusrChisq(par);
|
value += fRunListCollection->GetNonMusrChisq(par);
|
||||||
} else { // max likelyhood
|
} else { // max likelihood
|
||||||
value += fRunListCollection->GetSingleHistoMaximumLikelihood(par);
|
value += fRunListCollection->GetSingleHistoMaximumLikelihood(par);
|
||||||
value += fRunListCollection->GetAsymmetryMaximumLikelihood(par);
|
value += fRunListCollection->GetAsymmetryMaximumLikelihood(par);
|
||||||
value += fRunListCollection->GetRRFMaximumLikelihood(par);
|
value += fRunListCollection->GetRRFMaximumLikelihood(par);
|
||||||
|
@ -1467,7 +1467,7 @@ bool PMsrHandler::FilterFunMapNumber(TString str, const char *filter, int &no)
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p> In the command block there shall be a new command which can be used
|
* <p> In the command block there shall be a new command which can be used
|
||||||
* to switch between chi2 and maximum_likelyhood!!
|
* to switch between chi2 and maximum_likelihood!!
|
||||||
*
|
*
|
||||||
* \param lines is a list of lines containing the fitparameter block
|
* \param lines is a list of lines containing the fitparameter block
|
||||||
*/
|
*/
|
||||||
|
@ -99,9 +99,6 @@ bool PRunListCollection::Add(int runNo)
|
|||||||
|
|
||||||
int fitType = (*fMsrInfo->GetMsrRunList())[runNo].fFitType;
|
int fitType = (*fMsrInfo->GetMsrRunList())[runNo].fFitType;
|
||||||
|
|
||||||
PRunAsymmetry* asym;
|
|
||||||
bool status;
|
|
||||||
|
|
||||||
switch (fitType) {
|
switch (fitType) {
|
||||||
case PRUN_SINGLE_HISTO:
|
case PRUN_SINGLE_HISTO:
|
||||||
fRunSingleHistoList.push_back(new PRunSingleHisto(fMsrInfo, fData, runNo));
|
fRunSingleHistoList.push_back(new PRunSingleHisto(fMsrInfo, fData, runNo));
|
||||||
@ -110,8 +107,6 @@ bool status;
|
|||||||
break;
|
break;
|
||||||
case PRUN_ASYMMETRY:
|
case PRUN_ASYMMETRY:
|
||||||
fRunAsymmetryList.push_back(new PRunAsymmetry(fMsrInfo, fData, runNo));
|
fRunAsymmetryList.push_back(new PRunAsymmetry(fMsrInfo, fData, runNo));
|
||||||
asym = fRunAsymmetryList[fRunAsymmetryList.size()-1];
|
|
||||||
status = asym->IsValid();
|
|
||||||
if (!fRunAsymmetryList[fRunAsymmetryList.size()-1]->IsValid())
|
if (!fRunAsymmetryList[fRunAsymmetryList.size()-1]->IsValid())
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
@ -217,14 +212,15 @@ double PRunListCollection::GetSingleHistoMaximumLikelihood(const std::vector<dou
|
|||||||
// GetAsymmetryMaximumLikelihood
|
// GetAsymmetryMaximumLikelihood
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p> Since it is not clear yet how to handle asymmetry fits with max likelihood
|
||||||
|
* the chi square will be used!
|
||||||
*/
|
*/
|
||||||
double PRunListCollection::GetAsymmetryMaximumLikelihood(const std::vector<double>& par)
|
double PRunListCollection::GetAsymmetryMaximumLikelihood(const std::vector<double>& par)
|
||||||
{
|
{
|
||||||
double mlh = 0.0;
|
double mlh = 0.0;
|
||||||
|
|
||||||
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
|
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
|
||||||
mlh += fRunAsymmetryList[i]->CalcMaxLikelihood(par);
|
mlh += fRunAsymmetryList[i]->CalcChiSquare(par);
|
||||||
|
|
||||||
return mlh;
|
return mlh;
|
||||||
}
|
}
|
||||||
@ -233,14 +229,15 @@ double PRunListCollection::GetAsymmetryMaximumLikelihood(const std::vector<doubl
|
|||||||
// GetRRFMaximumLikelihood
|
// GetRRFMaximumLikelihood
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p> Since it is not clear yet how to handle RRF fits with max likelihood
|
||||||
|
* the chi square will be used!
|
||||||
*/
|
*/
|
||||||
double PRunListCollection::GetRRFMaximumLikelihood(const std::vector<double>& par)
|
double PRunListCollection::GetRRFMaximumLikelihood(const std::vector<double>& par)
|
||||||
{
|
{
|
||||||
double mlh = 0.0;
|
double mlh = 0.0;
|
||||||
|
|
||||||
for (unsigned int i=0; i<fRunRRFList.size(); i++)
|
for (unsigned int i=0; i<fRunRRFList.size(); i++)
|
||||||
mlh += fRunRRFList[i]->CalcMaxLikelihood(par);
|
mlh += fRunRRFList[i]->CalcChiSquare(par);
|
||||||
|
|
||||||
return mlh;
|
return mlh;
|
||||||
}
|
}
|
||||||
@ -249,14 +246,15 @@ double PRunListCollection::GetRRFMaximumLikelihood(const std::vector<double>& pa
|
|||||||
// GetNonMusrMaximumLikelihood
|
// GetNonMusrMaximumLikelihood
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p> Since it is not clear yet how to handle non musr fits with max likelihood
|
||||||
|
* the chi square will be used!
|
||||||
*/
|
*/
|
||||||
double PRunListCollection::GetNonMusrMaximumLikelihood(const std::vector<double>& par)
|
double PRunListCollection::GetNonMusrMaximumLikelihood(const std::vector<double>& par)
|
||||||
{
|
{
|
||||||
double mlh = 0.0;
|
double mlh = 0.0;
|
||||||
|
|
||||||
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
|
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
|
||||||
mlh += fRunNonMusrList[i]->CalcMaxLikelihood(par);
|
mlh += fRunNonMusrList[i]->CalcChiSquare(par);
|
||||||
|
|
||||||
return mlh;
|
return mlh;
|
||||||
}
|
}
|
||||||
|
@ -166,9 +166,54 @@ double PRunSingleHisto::CalcChiSquare(const std::vector<double>& par)
|
|||||||
*/
|
*/
|
||||||
double PRunSingleHisto::CalcMaxLikelihood(const std::vector<double>& par)
|
double PRunSingleHisto::CalcMaxLikelihood(const std::vector<double>& par)
|
||||||
{
|
{
|
||||||
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
|
double mllh = 0.0; // maximum log likelihood assuming poisson distribution for the single bin
|
||||||
|
|
||||||
return 1.0;
|
double N0;
|
||||||
|
|
||||||
|
// check if norm is a parameter or a function
|
||||||
|
if (fRunInfo->fNormParamNo < MSR_PARAM_FUN_OFFSET) { // norm is a parameter
|
||||||
|
N0 = par[fRunInfo->fNormParamNo-1];
|
||||||
|
} else { // norm is a function
|
||||||
|
// get function number
|
||||||
|
unsigned int funNo = fRunInfo->fNormParamNo-MSR_PARAM_FUN_OFFSET;
|
||||||
|
// evaluate function
|
||||||
|
N0 = fMsrInfo->EvalFunc(funNo,fRunInfo->fMap,par);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get tau
|
||||||
|
double tau;
|
||||||
|
if (fRunInfo->fLifetimeParamNo != -1)
|
||||||
|
tau = par[fRunInfo->fLifetimeParamNo-1];
|
||||||
|
else
|
||||||
|
tau = PMUON_LIFETIME;
|
||||||
|
|
||||||
|
// get background
|
||||||
|
double bkg = par[fRunInfo->fBkgFitParamNo-1];
|
||||||
|
|
||||||
|
// calculate functions
|
||||||
|
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
|
||||||
|
int funcNo = fMsrInfo->GetFuncNo(i);
|
||||||
|
fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, fRunInfo->fMap, par);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate maximum log likelihood
|
||||||
|
double theo;
|
||||||
|
double data;
|
||||||
|
for (unsigned int i=0; i<fData.fValue.size(); i++) {
|
||||||
|
if ((fData.fTime[i]>=fFitStartTime) && (fData.fTime[i]<=fFitStopTime)) {
|
||||||
|
// calculate theory for the given parameter set
|
||||||
|
theo = N0*TMath::Exp(-fData.fTime[i]/tau)*(1+fTheory->Func(fData.fTime[i], par, fFuncValues))+bkg;
|
||||||
|
// check if data value is not too small
|
||||||
|
if (fData.fValue[i] > 1.0e-9)
|
||||||
|
data = fData.fValue[i];
|
||||||
|
else
|
||||||
|
data = 1.0e-9;
|
||||||
|
// add maximum log likelihood contribution of bin i
|
||||||
|
mllh -= data*TMath::Log(theo) - theo - TMath::LnGamma(data+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mllh;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
@ -79,7 +79,7 @@ void minuit2test()
|
|||||||
gFitFcn->SetParNames("N0", "asym", "lambda", "B", "phase", "Bkg");
|
gFitFcn->SetParNames("N0", "asym", "lambda", "B", "phase", "Bkg");
|
||||||
gFitFcn->SetParameter(0, 30.0); // N0
|
gFitFcn->SetParameter(0, 30.0); // N0
|
||||||
// gFitFcn->SetParLimits(0, 0.0, 1.0e6);
|
// gFitFcn->SetParLimits(0, 0.0, 1.0e6);
|
||||||
gFitFcn->SetParameter(1, 0.11); // asym
|
gFitFcn->SetParameter(1, 0.26); // asym
|
||||||
// gFitFcn->SetParLimits(1, 0.0, 0.33);
|
// gFitFcn->SetParLimits(1, 0.0, 0.33);
|
||||||
gFitFcn->SetParameter(2, 0.3); // lambda
|
gFitFcn->SetParameter(2, 0.3); // lambda
|
||||||
// gFitFcn->SetParLimits(2, 0.0, 100.0);
|
// gFitFcn->SetParLimits(2, 0.0, 100.0);
|
||||||
@ -100,6 +100,9 @@ void minuit2test()
|
|||||||
|
|
||||||
histo->Draw();
|
histo->Draw();
|
||||||
|
|
||||||
|
gFitFcn->SetParameter(0, 150.0); // N0
|
||||||
|
gFitFcn->SetParameter(5, 23.0); // Bkg
|
||||||
|
|
||||||
TVirtualFitter::SetDefaultFitter("Minuit2");
|
TVirtualFitter::SetDefaultFitter("Minuit2");
|
||||||
histo->Fit("gFitFcn", "LE"); // L->likleyhood, E->minos
|
histo->Fit("gFitFcn", "L"); // L->likleyhood, E->minos
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user