Skip to content

Commit

Permalink
Adapt the type hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
mkborregaard committed Sep 8, 2018
1 parent 8057200 commit 2039eb2
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 56 deletions.
6 changes: 4 additions & 2 deletions src/ComMatrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ end

occupancy(com::AbstractComMatrix) = occupancy(occurrences(com))
richness(com::AbstractComMatrix) = richness(occurrences(com))
occurring(com::AbstractComMatrix) = occurring(occurrences(com))
occupied(com::AbstractComMatrix) = occupied(occurrences(com))
occurring(com::AbstractComMatrix, idx...) = occurring(occurrences(com), idx...)
occupied(com::AbstractComMatrix, idx...) = occupied(occurrences(com), idx...)

const nspecies = nthings
nthings(com::AbstractComMatrix) = size(com.occurrences, 1)
Expand All @@ -29,6 +29,8 @@ const nsites = nplaces
nplaces(com::AbstractComMatrix) = size(com.occurrences, 2)
nplaces(sd::SiteData) = size(coordinates(sd.site), 1)
nplaces(sd::SELocations) = DataFrames.ncol(sd.sitestats)
nplaces(gr::GridData) = size(gr.indices, 1)
nplaces(pd::PointData) = size(pd.coords, 1)

nrecords(com::AbstractComMatrix) = _nnz(occurrences(com))

Expand Down
4 changes: 2 additions & 2 deletions src/Constructor_helperfunctions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function dropspecies!(occ::SpeciesData)
occ.traits = occ.traits[occur,:]
end

function dropbyindex!(site::PointData, indicestokeep)
function dropbyindex!(site::Locations{PointData}, indicestokeep)
site.coords = site.coords[indicestokeep,:]
site.sitestats = site.sitestats[indicestokeep,:]
end
Expand All @@ -106,7 +106,7 @@ maxrange(x) = diff([extrema(x)...])[1]

# remember here - something wrong with the indices, make sure they are based from 1!

