added the option to write the content of the MINUIT2.OUTPUT ascii file as yaml. This extends the previous commit from Ryan M.L. McFadden.

This commit is contained in:
suter_a 2024-06-18 11:16:15 +02:00
parent 6bcb26f9d5
commit 64d3b6192b
25 changed files with 251 additions and 122 deletions

View File

@ -1,7 +1,7 @@
# - musrfit
cmake_minimum_required(VERSION 3.17)
project(musrfit VERSION 1.9.4 LANGUAGES C CXX)
project(musrfit VERSION 1.9.5 LANGUAGES C CXX)
#--- musrfit specific options -------------------------------------------------
option(nexus "build optional NeXus support. Needed for ISIS" OFF)

View File

@ -265,8 +265,8 @@ UInt_t PSectorChisq::GetNDF(UInt_t idx)
* \param runListCollection pointer of the run list collection (pre-processed historgrams)
* \param chisq_only flag: true=calculate chisq only (no fitting)
*/
PFitter::PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection, Bool_t chisq_only) :
fChisqOnly(chisq_only), fRunInfo(runInfo), fRunListCollection(runListCollection)
PFitter::PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection, Bool_t chisq_only, Bool_t yaml_out) :
fChisqOnly(chisq_only), fYamlOut(yaml_out), fRunInfo(runInfo), fRunListCollection(runListCollection)
{
// initialize variables
fIsScanOnly = true;
@ -2475,120 +2475,121 @@ Bool_t PFitter::ExecuteSave(Bool_t firstSave)
hcorr->Write("hcorr", TObject::kOverwrite, sizeof(hcorr));
ff.Close();
// write the fit results to an easy-to-read/parse yaml file
// note: the block names follow those used by Python library iminuit
// https://github.com/scikit-hep/iminuit
if (fYamlOut) {
// write the fit results to an easy-to-read/parse yaml file
// note: the block names follow those used by Python library iminuit
// https://github.com/scikit-hep/iminuit
// dynamically name the yaml output file
// https://stackoverflow.com/a/25389052
std::string yaml_filename(fRunInfo->GetFileName().Data());
const std::string msr_ext(".msr");
yaml_filename.replace(yaml_filename.find(msr_ext), msr_ext.length(),
".yaml");
// dynamically name the yaml output file
// https://stackoverflow.com/a/25389052
std::string yaml_filename(fRunInfo->GetFileName().Data());
const std::string msr_ext(".msr");
yaml_filename.replace(yaml_filename.find(msr_ext), msr_ext.length(),
".yaml");
// define yaml's 2-space indentation
const std::string yaml_indent(" ");
// define yaml's 2-space indentation
const std::string yaml_indent(" ");
// open the yaml file for writing
std::ofstream yaml_file(yaml_filename);
// open the yaml file for writing
std::ofstream yaml_file(yaml_filename);
// number formatting of the output
yaml_file << std::scientific << std::setprecision(16);
// number formatting of the output
yaml_file << std::scientific << std::setprecision(16);
// write the parameter values
yaml_file << "values:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
yaml_file << yaml_indent << fParams[i].fName.Data() << ": "
<< fParams[i].fValue << "\n";
}
// write the parabolic errors
yaml_file << "errors:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
yaml_file << yaml_indent << fParams[i].fName.Data() << ": "
<< fMnUserParams.Error(i) << "\n";
}
// write the minos errors
yaml_file << "mnerrors:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
// use boost's implementation of a variant, which can be streamed by
// default - see: https://stackoverflow.com/q/47168477
boost::variant<double, std::string> positive_error, negative_error;
if (fParams[i].fPosErrorPresent) {
positive_error = fParams[i].fPosError;
negative_error = fParams[i].fStep;
} else {
positive_error = "null";
negative_error = "null";
// write the parameter values
yaml_file << "values:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
yaml_file << yaml_indent << fParams[i].fName.Data() << ": "
<< fParams[i].fValue << "\n";
}
yaml_file << yaml_indent << fParams[i].fName.Data() << ":\n";
yaml_file << yaml_indent << yaml_indent
<< "positive: " << positive_error << "\n";
yaml_file << yaml_indent << yaml_indent
<< "negative: " << negative_error << "\n";
}
// write the parameter limits
yaml_file << "limits:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
// use boost's implementation of a variant, which can be streamed by
// default - see: https://stackoverflow.com/q/47168477
boost::variant<double, std::string> upper_limit, lower_limit;
if (fParams[i].fLowerBoundaryPresent) {
lower_limit = fParams[i].fLowerBoundary;
} else {
lower_limit = "null";
}
if (fParams[i].fUpperBoundaryPresent) {
upper_limit = fParams[i].fUpperBoundary;
} else {
upper_limit = "null";
// write the parabolic errors
yaml_file << "errors:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
yaml_file << yaml_indent << fParams[i].fName.Data() << ": "
<< fMnUserParams.Error(i) << "\n";
}
yaml_file << yaml_indent << fParams[i].fName.Data() << ":\n";
yaml_file << yaml_indent << yaml_indent << "lower: " << lower_limit
<< "\n";
yaml_file << yaml_indent << yaml_indent << "upper: " << upper_limit
<< "\n";
}
// write the minos errors
yaml_file << "mnerrors:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
// use boost's implementation of a variant, which can be streamed by
// default - see: https://stackoverflow.com/q/47168477
boost::variant<double, std::string> positive_error, negative_error;
if (fParams[i].fPosErrorPresent) {
positive_error = fParams[i].fPosError;
negative_error = fParams[i].fStep;
} else {
positive_error = "null";
negative_error = "null";
}
// write if the parameter is fixed
yaml_file << "fixed:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
std::string is_fixed = fParams[i].fStep == 0.0 ? "true" : "false";
yaml_file << yaml_indent << fParams[i].fName.Data() << ": " << is_fixed
<< "\n";
}
// write the covariance matrix (omitting fixed parameters)
yaml_file << "covariance:\n";
for (unsigned int i = 0; i < cov.Nrow(); ++i) {
yaml_file << yaml_indent << mnState.Name(parNo[i]) << ":\n";
for (unsigned int j = 0; j < cov.Nrow(); ++j) {
yaml_file << yaml_indent << yaml_indent << mnState.Name(parNo[j])
<< ": " << cov(i, j) << "\n";
yaml_file << yaml_indent << fParams[i].fName.Data() << ":\n";
yaml_file << yaml_indent << yaml_indent
<< "positive: " << positive_error << "\n";
yaml_file << yaml_indent << yaml_indent
<< "negative: " << negative_error << "\n";
}
}
// write the correlation matrix (omitting fixed parameters)
yaml_file << "correlation:\n";
for (unsigned int i = 0; i < cov.Nrow(); ++i) {
yaml_file << yaml_indent << mnState.Name(parNo[i]) << ":\n";
for (unsigned int j = 0; j < cov.Nrow(); ++j) {
double correlation =
i == j ? 1.0
: cov(i, j) / (fMnUserParams.Error(parNo[i]) *
fMnUserParams.Error(parNo[j]));
yaml_file << yaml_indent << yaml_indent << mnState.Name(parNo[j])
<< ": " << correlation << "\n";
// write the parameter limits
yaml_file << "limits:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
// use boost's implementation of a variant, which can be streamed by
// default - see: https://stackoverflow.com/q/47168477
boost::variant<double, std::string> upper_limit, lower_limit;
if (fParams[i].fLowerBoundaryPresent) {
lower_limit = fParams[i].fLowerBoundary;
} else {
lower_limit = "null";
}
if (fParams[i].fUpperBoundaryPresent) {
upper_limit = fParams[i].fUpperBoundary;
} else {
upper_limit = "null";
}
yaml_file << yaml_indent << fParams[i].fName.Data() << ":\n";
yaml_file << yaml_indent << yaml_indent << "lower: " << lower_limit
<< "\n";
yaml_file << yaml_indent << yaml_indent << "upper: " << upper_limit
<< "\n";
}
// write if the parameter is fixed
yaml_file << "fixed:\n";
for (unsigned int i = 0; i < fParams.size(); ++i) {
std::string is_fixed = fParams[i].fStep == 0.0 ? "true" : "false";
yaml_file << yaml_indent << fParams[i].fName.Data() << ": " << is_fixed
<< "\n";
}
// write the covariance matrix (omitting fixed parameters)
yaml_file << "covariance:\n";
for (unsigned int i = 0; i < cov.Nrow(); ++i) {
yaml_file << yaml_indent << mnState.Name(parNo[i]) << ":\n";
for (unsigned int j = 0; j < cov.Nrow(); ++j) {
yaml_file << yaml_indent << yaml_indent << mnState.Name(parNo[j])
<< ": " << cov(i, j) << "\n";
}
}
// write the correlation matrix (omitting fixed parameters)
yaml_file << "correlation:\n";
for (unsigned int i = 0; i < cov.Nrow(); ++i) {
yaml_file << yaml_indent << mnState.Name(parNo[i]) << ":\n";
for (unsigned int j = 0; j < cov.Nrow(); ++j) {
double correlation =
i == j ? 1.0
: cov(i, j) / (fMnUserParams.Error(parNo[i]) *
fMnUserParams.Error(parNo[j]));
yaml_file << yaml_indent << yaml_indent << mnState.Name(parNo[j])
<< ": " << correlation << "\n";
}
}
// close the yaml file
yaml_file.close();
}
// close the yaml file
yaml_file.close();
}
parNo.clear(); // clean up
} else {

View File

@ -111,7 +111,7 @@ class PSectorChisq
class PFitter
{
public:
PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection, Bool_t chisq_only = false);
PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection, Bool_t chisq_only = false, Bool_t yaml_out = false);
virtual ~PFitter();
Bool_t IsValid() { return fIsValid; }
@ -124,6 +124,7 @@ class PFitter
Bool_t fIsScanOnly; ///< flag. true: scan along some parameters (no fitting).
Bool_t fConverged; ///< flag. true: the fit has converged.
Bool_t fChisqOnly; ///< flag. true: calculate chi^2 only (no fitting).
Bool_t fYamlOut; ///< flag. true: generate yaml output file of the fit results (MINUIT2.OUTPUT -> yaml)
Bool_t fUseChi2; ///< flag. true: chi^2 fit. false: log-max-likelihood
UInt_t fPrintLevel; ///< tag, showing the level of messages whished. 0=minimum, 1=standard, 2=maximum

