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

Add the ability to set the administration duration for bolus injections

parent e4e515dc
......@@ -1099,6 +1099,8 @@ void PBPatientAction::Serialize(const CDM_BIND::SubstanceBolusData& src, SESubst
{
PBPatientAction::Serialize(src.patientaction(), dst);
dst.SetAdminRoute((eSubstanceAdministration_Route)src.administrationroute());
if (src.has_administrationduration())
PBProperty::Load(src.administrationduration(), dst.GetAdminDuration());
if (src.has_dose())
PBProperty::Load(src.dose(), dst.GetDose());
if (src.has_concentration())
......@@ -1117,6 +1119,8 @@ void PBPatientAction::Serialize(const SESubstanceBolus& src, CDM_BIND::Substance
PBPatientAction::Serialize(src, *dst.mutable_patientaction());
dst.set_substance(src.m_Substance.GetName());
dst.set_administrationroute((CDM_BIND::SubstanceBolusData::eRoute)src.m_AdminRoute);
if (src.HasAdminDuration())
dst.set_allocated_administrationduration(PBProperty::Unload(*src.m_AdminDuration));
if (src.HasDose())
dst.set_allocated_dose(PBProperty::Unload(*src.m_Dose));
if (src.HasConcentration())
......
......@@ -12,6 +12,7 @@
SESubstanceBolus::SESubstanceBolus(const SESubstance& substance, Logger* logger) : SESubstanceAdministration(logger), m_Substance(substance), m_State(substance)
{
m_AdminRoute=eSubstanceAdministration_Route::Intravenous;
m_AdminDuration=nullptr;
m_Dose=nullptr;
m_Concentration=nullptr;
}
......@@ -19,6 +20,7 @@ SESubstanceBolus::SESubstanceBolus(const SESubstance& substance, Logger* logger)
SESubstanceBolus::~SESubstanceBolus()
{
m_AdminRoute = eSubstanceAdministration_Route::Intravenous;
SAFE_DELETE(m_AdminDuration);
SAFE_DELETE(m_Dose);
SAFE_DELETE(m_Concentration);
m_State.Clear();
......@@ -28,6 +30,7 @@ void SESubstanceBolus::Clear()
{
SESubstanceAdministration::Clear();
m_AdminRoute=eSubstanceAdministration_Route::Intravenous;
INVALIDATE_PROPERTY(m_AdminDuration);
INVALIDATE_PROPERTY(m_Dose);
INVALIDATE_PROPERTY(m_Concentration);
m_State.Clear();
......@@ -57,6 +60,23 @@ void SESubstanceBolus::SetAdminRoute(eSubstanceAdministration_Route route)
m_AdminRoute = route;
}
bool SESubstanceBolus::HasAdminDuration() const
{
return m_AdminDuration == nullptr ? false : m_AdminDuration->IsValid();
}
SEScalarTime& SESubstanceBolus::GetAdminDuration()
{
if (m_AdminDuration == nullptr)
m_AdminDuration = new SEScalarTime();
return *m_AdminDuration;
}
double SESubstanceBolus::GetAdminDuration(const TimeUnit& unit) const
{
if (m_AdminDuration == nullptr)
return SEScalar::dNaN();
return m_AdminDuration->GetValue(unit);
}
bool SESubstanceBolus::HasDose() const
{
return m_Dose==nullptr?false:m_Dose->IsValid();
......@@ -105,10 +125,11 @@ void SESubstanceBolus::ToString(std::ostream &str) const
str << "Patient Action : Substance Bolus";
if(HasComment())
str<<"\n\tComment: "<<m_Comment;
str << "\n\tDose: "; HasDose()? str << *m_Dose : str << "No Dose Set";
str << "\n\tConcentration: "; HasConcentration()? str << *m_Concentration : str << "NaN";
str << "\n\tSubstance: " << m_Substance.GetName();
str << "\n\tAdministration Route: " << eSubstanceAdministration_Route_Name(GetAdminRoute());
str << "\n\tAdministration Route: " << eSubstanceAdministration_Route_Name(GetAdminRoute());
str << "\n\tAdministration Duration: "; HasAdminDuration() ? str << *m_AdminDuration : str << "No Administration Duration Set";
str << "\n\tDose: "; HasDose()? str << *m_Dose : str << "No Dose Set";
str << "\n\tConcentration: "; HasConcentration()? str << *m_Concentration : str << "NaN";
str << std::flush;
}
......
......@@ -43,6 +43,10 @@ public:
virtual eSubstanceAdministration_Route GetAdminRoute() const;
virtual void SetAdminRoute(eSubstanceAdministration_Route name);
virtual bool HasAdminDuration() const;
virtual SEScalarTime& GetAdminDuration();
virtual double GetAdminDuration(const TimeUnit& unit) const;
virtual bool HasConcentration() const;
virtual SEScalarMassPerVolume& GetConcentration();
virtual double GetConcentration(const MassPerVolumeUnit& unit) const;
......@@ -60,11 +64,10 @@ public:
virtual void ToString(std::ostream &str) const;
protected:
const SESubstance& m_Substance;
eSubstanceAdministration_Route m_AdminRoute;
SEScalarTime* m_AdminDuration;
SEScalarMassPerVolume* m_Concentration;
SEScalarVolume* m_Dose;
const SESubstance& m_Substance;
SESubstanceBolusState m_State;
};
};
......@@ -198,7 +198,7 @@ void Drugs::AdministerSubstanceBolus()
double dose_mL;
double concentration_ugPermL;
double massIncrement_ug = 0;
double administrationTime_s = 2; //administer dose over 2 seconds for a bolus dose
double administrationTime_s;
for (auto b : boluses)
{
......@@ -222,7 +222,7 @@ void Drugs::AdministerSubstanceBolus()
subQ = m_venaCavaVascular->GetSubstanceQuantity(*sub);
break;
case eSubstanceAdministration_Route::Intramuscular:
subQ = m_muscleIntracellular->GetSubstanceQuantity(*sub);
subQ = m_muscleIntracellular->GetSubstanceQuantity(*sub);
break;
default:
/// \error Error: Unavailable Administration Route
......@@ -230,8 +230,14 @@ void Drugs::AdministerSubstanceBolus()
completedBolus.push_back(b.first);// Remove it
continue;
}
concentration_ugPermL = bolus->GetConcentration().GetValue(MassPerVolumeUnit::ug_Per_mL);
if (!bolus->HasAdminDuration())
{
bolus->GetAdminDuration().SetValue(2, TimeUnit::s);
Info("Defaulting bolus administration duration of " + sub->GetName() + " to 2s");
}
administrationTime_s = bolus->GetAdminDuration(TimeUnit::s);
concentration_ugPermL = bolus->GetConcentration(MassPerVolumeUnit::ug_Per_mL);
massIncrement_ug = dose_mL*concentration_ugPermL*m_dt_s / administrationTime_s;
bolusState->GetElapsedTime().IncrementValue(m_dt_s, TimeUnit::s);
bolusState->GetAdministeredDose().IncrementValue(massIncrement_ug / concentration_ugPermL,VolumeUnit::mL);
......
......@@ -20,6 +20,7 @@ namespace Pulse.CDM
}
protected eAdministration admin_route;
protected SEScalarTime admin_duration;
protected SEScalarMassPerVolume concentration;
protected SEScalarVolume dose;
protected string substance;
......@@ -27,6 +28,7 @@ namespace Pulse.CDM
public SESubstanceBolus()
{
this.admin_route = eAdministration.Intravenous;
this.admin_duration = null;
this.dose = null;
this.concentration = null;
this.substance = null;
......@@ -37,6 +39,8 @@ namespace Pulse.CDM
base.Clear();
substance = null;
admin_route = eAdministration.Intravenous;
if (admin_duration != null)
admin_duration.Invalidate();
if (dose != null)
dose.Invalidate();
if (concentration != null)
......@@ -57,6 +61,17 @@ namespace Pulse.CDM
this.admin_route = adminRoute;
}
public bool HasAdminDuration()
{
return admin_duration == null ? false : admin_duration.IsValid();
}
public SEScalarTime GetAdminDuration()
{
if (admin_duration == null)
admin_duration = new SEScalarTime();
return admin_duration;
}
public bool HasConcentration()
{
return concentration == null ? false : concentration.IsValid();
......
......@@ -5,14 +5,14 @@ package com.kitware.pulse.cdm.patient.actions;
import com.kitware.pulse.cdm.bind.PatientActions.SubstanceBolusData;
import com.kitware.pulse.cdm.bind.PatientActions.SubstanceBolusData.eRoute;
import com.kitware.pulse.cdm.properties.SEScalarMassPerVolume;
import com.kitware.pulse.cdm.properties.SEScalarVolume;
import com.kitware.pulse.cdm.properties.*;
public class SESubstanceBolus extends SEPatientAction
{
private static final long serialVersionUID = -2177347285157137770L;
protected eRoute adminRoute;
protected SEScalarTime adminDuration;
protected SEScalarMassPerVolume concentration;
protected SEScalarVolume dose;
protected String substance;
......@@ -20,6 +20,7 @@ public class SESubstanceBolus extends SEPatientAction
public SESubstanceBolus()
{
this.adminRoute = null;
this.adminDuration = null;
this.dose = null;
this.concentration = null;
this.substance = "";
......@@ -30,8 +31,13 @@ public class SESubstanceBolus extends SEPatientAction
if(this==other)
return;
super.copy(other);
adminRoute = other.adminRoute;
substance = other.substance;
adminRoute = other.adminRoute;
if (other.adminDuration != null)
getAdministrationDuration().set(other.getAdministrationDuration());
else if (adminDuration != null)
adminDuration.invalidate();
if (other.dose != null)
getDose().set(other.getDose());
......@@ -49,6 +55,8 @@ public class SESubstanceBolus extends SEPatientAction
{
super.reset();
adminRoute = null;
if (adminDuration != null)
adminDuration.invalidate();
if (dose != null)
dose.invalidate();
if (concentration != null)
......@@ -65,6 +73,8 @@ public class SESubstanceBolus extends SEPatientAction
{
SEPatientAction.load(src.getPatientAction(), dst);
dst.setSubstance(src.getSubstance());
if(src.hasAdministrationDuration())
SEScalarTime.load(src.getAdministrationDuration(),dst.getAdministrationDuration());
if(src.hasDose())
SEScalarVolume.load(src.getDose(),dst.getDose());
if(src.hasConcentration())
......@@ -83,6 +93,8 @@ public class SESubstanceBolus extends SEPatientAction
protected static void unload(SESubstanceBolus src, SubstanceBolusData.Builder dst)
{
SEPatientAction.unload(src,dst.getPatientActionBuilder());
if (src.hasAdministrationDuration())
dst.setAdministrationDuration(SEScalarTime.unload(src.adminDuration));
if (src.hasDose())
dst.setDose(SEScalarVolume.unload(src.dose));
if (src.hasConcentration())
......@@ -106,6 +118,17 @@ public class SESubstanceBolus extends SEPatientAction
return adminRoute == null ? false : true;
}
public boolean hasAdministrationDuration()
{
return adminDuration == null ? false : adminDuration.isValid();
}
public SEScalarTime getAdministrationDuration()
{
if (adminDuration == null)
adminDuration = new SEScalarTime();
return adminDuration;
}
public boolean hasConcentration()
{
return concentration == null ? false : concentration.isValid();
......@@ -147,7 +170,8 @@ public class SESubstanceBolus extends SEPatientAction
+ "\n\tDose: " + getDose()
+ "\n\tConcentration: " + getConcentration()
+ "\n\tSubstance: " + getSubstance()
+ "\n\tAdministration Route: " + getAdministrationRoute();
+ "\n\tAdministration Route: " + getAdministrationRoute()
+ "\n\tAdministration Duration: " + getAdministrationDuration();
else
return "Action not specified properly";
}
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (python)" project-jdk-type="Python SDK" />
<component name="PythonCompatibilityInspectionAdvertiser">
<option name="version" value="3" />
</component>
......
......@@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Python 3.7 (python)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
......
......@@ -371,6 +371,8 @@ def serialize_respiratory_fatigue_from_bind(src: RespiratoryFatigueData, dst: SE
def serialize_substance_bolus_to_bind(src:SESubstanceBolus, dst: SubstanceBolusData):
serialize_patient_action_to_bind(src, dst.PatientAction)
if src.has_admin_duration():
serialize_scalar_time_to_bind(src.get_admin_duration(), dst.AdministrationDuration)
if src.has_concentration():
serialize_scalar_mass_per_volume_to_bind(src.get_concentration(), dst.Concentration)
if src.has_dose():
......
......@@ -992,11 +992,12 @@ class eSubstance_Administration(Enum):
Subcutaneous = 9
class SESubstanceBolus(SEPatientAction):
__slots__ = ["_admin_route", "_concentration", "_dose", "_substance"]
__slots__ = ["_admin_route", "_admin_duration", "_concentration", "_dose", "_substance"]
def __init__(self):
super().__init__()
self._admin_route = eSubstance_Administration.Intravenous
self._admin_duration = None
self._dose = None
self._concentration = None
self._substance = None
......@@ -1004,6 +1005,8 @@ class SESubstanceBolus(SEPatientAction):
def clear(self):
super().clear()
self._admin_route = eSubstance_Administration.Intravenous
if self._admin_duration is not None:
self._admin_duration.invalidate()
if self._dose is not None:
self._dose.invalidate()
if self._concentration is not None:
......@@ -1021,11 +1024,17 @@ class SESubstanceBolus(SEPatientAction):
def get_admin_route(self):
return self._admin_route
def get_admin_duration(self):
if self._admin_duration is None:
self._admin_duration = SEScalarTime()
return self._admin_duration
def has_admin_duration(self):
return self._admin_duration is not None
def get_concentration(self):
if self._concentration is None:
self._concentration = SEScalarMassPerVolume()
return self._concentration
def has_concentration(self):
return self._concentration is not None
......@@ -1044,9 +1053,12 @@ class SESubstanceBolus(SEPatientAction):
self._substance = substance
def __repr__(self):
return ("Substance Bolus\n"
" Administration Route: {}\n"
" Administration Duration: {}\n"
" Concentration: {}\n"
" Dose: {}\n"
" Substance: {}").format(self._concentration, self._dose, self._substance)
" Substance: {}").format(self._admin_route, self._admin_duration,
self._concentration, self._dose, self._substance)
class SESubstanceCompoundInfusion(SEPatientAction):
__slots__ = ["_bag_volume", "_rate", "_compound"]
......
......@@ -3,7 +3,7 @@
from pulse.cdm.engine import eSerializationFormat
from pulse.cdm.patient_actions import SESubstanceBolus, eSubstance_Administration
from pulse.cdm.scalars import MassPerVolumeUnit, VolumeUnit
from pulse.cdm.scalars import TimeUnit, MassPerVolumeUnit, VolumeUnit
from pulse.cpm.PulsePhysiologyEngine import PulsePhysiologyEngine
def HowTo_SubstanceBolus():
......@@ -21,13 +21,14 @@ def HowTo_SubstanceBolus():
print(results)
# Perform an action
substance = SESubstanceBolus()
substance.set_comment("Patient receives injection of Epinephrine")
substance.set_admin_route(eSubstance_Administration.Intramuscular)
substance.set_substance("Epinephrine")
substance.get_dose().set_value(1.0, VolumeUnit.mL)
substance.get_concentration().set_value(1.1, MassPerVolumeUnit.from_string("ug/L"))
pulse.process_action(substance)
bolus = SESubstanceBolus()
bolus.set_comment("Patient receives injection of Epinephrine")
bolus.set_admin_route(eSubstance_Administration.Intramuscular)
# bolus.get_admin_duration().set_value(2, TimeUnit.s) (optional)
bolus.set_substance("Epinephrine")
bolus.get_dose().set_value(1.0, VolumeUnit.mL)
bolus.get_concentration().set_value(1.1, MassPerVolumeUnit.ug_Per_L)
pulse.process_action(bolus)
# Advance some time and print out the vitals
pulse.advance_time_s(30)
......
......@@ -342,11 +342,12 @@ message SubstanceBolusData
}
PatientActionData PatientAction = 1;
eRoute AdministrationRoute = 2;/**<<@brief @ref SubstanceBolusData_eRouteTable */
string Substance = 3;/**<<@brief @ref SubstanceTable */
ScalarMassPerVolumeData Concentration = 4;/**<<@brief Concentration of the dose to administer. */
ScalarVolumeData Dose = 5;/**<<@brief Volume of dose to administer. */
SubstanceBolusStateData State = 6;/**<<@brief Current state of the bolus. */
string Substance = 2;/**<<@brief @ref SubstanceTable */
eRoute AdministrationRoute = 3;/**<<@brief @ref SubstanceBolusData_eRouteTable */
ScalarTimeData AdministrationDuration = 4;/**<<@brief Length of time taken to fully administer the bolus. */
ScalarMassPerVolumeData Concentration = 5;/**<<@brief Concentration of the dose to administer. */
ScalarVolumeData Dose = 6;/**<<@brief Volume of dose to administer. */
SubstanceBolusStateData State = 7;/**<<@brief Current state of the bolus. */
}
/** @brief Continuous injection of a compound. */
......
Markdown is supported
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