/**************************************************************************** PFitOutputHandler.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch *****************************************************************************/ /*************************************************************************** * Copyright (C) 2009-2019 by Andreas Suter * * andreas.suter@psi.ch * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include "PFitOutputHandler.h" //---------------------------------------------------------------------------------------------------- /** *

Sets up the fit output handler GUI and starts the actual fit * * \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. */ PFitOutputHandler::PFitOutputHandler(QString workingDirectory, QVector &cmd) { if (cmd.empty()) return; // Layout fVbox = new QVBoxLayout( this ); //Qt.3x fVbox->resize(800, 500); fOutput = new QPlainTextEdit(); fOutput->setMaximumBlockCount(1000); fVbox->addWidget(fOutput); fOutput->setMinimumSize(800, 455); fOutput->setReadOnly(true); connect( fOutput, SIGNAL( destroyed() ), this, SLOT( quitButtonPressed() ) ); fQuitButton = new QPushButton( tr("Fitting...") ); fVbox->addWidget(fQuitButton); connect( fQuitButton, SIGNAL( clicked() ), this, SLOT( quitButtonPressed() ) ); resize( 800, 500 ); fQuitButton->setFocus(); // QProcess related code fProc = new QProcess( this ); // make sure that the system environment variables are properly set QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("LD_LIBRARY_PATH", env.value("ROOTSYS") + "/lib:" + env.value("LD_LIBRARY_PATH")); fProc->setProcessEnvironment(env); fProc->setWorkingDirectory(workingDirectory); // Set up the command and arguments. QString program = cmd[0]; QStringList arguments; for (int i=1; istart(program, arguments); if ( !fProc->waitForStarted() ) { // error handling QString msg(tr("Could not execute the output command: ")+cmd[0]); QMessageBox::critical( nullptr, tr("Fatal error"), msg, tr("Quit") ); done(0); } fProcPID = fProc->pid(); } //---------------------------------------------------------------------------------------------------- /** *

Destructor. Checks if the a fit is still running and if yes try to kill it. */ PFitOutputHandler::~PFitOutputHandler() { if (fProc->state() == QProcess::Running) { fProc->terminate(); if (!fProc->waitForFinished()) { qDebug() << "fProc still running, will call kill." << endl; fProc->kill(); } fProc->waitForFinished(); } if (fProc->state() == QProcess::Running) { QString cmd = "kill -9 "+ QString("%1").arg(fProcPID); QString msg = "fProc still running even after Qt kill, will try system kill cmd: "+cmd; qDebug() << msg << endl; system(cmd.toLatin1()); } if (fProc) { delete fProc; fProc = nullptr; } } //---------------------------------------------------------------------------------------------------- /** *

Captures the standard output and adds it to the output text edit. */ void PFitOutputHandler::readFromStdOut() { // Read and process the data. // Bear in mind that the data might be output in chunks. fOutput->appendPlainText( fProc->readAllStandardOutput() ); } //---------------------------------------------------------------------------------------------------- /** *

Captures the standard error and adds it to the output text edit. */ void PFitOutputHandler::readFromStdErr() { // Read and process the data. // Bear in mind that the data might be output in chunks. fOutput->appendPlainText( fProc->readAllStandardError() ); } //---------------------------------------------------------------------------------------------------- /** *

If musrfit finishes, crashes, ..., the quit button text will be changed to done. * * \param exitCode exit code of musrfit * \param exitStatus exit status of musrfit */ void PFitOutputHandler::processDone(int exitCode, QProcess::ExitStatus exitStatus) { if ((exitStatus == QProcess::CrashExit) && (exitCode != 0)) qDebug() << "**ERROR** PFitOutputHandler::processDone: exitCode = " << exitCode << endl; fQuitButton->setText("Done"); } //---------------------------------------------------------------------------------------------------- /** *

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. */ void PFitOutputHandler::quitButtonPressed() { // if the fitting is still taking place, kill it if (fProc->state() == QProcess::Running) { fProc->terminate(); if (!fProc->waitForFinished()) { fProc->kill(); } } accept(); } //---------------------------------------------------------------------------------------------------- // END //----------------------------------------------------------------------------------------------------