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

Enable custom data writing #74

Merged
merged 4 commits into from
Apr 8, 2022
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ inst/doc
.Rhistory
.Rapp.history

*/.DS_Store
**/.DS_Store
# Session Data files
.RData

Expand Down
8 changes: 5 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: villager
Title: A framework for simulating ancient village structures
Version: 0.0.0.9000
Title: A framework for running Agent Based Models
Version: 1.0.0.0
Authors@R: c(
person(
given = "Thomas",
Expand All @@ -26,6 +26,7 @@ Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.1
Depends: R (>= 3.5.0)
Remotes:
edgararuiz/gregorian,
jimhester/lintr
Expand All @@ -38,7 +39,8 @@ Imports:
testthat,
tibble,
remotes,
gregorian
gregorian,
readr
Suggests:
lintr
VignetteBuilder: knitr
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Generated by roxygen2: do not edit by hand

export(model_data)
export(data_writer)
export(resource)
export(resource_manager)
export(simulation)
Expand Down
13 changes: 8 additions & 5 deletions R/Simulation.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#' @field start_date The Gregorian date that the simulation starts on
#' @field end_date The Gregorian date that the simulation ends on
#' @field villages A list of villages that the simulator will run
#' @field writer An instance of a data_writer class for writing village data to disk
#' @export
#' @section Methods:
#' \describe{
Expand All @@ -15,19 +16,23 @@ simulation <- R6::R6Class("simulation",
start_date = NA,
end_date = NA,
villages = NA,
writer=NA,

#' Creates a new Simulation instance
#'
#' @description Creates a new simulation object to control the experiment
#' @param start_date The date to start the simulation
#' @param end_date The date that the simulation should end
#' @param villages A list of villages that will be simulated
#' @param writer The data writer to be used with the villages
initialize = function(start_date,
end_date,
villages) {
villages,
writer=data_writer$new()) {
self$villages <- villages
self$start_date <- gregorian::as_gregorian(start_date)
self$end_date <- gregorian::as_gregorian(end_date)
self$writer <- writer
},

#' Runs the simulation
Expand All @@ -36,24 +41,22 @@ simulation <- R6::R6Class("simulation",
run_model = function() {
total_days <- gregorian::diff_days(self$start_date, self$end_date)
for (village in self$villages) {
village$optimize(total_days)

village$set_initial_state(self$start_date)
}
# Loop over each village and run the user defined initial condition function
current_date <- gregorian::add_days(self$start_date, 1)
date_diff <- gregorian::diff_days(current_date, self$end_date)
total_days_passed <- 1
while (date_diff >= 0) {
# Iterate the villages a single timestep
# Iterate the villages a single time step
for(village in self$villages) {
village$propagate(current_date, total_days_passed)
self$writer$write(village$current_state, village$name)
total_days_passed <- total_days_passed + 1
}
# Add '1' to the current day
current_date <- gregorian::add_days(current_date, 1)
date_diff <- gregorian::diff_days(current_date, self$end_date)

}
},

Expand Down
66 changes: 66 additions & 0 deletions R/data_writer.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#' @export
#' @title Data Writer
#' @docType class
#' @description A class responsible for the simulation data to disk.
#' @details This class can be subclasses to provide advanced data writing to other data sources. This should also be subclassed if the winik and resource
#' classes are subclasses, to write any addional fields to the data source.
#' @field results_directory The folder where the simulation resulst are written to
#' @field winik_filename The location where the winiks are written to
#' @field resource_filename The location where the resources are written to
#' @section Methods:
#' \describe{
#' \item{\code{write()}}{Writes the winik and resources to disk.}
#' }
data_writer <- R6::R6Class("data_writer",
public = list(results_directory=NULL,
winik_filename=NULL,
resource_filename=NULL,

#' Create a new data writer.
#'
#' @description Creates a new data writer object that has optional paths for data files.
#' @param results_directory The directory where the results file is written to
#' @param winik_filename The name of the file for the winik data
#' @param resource_filename The name of the file for the resource data
#' @return A new winik object
initialize = function(results_directory='results', winik_filename='winiks.csv', resource_filename='resources.csv') {
self$results_directory <- results_directory
self$winik_filename <- winik_filename
self$resource_filename <- resource_filename

# Check that the directory exists, delete it if it does
res_folder <- file.path(self$results_directory)
if (file.exists(res_folder)) {
unlink(res_folder, recursive = TRUE)
}
dir.create(res_folder, recursive = TRUE)
},

#' Writes a village's state to disk.
#'
#' @description Takes a state an the name of a village and writes the winiks and resources to disk
#' @param state The village's village_state that's being written
#' @param village_name The name of the village. This is used to create the data directory
#' @return None
write = function(state, village_name) {
# Check that the village_name folder where the csv files are written to exists; create it if it doesn't
res_folder <- file.path(self$results_directory, village_name)
if (!file.exists(res_folder)) {
dir.create(res_folder, recursive = TRUE)
}
# Write the winiks to disk
winik_path <- file.path(res_folder, self$winik_filename)
if (!file.exists(winik_path)) {
file.create(winik_path, recursive = TRUE)
}
readr::write_csv(state$winik_states, winik_path, na="NA", append=TRUE)

# Write the resources
resources_path <- file.path(res_folder, self$resource_filename)
if (!file.exists(resources_path)) {
file.create(resources_path, recursive = TRUE)
}
readr::write_csv(state$resource_states, resources_path, na="NA", append=TRUE)
}
)
)
14 changes: 11 additions & 3 deletions R/resource_manager.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
#' @title Resource Manager
#' @docType class
#' @description This object manages all of the resources in a village.
#' @field resources A list of resource objects
#' @section Methods:
#' \describe{
#' \item{\code{initialize()}}{Creates a new manager}
#' \item{\code{get_resources()}}{Gets all of the resources that the manager has}
#' \item{\code{get_resource()}}{Retrieves a resource from the manager}
#' \item{\code{add_resource()}}{Adds a resource to the manager}
#' \item{\code{remove_resource()}}{Removes a resource from the manager}
Expand All @@ -14,14 +14,22 @@
#' \item{\code{load()}}{Loads a csv file of resources and adds them to the manager.}
#' }
resource_manager <- R6::R6Class("resource_manager",
public = list(resources = NULL,

public = list(
#' @field resources A list of resource objects
resources = NA,
#' Creates a new , empty, resource manager for a village.
#' @description Get a new instance of a resource_manager
initialize = function() {
self$resources <- vector()
},

#' Gets all of the managed resources
#'
#' @return A list of resources
get_resources = function() {
return (self$resources)
},

#' Gets a resource given a resource name
#'
#' @param name The name of the requested resource
Expand Down
Loading