Skip to content

Commit 9932b75

Browse files
committed
vaccination data data restriction, rm for divi data
1 parent 672cbc1 commit 9932b75

File tree

7 files changed

+174
-28
lines changed

7 files changed

+174
-28
lines changed

cpp/memilio/io/epi_data.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,21 @@ class DiviEntry
238238
inline bool is_divi_data_available(const Date& date)
239239
{
240240
static const Date divi_data_start(2020, 4, 23);
241-
static const Date divi_data_end(2024, 7, 21);
242-
return date >= divi_data_start && date <= divi_data_end;
241+
return date >= divi_data_start;
242+
}
243+
244+
/**
245+
* @brief Checks if vaccination data is available for any day within the given date interval.
246+
* @param start_date The start date of the interval to check.
247+
* @param end_date The end date of the interval to check.
248+
* @return True if there is any overlap between the given date range and the vaccination data
249+
* availability period, false otherwise.
250+
*/
251+
inline bool is_vaccination_data_available(const Date& start_date, const Date& end_date)
252+
{
253+
static const Date vaccination_data_start(2020, 12, 27);
254+
static const Date vaccination_data_end(2024, 7, 9);
255+
return !(end_date < vaccination_data_start || start_date > vaccination_data_end);
243256
}
244257

245258
/**

cpp/models/ode_secirts/parameters_io.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,27 @@ template <typename FP = double>
952952
IOResult<void> set_vaccination_data(std::vector<Model<FP>>& model, const std::string& path, Date date,
953953
const std::vector<int>& vregion, int num_days)
954954
{
955+
// Check if vaccination data is available for the given date range
956+
auto end_date = offset_date_by_days(date, num_days);
957+
if (!is_vaccination_data_available(date, end_date)) {
958+
log_warning("No vaccination data available in range from {} to {}. "
959+
"Vaccination data will be set to 0.",
960+
date, end_date);
961+
// Set vaccination data to 0 for all models
962+
for (auto& m : model) {
963+
m.parameters.template get<DailyPartialVaccinations<FP>>().resize(SimulationDay(num_days + 1));
964+
m.parameters.template get<DailyFullVaccinations<FP>>().resize(SimulationDay(num_days + 1));
965+
m.parameters.template get<DailyBoosterVaccinations<FP>>().resize(SimulationDay(num_days + 1));
966+
for (auto d = SimulationDay(0); d < SimulationDay(num_days + 1); ++d) {
967+
for (auto a = AgeGroup(0); a < m.parameters.get_num_groups(); ++a) {
968+
m.parameters.template get<DailyPartialVaccinations<FP>>()[{a, d}] = 0.0;
969+
m.parameters.template get<DailyFullVaccinations<FP>>()[{a, d}] = 0.0;
970+
m.parameters.template get<DailyBoosterVaccinations<FP>>()[{a, d}] = 0.0;
971+
}
972+
}
973+
}
974+
return success();
975+
}
955976
BOOST_OUTCOME_TRY(auto&& vacc_data, read_vaccination_data(path));
956977
BOOST_OUTCOME_TRY(set_vaccination_data(model, vacc_data, date, vregion, num_days));
957978
return success();

cpp/models/ode_secirvvs/parameters_io.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,26 @@ template <typename FP = double>
833833
IOResult<void> set_vaccination_data(std::vector<Model<FP>>& model, const std::string& path, Date date,
834834
const std::vector<int>& vregion, int num_days)
835835
{
836+
// Check if vaccination data is available for the given date range
837+
auto end_date = offset_date_by_days(date, num_days);
838+
if (!is_vaccination_data_available(date, end_date)) {
839+
log_warning("No vaccination data available in range from {} to {}. "
840+
"Vaccination data will be set to 0.",
841+
date, end_date);
842+
// Set vaccination data to 0 for all models
843+
for (auto& m : model) {
844+
m.parameters.template get<DailyPartialVaccinations<FP>>().resize(SimulationDay(num_days + 1));
845+
m.parameters.template get<DailyFullVaccinations<FP>>().resize(SimulationDay(num_days + 1));
846+
847+
for (auto d = SimulationDay(0); d < SimulationDay(num_days + 1); ++d) {
848+
for (auto a = AgeGroup(0); a < m.parameters.get_num_groups(); ++a) {
849+
m.parameters.template get<DailyPartialVaccinations<FP>>()[{a, d}] = 0.0;
850+
m.parameters.template get<DailyFullVaccinations<FP>>()[{a, d}] = 0.0;
851+
}
852+
}
853+
}
854+
return success();
855+
}
836856
BOOST_OUTCOME_TRY(auto&& vacc_data, read_vaccination_data(path));
837857
BOOST_OUTCOME_TRY(set_vaccination_data(model, vacc_data, date, vregion, num_days));
838858
return success();

cpp/tests/test_epi_data_io.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,28 @@ TEST(TestEpiDataIo, read_divi_data)
300300
TEST(TestEpiDataIo, is_divi_data_available)
301301
{
302302
EXPECT_FALSE(mio::is_divi_data_available(mio::Date(2020, 4, 22))); // Before start
303-
EXPECT_FALSE(mio::is_divi_data_available(mio::Date(2024, 7, 22))); // After end
304303
EXPECT_TRUE(mio::is_divi_data_available(mio::Date(2020, 4, 23))); // Start date
305-
EXPECT_TRUE(mio::is_divi_data_available(mio::Date(2022, 1, 1))); // Inside range
306-
EXPECT_TRUE(mio::is_divi_data_available(mio::Date(2024, 7, 21))); // End date
304+
EXPECT_TRUE(mio::is_divi_data_available(mio::Date(2022, 1, 1))); // Day after start
305+
}
306+
307+
TEST(TestEpiDataIo, is_vaccination_data_available)
308+
{
309+
// Single date tests
310+
EXPECT_FALSE(mio::is_vaccination_data_available(mio::Date(2020, 12, 26), mio::Date(2020, 12, 26))); // Before start
311+
EXPECT_TRUE(mio::is_vaccination_data_available(mio::Date(2020, 12, 27), mio::Date(2020, 12, 27))); // Start date
312+
EXPECT_TRUE(mio::is_vaccination_data_available(mio::Date(2024, 7, 9), mio::Date(2024, 7, 9))); // End date
313+
EXPECT_FALSE(mio::is_vaccination_data_available(mio::Date(2024, 7, 10), mio::Date(2024, 7, 10))); // After end
314+
315+
// Date range tests
316+
EXPECT_TRUE(
317+
mio::is_vaccination_data_available(mio::Date(2020, 12, 20), mio::Date(2020, 12, 28))); // Overlap with start
318+
EXPECT_TRUE(mio::is_vaccination_data_available(mio::Date(2024, 7, 5), mio::Date(2024, 7, 15))); // Overlap with end
319+
EXPECT_TRUE(
320+
mio::is_vaccination_data_available(mio::Date(2021, 1, 1), mio::Date(2021, 12, 31))); // Completely within range
321+
EXPECT_TRUE(
322+
mio::is_vaccination_data_available(mio::Date(2020, 1, 1), mio::Date(2025, 1, 1))); // Contains entire range
323+
EXPECT_FALSE(mio::is_vaccination_data_available(mio::Date(2019, 1, 1), mio::Date(2020, 12, 26))); // Before start
324+
EXPECT_FALSE(mio::is_vaccination_data_available(mio::Date(2024, 7, 10), mio::Date(2025, 1, 1))); // After end
307325
}
308326

309327
TEST(TestEpiDataIo, read_confirmed_cases_data)

cpp/tests/test_odesecir.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,11 +1453,6 @@ TEST(TestOdeSecir, set_divi_data_invalid_dates)
14531453
EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast<double>()),
14541454
MatrixNear(print_wrap(model.populations.array().cast<double>()), 1e-10, 1e-10));
14551455

1456-
// Test with data after DIVI dataset was no longer updated.
1457-
EXPECT_THAT(mio::osecir::details::set_divi_data(model_vector, "", {1001}, {2025, 12, 01}, 1.0), IsSuccess());
1458-
EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast<double>()),
1459-
MatrixNear(print_wrap(model.populations.array().cast<double>()), 1e-10, 1e-10));
1460-
14611456
mio::set_log_level(mio::LogLevel::warn);
14621457
}
14631458

@@ -1478,7 +1473,7 @@ TEST_F(ModelTestOdeSecir, set_confirmed_cases_data_with_ICU)
14781473

14791474
// Change dates of the case data so that no ICU data is available at that time.
14801475
// Also, increase the number of confirmed cases by 1 each day.
1481-
const auto t0 = mio::Date(2025, 1, 1);
1476+
const auto t0 = mio::Date(2000, 1, 1);
14821477
auto day_add = 0;
14831478
for (auto& entry : case_data) {
14841479
entry.date = offset_date_by_days(t0, day_add);

cpp/tests/test_odesecirts.cpp

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -768,12 +768,6 @@ TEST(TestOdeSECIRTS, set_divi_data_invalid_dates)
768768
// Assure that populations is the same as before.
769769
EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast<double>()),
770770
MatrixNear(print_wrap(model.populations.array().cast<double>()), 1e-10, 1e-10));
771-
772-
// Test with data after DIVI dataset was no longer updated.
773-
EXPECT_THAT(mio::osecirts::details::set_divi_data(model_vector, "", {1001}, {2025, 12, 01}, 1.0), IsSuccess());
774-
EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast<double>()),
775-
MatrixNear(print_wrap(model.populations.array().cast<double>()), 1e-10, 1e-10));
776-
777771
mio::set_log_level(mio::LogLevel::warn);
778772
}
779773

@@ -802,7 +796,7 @@ TEST(TestOdeSECIRTS, set_confirmed_cases_data_with_ICU)
802796

803797
// Change dates of the case data so that no ICU data is available at that time.
804798
// Also, increase the number of confirmed cases by 1 each day.
805-
const auto t0 = mio::Date(2025, 1, 1);
799+
const auto t0 = mio::Date(2000, 1, 1);
806800
auto day_add = 0;
807801
for (auto& entry : case_data) {
808802
entry.date = offset_date_by_days(t0, day_add);
@@ -1593,3 +1587,51 @@ TEST(TestOdeSECIRTS, apply_variant_function)
15931587
sim.get_model().parameters.get<mio::osecirts::TransmissionProbabilityOnContact<double>>()[mio::AgeGroup(0)],
15941588
0.4, 1e-10);
15951589
}
1590+
1591+
TEST(TestOdeSECIRTS, set_vaccination_data_not_avail)
1592+
{
1593+
const auto num_age_groups = 2;
1594+
const auto num_days = 5;
1595+
mio::osecirts::Model<double> model(num_age_groups);
1596+
std::vector<mio::osecirts::Model<double>> model_vector = {model};
1597+
1598+
// Setup initial non-zero vaccination data
1599+
auto& params = model_vector[0].parameters;
1600+
params.get<mio::osecirts::DailyPartialVaccinations<double>>().resize(mio::SimulationDay(num_days + 1));
1601+
params.get<mio::osecirts::DailyFullVaccinations<double>>().resize(mio::SimulationDay(num_days + 1));
1602+
params.get<mio::osecirts::DailyBoosterVaccinations<double>>().resize(mio::SimulationDay(num_days + 1));
1603+
1604+
const double initial_partial_vacc_val = 10.0;
1605+
const double initial_full_vacc_val = 5.0;
1606+
const double initial_booster_vacc_val = 2.0;
1607+
1608+
for (auto g = mio::AgeGroup(0); g < mio::AgeGroup(num_age_groups); ++g) {
1609+
for (auto d = mio::SimulationDay(0); d < mio::SimulationDay(num_days + 1); ++d) {
1610+
params.get<mio::osecirts::DailyPartialVaccinations<double>>()[{g, d}] = initial_partial_vacc_val;
1611+
params.get<mio::osecirts::DailyFullVaccinations<double>>()[{g, d}] = initial_full_vacc_val;
1612+
params.get<mio::osecirts::DailyBoosterVaccinations<double>>()[{g, d}] = initial_booster_vacc_val;
1613+
}
1614+
}
1615+
1616+
// call set_vaccination_data with an unavailable date
1617+
mio::Date unavailable_date(2019, 1, 1); // Date before vaccinations started
1618+
std::vector<int> region = {1001};
1619+
std::string any_path = "dummy_vacc_path.json";
1620+
1621+
auto result =
1622+
mio::osecirts::details::set_vaccination_data(model_vector, any_path, unavailable_date, region, num_days);
1623+
1624+
ASSERT_THAT(result, IsSuccess());
1625+
1626+
// Check that vaccinations are set to zero for all days and age groups
1627+
for (auto d = mio::SimulationDay(0); d < mio::SimulationDay(num_days + 1); ++d) {
1628+
for (auto a = mio::AgeGroup(0); a < mio::AgeGroup(num_age_groups); ++a) {
1629+
auto partial_vacc = params.get<mio::osecirts::DailyPartialVaccinations<double>>()[{a, d}];
1630+
auto full_vacc = params.get<mio::osecirts::DailyFullVaccinations<double>>()[{a, d}];
1631+
auto booster_vacc = params.get<mio::osecirts::DailyBoosterVaccinations<double>>()[{a, d}];
1632+
EXPECT_NEAR(partial_vacc, 0.0, 1e-10);
1633+
EXPECT_NEAR(full_vacc, 0.0, 1e-10);
1634+
EXPECT_NEAR(booster_vacc, 0.0, 1e-10);
1635+
}
1636+
}
1637+
}

cpp/tests/test_odesecirvvs.cpp

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,6 @@ TEST(TestOdeSECIRVVS, set_divi_data_invalid_dates)
583583
EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast<double>()),
584584
MatrixNear(print_wrap(model.populations.array().cast<double>()), 1e-10, 1e-10));
585585

586-
// Test with data after DIVI dataset was no longer updated.
587-
EXPECT_THAT(mio::osecirvvs::details::set_divi_data(model_vector, "", {1001}, {2025, 12, 01}, 1.0), IsSuccess());
588-
EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast<double>()),
589-
MatrixNear(print_wrap(model.populations.array().cast<double>()), 1e-10, 1e-10));
590-
591586
mio::set_log_level(mio::LogLevel::warn);
592587
}
593588

@@ -612,7 +607,7 @@ TEST(TestOdeSECIRVVS, set_confirmed_cases_data_with_ICU)
612607

613608
// Change dates of the case data so that no ICU data is available at that time.
614609
// Also, increase the number of confirmed cases by 1 each day.
615-
const auto t0 = mio::Date(2025, 1, 1);
610+
const auto t0 = mio::Date(2000, 1, 1);
616611
auto day_add = 0;
617612
for (auto& entry : case_data) {
618613
entry.date = offset_date_by_days(t0, day_add);
@@ -666,14 +661,14 @@ TEST(TestOdeSECIRVVS, read_data)
666661

667662
auto read_result1 = mio::osecirvvs::read_input_data_county(model1, {2020, 12, 01}, {1002},
668663
std::vector<double>(size_t(num_age_groups), 1.0), 1.0,
669-
TEST_GERMANY_PYDATA_DIR, 10);
664+
TEST_GERMANY_PYDATA_DIR, 30);
670665

671666
auto read_result2 = mio::osecirvvs::read_input_data(model2, {2020, 12, 01}, {1002},
672667
std::vector<double>(size_t(num_age_groups), 1.0), 1.0,
673-
TEST_GERMANY_PYDATA_DIR, 10);
668+
TEST_GERMANY_PYDATA_DIR, 30);
674669

675670
auto read_result_district = mio::osecirvvs::read_input_data(
676-
model3, {2020, 12, 01}, {1002}, std::vector<double>(size_t(num_age_groups), 1.0), 1.0, pydata_dir_District, 10);
671+
model3, {2020, 12, 01}, {1002}, std::vector<double>(size_t(num_age_groups), 1.0), 1.0, pydata_dir_District, 30);
677672

678673
ASSERT_THAT(read_result1, IsSuccess());
679674
ASSERT_THAT(read_result2, IsSuccess());
@@ -903,7 +898,7 @@ TEST(TestOdeSECIRVVS, model_initialization)
903898

904899
ASSERT_THAT(mio::osecirvvs::read_input_data_county(model_vector, {2020, 12, 01}, {0},
905900
std::vector<double>(size_t(num_age_groups), 1.0), 1.0,
906-
TEST_GERMANY_PYDATA_DIR, 2, false),
901+
TEST_GERMANY_PYDATA_DIR, 30, false),
907902
IsSuccess());
908903

909904
// Values from data/export_time_series_init_osecirvvs.h5, for reading in comparison
@@ -1586,3 +1581,45 @@ TEST(TestOdeSECIRVVS, apply_variant_function)
15861581
sim.get_model().parameters.get<mio::osecirvvs::TransmissionProbabilityOnContact<double>>()[mio::AgeGroup(0)],
15871582
0.4, 1e-10);
15881583
}
1584+
1585+
TEST(TestOdeSECIRVVS, set_vaccination_data_not_avail)
1586+
{
1587+
const auto num_age_groups = 2;
1588+
const auto num_days = 5;
1589+
mio::osecirvvs::Model<double> model(num_age_groups);
1590+
std::vector<mio::osecirvvs::Model<double>> model_vector = {model};
1591+
1592+
// Setup initial non-zero vaccination data
1593+
auto& params = model_vector[0].parameters;
1594+
params.get<mio::osecirvvs::DailyPartialVaccinations<double>>().resize(mio::SimulationDay(num_days + 1));
1595+
params.get<mio::osecirvvs::DailyFullVaccinations<double>>().resize(mio::SimulationDay(num_days + 1));
1596+
1597+
const double initial_partial_vacc_val = 10.0;
1598+
const double initial_full_vacc_val = 5.0;
1599+
1600+
for (auto g = mio::AgeGroup(0); g < mio::AgeGroup(num_age_groups); ++g) {
1601+
for (auto d = mio::SimulationDay(0); d < mio::SimulationDay(num_days + 1); ++d) {
1602+
params.get<mio::osecirvvs::DailyPartialVaccinations<double>>()[{g, d}] = initial_partial_vacc_val;
1603+
params.get<mio::osecirvvs::DailyFullVaccinations<double>>()[{g, d}] = initial_full_vacc_val;
1604+
}
1605+
}
1606+
1607+
// call set_vaccination_data with an unavailable date
1608+
mio::Date unavailable_date(2019, 1, 1); // Date before vaccinations started
1609+
std::vector<int> region = {1001};
1610+
std::string any_path = "dummy_vacc_path.json";
1611+
auto result =
1612+
mio::osecirvvs::details::set_vaccination_data(model_vector, any_path, unavailable_date, region, num_days);
1613+
1614+
ASSERT_THAT(result, IsSuccess());
1615+
1616+
// Check that vaccinations are set to zero for all days and age groups
1617+
for (auto d = mio::SimulationDay(0); d < mio::SimulationDay(num_days + 1); ++d) {
1618+
for (auto a = mio::AgeGroup(0); a < mio::AgeGroup(num_age_groups); ++a) {
1619+
auto partial_vacc = params.get<mio::osecirvvs::DailyPartialVaccinations<double>>()[{a, d}];
1620+
auto full_vacc = params.get<mio::osecirvvs::DailyFullVaccinations<double>>()[{a, d}];
1621+
EXPECT_NEAR(partial_vacc, 0.0, 1e-10);
1622+
EXPECT_NEAR(full_vacc, 0.0, 1e-10);
1623+
}
1624+
}
1625+
}

0 commit comments

Comments
 (0)