commit 8b1cd340b84b6f8c0481f128f91a054872906aa8
parent 24ac44e780e53040fa737ea47821045f97588acd
Author: Anders Damsgaard <andersd@riseup.net>
Date: Fri, 17 Nov 2017 13:24:47 -0500
implement several changes to file IO, use Gnuplot for plotting
Diffstat:
A | deps/build.jl | | | 41 | +++++++++++++++++++++++++++++++++++++++++ |
M | src/grain.jl | | | 57 | +++++++++++++++++++++++++++++++++++++++------------------ |
M | src/io.jl | | | 77 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
M | test/grain.jl | | | 25 | +++++++++++-------------- |
M | test/jld.jl | | | 10 | ++++++++++ |
5 files changed, 169 insertions(+), 41 deletions(-)
diff --git a/deps/build.jl b/deps/build.jl
@@ -0,0 +1,41 @@
+
+#!/usr/bin/env julia
+using BinDeps
+@BinDeps.setup
+
+import Compat
+import Compat.Sys
+
+gnuplot = library_dependency("gnuplot")
+imagemagick = library_dependency("imagemagick", aliases = ["ImageMagick"])
+
+# Debian derivatives: https://www.debian.org/distrib/packages#search_packages
+provides(AptGet, "gnuplot", gnuplot, os = :Linux)
+provides(AptGet, "imagemagick", imagemagick, os = :Linux)
+
+# RHEL derivatives: http://rpm.pbone.net/index.php3/stat/2/simple/2
+provides(Yum, "gnuplot", gnuplot, os = :Linux)
+provides(Yum, Dict("ImageMagick" => imagemagick), os = :Linux)
+
+# Arch: https://www.archlinux.org/packages/
+provides(Pacman, "gnuplot", gnuplot, os = :Linux)
+provides(Pacman, "imagemagick", imagemagick, os = :Linux)
+
+# Mac: http://formulae.brew.sh/
+if Compat.Sys.isapple()
+ using Homebrew
+ provides(Homebrew.HB, "gnuplot", gnuplot, os = :Darwin)
+ provides(Homebrew.HB, "imagemagick", imagemagick, os = :Darwin)
+end
+
+# Windows: http://software.opensuse.org/search
+if Compat.Sys.iswindows()
+ using WinRPM
+ provides(WinRPM.RPM, "gnuplot", gnuplot, os = :Windows)
+ provides(WinRPM.RPM, "imagemagick", imagemagick, os = :Windows)
+end
+
+@BinDeps.install Dict([
+ (:gnuplot => :gnuplot),
+ (:imagemagick => :imagemagick),
+ ])
diff --git a/src/grain.jl b/src/grain.jl
@@ -1,12 +1,6 @@
## Manage grains in the model
using Compat.Test
-hasPyPlot = false
-if typeof(Pkg.installed("PyPlot")) == VersionNumber
- import PyPlot
- hasPyPlot = true
-end
-
export addGrainCylindrical!
"""
function addGrainCylindrical!(simulation, lin_pos, contact_radius,
@@ -742,7 +736,8 @@ string, and the `filetype`, and is written to the current folder.
true).
* `skip_fixed::Bool`: ommit grains that are fixed in space from the size
distribution (default = true).
-* `logy::Bool`: plot y-axis in log scale.
+* `log_y::Bool`: plot y-axis in log scale.
+* `show_plot::Bool`: show plot in pop-up window in addition to writing to disk.
"""
function plotGrainSizeDistribution(simulation::Simulation;
filename_postfix::String = "",
@@ -752,12 +747,9 @@ function plotGrainSizeDistribution(simulation::Simulation;
filetype::String = "png",
verbose::Bool = true,
skip_fixed::Bool = true,
- log_y::Bool = true)
+ log_y::Bool = false,
+ show_plot::Bool = false)
- if !hasPyPlot
- error("Function not available because PyPlot is not installed")
- return
- end
diameters = Float64[]
for i=1:length(simulation.grains)
if simulation.grains[i].fixed && skip_fixed
@@ -771,14 +763,43 @@ function plotGrainSizeDistribution(simulation::Simulation;
error("size_type '$size_type' not understood")
end
end
- PyPlot.pygui(false)
- PyPlot.figure(figsize=figsize)
- PyPlot.plt[:hist](diameters, nbins, log=log_y)
- PyPlot.xlabel("Diameter [m]")
- PyPlot.ylabel("Count [-]")
+
filename = string(simulation.id * filename_postfix *
"-grain-size-distribution." * filetype)
- PyPlot.savefig(filename)
+
+ # write data to temporary file on disk
+ datafile = Base.Filesystem.tempname()
+ writedlm(datafile, diameters)
+ gnuplotscript = Base.Filesystem.tempname()
+
+ open(gnuplotscript, "w") do f
+
+ write(f, """#!/usr/bin/env gnuplot
+ set out "$(filename)"
+ set xlabel "Diameter [m]"
+ set ylabel "Count [-]"
+ set style histogram
+ plot "$(datafile)"
+ """)
+ end
+
+ try
+ run(`gnuplot $gnuplotscript`)
+ catch return_signal
+ if isa(return_signal, Base.UVError)
+ error("Could not launch external gnuplot process")
+ end
+ end
+
+
+ xlabel = "Diameter [m]"
+ ylabel = "Count [-]"
+ if log_y
+ error("Logarithmic axis scaling isn't yet supported with GR histograms")
+ # try anyway
+ GR.setscale(GR.OPTION_Y_LOG)
+ GR.setscale(GR.OPTION_FLIP_X)
+ end
if verbose
info(filename)
end
diff --git a/src/io.jl b/src/io.jl
@@ -50,9 +50,14 @@ export readSimulation
readSimulation(filename::String="";
verbose::Bool=true)
-Read all content from `Simulation` from disk in JDL format.
+Return `Simulation` content read from disk using the JDL format.
+
+# Arguments
+* `filename::String`: path to file on disk containing the simulation
+ information.
+* `verbose::Bool=true`: confirm to console that the file has been read.
"""
-function readSimulation(filename::String="";
+function readSimulation(filename::String;
verbose::Bool=true)
if !hasJLD
warn("Package JLD not found. Simulation save/read not supported. " *
@@ -60,8 +65,42 @@ function readSimulation(filename::String="";
"requirements with `Pkg.add(\"JLD\")`.")
nothing
else
+ return JLD.load(filename, "simulation")
+ if verbose
+ info("Read simulation from $filename")
+ end
+ end
+end
+"""
+ readSimulation(simulation::Simulation;
+ step::Integer = -1,
+ verbose::Bool = true)
+
+Read the simulation state from disk and return as new simulation object.
+
+# Arguments
+* `simulation::Simulation`: use the `simulation.id` to determine the file name
+ to read from, and read information from the file into this object.
+* `step::Integer=-1`: attempt to read this output file step. At its default
+ value (`-1`), the function will try to read the latest file, determined by
+ calling [`readSimulationStatus`](@ref).
+* `verbose::Bool=true`: confirm to console that the file has been read.
+"""
+function readSimulation(simulation::Simulation;
+ step::Integer = -1,
+ verbose::Bool = true)
+ if !hasJLD
+ warn("Package JLD not found. Simulation save/read not supported. " *
+ "Please install JLD and its " *
+ "requirements with `Pkg.add(\"JLD\")`.")
+ nothing
+ else
+ if step == -1
+ step = readSimulationStatus(simulation)
+ end
+ filename = string(simulation.id, "/", simulation.id, ".$step.jld")
if verbose
- info("reading simulation from $filename")
+ info("Read simulation from $filename")
end
return JLD.load(filename, "simulation")
end
@@ -86,18 +125,22 @@ function writeSimulationStatus(simulation::Simulation;
simulation.time/simulation.time_total*100.
float(simulation.file_number)])
if verbose
- info("wrote status to $filename")
+ info("Wrote status to $filename")
end
nothing
end
export readSimulationStatus
"""
- readSimulationStatus(filename::String;
- folder::String=".",
- verbose::Bool=false)
+ readSimulationStatus(simulation_id[, folder, verbose])
-Write current simulation status to disk in a minimal txt file.
+Read the current simulation status from disk (`<sim.id>/<sim.id>.status.txt`)
+and return the last output file number.
+
+# Arguments
+* `simulation_id::String`: the simulation identifying string.
+* `folder::String="."`: the folder in which to search for the status file.
+* `verbose::Bool=true`: show simulation status in console.
"""
function readSimulationStatus(simulation_id::String;
folder::String=".",
@@ -113,7 +156,23 @@ function readSimulationStatus(simulation_id::String;
" complete: $(data[2])%\n" *
" last output file: $(Int(round(data[3])))\n")
end
- return data[3]
+ return Int(round(data[3]))
+"""
+ readSimulationStatus(simulation[, folder, verbose])
+
+Read the current simulation status from disk (`<sim.id>/<sim.id>.status.txt`)
+and return the last output file number.
+
+# Arguments
+* `simulation::Simulation`: the simulation to read the status for.
+* `folder::String="."`: the folder in which to search for the status file.
+* `verbose::Bool=true`: show simulation status in console.
+"""
+end
+function readSimulationStatus(sim::Simulation;
+ folder::String=".",
+ verbose::Bool=true)
+ readSimulationStatus(sim.id, folder=folder, verbose=verbose)
end
export status
diff --git a/test/grain.jl b/test/grain.jl
@@ -30,20 +30,17 @@ Granular.addGrainCylindrical!(sim, [ 0., 0.], 10., 1., verbose=false)
Granular.addGrainCylindrical!(sim, [ 0., 0.], 10., 1., verbose=false)
Granular.compareGrains(sim.grains[1], sim.grains[2])
-if typeof(Pkg.installed("PyPlot")) == VersionNumber
- info("Testing GSD plotting ")
- Granular.plotGrainSizeDistribution(sim)
- rm("test-grain-size-distribution.png")
- Granular.plotGrainSizeDistribution(sim, skip_fixed=false)
- rm("test-grain-size-distribution.png")
- Granular.plotGrainSizeDistribution(sim, log_y=false)
- rm("test-grain-size-distribution.png")
- Granular.plotGrainSizeDistribution(sim, size_type="areal")
- rm("test-grain-size-distribution.png")
- @test_throws ErrorException Granular.plotGrainSizeDistribution(sim, size_type="asdf")
-else
- @test_throws ErrorException Granular.plotGrainSizeDistribution(sim)
-end
+info("Testing GSD plotting ")
+Granular.plotGrainSizeDistribution(sim)
+@test isfile("test-grain-size-distribution.png")
+rm("test-grain-size-distribution.png")
+Granular.plotGrainSizeDistribution(sim, skip_fixed=false)
+@test isfile("test-grain-size-distribution.png")
+rm("test-grain-size-distribution.png")
+Granular.plotGrainSizeDistribution(sim, size_type="areal")
+@test isfile("test-grain-size-distribution.png")
+rm("test-grain-size-distribution.png")
+@test_throws ErrorException Granular.plotGrainSizeDistribution(sim, size_type="asdf")
info("Testing external body force routines")
sim = Granular.createSimulation(id="test")
diff --git a/test/jld.jl b/test/jld.jl
@@ -15,7 +15,17 @@ if typeof(Pkg.installed("JLD")) == VersionNumber
Granular.writeVTK(sim, verbose=false)
Granular.writeSimulation(sim)
+ Granular.writeSimulationStatus(sim)
+ info("Reading from JLD file by specifying the input file name")
sim2 = Granular.readSimulation("./test/test.1.jld")
Granular.compareSimulations(sim, sim2)
+
+ info("Reading and overwriting from JLD file by simulation id")
+ sim3 = Granular.createSimulation("test")
+ @test 1 == Granular.readSimulationStatus(sim3)
+ sim3 = Granular.readSimulation(sim3)
+ Granular.compareSimulations(sim, sim3)
+
+ rm("./test/test.1.jld")
end