Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardlavender committed May 26, 2024
1 parent 2a8faf4 commit ba93be6
Showing 1 changed file with 65 additions and 44 deletions.
109 changes: 65 additions & 44 deletions src/011-R-from-Julia.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,43 @@ using DataFrames
using OrderedCollections

"""
# R from Julia
# `R` from `Julia`
A collection of functions that facilitate the translation of inputs from `Julia` into `R`.
A collection of internal functions that facilitate the translation of `Julia` objects into `R`.
# Details
* [`r_get_states`] translates a State matrix into a `DataFrame` that can be passed to `R`. In the input matrix, each row is a particle and each column is a time step.
* [`r_get_dataset`] translates a Dictionary of observations into a Vector of DataFrames that can be passed to `R`.
* [`Patter.r_get_dataset()`](@ref) translates a Dictionary of observations into a `Vector` of `DataFrame`s that can be passed to `R`.
* [`Patter.r_get_states()`](@ref) translates a `Matrix` of [`State`](@ref)s into a `DataFrame` that can be passed to `R`. In the input `Matrix`, each row is a particle and each column is a time step.
* [`Patter.r_get_particles()`](@ref) wraps [`Patter.r_get_states()`](@ref) and translates particle outputs (from [`particle_filter()`](@ref) and [`two_filter_smoother()`](@ref)) into a `NamedTuple` for `R`.
These functions are [`State`](@ref) and model agnostic; that is, they work irrespective of the input [`State`](@ref) and model sub-types. Custom methods are not required to handle novel sub-types.
# Returns
A long-format `DataFrame`, with columns for `path_id`, `timestep` and each state dimension.
"""
function r_get_states(state::Matrix, timesteps::Vector = collect(1:size(state, 2)))
# Initialise empty matrix
fields = fieldnames(typeof(state[1]))
values = Matrix{Float64}(undef, prod(size(state)), length(fields) + 2)
# Define path ID & time step columns
np = size(state, 1)
nt = size(state, 2)
values[:, 1] = repeat(1:np, inner = nt)
values[:, 2] = repeat(1:nt, outer = np)
# Populate matrix
for i in 1:size(values, 1)
for j in eachindex(fields)
values[i, j + 2] = getfield(state[Int(values[i, 1]), Int(values[i, 2])], fields[j])
end
end
# Replace column indices with timesteps
values[:, 2] = repeat(minimum(timesteps):maximum(timesteps), outer = np)
# Coerce to dataframe
fields = (:path_id, :timestep, fields...)
df = DataFrame(values, collect(fields))
df.path_id = Int.(df.path_id)
df.timestep = Int.(df.timestep)
df
end
# Examples:
* [`Patter.r_get_dataset()`](@ref) returns a `Vector` of `DataFrame`s, with columns for `timestamp`, `obs` and the observation model parameters;
* [`Patter.r_get_states()`](@ref) returns a long-format `DataFrame`, with columns for `path_id`, `timestep` and each state dimension;
* [`Patter.r_get_particles()`](@ref) returns a `NamedTuple` of particle information, including:
- `states`: A `DataFrame` of [`State`](@ref) dimensions (from [`Patter.r_get_states()`](@ref));
- `diagnostics`: A `DataFrame` of algorithm diagnostics, including `timestep`, `timestamp`, `ess` and `maxlp` columns;
- `convergence`: A `Boolian` that defines algorithm convergence;
# Define state matrix:
# * Two rows: two particles
# * Three columns: three time steps
# state = [StateXY(0.0, 1.0, 2.0) StateXY(0.0, 3.0, 4.0) StateXY(0.0, 5.0, 6.0);
# StateXY(0.0, 7.0, 8.0) StateXY(0.0, 9.0, 10.0) StateXY(0.0, 11.0, 2.0)]
# r_get_states(state)
"""
function r_get end

# Create a big matrix of StateXY objects
# np = 1000
# nt = 20000
# state = [StateXY(rand(), rand(), rand()) for _ in 1:np, _ in 1:nt]
# r_get_states(state)

#### Convert struct to dict
#### Convert a struct to an Ordered Dict
function struct_to_dict(s)
return OrderedCollections.OrderedDict(key => getfield(s, key) for key in propertynames(s))
end


#### Formulate dictionaries to hold the observation for a selected time stamp
function dict_obs(timestamp, obs, sensor)
OrderedCollections.OrderedDict(:timestamp => timestamp, :obs => obs, struct_to_dict(sensor)...)
end


#### Extract dataset(s) from yobs for a selected model type
function r_get_dataset(yobs::Dict, model_type::Type{<: ModelObs})

Expand Down Expand Up @@ -93,7 +69,51 @@ function r_get_dataset(yobs::Dict, model_type::Type{<: ModelObs})
output

end
@doc (@doc r_get) r_get_dataset


#### Get a DataFrame of States
function r_get_states(state::Matrix, timesteps::Vector = collect(1:size(state, 2)))
# Initialise empty matrix
fields = fieldnames(typeof(state[1]))
values = Matrix{Float64}(undef, prod(size(state)), length(fields) + 2)
# Define path ID & time step columns
np = size(state, 1)
nt = size(state, 2)
values[:, 1] = repeat(1:np, inner = nt)
values[:, 2] = repeat(1:nt, outer = np)
# Populate matrix
for i in 1:size(values, 1)
for j in eachindex(fields)
values[i, j + 2] = getfield(state[Int(values[i, 1]), Int(values[i, 2])], fields[j])
end
end
# Replace column indices with timesteps
values[:, 2] = repeat(minimum(timesteps):maximum(timesteps), outer = np)
# Coerce to dataframe
fields = (:path_id, :timestep, fields...)
df = DataFrame(values, collect(fields))
df.path_id = Int.(df.path_id)
df.timestep = Int.(df.timestep)
df
end
@doc (@doc r_get) r_get_states

# Examples:
# Define state matrix:
# * Two rows: two particles
# * Three columns: three time steps
# state = [StateXY(0.0, 1.0, 2.0) StateXY(0.0, 3.0, 4.0) StateXY(0.0, 5.0, 6.0);
# StateXY(0.0, 7.0, 8.0) StateXY(0.0, 9.0, 10.0) StateXY(0.0, 11.0, 2.0)]
# r_get_states(state)
# Create a big matrix of StateXY objects
# np = 1000
# nt = 20000
# state = [StateXY(rand(), rand(), rand()) for _ in 1:np, _ in 1:nt]
# r_get_states(state)


#### Get a Tuple of particle information (states, diagnostics, convergence)
function r_get_particles(particles::NamedTuple)
# Collate information
states = r_get_states(particles.state, particles.timesteps)
Expand All @@ -107,4 +127,5 @@ function r_get_particles(particles::NamedTuple)
diagnostics = diagnostics,
convergence = particles.convergence
)
end
end
@doc (@doc r_get) r_get_particles

0 comments on commit ba93be6

Please sign in to comment.