rama creada apartir de master en j
This commit is contained in:
@@ -11,6 +11,13 @@ using MongoDB.Bson;
|
||||
|
||||
namespace adas_core.Application.Customizations.HRYC;
|
||||
|
||||
/// <summary>
|
||||
/// Implements the HRYC-specific clinical calculations that derive secondary
|
||||
/// <see cref="PatientObservation"/> values (NEWS alarms, IROX, Resp_Rate_Calculated, Hydric_Balance_Calculated,
|
||||
/// Weight_Diff, Diuresis_Weight, Delta_Pressure, Daily_Balance_Calculated, Allergies, DVE, Drainage_Height,
|
||||
/// Resp_Type, and Hour_Balance) from incoming raw observations and active configurations loaded from
|
||||
/// <see cref="ApiSettings"/>.
|
||||
/// </summary>
|
||||
public class CalculatedObservations : ICalculatedObservations
|
||||
{
|
||||
private readonly IOptions<ApiSettings> _apiSettings;
|
||||
@@ -27,6 +34,14 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
private readonly Lazy<IPatientService> _patientService;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CalculatedObservations"/> class,
|
||||
/// resolving its dependencies (observation, patient, light-beacon, and config-observation services,
|
||||
/// plus the logger) from the supplied <see cref="IServiceProvider"/> and loading the configured
|
||||
/// code catalogues (high-frequency ventilation, non-invasive ventilation, and invasive ventilation)
|
||||
/// from <see cref="ApiSettings"/>.
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">The application's service provider used to resolve the required dependencies and configuration.</param>
|
||||
public CalculatedObservations(IServiceProvider serviceProvider)
|
||||
{
|
||||
_observationService = serviceProvider.GetRequiredService<Lazy<IObservationService>>(); //observationService;
|
||||
@@ -52,6 +67,25 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Dispatches the supplied raw observation to the appropriate HRYC calculation based on its
|
||||
/// <see cref="BasePatientObservation.Name"/>. The set of supported calculations includes
|
||||
/// <c>Resp_Mode</c> (ventilation type), <c>Diuresis</c> / <c>Weight_Current</c>
|
||||
/// (weight difference and diuresis-per-kilogram), <c>AllergiesObs</c>, <c>DrainagesObs</c>,
|
||||
/// <c>PEEP</c> / <c>Pleateu_Pressure</c> (driving pressure), <c>Daily_Balance</c>,
|
||||
/// <c>Hydric_Balance</c> / <c>Hour_Balance</c> (time shifting), <c>FR</c> / <c>Vent_Rate</c>
|
||||
/// (respiratory rate), <c>SpO2</c> / <c>FiO2</c> (IROX), and <c>NEWS</c> (alarms).
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The concrete observation type, deriving from <see cref="BasePatientObservation"/>.</typeparam>
|
||||
/// <param name="obs">The observation to map or transform in-place.</param>
|
||||
/// <param name="onlyByName">
|
||||
/// Reserved for future use. When <see langword="true"/>, restricts the mapping strategy to
|
||||
/// name-based lookups only.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task{T}"/> that resolves to the (possibly transformed) observation,
|
||||
/// or <see langword="null"/> when the input observation has no name.
|
||||
/// </returns>
|
||||
public async Task<T?> Map<T>(T obs, bool onlyByName) where T : BasePatientObservation
|
||||
{
|
||||
_logger.LogTrace("Mapping {name} observation {obs}", obs.Name, obs);
|
||||
@@ -107,40 +141,89 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Placeholder mapping for a <see cref="PatientTreatment"/>. The HRYC customization does not
|
||||
/// currently derive observations from treatments.
|
||||
/// </summary>
|
||||
/// <param name="treatment">The treatment to map.</param>
|
||||
/// <returns>Never returns a result.</returns>
|
||||
/// <exception cref="NotImplementedException">Always thrown because treatment mapping is not implemented in the HRYC customization.</exception>
|
||||
public Task<PatientTreatment> Map(PatientTreatment treatment)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Identity mapping for a <see cref="PumpObservation"/>: returns the supplied instance unchanged,
|
||||
/// wrapped in a completed task. Provided to satisfy the customization contract; pump observations
|
||||
/// do not require HRYC-specific calculation.
|
||||
/// </summary>
|
||||
/// <param name="pumpObservation">The pump observation to map.</param>
|
||||
/// <returns>A task containing the same <see cref="PumpObservation"/> instance that was passed in.</returns>
|
||||
public async Task<PumpObservation> Map(PumpObservation pumpObservation)
|
||||
{
|
||||
return await Task.FromResult(pumpObservation);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No-op implementation of the medicine-observation calculation hook. The HRYC customization does
|
||||
/// not derive Medication or ERMedication observations from the active medicine list.
|
||||
/// </summary>
|
||||
/// <param name="activeMedicines">The list of active medicines (ignored).</param>
|
||||
/// <param name="patientId">The unique identifier of the patient (ignored).</param>
|
||||
/// <returns>A completed task.</returns>
|
||||
public Task CalculateMedicineObservation(List<Medicine> activeMedicines, ObjectId patientId)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No-op implementation of the active-bolus calculation hook. The HRYC customization does not
|
||||
/// derive an OpiateBoluses observation.
|
||||
/// </summary>
|
||||
/// <param name="patientId">The unique identifier of the patient (ignored).</param>
|
||||
/// <returns>A completed task.</returns>
|
||||
public Task CalculateActiveBolus(ObjectId patientId)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an empty enumerable of active treatments. The HRYC customization does not currently
|
||||
/// maintain a per-patient active-treatment cache.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the patient (ignored).</param>
|
||||
/// <returns>A completed task containing an empty <see cref="IEnumerable{PatientTreatment}"/>.</returns>
|
||||
public Task<IEnumerable<PatientTreatment?>> GetActiveTreatmentsByPatient(ObjectId id)
|
||||
{
|
||||
return Task.FromResult(new List<PatientTreatment?>().AsEnumerable());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identity mapping for a <see cref="PatientDiagnosis"/>: returns the supplied instance unchanged,
|
||||
/// wrapped in a completed task. Provided to satisfy the customization contract.
|
||||
/// </summary>
|
||||
/// <param name="diagnosis">The <see cref="PatientDiagnosis"/> to map.</param>
|
||||
/// <returns>A task containing the same <see cref="PatientDiagnosis"/> instance that was passed in.</returns>
|
||||
public Task<PatientDiagnosis> Map(PatientDiagnosis diagnosis)
|
||||
{
|
||||
return Task.FromResult(diagnosis);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resolves time-inconsistencies for a new patient observation when it arrives with the same
|
||||
/// (down-to-the-second) timestamp as the latest stored observation of the same name. The new
|
||||
/// observation's <c>Time</c> is shifted forward by one second to avoid duplicate-key collisions.
|
||||
/// </summary>
|
||||
/// <param name="newObservation">The new patient observation to evaluate for time inconsistencies.</param>
|
||||
/// <returns>
|
||||
/// A task that resolves to the (possibly time-shifted) <see cref="PatientObservation"/>.
|
||||
/// Returns the input unchanged when its <c>Name</c> is null or empty, logging the error.
|
||||
/// </returns>
|
||||
public async Task<PatientObservation?> FixTimeInconsistencyWithLast(PatientObservation newObservation)
|
||||
{
|
||||
if (string.IsNullOrEmpty(newObservation.Name))
|
||||
@@ -168,6 +251,17 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
return newObservation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pre-maps a batch of patient observations, optimising the order in which they are persisted
|
||||
/// when both <c>Vent_Rate</c> and <c>FR</c> are present. If both observations are present with
|
||||
/// non-zero values, <c>Vent_Rate</c> is inserted first (and removed from the returned list) so
|
||||
/// that <see cref="CalculateRespRate"/> can derive <c>Resp_Rate_Calculated</c> correctly.
|
||||
/// </summary>
|
||||
/// <param name="listToInsert">The list of patient observations to pre-map. Modified in-place.</param>
|
||||
/// <returns>
|
||||
/// A task that resolves to the resulting list of observations (with <c>Vent_Rate</c> removed
|
||||
/// when it was inserted synchronously, or the original list otherwise).
|
||||
/// </returns>
|
||||
public async Task<List<PatientObservation>> PreMapList(List<PatientObservation> listToInsert)
|
||||
{
|
||||
var ventRate = listToInsert.FirstOrDefault(obs => obs.Name == "MDC_VENT_RESP_RATE");
|
||||
@@ -210,20 +304,41 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
return listToInsert;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identity mapping for a source alarm observation paired with a <see cref="PatientObservationAlarm"/>:
|
||||
/// returns the supplied observation unchanged, wrapped in a completed task. Provided to satisfy the
|
||||
/// customization contract.
|
||||
/// </summary>
|
||||
/// <param name="obs">The patient observation that triggered the alarm.</param>
|
||||
/// <param name="alarmToInsert">The alarm metadata to be inserted alongside the observation.</param>
|
||||
/// <returns>A task containing the same <see cref="PatientObservation"/> instance that was passed in.</returns>
|
||||
public Task<PatientObservation> MapSourceAlarm(PatientObservation obs, PatientObservationAlarm alarmToInsert)
|
||||
{
|
||||
return Task.FromResult(obs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Placeholder alarm dispatch hook used by the customization contract. The HRYC customization
|
||||
/// dispatches NEWS alarms through its private <c>SendAlarm(BasePatientObservation, AlarmEnum.Name)</c>
|
||||
/// overload; calling this public overload always throws.
|
||||
/// </summary>
|
||||
/// <param name="obs">The patient observation that triggered the alarm.</param>
|
||||
/// <param name="name">The alarm display name.</param>
|
||||
/// <param name="code">The optional alarm code from <see cref="AlarmEnum.Name"/>.</param>
|
||||
/// <returns>Never returns a result.</returns>
|
||||
/// <exception cref="NotImplementedException">Always thrown because this overload is not used in the HRYC customization.</exception>
|
||||
public Task SendAlarm(PatientObservation obs, string name, AlarmEnum.Name? code)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IF news greater or equal than 5 and less than 7 is warning beacon and if greater or equal than 7 alert
|
||||
/// Translates a NEWS (National Early Warning Score) value into an alarm level: a value below 5
|
||||
/// (or an unparsable value) is reported as <c>NewsOff</c>, between 5 and 7 as <c>NewsWarning</c>,
|
||||
/// and 7 or above as <c>NewsAlert</c>. Returns early when the patient cannot be located.
|
||||
/// </summary>
|
||||
/// <param name="obs"></param>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> whose <c>Name</c> is <c>NEWS</c>.</param>
|
||||
/// <returns>A task that represents the asynchronous alarm evaluation.</returns>
|
||||
private async Task CalculateNews(BasePatientObservation obs)
|
||||
{
|
||||
var pobs = (PatientObservation)obs;
|
||||
@@ -258,6 +373,15 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
//if (obsAlarm == null) return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a synthetic <c>Alarm_<Name></c> observation, looks up its configuration, and when
|
||||
/// the configured alarm and its beacon are enabled, dispatches a light-beacon colour change for
|
||||
/// the patient's point-of-care. The alarm observation is always persisted. Errors are logged and
|
||||
/// swallowed.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the alarm (used to derive <c>PatientId</c> and <c>Time</c>).</param>
|
||||
/// <param name="name">The <see cref="AlarmEnum.Name"/> describing the alarm kind (for example, <c>NewsOff</c>, <c>NewsWarning</c>, <c>NewsAlert</c>).</param>
|
||||
/// <returns>A task that represents the asynchronous alarm dispatch.</returns>
|
||||
private async Task SendAlarm(BasePatientObservation obs, AlarmEnum.Name name)
|
||||
{
|
||||
var pobs = (PatientObservation)obs;
|
||||
@@ -273,10 +397,10 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
{
|
||||
//ConfigObservations
|
||||
var configObs = await _configObservationService.Get(new PatientObservation
|
||||
{
|
||||
Name = nObs.Name,
|
||||
PatientId = obs.PatientId
|
||||
}
|
||||
{
|
||||
Name = nObs.Name,
|
||||
PatientId = obs.PatientId
|
||||
}
|
||||
);
|
||||
if (configObs == null)
|
||||
{
|
||||
@@ -313,6 +437,13 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a colour command to the light beacon associated with the patient's point-of-care.
|
||||
/// Maps <see cref="AlarmEnum.BeaconColor"/> values to <see cref="LightBeaconColor"/> commands
|
||||
/// (blue, yellow, red, or off) and logs an error when the patient has no point-of-care identifier.
|
||||
/// </summary>
|
||||
/// <param name="color">The beacon colour to apply.</param>
|
||||
/// <param name="patient">The patient whose associated beacon should be updated.</param>
|
||||
private void SendBeaconCode(AlarmEnum.BeaconColor color, Patient patient)
|
||||
{
|
||||
if (!patient.PointOfCareId.HasValue)
|
||||
@@ -339,7 +470,14 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
//(SpO2/FiO2)/FR IROX formula. Only calculate when all observations are in last 10 minutes.
|
||||
/// <summary>
|
||||
/// Computes the IROX index (<c>SpO2 / FiO2 / FR</c>) when <c>SpO2</c>, <c>FiO2</c>, and <c>FR</c>
|
||||
/// are all present in the latest observations and were recorded within the last 10 minutes.
|
||||
/// Persists the resulting <c>IROX</c> observation. Skips silently when any input is missing,
|
||||
/// zero, or unparsable. Errors are logged and swallowed.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation (<c>SpO2</c>, <c>FiO2</c>, or <c>FR</c>).</param>
|
||||
/// <returns>A task that represents the asynchronous calculation operation.</returns>
|
||||
private async Task CalculateIrox(BasePatientObservation obs)
|
||||
{
|
||||
try
|
||||
@@ -412,13 +550,16 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
RespRate solo se tiene que poner cuando no hay ningún ventRate en los últimos min y veinte segundos y el último no es un 0.
|
||||
|
||||
*/
|
||||
|
||||
//static readonly SemaphoreSlim semaphoreCalculateRespRate = new(1, 1);
|
||||
/// <summary>
|
||||
/// Persists a <c>Resp_Rate_Calculated</c> observation when the supplied observation's value is
|
||||
/// non-zero. For <c>FR</c>, the insert is skipped if a recent (within
|
||||
/// <c>CalculateRespRateVentExpires</c> minutes) non-zero <c>Vent_Rate</c> observation exists;
|
||||
/// the inserted observation's <c>Time</c> is set to the original <c>Time</c> for <c>FR</c>, or
|
||||
/// shifted one second forward for any other name.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation (<c>FR</c> or <c>Vent_Rate</c>).</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateRespRate(BasePatientObservation obs)
|
||||
{
|
||||
var pobs = (PatientObservation)obs;
|
||||
@@ -479,6 +620,13 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
obs.Name, obs.Time, pobs.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shifts the timestamp of a <c>Hydric_Balance</c> observation forward by one second when another
|
||||
/// <c>Hydric_Balance</c> observation was already recorded within the same hour, so the most
|
||||
/// recent entry can be identified unambiguously.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Hydric_Balance</c>.</param>
|
||||
/// <returns>A task that resolves to the (possibly time-shifted) base patient observation.</returns>
|
||||
private async Task<BasePatientObservation> CalculateHydricBalance(BasePatientObservation obs)
|
||||
{
|
||||
var pobs = (PatientObservation)obs;
|
||||
@@ -496,6 +644,12 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
return obs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shifts the timestamp of a <c>Hour_Balance</c> observation forward by one second when another
|
||||
/// <c>Hour_Balance</c> observation was already recorded within the same hour.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Hour_Balance</c>.</param>
|
||||
/// <returns>A task that resolves to the (possibly time-shifted) base patient observation.</returns>
|
||||
private async Task<BasePatientObservation> CalculateHourBalance(BasePatientObservation obs)
|
||||
{
|
||||
var pobs = (PatientObservation)obs;
|
||||
@@ -513,6 +667,16 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
return obs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Persists a <c>Hydric_Balance_Calculated</c> observation mirroring the supplied
|
||||
/// <c>Hydric_Balance</c> value, after enforcing three guards: the observation's hour must not be
|
||||
/// in the future, the latest <c>Hydric_Balance_Calculated</c> for the current hour prevents
|
||||
/// replaying older hours, and a newer stored <c>Hydric_Balance_Calculated</c> prevents
|
||||
/// overwriting it. The stored time is shifted one second forward when an existing calculated
|
||||
/// observation in the same hour is detected.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Hydric_Balance</c>.</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateHydricBalanceCalculated(BasePatientObservation obs)
|
||||
{
|
||||
//Hydric_Balance_Calculated
|
||||
@@ -580,6 +744,15 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
await _observationService.Value.InsertObservation(calculatedHydricBalance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a <c>Resp_Mode</c> observation to a <c>Resp_Type</c> value: codes listed in
|
||||
/// <c>InvasiveVentilation</c> yield <c>Invasive</c>, otherwise the observation's value is matched
|
||||
/// against the configured high-frequency / non-invasive catalogues (yielding
|
||||
/// <c>HighFrequencyVentilation</c>, <c>NonInvasive</c>, or <c>Invasive</c> as fallback). Values
|
||||
/// equal to <c>"EnESPERA"</c> are skipped.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Resp_Mode</c>.</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateVentilationMode(BasePatientObservation obs)
|
||||
{
|
||||
_logger.LogDebug("CalculateVentilationMode {obs}", obs);
|
||||
@@ -620,6 +793,13 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the <c>Weight_Diff</c> observation (new weight − previous weight, rounded to two
|
||||
/// decimals) by comparing the supplied <c>Weight_Current</c> observation against the most
|
||||
/// recently stored one for the same patient. Skipped when either value cannot be parsed.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Weight_Current</c>.</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateWeight_DiffObservation(BasePatientObservation obs)
|
||||
{
|
||||
var toSearchList = new List<string>();
|
||||
@@ -651,6 +831,14 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the <c>Diuresis_Weight</c> observation (diuresis / current weight in ml/kg) when
|
||||
/// either a <c>Diuresis</c> or a <c>Weight_Current</c> observation is received. When triggered
|
||||
/// by <c>Weight_Current</c>, the operation is skipped if the latest <c>Diuresis</c> observation
|
||||
/// has expired. Skipped silently when the weight is zero or any value is unparsable.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation (<c>Diuresis</c> or <c>Weight_Current</c>).</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateDiureis_WeightObservation(BasePatientObservation obs)
|
||||
{
|
||||
var toSearchList = new List<string>();
|
||||
@@ -695,6 +883,14 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggregates a <c>AllergiesObs</c> observation into a single <c>Allergies</c> string per type,
|
||||
/// special-casing drug allergies ("FÁRMACOS") into a single grouped entry and setting the
|
||||
/// <c>Status</c> to <c>Alert</c> when drug allergies are present. <c>InvalidCastException</c>s
|
||||
/// are logged and swallowed.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>AllergiesObs</c> and a collection-valued <c>Value</c> of <see cref="PatientAllergiesValue"/>.</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateAllergiesObservation(BasePatientObservation obs)
|
||||
{
|
||||
try
|
||||
@@ -764,6 +960,13 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For a <c>DrainagesObs</c> observation of type <c>"Drenaje ventricular"</c>, persists the
|
||||
/// derived <c>DVE</c> (volume) and <c>Drainage_Height</c> observations using the underlying
|
||||
/// <see cref="PatientDrainagesValue"/> properties.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>DrainagesObs</c> and a <see cref="PatientDrainagesValue"/>-typed <c>Value</c>.</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateDrainagesObservation(BasePatientObservation obs)
|
||||
{
|
||||
var pobs = (PatientObservation)obs;
|
||||
@@ -803,6 +1006,13 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the <c>Delta_Pressure</c> observation (driving pressure = plateau − PEEP) when both
|
||||
/// <c>PEEP</c> and <c>Pleateu_Pressure</c> observations are available. The stored <c>Time</c> is
|
||||
/// the most recent of the two source observations, so the result is anchored to the latest input.
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation (<c>PEEP</c> or <c>Pleateu_Pressure</c>).</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateDelta_PressureObservation(BasePatientObservation obs)
|
||||
{
|
||||
var toSearchList = new List<string>();
|
||||
@@ -854,6 +1064,13 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Persists a <c>Daily_Balance_Calculated</c> observation mirroring the supplied
|
||||
/// <c>Daily_Balance</c> value, but only when the local hour of the observation is 8 (the daily
|
||||
/// balance cut-off used by the HRYC customization).
|
||||
/// </summary>
|
||||
/// <param name="obs">The base patient observation that triggered the calculation, expected to be a <see cref="PatientObservation"/> with <c>Name</c> <c>Daily_Balance</c>.</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
private async Task CalculateDaily_BalanceObservation(BasePatientObservation obs)
|
||||
{
|
||||
if (obs.Time.ToLocalTime().Hour == 8)
|
||||
@@ -872,6 +1089,15 @@ public class CalculatedObservations : ICalculatedObservations
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a patient observation has expired by comparing the current time against
|
||||
/// <c>Time + Expires</c> seconds, when <c>Expires</c> is set.
|
||||
/// </summary>
|
||||
/// <param name="obs">The patient observation to evaluate.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> when the observation has an <c>Expires</c> value and the current time
|
||||
/// is past the expiration instant; otherwise, <see langword="false"/>.
|
||||
/// </returns>
|
||||
private static bool CheckExpired(PatientObservation obs)
|
||||
{
|
||||
if (obs.Expires == null) return false;
|
||||
|
||||
Reference in New Issue
Block a user