Skip to content

Commit

Permalink
Merge pull request #51 from cesaraustralia/bugfix_tspan
Browse files Browse the repository at this point in the history
add tstopped to extent to fix tspan bug
  • Loading branch information
rafaqz authored Jul 28, 2020
2 parents c113e52 + d347e90 commit c775eed
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 71 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DynamicGrids"
uuid = "a5dba43e-3abc-5203-bfc5-584ca68d3f5b"
authors = ["Rafael Schouten <[email protected]>"]
version = "0.10.0"
version = "0.10.1"

[deps]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Expand Down
2 changes: 1 addition & 1 deletion src/DynamicGrids.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import FieldMetadata: @description, description,
export sim!, resume!, replay, savegif, isinferred, method, methodtype

export rules, neighbors, inbounds, isinbounds, radius, gridsize,
currenttime, currenttimestep, timestep, tspan
currenttime, currenttimestep, timestep

export Rule, NeighborhoodRule, CellRule, ManualRule, ManualNeighborhoodRule

Expand Down
20 changes: 8 additions & 12 deletions src/extent.jl
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@

"""
Extent(init, mask, tspan, aux)
Extent(; init, mask=nothing, tspan, aux=nothing, kwargs...)
Extent(init, mask, aux, tspan, tstopped)
Extent(; init, mask=nothing, aux=nothing, tspan, kwargs...)
Container for extensive variables: spatial and timeseries data.
These are kept separate from rules to allow application
of rules to alternate spatial and temporal contexts.
Not usually constructed directly by users, but it can be passed to outputs
instead of `init`, `mask`, `tspan` and `aux`.
Extent is not usually constructed directly by users, but it can be passed
to `Output` constructors instead of `init`, `mask`, `aux` and `tspan`.
"""
mutable struct Extent{I,M,A}
init::I
mask::M
tspan::AbstractRange
aux::A
tspan::AbstractRange
end
Extent(; init, mask=nothing, tspan, aux=nothing, kwargs...) =
Extent(init, mask, tspan, aux)
Extent(; init, mask=nothing, aux=nothing, tspan, kwargs...) =
Extent(init, mask, aux, tspan)

init(e::Extent) = e.init
mask(e::Extent) = e.mask
tspan(e::Extent) = e.tspan
aux(e::Extent) = e.aux
tspan(e::Extent) = e.tspan

settspan!(e::Extent, tspan) = e.tspan = tspan
setstarttime!(e::Extent, start) =
e.tspan = start:step(tspan(e)):last(tspan(e))
setstoptime!(e::Extent, stop) =
e.tspan = first(tspan(e)):step(tspan(e)):stop

