diff --git a/src/musredit_qt6/musredit/PFitOutputHandler.cpp b/src/musredit_qt6/musredit/PFitOutputHandler.cpp index 8751305f9..706bda828 100644 --- a/src/musredit_qt6/musredit/PFitOutputHandler.cpp +++ b/src/musredit_qt6/musredit/PFitOutputHandler.cpp @@ -27,6 +27,20 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +/** + * @file PFitOutputHandler.cpp + * @brief Implementation of the PFitOutputHandler class. + * @details This file implements the fit output handler dialog which executes + * musrfit and displays its output in real-time. The implementation handles + * process lifecycle management, output capture, status updates, and proper + * cleanup when the fit completes or is interrupted. + * + * @author Andreas Suter + * @date 2009-2025 + * @copyright Copyright (C) 2009-2025 by Andreas Suter + * @license GNU General Public License v2 or later + */ + #include #include @@ -35,10 +49,29 @@ //---------------------------------------------------------------------------------------------------- /** - *

Sets up the fit output handler GUI and starts the actual fit + * @brief Constructs the fit output handler dialog and starts the musrfit process. * - * \param workingDirectory string holding the working directory wished. In this directory the mlog-file will be saved. - * \param cmd command string vector. From this the actuall fit command will be generated and executed. + * @details Initializes the dialog UI and starts the musrfit fitting process. + * The constructor performs the following steps: + * -# Creates the dialog layout with a plain text output area (max 1000 lines) and button + * -# Configures the process environment with appropriate library paths + * -# Sets the working directory for output files (mlog, etc.) + * -# Extracts the program and arguments from the command vector + * -# Connects process signals for output capture and completion notification + * -# Starts the musrfit process + * + * @par Environment Configuration: + * - On macOS: Sets DYLD_LIBRARY_PATH to include $ROOTSYS/lib + * - On Linux: Sets LD_LIBRARY_PATH to include $ROOTSYS/lib + * + * @param workingDirectory Directory where musrfit will run and save output files + * (mlog files, MINUIT2 output, etc.). + * @param cmd Command vector where cmd[0] is the musrfit executable path and + * subsequent elements are command-line arguments (msr filename, options). + * + * @note If the command vector is empty, the constructor returns immediately + * without creating the UI. If the process fails to start, an error dialog + * is displayed. */ PFitOutputHandler::PFitOutputHandler(QString workingDirectory, QVector &cmd) { @@ -95,7 +128,18 @@ PFitOutputHandler::PFitOutputHandler(QString workingDirectory, QVector //---------------------------------------------------------------------------------------------------- /** - *

Destructor. Checks if the a fit is still running and if yes try to kill it. + * @brief Destructor - ensures the musrfit process is terminated. + * + * @details Performs cleanup by ensuring the musrfit child process is properly + * terminated. The termination sequence is: + * -# Attempt graceful termination with QProcess::terminate() (SIGTERM) + * -# Wait for process to finish + * -# If still running, use QProcess::kill() (SIGKILL) + * -# As a last resort, use system kill -9 command with stored PID + * + * This multi-stage approach ensures the process doesn't become orphaned, + * even if musrfit doesn't respond to normal termination signals (e.g., if + * stuck in a long calculation). */ PFitOutputHandler::~PFitOutputHandler() { @@ -117,7 +161,15 @@ PFitOutputHandler::~PFitOutputHandler() //---------------------------------------------------------------------------------------------------- /** - *

Captures the standard output and adds it to the output text edit. + * @brief Slot to capture and display standard output from musrfit. + * + * @details Reads all available data from the musrfit process's standard output + * stream and appends it to the text display widget. This slot is connected to + * the QProcess::readyReadStandardOutput signal and may be called multiple times + * as output arrives in chunks during the fitting process. + * + * The output typically includes MINUIT2 iteration progress, parameter values, + * and chi-square information. */ void PFitOutputHandler::readFromStdOut() { @@ -128,7 +180,15 @@ void PFitOutputHandler::readFromStdOut() //---------------------------------------------------------------------------------------------------- /** - *

Captures the standard error and adds it to the output text edit. + * @brief Slot to capture and display standard error from musrfit. + * + * @details Reads all available data from the musrfit process's standard error + * stream and appends it to the text display widget. This slot is connected to + * the QProcess::readyReadStandardError signal and may be called multiple times + * as error output arrives in chunks. + * + * Error output typically includes warnings about parameter bounds, convergence + * issues, file access problems, and other diagnostic messages. */ void PFitOutputHandler::readFromStdErr() { @@ -139,10 +199,18 @@ void PFitOutputHandler::readFromStdErr() //---------------------------------------------------------------------------------------------------- /** - *

