Commit 26a43db9 authored by Aaron Bray's avatar Aaron Bray
Browse files

Minor bugs, new units, and expose scenario runner for all to use

parent e43d1bec
......@@ -47,7 +47,7 @@ void SEPatientConfiguration::Clear()
bool SEPatientConfiguration::IsValid() const
{
if(!HasPatientFile() && HasPatient())
if(!HasPatientFile() && !HasPatient())
return false;
return true;
}
......
......@@ -57,9 +57,7 @@ public:
virtual void ToString(std::ostream &str) const;
protected:
std::stringstream m_ss;
eSwitch m_State;
eSwitch m_State;
SEScalarVolumePerTime* m_Flow;
SEScalarPressure* m_Pressure;
......
......@@ -10,6 +10,7 @@ const LengthPerTimeUnit LengthPerTimeUnit::m_Per_min("m/min");
const LengthPerTimeUnit LengthPerTimeUnit::cm_Per_min("cm/min");
const LengthPerTimeUnit LengthPerTimeUnit::ft_Per_s("ft/s");
const LengthPerTimeUnit LengthPerTimeUnit::ft_Per_min("ft/min");
const LengthPerTimeUnit LengthPerTimeUnit::km_Per_hr("km/hr");
bool LengthPerTimeUnit::IsValidUnit(const std::string& unit)
{
......@@ -25,6 +26,8 @@ bool LengthPerTimeUnit::IsValidUnit(const std::string& unit)
return true;
if (ft_Per_min.GetString().compare(unit) == 0)
return true;
if (km_Per_hr.GetString().compare(unit) == 0)
return true;
return false;
}
......@@ -42,6 +45,8 @@ const LengthPerTimeUnit& LengthPerTimeUnit::GetCompoundUnit(const std::string& u
return ft_Per_s;
if (ft_Per_min.GetString().compare(unit) == 0)
return ft_Per_min;
if (km_Per_hr.GetString().compare(unit) == 0)
return km_Per_hr;
std::stringstream err;
err << unit << " is not a valid LengthPerTime unit";
throw CommonDataModelException(err.str());
......
......@@ -19,6 +19,7 @@ public:
static const LengthPerTimeUnit cm_Per_min;
static const LengthPerTimeUnit ft_Per_s;
static const LengthPerTimeUnit ft_Per_min;
static const LengthPerTimeUnit km_Per_hr;
};
class CDM_DECL SEScalarLengthPerTime : public SEScalarQuantity<LengthPerTimeUnit>
......
......@@ -9,6 +9,7 @@ const PressureUnit PressureUnit::mmHg("mmHg");
const PressureUnit PressureUnit::cmH2O("cmH2O");
const PressureUnit PressureUnit::psi("psi");
const PressureUnit PressureUnit::atm("atm");
const PressureUnit PressureUnit::mbar("mbar");
bool PressureUnit::IsValidUnit(const std::string& unit)
{
......@@ -22,6 +23,8 @@ bool PressureUnit::IsValidUnit(const std::string& unit)
return true;
if (atm.GetString().compare(unit) == 0)
return true;
if (mbar.GetString().compare(unit) == 0)
return true;
return false;
}
......@@ -37,6 +40,8 @@ const PressureUnit& PressureUnit::GetCompoundUnit(const std::string& unit)
return psi;
if (atm.GetString().compare(unit) == 0)
return atm;
if (mbar.GetString().compare(unit) == 0)
return mbar;
std::stringstream err;
err << unit << " is not a valid Pressure unit";
throw CommonDataModelException(err.str());
......
......@@ -18,6 +18,7 @@ public:
static const PressureUnit cmH2O;
static const PressureUnit psi;
static const PressureUnit atm;
static const PressureUnit mbar;
};
class CDM_DECL SEScalarPressure : public SEScalarQuantity<PressureUnit>
......
This diff is collapsed.
......@@ -6,6 +6,8 @@ set(PULSE_FILES
"cpp/PulsePhysiologySystems.h"
"cpp/PulseScenario.h"
"cpp/PulseScenario.cpp"
"cpp/PulseScenarioExec.h"
"cpp/PulseScenarioExec.cpp"
)
source_group("" FILES ${PULSE_FILES})
set(SOURCE ${PULSE_FILES})
......@@ -21,8 +23,6 @@ set(PULSE_CONTROLLER_FILES
"cpp/controller/Engine.cpp"
"cpp/controller/PatientSetup.h"
"cpp/controller/PatientSetup.cpp"
"cpp/controller/ScenarioExec.h"
"cpp/controller/ScenarioExec.cpp"
"cpp/controller/Substances.h"
"cpp/controller/Substances.cpp"
"cpp/controller/System.h"
......@@ -140,4 +140,5 @@ install(TARGETS PulseEngine
ARCHIVE DESTINATION ${INSTALL_LIB})
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cpp/PulsePhysiologyEngine.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cpp/PulseConfiguration.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cpp/PulseScenarioExec.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cpp/PulseScenario.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
......@@ -3,7 +3,7 @@
#include "PulseEngineJNI.h"
#include "PulseScenario.h"
#include "controller/ScenarioExec.h"
#include "PulseScenarioExec.h"
#include "engine/SEAction.h"
#include "engine/SEDataRequest.h"
#include "engine/SEDataRequestManager.h"
......@@ -150,7 +150,6 @@ JNIEXPORT jboolean JNICALL Java_com_kitware_physiology_pulse_engine_PulseEngine_
}
else
{
std::cout << "Loading... " << std::endl;
bRet = engineJNI->eng->SerializeFromFile(pStateFilename, JSON);
}
engineJNI->eng->SetEventHandler(engineJNI);
......
......@@ -3,90 +3,23 @@
#include "PulseScenarioDriver.h"
#include "PulsePhysiologyEngine.h"
#include "controller/Controller.h"
#include "controller/ScenarioExec.h"
#include "utils/FileUtils.h"
bool PulseScenarioDriver::Configure(int argc, char* argv[])
{
if (argc <= 1)
{
std::cerr << "Need scenario file or config file to execute" << std::endl;
return false;
}
m_file = argv[1];
for (int i = 2; i < argc; ++i)
{
std::string argument(argv[i]);
if (argument.at(0) == '-')
{
m_arguments.insert(argument.substr(1));
}
}
return true;
}
void PulseScenarioDriver::Run()
{
// Set up the log file
std::string logFile = m_file;
logFile = Replace(logFile, "verification", "test_results");
logFile = Replace(logFile, ".json", ".log");
// Set up the verification output file
std::string dataFile = m_file;
dataFile = Replace(dataFile, "verification", "test_results");
dataFile = Replace(dataFile, ".json", "Results.csv");
// What are we creating?
std::cout << "Log File : " << logFile << std::endl;
std::cout << "Results File : " << dataFile << std::endl;
// Delete any results file that may be there
remove(dataFile.c_str());
std::unique_ptr<PhysiologyEngine> Pulse = CreatePulseEngine(logFile.c_str());
if (!Pulse)
{
std::cerr << "Unable to create PulseEngine" << std::endl;
return;
}
try
{
PulseScenarioExec exec(*((PulseEngine*)Pulse.get()));
exec.Execute(m_file.c_str(), dataFile.c_str());
}
catch (CommonDataModelException ex)
{
std::cerr << ex.what() << std::endl;
}
catch (std::exception ex)
{
std::cerr << ex.what() << std::endl;
}
catch (...)
{
std::cerr << "Unable to run scenario " << m_file << std::endl;
}
}
bool PulseScenarioDriver::HasArgument(const std::string& argument)
{
return m_arguments.find(argument) != end(m_arguments);
}
#include "PulseScenarioExec.h"
int main(int argc, char* argv[])
{
try
{
PulseScenarioDriver scenarioDriver;
if (!scenarioDriver.Configure(argc, argv))
if (argc <= 1)
{
std::cerr << "Need scenario file or config file to execute" << std::endl;
return 1;
}
scenarioDriver.Run();
PulseScenarioExec::Run(argv[1]);
}
catch (std::exception ex)
{
std::cerr << ex.what() << std::endl;
return 1;
}
return 0;
return 0;
}
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#pragma once
#include <string>
#include <set>
class PulseScenarioDriver
{
public:
PulseScenarioDriver() = default;
~PulseScenarioDriver() = default;
bool Configure(int argc, char* argv[]);
void Run();
private:
bool HasArgument(const std::string& argument);
std::string m_file;
std::set<std::string> m_arguments;
};
\ No newline at end of file
#pragma once
\ No newline at end of file
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#include "stdafx.h"
#include "PulseScenarioExec.h"
#include "controller/Engine.h"
#include "engine/SEAction.h"
#include "engine/SEAutoSerialization.h"
#include "PulseScenario.h"
#include "PulseConfiguration.h"
#include "properties/SEScalarTime.h"
#include "utils/FileUtils.h"
void PulseScenarioExec::Run(const std::string& scenarioFile)
{
// Set up the log file
std::string logFile = scenarioFile;
logFile = Replace(logFile, "verification", "test_results");
logFile = Replace(logFile, ".json", ".log");
// Set up the verification output file
std::string dataFile = scenarioFile;
dataFile = Replace(dataFile, "verification", "test_results");
dataFile = Replace(dataFile, ".json", "Results.csv");
// What are we creating?
std::cout << "Log File : " << logFile << std::endl;
std::cout << "Results File : " << dataFile << std::endl;
// Delete any results file that may be there
remove(dataFile.c_str());
std::unique_ptr<PhysiologyEngine> Pulse = CreatePulseEngine(logFile.c_str());
if (!Pulse)
{
std::cerr << "Unable to create PulseEngine" << std::endl;
return;
}
try
{
PulseScenarioExec exec(*((PulseEngine*)Pulse.get()));
exec.Execute(scenarioFile.c_str(), dataFile.c_str());
}
catch (CommonDataModelException ex)
{
std::cerr << ex.what() << std::endl;
}
catch (std::exception ex)
{
std::cerr << ex.what() << std::endl;
}
catch (...)
{
std::cerr << "Unable to run scenario " << scenarioFile << std::endl;
}
}
PulseScenarioExec::PulseScenarioExec(PulseEngine& engine) : SEScenarioExec(engine), m_PulseConfiguration(engine.GetSubstanceManager())
{
m_EngineConfiguration = &m_PulseConfiguration;
m_AutoSerializationTime_s = 0;
m_AutoSerializationPeriod_s = 0;
m_AutoSerializationTimeStamps = eSwitch::Off;
m_AutoSerializationAfterActions = eSwitch::Off;
m_AutoSerializationReload = eSwitch::Off;
m_AutoSerializationFileName = "";
}
PulseScenarioExec::~PulseScenarioExec()
{
}
bool PulseScenarioExec::Execute(const std::string& scenarioFile, const std::string& resultsFile)
{
try
{
m_ss << "Executing scenario file : " << scenarioFile << std::endl;
Info(m_ss);
m_Cancel = false;
PulseScenario scenario(m_Engine.GetSubstanceManager());
if (!scenario.SerializeFromFile(scenarioFile,JSON))
{
Error("Unable to load scenario file : " + scenarioFile);
return false;
}
std::string rFile = resultsFile;
if (rFile.empty())
{
rFile = scenarioFile;
rFile += ".csv";
}
return Execute(scenario, rFile);
}
catch (CommonDataModelException& ex)
{
Error(ex.what());
}
catch (...)
{
Error("Caught unknown exception, ending simulation");
}
return false;
}
bool PulseScenarioExec::Execute(const PulseScenario& scenario, const std::string& resultsFile)
{
// If any configuration parameters were provided, use them over what we had
if (scenario.HasConfiguration())
{
m_PulseConfiguration.Merge(*scenario.GetConfiguration());
if (m_PulseConfiguration.HasAutoSerialization())
{
m_AutoSerializationPeriod_s = m_PulseConfiguration.GetAutoSerialization().GetPeriod(TimeUnit::s);
m_AutoSerializationTimeStamps = m_PulseConfiguration.GetAutoSerialization().GetPeriodTimeStamps();
m_AutoSerializationAfterActions = m_PulseConfiguration.GetAutoSerialization().GetAfterActions();
m_AutoSerializationReload = m_PulseConfiguration.GetAutoSerialization().GetReloadState();
m_AutoSerializationFileName = m_PulseConfiguration.GetAutoSerialization().GetFileName();
m_AutoSerializationDirectory = m_PulseConfiguration.GetAutoSerialization().GetDirectory();
CreateFilePath(m_AutoSerializationDirectory);
Info("Exeucting Scenario with AutoSerialization");
}
}
bool success = SEScenarioExec::Execute(scenario, resultsFile);
return success;
}
bool PulseScenarioExec::ProcessActions(const SEScenario& scenario)
{
return SEScenarioExec::ProcessActions(scenario);
}
bool PulseScenarioExec::ProcessAction(const SEAction& action)
{
if (m_AutoSerializationAfterActions == eSwitch::On)
{
m_ss << action;
size_t start = m_ss.str().find(": ") + 2;
size_t end = m_ss.str().find('\n');
m_AutoSerializationActions << "-" << m_ss.str().substr(start, end - start);
m_ss.str("");
}
return SEScenarioExec::ProcessAction(action);
}
void PulseScenarioExec::AdvanceEngine()
{
if (m_AutoSerializationPeriod_s > 0)
{
m_AutoSerializationTime_s += m_Engine.GetTimeStep(TimeUnit::s);
if (m_AutoSerializationTime_s >= m_AutoSerializationPeriod_s)
{
Info("Serializing state after requested period : " + m_AutoSerializationActions.str());
m_AutoSerializationTime_s = 0;
m_AutoSerializationOutput.str("");
m_AutoSerializationOutput << m_AutoSerializationDirectory <<"/"<< m_AutoSerializationFileName;
if (m_AutoSerializationTimeStamps == eSwitch::On)
m_AutoSerializationOutput << "@" << m_Engine.GetSimulationTime(TimeUnit::s);
m_Engine.SerializeToFile(m_AutoSerializationOutput.str() + ".json", SerializationFormat::JSON);
if (m_AutoSerializationReload == eSwitch::On)
{
m_Engine.SerializeFromFile(m_AutoSerializationOutput.str() + ".json", SerializationFormat::JSON);
m_Engine.SerializeToFile(m_AutoSerializationOutput.str() + ".Reloaded.json", SerializationFormat::JSON);
}
}
}
m_Engine.AdvanceModelTime();
if (m_AutoSerializationActions.str().length() > 0)
{
Info("Serializing state after actions : " + m_AutoSerializationActions.str());
m_AutoSerializationOutput.str("");
m_AutoSerializationOutput << m_AutoSerializationDirectory <<"/"<< m_AutoSerializationFileName<<m_AutoSerializationActions.str();
if (m_AutoSerializationTimeStamps == eSwitch::On)
m_AutoSerializationOutput << "@" << m_Engine.GetSimulationTime(TimeUnit::s);
m_Engine.SerializeToFile(m_AutoSerializationOutput.str() + ".json", SerializationFormat::JSON);
if (m_AutoSerializationReload == eSwitch::On)
{
m_Engine.SerializeFromFile(m_AutoSerializationOutput.str() + ".json", SerializationFormat::JSON);
m_Engine.SerializeToFile(m_AutoSerializationOutput.str() + ".Reloaded.json", SerializationFormat::JSON);
}
m_AutoSerializationActions.str("");
}
}
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#pragma once
#include "scenario/SEScenarioExec.h"
#include "PulseConfiguration.h"
class PulseEngine;
class PulseScenario;
class SEAutoSerialization;
/**
* @brief Overloaded scenario exector to run a %Pulse specific scenario
*/
class PULSE_DECL PulseScenarioExec : public SEScenarioExec
{
public:
PulseScenarioExec(PulseEngine& engine);
virtual ~PulseScenarioExec();
virtual bool Execute(const std::string& scenarioFile, const std::string& resultsFile);
virtual bool Execute(const PulseScenario& scenario, const std::string& resultsFile);
static void Run(const std::string& scenarioFile);
protected:
PulseConfiguration m_PulseConfiguration;
double m_AutoSerializationPeriod_s;
double m_AutoSerializationTime_s;
eSwitch m_AutoSerializationTimeStamps;
eSwitch m_AutoSerializationAfterActions;
eSwitch m_AutoSerializationReload;
std::string m_AutoSerializationFileName;
std::string m_AutoSerializationDirectory;
std::stringstream m_AutoSerializationOutput;
std::stringstream m_AutoSerializationActions;
virtual bool ProcessActions(const SEScenario& scenario);
virtual bool ProcessAction(const SEAction& action);
virtual void AdvanceEngine();
};
\ No newline at end of file
......@@ -1020,7 +1020,6 @@ void Cardiovascular::Hemorrhage()
if (h->GetType() == eHemorrhage_Type::Internal)
{
SELiquidCompartment* abdomenCompartment = m_data.GetCompartments().GetLiquidCompartment(pulse::VascularCompartment::Abdomen);
//SELiquidCompartment* abdomenCompartment = m_data.GetCompartments().GetCardiovascularGraph().GetCompartment(pulse::VascularCompartment::Abdomen);
if (!abdomenCompartment->HasChild(compartment->GetName()))
{
m_ss << "Internal Hemorrhage is only supported for the abdominal region, including the right and left kidneys, liver, spleen, splanchnic, and small and large intestine vascular compartments.";
......@@ -1029,12 +1028,11 @@ void Cardiovascular::Hemorrhage()
continue;
}
}
if (h->GetType() == eHemorrhage_Type::External)
else //(h->GetType() == eHemorrhage_Type::External)
{
//Only mass is merely transfered if it is an internal bleed
TotalLossRate_mL_Per_s += rate_mL_Per_s;
}
}
//Get all circuit nodes in this compartment
std::vector<SEFluidCircuitNode*> nodes;
......
......@@ -49,7 +49,7 @@ public:
{
while (active)
{
wait = true;
wait = true;// Sleep until something flips wait to false
do { std::this_thread::sleep_for(std::chrono::microseconds(20)); } while (wait);
if (!active) break;
wait = true;
......@@ -104,7 +104,7 @@ void HowToTestSystemCapability()
profiler.Start("s");
do
{
{// Wait for all threads to be ready
ready = true;
for(auto slt : slts)
ready &= slt->wait;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment