Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update core scheduler #9

Merged
merged 7 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sample_inputs/input.yml
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@ epidemiological_parameters:
# ---------------------------------------------------------------
# 15. Mosquito Parameters (default is location based)
# ---------------------------------------------------------------
#TODO: Check this implementation in Mosquito class
mosquito_parameters:
mosquito_config:
mode: "location_based" # or "grid_based"
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ find_package(sol2 CONFIG REQUIRED)
find_package(Lua REQUIRED)
find_package(spdlog REQUIRED)
find_package(date CONFIG REQUIRED)
find_package(CLI11 CONFIG REQUIRED)

include_directories(
${PROJECT_SOURCE_DIR}/src
Expand Down Expand Up @@ -34,6 +35,7 @@ target_link_libraries(MalaSimCore PUBLIC
sol2
spdlog::spdlog
date::date date::date-tz
CLI11::CLI11
)

set_property(TARGET MalaSimCore PROPERTY CXX_STANDARD 20)
Expand Down
85 changes: 50 additions & 35 deletions src/Configuration/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,58 +13,73 @@ int inline get_pipe_count(const std::string &str) {
return pipe_count;
}

void Config::load(const std::string &filename) {
bool Config::load(const std::string &filename) {
config_file_path_ = filename;
YAML::Node config = YAML::LoadFile(filename);
try {
YAML::Node config = YAML::LoadFile(filename);

config_data_.model_settings = config["model_settings"].as<ModelSettings>();
config_data_.simulation_timeframe =
config["simulation_timeframe"].as<SimulationTimeframe>();
std::cout << "Configuration file loaded successfully" << std::endl;

config_data_.transmission_settings =
config["transmission_settings"].as<TransmissionSettings>();
config_data_.model_settings = config["model_settings"].as<ModelSettings>();
config_data_.simulation_timeframe =
config["simulation_timeframe"].as<SimulationTimeframe>();

config_data_.population_demographic =
config["population_demographic"].as<PopulationDemographic>();
config_data_.transmission_settings =
config["transmission_settings"].as<TransmissionSettings>();

config_data_.spatial_settings =
config["spatial_settings"].as<SpatialSettings>();
config_data_.population_demographic =
config["population_demographic"].as<PopulationDemographic>();

config_data_.seasonality_settings =
config["seasonality_settings"].as<SeasonalitySettings>();
config_data_.spatial_settings =
config["spatial_settings"].as<SpatialSettings>();

config_data_.movement_settings =
config["movement_settings"].as<MovementSettings>();
config_data_.seasonality_settings =
config["seasonality_settings"].as<SeasonalitySettings>();

config_data_.parasite_parameters =
config["parasite_parameters"].as<ParasiteParameters>();
config_data_.movement_settings =
config["movement_settings"].as<MovementSettings>();

config_data_.immune_system_parameters =
config["immune_system_parameters"].as<ImmuneSystemParameters>();
config_data_.parasite_parameters =
config["parasite_parameters"].as<ParasiteParameters>();

config_data_.genotype_parameters =
config["genotype_parameters"].as<GenotypeParameters>();
config_data_.immune_system_parameters =
config["immune_system_parameters"].as<ImmuneSystemParameters>();

config_data_.drug_parameters =
config["drug_parameters"].as<DrugParameters>();
config_data_.genotype_parameters =
config["genotype_parameters"].as<GenotypeParameters>();

config_data_.therapy_parameters =
config["therapy_parameters"].as<TherapyParameters>();
config_data_.drug_parameters =
config["drug_parameters"].as<DrugParameters>();

config_data_.strategy_parameters =
config["strategy_parameters"].as<StrategyParameters>();
config_data_.therapy_parameters =
config["therapy_parameters"].as<TherapyParameters>();

config_data_.epidemiological_parameters =
config["epidemiological_parameters"].as<EpidemiologicalParameters>();
config_data_.strategy_parameters =
config["strategy_parameters"].as<StrategyParameters>();

config_data_.mosquito_parameters =
config["mosquito_parameters"].as<MosquitoParameters>();
config_data_.epidemiological_parameters =
config["epidemiological_parameters"].as<EpidemiologicalParameters>();

config_data_.population_events =
config["population_events"].as<PopulationEvents>();
config_data_.mosquito_parameters =
config["mosquito_parameters"].as<MosquitoParameters>();

// Validate all cross field validations
validate_all_cross_field_validations();
config_data_.population_events =
config["population_events"].as<PopulationEvents>();

std::cout << "Configuration file parsed successfully" << std::endl;

// Validate all cross field validations
validate_all_cross_field_validations();

std::cout << "Configuration file validated successfully" << std::endl;

return true;
}
catch (YAML::BadFile) {
std::cerr << "Error: File not found" << std::endl;
return false;
}
return false;
}

void Config::validate_all_cross_field_validations() {
Expand Down
2 changes: 1 addition & 1 deletion src/Configuration/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Config {
Config &operator=(Config &&) = delete;

// Load configuration from a YAML file
void load(const std::string &filename);
bool load(const std::string &filename);

// Reload configuration (useful for dynamic updates)
void reload();
Expand Down
46 changes: 46 additions & 0 deletions src/Configuration/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,47 @@
# Core Config

The Configuration module is responsible for loading, validating, and managing the configuration settings for the simulation. It reads configuration data from a YAML file and provides access to various configuration parameters through getter methods.

## Files

- `Config.h` and `Config.cpp`: Defines the `Config` class, which handles loading and validating the configuration file.
- `ConfigData.h`: Defines the `ConfigData` struct, which holds all the configuration parameters.
- `ConfigData.cpp`: Implements the methods for the `ConfigData` struct.

## Classes

### Config

The `Config` class is responsible for:

- Loading configuration data from a YAML file.
- Validating the configuration data.
- Providing access to the configuration parameters.

#### Methods

- `bool load(const std::string &filename)`: Loads the configuration from the specified YAML file.
- `void reload()`: Reloads the configuration file.
- `void validate_all_cross_field_validations()`: Validates all cross-field validations.
- Various getter methods to access specific configuration parameters.

### ConfigData

The `ConfigData` struct holds all the configuration parameters. It includes the following fields:

- `ModelSettings model_settings`: Configuration for the model settings.
- `TransmissionSettings transmission_settings`: Configuration for transmission settings.
- `PopulationDemographic population_demographic`: Configuration for population demographics.
- `SimulationTimeframe simulation_timeframe`: Configuration for the simulation timeframe.
- `SpatialSettings spatial_settings`: Configuration for spatial settings.
- `SeasonalitySettings seasonality_settings`: Configuration for seasonality settings.
- `MovementSettings movement_settings`: Configuration for movement settings.
- `ParasiteParameters parasite_parameters`: Configuration for parasite parameters.
- `ImmuneSystemParameters immune_system_parameters`: Configuration for immune system parameters.
- `GenotypeParameters genotype_parameters`: Configuration for genotype parameters.
- `DrugParameters drug_parameters`: Configuration for drug parameters.
- `TherapyParameters therapy_parameters`: Configuration for therapy parameters.
- `StrategyParameters strategy_parameters`: Configuration for strategy parameters.
- `EpidemiologicalParameters epidemiological_parameters`: Configuration for epidemiological parameters.
- `MosquitoParameters mosquito_parameters`: Configuration for mosquito parameters.
- `PopulationEvents population_events`: Configuration for population events.
11 changes: 11 additions & 0 deletions src/Configuration/SimulationTimeframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <spdlog/spdlog.h>

#include "Utils/YamlFile.h"
#include "Utils/Time.h"

// Class to hold the simulation timeframe data
class SimulationTimeframe {
Expand Down Expand Up @@ -53,11 +54,20 @@ class SimulationTimeframe {
start_collect_data_day_ = value;
}

void set_total_time(int total_time) {
total_time_ = total_time;
}

[[nodiscard]] int get_total_time() const {
return total_time_;
}

private:
date::year_month_day starting_date_;
date::year_month_day start_of_comparison_period_;
date::year_month_day ending_date_;
int start_collect_data_day_;
int total_time_;
};

// Specialization of convert for the SimulationTimeframe class
Expand Down Expand Up @@ -93,6 +103,7 @@ struct convert<SimulationTimeframe> {
rhs.set_ending_date(node["ending_date"].as<date::year_month_day>());
rhs.set_start_collect_data_day(node["start_collect_data_day"].as<int>());

rhs.set_total_time(utils::Time::instance().get_day_count(rhs.get_starting_date(), rhs.get_ending_date()));
return true;
}
};
Expand Down
36 changes: 36 additions & 0 deletions src/Core/Scheduler/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
# Core Scheduler

The Scheduler module is responsible for managing the simulation's time progression and scheduling events. It interacts with the `Model` class to execute daily, monthly, and yearly updates.

## Files

- `Scheduler.h` and `Scheduler.cpp`: Defines the `Scheduler` class, which handles the simulation's time management and event scheduling.

## Classes

### Scheduler

The `Scheduler` class is responsible for:

- Managing the simulation's current time and total available time.
- Interacting with the `Model` class to perform updates.
- Handling the simulation's calendar date.
- Providing methods to start, run, and stop the simulation.

#### Methods

- `Scheduler(Model *model = nullptr)`: Constructor that initializes the scheduler with an optional `Model` instance.
- `~Scheduler()`: Destructor that clears all events.
- `void extend_total_time(int new_total_time)`: Extends the total available time for the simulation.
- `void clear_all_events()`: Clears all scheduled events.
- `void initialize(const date::year_month_day &starting_date, const int &total_time)`: Initializes the scheduler with a starting date and total time.
- `void run()`: Runs the simulation.
- `void begin_time_step() const`: Begins a time step in the simulation.
- `void end_time_step() const`: Ends a time step in the simulation.
- `bool can_stop() const`: Checks if the simulation can stop.
- `int current_day_in_year() const`: Returns the current day in the year.
- `int current_month_in_year() const`: Returns the current month in the year.
- `bool is_today_last_day_of_month() const`: Checks if today is the last day of the month.
- `bool is_today_first_day_of_month() const`: Checks if today is the first day of the month.
- `bool is_today_first_day_of_year() const`: Checks if today is the first day of the year.
- `bool is_today_last_day_of_year() const`: Checks if today is the last day of the year.
- `void daily_update() const`: Performs daily updates in the simulation.
111 changes: 111 additions & 0 deletions src/Core/Scheduler/Scheduler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include "Scheduler.h"

#include <Configuration/Config.h>

Scheduler::Scheduler(Model* model)
: current_time_(-1), total_available_time_(-1), model_(model), is_force_stop_(false) {}

Scheduler::~Scheduler() {
clear_all_events();
}

void Scheduler::extend_total_time(int new_total_time) {
if (total_available_time_ < new_total_time) {
// for (auto i = total_available_time_; i <= new_total_time; i++) {
// individual_events_list_.push_back(EventPtrVector());
// population_events_list_.push_back(EventPtrVector());
// }
}
total_available_time_ = new_total_time;
}

void Scheduler::clear_all_events() {
// clear_all_events(individual_events_list_);
// clear_all_events(population_events_list_);
}

void Scheduler::initialize(const date::year_month_day& starting_date, const int& total_time) {
set_total_available_time(total_time + 720); // Prevent scheduling at the end of simulation
set_current_time(0);
calendar_date = date::sys_days(starting_date);
}

// Methods not declared in the header have been removed

void Scheduler::run() {
current_time_ = 0;
for (current_time_ = 0; !can_stop(); current_time_++) {
if (current_time_ % model_->get_config()->get_model_settings().get_days_between_stdout_output() == 0) {
spdlog::info("Day: {}", current_time_);
}
begin_time_step();
daily_update();
end_time_step();
calendar_date += date::days{1};
}
}

void Scheduler::begin_time_step() const {
if (model_ != nullptr) {
model_->begin_time_step();
}
}

void Scheduler::daily_update() const {
if (model_ != nullptr) {
model_->daily_update();

if (is_today_first_day_of_month()) {
model_->monthly_update();
}

if (is_today_first_day_of_year()) {
model_->yearly_update();
}

// Executing population-related events
// execute_events_list(population_events_list_[current_time_]);

// Executing individual-related events
// execute_events_list(individual_events_list_[current_time_]);
}
}

void Scheduler::end_time_step() const {
if (model_ != nullptr) {
model_->end_time_step();
}
}

bool Scheduler::can_stop() const {
return current_time_ > model_->get_config()->get_simulation_timeframe().get_total_time();
}

int Scheduler::current_day_in_year() const {
return utils::Time::instance().day_of_year(calendar_date);
}

int Scheduler::current_month_in_year() const {
return utils::Time::instance().month_of_year(calendar_date);
}

bool Scheduler::is_today_last_day_of_year() const {
date::year_month_day ymd{calendar_date};
return ymd.month() == date::month{12} && ymd.day() == date::day{31};
}

bool Scheduler::is_today_first_day_of_month() const {
date::year_month_day ymd{calendar_date};
return ymd.day() == date::day{1};
}

bool Scheduler::is_today_first_day_of_year() const {
date::year_month_day ymd{calendar_date};
return ymd.month() == date::month{1} && ymd.day() == date::day{1};
}

bool Scheduler::is_today_last_day_of_month() const {
const auto next_date = calendar_date + date::days{1};
date::year_month_day ymd{next_date};
return ymd.day() == date::day{1};
}
Loading
Loading