From 214457e78ceb101908ebc102356d9d3b79469dad Mon Sep 17 00:00:00 2001 From: Julian Pychy <julian@pc17.ep1.rub.de> Date: Mon, 18 Nov 2013 18:30:13 +0100 Subject: [PATCH] workaround for minuit returning bad covariance matrix, improved startup performance --- Examples/epem/epemReactionApp.cc | 6 ++--- Examples/pbarp/pbarpReactionApp.cc | 5 ++-- PwaUtils/AppBase.cc | 42 ++++++++++++++++++++++++++---- PwaUtils/PwaCovMatrix.cc | 16 ++++++++++++ PwaUtils/PwaCovMatrix.hh | 2 ++ 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/Examples/epem/epemReactionApp.cc b/Examples/epem/epemReactionApp.cc index ad2b9eae..bd46e63a 100644 --- a/Examples/epem/epemReactionApp.cc +++ b/Examples/epem/epemReactionApp.cc @@ -82,9 +82,6 @@ int main(int __argc,char *__argv[]){ Info << welcomeScreen << endmsg; Info << "Compiled " << __DATE__ << " " << __TIME__ << endmsg; - // Disable output buffering - setvbuf(stdout, NULL, _IONBF, 0); - // Parse the command line epemParser* theAppParams=new epemParser(__argc, __argv); @@ -162,7 +159,8 @@ int main(int __argc,char *__argv[]){ theAppBase.fixParams(upar,fixedParams); const unsigned int noOfFreeFitParams = upar.VariableParameters(); - + // Disable output buffering + setvbuf(stdout, NULL, _IONBF, 0); if(mode == "client"){ diff --git a/Examples/pbarp/pbarpReactionApp.cc b/Examples/pbarp/pbarpReactionApp.cc index 54f06285..ca6dda92 100644 --- a/Examples/pbarp/pbarpReactionApp.cc +++ b/Examples/pbarp/pbarpReactionApp.cc @@ -90,9 +90,6 @@ int main(int __argc,char *__argv[]){ Info << welcomeScreen << endmsg; Info << "Compiled " << __DATE__ << " " << __TIME__ << endmsg; - // Disable output buffering - setvbuf(stdout, NULL, _IONBF, 0); - // Parse the command line pbarpParser* theAppParams=new pbarpParser(__argc, __argv); @@ -177,6 +174,8 @@ int main(int __argc,char *__argv[]){ theAppBase.fixParams(upar,fixedParams); const unsigned int noOfFreeFitParams = upar.VariableParameters(); + // Disable output buffering + setvbuf(stdout, NULL, _IONBF, 0); if(mode == "client"){ diff --git a/PwaUtils/AppBase.cc b/PwaUtils/AppBase.cc index 6b53aa69..699fd5f8 100644 --- a/PwaUtils/AppBase.cc +++ b/PwaUtils/AppBase.cc @@ -294,11 +294,43 @@ FunctionMinimum AppBase::migradDefault(AbsFcn& theFcn, MnUserParameters& upar){ MnMigrad migrad(theFcn, upar); Info <<"start migrad "<< endmsg; FunctionMinimum funcMin = migrad(); - if(!funcMin.IsValid()) { - //try with higher strategy - Info <<"FM is invalid, try with strategy = 2."<< endmsg; - MnMigrad migrad2(theFcn, funcMin.UserState(), MnStrategy(2)); - funcMin = migrad2(); + + if(funcMin.IsValid()){ + return funcMin; + } + + // Two more tries to get a valid result unsing strategy 2 + for(int i=0; i<2; i++){ + Warning <<"FM is invalid, try with strategy = 2."<< endmsg; + + // Check minimum covariance matrix + bool badCovarianceDiagonal=false; + if(funcMin.HasCovariance()){ + badCovarianceDiagonal = !PwaCovMatrix::DiagonalIsValid(funcMin.UserCovariance()); + } + + if(badCovarianceDiagonal){ + Warning << "Using default errors" << endmsg; + MnUserParameters newParams = upar; + for(unsigned int i=0; i< funcMin.UserParameters().Params().size();i++){ + newParams.SetValue(i, funcMin.UserParameters().Params().at(i)); + } + MnMigrad migrad2(theFcn, newParams, MnStrategy(2)); + funcMin = migrad2(); + } + else{ + MnUserParameters newParams = upar; + for(unsigned int i=0; i< funcMin.UserParameters().Params().size();i++){ + newParams.SetValue(i, funcMin.UserParameters().Params().at(i)); + newParams.SetError(i, funcMin.UserParameters().Errors().at(i)); + } + MnMigrad migrad2(theFcn, newParams, MnStrategy(2)); + funcMin = migrad2(); + } + + if(funcMin.IsValid()){ + break; + } } return funcMin; diff --git a/PwaUtils/PwaCovMatrix.cc b/PwaUtils/PwaCovMatrix.cc index e100f998..ae5574e6 100644 --- a/PwaUtils/PwaCovMatrix.cc +++ b/PwaUtils/PwaCovMatrix.cc @@ -43,6 +43,8 @@ PwaCovMatrix::PwaCovMatrix(ROOT::Minuit2::MnUserCovariance &theMinuitCovMatrix, ROOT::Minuit2::MnUserParameters &theMinuitParameters, fitParams &theFitParams) { + DiagonalIsValid(theMinuitCovMatrix); + _n = theMinuitCovMatrix.Nrow(); unsigned int _nPar = theMinuitParameters.Params().size(); @@ -106,3 +108,17 @@ double PwaCovMatrix::GetElement(std::string parameter1, std::string parameter2){ return _covMatrix[parameter1][parameter2]; } + + +bool PwaCovMatrix::DiagonalIsValid(const ROOT::Minuit2::MnUserCovariance &theMinuitCovMatrix){ + + bool result = true; + for(unsigned int i=0; i<theMinuitCovMatrix.Nrow(); i++){ + if(theMinuitCovMatrix(i, i) < 0){ + Warning << "Covariance element (" << i << "," << i << ")" + << " = " << theMinuitCovMatrix(i,i) << " < 0" << endmsg; + result = false; + } + } + return result; +} diff --git a/PwaUtils/PwaCovMatrix.hh b/PwaUtils/PwaCovMatrix.hh index 8f344acc..f0f5ae18 100644 --- a/PwaUtils/PwaCovMatrix.hh +++ b/PwaUtils/PwaCovMatrix.hh @@ -52,6 +52,8 @@ class PwaCovMatrix ROOT::Minuit2::MnUserParameters &theMinuitParameters, fitParams &theFitParams); double GetElement(std::string parameter1, std::string parameter2); + static bool DiagonalIsValid(const ROOT::Minuit2::MnUserCovariance &theMinuitCovMatrix); + template<class Archive> void serialize(Archive & ar, const unsigned int version){ -- GitLab