Skip to content

Commit a0c1752

Browse files
HenrZujubicker
andauthored
1508 (ODE) implement possibility of death from hospitalization without intensive care (#1526)
Co-authored-by: jubicker <113909589+jubicker@users.noreply.github.com>
1 parent 6ac09dd commit a0c1752

12 files changed

Lines changed: 408 additions & 25 deletions

File tree

cpp/models/ode_secir/model.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,12 @@ class Model : public FlowModel<FP, InfectionState, Populations<FP, AgeGroup, Inf
196196
flows[this->template get_flat_flow_index<InfectionState::InfectedSevere, InfectionState::InfectedCritical>(
197197
{i})] = criticalPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevi];
198198
flows[this->template get_flat_flow_index<InfectionState::InfectedSevere, InfectionState::Recovered>({i})] =
199-
(1.0 - params.template get<CriticalPerSevere<FP>>()[i]) /
199+
(1.0 - params.template get<CriticalPerSevere<FP>>()[i] -
200+
params.template get<DeathsPerSevere<FP>>()[i]) /
200201
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevi];
201202
flows[this->template get_flat_flow_index<InfectionState::InfectedSevere, InfectionState::Dead>({i})] =
202-
deathsPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevi];
203+
(params.template get<DeathsPerSevere<FP>>()[i] + deathsPerSevereAdjusted) /
204+
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevi];
203205

204206
// InfectedCritical -> Dead / Recovered
205207
flows[this->template get_flat_flow_index<InfectionState::InfectedCritical, InfectionState::Dead>({i})] =
@@ -678,8 +680,8 @@ auto get_mobility_factors(const Simulation<FP, Base>& sim, FP /*t*/, const Eigen
678680
auto test_and_trace_capacity = FP(params.template get<TestAndTraceCapacity<FP>>());
679681
auto test_and_trace_capacity_max_risk = FP(params.template get<TestAndTraceCapacityMaxRisk<FP>>());
680682
auto riskFromInfectedSymptomatic = smoother_cosine<FP>(test_and_trace_required, test_and_trace_capacity,
681-
test_and_trace_capacity * test_and_trace_capacity_max_risk,
682-
p_inf.matrix(), p_inf_max.matrix());
683+
test_and_trace_capacity * test_and_trace_capacity_max_risk,
684+
p_inf.matrix(), p_inf_max.matrix());
683685

684686
//set factor for infected
685687
auto factors = Eigen::VectorX<FP>::Ones(y.rows()).eval();

cpp/models/ode_secir/parameters.h

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,24 @@ struct CriticalPerSevere {
285285
}
286286
};
287287

288+
/**
289+
* @brief the percentage of dead patients per hospitalized patients.
290+
* This is a direct mortality probability from the InfectedSevere compartment,
291+
* independent of ICU capacity.
292+
*/
293+
template <typename FP>
294+
struct DeathsPerSevere {
295+
using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
296+
static Type get_default(AgeGroup size)
297+
{
298+
return Type(size, 0.);
299+
}
300+
static std::string name()
301+
{
302+
return "DeathsPerSevere";
303+
}
304+
};
305+
288306
/**
289307
* @brief the percentage of dead patients per ICU patients in the SECIR model
290308
*/
@@ -389,7 +407,7 @@ using ParametersBase =
389407
TimeInfectedSevere<FP>, TimeInfectedCritical<FP>, TransmissionProbabilityOnContact<FP>,
390408
RelativeTransmissionNoSymptoms<FP>, RecoveredPerInfectedNoSymptoms<FP>,
391409
RiskOfInfectionFromSymptomatic<FP>, MaxRiskOfInfectionFromSymptomatic<FP>,
392-
SeverePerInfectedSymptoms<FP>, CriticalPerSevere<FP>, DeathsPerCritical<FP>>;
410+
SeverePerInfectedSymptoms<FP>, CriticalPerSevere<FP>, DeathsPerSevere<FP>, DeathsPerCritical<FP>>;
393411

