Commit e7f82789 authored by Aaron Bray's avatar Aaron Bray
Browse files

Merge branch 'feature/supplemental_O2' into '2.x'

New Equipment Models Providing Supplemental O2 to a Patient

See merge request !23
parents b7e9cc20 d4bacf5f
......@@ -77,7 +77,7 @@ elseif(TYPE STREQUAL "doxygen")
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -Xmx900m -classpath "${JAVA_CLASSPATH}" com.kitware.physiology.utilities.csv.plots.PlotDriver PlotRun.config)
execute_process(COMMAND doxygen ./docs/full.doxy)
elseif(TYPE STREQUAL "protoc")
execute_process(COMMAND ${CMAKE_COMMAND} -DSCHEMA_SRC:STRING="@SCHEMA_SRC@" -DSCHEMA_DST:STRING="@SCHEMA_DST@" -P "@CMAKE_SOURCE_DIR@/schema/GenerateCDMBindings.cmake")
execute_process(COMMAND ${CMAKE_COMMAND} -DSCHEMA_SRC:STRING=@SCHEMA_SRC@ -DSCHEMA_DST:STRING=@SCHEMA_DST@ -P "@CMAKE_SOURCE_DIR@/schema/GenerateCDMBindings.cmake")
elseif(TYPE STREQUAL "updateBaselines")
execute_process(COMMAND ${CMAKE_COMMAND} --build "@CMAKE_CURRENT_BINARY_DIR@" --target UpdateVerification)
elseif(TYPE STREQUAL "rebase")
......
......@@ -3,7 +3,6 @@
#pragma once
class SEEventHandler;
class SEAdvanceHandler;
class SEPatient;
class SEPatientConfiguration;
......@@ -31,6 +30,7 @@ class SEElectroCardioGram;
class SECompartmentManager;
class SEActionManager;
class SEConditionManager;
class SEEventManager;
class SEEngineTracker;
class SEEngineConfiguration;
......@@ -210,9 +210,10 @@ public:
//--------------------------------------------------------------------------------------------------
/// \brief
/// Add a callback object that will be called whenever a pateint or anesthesia machine event changes state
/// Retrieves the associated event manager.
///
//--------------------------------------------------------------------------------------------------
virtual void SetEventHandler(SEEventHandler* handler) = 0;
virtual const SEEventManager& GetEventManager() const = 0;
//--------------------------------------------------------------------------------------------------
/// \brief
......
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#pragma once
#include "patient/SEPatient.h"
#include "system/equipment/anesthesiamachine/SEAnesthesiaMachine.h"
class CDM_DECL SEEventHandler
{
public:
SEEventHandler() {};
virtual ~SEEventHandler(){};
virtual void HandlePatientEvent(ePatient_Event type, bool active, const SEScalarTime* time = nullptr)=0;
virtual void HandleAnesthesiaMachineEvent(eAnesthesiaMachine_Event type, bool active, const SEScalarTime* time = nullptr) = 0;
};
\ No newline at end of file
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#include "stdafx.h"
#include "engine/SEEventManager.h"
#include "properties/SEScalarTime.h"
SEEventManager::SEEventManager(Logger* logger) : Loggable(logger)
{
Clear();
}
SEEventManager::~SEEventManager()
{
}
void SEEventManager::Clear()
{
m_EventHandler = nullptr;
m_EventState.clear();
m_EventDuration_s.clear();
}
void SEEventManager::SetEvent(eEvent type, bool active, const SEScalarTime& time)
{
bool b = false;// Default is off
if (m_EventState.find(type) != m_EventState.end())
b = m_EventState[type];
if (b == active)
return;//No Change
if (active != b)
{
m_ss.str("");
m_ss << "[Event] " << time << ", ";
if (active)
{
switch (type)
{
case eEvent::Antidiuresis:
m_ss << " Patient has Antidiuresis";
break;
case eEvent::Asystole:
m_ss << " Patient has Asystole";
break;
case eEvent::Bradycardia:
m_ss << " Patient has Bradycardia";
break;
case eEvent::Bradypnea:
m_ss << " Patient has Bradypnea";
break;
case eEvent::BrainOxygenDeficit:
m_ss << " Oxygen tension in the brain is dangerously low";
break;
case eEvent::CardiacArrest:
m_ss << " Patient has Cardiac Arrest";
break;
case eEvent::CardiogenicShock:
m_ss << " Patient has Cardiogenic Shock";
break;
case eEvent::CriticalBrainOxygenDeficit:
m_ss << " Oxygen tension in the brain is critically low";
break;
case eEvent::Dehydration:
m_ss << " Patient has entered state of Dehydration";
break;
case eEvent::Diuresis:
m_ss << " Patient has entered Diuresis";
break;
case eEvent::Fasciculation:
m_ss << "Patient has Fasciculation";
break;
case eEvent::FunctionalIncontinence:
m_ss << " Patient has involuntarily emptied their bladder";
break;
case eEvent::Hypercapnia:
m_ss << " Patient has Hypercapnia";
break;
case eEvent::Hyperglycemia:
m_ss << " Patient has Hyperglycemia";
break;
case eEvent::Hyperthermia:
m_ss << " Patient is Hyperthermic";
break;
case eEvent::Hypoglycemia:
m_ss << " Patient has Hypoglycemia";
break;
case eEvent::Hypothermia:
m_ss << " Patient is Hypothermic";
break;
case eEvent::Hypoxia:
m_ss << " Patient has Hypoxia";
break;
case eEvent::IntracranialHypertension:
m_ss << " Patient has Intracranial Hypertension";
break;
case eEvent::IntracranialHypotension:
m_ss << " Patient has Intracranial Hypotension";
break;
case eEvent::HypovolemicShock:
m_ss << " Patient is in Hypovolemic Shock";
break;
case eEvent::IrreversibleState:
m_ss << " Patient has entered irreversible state";
break;
case eEvent::Ketoacidosis:
m_ss << " Patient has Ketoacidosis";
break;
case eEvent::LacticAcidosis:
m_ss << " Patient has LacticAcidosis";
break;
case eEvent::MaximumPulmonaryVentilationRate:
m_ss << " Patient's Respiratory Driver has exceeded the maximum target pulmonary ventilation rate, setting value to the maximum allowable rate";
break;
case eEvent::MetabolicAcidosis:
m_ss << " The patient is in a state of metabolic acidosis";
break;
case eEvent::MetabolicAlkalosis:
m_ss << " The patient is in a state of metabolic alkalosis";
break;
case eEvent::MildAcuteRespiratoryDistress:
m_ss << " The patient has Mild Acute Respiratory Distress";
break;
case eEvent::ModerateAcuteRespiratoryDistress:
m_ss << " The patient has Moderate Acute Respiratory Distress";
break;
case eEvent::MyocardiumOxygenDeficit:
m_ss << " The patient's heart is not receiving enough oxygen";
break;
case eEvent::Natriuresis:
m_ss << " Patient has Natriuresis";
break;
case eEvent::NutritionDepleted:
m_ss << " Patient has depleted all nutrition in body";
break;
case eEvent::RenalHypoperfusion:
m_ss << " Patient has Renal Hypoperfusion";
break;
case eEvent::SevereAcuteRespiratoryDistress:
m_ss << " The patient has Severe Acute Respiratory Distress";
break;
case eEvent::Tachycardia:
m_ss << " Patient has Tachycardia";
break;
case eEvent::Tachypnea:
m_ss << " Patient has Tachypnea";
break;
case eEvent::Fatigue:
m_ss << "Patient has fatigue";
break;
case eEvent::StartOfCardiacCycle:
case eEvent::StartOfExhale:
case eEvent::StartOfInhale:
m_ss.str("");// make m_ss empty and nothing will be logged, this event does not need to get logged each activation
break;
// Equipment
case eEvent::AnesthesiaMachineOxygenBottleOneExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 1 has been exhausted";
break;
case eEvent::AnesthesiaMachineOxygenBottleTwoExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 2 has been exhausted";
break;
case eEvent::AnesthesiaMachineReliefValveActive:
m_ss << "Anesthesi aMachine Relief valve active - pressure exceeded";
break;
default:
m_ss << " Engine has entered state : " << eEvent_Name(type);
}
}
else
{
switch (type)
{
case eEvent::Antidiuresis:
m_ss << " Patient no longer is in Antidiuresis";
break;
case eEvent::Asystole:
m_ss << " Patient no longer is in Asystole";
break;
case eEvent::Bradycardia:
m_ss << " Patient no longer has Bradycardia";
break;
case eEvent::Bradypnea:
m_ss << " Patient no longer has Bradypnea";
break;
case eEvent::BrainOxygenDeficit:
m_ss << " Oxygen tension in the brain has increased above the danger threshold";
break;
case eEvent::CardiacArrest:
m_ss << " Patient no longer has Cardiac Arrest";
break;
case eEvent::CardiogenicShock:
m_ss << " Patient no longer has Cardiogenic Shock";
break;
case eEvent::CriticalBrainOxygenDeficit:
m_ss << " Oxygen tension in the brain has increased above the critical threshold";
break;
case eEvent::Dehydration:
m_ss << " Patient no longer is in Dehydration state";
break;
case eEvent::Diuresis:
m_ss << " Patient no longer has Diuresis";
break;
case eEvent::Fasciculation:
m_ss << "Patient no longer has fasciculations";
break;
case eEvent::FunctionalIncontinence:
m_ss << " Patient has an empty bladder";
break;
case eEvent::Hypercapnia:
m_ss << " Patient no longer has Hypercapnia";
break;
case eEvent::Hyperglycemia:
m_ss << " Patient no longer has Hyperglycemia";
break;
case eEvent::Hyperthermia:
m_ss << " Patient is no longer has Hyperthermic";
break;
case eEvent::Hypoglycemia:
m_ss << " Patient no longer has Hypoglycemia";
break;
case eEvent::Hypothermia:
m_ss << " Patient is no longer has Hypothermic";
break;
case eEvent::Hypoxia:
m_ss << " Patient no longer has Hypoxia";
break;
case eEvent::HypovolemicShock:
m_ss << " Patient is no longer in Hypovolemic Shock";
break;
case eEvent::IntracranialHypertension:
m_ss << " Patient no longer has Intracranial Hypertension";
break;
case eEvent::IntracranialHypotension:
m_ss << " Patient no longer has Intracranial Hypotension";
break;
case eEvent::IrreversibleState:
m_ss << " Patient no longer is in irreversible state?!";
break;
case eEvent::Ketoacidosis:
m_ss << " Patient no longer has Ketoacidosis";
break;
case eEvent::LacticAcidosis:
m_ss << " Patient no longer has LacticAcidosis";
break;
case eEvent::MaximumPulmonaryVentilationRate:
m_ss << " Patient's Respiratory Driver is no longer exceeding the maximum target pulmonary ventilation rate";
break;
case eEvent::MetabolicAcidosis:
m_ss << " The patient is no longer in a state of metabolic acidosis";
break;
case eEvent::MetabolicAlkalosis:
m_ss << " The patient is no longer in a state of metabolic alkalosis";
break;
case eEvent::MildAcuteRespiratoryDistress:
m_ss << " Patient no longer has a Mild Acute Respiratory Distress";
break;
case eEvent::ModerateAcuteRespiratoryDistress:
m_ss << " Patient no longer has a Moderate Acute Respiratory Distress";
break;
case eEvent::MyocardiumOxygenDeficit:
m_ss << " Patient no longer has a Myocardium Oxygen Deficit";
break;
case eEvent::Natriuresis:
m_ss << " Patient no longer has Natriuresis";
break;
case eEvent::NutritionDepleted:
m_ss << " Patient has nutrition in body";
break;
case eEvent::RenalHypoperfusion:
m_ss << " Patient no longer has Renal Hypoperfusion";
break;
case eEvent::SevereAcuteRespiratoryDistress:
m_ss << " Patient no longer has a Severe Acute Respiratory Distress";
break;
case eEvent::Tachycardia:
m_ss << " Patient no longer has Tachycardia";
break;
case eEvent::Tachypnea:
m_ss << " Patient no longer has Tachypnea";
break;
case eEvent::Fatigue:
m_ss << "Patient is no longer fatigued";
break;
case eEvent::StartOfCardiacCycle:
case eEvent::StartOfExhale:
case eEvent::StartOfInhale:
m_ss.str("");// make m_ss empty and nothing will be logged, this event does not need to get logged each activation
break;
// Equipment
case eEvent::AnesthesiaMachineOxygenBottleOneExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 1 has been replenished";
break;
case eEvent::AnesthesiaMachineOxygenBottleTwoExhausted:
m_ss << "Anesthesia Machine Oxygen Bottle 2 has been replenished";
break;
case eEvent::AnesthesiaMachineReliefValveActive:
m_ss << "Anesthesia Machine Relief valve inactive - pressure below setting";
break;
default:
m_ss << " Engine has exited state : " << eEvent_Name(type);
}
}
if (!m_ss.str().empty())
Info(m_ss);
}
m_EventState[type] = active;
m_EventDuration_s[type] = 0;
if (m_EventHandler != nullptr)
m_EventHandler->HandleEvent(type, active, &time);
}
bool SEEventManager::IsEventActive(eEvent e) const
{
auto i = m_EventState.find(e);
if (i == m_EventState.end())
return false;
return i->second;
}
double SEEventManager::GetEventDuration(eEvent e, const TimeUnit& unit) const
{
auto i = m_EventDuration_s.find(e);
if (i == m_EventDuration_s.end())
return 0;
return Convert(i->second, TimeUnit::s, unit);
}
void SEEventManager::OverrideActiveState(eEvent e, const SEScalarTime& duration)
{
m_EventState[e] = true;
m_EventDuration_s[e] = duration.GetValue(TimeUnit::s);
}
void SEEventManager::UpdateEvents(const SEScalarTime& timeStep)
{
for (auto& itr : m_EventDuration_s)
itr.second += timeStep.GetValue(TimeUnit::s);
}
void SEEventManager::ForwardEvents(SEEventHandler* handler) const
{
m_EventHandler = handler;
}
\ No newline at end of file
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#pragma once
// Keep enums in sync with appropriate schema/cdm/Event.proto file !!
enum class eEvent
{
Antidiuresis = 0,
Asystole = 1,
Bradycardia = 2,
Bradypnea = 3,
BrainOxygenDeficit = 4,
CardiacArrest = 5,
CardiogenicShock = 6,
CriticalBrainOxygenDeficit = 7,
Dehydration = 8,
Diuresis = 9,
Fasciculation = 10,
Fatigue = 11,
FunctionalIncontinence = 12,
Hypercapnia = 13,
Hyperglycemia = 14,
Hyperthermia = 15,
Hypoglycemia = 16,
Hypothermia = 17,
Hypoxia = 18,
HypovolemicShock = 19,
IntracranialHypertension = 20,
IntracranialHypotension = 21,
IrreversibleState = 22,
Ketoacidosis = 23,
LacticAcidosis = 24,
MaximumPulmonaryVentilationRate = 25,
MetabolicAcidosis = 26,
MetabolicAlkalosis = 27,
MildAcuteRespiratoryDistress = 28,
ModerateAcuteRespiratoryDistress = 29,
MyocardiumOxygenDeficit = 30,
Natriuresis = 31,
NutritionDepleted = 32,
RenalHypoperfusion = 33,
RespiratoryAcidosis = 34,
RespiratoryAlkalosis = 35,
StartOfCardiacCycle = 36,
StartOfExhale = 37,
StartOfInhale = 38,
SevereAcuteRespiratoryDistress = 39,
Tachycardia = 40,
Tachypnea = 41,
// Equipment
AnesthesiaMachineOxygenBottleOneExhausted = 1000,
AnesthesiaMachineOxygenBottleTwoExhausted = 1001,
AnesthesiaMachineReliefValveActive = 1002
};
extern const std::string& eEvent_Name(eEvent m);
class CDM_DECL SEEventHandler
{
public:
SEEventHandler() {};
virtual ~SEEventHandler() {};
virtual void HandleEvent(eEvent type, bool active, const SEScalarTime* time = nullptr) = 0;
};
class CDM_DECL SEEventManager : public Loggable
{
public:
SEEventManager(Logger* logger);
virtual ~SEEventManager();
void Clear();
// Essentially a load, this will set the state to active and set its duration
virtual void OverrideActiveState(eEvent state, const SEScalarTime& duration);
virtual const std::map<eEvent, bool>& GetEventStates() const { return m_EventState; }
virtual void SetEvent(eEvent e, bool active, const SEScalarTime& time);
virtual bool IsEventActive(eEvent e) const;
virtual double GetEventDuration(eEvent e, const TimeUnit& unit) const;
virtual void UpdateEvents(const SEScalarTime& timeStep);
/** @name ForwardEvents
* @brief - Set a callback class to invoke when any event changes
* @details - Note that the handler callback can and will be called in the middle of a time step
* So system and compartment objects may not be completely up to date when called.
* Use the PhysiologyEngineInterface::SetEventHandler to ensure that all engine
* data is up to date at the time the callback is invoked
*/
virtual void ForwardEvents(SEEventHandler* handler) const;
virtual SEEventHandler* GetEventHandler() { return m_EventHandler; }
protected:
std::stringstream m_ss;
mutable SEEventHandler* m_EventHandler;
std::map<eEvent, bool> m_EventState;
std::map<eEvent, double> m_EventDuration_s;
};
......@@ -22,10 +22,11 @@
#include "patient/actions/SEMechanicalVentilation.h"
#include "patient/actions/SENeedleDecompression.h"
#include "patient/actions/SEPericardialEffusion.h"
#include "patient/actions/SETensionPneumothorax.h"
#include "patient/actions/SESubstanceBolus.h"
#include "patient/actions/SESubstanceCompoundInfusion.h"
#include "patient/actions/SESubstanceInfusion.h"
#include "patient/actions/SESupplementalOxygen.h"
#include "patient/actions/SETensionPneumothorax.h"
#include "patient/actions/SEUrinate.h"
#include "patient/actions/SEPatientAssessmentRequest.h"
......@@ -56,6 +57,7 @@ SEPatientActionCollection::SEPatientActionCollection(SESubstanceManager& substan
m_LeftNeedleDecompression = nullptr;
m_RightNeedleDecompression = nullptr;
m_PericardialEffusion = nullptr;
m_SupplementalOxygen = nullptr;
m_LeftOpenTensionPneumothorax = nullptr;
m_LeftClosedTensionPneumothorax = nullptr;
m_RightOpenTensionPneumothorax = nullptr;
......@@ -435,6 +437,17 @@ bool SEPatientActionCollection::ProcessAction(const SEPatientAction& action)
return true;
}
const SESupplementalOxygen* supplementalO2 = dynamic_cast<const SESupplementalOxygen*>(&action);
if (supplementalO2 != nullptr)
{
if (m_SupplementalOxygen == nullptr)
m_SupplementalOxygen = new SESupplementalOxygen();
m_SupplementalOxygen->Copy(*supplementalO2);
if (!m_SupplementalOxygen->IsActive())
RemoveSupplementalOxygen();
return true;
}
const SETensionPneumothorax* pneumo = dynamic_cast<const SETensionPneumothorax*>(&action);
if (pneumo != nullptr)
{
......@@ -845,6 +858,56 @@ void SEPatientActionCollection::RemovePericardialEffusion()
SAFE_DELETE(m_PericardialEffusion);
}
bool SEPatientActionCollection::HasSupplementalOxygen() const
{
return m_SupplementalOxygen == nullptr ? false : m_SupplementalOxygen->IsActive();
}
SESupplementalOxygen* SEPatientActionCollection::GetSupplementalOxygen()
{
return m_SupplementalOxygen;
}
const SESupplementalOxygen* SEPatientActionCollection::GetSupplementalOxygen() const
{
return m_SupplementalOxygen;
}
void SEPatientActionCollection::RemoveSupplementalOxygen()
{
SAFE_DELETE(m_SupplementalOxygen);
}
const std::map<const SESubstance*, SESubstanceBolus*>& SEPatientActionCollection::GetSubstanceBoluses() const
{
return m_SubstanceBolus;
}
void SEPatientActionCollection::RemoveSubstanceBolus(const SESubstance& sub)
{
SESubstanceBolus* b = m_SubstanceBolus[&sub];
m_SubstanceBolus.erase(&sub);
SAFE_DELETE(b);
}
const std::map<const SESubstance*, SESubstanceInfusion*>& SEPatientActionCollection::GetSubstanceInfusions() const
{
return m_SubstanceInfusions;
}
void SEPatientActionCollection::RemoveSubstanceInfusion(const SESubstance& sub)
{
SESubstanceInfusion* si = m_SubstanceInfusions[&sub];
m_SubstanceInfusions.erase(&sub);
SAFE_DELETE(si);
}
const std::map<const SESubstanceCompound*, SESubstanceCompoundInfusion*>& SEPatientActionCollection::GetSubstanceCompoundInfusions() const
{
return m_SubstanceCompoundInfusions;
}
void SEPatientActionCollection::RemoveSubstanceCompoundInfusion(const SESubstanceCompound& cSub)
{
SESubstanceCompoundInfusion* sci = m_SubstanceCompoundInfusions[&cSub];
m_SubstanceCompoundInfusions.erase(&cSub);
SAFE_DELETE(sci);
}
bool SEPatientActionCollection::HasTensionPneumothorax() const
{
if (m_LeftOpenTensionPneumothorax != nullptr&&m_LeftOpenTensionPneumothorax->IsActive())
......@@ -930,39 +993,6 @@ void SEPatientActionCollection::RemoveRightClosedTensionPneumothorax()
SAFE_DELETE(m_RightClosedTensionPneumothorax);
}
const std::map<const SESubstance*, SESubstanceBolus*>& SEPatientActionCollection::GetSubstanceBoluses() const
{
return m_SubstanceBolus;
}
void SEPatientActionCollection::RemoveSubstanceBolus(const SESubstance& sub)
{
SESubstanceBolus* b = m_SubstanceBolus[&sub];
m_SubstanceBolus.erase(&sub);