Commit 9f88bda5 authored by Aaron Bray's avatar Aaron Bray
Browse files

Correct scenario json

Allow adding nodes/paths/cmpts/links with the same names
Refactor multiplex engine to use the proto structures
parent 34190eb8
......@@ -7,8 +7,8 @@
"AcuteRespiratoryDistressSyndrome": {
"Severity": { "Scalar0To1": { "Value": 0.3 } },
"LeftLungAffected": { "Scalar0To1": { "Value": 1.0 } },
"RightLungAffected": { "Scalar0To1": { "Value": 1.0 } } } } }
] }
"RightLungAffected": { "Scalar0To1": { "Value": 1.0 } } } } }
] }
}
},
"DataRequestManager":
......@@ -70,106 +70,104 @@
{ "DecimalFormat": { "Precision": 2 }, "Category": "Substance", "SubstanceName": "CarbonDioxide", "PropertyName": "AlveolarTransfer", "Unit": "mL/s" },
{ "DecimalFormat": { "Precision": 6 }, "Category": "Substance", "SubstanceName": "Epinephrine", "PropertyName": "BloodConcentration", "Unit": "ug/L" },
{ "DecimalFormat": { "Precision": 8 }, "Category": "Substance", "SubstanceName": "Epinephrine", "PropertyName": "SystemicMassCleared", "Unit": "ug" },
{ "DecimalFormat": { "Precision": 2 }, "Category": "Physiology", "PropertyName": "InspiratoryExpiratoryRatio", "Unit": "unitless" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "ExpiratoryFlow", "Unit": "L/s" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "InspiratoryFlow", "Unit": "L/s" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "PulmonaryCompliance", "Unit": "L/cmH2O" },
{ "DecimalFormat": { "Precision": 2 }, "Category": "Physiology", "PropertyName": "InspiratoryExpiratoryRatio", "Unit": "unitless" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "ExpiratoryFlow", "Unit": "L/s" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "InspiratoryFlow", "Unit": "L/s" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "PulmonaryCompliance", "Unit": "L/cmH2O" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "InspiratoryPulmonaryResistance", "Unit": "cmH2O s/L" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "ExpiratoryPulmonaryResistance", "Unit": "cmH2O s/L" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "CarricoIndex", "Unit": "mmHg" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "TransthoracicPressure", "Unit": "cmH2O" },
{ "DecimalFormat": { "Precision": 3 }, "Category": "Physiology", "PropertyName": "ShuntFraction", "Unit": "unitless" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "AlveolarArterialGradient", "Unit": "mmHg" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "ExpiratoryPulmonaryResistance", "Unit": "cmH2O s/L" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "CarricoIndex", "Unit": "mmHg" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "TransthoracicPressure", "Unit": "cmH2O" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "TotalPulmonaryVentilation", "Unit": "L/min" },
{ "DecimalFormat": { "Precision": 2 }, "Category": "GasCompartment", "CompartmentName": "Carina", "PropertyName": "OutFlow", "Unit": "L/s" },
{ "DecimalFormat": { "Precision": 3 }, "Category": "Patient", "PropertyName": "AlveoliSurfaceArea", "Unit": "m^2" }
{ "DecimalFormat": { "Precision": 3 }, "Category": "Physiology", "PropertyName": "ShuntFraction", "Unit": "unitless" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "AlveolarArterialGradient", "Unit": "mmHg" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "TransthoracicPressure", "Unit": "cmH2O" },
{ "DecimalFormat": { "Precision": 4 }, "Category": "Physiology", "PropertyName": "TotalPulmonaryVentilation", "Unit": "L/min" },
{ "DecimalFormat": { "Precision": 2 }, "Category": "GasCompartment", "CompartmentName": "Carina", "PropertyName": "OutFlow", "Unit": "L/s" },
{ "DecimalFormat": { "Precision": 3 }, "Category": "Patient", "PropertyName": "AlveoliSurfaceArea", "Unit": "m^2" }
]
},
"AnyAction":
[
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 30.0, "Unit": "s" } } } },
{ "PatientAction": { "Intubation": { "Type": "Tracheal" } } },
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 30.0, "Unit": "s" } } } },
{ "PatientAction": { "Dyspnea": { "Severity": { "Scalar0To1": { "Value": 1.0 } } } } },
{
"EquipmentAction": {
"MechanicalVentilatorConfiguration": {
"MechanicalVentilatorAction": { "EquipmentAction": { "Action": {
"Comment": "Attach the mechanical ventilator" }}},
"Configuration":
{
"BreathProfile": {
"Rate": { "ScalarFrequency": { "Value": 20.0, "Unit": "1/min" } },
"InspiratoryExpiratoryRatio": { "Value": 0.5, "Unit": "" }
},
"Connection": "Tube",
"Control": "PC_CMV",
"DriverWaveform": "Square",
"PeakInspiratoryPressure": { "ScalarPressure": { "Value": 20.0, "Unit": "cmH2O" } },
"PositiveEndExpiredPressure": { "ScalarPressure": { "Value": 8.0, "Unit": "cmH2O" } },
"FractionInspiredGas": [
{ "Name": "Oxygen", "Amount": { "Scalar0To1": { "Value": 0.25, "Unit": "" } } }
]
}
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 30.0, "Unit": "s" } } } },
{ "PatientAction": { "Intubation": { "Type": "Tracheal" } } },
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 30.0, "Unit": "s" } } } },
{ "PatientAction": { "Dyspnea": { "Severity": { "Scalar0To1": { "Value": 1.0 } } } } },
{
"EquipmentAction": {
"MechanicalVentilatorConfiguration": {
"MechanicalVentilatorAction": { "EquipmentAction": { "Action": {
"Comment": "Attach the mechanical ventilator" }}},
"Configuration":
{
"BreathProfile": {
"Rate": { "ScalarFrequency": { "Value": 20.0, "Unit": "1/min" } },
"InspiratoryExpiratoryRatio": { "Value": 0.5, "Unit": "" }
},
"Connection": "Tube",
"Control": "PC_CMV",
"DriverWaveform": "Square",
"PeakInspiratoryPressure": { "ScalarPressure": { "Value": 20.0, "Unit": "cmH2O" } },
"PositiveEndExpiredPressure": { "ScalarPressure": { "Value": 8.0, "Unit": "cmH2O" } },
"FractionInspiredGas": [
{ "Name": "Oxygen", "Amount": { "Scalar0To1": { "Value": 0.25, "Unit": "" } } }
]
}
}
},
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 5.0, "Unit": "min" } } } },
{ "PatientAction": { "AcuteRespiratoryDistressSyndromeExacerbation":
}
},
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 5.0, "Unit": "min" } } } },
{ "PatientAction": { "AcuteRespiratoryDistressSyndromeExacerbation":
{
"Severity": { "Scalar0To1": { "Value": 0.6 }},
"LeftLungAffected": { "Scalar0To1": { "Value": 1.0 }},
"RightLungAffected": { "Scalar0To1": { "Value": 1.0 }}
}}
},
{
"EquipmentAction": {
"MechanicalVentilatorConfiguration": {
"MechanicalVentilatorAction": { "EquipmentAction": { "Action": {
"Comment": "Attach the mechanical ventilator" }}},
"Configuration":
{
"BreathProfile": {
"Rate": { "ScalarFrequency": { "Value": 20.0, "Unit": "1/min" } },
"InspiratoryExpiratoryRatio": { "Value": 0.5, "Unit": "" }
},
"Connection": "Tube",
"Control": "PM_CMV",
"DriverWaveform": "Square",
"PeakInspiratoryPressure": { "ScalarPressure": { "Value": 25.0, "Unit": "cmH2O" } },
"PositiveEndExpiredPressure": { "ScalarPressure": { "Value": 10.0, "Unit": "cmH2O" } },
"FractionInspiredGas": [
{ "Name": "Oxygen", "Amount": { "Scalar0To1": { "Value": 0.5, "Unit": "" } } }
]
}
{
"EquipmentAction": {
"MechanicalVentilatorConfiguration": {
"MechanicalVentilatorAction": { "EquipmentAction": { "Action": {
"Comment": "Attach the mechanical ventilator" }}},
"Configuration":
{
"BreathProfile": {
"Rate": { "ScalarFrequency": { "Value": 20.0, "Unit": "1/min" } },
"InspiratoryExpiratoryRatio": { "Value": 0.5, "Unit": "" }
},
"Connection": "Tube",
"Control": "PC_CMV",
"DriverWaveform": "Square",
"PeakInspiratoryPressure": { "ScalarPressure": { "Value": 25.0, "Unit": "cmH2O" } },
"PositiveEndExpiredPressure": { "ScalarPressure": { "Value": 10.0, "Unit": "cmH2O" } },
"FractionInspiredGas": [
{ "Name": "Oxygen", "Amount": { "Scalar0To1": { "Value": 0.5, "Unit": "" } } }
]
}
}
},
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 5.0, "Unit": "min" } } } },
{ "PatientAction": { "AcuteRespiratoryDistressSyndromeExacerbation":
}
},
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 5.0, "Unit": "min" } } } },
{ "PatientAction": { "AcuteRespiratoryDistressSyndromeExacerbation":
{
"Severity": { "Scalar0To1": { "Value": 0.9 }},
"LeftLungAffected": { "Scalar0To1": { "Value": 1.0 }},
"RightLungAffected": { "Scalar0To1": { "Value": 1.0 }}
}}
},
{
{
"EquipmentAction": {
"MechanicalVentilatorConfiguration": {
"MechanicalVentilatorAction": { "EquipmentAction": { "Action": {
......@@ -181,7 +179,7 @@
"InspiratoryExpiratoryRatio": { "Value": 0.5, "Unit": "" }
},
"Connection": "Tube",
"Control": "PM_CMV",
"Control": "PC_CMV",
"DriverWaveform": "Square",
"PeakInspiratoryPressure": { "ScalarPressure": { "Value": 32.0, "Unit": "cmH2O" } },
"PositiveEndExpiredPressure": { "ScalarPressure": { "Value": 15.0, "Unit": "cmH2O" } },
......@@ -191,8 +189,8 @@
}
}
}
},
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 5.0, "Unit": "min" } } } }
},
{ "AdvanceTime": { "Time": { "ScalarTime": { "Value": 5.0, "Unit": "min" } } } }
]
}
\ No newline at end of file
......@@ -151,6 +151,11 @@ void SECircuit<CIRCUIT_TYPES>::AddNode(NodeType& node)
this->m_Nodes.push_back(&node);
}
template<CIRCUIT_TEMPLATE>
void SECircuit<CIRCUIT_TYPES>::ForceAddNode(NodeType& node)
{
this->m_Nodes.push_back(&node);
}
template<CIRCUIT_TEMPLATE>
bool SECircuit<CIRCUIT_TYPES>::HasNode(NodeType& node)
{
return Contains(m_Nodes, node);
......@@ -221,6 +226,11 @@ void SECircuit<CIRCUIT_TYPES>::AddPath(PathType& path)
m_Paths.push_back(&path);
}
template<CIRCUIT_TEMPLATE>
void SECircuit<CIRCUIT_TYPES>::ForceAddPath(PathType& path)
{
m_Paths.push_back(&path);
}
template<CIRCUIT_TEMPLATE>
bool SECircuit<CIRCUIT_TYPES>::HasPath(PathType& path)
{
return Contains(m_Paths, path);
......
......@@ -25,6 +25,7 @@ public:
// Nodes //
virtual void AddNode(NodeType& node);
virtual void ForceAddNode(NodeType& node);// No check for node with the same name
virtual bool HasNode(NodeType& node);
virtual bool HasNode(const std::string& name);
virtual NodeType* GetNode(const std::string& name);
......@@ -35,6 +36,7 @@ public:
// Paths //
virtual void AddPath(PathType& node);
virtual void ForceAddPath(PathType& node);// No check for path with the same name
virtual bool HasPath(PathType& node);
virtual bool HasPath(const std::string& name);
virtual PathType* GetPath(const std::string& name);
......
......@@ -35,6 +35,11 @@ void SECompartmentGraph<COMPARTMENT_GRAPH_TYPES>::AddCompartment(CompartmentType
m_Compartments.push_back(&cmpt);
}
template<COMPARTMENT_GRAPH_TEMPLATE>
void SECompartmentGraph<COMPARTMENT_GRAPH_TYPES>::ForceAddCompartment(CompartmentType& cmpt)
{
m_Compartments.push_back(&cmpt);
}
template<COMPARTMENT_GRAPH_TEMPLATE>
CompartmentType* SECompartmentGraph<COMPARTMENT_GRAPH_TYPES>::GetCompartment(const std::string& name)
{
for (CompartmentType* c : m_Compartments)
......@@ -95,6 +100,11 @@ void SECompartmentGraph<COMPARTMENT_GRAPH_TYPES>::AddLink(CompartmentLinkType& l
m_CompartmentLinks.push_back(&link);
}
template<COMPARTMENT_GRAPH_TEMPLATE>
void SECompartmentGraph<COMPARTMENT_GRAPH_TYPES>::ForceAddLink(CompartmentLinkType& link)
{
m_CompartmentLinks.push_back(&link);
}
template<COMPARTMENT_GRAPH_TEMPLATE>
CompartmentLinkType* SECompartmentGraph<COMPARTMENT_GRAPH_TYPES>::GetLink(const std::string& name)
{
for (CompartmentLinkType* p : m_CompartmentLinks)
......
......@@ -20,6 +20,7 @@ public:
virtual std::string GetName() const;
virtual void AddCompartment(CompartmentType& cmpt);
virtual void ForceAddCompartment(CompartmentType& cmpt);// No check for cmpt with the same name
virtual CompartmentType* GetCompartment(const std::string& name);
virtual const CompartmentType* GetCompartment(const std::string& name) const;
virtual const std::vector<CompartmentType*>& GetCompartments() const;
......@@ -27,6 +28,7 @@ public:
virtual void RemoveCompartment(const std::string& name);
virtual void AddLink(CompartmentLinkType& link);
virtual void ForceAddLink(CompartmentLinkType& link);// No check for link with the same name
virtual CompartmentLinkType* GetLink(const std::string& name);
virtual const CompartmentLinkType* GetLink(const std::string& name) const;
virtual const std::vector<CompartmentLinkType*>& GetLinks() const;
......
......@@ -2,6 +2,7 @@
add_executable_ex(MultiplexVentilationDriver main.cpp
MVController.cpp
MVController.h
MVGenData.cpp)
MVGenData.cpp
MVSimulation.cpp)
target_link_libraries(MultiplexVentilationDriver CommonPulseModels protobuf::libprotobuf)
\ No newline at end of file
......@@ -3,47 +3,6 @@
#include "MVController.h"
#include "controller/Circuits.h"
#include "controller/Compartments.h"
#include "controller/Substances.h"
#include "physiology/BloodChemistry.h"
#include "physiology/Cardiovascular.h"
#include "physiology/Drugs.h"
#include "physiology/Endocrine.h"
#include "physiology/Energy.h"
#include "physiology/Gastrointestinal.h"
#include "physiology/Hepatic.h"
#include "physiology/Nervous.h"
#include "physiology/Renal.h"
#include "physiology/Respiratory.h"
#include "physiology/Saturation.h"
#include "physiology/Tissue.h"
#include "environment/Environment.h"
#include "equipment/AnesthesiaMachine.h"
#include "equipment/ECG.h"
#include "equipment/Inhaler.h"
#include "equipment/MechanicalVentilator.h"
#include "engine/SEEngineTracker.h"
#include "engine/SEDataRequestManager.h"
#include "substance/SESubstanceTransport.h"
#include "circuit/fluid/SEFluidCircuitCalculator.h"
#include "circuit/fluid/SEFluidCircuit.h"
#include "circuit/fluid/SEFluidCircuitNode.h"
#include "circuit/fluid/SEFluidCircuitPath.h"
#include "compartment/fluid/SEGasCompartmentGraph.h"
#include "compartment/fluid/SELiquidCompartmentGraph.h"
#include "utils/DataTrack.h"
#include "properties/SEScalar0To1.h"
#include "properties/SEScalarFrequency.h"
#include "properties/SEScalarMass.h"
#include "properties/SEScalarFrequency.h"
#include "properties/SEScalarMassPerVolume.h"
#include "properties/SEScalarVolume.h"
#include "properties/SEScalarVolumePerPressure.h"
MVController::MVController(const std::string& logFileName, const std::string& data_dir) : Loggable(new Logger(logFileName))
{
m_BaseFileName = logFileName.substr(0, logFileName.length() - 4);
......@@ -53,237 +12,23 @@ MVController::~MVController()
}
bool MVController::Run(std::vector<std::string>& patients)
void MVController::TrackData(SEEngineTracker& trkr, const std::string& csv_filename)
{
SESubstanceManager* subMgr;
bool enableMultiplexVentilation;
double timeStep_s = 0.02;
double currentTime_s = 0;
SEFluidCircuit* multiplexVentilationCircuit;
SEGasCompartmentGraph* multiplexVentilationGraph;
SEFluidCircuitCalculator* calculator;
SEGasTransporter* transporter;
SELiquidTransporter* aerosolTransporter;
std::vector<PulseController*> engines;
calculator = new SEFluidCircuitCalculator(VolumePerPressureUnit::L_Per_cmH2O, VolumePerTimeUnit::L_Per_s,
PressureTimeSquaredPerVolumeUnit::cmH2O_s2_Per_L, PressureUnit::cmH2O,
VolumeUnit::L, PressureTimePerVolumeUnit::cmH2O_s_Per_L, GetLogger());
transporter = new SEGasTransporter(VolumePerTimeUnit::L_Per_s, VolumeUnit::L, VolumeUnit::L, GetLogger());
//aerosolTransporter = new SELiquidTransporter(VolumePerTimeUnit::mL_Per_s, VolumeUnit::mL, MassUnit::ug, MassPerVolumeUnit::ug_Per_mL, GetLogger());
// jbw Grab whatever nodes/compartments you need to connect everything
SEFluidCircuitNode* connectionNode = nullptr; // ex. Set this in a loop below
SEGasCompartment* connectionCmpt = nullptr;// ex. Set this in a loop below
int i=0;
for (std::string state : patients)
{
PulseController* pc = new PulseController(m_BaseFileName+"_p"+std::to_string(i++)+".log");
pc->SerializeFromFile(state, SerializationFormat::JSON);
// Build our multiplex circuit
// Let's add the first mechanical ventilator circuit to our circuit
if (i == 0)
{
subMgr = &pc->GetSubstances();
for (SEFluidCircuitNode* node : pc->GetCircuits().GetMechanicalVentilatorCircuit().GetNodes())
multiplexVentilationCircuit->AddNode(*node);
for (SEFluidCircuitPath* path : pc->GetCircuits().GetMechanicalVentilatorCircuit().GetPaths())
multiplexVentilationCircuit->AddPath(*path);
for (SEGasCompartment* cmpt : pc->GetCompartments().GetMechanicalVentilatorGraph().GetCompartments())
multiplexVentilationGraph->AddCompartment(*cmpt);
for (SEGasCompartmentLink* link : pc->GetCompartments().GetMechanicalVentilatorGraph().GetLinks())
multiplexVentilationGraph->AddLink(*link);
}
// Add all the nodes/paths/compartments/links to our circuit/graph
for (SEFluidCircuitNode* node : pc->GetCircuits().GetRespiratoryCircuit().GetNodes())
multiplexVentilationCircuit->AddNode(*node);
for (SEFluidCircuitPath* path : pc->GetCircuits().GetRespiratoryCircuit().GetPaths())
multiplexVentilationCircuit->AddPath(*path);
for (SEGasCompartment* cmpt : pc->GetCompartments().GetRespiratoryGraph().GetCompartments())
multiplexVentilationGraph->AddCompartment(*cmpt);
for (SEGasCompartmentLink* link : pc->GetCompartments().GetRespiratoryGraph().GetLinks())
multiplexVentilationGraph->AddLink(*link);
// jbw Add new path/link to connect patient respiratory system to mechanical ventilator
pc->GetEngineTracker().GetDataRequestManager().SetResultsFilename(m_BaseFileName+"_p"+std::to_string(i)+".csv");
pc->GetEngineTracker().GetDataRequestManager().CreateMechanicalVentilatorDataRequest("PeakInspiratoryPressure", PressureUnit::cmH2O);
pc->GetEngineTracker().GetDataRequestManager().CreateMechanicalVentilatorDataRequest("PositiveEndExpiredPressure", PressureUnit::cmH2O);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("TotalRespiratoryModelCompliance", VolumePerPressureUnit::L_Per_cmH2O);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("TidalVolume", VolumeUnit::L);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("EndTidalCarbonDioxidePressure", PressureUnit::cmH2O);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("RespirationRate", FrequencyUnit::Per_min);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("OxygenSaturation");
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("CarricoIndex", PressureUnit::mmHg);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("InspiratoryExpiratoryRatio");
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("SystolicArterialPressure", PressureUnit::mmHg);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("DiastolicArterialPressure", PressureUnit::mmHg);
pc->GetEngineTracker().GetDataRequestManager().CreatePhysiologyDataRequest("HeartRate", FrequencyUnit::Per_min);
// TODO Add any probes we may want...
pc->GetEngineTracker().SetupRequests();
engines.push_back(pc);
}
multiplexVentilationCircuit->StateChange();
multiplexVentilationGraph->StateChange();
SEMechanicalVentilatorConfiguration config(*subMgr);
int vent_count;
int count = (int)(60 / timeStep_s);
for (int i = 0; i < count; i++)
{
for (PulseController* pc : engines)
{
if(pc->GetEvents().IsEventActive(eEvent::IrreversibleState))
return false;
}
// PreProcess
for (PulseController* pc : engines)
((Environment&)pc->GetEnvironment()).PreProcess();
for (PulseController* pc : engines)
((Cardiovascular&)pc->GetCardiovascular()).PreProcess();
for (PulseController* pc : engines)
((Inhaler&)pc->GetInhaler()).PreProcess();
for (PulseController* pc : engines)
((Respiratory&)pc->GetRespiratory()).PreProcess();
for (PulseController* pc : engines)
((AnesthesiaMachine&)pc->GetAnesthesiaMachine()).PreProcess();
for (PulseController* pc : engines)
((MechanicalVentilator&)pc->GetMechanicalVentilator()).PreProcess();
for (PulseController* pc : engines)
((Gastrointestinal&)pc->GetGastrointestinal()).PreProcess();
for (PulseController* pc : engines)
((Hepatic&)pc->GetHepatic()).PreProcess();
for (PulseController* pc : engines)
((Renal&)pc->GetRenal()).PreProcess();
for (PulseController* pc : engines)
((Nervous&)pc->GetNervous()).PreProcess();
for (PulseController* pc : engines)
((Energy&)pc->GetEnergy()).PreProcess();
for (PulseController* pc : engines)
((Endocrine&)pc->GetEndocrine()).PreProcess();
for (PulseController* pc : engines)
((Drugs&)pc->GetDrugs()).PreProcess();
for (PulseController* pc : engines)
((Tissue&)pc->GetTissue()).PreProcess();
for (PulseController* pc : engines)
((BloodChemistry&)pc->GetBloodChemistry()).PreProcess();
// Since this is the last preprocess,
// Check if we are in mechanical ventilator mode
vent_count = 0;
enableMultiplexVentilation = false;
for (PulseController* pc : engines)
{
((ECG&)pc->GetECG()).PreProcess();
if (pc->GetAirwayMode() == eAirwayMode::MechanicalVentilator)
vent_count++;
}
if (vent_count > 0)
{
if (vent_count == engines.size())
enableMultiplexVentilation = true;
else
{
Fatal("Engines are out of sync");
return false;
}
}
// Process
for (PulseController* pc : engines)
((Environment&)pc->GetEnvironment()).Process();
for (PulseController* pc : engines)
((Cardiovascular&)pc->GetCardiovascular()).Process();
for (PulseController* pc : engines)
((Inhaler&)pc->GetInhaler()).Process();
if (enableMultiplexVentilation)
{
// Solve the multiplex circuit
calculator->Process(*multiplexVentilationCircuit, timeStep_s);
// Transport the multiplex graph
transporter->Transport(*multiplexVentilationGraph, timeStep_s);
// TODO Consider adding aerosol support
}
for (PulseController* pc : engines)
((Respiratory&)pc->GetRespiratory()).Process(!enableMultiplexVentilation);
for (PulseController* pc : engines)
((AnesthesiaMachine&)pc->GetAnesthesiaMachine()).Process();
for (PulseController* pc : engines)
((MechanicalVentilator&)pc->GetMechanicalVentilator()).Process();
for (PulseController* pc : engines)
((Gastrointestinal&)pc->GetGastrointestinal()).Process();
for (PulseController* pc : engines)
((Hepatic&)pc->GetHepatic()).Process();
for (PulseController* pc : engines)
((Renal&)pc->GetRenal()).Process();
for (PulseController* pc : engines)
((Nervous&)pc->GetNervous()).Process();
for (PulseController* pc : engines)
((Energy&)pc->GetEnergy()).Process();
for (PulseController* pc : engines)
((Endocrine&)pc->GetEndocrine()).Process();
for (PulseController* pc : engines)
((Drugs&)pc->GetDrugs()).Process();
for (PulseController* pc : engines)
((Tissue&)pc->GetTissue()).Process();
for (PulseController* pc : engines)
((BloodChemistry&)pc->GetBloodChemistry()).Process();
for (PulseController* pc : engines)
((ECG&)pc->GetECG()).Process();
// PostProcess
for (PulseController* pc : engines)
((Environment&)pc->GetEnvironment()).PostProcess();
for (PulseController* pc : engines)
((Cardiovascular&)pc->GetCardiovascular()).PostProcess();
for (PulseController* pc : engines)
((Inhaler&)pc->GetInhaler()).PostProcess();
for (PulseController* pc : engines)