gridsize(extent::Extent) = gridsize(init(extent))
gridsize(A::AbstractArray) = size(A)
Expand Down
37 changes: 18 additions & 19 deletions src/framework.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,20 @@ sim!(output::Output, ruleset=ruleset(output);
throw(ArgumentError("tspan step $(step(tspan)) must equal rule step $(step(ruleset))"))

# Rebuild Extent to allow kwarg alterations
extent = Extent(asnamedtuple(init), mask, tspan, aux)
extent = Extent(; init=asnamedtuple(init), mask=mask, aux=aux, tspan=tspan)
# Set up output
initialise(output)
isrunning(output) && error("A simulation is already running in this output")
setrunning!(output, true) || error("Could not start the simulation with this output")
setstarttime!(output, first(tspan))
settspan!(output, tspan)
# Create or update the combined data object for the simulation
simdata = initdata!(simdata, extent, ruleset, nreplicates)
# Delete grids output by the previous simulations
initgrids!(output, init)
# Set run speed for GraphicOutputs
setfps!(output, fps)
# Show the first grid
showframe(output, simdata, 1, tspan)
showframe(output, simdata, 1, first(tspan))
# Let the init grid be displayed as long as a normal grid
delay(output, 1)
# Run the simulation over simdata and a unitrange
Expand All @@ -78,14 +78,14 @@ sim!(output::Output, rules::Rule...;
end

"""
resume!(output::Output, ruleset::Ruleset;
tstop=stoptime(output),
resume!(output::GraphicOutput, ruleset::Ruleset;
tstop=last(tspan(output)),
fps=fps(output),
simdata=nothing,
nreplicates=nothing)
Restart the simulation from where you stopped last time. For arguments see [`sim!`](@ref).
The keyword arg `stop` can be used to extend the length of the simulation.
The keyword arg `tstop` can be used to extend the length of the simulation.
### Arguments
- `output`: An [`Output`](@ref) to store grids or display them on the screen.
Expand All @@ -100,33 +100,32 @@ The keyword arg `stop` can be used to extend the length of the simulation.
- `simdata`: a [`SimData`](@ref) object. Keeping it between simulations can improve performance
when that is important
"""
resume!(output::Output, ruleset::Ruleset=ruleset(output);
tstop=stoptime(output),
resume!(output::GraphicOutput, ruleset::Ruleset=ruleset(output);
tstop=last(tspan(output)),
fps=fps(output),
simdata=nothing,
nreplicates=nothing) = begin
# Initialise
initialise(output)
# Check status and arguments
length(output) > 0 || error("There is no simulation to resume. Run `sim!` first")
isrunning(output) && error("A simulation is already running in this output")
setrunning!(output, true) || error("Could not start the simulation with this output")

# Calculate new timespan
lastframe = lastindex(tspan(output))
new_tspan = tspan(output)[1]:step(tspan(output)):tstop
stopframe = lastindex(new_tspan)
fspan = lastframe:stopframe
setstoptime!(output, tstop)
new_tspan = first(tspan(output)):step(tspan(output)):tstop
stoppedframe_ = stoppedframe(output)
fspan = stoppedframe_:lastindex(new_tspan)
settspan!(output, new_tspan)

# Use the last frame of the existing simulation as the init frame
if lastframe <= length(output)
init = output[lastframe]
if stoppedframe_ <= length(output)
init = output[stoppedframe_]
else
init = first(output)
init = output[1]
end

setfps!(output, fps)
extent = Extent(asnamedtuple(init), mask(output), new_tspan, aux(output))
extent = Extent(; init=asnamedtuple(init), mask=mask(output), aux=aux(output), tspan=new_tspan)
simdata = initdata!(simdata, extent, ruleset, nreplicates)
runsim!(output, simdata, fspan)
end
Expand Down Expand Up @@ -164,7 +163,7 @@ simloop!(output::Output, simdata, fspan) = begin
# Exit gracefully
if !isrunning(output) || f == last(fspan)
showframe(output, simdata, f, currenttime(simdata))
setstoptime!(output, currenttime(simdata))
setstoppedframe!(output, f)
finalise(output)
break
end
Expand Down
16 changes: 9 additions & 7 deletions src/outputs/graphic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,29 @@ const RulesetOrSimData = Union{AbstractRuleset,AbstractSimData}
Config and variables for graphic outputs.
"""
mutable struct GraphicConfig{FPS,TS,SF}
mutable struct GraphicConfig{FPS,TS}
fps::FPS
timestamp::TS
stampframe::SF
stampframe::Int
stoppedframe::Int
store::Bool
end
GraphicConfig(; fps=25.0, store=false, kwargs...) =
GraphicConfig(fps, 0.0, 1, store)

GraphicConfig(fps, 0.0, 1, 1, store)

fps(gc::GraphicConfig) = gc.fps
timestamp(gc::GraphicConfig) = gc.timestamp
stampframe(gc::GraphicConfig) = gc.stampframe
stoppedframe(gc::GraphicConfig) = gc.stoppedframe
store(gc::GraphicConfig) = gc.store
setfps!(gc::GraphicConfig, x) = gc.fps = x
settimestamp!(o::GraphicConfig, f) = begin
o.timestamp = time()
o.stampframe = f
end

setstoppedframe!(gc::GraphicConfig, f) = gc.stoppedframe = f

"""
Outputs that display the simulation frames live.
Expand All @@ -53,14 +56,13 @@ graphicconfig(o::GraphicOutput) = o.graphicconfig
fps(o::GraphicOutput) = fps(graphicconfig(o))
timestamp(o::GraphicOutput) = timestamp(graphicconfig(o))
stampframe(o::GraphicOutput) = stampframe(graphicconfig(o))
stoppedframe(o::GraphicOutput) = stoppedframe(graphicconfig(o))
store(o::GraphicOutput) = store(graphicconfig(o))
isstored(o::GraphicOutput) = store(o)

setfps!(o::Output, x) = nothing
setfps!(o::GraphicOutput, x) = setfps!(graphicconfig(o), x)

settimestamp!(o::Output, f) = nothing
settimestamp!(o::GraphicOutput, f) = settimestamp!(graphicconfig(o), f)
setstoppedframe!(o::GraphicOutput, f) = setstoppedframe!(graphicconfig(o), f)

# Output interface
# Delay output to maintain the frame rate
Expand Down
5 changes: 2 additions & 3 deletions src/outputs/image.jl
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,8 @@ Converts output grids to a colorsheme.
maskcolor::M | nothing
textconfig::TC | nothing
end
ColorProcessor(scheme::S, zerocolor::Z=nothing, maskcolor::M=nothing, textconfig::TC=nothing
) where {S,Z,M,TC} =
ColorProcessor{S,Z,M,TC}(scheme, zerocolor, maskcolor, textconfig)
ColorProcessor(scheme, zerocolor=nothing, maskcolor=nothing) =
ColorProcessor(scheme, zerocolor, maskcolor, nothing)

scheme(processor::ColorProcessor) = processor.scheme
zerocolor(processor::ColorProcessor) = processor.zerocolor
Expand Down
9 changes: 4 additions & 5 deletions src/outputs/output.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,18 @@ isrunning(o::Output) = o.running
extent(o::Output) = o.extent
init(o::Output) = init(extent(o))
mask(o::Output) = mask(extent(o))
tspan(o::Output) = tspan(extent(o))
aux(o::Output) = aux(extent(o))
starttime(o::Output) = first(tspan(o))
stoptime(o::Output) = last(tspan(o))
tspan(o::Output) = tspan(extent(o))
Base.step(o::Output) = step(tspan(o))
ruleset(o::Output) =
throw(ArgumentError("No ruleset on the output. Pass one to `sim!` as the second argument"))
fps(o::Output) = nothing

setrunning!(o::Output, val) = o.running = val
settspan!(o::Output, tspan) = settspan!(extent(o), tspan)
setstarttime!(o::Output, start) = setstarttime!(extent(o), start)
setstoptime!(o::Output, stop) = setstoptime!(extent(o), stop)
setfps!(o::Output, x) = nothing
settimestamp!(o::Output, f) = nothing
setstoppedframe!(o::Output, f) = nothing

"""
isasync(o::Output)
Expand Down
2 changes: 1 addition & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ end

asnamedtuple(x::NamedTuple) = x
asnamedtuple(x::AbstractArray) = (_default_=x,)
asnamedtuple(e::Extent) = Extent(asnamedtuple(init(e)), mask(e), tspan(e), aux(e))
asnamedtuple(e::Extent) = Extent(asnamedtuple(init(e)), mask(e), aux(e), tspan(e))

zerogrids(initgrid::AbstractArray, nframes) = [zero(initgrid) for f in 1:nframes]
zerogrids(initgrids::NamedTuple, nframes) =
Expand Down
6 changes: 3 additions & 3 deletions test/image.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ end
@test frames(output)[1] == 5init
@test isshowable(output, 1)

simdata = SimData(Extent(init, nothing, 1:10, nothing), Ruleset(Life()))
simdata = SimData(Extent(; init=init, tspan=1:10), Ruleset(Life()))
@test_broken showframe(output, simdata, 1, 1) ==
[ARGB32(1.0, 1.0, 1.0) ARGB32(1.0, 1.0, 1.0)
ARGB32(0.0, 0.0, 0.0) ARGB32(1.0, 1.0, 1.0)]
Expand All @@ -97,7 +97,7 @@ end
@test maxval(output) === 10.0
@test processor(output) == ColorProcessor(zerocolor=(1.0, 0.0, 0.0))
@test isstored(output) == true
simdata = SimData(Extent(init, nothing, 1:10, nothing), Ruleset(Life()))
simdata = SimData(Extent(; init=init, tspan=1:10), Ruleset(Life()))

# Test level normalisation
normed = normalise.(output[1][:a], minval(output), maxval(output))
Expand Down Expand Up @@ -191,7 +191,7 @@ end
@test maxval(output) === (10, 20)
@test processor(output) === proc
@test isstored(output) == true
simdata = SimData(Extent(init, nothing, 1:10, nothing), Ruleset(Life()))
simdata = SimData(Extent(; init=init, tspan=1:10), Ruleset(Life()))

# Test image is joined from :a, nothing, :b
@test grid2image(output, Ruleset(), multiinit, 1) ==
Expand Down
16 changes: 9 additions & 7 deletions test/integration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,15 @@ end
opt=SparseOpt(),
)
tspan = Date(2010, 4):Month(1):Date(2010, 7)
output = REPLOutput(init_a; tspan=tspan, style=Braile(), fps=100, store=true)
output = REPLOutput(init_a; tspan=tspan, style=Braile(), fps=100, store=false)

sim!(output, ruleset)
@test output[2][:_default_] == test6_7[:test2]
@test output[3][:_default_] == test6_7[:test3]
@test output[1][:_default_] == test6_7[:test4]
@test DynamicGrids.tspan(output) == Date(2010, 4):Month(1):Date(2010, 7)
resume!(output, ruleset; tstop=Date(2010, 11))
@test DynamicGrids.tspan(output) == Date(2010, 4):Month(1):Date(2010, 11)
@test output[5][:_default_] == test6_7[:test5]
@test output[7][:_default_] == test6_7[:test7]

resume!(output, ruleset; tstop=Date(2010, 10))
@test DynamicGrids.tspan(output) == Date(2010, 4):Month(1):Date(2010, 10)
@test output[1][:_default_] == test6_7[:test7]

end

6 changes: 3 additions & 3 deletions test/neighborhoods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ end
hood = Moore(1)
rule = TestManualNeighborhoodRule{:a,:a}(hood)
ruleset = Ruleset(rule)
extent = Extent((_default_=init,), nothing, 1:1, nothing)
extent = Extent(; init=(_default_=init,), tspan=1:1)
simdata = SimData(extent, ruleset)
state = 5
index = (3, 3)
Expand All @@ -179,7 +179,7 @@ end
hood = Positional(((-1, -1), (1, 1)))
rule = TestManualNeighborhoodRule{:a,:a}(hood)
ruleset = Ruleset(rule)
extent = Extent((_default_=init,), nothing, 1:1, nothing)
extent = Extent(; init=(_default_=init,), tspan=1:1)
simdata = SimData(extent, ruleset)
state = 1
index = (5, 5)
Expand All @@ -200,7 +200,7 @@ end
rule = TestManualNeighborhoodRule{:a,:a}(hood)
@test radius(rule) === 2
ruleset = Ruleset(rule)
extent = Extent((_default_=init,), nothing, 1:1, nothing)
extent = Extent(; init=(_default_=init,), tspan=1:1)
simdata = SimData(extent, ruleset)
state = 1
index = (3, 3)
Expand Down
8 changes: 4 additions & 4 deletions test/rules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ applyrule(data, ::TestRule, state, index) = 0
@test DynamicGrids.timestep(ruleset) === nothing
@test DynamicGrids.ruleset(ruleset) === ruleset

extent = Extent((_default_=init,), nothing, 1:1, nothing)
extent = Extent(; init=(_default_=init,), tspan=1:1)
simdata = SimData(extent, ruleset)

# Test maprules components
Expand All @@ -82,7 +82,7 @@ applyrule!(data, ::TestManual, state, index) = 0
ruleset = Ruleset(rule)
mask = nothing
# Test type stability
extent = Extent((_default_=init,), nothing, 1:1, nothing)
extent = Extent(; init=(_default_=init,), tspan=1:1)
simdata = SimData(extent, ruleset)
rkeys, rgrids = getgrids(_Read_(), rule, simdata)
wkeys, wgrids = getgrids(_Write_(), rule, simdata)
Expand All @@ -106,7 +106,7 @@ applyrule!(data, ::TestManualWrite, state, index) = data[:_default_][index[1], 2

rule = TestManualWrite()
ruleset = Ruleset(rule)
extent = Extent((_default_=init,), nothing, 1:1, nothing)
extent = Extent(; init=(_default_=init,), tspan=1:1)
simdata = SimData(extent, ruleset)
resultdata = maprule!(simdata, rule)
@test source(first(resultdata)) == final
Expand All @@ -127,7 +127,7 @@ applyrule(data, ::TestCellSquare, (state,), index) = state^2
rule = Chain(TestCellTriple(),
TestCellSquare())
ruleset = Ruleset(rule)
extent = Extent((_default_=init,), nothing, 1:1, nothing)
extent = Extent(; init=(_default_=init,), tspan=1:1)
simdata = SimData(extent, ruleset)
resultdata = maprule!(simdata, ruleset.rules[1]);
@test source(first(resultdata)) == final
Expand Down
Loading

2 comments on commit c775eed

@rafaqz
Copy link
Member Author

@rafaqz rafaqz commented on c775eed Jul 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/18579

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.10.1 -m "<description of version>" c775eeda0a3d48c76779da8fd8740141b50fee48
git push origin v0.10.1

Please sign in to comment.