diff --git a/CMakeLists.txt b/CMakeLists.txt index 7485b056..525ddbe9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/src/classes/PFitter.cpp b/src/classes/PFitter.cpp index ac1c0a3f..5b155728 100644 --- a/src/classes/PFitter.cpp +++ b/src/classes/PFitter.cpp @@ -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 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 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 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 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 { diff --git a/src/include/PFitter.h b/src/include/PFitter.h index 640b5927..715d8027 100644 --- a/src/include/PFitter.h +++ b/src/include/PFitter.h @@ -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 diff --git a/src/msr2data.cpp b/src/msr2data.cpp index f2a2c796..4f8ad9c9 100644 --- a/src/msr2data.cpp +++ b/src/msr2data.cpp @@ -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 .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 &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 "); } diff --git a/src/musredit_qt5/musredit/PAdmin.cpp b/src/musredit_qt5/musredit/PAdmin.cpp index 8d440713..9963bbcb 100644 --- a/src/musredit_qt5/musredit/PAdmin.cpp +++ b/src/musredit_qt5/musredit/PAdmin.cpp @@ -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] = " n"; } + if (data[i].contains("") && data[i].contains("")) { + if (fYamlOut) + data[i] = " y"; + else + data[i] = " n"; + } if (data[i].contains("") && data[i].contains("")) { if (fMusrviewShowFourier) data[i] = " y"; diff --git a/src/musredit_qt5/musredit/PAdmin.h b/src/musredit_qt5/musredit/PAdmin.h index f359638d..1866d77b 100644 --- a/src/musredit_qt5/musredit/PAdmin.h +++ b/src/musredit_qt5/musredit/PAdmin.h @@ -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 .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) diff --git a/src/musredit_qt5/musredit/PMsr2DataDialog.cpp b/src/musredit_qt5/musredit/PMsr2DataDialog.cpp index 94d13485..d9aa50cc 100644 --- a/src/musredit_qt5/musredit/PMsr2DataDialog.cpp +++ b/src/musredit_qt5/musredit/PMsr2DataDialog.cpp @@ -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(); diff --git a/src/musredit_qt5/musredit/PPrefsDialog.cpp b/src/musredit_qt5/musredit/PPrefsDialog.cpp index 610e4262..0683edd4 100644 --- a/src/musredit_qt5/musredit/PPrefsDialog.cpp +++ b/src/musredit_qt5/musredit/PPrefsDialog.cpp @@ -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()); diff --git a/src/musredit_qt5/musredit/PPrefsDialog.h b/src/musredit_qt5/musredit/PPrefsDialog.h index ce38e856..25c4b372 100644 --- a/src/musredit_qt5/musredit/PPrefsDialog.h +++ b/src/musredit_qt5/musredit/PPrefsDialog.h @@ -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(); } diff --git a/src/musredit_qt5/musredit/PTextEdit.cpp b/src/musredit_qt5/musredit/PTextEdit.cpp index ac4feb58..96a99090 100644 --- a/src/musredit_qt5/musredit/PTextEdit.cpp +++ b/src/musredit_qt5/musredit/PTextEdit.cpp @@ -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; diff --git a/src/musredit_qt5/musredit/forms/PMsr2DataDialog.ui b/src/musredit_qt5/musredit/forms/PMsr2DataDialog.ui index 32178f4f..2f913a7d 100644 --- a/src/musredit_qt5/musredit/forms/PMsr2DataDialog.ui +++ b/src/musredit_qt5/musredit/forms/PMsr2DataDialog.ui @@ -338,7 +338,7 @@ 6 20 560 - 131 + 135 @@ -456,6 +456,13 @@ + + + + yaml out + + + diff --git a/src/musredit_qt5/musredit/forms/PPrefsDialog.ui b/src/musredit_qt5/musredit/forms/PPrefsDialog.ui index b1eb78f0..5a8060c9 100644 --- a/src/musredit_qt5/musredit/forms/PPrefsDialog.ui +++ b/src/musredit_qt5/musredit/forms/PPrefsDialog.ui @@ -33,7 +33,7 @@ - 2 + 1 @@ -152,9 +152,9 @@ - 190 + 170 10 - 241 + 161 23 @@ -165,9 +165,9 @@ - 190 + 170 35 - 241 + 181 22 @@ -178,9 +178,9 @@ - 190 + 170 60 - 241 + 171 22 @@ -188,6 +188,19 @@ estimate N0 + + + + 350 + 10 + 85 + 21 + + + + yaml out + + diff --git a/src/musredit_qt5/musredit/musredit.h b/src/musredit_qt5/musredit/musredit.h index 4cee4420..c66fbb59 100644 --- a/src/musredit_qt5/musredit/musredit.h +++ b/src/musredit_qt5/musredit/musredit.h @@ -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 .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-