394412
/**
395413
* @brief Parameters of an age-resolved SECIR/SECIHURD model.
@@ -605,6 +623,22 @@ class Parameters : public ParametersBase<FP>
605623
corrected = true;
606624
}
607625

626+
if (this->template get<DeathsPerSevere<FP>>()[i] < 0.0 ||
627+
this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
628+
log_warning("Constraint check: Parameter DeathsPerSevere changed from {} to {}",
629+
this->template get<DeathsPerSevere<FP>>()[i], 0);
630+
this->template get<DeathsPerSevere<FP>>()[i] = 0;
631+
corrected = true;
632+
}
633+
634+
if (this->template get<CriticalPerSevere<FP>>()[i] + this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
635+
log_warning("Constraint check: CriticalPerSevere + DeathsPerSevere exceed 1.0 for age group {}. "
636+
"DeathsPerSevere changed from {} to 0.",
637+
static_cast<size_t>(i), this->template get<DeathsPerSevere<FP>>()[i]);
638+
this->template get<DeathsPerSevere<FP>>()[i] = 0;
639+
corrected = true;
640+
}
641+
608642
if (this->template get<DeathsPerCritical<FP>>()[i] < 0.0 ||
609643
this->template get<DeathsPerCritical<FP>>()[i] > 1.0) {
610644
log_warning("Constraint check: Parameter DeathsPerCritical changed from {} to {}",
@@ -726,6 +760,18 @@ class Parameters : public ParametersBase<FP>
726760
return true;
727761
}
728762

763+
if (this->template get<DeathsPerSevere<FP>>()[i] < 0.0 ||
764+
this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
765+
log_error("Constraint check: Parameter DeathsPerSevere smaller {} or larger {}", 0, 1);
766+
return true;
767+
}
768+
769+
if (this->template get<CriticalPerSevere<FP>>()[i] + this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
770+
log_error("Constraint check: CriticalPerSevere + DeathsPerSevere exceed 1.0 for age group {}.",
771+
static_cast<size_t>(i));
772+
return true;
773+
}
774+
729775
if (this->template get<DeathsPerCritical<FP>>()[i] < 0.0 ||
730776
this->template get<DeathsPerCritical<FP>>()[i] > 1.0) {
731777
log_error("Constraint check: Parameter DeathsPerCritical smaller {} or larger {}", 0, 1);

cpp/models/ode_secirts/model.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,12 @@ class Model
386386

387387
flows[this->template get_flat_flow_index<InfectionState::InfectedSevereNaive,
388388
InfectionState::TemporaryImmunePartialImmunity>({i})] =
389-
(1 - params.template get<CriticalPerSevere<FP>>()[i]) /
389+
(1 - params.template get<CriticalPerSevere<FP>>()[i] - params.template get<DeathsPerSevere<FP>>()[i]) /
390390
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevNi];
391391

392392
flows[this->template get_flat_flow_index<InfectionState::InfectedSevereNaive, InfectionState::DeadNaive>(
393-
{i})] = deathsPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevNi];
393+
{i})] = (params.template get<DeathsPerSevere<FP>>()[i] + deathsPerSevereAdjusted) /
394+
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevNi];
394395
// InfectedCritical
395396
flows[this->template get_flat_flow_index<InfectionState::InfectedCriticalNaive, InfectionState::DeadNaive>(
396397
{i})] = params.template get<DeathsPerCritical<FP>>()[i] /
@@ -472,13 +473,15 @@ class Model
472473
flows[this->template get_flat_flow_index<InfectionState::InfectedSeverePartialImmunity,
473474
InfectionState::TemporaryImmuneImprovedImmunity>({i})] =
474475
(1 - (reducInfectedSevereCriticalDeadPartialImmunity / reducInfectedSevereCriticalDeadPartialImmunity) *
475-
params.template get<CriticalPerSevere<FP>>()[i]) /
476+
(params.template get<CriticalPerSevere<FP>>()[i] +
477+
params.template get<DeathsPerSevere<FP>>()[i])) /
476478
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevPIi];
477479

478480
flows[this->template get_flat_flow_index<InfectionState::InfectedSeverePartialImmunity,
479481
InfectionState::DeadPartialImmunity>({i})] =
480482
(reducInfectedSevereCriticalDeadPartialImmunity / reducInfectedSevereCriticalDeadPartialImmunity) *
481-
deathsPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevPIi];
483+
(params.template get<DeathsPerSevere<FP>>()[i] + deathsPerSevereAdjusted) /
484+
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevPIi];
482485
// InfectedCritical
483486
flows[this->template get_flat_flow_index<InfectionState::InfectedCriticalPartialImmunity,
484487
InfectionState::DeadPartialImmunity>({i})] =
@@ -555,13 +558,15 @@ class Model
555558
InfectionState::TemporaryImmuneImprovedImmunity>({i})] =
556559
(1 -
557560
(reducInfectedSevereCriticalDeadImprovedImmunity / reducInfectedSevereCriticalDeadImprovedImmunity) *
558-
params.template get<CriticalPerSevere<FP>>()[i]) /
561+
(params.template get<CriticalPerSevere<FP>>()[i] +
562+
params.template get<DeathsPerSevere<FP>>()[i])) /
559563
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevIIi];
560564

561565
flows[this->template get_flat_flow_index<InfectionState::InfectedSevereImprovedImmunity,
562566
InfectionState::DeadImprovedImmunity>({i})] =
563567
(reducInfectedSevereCriticalDeadImprovedImmunity / reducInfectedSevereCriticalDeadImprovedImmunity) *
564-
deathsPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevIIi];
568+
(params.template get<DeathsPerSevere<FP>>()[i] + deathsPerSevereAdjusted) /
569+
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevIIi];
565570

566571
// InfectedCritical
567572
flows[this->template get_flat_flow_index<InfectionState::InfectedCriticalImprovedImmunity,

cpp/models/ode_secirts/parameters.h

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,25 @@ struct CriticalPerSevere {
471471
}
472472
};
473473

474+
/**
475+
* @brief The percentage of dead patients per hospitalized patients.
476+
* This is a direct mortality probability from the InfectedSevere compartments,
477+
* independent of ICU capacity.
478+
* @tparam FP The floating-point type (default: double).
479+
*/
480+
template <typename FP>
481+
struct DeathsPerSevere {
482+
using Type = CustomIndexArray<UncertainValue<FP>, AgeGroup>;
483+
static Type get_default(AgeGroup size)
484+
{
485+
return Type(size, 0.);
486+
}
487+
static std::string name()
488+
{
489+
return "DeathsPerSevere";
490+
}
491+
};
492+
474493
/**
475494
* @brief The percentage of dead patients per ICU patients in the SECIRTS model.
476495
* @tparam FP The floating-point type (default: double).
@@ -751,7 +770,7 @@ using ParametersBase = ParameterSet<
751770
TimeWaningPartialImmunity<FP>, TimeWaningImprovedImmunity<FP>, TimeTemporaryImmunityPI<FP>,
752771
TimeTemporaryImmunityII<FP>, TransmissionProbabilityOnContact<FP>, RelativeTransmissionNoSymptoms<FP>,
753772
RecoveredPerInfectedNoSymptoms<FP>, RiskOfInfectionFromSymptomatic<FP>, MaxRiskOfInfectionFromSymptomatic<FP>,
754-
SeverePerInfectedSymptoms<FP>, CriticalPerSevere<FP>, DeathsPerCritical<FP>,
773+
SeverePerInfectedSymptoms<FP>, CriticalPerSevere<FP>, DeathsPerSevere<FP>, DeathsPerCritical<FP>,
755774
DaysUntilEffectivePartialVaccination<FP>, DaysUntilEffectiveImprovedVaccination<FP>,
756775
DaysUntilEffectiveBoosterImmunity<FP>, DailyFullVaccinations<FP>, DailyPartialVaccinations<FP>,
757776
DailyBoosterVaccinations<FP>, ReducExposedPartialImmunity<FP>, ReducExposedImprovedImmunity<FP>,
@@ -1019,6 +1038,22 @@ class Parameters : public ParametersBase<FP>
10191038
corrected = true;
10201039
}
10211040

1041+
if (this->template get<DeathsPerSevere<FP>>()[i] < 0.0 ||
1042+
this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
1043+
log_warning("Constraint check: Parameter DeathsPerSevere changed from {} to {}",
1044+
this->template get<DeathsPerSevere<FP>>()[i], 0);
1045+
this->template get<DeathsPerSevere<FP>>()[i] = 0;
1046+
corrected = true;
1047+
}
1048+
1049+
if (this->template get<CriticalPerSevere<FP>>()[i] + this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
1050+
log_warning("Constraint check: CriticalPerSevere + DeathsPerSevere exceed 1.0 for age group {}. "
1051+
"DeathsPerSevere changed from {} to 0.",
1052+
static_cast<size_t>(i), this->template get<DeathsPerSevere<FP>>()[i]);
1053+
this->template get<DeathsPerSevere<FP>>()[i] = 0;
1054+
corrected = true;
1055+
}
1056+
10221057
if (this->template get<DeathsPerCritical<FP>>()[i] < 0.0 ||
10231058
this->template get<DeathsPerCritical<FP>>()[i] > 1.0) {
10241059
log_warning("Constraint check: Parameter DeathsPerCritical changed from {} to {}",
@@ -1256,6 +1291,18 @@ class Parameters : public ParametersBase<FP>
12561291
return true;
12571292
}
12581293

1294+
if (this->template get<DeathsPerSevere<FP>>()[i] < 0.0 ||
1295+
this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
1296+
log_error("Constraint check: Parameter DeathsPerSevere smaller {} or larger {}", 0, 1);
1297+
return true;
1298+
}
1299+
1300+
if (this->template get<CriticalPerSevere<FP>>()[i] + this->template get<DeathsPerSevere<FP>>()[i] > 1.0) {
1301+
log_error("Constraint check: CriticalPerSevere + DeathsPerSevere exceed 1.0 for age group {}.",
1302+
static_cast<size_t>(i));
1303+
return true;
1304+
}
1305+
12591306
if (this->template get<DeathsPerCritical<FP>>()[i] < 0.0 ||
12601307
this->template get<DeathsPerCritical<FP>>()[i] > 1.0) {
12611308
log_error("Constraint check: Parameter DeathsPerCritical smaller {} or larger {}", 0, 1);

cpp/models/ode_secirvvs/model.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,11 +328,12 @@ class Model
328328

329329
flows[this->template get_flat_flow_index<InfectionState::InfectedSevereNaive,
330330
InfectionState::SusceptibleImprovedImmunity>({i})] =
331-
(1 - params.template get<CriticalPerSevere<FP>>()[i]) /
331+
(1 - params.template get<CriticalPerSevere<FP>>()[i] - params.template get<DeathsPerSevere<FP>>()[i]) /
332332
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevNi];
333333

334334
flows[this->template get_flat_flow_index<InfectionState::InfectedSevereNaive, InfectionState::DeadNaive>(
335-
{i})] = deathsPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevNi];
335+
{i})] = (params.template get<DeathsPerSevere<FP>>()[i] + deathsPerSevereAdjusted) /
336+
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevNi];
336337

337338
// InfectedCritical
338339
flows[this->template get_flat_flow_index<InfectionState::InfectedCriticalNaive, InfectionState::DeadNaive>(
@@ -406,13 +407,15 @@ class Model
406407
flows[this->template get_flat_flow_index<InfectionState::InfectedSeverePartialImmunity,
407408
InfectionState::SusceptibleImprovedImmunity>({i})] =
408409
(1 - (reducInfectedSevereCriticalDeadPartialImmunity / reducInfectedSevereCriticalDeadPartialImmunity) *
409-
params.template get<CriticalPerSevere<FP>>()[i]) /
410+
(params.template get<CriticalPerSevere<FP>>()[i] +
411+
params.template get<DeathsPerSevere<FP>>()[i])) /
410412
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevPIi];
411413

412414
flows[this->template get_flat_flow_index<InfectionState::InfectedSeverePartialImmunity,
413415
InfectionState::DeadPartialImmunity>({i})] =
414416
(reducInfectedSevereCriticalDeadPartialImmunity / reducInfectedSevereCriticalDeadPartialImmunity) *
415-
deathsPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevPIi];
417+
(params.template get<DeathsPerSevere<FP>>()[i] + deathsPerSevereAdjusted) /
418+
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevPIi];
416419

417420
// InfectedCritical
418421
flows[this->template get_flat_flow_index<InfectionState::InfectedCriticalPartialImmunity,
@@ -490,13 +493,15 @@ class Model
490493
InfectionState::SusceptibleImprovedImmunity>({i})] =
491494
(1 -
492495
(reducInfectedSevereCriticalDeadImprovedImmunity / reducInfectedSevereCriticalDeadImprovedImmunity) *
493-
params.template get<CriticalPerSevere<FP>>()[i]) /
496+
(params.template get<CriticalPerSevere<FP>>()[i] +
497+
params.template get<DeathsPerSevere<FP>>()[i])) /
494498
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevIIi];
495499

496500
flows[this->template get_flat_flow_index<InfectionState::InfectedSevereImprovedImmunity,
497501
InfectionState::DeadImprovedImmunity>({i})] =
498502
(reducInfectedSevereCriticalDeadImprovedImmunity / reducInfectedSevereCriticalDeadImprovedImmunity) *
499-
deathsPerSevereAdjusted / params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevIIi];
503+
(params.template get<DeathsPerSevere<FP>>()[i] + deathsPerSevereAdjusted) /
504+
params.template get<TimeInfectedSevere<FP>>()[i] * y[ISevIIi];
500505

501506
// InfectedCritical
502507
flows[this->template get_flat_flow_index<InfectionState::InfectedCriticalImprovedImmunity,

0 commit comments

Comments
 (0)