void ApplyMeasureNowDialog::runMeasure() { runmanager::ConfigOptions co(true); if (co.getTools().getAllByName("ruby").tools().size() == 0) { QMessageBox::information(this, "Missing Ruby", "Ruby could not be located.\nOpenStudio will scan for tools.", QMessageBox::Ok); co.findTools(true); openstudio::runmanager::RunManager rm; rm.setConfigOptions(co); rm.showConfigGui(); rm.getConfigOptions().saveQSettings(); emit toolsUpdated(); if (co.getTools().getAllByName("ruby").tools().size() == 0) { QMessageBox::information(this, "Missing Ruby", "Ruby was not located by tool search.\nPlease ensure Ruby correctly installed.\nSimulation aborted.", QMessageBox::Ok); m_mainPaneStackedWidget->setCurrentIndex(m_inputPageIdx); m_timer->stop(); this->okButton()->hide(); this->backButton()->hide(); return; } } m_mainPaneStackedWidget->setCurrentIndex(m_runningPageIdx); m_timer->start(50); this->okButton()->hide(); this->backButton()->hide(); OS_ASSERT(m_model); openstudio::OSAppBase * app = OSAppBase::instance(); m_workingDir = openstudio::toPath(app->currentDocument()->modelTempDir()) / openstudio::toPath("ApplyMeasureNow"); openstudio::path modelPath = m_workingDir / openstudio::toPath("modelClone.osm"); openstudio::path epwPath; // DLM: todo look at how this is done in the run tab removeWorkingDir(); // save cloned model to temp directory m_model->save(modelPath,true); // remove? this is shown only in debug (EW) QString path("Measure Output Location: "); path.append(toQString(m_workingDir)); m_jobPath->setText(path); analysis::RubyMeasure rubyMeasure = m_currentMeasureItem->measure(); // DLM: should be able to assert this bool hasIncompleteArguments = m_currentMeasureItem->hasIncompleteArguments(); OS_ASSERT(!hasIncompleteArguments); runmanager::RubyJobBuilder rjb(*m_bclMeasure, rubyMeasure.arguments()); openstudio::path p = getOpenStudioRubyIncludePath(); QString arg = "-I"; arg.append(toQString(p)); rjb.addToolArgument(arg.toStdString()); openstudio::runmanager::Workflow wf; rjb.addToWorkflow(wf); wf.add(co.getTools()); wf.setInputFiles(modelPath, openstudio::path()); m_job = wf.create(m_workingDir, modelPath); // DLM: you could make rm a class member then you would not have to call waitForFinished here runmanager::RunManager rm; bool queued = rm.enqueue(*m_job, true); OS_ASSERT(queued); std::vector<runmanager::Job> jobs = rm.getJobs(); OS_ASSERT(jobs.size() == 1); rm.waitForFinished (); QTimer::singleShot(0, this, SLOT(displayResults())); }
void RunManagerWatcher::jobFinishedExtInternal(const openstudio::UUID &t_id, const openstudio::runmanager::JobErrors& t_errors, const openstudio::DateTime &t_lastRun, const std::vector<openstudio::runmanager::FileInfo> &t_outputfiles) { jobFinishedExt(t_id, t_errors, t_lastRun, t_outputfiles); try { Job job = m_runManager.getJob(t_id); boost::optional<openstudio::runmanager::Job> parent = job; while (parent->parent()) { parent = parent->parent(); } TreeStatusEnum status = parent->treeStatus(); if (status == TreeStatusEnum::Finished || status == TreeStatusEnum::Failed || status == TreeStatusEnum::Canceled) { LOG(Debug, "Calling treeFinished"); treeFinished(*parent); } if (job.hasMergedJobs()) { std::vector<MergedJobResults> mergedJobs = job.mergedJobResults(); openstudio::runmanager::JobType jobtype = job.jobType(); openstudio::DateTime lastRun = t_lastRun; openstudio::UUID mergedIntoJobId = t_id; JobParams inputParams = job.params(); std::vector<JobParams> params; if (jobtype == JobType::Ruby) { RubyJobBuilder rjb(inputParams); std::vector<RubyJobBuilder> mergedRubyJobs = rjb.mergedJobs(); OS_ASSERT(mergedRubyJobs.size() + 1 == mergedJobs.size()); params.push_back(inputParams); for (std::vector<RubyJobBuilder>::const_iterator itr = mergedRubyJobs.begin(); itr != mergedRubyJobs.end(); ++itr) { params.push_back(itr->toParams()); } } OS_ASSERT(params.empty() || params.size() == mergedJobs.size()); for (size_t pos = 0; pos < mergedJobs.size(); ++pos) { openstudio::UUID jobId = mergedJobs[pos].uuid; JobErrors errors = mergedJobs[pos].errors; Files outputFiles = mergedJobs[pos].outputFiles; bool isMergedJob = true; jobFinishedDetails(jobId, jobtype, lastRun, errors, outputFiles, params.empty()?inputParams:params.at(pos), isMergedJob, mergedIntoJobId); } } else { // no merged jobs jobFinishedDetails(t_id, job.jobType(), t_lastRun, t_errors, Files(job.outputFiles()), JobParams(job.params()), false, openstudio::UUID()); } } catch (const std::runtime_error &e) { LOG(Error, "Error extracting job finished details " << e.what()); } }
std::string getReportRequestMeasureArgument(const std::vector<runmanager::WorkItem>& workItems) { std::vector<openstudio::runmanager::RubyJobBuilder> rubyJobBuilders; // loop over all reporting measures and gather ruby jobs bool pastEnergyPlus = false; for (const auto& workItem : workItems) { if (workItem.type == openstudio::runmanager::JobType::EnergyPlus){ pastEnergyPlus = true; } if (pastEnergyPlus && workItem.type == openstudio::runmanager::JobType::UserScript){ openstudio::runmanager::RubyJobBuilder rjb(workItem); const std::vector<openstudio::runmanager::RubyJobBuilder>& mergedJobs = rjb.mergedJobs(); if (mergedJobs.empty()){ rubyJobBuilders.push_back(rjb); } else { rubyJobBuilders.insert(rubyJobBuilders.end(), mergedJobs.begin(), mergedJobs.end());; } } } QVariantList measureList; // loop over ruby jobs and gather information for report request measure for (const auto& rjb : rubyJobBuilders){ QVariantMap measureHash; // DLM: this is just UserScriptAdapter to get the actual script you need to use requiredFiles //measureHash["script"] = toQString(rjb.script()); //QVariantList requiredFileList; for (const auto& requiredFile : rjb.requiredFiles()){ //QVariantMap requiredFileMap; // second is local file path, first is absolute system path //requiredFileMap[toQString(requiredFile.second)] = toQString(requiredFile.first); //requiredFileList << requiredFileMap; // DLM: most measures have the measure mapped to both required file user_script.rb and measure.rb // if have both, use measure.rb if (istringEqual(toString(requiredFile.second), "user_script.rb")){ if (!measureHash.contains("measure")){ measureHash["measure"] = toQString(requiredFile.first); } } if (istringEqual(toString(requiredFile.second), "measure.rb")){ measureHash["measure"] = toQString(requiredFile.first); } } // DLM: I should probably be attaching these required files to this job in some way? // DLM: will this work for now given that we are removing the requirement for remote runs? //measureHash["required_files"] = requiredFileList; // The measure arguments will be script parameters in pairs of "--argumentName=name","argumentValue=value" QVariantMap argumentHash; QString lastArgumentName; QRegularExpression argumentNameExp("--argumentName=(.*)"); QRegularExpression argumentValueExp("--argumentValue=(.*)"); for (const auto& parameter : rjb.getScriptParameters()){ QString temp = toQString(parameter); QRegularExpressionMatch match = argumentNameExp.match(temp); if (match.hasMatch()){ lastArgumentName = match.captured(1); } else { match = argumentValueExp.match(temp); if (match.hasMatch()){ argumentHash[lastArgumentName] = match.captured(1); } else { LOG_FREE(Error, "openstudio.runmanager.getReportRequestMeasureArgument", "Unexpected parameter '" << parameter << "'"); } } }; measureHash["arguments"] = argumentHash; // DLM: args were not populated here //QVariantList argList; //auto args = openstudio::runmanager::RubyJobBuilder::toOSArguments(itr->params); //for (const auto& arg : args){ // argList << ruleset::detail::toVariant(arg); //} //measureHash["arguments"] = argList; if (measureHash.contains("measure")){ measureList << measureHash; } else{ LOG_FREE(Debug, "openstudio.runmanager.getReportRequestMeasureArgument", "RubyJobBuilder does not include measure") } } QJsonDocument document = QJsonDocument::fromVariant(measureList); QString jsonValue = document.toJson(QJsonDocument::Compact); //QString jsonValue = document.toJson(QJsonDocument::Indented); return toString(jsonValue); }