If musrfit finishes, crashes, ..., the quit button text will be changed to done. + * @brief Slot called when the musrfit process finishes execution. * - * \param exitCode exit code of musrfit - * \param exitStatus exit status of musrfit + * @details This slot is connected to QProcess::finished signal and is called + * when musrfit terminates, whether normally or due to a crash. It updates + * the button text from "Fitting..." to "Done" to indicate the fit has completed. + * + * If the process crashed (exitStatus == QProcess::CrashExit), a debug message + * is logged with the exit code for diagnostic purposes. + * + * @param exitCode The exit code returned by musrfit (0 typically indicates success). + * @param exitStatus The exit status: QProcess::NormalExit for normal termination, + * QProcess::CrashExit if the process crashed. */ void PFitOutputHandler::processDone(int exitCode, QProcess::ExitStatus exitStatus) { @@ -154,8 +222,17 @@ void PFitOutputHandler::processDone(int exitCode, QProcess::ExitStatus exitStatu //---------------------------------------------------------------------------------------------------- /** - *

If the quit button is pressed while the fit is still running, try to terminate musrfit, if this - * does not work, try to kill musrfit. + * @brief Slot called when the Quit/Done button is pressed. + * + * @details Handles user request to close the dialog. The behavior depends on + * whether the fit is still running: + * - If running: Attempts to terminate musrfit gracefully using QProcess::terminate(). + * If graceful termination fails within the timeout period, forcefully kills + * the process using QProcess::kill(). + * - If finished: Simply closes the dialog. + * + * After ensuring the process is stopped (or was already stopped), accepts the + * dialog (closes it with QDialog::Accepted result). */ void PFitOutputHandler::quitButtonPressed() { diff --git a/src/musredit_qt6/musredit/PFitOutputHandler.h b/src/musredit_qt6/musredit/PFitOutputHandler.h index 9d4c22818..46e4073c6 100644 --- a/src/musredit_qt6/musredit/PFitOutputHandler.h +++ b/src/musredit_qt6/musredit/PFitOutputHandler.h @@ -27,6 +27,22 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +/** + * @file PFitOutputHandler.h + * @brief Dialog for displaying musrfit fitting process output. + * @details This header defines the PFitOutputHandler class which provides + * a dialog window for executing the musrfit fitting tool and displaying its + * output in real-time. Users can monitor the fitting progress, view warnings + * and errors, and interrupt the fit if needed. + * + * @author Andreas Suter + * @date 2010-2025 + * @copyright Copyright (C) 2010-2025 by Andreas Suter + * @license GNU General Public License v2 or later + * + * @see PDumpOutputHandler For similar output handling with dump_header + */ + #ifndef _PFITOUTPUTHANDLER_H_ #define _PFITOUTPUTHANDLER_H_ @@ -44,9 +60,39 @@ //--------------------------------------------------------------------------------------- /** - *

This class is the capturing the output of musrfit and displays it in a dialog so - * the user has the chance to follow the fitting process, warnings, error messages of - * musrfit. + * @class PFitOutputHandler + * @brief Dialog for executing and monitoring musrfit fitting processes. + * + * @details This class provides a dialog that executes musrfit as a child process + * and displays its output in real-time. It allows users to monitor the fitting + * progress, including MINUIT2 iterations, chi-square values, warnings, and error + * messages. + * + * @par Features: + * - Executes musrfit as a child process via QProcess + * - Captures both stdout and stderr output in real-time + * - Displays output in a scrollable, read-only text widget (limited to 1000 lines) + * - Button shows "Fitting..." during execution, changes to "Done" when complete + * - Allows interrupting a running fit by pressing the button + * - Proper process cleanup on dialog close or destruction + * + * @par Usage: + * @code + * QVector cmd; + * cmd << "/path/to/musrfit" << "file.msr"; + * PFitOutputHandler dialog("/path/to/working/dir", cmd); + * dialog.exec(); + * @endcode + * + * @par Platform Notes: + * - On macOS: Sets DYLD_LIBRARY_PATH for ROOT library access + * - On Linux: Sets LD_LIBRARY_PATH for ROOT library access + * + * @par Output Files: + * The working directory parameter determines where musrfit saves its output + * files, including the .mlog fit log file. + * + * @see PDumpOutputHandler For similar handling of dump_header output */ class PFitOutputHandler : public QDialog { @@ -57,18 +103,45 @@ class PFitOutputHandler : public QDialog virtual ~PFitOutputHandler(); private slots: + /** + * @brief Slot to read and display standard output from musrfit. + */ virtual void readFromStdOut(); + + /** + * @brief Slot to read and display standard error from musrfit. + */ virtual void readFromStdErr(); + + /** + * @brief Slot called when the Quit/Done button is pressed. + */ virtual void quitButtonPressed(); + + /** + * @brief Slot called when the musrfit process finishes. + * @param exitCode The exit code returned by musrfit. + * @param exitStatus The exit status (normal or crash). + */ virtual void processDone(int exitCode, QProcess::ExitStatus exitStatus); -private: - qint64 fProcPID; ///< keeps the process PID - std::unique_ptr fProc; ///< pointer to the musrfit process + private: + /** @name Process Management + * @brief Members for managing the musrfit process. + * @{ + */ + qint64 fProcPID; ///< Process ID of the running musrfit process. + std::unique_ptr fProc; ///< QProcess object managing the musrfit execution. + /** @} */ - std::unique_ptr fVbox; ///< pointer to the dialog layout manager - std::unique_ptr fOutput; ///< the captured musrfit output is written (read only) into this text edit object. - std::unique_ptr fQuitButton; ///< quit button, either to interrupt the fit or to close the dialog at the end of the fit. + /** @name UI Components + * @brief Dialog user interface elements. + * @{ + */ + std::unique_ptr fVbox; ///< Vertical layout manager for dialog widgets. + std::unique_ptr fOutput; ///< Read-only text widget displaying musrfit output (max 1000 lines). + std::unique_ptr fQuitButton; ///< Button showing "Fitting..." during fit, "Done" after completion. + /** @} */ }; #endif // _PFITOUTPUTHANDLER_H_