Beispiel #1
0
int System(const QString exename, const QStringList & args, const QString fileStdErr, const QString fileStdOut, bool* cancel)
{
    QProcess proc;
    if (!fileStdOut.isEmpty())
        proc.setStandardOutputFile(fileStdOut);
    if (!fileStdErr.isEmpty())
        proc.setStandardErrorFile(fileStdErr);
    proc.start(exename, args);
    if (proc.waitForStarted(5000))
    {
        while (!proc.waitForFinished(5000))
        {
            qApp->processEvents();
            if (cancel && (*cancel == true))
            {
                proc.kill();
                break;
            }
        }
    }
    if (cancel && (*cancel == true))
        return -1;
    int ex = proc.exitCode();
    return ex;
}
void Widget::on_runButton_clicked()
{
    QProcess *process = new QProcess();

    QString filename = "";
    if(ui->fileNameEdit->text() == ""){
        filename = "sca_" + QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm") + getOptions();
    }else{
        filename = ui->fileNameEdit->text();
    }

    process->setStandardOutputFile(filename);

    QString command = "clang-tidy -extra-arg=\"-std=c++11\"" + getConfig() + " -checks='-*,misc-suspicious-call-argument' " + ui->pathEdit->text() + " --";

    //process->setWorkingDirectory("/home/varjujan/Asztal");

    process->start("/bin/bash", QStringList() << "-c" << command);
    process->waitForFinished();
    process->close();

    ui->textBrowser->setText(command);

    process = new QProcess();
    process->start("gedit", QStringList() << filename);
    process->waitForStarted();
    //process->close();
}
// Load image data
QImage ExternalImageLoader::loadImage()
{
	QImage result;

	// Configuration file loading
	QSettings settings("../res/externalimageloader.ini", QSettings::IniFormat);

	// Get external program, redirection and result file names
	QString program = settings.value("program").toString();
	QString redirection = settings.value("redirection").toString();
	QString filename = settings.value("filename").toString();

	if (program.isEmpty() || filename.isEmpty())
		return result;

	// Ensure program has started
	QProcess process;
	if (!redirection.isEmpty())
		process.setStandardOutputFile(redirection);
	process.start(program);
	if (!process.waitForStarted())
		return result;

	// Get timeout value
	int timeout = settings.value("timeout").toInt();
	QTime timer;
	timer.start();

	// Check for program exit or timeout event
	while (process.state() != QProcess::NotRunning)
	{
		if (timeout > 0 && timer.elapsed() > timeout)
		{
			// Stop process
			process.kill();
			// Try to delete file
			QDir dir;
			dir.remove(filename);
			// Return null image
			return result;
		}

		qApp->processEvents();
	}

	// Ensure program has finished correctly
	if (process.exitStatus() != QProcess::NormalExit)
		return result;

	// Try to read and remove the output file
	result = QImage(filename);
	QDir dir;
	dir.remove(filename);
	return result;
}
QProcess* Runtime::createProcess()
{
    QProcess* process = new QProcess();

    QString logFile = this->logsDir + QString("/") + QDate::currentDate().toString() + QString("_log.txt");

    process->setStandardErrorFile(logFile, QIODevice::Append);
    process->setStandardOutputFile(logFile, QIODevice::Append);

    return process;
}
Beispiel #5
0
void LSession::startProcess(QString ID, QString command){
  QString logfile = QDir::homePath()+"/.lumina/logs/"+ID+".log";
  if(QFile::exists(logfile+".old")){ QFile::remove(logfile+".old"); }
  if(QFile::exists(logfile)){ QFile::rename(logfile,logfile+".old"); }
  QProcess *proc = new QProcess();
  proc->setProcessChannelMode(QProcess::MergedChannels);
  proc->setProcessEnvironment( QProcessEnvironment::systemEnvironment() );
  proc->setStandardOutputFile(logfile);
  proc->start(command, QIODevice::ReadOnly);
  connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(procFinished()) );
  PROCS << proc;
}
Beispiel #6
0
bool PdmlFileFormat::save(const OstProto::StreamConfigList streams,
        const QString fileName, QString &error)
{
    bool isOk = false;
    QTemporaryFile pcapFile;
    StreamFileFormat *fmt = StreamFileFormat::fileFormatFromType("PCAP");
    QProcess tshark;

    Q_ASSERT(fmt);

    if (!pcapFile.open())
    {
        error.append("Unable to open temporary file to create PCAP\n");
        goto _fail;
    }

    qDebug("intermediate PCAP %s", pcapFile.fileName().toAscii().constData());

    connect(fmt, SIGNAL(target(int)), this, SIGNAL(target(int)));
    connect(fmt, SIGNAL(progress(int)), this, SIGNAL(progress(int)));

    emit status("Writing intermediate PCAP file...");
    isOk = fmt->save(streams, pcapFile.fileName(), error);

    qDebug("generating PDML %s", fileName.toAscii().constData());
    emit status("Converting PCAP to PDML...");
    emit target(0);

    tshark.setStandardOutputFile(fileName);
    tshark.start(OstProtoLib::tsharkPath(), 
            QStringList() 
            << QString("-r%1").arg(pcapFile.fileName())
            << "-Tpdml");
    if (!tshark.waitForStarted(-1))
    {
        error.append(QString("Unable to start tshark. Check path in preferences.\n"));
        goto _fail;
    }

    if (!tshark.waitForFinished(-1))
    {
        error.append(QString("Error running tshark\n"));
        goto _fail;
    }

    isOk = true;
_fail:
    return isOk;
}
Beispiel #7
0
void detailwnd::enregistrer( )
{
	QString destFile = QFileDialog::getSaveFileName(this, tr("Sauver la video"),
                            "/home/dige7306/"+leAdresse->text(),
                            tr("Video (*.asf *.asx *.wsx *.wmv *.flv *.avi)"));
	if ( destFile.isEmpty() ) return;
	QStringList arg;
	/* for eurosport
	arg << "-cache";
	arg << "4096";
	arg << "-dumpstream";
	arg << "-dumpfile";
	arg << destFile;
	arg << leAdresse->text();
	QProcess::execute( "mplayer", arg );
	arg.clear();
	arg << "/usr/share/sounds/k3b_success1.wav";
	QProcess::execute( "mplayer", arg );
	*/
	/* for atdhe.net */
	arg << leAdresse->text();
	QProcess::execute( "firefox", arg );
	sleep( 5 );	/* wait for plugin to start */
	QStringList f;
	f << "Flash*";
	QStringList files = QDir::temp().entryList( f );
	qDebug() << files[0];
	arg.clear();
	arg << "-n" << "100000" << "--follow=name" << QDir::tempPath() + "/" + files[0];
	QProcess *tail = new QProcess( this );
	tail->setStandardOutputFile( destFile, QIODevice::Truncate );
	tail->setStandardErrorFile( "/tmp/tail.err", QIODevice::Truncate );
	tail->start( "tail", arg );
	if ( tail->waitForStarted() )
	{
		int msec = teDuree->time().hour() * 60 * 60 + teDuree->time().minute() * 60;
		msec *= 1000;
		if ( msec == 0 ) msec = -1;
		if ( !tail->waitForFinished(msec) )
		{
			tail->terminate();
		}
		qDebug() << " tail : " << tail->exitStatus() << " " << tail->exitCode() << endl;
	}
	else
	{
		qDebug() << " tail non demarre" << endl;
	}
}
Beispiel #8
0
void LSession::startProcess(QString ID, QString command){
  QString dir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/logs";
  if(!QFile::exists(dir)){ QDir tmp(dir); tmp.mkpath(dir); }
  QString logfile = dir+"/"+ID+".log";
  if(QFile::exists(logfile+".old")){ QFile::remove(logfile+".old"); }
  if(QFile::exists(logfile)){ QFile::rename(logfile,logfile+".old"); }

  QProcess *proc = new QProcess();
  proc->setProcessChannelMode(QProcess::MergedChannels);
  proc->setProcessEnvironment( QProcessEnvironment::systemEnvironment() );
  proc->setStandardOutputFile(logfile);
  proc->start(command, QIODevice::ReadOnly);
  connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(procFinished()) );
  PROCS << proc;
}
Beispiel #9
0
void ScannerDialog::on_btnScan_clicked()
{
#ifdef Q_OS_LINUX
    ui->btnTest->setEnabled(false);
    ui->btnScan->setEnabled(false);
    ui->btnAnnuler->setEnabled(false);

    QProcess* process = new QProcess();
    process->setStandardOutputFile(QDir::tempPath() + "/output.pnm");
    process->start("scanimage --resolution 200");

    ui->progressBar->show();

    connect(process, SIGNAL(finished(int)), SLOT(scanFinished(int)));
#endif
}
Beispiel #10
0
QString Repository::Git::GitUtils::makeTmpFileFromCommand( QString command, QString filepath )
{
	bool ok = true;

	// Ulozim si current working directory
	QString cwd = QDir::currentPath();

	// Nastavim absolutnu cestu k  temp file ako template a zakazem automaticke mazanie
	QTemporaryFile tempFile;
	tempFile.setFileTemplate( QDir::toNativeSeparators( QDir::tempPath() + "/" +  "qXXXXXX" ) );
	tempFile.setAutoRemove( false );

	// Ak sa nepodarilo vytvorit temp subor, tak nastavim flag "ok" na false a vypisem chybu
	if ( !tempFile.open() ) {
		qDebug() << "Nepodarilo sa vytvorit tmp subor";
		ok = false;
	}

	// Ak sa podarilo vytvorit temp subor, tak zmenim current working directory
	if ( ok ) {
		ok = changeDir( filepath );
	}

	// Ak sa podarilo zmenit current working directory, tak skontroluje existenciu git repozitara
	if ( ok ) {
		ok = existGit( filepath );
	}

	// Ak existuje na danej ceste git repozitar, tak vykonam command a vystup ulozim do temp suboru
	if ( ok ) {
		QProcess process;
		process.setStandardOutputFile( QDir::toNativeSeparators( tempFile.fileName() ) );
		process.start( command );
		process.waitForFinished();
		process.close();
		process.terminate();

	}

	// Vratim povodny current working directory, ak sa nepodari zmenit, vypisem do konzoly
	if ( !changeDir( cwd ) ) {
		qDebug() << "Nepodarilo sa vratit na povodny current working directory";
	}

	// Vratim absolutnu cestu k temp suboru
	return tempFile.fileName();
}
static QString RunApp(const QString &execPath, const QString &execParam, const QString &execPipeIn="") {
    QString outPipePath = Xapi::TmpFilePath("pipeOut");

    QProcess app;
    app.setStandardInputFile(execPipeIn);
    app.setStandardOutputFile(outPipePath);
    app.setStandardErrorFile(outPipePath);
    app.start(execPath + " " + execParam);
    app.waitForFinished();

    if (QProcess::NormalExit != app.exitStatus())
        qDebug()<<app.error()<<app.errorString()<<app.state();

    QFile locale(outPipePath);
    if (!locale.open(QIODevice::ReadOnly)) {
        qDebug()<<"Open output pipe Fialed!"<<outPipePath;
        return "";
    }
    QTextStream localets(&locale);

    QString outUtf8PipePath = Xapi::TmpFilePath("utf8pipeOut");
    QFile utf8(outUtf8PipePath);
    if (!utf8.open(QIODevice::WriteOnly)) {
        qDebug()<<"Open utf8 output pipe Fialed!"<<outUtf8PipePath;
        return "";
    }
    QTextStream utf8ts(&utf8);
    utf8ts.setCodec("utf8");
    utf8ts<<localets.readAll();
    locale.close();
    utf8.close();

    utf8.open(QIODevice::ReadOnly);
    QString ret = QString(utf8.readAll());
    utf8.close();

    locale.remove();
    utf8.remove();
    return ret;
}
Beispiel #12
0
void executeCommand(const QString &command, const QStringList &arguments, const QString &outputFile,
                    bool verbose)
{
    QTextStream out(stderr);
    if (command.isEmpty()) {
        out << "Error: " << Q_FUNC_INFO << "Got empty command to execute." << endl;
        exit(EXIT_FAILURE);
    }

    const QString fullCommand = command + QLatin1Char(' ') + arguments.join(QLatin1Char(' '));
    if (verbose)
        out << "Executing: " << fullCommand << endl;

    QProcess process;
    if (!outputFile.isEmpty())
        process.setStandardOutputFile(outputFile, QIODevice::Truncate);
    process.start(command, arguments);
    if (!process.waitForStarted()) {
        out << QString::fromLatin1("Error: Process \"%1\" did not start within timeout: %2.")
            .arg(fullCommand, process.errorString())
            << endl;
        exit(EXIT_FAILURE);
    }
    if (!process.waitForFinished()) {
        if (!verbose)
            out << process.readAll() << endl;
        out << QString::fromLatin1("Error: Process \"%1\" did not finish within timeout.")
            .arg(fullCommand)
            << endl;
        exit(EXIT_FAILURE);
    }
    const int exitCode = process.exitCode();
    if (exitCode != 0) {
        out << process.readAllStandardError() << endl;
        out << QString::fromLatin1("Error: Process \"%1\" finished with non zero exit value %2")
            .arg(fullCommand, exitCode) << endl;
        exit(EXIT_FAILURE);
    }
}
void SqliteProcess::start(const QStringList & commands, const QStringList & options)
{
	QProcess p;

	if (!m_stdout.isNull())
		p.setStandardOutputFile(m_stdout);

	QStringList list = QStringList() << options << m_mainDbPath << commands;
	qDebug() << "Running " << SQLITE_BINARY << " with args: " << list;
	qDebug() << QString("     %1 %2").arg(SQLITE_BINARY).arg(list.join(" "));
	p.start(SQLITE_BINARY, list);
	if (!p.waitForStarted() || !p.waitForFinished(-1) || (p.exitStatus() != QProcess::NormalExit))
	{
		m_success = false;
		switch (p.error())
		{
			case (QProcess::FailedToStart) :
				m_error = tr("The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.");
				break;
			case (QProcess::Crashed) :
				m_error = tr("The process crashed some time after starting successfully.");
				break;
			case (QProcess::WriteError) :
				m_error = tr("An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.");
				break;
			case (QProcess::ReadError):
				m_error = tr("An error occurred when attempting to read from the process. For example, the process may not be running.");
				break;
			default:
				m_error = tr("An unknown error occurred.");
		}
	}
	else
		m_success = true;
	m_stderr = QString(p.readAllStandardError());
	m_stdout = QString(p.readAllStandardOutput());
}
Beispiel #14
0
QString getExecutionOutput(const QString& cmd, const QStringList& args)
{
    QProcess p;
    p.setStandardOutputFile(QDir::temp().filePath(QString().sprintf("adb-state-repair-center.%lx", long(QThread::currentThreadId()))));
    p.setStandardErrorFile(QDir::temp().filePath(QString().sprintf("adb-state-repair-center.%lx", long(QThread::currentThreadId()))));
    p.start(cmd, args);
    if (!p.waitForFinished(-1)) {
        p.kill();
        p.waitForFinished();
    } else {
        QFile result(QDir::temp().filePath(QString().sprintf("adb-state-repair-center.%lx", long(QThread::currentThreadId()))));
        result.open(QIODevice::ReadOnly);
        QString ret = result.readAll();
        ret.replace("\r", "");
        while (ret.endsWith("\n")) {
            ret.chop(1);
        }
        result.close();
        result.remove();
        return ret;
    }
    return "";

}
Beispiel #15
0
bool MOomc::startServer()
{
    try
    {
        // evalMutex.unlock();
        QString msg;
        const char *omhome = getenv("OPENMODELICAHOME");
        QString omcPath;
#ifdef WIN32
        if (!omhome)
        {
            InfoSender::instance()->send(Info("OPEN_MODELICA_HOME_NOT_FOUND"));
            return false;
        }
        omcPath = QString( omhome ) + "bin/omc.exe";
#else /* unix */
        omcPath = (omhome ? QString(omhome)+"bin/omc" : QString(CONFIG_DEFAULT_OPENMODELICAHOME) + "/bin/omc");
#endif

        // Check the IOR file created by omc.exe
        QFile objectRefFile;
        QString fileIdentifier;
        fileIdentifier = qApp->sessionId().append(QTime::currentTime().toString(tr("hh:mm:ss:zzz")).remove(":"));

#ifdef WIN32 // Win32
        objectRefFile.setFileName(QString(QDir::tempPath()).append(QDir::separator()).append("openmodelica.objid.").append(this->mName).append(fileIdentifier));
#else // UNIX environment
        char *user = getenv("USER");
        if (!user) { user = "******"; }
        objectRefFile.setFileName(QString(QDir::tempPath()).append(QDir::separator()).append("openmodelica.").append(QString(user)).append(".objid.").append(this->mName).append(fileIdentifier));
#endif

        if (objectRefFile.exists())
            objectRefFile.remove();

        mObjectRefFile = objectRefFile.fileName();


        // Start the omc.exe
        QStringList parameters;
        parameters << QString("+c=").append(mName).append(fileIdentifier) << QString("+d=interactiveCorba") << QString("+corbaObjectReferenceFilePath=").append(QDir::tempPath());
        QProcess *omcProcess = new QProcess();
        QFile omcOutputFile;
#ifdef WIN32 // Win32
        omcOutputFile.setFileName(QString(QDir::tempPath()).append(QDir::separator()).append("openmodelica.omc.output.").append(mName));
#else // UNIX environment
        omcOutputFile.setFileName(QString(QDir::tempPath()).append(QDir::separator()).append("openmodelica.").append(( QString(user))).append(".omc.output.").append(mName));
#endif
        omcProcess->setProcessChannelMode(QProcess::MergedChannels);
        omcProcess->setStandardOutputFile(omcOutputFile.fileName());
        omcProcess->start(omcPath, parameters);
        // wait for the server to start.
        int ticks = 0;
        while (!objectRefFile.exists())
        {
            SleeperThread::msleep(1000);
            ticks++;
            if (ticks > 20)
            {
                msg = "Unable to find " + OMCHelper::applicationName + " server, Object reference file " + mObjectRefFile + " not created.";
                throw std::runtime_error(msg.toStdString());
            }
        }

        // ORB initialization.
        int argc = 2;
        static const char *argv[] = { "-ORBgiopMaxMsgSize", "10485760" };
        CORBA::ORB_var orb = CORBA::ORB_init(argc, (char **)argv);

        objectRefFile.open(QIODevice::ReadOnly);

        char buf[1024];
        objectRefFile.readLine( buf, sizeof(buf) );
        QString uri( (const char*)buf );

        CORBA::Object_var obj = orb->string_to_object(uri.trimmed().toLatin1());

        mOMC = OmcCommunication::_narrow(obj);
        mHasInitialized = true;
    }
    catch(std::exception &e)
    {
        QString msg = e.what();
        InfoSender::instance()->send(Info(msg,ListInfo::ERROR2));
        mHasInitialized = false;
        return false;
    }
    catch (CORBA::Exception&)
    {
        QString msg = "Unable to communicate with OMC";
        InfoSender::instance()->send(Info(msg,ListInfo::ERROR2));
        mHasInitialized = false;
        return false;
    }

    evalCommand("getInstallationDirectoryPath()");
    OMCHelper::OpenModelicaHome = StringHandler::removeFirstLastQuotes(getResult());

    initTempDirectory();

    // set the OpenModelicaLibrary variable.
    evalCommand("getModelicaPath()");
    OMCHelper::OpenModelicaLibrary = StringHandler::removeFirstLastQuotes(getResult());
    return true;
}
bool ExportHelper::XSLTConvertFile(QString inputfilename, QString outputfilename, QString xsltfilename, QString &errmsg)
{
  QString xsltdir;
  QString xsltcmd;

  XSqlQuery q;
  q.prepare("SELECT fetchMetricText(:xsltdir) AS dir,"
            "       fetchMetricText(:xsltcmd) AS cmd;");
#if defined Q_OS_MAC
  q.bindValue(":xsltdir", "XSLTDefaultDirMac");
  q.bindValue(":xsltcmd", "XSLTProcessorMac");
#elif defined Q_OS_WIN
  q.bindValue(":xsltdir", "XSLTDefaultDirWindows");
  q.bindValue(":xsltcmd", "XSLTProcessorWindows");
#elif defined Q_OS_LINUX
  q.bindValue(":xsltdir", "XSLTDefaultDirLinux");
  q.bindValue(":xsltcmd", "XSLTProcessorLinux");
#endif
  q.exec();
  if (q.first())
  {
    xsltdir = q.value("dir").toString();
    xsltcmd = q.value("cmd").toString();
  }
  else if (q.lastError().type() != QSqlError::NoError)
  {
    errmsg = q.lastError().text();
    return false;
  }
  else
  {
    errmsg = tr("Could not find the XSLT directory and command metrics.");
    return false;
  }

  QStringList args = xsltcmd.split(" ", QString::SkipEmptyParts);
  QString command = args[0];
  args.removeFirst();
  args.replaceInStrings("%f", inputfilename);

  if (QFile::exists(xsltfilename))
    args.replaceInStrings("%x", xsltfilename);
  else if (QFile::exists(xsltdir + QDir::separator() + xsltfilename))
    args.replaceInStrings("%x", xsltdir + QDir::separator() + xsltfilename);
  else
  {
    errmsg = tr("Cannot find the XSLT file as either %1 or %2")
                .arg(xsltfilename, xsltdir + QDir::separator() + xsltfilename);
    return false;
  }

  QProcess xslt;
  xslt.setStandardOutputFile(outputfilename);
  xslt.start(command, args);
  QString commandline = command + " " + args.join(" ");
  errmsg = "";
  /* TODO: make the file-processing asynchronous
     this will keep the UI snappy and handle spurious errors
     like the occasional waitForFinished failure if the processing
     runs faster than expected.
   */
  if (! xslt.waitForStarted())
    errmsg = tr("Error starting XSLT Processing: %1\n%2")
                      .arg(commandline)
                      .arg(QString(xslt.readAllStandardError()));
  if (! xslt.waitForFinished())
    errmsg = tr("The XSLT Processor encountered an error: %1\n%2")
                      .arg(commandline)
                      .arg(QString(xslt.readAllStandardError()));
  if (xslt.exitStatus() !=  QProcess::NormalExit)
    errmsg = tr("The XSLT Processor did not exit normally: %1\n%2")
                      .arg(commandline)
                      .arg(QString(xslt.readAllStandardError()));
  if (xslt.exitCode() != 0)
    errmsg = tr("The XSLT Processor returned an error code: %1\nreturned %2\n%3")
                      .arg(commandline)
                      .arg(xslt.exitCode())
                      .arg(QString(xslt.readAllStandardError()));

  return errmsg.isEmpty();
}
Beispiel #17
0
void QProcessProto::setStandardOutputFile(const QString &fileName, QIODevice::OpenMode mode)
{
  QProcess *item = qscriptvalue_cast<QProcess*>(thisObject());
  if (item)
    item->setStandardOutputFile(fileName, mode);
}
Beispiel #18
0
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //-----------------------------------------------------------------------------------------------------------------
    // SET MAJOR VARIABLES HERE
    //-----------------------------------------------------------------------------------------------------------------
    KlaserFunction operation = Feature_From_Vmt;
    bool isGsuData = false;

    QDir dataDir("...");
    QDir trackFileDir("...");
    QDir targetDir("/home/emredog/LIRIS-data/test_features/20141102-rot-int_args16");
    QDir vmtDir("/home/emredog/LIRIS-data/test_VMTs_20140916-ROTATED-INTERPOLATED");
    //------------------------------------------------------------------------------------------------------------------

    if (!targetDir.exists())
        QDir().mkdir(targetDir.absolutePath());
    QDir initialDir = QDir::current();
    QDir::setCurrent("/home/emredog/qt_builds/build-Klaser-Schmid_Hog3D_VMT-Desktop-Release");
    const int threadCount = 2;

    QStringList algoArgs;

    switch(operation)
    {
    case Generate_Vmt:
    {
        // SET KLASER&SCHMID VARIABLES HERE
        algoArgs << "--vmt-only";
        if (isGsuData)
            algoArgs << "--gsu-data";

        cout << "Data directory: " << dataDir.absolutePath().toStdString() << endl;
        QStringList nameFilters;

        //get all image sequences:
        QStringList videos = dataDir.entryList(nameFilters, QDir::AllDirs | QDir::NoDotAndDotDot);
        cout << "Videos fetched: " << videos.count() << endl;

        //get all track files
        nameFilters << "*.track";
        QStringList trackFiles = trackFileDir.entryList(nameFilters, QDir::Files | QDir::NoDotAndDotDot);
        cout << "Track files fetched: " << trackFiles.count() << endl;

        //match track files and videos:
        cout << "Matching track files and videos";

        QHash<QString, QString> videosToTrackFiles;
        foreach (QString video, videos)
        {
            QStringList searchResults = trackFiles.filter(video);
            foreach (QString result, searchResults)
                videosToTrackFiles.insertMulti(video, result);

            cout << ".";
        }

        cout << endl << "Matching completed." << endl;


        QHash<QString, QString>::const_iterator it = videosToTrackFiles.constBegin();


        QList<VideoTrackPair> pairs;

        while (it != videosToTrackFiles.constEnd())
        {
            VideoTrackPair pair;
            pair.first = it.key();
            pair.second = it.value();
            pairs.append(pair);
            ++it;
        }

        int length = pairs.length()/threadCount;

        struct timespec ts = { 5000 / 1000, (5000 % 1000) * 1000 * 1000 };
        nanosleep(&ts, NULL);

        for (int i=0; i<threadCount; i++)
        {
            int startPos = i * length;

            if (i == threadCount - 1) //if it's the last thread
                length = -1; //just take all of the remaining files

            KlaserSchmidThread* proc = new KlaserSchmidThread(pairs.mid(startPos, length), algoArgs, dataDir, trackFileDir, targetDir, i+1);
            proc->start();
        }
        break;

    }
    case Feature_From_Vmt: //we have VMT files already
    {
        // SET KLASER&SCHMID VARIABLES HERE
        algoArgs << "-P" << "icosahedron" //"dodecahedron" icosahedron
                    //<< "--loose-track"
                 << "--xy-stride" <<  "16"  //"16" "32"
                 << "--t-stride" << "16"    //"16" "32"
                 << "--xy-ncells" << "2"
                 << "--t-ncells" << "2"
                 << "--npix" << "2";

        if (isGsuData)
            algoArgs << "--gsu-data";

        cout << "VMT directory: " << vmtDir.absolutePath().toStdString() << endl;
        QStringList nameFilters;
        //get all VMT files
        nameFilters << "*.pcd";
        QStringList vmtFiles = vmtDir.entryList(nameFilters, QDir::Files | QDir::NoDotAndDotDot);
        cout << "VMT files fetched: " << vmtFiles.count() << endl;

        int length = vmtFiles.length()/threadCount;

        struct timespec ts = { 5000 / 1000, (5000 % 1000) * 1000 * 1000 };
        nanosleep(&ts, NULL);

        for (int i=0; i<threadCount; i++)
        {
            int startPos = i * length;

            if (i == threadCount - 1) //if it's the last thread
                length = -1; //just take all of the remaining files

            KlaserSchmidThreadFromVMT* proc = new KlaserSchmidThreadFromVMT(vmtFiles.mid(startPos, length), vmtDir, algoArgs, targetDir, i+1);
            proc->start();
        }
        break;
    }
    case Rotation_Angle_Only:
    {
        // SET KLASER&SCHMID VARIABLES HERE
        algoArgs << "--calculate-rotation";
        if (isGsuData)
            algoArgs << "--gsu-data";

        QString program = "./Klaser-Schmid_Hog3D_VMT";

        cout << "Data directory: " << dataDir.absolutePath().toStdString() << endl;
        QStringList nameFilters;

        //get all image sequences:
        QStringList videos = dataDir.entryList(nameFilters, QDir::AllDirs | QDir::NoDotAndDotDot);
        cout << "Videos fetched: " << videos.count() << endl;

        //get all track files
        nameFilters << "*.track";
        QStringList trackFiles = trackFileDir.entryList(nameFilters, QDir::Files | QDir::NoDotAndDotDot);
        cout << "Track files fetched: " << trackFiles.count() << endl;

        //match track files and videos:
        cout << "Matching track files and videos";

        QHash<QString, QString> videosToTrackFiles;
        foreach (QString video, videos)
        {
            QStringList searchResults = trackFiles.filter(video);
            foreach (QString result, searchResults)
                videosToTrackFiles.insertMulti(video, result);

            cout << ".";
        }

        cout << endl << "Matching completed." << endl;


        QHash<QString, QString>::const_iterator it = videosToTrackFiles.constBegin();

        QStringList inputArgs;
        QFileInfo* trackFileInfo;
        int counter = 1;

        QList<VideoTrackPair> pairs;

        while (it != videosToTrackFiles.constEnd())
        {
            VideoTrackPair pair;
            pair.first = it.key();
            pair.second = it.value();
            pairs.append(pair);
            ++it;
        }

        //we don't need multithread functionality for this operation

        QProcess* process;
        QString outputFilePath = initialDir.absoluteFilePath("rotationAngles.txt");

        foreach (VideoTrackPair pair, pairs)
        {
            inputArgs << "--video-file" << dataDir.absoluteFilePath(pair.first)
                      << "-t" << trackFileDir.absoluteFilePath(pair.second);

            //create a new process
            process = new QProcess();
            //set output file name
            trackFileInfo = new QFileInfo(pair.second);
            process->setStandardOutputFile(outputFilePath, QIODevice::Append);

            //run the program
            process->start(program, inputArgs + algoArgs);
            cout << "All parameters:" << endl << "\t"
                 << inputArgs.join(" ").toStdString() << " " << algoArgs.join(" ").toStdString() << endl << endl;

            //check if it started normally
            if (!process->waitForStarted(3000))
            {
                cerr << "Could not start process with following parameters:" << endl
                     << "input: " << inputArgs.join(" ").toStdString() << endl
                     << "parameters: " << algoArgs.join(" ").toStdString() << endl;

                continue;
            }

            //wait 10 minutes for it to finish
            if (!process->waitForFinished(600000)) //wait for 10 minutes
            {
                cerr << "Could not complete process within 10 minutes, with following parameters:" << endl
                     << "input: " << inputArgs.join(" ").toStdString() << endl
                     << "parameters: " << algoArgs.join(" ").toStdString() << endl;

                continue;
            }

            counter++;

            //clean-up
            delete process;
            delete trackFileInfo;
            inputArgs.clear();
        }
bool CommandLineExporter::executeCommand
(
    const QString& command,
    const QString& inputFilePath,
    const QString& textInput,
    const QString& outputFilePath,
    QString& stdoutOutput,
    QString& stderrOutput
)
{
    QProcess process;
    process.setReadChannel(QProcess::StandardOutput);

    QString expandedCommand = command + QString(" ");

    if (!outputFilePath.isNull() && !outputFilePath.isEmpty())
    {
        // Redirect stdout to the output file path if the path variable wasn't
        // set in the command string.
        //
        if (!expandedCommand.contains(OUTPUT_FILE_PATH_VAR))
        {
            process.setStandardOutputFile(outputFilePath);
        }
        else
        {
            // Surround file path with quotes in case there are spaces in the
            // path.
            //
            QString outputFilePathWithQuotes = QString('\"') +
                outputFilePath + '\"';
            expandedCommand.replace(OUTPUT_FILE_PATH_VAR, outputFilePathWithQuotes);
        }
    }

    if
    (
        this->getSmartTypographyEnabled() &&
        !this->smartTypographyOnArgument.isNull()
    )
    {
        expandedCommand.replace
        (
            SMART_TYPOGRAPHY_ARG,
            smartTypographyOnArgument
        );
    }
    else if
    (
        !this->getSmartTypographyEnabled() &&
        !this->smartTypographyOffArgument.isNull()
    )
    {
        expandedCommand.replace
        (
            SMART_TYPOGRAPHY_ARG,
            smartTypographyOffArgument
        );
    }

    if (!inputFilePath.isNull() && !inputFilePath.isEmpty())
    {
        process.setWorkingDirectory(QFileInfo(inputFilePath).dir().path());
    }

    process.start(expandedCommand);

    if (!process.waitForStarted())
    {
        return false;
    }
    else
    {
        if (!textInput.isNull() && !textInput.isEmpty())
        {
            process.write(textInput.toUtf8());
            process.closeWriteChannel();
        }

        if (!process.waitForFinished())
        {
            return false;
        }
        else
        {
            stdoutOutput = QString::fromUtf8(process.readAllStandardOutput().data());
            stderrOutput = QString::fromUtf8(process.readAllStandardError().data());
        }
    }

    return true;
}
Beispiel #20
0
    ExitCodes main_(int , const char**) override
    {

      // path to the log file
      String logfile(getStringOption_("log"));
      String pepnovo_executable(getStringOption_("pepnovo_executable"));

      PeakMap exp;

      String inputfile_name = getStringOption_("in");
      writeDebug_(String("Input file: ") + inputfile_name, 1);

      String outputfile_name = getStringOption_("out");
      writeDebug_(String("Output file: ") + outputfile_name, 1);

      String model_directory = getStringOption_("model_directory");
      writeDebug_(String("model directory: ") + model_directory, 1);

      String model_name = getStringOption_("model");
      writeDebug_(String("model directory: ") + model_name, 1);

      double fragment_tolerance = getDoubleOption_("fragment_tolerance");
      if (fragment_tolerance!=-1.0 && (fragment_tolerance<0 || fragment_tolerance>0.75))
      {
        writeLog_("Invalid fragment tolerance");
        printUsage_();
        return ILLEGAL_PARAMETERS;
      }

      double pm_tolerance = getDoubleOption_("pm_tolerance");
      if (pm_tolerance!=-1.0 && (pm_tolerance<0.0 || pm_tolerance>5.0))
      {
        writeLog_("Invalid fragment tolerance");
        printUsage_();
        return ILLEGAL_PARAMETERS;
      }

      Int tag_length = getIntOption_("tag_length");
      if ( tag_length!=-1 && (tag_length<3 || tag_length>6))
      {
        writeLog_("Invalid fragment tolerance");
        printUsage_();
        return ILLEGAL_PARAMETERS;
      }
      String digest = getStringOption_("digest");
      Size num_solutions=getIntOption_("num_solutions");

      //-------------------------------------------------------------
      // reading input
      //-------------------------------------------------------------

      // only load msLevel 2
      MzMLFile mzml_infile;
      mzml_infile.getOptions().addMSLevel(2);
      mzml_infile.setLogType(log_type_);
      mzml_infile.load(inputfile_name, exp);

      // we map the native id to the MZ and RT to be able to
      // map the IDs back to the spectra (RT, and MZ Meta Information)
      PepNovoOutfile::IndexPosMappingType index_to_precursor;
      for (Size i = 0; i < exp.size(); ++i)
      {
        index_to_precursor[i]= make_pair(exp[i].getRT(), exp[i].getPrecursors()[0].getPosition()[0]); //set entry <RT, MZ>
      }

      logfile = getStringOption_("log");
      
      QDir qdir_models_source(model_directory.c_str());
      if (!qdir_models_source.exists())
      {
        writeLog_("The model directory does not exist");
        return INPUT_FILE_NOT_FOUND;
      }
      
      // create temp directory
      QDir qdir_temp(File::getTempDirectory().toQString());
      String temp_data_directory = File::getUniqueName();
      qdir_temp.mkdir(temp_data_directory.toQString());
      qdir_temp.cd(temp_data_directory.toQString());
      temp_data_directory  = File::getTempDirectory() + "/" + temp_data_directory; // delete later

      String mgf_file = temp_data_directory + "/" + File::getUniqueName() + ".mgf"; // the mzXML parser of PepNovo is somewhat broken.. don't use mzXML
      MascotGenericFile().store(mgf_file, exp);

      bool error(false);

      try
      {
        //temporary File to store PepNovo output
        String temp_pepnovo_outfile = qdir_temp.absoluteFilePath("tmp_pepnovo_out.txt");
        String tmp_models_dir = qdir_temp.absoluteFilePath("Models");

        std::map<String, String>mods_and_keys; //, key_to_id;

        if (qdir_temp.cd("Models"))
        {
          writeLog_("The temporary directory already contains \"Model\" Folder. Please delete it and re-run. Aborting!");
          return CANNOT_WRITE_OUTPUT_FILE;
        }
        else
        {
          qdir_temp.mkdir("Models");
          qdir_temp.cd("Models");
        }

        //copy the Models folder of OpenMS into the temp_data_directory
        QStringList pepnovo_files = qdir_models_source.entryList(QDir::Dirs | QDir::Files|QDir::NoDotAndDotDot);
        if (pepnovo_files.empty())
        {
          writeLog_("The \"Model\" directory does not contain model files. Aborting!");
          return INPUT_FILE_NOT_FOUND;
        }

        for (QStringList::ConstIterator file_it=pepnovo_files.begin(); file_it!=pepnovo_files.end(); ++file_it)
        {
          if (qdir_models_source.cd(*file_it))
          {
            qdir_temp.mkdir(*file_it);
            qdir_temp.cd(*file_it);
            QStringList subdir_files = qdir_models_source.entryList(QDir::Dirs | QDir::Files|QDir::NoDotAndDotDot);
            for (QStringList::ConstIterator subdir_file_it=subdir_files.begin(); subdir_file_it!=subdir_files.end(); ++subdir_file_it)
            {
              QFile::copy(qdir_models_source.filePath(*subdir_file_it), qdir_temp.filePath(*subdir_file_it));
            }
            qdir_temp.cdUp();
            qdir_models_source.cdUp();
          }
          else
          {
            QFile::copy(qdir_models_source.filePath(*file_it), qdir_temp.filePath(*file_it));
          }
        }

        //generate PTM File and store in temp directory
        PepNovoInfile p_novo_infile;
        String ptm_command;
        if (!getStringList_("fixed_modifications").empty() || !getStringList_("variable_modifications").empty())
        {
          p_novo_infile.setModifications(getStringList_("fixed_modifications"), getStringList_("variable_modifications"));
          p_novo_infile.store(qdir_temp.filePath("PepNovo_PTMs.txt"));
          pepnovo_files.append("PepNovo_PTMs.txt");
          p_novo_infile.getModifications(mods_and_keys);

          for (std::map<String, String>::const_iterator key_it=mods_and_keys.begin(); key_it!=mods_and_keys.end();++key_it)
          {
            if (ptm_command!="")
            {
              ptm_command+=":";
            }
            ptm_command+= key_it->first;
            //key_to_id[key_it->second]=key_it->first;
          }
        }

        //-------------------------------------------------------------
        // (3) running program according to parameters
        //-------------------------------------------------------------
        QStringList arguments;

        arguments << "-file" << mgf_file.toQString();
        arguments << "-model" << model_name.toQString();
        if (pm_tolerance != -1 ) arguments << "-pm_tolerance"<<String(pm_tolerance).toQString();
        if (fragment_tolerance != -1 ) arguments << "-fragment_tolerance" <<String(fragment_tolerance).toQString();
        if (!ptm_command.empty()) arguments <<"-PTMs" <<ptm_command.toQString();
        if (getFlag_("correct_pm")) arguments << "-correct_pm";
        if (getFlag_("use_spectrum_charge")) arguments << "-use_spectrum_charge";
        if (getFlag_("use_spectrum_mz")) arguments << "-use_spectrum_mz";
        if (getFlag_("no_quality_filter")) arguments << "-no_quality_filter";
        arguments << "-digest" << digest.toQString();
        arguments << "-num_solutions" << String(num_solutions).toQString();
        if (tag_length!=-1) arguments<<"-tag_length" << String(tag_length).toQString();
        arguments<<"-model_dir" << tmp_models_dir.toQString();
        //arguments<<">" << temp_pepnovo_outfile.toQString();

        writeDebug_("Use this line to call PepNovo: ", 1);
        writeDebug_(pepnovo_executable + " " + String(arguments.join(" ")), 1);
        QProcess process;
        process.setStandardOutputFile(temp_pepnovo_outfile.toQString());
        process.setStandardErrorFile(temp_pepnovo_outfile.toQString());
        process.start(pepnovo_executable.toQString(), arguments); // does automatic escaping etc...
        if (process.waitForFinished(-1))
        {
          //if PepNovo finished successfully use PepNovoOutfile to parse the results and generate idXML
          std::vector< PeptideIdentification > peptide_identifications;
          ProteinIdentification protein_identification;
          StringList ms_runs;
          exp.getPrimaryMSRunPath(ms_runs);
          protein_identification.setPrimaryMSRunPath(ms_runs);

          PepNovoOutfile p_novo_outfile;

          //resolve PTMs (match them back to the OpenMs Identifier String)
          std::vector<ProteinIdentification>prot_ids;
          p_novo_outfile.load(temp_pepnovo_outfile, peptide_identifications, protein_identification, -1e5, index_to_precursor, mods_and_keys);
          prot_ids.push_back(protein_identification);
          IdXMLFile().store(outputfile_name, prot_ids, peptide_identifications);
        }

        if (process.exitStatus() != 0)  error = true;
       
      }
      catch(Exception::BaseException &exc)
      {
        writeLog_(exc.what());
        LOG_ERROR << "Error occurred: " << exc.what() << std::endl;
        error = true;
      }
      
      if (!error)
      {
        File::removeDirRecursively(temp_data_directory);
        return EXECUTION_OK;
      }
      else
      {
        writeLog_("PepNovo problem. Aborting! (Details can be seen in outfiles: '" + temp_data_directory + "')");
        return EXTERNAL_PROGRAM_ERROR;
      }

    }
void QtDcmConvert::convert()
{
    if (QtDcmPreferences::instance()->useDcm2nii())
    {
        QString program = QtDcmPreferences::instance()->getDcm2niiPath();
        QStringList arguments;
        arguments << "-x" << "N";
        arguments << "-r" << "N";
        arguments << "-g" << "N";
        arguments << "-o" << d->outputDirectory << d->inputDirectory;
        
        QProcess * process = new QProcess(this);
        process->setStandardOutputFile(d->tempDirectory + QDir::separator() + "logs" + QDir::separator() + d->serieUID + ".txt");
        process->start(program, arguments);
        process->waitForFinished();

        delete process;
    }
    else
    {
        typedef signed short                                PixelType;
        const unsigned int Dimension = 3;
        typedef itk::Image< PixelType, Dimension >          ImageType;
        typedef itk::ImageSeriesReader< ImageType >         ReaderType;
        typedef itk::ImageFileWriter<ImageType>             WriterType;
        typedef itk::GDCMImageIO                            ImageIOType;
        typedef itk::GDCMSeriesFileNames                    NamesGeneratorType;
        typedef std::vector< std::string >                  FileNamesContainer;
        typedef std::vector< std::string >                  SeriesIdContainer;

//     ImageType::Pointer image = 0;

        ReaderType::Pointer reader = ReaderType::New();
        ImageIOType::Pointer dicomIO = ImageIOType::New();

        NamesGeneratorType::Pointer inputNames = NamesGeneratorType::New();
        inputNames->SetUseSeriesDetails ( true );
        inputNames->AddSeriesRestriction ( "0008|0021" );
        inputNames->AddSeriesRestriction ( "0020,0037" );
        inputNames->LoadSequencesOn();
        inputNames->LoadPrivateTagsOn();
        inputNames->SetInputDirectory ( d->inputDirectory.toStdString() );
        try
        {
            const SeriesIdContainer & seriesUID = inputNames->GetSeriesUIDs();
            std::string seriesIdentifier = seriesUID.begin()->c_str();
            FileNamesContainer filenames = inputNames->GetFileNames ( seriesIdentifier );

            dicomIO->SetFileName ( filenames.begin()->c_str() );
            try
            {
                dicomIO->ReadImageInformation();
            }
            catch ( itk::ExceptionObject &e )
            {
                qDebug() << e.GetDescription();
                return;
            }

            reader->UseStreamingOn();
            reader->SetFileNames ( filenames );
            reader->SetImageIO ( dicomIO );

            try
            {
                reader->Update();
            }
            catch ( itk::ExceptionObject &excp )
            {
                std::cerr << excp << std::endl;
                return;
            }

//         IteratorType itOut;
//
//         image = reader->GetOutput();
//
//         RegionType region;
//         region.SetSize ( 0, image->GetLargestPossibleRegion().GetSize() [0] );
//         region.SetSize ( 1, image->GetLargestPossibleRegion().GetSize() [1] );
//         region.SetSize ( 2, image->GetLargestPossibleRegion().GetSize() [2] );
//         image->SetRegions ( region );
//         image->Allocate();
//         SpacingType spacing;
//         spacing[0] = image->GetSpacing() [0];
//         spacing[1] = image->GetSpacing() [1];
//         spacing[2] = image->GetSpacing() [2];
//         spacing[3] = 1;
//         image->SetSpacing ( spacing );
//         PointType origin;
//         origin[0] = image->GetOrigin() [0];
//         origin[1] = image->GetOrigin() [1];
//         origin[2] = image->GetOrigin() [2];
//         origin[3] = 0;
//         image->SetOrigin ( origin );
//         DirectionType direction;
//         for ( unsigned int i=0; i<4; i++ )
//             for ( unsigned int j=0; j<4; j++ )
//             {
//                 if ( ( i < 3 ) && ( j < 3 ) )
//                     direction[i][j] = image->GetDirection() [i][j];
//                 else
//                     direction[i][j] = ( i == j ) ? 1 : 0;
//             }
//         image->SetDirection ( direction );
//         itOut = IteratorType ( image, region );
//
//         image->SetMetaDataDictionary ( dicomIO->GetMetaDataDictionary() );
//
//
//         itk::ImageRegionIterator<ImageType> itIn ( image, image->GetLargestPossibleRegion() );
//         while ( !itIn.IsAtEnd() )
//         {
//             itOut.Set ( itIn.Get() );
//             ++itIn;
//             ++itOut;
//         }


            WriterType::Pointer writer = WriterType::New();

            QString completeFilename = d->outputDirectory + QDir::separator() + d->outputFilename;

            writer->SetFileName ( completeFilename.toStdString() );
            writer->SetInput ( reader->GetOutput() );
//         writer->SetInput ( image );

            try
            {
                writer->Update();
            }
            catch ( itk::ExceptionObject &ex )
            {
                std::cout << ex << std::endl;
                return;
            }
        }
        catch ( itk::ExceptionObject &ex )
        {
            std::cout << ex << std::endl;
            return;
        }
    }
}
void AssignmentClientMonitor::spawnChildClient() {
    QProcess* assignmentClient = new QProcess(this);

    // unparse the parts of the command-line that the child cares about
    QStringList _childArguments;
    if (_assignmentPool != "") {
        _childArguments.append("--" + ASSIGNMENT_POOL_OPTION);
        _childArguments.append(_assignmentPool);
    }
    if (!_walletUUID.isNull()) {
        _childArguments.append("--" + ASSIGNMENT_WALLET_DESTINATION_ID_OPTION);
        _childArguments.append(_walletUUID.toString());
    }
    if (_assignmentServerHostname != "") {
        _childArguments.append("--" + CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION);
        _childArguments.append(_assignmentServerHostname);
    }
    if (_assignmentServerPort != DEFAULT_DOMAIN_SERVER_PORT) {
        _childArguments.append("--" + CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION);
        _childArguments.append(QString::number(_assignmentServerPort));
    }
    if (_requestAssignmentType != Assignment::AllTypes) {
        _childArguments.append("--" + ASSIGNMENT_TYPE_OVERRIDE_OPTION);
        _childArguments.append(QString::number(_requestAssignmentType));
    }

    // tell children which assignment monitor port to use
    // for now they simply talk to us on localhost
    _childArguments.append("--" + ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION);
    _childArguments.append(QString::number(DependencyManager::get<NodeList>()->getLocalSockAddr().getPort()));

    _childArguments.append("--" + PARENT_PID_OPTION);
    _childArguments.append(QString::number(QCoreApplication::applicationPid()));

    QString nowString, stdoutFilenameTemp, stderrFilenameTemp, stdoutPathTemp, stderrPathTemp;


    if (_wantsChildFileLogging) {
        // Setup log files
        const QString DATETIME_FORMAT = "yyyyMMdd.hh.mm.ss.zzz";

        if (!_logDirectory.exists()) {
            qDebug() << "Log directory (" << _logDirectory.absolutePath() << ") does not exist, creating.";
            _logDirectory.mkpath(_logDirectory.absolutePath());
        }

        nowString = QDateTime::currentDateTime().toString(DATETIME_FORMAT);
        stdoutFilenameTemp = QString("ac-%1-stdout.txt").arg(nowString);
        stderrFilenameTemp = QString("ac-%1-stderr.txt").arg(nowString);
        stdoutPathTemp = _logDirectory.absoluteFilePath(stdoutFilenameTemp);
        stderrPathTemp = _logDirectory.absoluteFilePath(stderrFilenameTemp);

        // reset our output and error files
        assignmentClient->setStandardOutputFile(stdoutPathTemp);
        assignmentClient->setStandardErrorFile(stderrPathTemp);
    }

    // make sure that the output from the child process appears in our output
    assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels);
    assignmentClient->start(QCoreApplication::applicationFilePath(), _childArguments);

#ifdef Q_OS_WIN
    addProcessToGroup(PROCESS_GROUP, assignmentClient->processId());
#endif

    QString stdoutPath, stderrPath;

    if (_wantsChildFileLogging) {

        // Update log path to use PID in filename
        auto stdoutFilename = QString("ac-%1_%2-stdout.txt").arg(nowString).arg(assignmentClient->processId());
        auto stderrFilename = QString("ac-%1_%2-stderr.txt").arg(nowString).arg(assignmentClient->processId());
        stdoutPath = _logDirectory.absoluteFilePath(stdoutFilename);
        stderrPath = _logDirectory.absoluteFilePath(stderrFilename);

        qDebug() << "Renaming " << stdoutPathTemp << " to " << stdoutPath;
        if (!_logDirectory.rename(stdoutFilenameTemp, stdoutFilename)) {
            qDebug() << "Failed to rename " << stdoutFilenameTemp;
            stdoutPath = stdoutPathTemp;
            stdoutFilename = stdoutFilenameTemp;
        }

        qDebug() << "Renaming " << stderrPathTemp << " to " << stderrPath;
        if (!QFile::rename(stderrPathTemp, stderrPath)) {
            qDebug() << "Failed to rename " << stderrFilenameTemp;
            stderrPath = stderrPathTemp;
            stderrFilename = stderrFilenameTemp;
        }
        
        qDebug() << "Child stdout being written to: " << stdoutFilename;
        qDebug() << "Child stderr being written to: " << stderrFilename;
    }

    if (assignmentClient->processId() > 0) {
        auto pid = assignmentClient->processId();
        // make sure we hear that this process has finished when it does
        connect(assignmentClient, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
                this, [this, pid](int exitCode, QProcess::ExitStatus exitStatus) {
                    childProcessFinished(pid, exitCode, exitStatus);
            });

        qDebug() << "Spawned a child client with PID" << assignmentClient->processId();

        _childProcesses.insert(assignmentClient->processId(), { assignmentClient, stdoutPath, stderrPath });
    }
}