View File

@ -127,6 +127,7 @@ void msr2data_syntax()
std::cout << std::endl << " -k, --keep-mn2-output : if fitting is used, pass the option --keep-mn2-output to musrfit";
std::cout << std::endl << " -t, --title-from-data-file : if fitting is used, pass the option --title-from-data-file to musrfit";
std::cout << std::endl << " -e, --estimateN0: estimate N0 for single histogram fits.";
std::cout << std::endl << " -y, --yaml: write fit results (MINUIT2.OUTPUT) into a yaml-file. Output <msr-file>.yaml";
std::cout << std::endl << " -p, --per-run-block-chisq: will per run block chisq to the msr-file.";
std::cout << std::endl;
std::cout << std::endl << " global : switch on the global-fit mode";
@ -187,6 +188,7 @@ std::string msr2data_validArguments(const std::vector<std::string> &arg)
|| (!iter->substr(0,3).compare("fit")) || (!iter->compare("-k")) || (!iter->compare("--keep-mn2-output")) \
|| (!iter->compare("-t")) || (!iter->compare("--title-from-data-file")) \
|| (!iter->compare("-e")) || (!iter->compare("--estimateN0")) \
|| (!iter->compare("-y") || (!iter->compare("--yaml"))) \
|| (!iter->compare("-p")) || (!iter->compare("--per-run-block-chisq")) \
|| (!iter->compare("data")) || (!iter->substr(0,4).compare("msr-")) || (!iter->compare("global")) \
|| (!iter->compare("global+")) || (!iter->compare("global+!")) || (!iter->compare("new")) \
@ -716,6 +718,8 @@ int main(int argc, char *argv[])
musrfitOptions.append("-t ");
if (!msr2data_useOption(arg, "-e") || !msr2data_useOption(arg, "--estimateN0"))
musrfitOptions.append("-e ");
if (!msr2data_useOption(arg, "-y") || !msr2data_useOption(arg, "--yaml"))
musrfitOptions.append("-y ");
if (!msr2data_useOption(arg, "-p") || !msr2data_useOption(arg, "--per-run-block-chisq"))
musrfitOptions.append("-p ");
}

