diff --git a/src/musredit_qt6/musredit/PMsr2DataDialog.cpp b/src/musredit_qt6/musredit/PMsr2DataDialog.cpp index 58e7bfdb6..a8ee6dc9e 100644 --- a/src/musredit_qt6/musredit/PMsr2DataDialog.cpp +++ b/src/musredit_qt6/musredit/PMsr2DataDialog.cpp @@ -27,6 +27,23 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +/** + * @file PMsr2DataDialog.cpp + * @brief Implementation of the msr2data configuration dialog. + * + * @details Provides the implementation of PMsr2DataDialog class methods for + * configuring batch processing of µSR data fits using the msr2data tool. The + * dialog manages complex parameter interdependencies and validates user input + * to ensure consistent msr2data execution. + * + * The implementation handles initialization of all UI controls from saved + * parameters, enforces mutual exclusivity between conflicting options, and + * collects the complete configuration for msr2data execution. + * + * @author Andreas Suter + * @date 2009-2025 + */ + #include #include #include @@ -39,10 +56,60 @@ //---------------------------------------------------------------------------------------------------- /** - *

Constructor. + * @brief Constructor - Initializes the msr2data configuration dialog. * - * \param msr2DataParam data structure keeping the necessary information to feed msr2data - * \param helpUrl help url for msr2data + * @details Sets up the complete user interface for msr2data parameter configuration. + * The initialization process includes: + * + * 1. **UI Setup**: Loads the dialog layout from Qt Designer UI file + * 2. **Modal Configuration**: Sets the dialog as modal to ensure completion + * 3. **Field Population**: Fills all text fields from saved parameters + * 4. **Validation**: Installs integer validator on template run number field + * 5. **Checkbox States**: Restores all checkbox states from saved configuration + * 6. **Signal Connections**: Establishes slots for option interdependencies + * + * The dialog handles a comprehensive set of msr2data parameters: + * + * **Run Input:** + * - Direct run list (comma-separated, ranges allowed) + * - Run list file path + * - Template run number for msr file generation + * - msr file extension (e.g., ".msr") + * + * **Output Configuration:** + * - Database output file name + * - Parameter list for output + * - Write/recreate database file options + * - Column data and YAML output formats + * + * **Processing Options:** + * - Create msr files only (no fitting) + * - Fit only (use existing msr files) + * - Chain fitting (sequential parameter passing) + * - Global/Global+ fitting modes (mutually exclusive) + * + * **Advanced Options:** + * - Estimate N0 from data + * - Keep MINUIT2 output files + * - Per-run block chi-square values + * - Title from data file + * - Ignore data header information + * - Open files after fitting + * + * @param msr2DataParam Pointer to PMsr2DataParam structure containing previously + * saved msr2data settings. Must not be nullptr. The dialog + * will populate UI controls from this structure and update + * it when accepted. + * @param helpUrl URL string for online msr2data documentation. If empty, the + * help button will display a placeholder message. + * + * @note The template run number field only accepts integer input via QIntValidator. + * @note The OK button is set as the default button for convenient dialog acceptance. + * @note Signal connections enforce mutual exclusivity between global and global+. + * + * @see getMsr2DataParam() Retrieves updated parameters after dialog acceptance + * @see globalOptionSet() Handles global checkbox interactions + * @see globalPlusOptionSet() Handles global+ checkbox interactions */ PMsr2DataDialog::PMsr2DataDialog(PMsr2DataParam *msr2DataParam, const QString helpUrl) : fMsr2DataParam(msr2DataParam), fHelpUrl(helpUrl) { @@ -104,7 +171,53 @@ PMsr2DataDialog::PMsr2DataDialog(PMsr2DataParam *msr2DataParam, const QString he //---------------------------------------------------------------------------------------------------- /** - *

returns the msr2data relevant parameters from the GUI. + * @brief Retrieves all msr2data parameters from dialog UI controls. + * + * @details Collects values from all text fields and checkboxes in the dialog + * and updates the internal PMsr2DataParam structure. This method provides a + * complete snapshot of the user's msr2data configuration. + * + * The collected parameters include: + * + * **Run Specification:** + * - runList: Direct run list string (e.g., "123,125-130,145") + * - runListFileName: Path to file containing run numbers + * - msrFileExtension: File extension for msr files (e.g., ".msr") + * - templateRunNo: Template run number for msr file generation (-1 if empty) + * + * **Output Configuration:** + * - dbOutputFileName: Database file path for fit results + * - paramList: Comma-separated list of parameters to extract + * - writeDbHeader: Write header line to database file + * - writeColumnData: Output results in column format + * - yamlOut: Generate YAML format output + * - perRunBlockChisq: Include per-run chi-square values + * + * **Processing Control:** + * - createMsrFileOnly: Generate msr files without fitting + * - fitOnly: Fit existing msr files (no template needed) + * - chainFit: Pass parameters sequentially between runs + * - global: Standard global fitting mode + * - globalPlus: Enhanced global fitting mode + * + * **Advanced Options:** + * - estimateN0: Estimate initial asymmetry from data + * - keepMinuit2Output: Preserve MINUIT2 output files + * - recreateDbFile: Overwrite existing database file + * - ignoreDataHeaderInfo: Skip data file header parsing + * - titleFromDataFile: Extract title from data file + * - openFilesAfterFitting: Open result files in default applications + * + * @return PMsr2DataParam* Pointer to the updated parameter structure. This is + * the same pointer passed to the constructor, with all fields updated + * from the dialog UI. The caller retains ownership. + * + * @note This method is typically called after the dialog is accepted via OK button. + * @note Empty template run number field is converted to -1 to indicate no template. + * @note The method performs no validation; all values are accepted as entered. + * + * @see PMsr2DataDialog::PMsr2DataDialog() Where the parameter structure is initialized + * @see PMsr2DataParam Structure definition with all field descriptions */ PMsr2DataParam* PMsr2DataDialog::getMsr2DataParam() { @@ -139,10 +252,26 @@ PMsr2DataParam* PMsr2DataDialog::getMsr2DataParam() //---------------------------------------------------------------------------------------------------- /** - *

SLOT: called when in the 'Run List Input', the 'Run List' text field is activated. It clears any - * entries in 'First', 'Last', and 'Run List File Name'. It furthermore sets the run tag. + * @brief Slot: Handles direct run list entry. * - * \param str string content of the QTextEdit field. + * @details Called when the user enters text in the direct run list field. + * Ensures that only one run input method is active by clearing the run list + * file name field if it contains text. Sets the run tag to 0 to indicate + * direct list input mode. + * + * The run list accepts various formats: + * - Single runs: "123" + * - Multiple runs: "123,125,130" + * - Ranges: "123-130" + * - Combined: "123,125-130,145" + * + * @param str The run list string entered by the user. Empty strings are ignored. + * + * @note This method enforces mutual exclusivity with runListFileNameEntered(). + * @note The run tag value can be retrieved via getRunTag() after dialog acceptance. + * + * @see runListFileNameEntered() Alternative run input method + * @see getRunTag() Returns the active input method indicator */ void PMsr2DataDialog::runListEntered(const QString &str) { @@ -157,10 +286,36 @@ void PMsr2DataDialog::runListEntered(const QString &str) //---------------------------------------------------------------------------------------------------- /** - *

SLOT: called when in the 'Run List Input', the 'Run List File Name' text field is activated. It clears any - * entries in 'First', 'Last', and 'Run List'. It furthermore sets the run tag. + * @brief Slot: Handles run list file name entry. * - * \param str string content of the QTextEdit field. + * @details Called when the user enters a file path in the run list file name + * field. Ensures that only one run input method is active by clearing the + * direct run list field if it contains text. Sets the run tag to 1 to indicate + * file-based input mode. + * + * The run list file should contain run numbers in simple format: + * - One run per line + * - Ranges allowed (e.g., "123-130") + * - Comments starting with '#' + * - Blank lines ignored + * + * Example run list file: + * @code + * # Temperature series + * 123 + * 125-130 + * 145 + * @endcode + * + * @param str The file path entered by the user. Empty strings are ignored. + * + * @note This method enforces mutual exclusivity with runListEntered(). + * @note The file path is not validated by this method; validation occurs + * during msr2data execution. + * @note The run tag value can be retrieved via getRunTag() after dialog acceptance. + * + * @see runListEntered() Alternative run input method + * @see getRunTag() Returns the active input method indicator */ void PMsr2DataDialog::runListFileNameEntered(const QString &str) { @@ -175,10 +330,28 @@ void PMsr2DataDialog::runListFileNameEntered(const QString &str) //---------------------------------------------------------------------------------------------------- /** - *

SLOT: called when in 'Template Run Input', the 'Template Run Number' text field is activated. - * It set at the same time the fit-only flag to false. + * @brief Slot: Handles template run number entry. * - * \param str string content of the QTextEdit field. + * @details Called when the user enters a template run number. The template run + * specifies an existing msr file that will be used as a pattern for generating + * msr files for all runs in the run list. + * + * Since providing a template implies the intent to create new msr files, this + * method automatically unchecks the "Fit Only" checkbox to ensure consistency. + * The fit-only mode assumes existing msr files and doesn't use templates. + * + * The template run number must correspond to an existing, valid msr file. The + * template's structure (FITPARAMETER, THEORY, RUN blocks) will be preserved, + * with RUN block numbers updated for each processed run. + * + * @param str The template run number string. Must be a valid integer. Non-empty + * values automatically disable fit-only mode. + * + * @note The integer validator ensures only numeric input is accepted. + * @note Empty string is allowed to clear the template (for fit-only mode). + * + * @see fitOnlyChanged() Complementary method that clears template when fit-only + * mode is enabled */ void PMsr2DataDialog::templateRunEntered(const QString &str) { @@ -189,10 +362,26 @@ void PMsr2DataDialog::templateRunEntered(const QString &str) //---------------------------------------------------------------------------------------------------- /** - *

SLOT: called when the 'Create msr-File only' QCheckBox under 'Options' is activated. - * Sets at the same time the fit-only flag to false. + * @brief Slot: Handles "Create msr-File only" checkbox changes. * - * \param buttonState state of the button. + * @details Called when the user toggles the create-msr-file-only checkbox. + * This mode generates msr files from the template without performing fits, + * which is useful for reviewing generated files before batch fitting. + * + * Since creating files only and fitting only are mutually exclusive operations, + * checking this option automatically unchecks "Fit Only". + * + * Workflow for create-only mode: + * 1. Specify run list (direct or file) + * 2. Provide template run number + * 3. Check "Create msr-File only" + * 4. Execute to generate msr files + * 5. Review generated files + * 6. Optionally run again with "Fit Only" to perform fits + * + * @param buttonState Qt checkbox state (Qt::Checked or Qt::Unchecked). + * + * @see fitOnlyChanged() Complementary method for the fit-only option */ void PMsr2DataDialog::createMsrFileOnlyChanged(int buttonState) { @@ -203,11 +392,31 @@ void PMsr2DataDialog::createMsrFileOnlyChanged(int buttonState) //---------------------------------------------------------------------------------------------------- /** - *

SLOT: called when the 'Fit Only' QCheckBox under 'Options' is activated. - * Sets at the same time the create-msr-file-only and global flags to false. Clears the 'Template Run Number' - * field. + * @brief Slot: Handles "Fit Only" checkbox changes. * - * \param buttonState state of the button. + * @details Called when the user toggles the fit-only checkbox. This mode fits + * existing msr files without generating new ones, which is useful for refitting + * after manual msr file modifications or after initial create-only generation. + * + * When fit-only mode is enabled: + * - "Create msr-File only" is automatically unchecked (mutually exclusive) + * - Template run number field is cleared (no template needed) + * + * Fit-only mode workflow: + * 1. Specify run list (direct or file) + * 2. Ensure msr files exist for all runs + * 3. Check "Fit Only" + * 4. Execute to fit existing msr files + * + * This is particularly useful for: + * - Refitting after parameter adjustments + * - Fitting manually created msr files + * - Two-stage workflow (create, review, then fit) + * + * @param buttonState Qt checkbox state (Qt::Checked or Qt::Unchecked). + * + * @see createMsrFileOnlyChanged() Complementary method for the create-only option + * @see templateRunEntered() Clears fit-only when template is provided */ void PMsr2DataDialog::fitOnlyChanged(int buttonState) { @@ -219,7 +428,35 @@ void PMsr2DataDialog::fitOnlyChanged(int buttonState) //---------------------------------------------------------------------------------------------------- /** - *

Generates a help content window showing the description for msr2data. + * @brief Opens online help documentation for msr2data. + * + * @details Attempts to open the msr2data help URL in the user's default web + * browser using QDesktopServices::openUrl(). The documentation typically covers: + * + * - Command-line syntax and options + * - Template system usage and requirements + * - Run list formats and specifications + * - Global and global+ fitting modes + * - Output file formats (database, column, YAML) + * - Parameter extraction and mapping + * - Chain fitting for sequential parameter passing + * - Batch processing best practices + * - Troubleshooting common issues + * + * Error handling: + * - If fHelpUrl is empty: displays an information dialog with a placeholder + * message indicating future help availability + * - If the browser fails to open: displays a critical error dialog with the + * URL formatted as a clickable hyperlink for manual access + * + * The URL is parsed in TolerantMode to handle various URL formats flexibly. + * + * @note This slot is connected to the help button click signal in the UI. + * @note The dialog remains open after help is displayed, allowing users to + * reference documentation while configuring parameters. + * + * @see PMsr2DataDialog::PMsr2DataDialog() Where fHelpUrl is initialized + * @see QDesktopServices::openUrl() For the browser opening mechanism */ void PMsr2DataDialog::helpContent() { @@ -236,9 +473,27 @@ void PMsr2DataDialog::helpContent() //---------------------------------------------------------------------------------------------------- /** - *

Unchecks global+ if global is checked since global/global+ are excluding options + * @brief Private slot: Enforces global/global+ mutual exclusivity (global side). * - * \param checked true, if the check-box is checked + * @details Called when the "global" checkbox state changes. Global and global+ + * are mutually exclusive fitting modes that cannot be used simultaneously: + * + * - **global**: Standard global fitting where parameters marked as "global" in + * the msr file are shared across all runs in the fit. All runs are fitted + * simultaneously with shared parameters constrained to have identical values. + * + * - **global+**: Enhanced global fitting mode with additional features for + * complex multi-run scenarios (see msr2data documentation for details). + * + * When global is checked, this method automatically unchecks global+ to prevent + * conflicting mode selection. + * + * @param checked true if the global checkbox is now checked, false otherwise. + * + * @note This slot is connected to the global checkbox clicked signal in the + * constructor. + * + * @see globalPlusOptionSet() Complementary method handling global+ checkbox */ void PMsr2DataDialog::globalOptionSet(bool checked) { @@ -250,9 +505,27 @@ void PMsr2DataDialog::globalOptionSet(bool checked) //---------------------------------------------------------------------------------------------------- /** - *

Unchecks global if global+ is checked since global/global+ are excluding options + * @brief Private slot: Enforces global/global+ mutual exclusivity (global+ side). * - * \param checked true, if the check-box is checked + * @details Called when the "global+" checkbox state changes. Global and global+ + * are mutually exclusive fitting modes that cannot be used simultaneously: + * + * - **global**: Standard global fitting where parameters marked as "global" in + * the msr file are shared across all runs in the fit. + * + * - **global+**: Enhanced global fitting mode with extended capabilities for + * handling more complex global fitting scenarios with additional constraints + * and parameter relationships. + * + * When global+ is checked, this method automatically unchecks global to prevent + * conflicting mode selection. + * + * @param checked true if the global+ checkbox is now checked, false otherwise. + * + * @note This slot is connected to the global+ checkbox clicked signal in the + * constructor. + * + * @see globalOptionSet() Complementary method handling global checkbox */ void PMsr2DataDialog::globalPlusOptionSet(bool checked) { diff --git a/src/musredit_qt6/musredit/PMsr2DataDialog.h b/src/musredit_qt6/musredit/PMsr2DataDialog.h index 936db278d..9fdb01e1e 100644 --- a/src/musredit_qt6/musredit/PMsr2DataDialog.h +++ b/src/musredit_qt6/musredit/PMsr2DataDialog.h @@ -27,6 +27,24 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +/** + * @file PMsr2DataDialog.h + * @brief Dialog interface for the msr2data batch processing tool. + * + * @details This header defines the PMsr2DataDialog class which provides a + * graphical user interface for configuring and launching B.M. Wojek's msr2data + * program. The msr2data tool automates the process of fitting multiple µSR runs + * using template msr files and extracting fit parameters to data files. + * + * @author Andreas Suter + * @date 2010-2025 + * @copyright Copyright (C) 2010-2025 by Andreas Suter + * @license GNU General Public License v2 or later + * + * @see PMsr2DataParam Data structure for msr2data parameters + * @see musredit Main editor application + */ + #ifndef _PMSR2DATADIALOG_H_ #define _PMSR2DATADIALOG_H_ @@ -37,35 +55,221 @@ #include "ui_PMsr2DataDialog.h" /** - *

Class handling the content of the MusrFit/Msr2Data GUI. It collects the input - * for B.M. Wojek's msr2data program. + * @class PMsr2DataDialog + * @brief Dialog for configuring msr2data batch processing parameters. + * + * @details This dialog collects all necessary input parameters for B.M. Wojek's + * msr2data program, which automates the fitting of multiple µSR data runs. The + * tool uses a template msr file to generate individual fit files for each run + * and optionally extracts fit results to database or column files. + * + * @par Run Selection: + * Users can specify runs to process in two ways: + * - Direct run list: Comma-separated run numbers (e.g., "123,125-130,145") + * - Run list file: Path to a file containing run numbers + * + * @par Template System: + * A template run number defines an existing msr file used as a pattern for + * creating msr files for all runs in the list. The template's RUN blocks + * are updated with new run numbers while preserving the fit structure. + * + * @par Processing Modes: + * - Create msr files only: Generate msr files without fitting + * - Fit only: Fit existing msr files (no template needed) + * - Full processing: Create msr files and fit them + * + * @par Global Fitting: + * - global: Fit with shared parameters across runs (standard global fit) + * - global+: Enhanced global fitting with additional constraints + * + * @par Output Options: + * - Database file: Append fit results to a structured database + * - Column file: Write results in columnar format + * - YAML output: Export fit results in YAML format + * - Per-run chi-square: Include individual run chi-square values + * + * @note The dialog enforces mutual exclusivity between conflicting options + * (e.g., create-only vs. fit-only, global vs. global+). + * + * @see PMsr2DataParam Structure holding all msr2data parameters + * @see musredit For the main editor application */ class PMsr2DataDialog : public QDialog, private Ui::PMsr2DataDialog { Q_OBJECT public: + /** + * @brief Constructs the msr2data configuration dialog. + * + * @details Initializes the dialog with existing msr2data parameters and + * sets up all UI controls including text fields, checkboxes, and validators. + * The dialog is configured as modal and establishes signal-slot connections + * for option interdependencies. + * + * @param msr2DataParam Pointer to the parameter structure containing + * previously saved msr2data settings. The dialog will + * populate fields with these values and update them + * when the user accepts the dialog. + * @param helpUrl URL string pointing to online msr2data documentation. + * If empty, the help button will show a placeholder message. + * + * @see getMsr2DataParam() Retrieves updated parameters after dialog acceptance + * @see PMsr2DataParam Data structure definition + */ PMsr2DataDialog(PMsr2DataParam *msr2DataParam, const QString helpUrl); + /** + * @brief Returns the run input method tag. + * + * @details Indicates which method was used to specify the run list: + * - -1: Invalid or no input provided + * - 0: Direct run list entered in the text field + * - 1: Run list file name provided + * + * This tag helps the caller determine how to interpret the run information + * when processing the dialog results. + * + * @return int representing the run input method (see details). + * + * @see runListEntered() Sets tag to 0 + * @see runListFileNameEntered() Sets tag to 1 + */ virtual int getRunTag() { return fRunTag; } + + /** + * @brief Retrieves all msr2data parameters from the dialog. + * + * @details Collects values from all UI controls and updates the internal + * PMsr2DataParam structure. This includes: + * - Run list specifications (direct list or file) + * - Template run number + * - msr file extension + * - Output file names and parameter list + * - All checkbox options (header writing, estimation, fitting modes, etc.) + * + * This method is typically called after the dialog is accepted to obtain + * the complete configuration for launching msr2data. + * + * @return PMsr2DataParam* Pointer to the updated parameter structure. + * The caller owns this structure and must manage its lifetime. + * + * @note The returned pointer is the same as the one passed to the constructor, + * just with updated values. + * + * @see PMsr2DataParam For the complete parameter structure definition + */ virtual PMsr2DataParam* getMsr2DataParam(); public slots: + /** + * @brief Handles run list text field activation. + * + * @details Called when the user enters text in the direct run list field. + * Clears the run list file name field to ensure only one input method is + * active, and sets the run tag to indicate direct list entry. + * + * @param str The run list string (e.g., "123,125-130,145"). + * + * @see runListFileNameEntered() For the alternative input method + * @see getRunTag() Returns the set run tag value + */ void runListEntered(const QString&); + + /** + * @brief Handles run list file name text field activation. + * + * @details Called when the user enters a file name containing run numbers. + * Clears the direct run list field to ensure only one input method is + * active, and sets the run tag to indicate file-based input. + * + * @param str Path to the run list file. + * + * @see runListEntered() For the alternative input method + * @see getRunTag() Returns the set run tag value + */ void runListFileNameEntered(const QString&); + + /** + * @brief Handles template run number text field activation. + * + * @details Called when the user enters a template run number. Automatically + * disables the "Fit Only" checkbox since a template implies msr file creation. + * + * @param str The template run number string. + * + * @note Template run numbers must be valid integers representing existing + * msr files. + */ void templateRunEntered(const QString&); + + /** + * @brief Handles "Create msr-File only" checkbox state changes. + * + * @details Called when the create-only checkbox is toggled. If checked, + * automatically unchecks "Fit Only" since these modes are mutually exclusive. + * + * @param buttonState Qt checkbox state (Qt::Checked or Qt::Unchecked). + * + * @see fitOnlyChanged() For the complementary option + */ void createMsrFileOnlyChanged(int); + + /** + * @brief Handles "Fit Only" checkbox state changes. + * + * @details Called when the fit-only checkbox is toggled. If checked, + * automatically unchecks "Create msr-File only" and clears the template + * run number since fitting existing files doesn't require a template. + * + * @param buttonState Qt checkbox state (Qt::Checked or Qt::Unchecked). + * + * @see createMsrFileOnlyChanged() For the complementary option + */ void fitOnlyChanged(int); + + /** + * @brief Opens online help for msr2data. + * + * @details Attempts to open the msr2data documentation in the default + * web browser. The documentation covers command-line options, template + * system usage, global fitting, and output formats. + * + * @see PMsr2DataDialog::PMsr2DataDialog() Where helpUrl is initialized + */ void helpContent(); private slots: + /** + * @brief Enforces mutual exclusivity between global and global+ options. + * + * @details Called when the "global" checkbox is toggled. If global is + * checked, automatically unchecks global+ since these fitting modes + * cannot be used simultaneously. + * + * @param checked true if the global checkbox is now checked. + * + * @see globalPlusOptionSet() For the complementary option + */ void globalOptionSet(bool checked); + + /** + * @brief Enforces mutual exclusivity between global+ and global options. + * + * @details Called when the "global+" checkbox is toggled. If global+ is + * checked, automatically unchecks global since these fitting modes + * cannot be used simultaneously. + * + * @param checked true if the global+ checkbox is now checked. + * + * @see globalOptionSet() For the complementary option + */ void globalPlusOptionSet(bool checked); private: - int fRunTag; ///< -1 = not valid, 0 = run list, 1 = run list file name - PMsr2DataParam *fMsr2DataParam; ///< data structure used to handle the necessary input for msr2data. - QString fHelpUrl; ///< help url for the Fourier block + int fRunTag; ///< Run input method: -1=invalid, 0=direct list, 1=file name. + PMsr2DataParam *fMsr2DataParam; ///< Pointer to parameter structure for msr2data configuration. + QString fHelpUrl; ///< URL to online msr2data documentation. }; #endif // _PMSR2DATADIALOG_H_