function dropbyindex!(site::GridData, indicestokeep)
function dropbyindex!(site::Locations{GridData}, indicestokeep)
site.indices = site.indices[indicestokeep,:]
site.sitestats = site.sitestats[indicestokeep,:]
site.grid.xmin = xrange(site.grid)[minimum(site.indices[:,1])]
Expand Down
23 changes: 11 additions & 12 deletions src/Constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,31 @@ function Assemblage(occ::ComMatrix, coords::AbstractMatrix;
occ, coords, sitestat = match_commat_coords(occ, coords, sitestat)
end

Assemblage(createSELocations(coords, cdtype, sitestat), SpeciesData(occ, traits))
Assemblage(createLocations(coords, cdtype, sitestat), SpeciesData(occ, traits))
end

function Assemblage(site::S, occ::SpeciesData{D};
dropemptyspecies::Bool = false, dropemptysites::Bool = false) where {D <: Real, S <: SELocations}
function Assemblage(site::P, occ::SpeciesData{D};
dropemptyspecies::Bool = false, dropemptysites::Bool = false) where {D <: Real, P <: SELocations}

if dropemptyspecies
dropspecies!(occ)
end
if dropemptysites
dropsites!(occ, site)
end
Assemblage{S}{T}(site, occ)
Assemblage{D, P}(site, occ)
end

function createSELocations(coords::AbstractMatrix, cdtype::coordstype = auto, #by design, this is not type stable, but maybe that is OK for type constructors
function createLocations(coords::AbstractMatrix, cdtype::coordstype = auto, #by design, this is not type stable, but maybe that is OK for type constructors
sitestat = DataFrames.DataFrame(sites = sitenames(occ)))

cdtype == pointdata && return PointData(coords, sitestat)
cdtype == griddata && return GridData(coords, sitestat)
cdtype == pointdata && return Locations{PointData}(PointData(coords), sitestat)
cdtype == griddata && return Locations{GridData}(GridData(coords), sitestat)
if cdtype == auto
try
return GridData(coords, sitestat)
return Locations{GridData}(GridData(coords), sitestat)
catch
return PointData(coords, sitestat)
return Locations{PointData}(PointData(coords), sitestat)
end
end
end
Expand Down Expand Up @@ -131,9 +131,8 @@ function ComMatrix(occurrences; specnames = :auto, sitenames = :auto, sitecolumn
ComMatrix{eltype(occurrences)}(sparse(occurrences), string.(specnames), string.(sitenames))
end

function GridData(coords::AbstractMatrix{<:Union{AbstractFloat, Missings.Missing}},
sitestats::DataFrames.DataFrame = DataFrames.DataFrame(id = 1:size(coords,1)))
function GridData(coords::AbstractMatrix{<:Union{AbstractFloat, Missing}})
grid = creategrid(coords)
indices = getindices(coords, grid)
GridData(indices, grid, sitestats)
GridData(indices, grid)
end
36 changes: 15 additions & 21 deletions src/DataTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
# implement with unions
abstract type SESpatialData <: EcoBase.AbstractPlaces end
abstract type SELocations <: EcoBase.AbstractLocations end
abstract type SEPointData <: SELocations end
abstract type SEGrid <: EcoBase.AbstractGrid end
abstract type SEThings{D <: Real} <: EcoBase.AbstractThings end
abstract type SEGrid <: EcoBase.AbstractGrid end
abstract type SEPointData end

abstract type AbstractComMatrix{ D<:Real } end


# I could implement sitestats as a Dict with several DataFrames to make space for big data sets, but I prefer to not do this now. Example below.

# I could do a lot more with immutable types if I had a clearer view/copy implementation
mutable struct GridTopology
mutable struct GridTopology <: EcoBase.AbstractGrid
xmin::Number
xcellsize::Number
xcells::Int
Expand All @@ -32,28 +32,22 @@ mutable struct Bbox
ymax::Number
end


# Do I need sitenames here? I think so, they should match those in sitestats, and be separate
mutable struct PointData <: SEPointData
coords::Matrix{Float64}
sitestats::DataFrames.DataFrame
# inner constructor
function PointData(coords, sitestats = DataFrames.DataFrame(id = 1:size(coords,1)))

DataFrames.nrow(sitestats) == size(coords, 1) || throw(DimensionMismatch("Wrong number of rows in sitestat")) # a little check for the right number
new(coords, sitestats)
end
end


mutable struct GridData <: SEGrid
indices::Matrix{Int}
grid::GridTopology
sitestats::DataFrames.DataFrame
end

function GridData(indices, grid, sitestats = DataFrames.DataFrame(id = 1:size(coords,1)))
DataFrames.nrow(sitestats) == size(indices, 1) || throw(DimensionMismatch("Wrong number of rows in sitestat")) # a little check for the right number
new(indices, grid, sitestats)
mutable struct Locations{T<:Union{GridData, PointData}} <: SELocations
coords::T
sitestats::DataFrames.DataFrame
function Locations{T}(coords, sitestats = DataFrames.DataFrame(id = 1:size(coords,1))) where T
DataFrames.nrow(sitestats) == nsites(coords) || throw(DimensionMismatch("Wrong number of rows in sitestat")) # a little check for the right number
new(coords, sitestats)
end
end

Expand All @@ -77,18 +71,18 @@ end
SpeciesData(commatrix::ComMatrix{D}, traits) where D<:Real = SpeciesData{D}(commatrix, traits)

# Not really sure what this type is for
mutable struct SiteData{S} <: SESpatialData where S <: SELocations
mutable struct SiteData{S} <: SESpatialData where S <: Locations
site::S
end

abstract type SEAssemblage{D<:Real, P<:SELocations} <: EcoBase.AbstractAssemblage{D, SpeciesData, P} end
abstract type SEAssemblage{D<:Real, T<:SEThings, P<:SELocations} <: EcoBase.AbstractAssemblage{D, T, P} end

mutable struct Assemblage{D<:Real, P<:SELocations} <: SEAssemblage{D, P} # A type to keep subtypes together, ensuring that they are all aligned at all times
mutable struct Assemblage{D<:Real, P<:Locations} <: SEAssemblage{D, SpeciesData{D}, P} # A type to keep subtypes together, ensuring that they are all aligned at all times
site::P
occ::SpeciesData
occ::SpeciesData{D}

# inner constructor
function Assemblage{D, P}(site::P, occ::SpeciesData, com::ComMatrix{D}) where {P <: SELocations, D <: Real}
function Assemblage{D, P}(site::P, occ::SpeciesData{D}) where {P <: SELocations, D <: Real}
size(occurrences(occ), 2) == size(coordinates(site), 1) || error("Length mismatch between occurrence matrix and coordinates")
#TODO activate this # sitenames(occ) == sitenames(site) || error("sitenames do not match") #I need a constructor that matches them up actively
new(site, occ)
Expand Down
16 changes: 9 additions & 7 deletions src/Gridfunctions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ xcells(g::GridTopology) = g.xcells
ycells(g::GridTopology) = g.ycells
boundingbox(g::GridTopology) = Bbox(xmin(g), xmax(g), ymin(g), ymax(g))

@forward_func SEGrid.grid xmin, ymin, xcellsize, ycellsize, cellsize, xcells, ycells, cells, xrange, yrange, xmax, ymax, boundingbox
@forward_func GridData.grid xmin, ymin, xcellsize, ycellsize, cellsize, xcells, ycells, cells, xrange, yrange, xmax, ymax, boundingbox
@forward_func Locations{GridData}.coords xmin, ymin, xcellsize, ycellsize, cellsize, xcells, ycells, cells, xrange, yrange, xmax, ymax, boundingbox


show(io::IO, b::Bbox) = println(io, "xmin:\t$(b.xmin)\nxmax:\t$(b.xmax)\nymin:\t$(b.ymin)\nymax:\t$(b.ymax)")
show(io::IO, g::SEGrid) = println(io,
"""Spatial grid
Lower left corner: $(xmin(g)), $(ymin(g))
Cellsizes : $(xcellsize(g)), $(ycellsize(g))
Size : $(xcells(g)), $(ycells(g))
""")
show(io::IO, g::GridData) = println(io,
"""
Spatial grid
lower left : $(xmin(g)), $(ymin(g))
cellsizes : $(xcellsize(g)), $(ycellsize(g))
size : $(xcells(g)), $(ycells(g))""")
25 changes: 14 additions & 11 deletions src/Subsetting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,27 @@ mutable struct SubSpeciesData{D <: Real} <: SEThings{D}
traits::DataFrames.SubDataFrame
end

mutable struct SubGridData <: SEGrid
mutable struct SubGridData <: EcoBase.AbstractGrid
indices::SubArray{Int,2}
grid::GridTopology
sitestats::DataFrames.SubDataFrame
end

mutable struct SubPointData <: SEPointData
mutable struct SubPointData
coords::SubArray{Float64,2}
end

mutable struct SubLocations{T<:Union{SubGridData, SubPointData}} <: SELocations
coords::T
sitestats::DataFrames.SubDataFrame
end

mutable struct SubAssemblage{D <: Real, P <: Union{SubGridData, SubPointData}} <: SEAssemblage{D, P} # A type to keep subtypes together, ensuring that they are all aligned at all times
mutable struct SubAssemblage{D <: Real, P <: SubLocations} <: SEAssemblage{D, SubSpeciesData{D}, P} # A type to keep subtypes together, ensuring that they are all aligned at all times
site::P
occ::SubSpeciesData
occ::SubSpeciesData{D}
end

# TODO delete
mutable struct SubSiteData{S} <: SESpatialData where S <: Union{SubGridData, SubPointData}
mutable struct SubSiteData{S} <: SESpatialData where S <: SubLocations
site::S
end

Expand All @@ -50,12 +53,12 @@ function view(com::AbstractComMatrix; species = 1:nspecies(com), sites = 1:nsite
SubComMatrix(view(com.occurrences, spec, sit), view(com.specnames, spec), view(com.sitenames, sit)) #TODO change the order of these in the object to fit the array index order
end

view(pd::SEPointData, sites) = SubPointData(view(pd.coords, sites), view(pd.sitestats, sites))

view(gd::SEGrid, sites) = SubGridData(view(gd.indices, sites, :), gd.grid, view(gd.sitestats, sites))
view(pd::SEPointData, sites) = SubPointData(view(pd.coords, sites))
view(gd::SEGrid, sites) = SubGridData(view(gd.indices, sites, :), gd.grid)
view(gd::SELocations, sites) = SubLocations{SubGridData}(view(gd.coords, sites), view(gd.sitestats, sites))
view(sp::SESpatialData, sites = 1:nsites(sp)) = SubSiteData(view(sp.site, sites))

function view(asm::SEAssemblage; species = 1:nspecies(asm), sites = 1:nsites(asm), dropsites = false, dropspecies = false, dropempty = false)
function view(asm::SEAssemblage{D, P}; species = 1:nspecies(asm), sites = 1:nsites(asm), dropsites = false, dropspecies = false, dropempty = false) where D where P
occ = view(asm.occ, species = species, sites = sites)
site = view(asm.site, sites)

Expand All @@ -69,7 +72,7 @@ function view(asm::SEAssemblage; species = 1:nspecies(asm), sites = 1:nsites(asm
occ = view(occ, species = occurring(occ))
end

SubAssemblage(site, occ)
SubAssemblage{D, typeof(site)}(site, occ)
end

Assemblage(assm::SubAssemblage) = copy(assm)
Expand Down
2 changes: 1 addition & 1 deletion test/Assemblage_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using Test
amphdat = CSV.read(joinpath(dirname(pathof(SpatialEcology)), "..", "data", "amph_Europe.csv"))
amph = Assemblage(amphdat[4:end], amphdat[1:3], sitecolumns = false)

@test typeof(amph) == Assemblage{SpatialEcology.GridData,Bool}
@test typeof(amph) == Assemblage{Bool,SpatialEcology.Locations{SpatialEcology.GridData}}

# accesseors
@test extrema(richness(amph)) == (1, 20)
Expand Down

0 comments on commit 2039eb2

Please sign in to comment.