View File

@ -160,6 +160,8 @@ bool PAdminXMLParser::startElement()
fKeyWord = eDumpRoot;
} else if (qName == "estimate_n0") {
fKeyWord = eEstimateN0;
} else if (qName == "yaml_out") {
fKeyWord = eYamlOut;
} else if (qName == "chisq_per_run_block") {
fKeyWord = eChisqPreRunBlock;
} else if (qName == "path_file_name") {
@ -389,6 +391,14 @@ bool PAdminXMLParser::characters()
fAdmin->fMsr2DataParam.estimateN0 = flag;
fAdmin->setEstimateN0Flag(flag);
break;
case eYamlOut:
if (str == "y")
flag = true;
else
flag = false;
fAdmin->fMsr2DataParam.yamlOut = flag;
fAdmin->setYamlOutFlag(flag);
break;
case eChisqPreRunBlock:
if (str == "y")
flag = true;
@ -608,6 +618,7 @@ void PAdminXMLParser::dump()
std::cout << "debug> title_from_data_file : " << fAdmin->getTitleFromDataFileFlag() << std::endl;
std::cout << "debug> chisq_per_run_block : " << fAdmin->getChisqPerRunBlockFlag() << std::endl;
std::cout << "debug> estimate_n0 : " << fAdmin->getEstimateN0Flag() << std::endl;
std::cout << "debug> yaml_out : " << fAdmin->getYamlOutFlag() << std::endl;
std::cout << "debug> musrview_show_fourier : " << fAdmin->getMusrviewShowFourierFlag() << std::endl;
std::cout << "debug> musrview_show_avg : " << fAdmin->getMusrviewShowAvgFlag() << std::endl;
std::cout << "debug> enable_musrt0 : " << fAdmin->getEnableMusrT0Flag() << std::endl;
@ -746,6 +757,7 @@ PAdmin::PAdmin() : QObject()
fEnableMusrT0 = false;
fLifetimeCorrection = true;
fEstimateN0 = true;
fYamlOut = false;
fChisqPreRunBlock = false;
fEditWidth = 900;
@ -760,6 +772,7 @@ PAdmin::PAdmin() : QObject()
fMsr2DataParam.ignoreDataHeaderInfo = false;
fMsr2DataParam.keepMinuit2Output = false;
fMsr2DataParam.estimateN0 = fEstimateN0;
fMsr2DataParam.yamlOut = false;
fMsr2DataParam.writeColumnData = false;
fMsr2DataParam.recreateDbFile = false;
fMsr2DataParam.chainFit = true;
@ -991,6 +1004,12 @@ int PAdmin::savePrefs(QString pref_fln)
else
data[i] = " <estimate_n0>n</estimate_n0>";
}
if (data[i].contains("<yaml_out>") && data[i].contains("</yaml_out>")) {
if (fYamlOut)
data[i] = " <yaml_out>y</yaml_out>";
else
data[i] = " <yaml_out>n</yaml_out>";
}
if (data[i].contains("<musrview_show_fourier>") && data[i].contains("</musrview_show_fourier>")) {
if (fMusrviewShowFourier)
data[i] = " <musrview_show_fourier>y</musrview_show_fourier>";

View File

@ -71,7 +71,7 @@ class PAdminXMLParser
private:
enum EAdminKeyWords {eEmpty, eTimeout, eKeepMinuit2Output, eDumpAscii, eDumpRoot,
eTitleFromDataFile, eChisqPreRunBlock, eEstimateN0,
eTitleFromDataFile, eChisqPreRunBlock, eEstimateN0, eYamlOut,
eMusrviewShowFourier, eMusrviewShowAvg, eMusrviewShowOneToOne, eEnableMusrT0,
eDarkThemeIconsMenu, eDarkThemeIconsToolbar, eEditW, eEditH,
eFontName, eFontSize, eExecPath, eDefaultSavePath,
@ -129,6 +129,7 @@ class PAdmin : public QObject
bool getDumpAsciiFlag() { return fDumpAscii; }
bool getDumpRootFlag() { return fDumpRoot; }
bool getEstimateN0Flag() { return fEstimateN0; }
bool getYamlOutFlag() { return fYamlOut; }
bool getChisqPerRunBlockFlag() { return fChisqPreRunBlock; }
bool getDarkThemeIconsMenuFlag() { return fDarkThemeIconsMenu; }
bool getDarkThemeIconsToolbarFlag() { return fDarkThemeIconsToolbar; }
@ -157,6 +158,7 @@ class PAdmin : public QObject
void setDumpAsciiFlag(const bool flag) { fDumpAscii = flag; }
void setDumpRootFlag(const bool flag) { fDumpRoot = flag; }
void setEstimateN0Flag(const bool flag) { fEstimateN0 = flag; }
void setYamlOutFlag(const bool flag) { fYamlOut = flag; }
void setChisqPerRunBlockFlag(const bool flag) { fChisqPreRunBlock = flag; }
void setDarkThemeIconsMenuFlag(const bool flag) { fDarkThemeIconsMenu = flag; }
void setDarkThemeIconsToolbarFlag(const bool flag) { fDarkThemeIconsToolbar = flag; }
@ -205,6 +207,7 @@ class PAdmin : public QObject
bool fTitleFromDataFile; ///< flag indicating if the title should be extracted from the data file (default: yes).
bool fChisqPreRunBlock; ///< flag indicating if musrfit shall write 'per run block' chisq to the msr-file (default: no).
bool fEstimateN0; ///< flag indicating if musrfit shall estimate N0 for single histogram fits (default: yes).
bool fYamlOut; ///< flag indicating if the MINUIT2.OUTPUT file should also be written as <msr-file>.yaml output. (default: no).
bool fEnableMusrT0; ///< flag indicating if musrT0 shall be enabled at startup from within musredit (default: yes).
bool fDarkThemeIconsMenu; ///< flag indicating if dark theme icons shall be used in the menu (default: no)
bool fDarkThemeIconsToolbar; ///< flag indicating if dark theme icons shall be used in the toolbar (default: no)

View File

@ -84,6 +84,7 @@ PMsr2DataDialog::PMsr2DataDialog(PMsr2DataParam *msr2DataParam, const QString he
fIgnoreDataHeaderInfo_checkBox->setChecked(fMsr2DataParam->ignoreDataHeaderInfo);
fKeepMinuit2Output_checkBox->setChecked(fMsr2DataParam->keepMinuit2Output);
fEstimateN0_checkBox->setChecked(fMsr2DataParam->estimateN0);
fYamlOut_checkBox->setChecked(fMsr2DataParam->yamlOut);
fWriteColumnData_checkBox->setChecked(fMsr2DataParam->writeColumnData);
fRecreateDataFile_checkBox->setChecked(fMsr2DataParam->recreateDbFile);
fChainFit_checkBox->setChecked(fMsr2DataParam->chainFit);
@ -121,6 +122,7 @@ PMsr2DataParam* PMsr2DataDialog::getMsr2DataParam()
fMsr2DataParam->ignoreDataHeaderInfo = fIgnoreDataHeaderInfo_checkBox->isChecked();
fMsr2DataParam->keepMinuit2Output = fKeepMinuit2Output_checkBox->isChecked();
fMsr2DataParam->estimateN0 = fEstimateN0_checkBox->isChecked();
fMsr2DataParam->yamlOut = fYamlOut_checkBox->isChecked();
fMsr2DataParam->writeColumnData = fWriteColumnData_checkBox->isChecked();
fMsr2DataParam->recreateDbFile = fRecreateDataFile_checkBox->isChecked();
fMsr2DataParam->chainFit = fChainFit_checkBox->isChecked();

View File

@ -76,6 +76,7 @@ PPrefsDialog::PPrefsDialog(PAdmin *admin) : fAdmin(admin)
fEnableMusrT0_checkBox->setChecked(fAdmin->getEnableMusrT0Flag());
fPerRunBlockChisq_checkBox->setChecked(fAdmin->getChisqPerRunBlockFlag());
fEstimateN0_checkBox->setChecked(fAdmin->getEstimateN0Flag());
fYamlOut_checkBox->setChecked(fAdmin->getYamlOutFlag());
fFourier_checkBox->setChecked(fAdmin->getMusrviewShowFourierFlag());
fAvg_checkBox->setChecked(fAdmin->getMusrviewShowAvgFlag());
fOneToOne_checkBox->setChecked(fAdmin->getMusrviewShowOneToOneFlag());

View File

@ -54,6 +54,7 @@ class PPrefsDialog : public QDialog, private Ui::PPrefsDialog
bool getEnableMusrT0Flag() { return fEnableMusrT0_checkBox->isChecked(); }
bool getKeepRunPerBlockChisqFlag() { return fPerRunBlockChisq_checkBox->isChecked(); }
bool getEstimateN0Flag() { return fEstimateN0_checkBox->isChecked(); }
bool getYamlOutFlag() { return fYamlOut_checkBox->isChecked(); }
bool getDarkThemeIconsMenuFlag() { return fDarkThemeIconsMenu_checkBox->isChecked(); }
bool getDarkThemeIconsToolbarFlag() { return fDarkThemeIconsToolbar_checkBox->isChecked(); }
bool getOneToOneFlag() { return fOneToOne_checkBox->isChecked(); }

View File

@ -2104,6 +2104,11 @@ void PTextEdit::musrFit()
cmd.append("--estimateN0");
}
// check yamlOut flag
if (fAdmin->getYamlOutFlag()) {
cmd.append("--yaml");
}
// check per-run-block-chisq flag
if (fAdmin->getChisqPerRunBlockFlag()) {
cmd.append("--per-run-block-chisq");
@ -2336,6 +2341,11 @@ void PTextEdit::musrMsr2Data()
cmd.append("-e");
}
// yaml out. Add flag only if a fit is done
if (fMsr2DataParam->yamlOut && (fMsr2DataParam->fitOnly || fMsr2DataParam->templateRunNo != -1)) {
cmd.append("-y");
}
// write per-run-block chisq. Add flag only if a fit is done
if (fMsr2DataParam->perRunBlockChisq && (fMsr2DataParam->fitOnly || fMsr2DataParam->templateRunNo != -1)) {
cmd.append("-p");
@ -2719,6 +2729,7 @@ void PTextEdit::musrPrefs()
fAdmin->setTimeout(dlg->getTimeout());
fAdmin->setChisqPerRunBlockFlag(dlg->getKeepRunPerBlockChisqFlag());
fAdmin->setEstimateN0Flag(dlg->getEstimateN0Flag());
fAdmin->setYamlOutFlag(dlg->getYamlOutFlag());
}
delete dlg;

View File

@ -338,7 +338,7 @@
<x>6</x>
<y>20</y>
<width>560</width>
<height>131</height>
<height>135</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
@ -456,6 +456,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fYamlOut_checkBox">
<property name="text">
<string>yaml out</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>

View File

@ -33,7 +33,7 @@
<item>
<widget class="QTabWidget" name="fTabWidget">
<property name="currentIndex">
<number>2</number>
<number>1</number>
</property>
<widget class="QWidget" name="fGeneral_tab">
<attribute name="title">
@ -152,9 +152,9 @@
<widget class="QCheckBox" name="fTitleFromData_checkBox">
<property name="geometry">
<rect>
<x>190</x>
<x>170</x>
<y>10</y>
<width>241</width>
<width>161</width>
<height>23</height>
</rect>
</property>
@ -165,9 +165,9 @@
<widget class="QCheckBox" name="fPerRunBlockChisq_checkBox">
<property name="geometry">
<rect>
<x>190</x>
<x>170</x>
<y>35</y>
<width>241</width>
<width>181</width>
<height>22</height>
</rect>
</property>
@ -178,9 +178,9 @@
<widget class="QCheckBox" name="fEstimateN0_checkBox">
<property name="geometry">
<rect>
<x>190</x>
<x>170</x>
<y>60</y>
<width>241</width>
<width>171</width>
<height>22</height>
</rect>
</property>
@ -188,6 +188,19 @@
<string>estimate N0</string>
</property>
</widget>
<widget class="QCheckBox" name="fYamlOut_checkBox">
<property name="geometry">
<rect>
<x>350</x>
<y>10</y>
<width>85</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>yaml out</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="fMusrview_tab">
<attribute name="title">

View File

@ -56,6 +56,7 @@ struct PMsr2DataParam {
bool openFilesAfterFitting; ///< flag: true = open msr-file after fit in musredit. false = do not open msr-file after fit.
bool titleFromDataFile; ///< flag indicating if the title for the msr-file shall be extracted from the data-file ('-t' in msr2data)
bool estimateN0; ///< flag indicating if the N0 shall be estimated for single histogram fitting
bool yamlOut; ///< flag indicating if the MINUIT2.OUTPUT content should be written to <msr-file>.yaml
bool perRunBlockChisq; ///< flag indicating if per-run-block-chisq shall be dumped into the msr-file
bool createMsrFileOnly; ///< flag: true = just create the msr-files without any fitting ('msr-<template>' in msr2data)
bool fitOnly; ///< flag: true = just perform the fits wihtout generating any msr-files ('fit' in msr2data).

View File

@ -14,6 +14,7 @@
<title_from_data_file>y</title_from_data_file>
<chisq_per_run_block>n</chisq_per_run_block>
<estimate_n0>y</estimate_n0>
<yaml_out>n</yaml_out>
<musrview_show_fourier>n</musrview_show_fourier>
<musrview_show_avg>n</musrview_show_avg>
<musrview_show_one_to_one>n</musrview_show_one_to_one>

View File

@ -166,6 +166,8 @@ bool PAdminXMLParser::startElement()
fKeyWord = eDumpRoot;
} else if (qName == "estimate_n0") {
fKeyWord = eEstimateN0;
} else if (qName == "yaml_out") {
fKeyWord = eYamlOut;
} else if (qName == "chisq_per_run_block") {
fKeyWord = eChisqPreRunBlock;
} else if (qName == "path_file_name") {
@ -396,6 +398,13 @@ bool PAdminXMLParser::characters()
fAdmin->fMsr2DataParam.estimateN0 = flag;
fAdmin->setEstimateN0Flag(flag);
break;
case eYamlOut:
if (str == "y")
flag = true;
else
flag = false;
fAdmin->fMsr2DataParam.yamlOut = flag;
fAdmin->setYamlOutFlag(flag);
case eChisqPreRunBlock:
if (str == "y")
flag = true;
@ -615,6 +624,7 @@ void PAdminXMLParser::dump()
std::cout << "debug> title_from_data_file : " << fAdmin->getTitleFromDataFileFlag() << std::endl;
std::cout << "debug> chisq_per_run_block : " << fAdmin->getChisqPerRunBlockFlag() << std::endl;
std::cout << "debug> estimate_n0 : " << fAdmin->getEstimateN0Flag() << std::endl;
std::cout << "debug> yaml_out : " << fAdmin->getYamlOutFlag() << std::endl;
std::cout << "debug> musrview_show_fourier : " << fAdmin->getMusrviewShowFourierFlag() << std::endl;
std::cout << "debug> musrview_show_avg : " << fAdmin->getMusrviewShowAvgFlag() << std::endl;
std::cout << "debug> enable_musrt0 : " << fAdmin->getEnableMusrT0Flag() << std::endl;
@ -753,6 +763,7 @@ PAdmin::PAdmin() : QObject()
fEnableMusrT0 = false;
fLifetimeCorrection = true;
fEstimateN0 = true;
fYamlOut = false;
fChisqPreRunBlock = false;
fMsr2DataParam.runList = QString("");
@ -764,6 +775,7 @@ PAdmin::PAdmin() : QObject()
fMsr2DataParam.ignoreDataHeaderInfo = false;
fMsr2DataParam.keepMinuit2Output = false;
fMsr2DataParam.estimateN0 = fEstimateN0;
fMsr2DataParam.yamlOut = false;
fMsr2DataParam.writeColumnData = false;
fMsr2DataParam.recreateDbFile = false;
fMsr2DataParam.chainFit = true;
@ -995,6 +1007,12 @@ int PAdmin::savePrefs(QString pref_fln)
else
data[i] = " <estimate_n0>n</estimate_n0>";
}
if (data[i].contains("<yaml_out>") && data[i].contains("</yaml_out>")) {
if (fYamlOut)
data[i] = " <yaml_out>y</yaml_out>";
else
data[i] = " <yaml_out>n</yaml_out>";
}
if (data[i].contains("<musrview_show_fourier>") && data[i].contains("</musrview_show_fourier>")) {
if (fMusrviewShowFourier)
data[i] = " <musrview_show_fourier>y</musrview_show_fourier>";

View File

@ -71,7 +71,7 @@ class PAdminXMLParser
private:
enum EAdminKeyWords {eEmpty, eTimeout, eKeepMinuit2Output, eDumpAscii, eDumpRoot,
eTitleFromDataFile, eChisqPreRunBlock, eEstimateN0,
eTitleFromDataFile, eChisqPreRunBlock, eEstimateN0, eYamlOut,
eMusrviewShowFourier, eMusrviewShowAvg, eMusrviewShowOneToOne, eEnableMusrT0,
eDarkThemeIconsMenu, eDarkThemeIconsToolbar, eEditW, eEditH,
eFontName, eFontSize, eExecPath, eDefaultSavePath,
@ -125,6 +125,7 @@ class PAdmin : public QObject
bool getMusrviewShowAvgFlag() { return fMusrviewShowAvg; }
bool getMusrviewShowOneToOneFlag() { return fMusrviewShowOneToOne; }
bool getEnableMusrT0Flag() { return fEnableMusrT0; }
bool getYamlOutFlag() { return fYamlOut; }
bool getKeepMinuit2OutputFlag() { return fKeepMinuit2Output; }
bool getDumpAsciiFlag() { return fDumpAscii; }
bool getDumpRootFlag() { return fDumpRoot; }
@ -157,6 +158,7 @@ class PAdmin : public QObject
void setDumpAsciiFlag(const bool flag) { fDumpAscii = flag; }
void setDumpRootFlag(const bool flag) { fDumpRoot = flag; }
void setEstimateN0Flag(const bool flag) { fEstimateN0 = flag; }
void setYamlOutFlag(const bool flag) { fYamlOut = flag; }
void setChisqPerRunBlockFlag(const bool flag) { fChisqPreRunBlock = flag; }
void setDarkThemeIconsMenuFlag(const bool flag) { fDarkThemeIconsMenu = flag; }
void setDarkThemeIconsToolbarFlag(const bool flag) { fDarkThemeIconsToolbar = flag; }
@ -205,6 +207,7 @@ class PAdmin : public QObject
bool fTitleFromDataFile; ///< flag indicating if the title should be extracted from the data file (default: yes).
bool fChisqPreRunBlock; ///< flag indicating if musrfit shall write 'per run block' chisq to the msr-file (default: no).
bool fEstimateN0; ///< flag indicating if musrfit shall estimate N0 for single histogram fits (default: yes).
bool fYamlOut; ///< flag indicating if the MINUIT2.OUTPUT file should also be written as <msr-file>.yaml output. (default: no).
bool fEnableMusrT0; ///< flag indicating if musrT0 shall be enabled at startup from within musredit (default: yes).
bool fDarkThemeIconsMenu; ///< flag indicating if dark theme icons shall be used in the menu (default: no)
bool fDarkThemeIconsToolbar; ///< flag indicating if dark theme icons shall be used in the toolbar (default: no)

View File

@ -84,6 +84,7 @@ PMsr2DataDialog::PMsr2DataDialog(PMsr2DataParam *msr2DataParam, const QString he
fIgnoreDataHeaderInfo_checkBox->setChecked(fMsr2DataParam->ignoreDataHeaderInfo);
fKeepMinuit2Output_checkBox->setChecked(fMsr2DataParam->keepMinuit2Output);
fEstimateN0_checkBox->setChecked(fMsr2DataParam->estimateN0);
fYamlOut_checkBox->setChecked(fMsr2DataParam->yamlOut);
fWriteColumnData_checkBox->setChecked(fMsr2DataParam->writeColumnData);
fRecreateDataFile_checkBox->setChecked(fMsr2DataParam->recreateDbFile);
fChainFit_checkBox->setChecked(fMsr2DataParam->chainFit);
@ -121,6 +122,7 @@ PMsr2DataParam* PMsr2DataDialog::getMsr2DataParam()
fMsr2DataParam->ignoreDataHeaderInfo = fIgnoreDataHeaderInfo_checkBox->isChecked();
fMsr2DataParam->keepMinuit2Output = fKeepMinuit2Output_checkBox->isChecked();
fMsr2DataParam->estimateN0 = fEstimateN0_checkBox->isChecked();
fMsr2DataParam->yamlOut = fYamlOut_checkBox->isChecked();
fMsr2DataParam->writeColumnData = fWriteColumnData_checkBox->isChecked();
fMsr2DataParam->recreateDbFile = fRecreateDataFile_checkBox->isChecked();
fMsr2DataParam->chainFit = fChainFit_checkBox->isChecked();

View File

@ -76,6 +76,7 @@ PPrefsDialog::PPrefsDialog(PAdmin *admin) : fAdmin(admin)
fEnableMusrT0_checkBox->setChecked(fAdmin->getEnableMusrT0Flag());
fPerRunBlockChisq_checkBox->setChecked(fAdmin->getChisqPerRunBlockFlag());
fEstimateN0_checkBox->setChecked(fAdmin->getEstimateN0Flag());
fYamlOut_checkBox->setChecked(fAdmin->getYamlOutFlag());
fFourier_checkBox->setChecked(fAdmin->getMusrviewShowFourierFlag());
fAvg_checkBox->setChecked(fAdmin->getMusrviewShowAvgFlag());
fOneToOne_checkBox->setChecked(fAdmin->getMusrviewShowOneToOneFlag());

View File

@ -54,6 +54,7 @@ class PPrefsDialog : public QDialog, private Ui::PPrefsDialog
bool getEnableMusrT0Flag() { return fEnableMusrT0_checkBox->isChecked(); }
bool getKeepRunPerBlockChisqFlag() { return fPerRunBlockChisq_checkBox->isChecked(); }
bool getEstimateN0Flag() { return fEstimateN0_checkBox->isChecked(); }
bool getYamlOutFlag() { return fYamlOut_checkBox->isChecked(); }
bool getDarkThemeIconsMenuFlag() { return fDarkThemeIconsMenu_checkBox->isChecked(); }
bool getDarkThemeIconsToolbarFlag() { return fDarkThemeIconsToolbar_checkBox->isChecked(); }
bool getOneToOneFlag() { return fOneToOne_checkBox->isChecked(); }

View File

@ -2108,6 +2108,11 @@ void PTextEdit::musrFit()
cmd.append("--estimateN0");
}
// check yamlOut flag
if (fAdmin->getYamlOutFlag()) {
cmd.append("--yaml");
}
// check per-run-block-chisq flag
if (fAdmin->getChisqPerRunBlockFlag()) {
cmd.append("--per-run-block-chisq");
@ -2184,6 +2189,7 @@ void PTextEdit::musrMsr2Data()
fMsr2DataParam->keepMinuit2Output = fAdmin->getKeepMinuit2OutputFlag();
fMsr2DataParam->titleFromDataFile = fAdmin->getTitleFromDataFileFlag();
fMsr2DataParam->estimateN0 = fAdmin->getEstimateN0Flag();
fMsr2DataParam->yamlOut = fAdmin->getYamlOutFlag();
fMsr2DataParam->perRunBlockChisq = fAdmin->getChisqPerRunBlockFlag();
PMsr2DataDialog *dlg = new PMsr2DataDialog(fMsr2DataParam, fAdmin->getHelpUrl("msr2data"));
@ -2206,6 +2212,7 @@ void PTextEdit::musrMsr2Data()
fAdmin->setKeepMinuit2OutputFlag(fMsr2DataParam->keepMinuit2Output);
fAdmin->setTitleFromDataFileFlag(fMsr2DataParam->titleFromDataFile);
fAdmin->setEstimateN0Flag(fMsr2DataParam->estimateN0);
fAdmin->setYamlOutFlag(fMsr2DataParam->yamlOut);
fAdmin->setChisqPerRunBlockFlag(fMsr2DataParam->perRunBlockChisq);
// analyze parameters
@ -2336,6 +2343,11 @@ void PTextEdit::musrMsr2Data()
cmd.append("-e");
}
// yaml out. Add flag only if a fit is done
if (fMsr2DataParam->yamlOut && (fMsr2DataParam->fitOnly || fMsr2DataParam->templateRunNo != -1)) {
cmd.append("-y");
}
// write per-run-block chisq. Add flag only if a fit is done
if (fMsr2DataParam->perRunBlockChisq && (fMsr2DataParam->fitOnly || fMsr2DataParam->templateRunNo != -1)) {
cmd.append("-p");
@ -2713,6 +2725,7 @@ void PTextEdit::musrPrefs()
fAdmin->setTimeout(dlg->getTimeout());
fAdmin->setChisqPerRunBlockFlag(dlg->getKeepRunPerBlockChisqFlag());
fAdmin->setEstimateN0Flag(dlg->getEstimateN0Flag());
fAdmin->setYamlOutFlag(dlg->getYamlOutFlag());
}
delete dlg;

View File

@ -338,7 +338,7 @@
<x>6</x>
<y>20</y>
<width>560</width>
<height>131</height>
<height>135</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
@ -456,6 +456,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fYamlOut_checkBox">
<property name="text">
<string>yaml out</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>

View File

@ -33,7 +33,7 @@
<item>
<widget class="QTabWidget" name="fTabWidget">
<property name="currentIndex">
<number>2</number>
<number>1</number>
</property>
<widget class="QWidget" name="fGeneral_tab">
<attribute name="title">
@ -152,9 +152,9 @@
<widget class="QCheckBox" name="fTitleFromData_checkBox">
<property name="geometry">
<rect>
<x>190</x>
<x>170</x>
<y>10</y>
<width>241</width>
<width>171</width>
<height>23</height>
</rect>
</property>
@ -165,7 +165,7 @@
<widget class="QCheckBox" name="fPerRunBlockChisq_checkBox">
<property name="geometry">
<rect>
<x>190</x>
<x>170</x>
<y>35</y>
<width>241</width>
<height>22</height>
@ -178,9 +178,9 @@
<widget class="QCheckBox" name="fEstimateN0_checkBox">
<property name="geometry">
<rect>
<x>190</x>
<x>170</x>
<y>60</y>
<width>241</width>
<width>101</width>
<height>22</height>
</rect>
</property>
@ -188,6 +188,19 @@
<string>estimate N0</string>
</property>
</widget>
<widget class="QCheckBox" name="fYamlOut_checkBox">
<property name="geometry">
<rect>
<x>360</x>
<y>10</y>
<width>85</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>yaml out</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="fMusrview_tab">
<attribute name="title">

View File

@ -56,6 +56,7 @@ struct PMsr2DataParam {
bool openFilesAfterFitting; ///< flag: true = open msr-file after fit in musredit. false = do not open msr-file after fit.
bool titleFromDataFile; ///< flag indicating if the title for the msr-file shall be extracted from the data-file ('-t' in msr2data)
bool estimateN0; ///< flag indicating if the N0 shall be estimated for single histogram fitting
bool yamlOut; ///< flag indicating if the MINUIT2.OUTPUT content should be written to <msr-file>.yaml
bool perRunBlockChisq; ///< flag indicating if per-run-block-chisq shall be dumped into the msr-file
bool createMsrFileOnly; ///< flag: true = just create the msr-files without any fitting ('msr-<template>' in msr2data)
bool fitOnly; ///< flag: true = just perform the fits wihtout generating any msr-files ('fit' in msr2data).

View File

@ -14,6 +14,7 @@
<title_from_data_file>y</title_from_data_file>
<chisq_per_run_block>n</chisq_per_run_block>
<estimate_n0>y</estimate_n0>
<yaml_out>n</yaml_out>
<musrview_show_fourier>n</musrview_show_fourier>
<musrview_show_avg>n</musrview_show_avg>
<musrview_show_one_to_one>n</musrview_show_one_to_one>

View File

@ -127,6 +127,7 @@ void musrfit_syntax()
std::cout << std::endl << " (ii) if present under $HOME/.musrfit/";
std::cout << std::endl << " (iii) if present under $MUSRFITPATH/";
std::cout << std::endl << " (iv) if present under $ROOTSYS/";
std::cout << std::endl << " -y, --yaml: write fit results (MINUIT2.OUTPUT) into a yaml-file. Output <msr-file>.yaml";
std::cout << std::endl << " --dump <type> is writing a data file with the fit data and the theory";
std::cout << std::endl << " <type> can be 'ascii', 'root'";
std::cout << std::endl << " --timeout <timeout_tag>: overwrites to predefined timeout of " << timeout << " (sec).";
@ -446,6 +447,7 @@ int main(int argc, char *argv[])
int status;
bool keep_mn2_output = false;
bool chisq_only = false;
bool yaml_out = false;
bool title_from_data_file = false;
bool timeout_enabled = true;
bool reset_startup_file = false;
@ -532,6 +534,8 @@ int main(int argc, char *argv[])
startup_options.estimateN0 = true;
} else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--per-run-block-chisq")) {
startup_options.writeExpectedChisq = true;
} else if (!strcmp(argv[i], "-y") || !strcmp(argv[i], "--yaml")) {
yaml_out = true;
} else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--no-of-cores-avail")) {
#ifdef HAVE_GOMP
std::cout << std::endl;
@ -724,7 +728,7 @@ int main(int argc, char *argv[])
// do fitting
std::unique_ptr<PFitter> fitter;
if (success) {
fitter = std::make_unique<PFitter>(msrHandler.get(), runListCollection.get(), chisq_only);
fitter = std::make_unique<PFitter>(msrHandler.get(), runListCollection.get(), chisq_only, yaml_out);
if (fitter->IsValid()) {
fitter->DoFit();
if (!fitter->IsScanOnly())