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

refactor: Rework parametric types for more flexibility #807

Closed
Closed
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
4 changes: 1 addition & 3 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"

#[compat]
#Documenter = "~0.25"
GMT = "5752ebe1-31b9-557e-87aa-f909b540aa54"
4 changes: 4 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
using Pkg
Pkg.activate("$(@__DIR__)")
Pkg.update()

using Documenter, GMT, GMT.Drawing, GMT.Gdal

makedocs(
Expand Down
4 changes: 2 additions & 2 deletions docs/src/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ The issue with this solution, that could be implemented internally without user
currently only works on Windows.

Another alternative to a file format is the option to create RGB images with *psconvert* and
return it to Julia as a [Image type](@ref) type.
return it to Julia as a [`GMTimage`](@ref) type.

I = psconvert(in_memory=true, adjust=true)

Expand All @@ -194,7 +194,7 @@ image with the [`Images.jl`](https://github.com/JuliaImages/Images.jl) package.

As referred in the [Monolithic](@ref) section, we have two programs to do read and writing. Their
module names are *gmtread* and *gmtwrite*. These modules allow to import and export any of the GMT
data types to and from external files. For instance, to save the grid *G* stored into a GMTgrid type
data types to and from external files. For instance, to save the grid *G* stored into a [`GMTgrid`](@ref) type
into the file *relief.nc* we run

gmtwrite("relief.nc", G)
Expand Down
6 changes: 3 additions & 3 deletions docs/src/quick_learn.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ be achieved by previously reading the grid file.

Though not particularly useful nor memory more efficient to read the grid first this example illustrates
typical usage. That is, use GMT to process and map/plot data resident in Julia memory. GMT modules know
how to manipulate import/create data stored in `GMTgrid`[Grid type](@ref), `GMTimage`[Image type](@ref),
`GMTdataset`[Dataset type](@ref), `GMTcpt`[CPT type](@ref) and `GMTps`[Postscript type](@ref) objects.
The helper functions `mat2grid`, `mat2img` and `mat2ds` exist to allow creating those objects from 2D arrays
how to manipulate import/create data stored in [`GMTgrid`](@ref), [`GMTimage`](@ref),
[`GMTdataset`](@ref), [`GMTcpt`](@ref) and [`GMTps`](@ref) objects.
The helper functions [`mat2grid`](@ref), [`mat2img`](@ref) and [`mat2ds`](@ref) exist to allow creating those objects from 2D arrays
of floats, uint8, uint16 and MxN matrices respectively.

Example: create three grids with random data, compute their average and display it
Expand Down
103 changes: 7 additions & 96 deletions docs/src/types.md
Original file line number Diff line number Diff line change
@@ -1,99 +1,10 @@
# The GMT.jl types

Grid type
---------
```@docs
GMTgrid
GMTimage
GMTdataset
GMTcpt
GMTps
```

type GMTgrid{T<:Real,N} <: AbstractArray{T,N} # The type holding a local header and data of a GMT grid
proj4::String # Projection string in PROJ4 syntax (Optional)
wkt::String # Projection string in WKT syntax (Optional)
epsg::Int # EPSG code
range::Array{Float64,1} # 1x6[8] vector with [x_min, x_max, y_min, y_max, z_min, z_max [, v_min, v_max]]
inc::Array{Float64,1} # 1x2[3] vector with [x_inc, y_inc [,v_inc]]
registration::Int # Registration type: 0 -> Grid registration; 1 -> Pixel registration
nodata::Float64 # The value of nodata
title::String # Title (Optional)
comment::String # Remark (Optional)
command::String # Command used to create the grid (Optional)
names::Vector{String} # To use whith multi-layered and when layers have names (Optional)
x::Array{Float64,1} # [1 x n_columns] vector with XX coordinates
y::Array{Float64,1} # [1 x n_rows] vector with YY coordinates
v::Array{Float64,1} # [v x n_bands] vector with VV (vertical for 3D grids) coordinates
z::Array{Float32,2} # [n_rows x n_columns] grid array
x_units::String # Units of XX axis (Optional)
y_units::String # Units of YY axis (Optional)
v_units::String # Units of Vertical axis (Optional)
z_units::String # Units of z vlues (Optional)
layout::String # A three character string describing the grid memory layout
scale::Union{Float64, Float32} # When saving in file apply `z = z * scale + offset`
offset::Union{Float64, Float32}
pad::Int # When != 0 means that the array is placed in a padded array of PAD rows/cols
end

Image type
----------

type GMTimage{T<:Unsigned, N} <: AbstractArray{T,N} # The type holding a local header and data of a GMT image
proj4::String # Projection string in PROJ4 syntax (Optional)
wkt::String # Projection string in WKT syntax (Optional)
epsg::Int # EPSG code
range::Array{Float64,1} # 1x6 vector with [x_min x_max y_min y_max z_min z_max]
inc::Array{Float64,1} # 1x2 vector with [x_inc y_inc]
registration::Int # Registration type: 0 -> Grid registration; 1 -> Pixel registration
nodata::Unsigned # The value of nodata
color_interp::String # If equal to "Gray" an indexed image with no cmap will get a gray cmap
metadata::Vector{String} # To store any metadata that can eventually be passed to GDAL (Optional)
names::Vector{String} # To use whith multi-band and when bands have names (Optional)
x::Array{Float64,1} # [1 x n_columns] vector with XX coordinates
y::Array{Float64,1} # [1 x n_rows] vector with YY coordinates
v::Array{Float64,1} # [v x n_bands] vector with vertical coords or wavelengths in hypercubes (Optional)
image::Array{T,N} # [n_rows x n_columns x n_bands] image array
colormap::Array{Int32,1} #
alpha::Array{UInt8,2} # A [n_rows x n_columns] alpha array
layout::String # A four character string describing the image memory layout
pad::Int # When != 0 means that the array is placed in a padded array of PAD rows/cols
end

Dataset type
------------

type GMTdataset{T<:Real, N} <: AbstractArray{T,N}
data::Array{T,N} # Mx2 Matrix with segment data
ds_bbox::Vector{Float64} # Global BoundingBox (for when there are many segments)
bbox::Vector{Float64} # Segment BoundingBox
attrib::Dict{String, String} # Dictionary with attributes/values (optional)
colnames::Vector{String} # Column names. Antecipate using this with a future Tables inerface
text::Vector{String} # Array with text after data coordinates (mandatory only when plotting Text)
header::String # String with segment header (Optional but sometimes very useful)
comment::Vector{String} # Array with any dataset comments [empty after first segment]
proj4::String # Projection string in PROJ4 syntax (Optional)
wkt::String # Projection string in WKT syntax (Optional)
geom::Integer # Geometry type. One of the GDAL's enum (wkbPoint, wkbPolygon, etc...)
end

CPT type
--------

type GMTcpt
colormap::Array{Float64,2}
alpha::Array{Float64,1}
range::Array{Float64,2}
minmax::Array{Float64,1}
bfn::Array{Float64,2}
depth::Cint
hinge::Cdouble
cpt::Array{Float64,2}
label::Vector{String} # Labels of a Categorical CPT
key::Vector{String} # Keys of a Categorical CPT
model::String
comment::Array{Any,1} # Cell array with any comments
end

Postscript type
---------------

type GMTps
postscript::String # Actual PS plot (text string)
length::Int # Byte length of postscript
mode::Int # 1 = Has header, 2 = Has trailer, 3 = Has both
comment::Array{Any,1} # Cell array with any comments
end
Copy link
Member

Choose a reason for hiding this comment

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

But this would loose the descriptions of each field

Copy link
Author

@adigitoleo adigitoleo Jan 17, 2022

Choose a reason for hiding this comment

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

I don't think it should, from this commit you can run julia --project and in the REPL do a ?GMTgrid. This shows the fields as I have added to the source docstrings, e.g. https://github.com/GenericMappingTools/GMT.jl/pull/807/files/8699804706c9979b804e20ad82be0787f98cd972#diff-f757a5fd59739f474cf66fd576eab2d7099ebc0bd28dda3ad57e92bfa6ca7829R1-R32

I'm pretty sure that documenter shows the same information, and also now they are accessible via REPL help.

OH I think I see what you mean now, we lose the default output of e.g. ?GMTgrid:

  No documentation found.

  Summary
  ≡≡≡≡≡≡≡≡≡

  mutable struct GMTdataset{T<:Real, N}

  Fields
  ≡≡≡≡≡≡≡≡

  data     :: Array{T<:Real, N}
  ds_bbox  :: Vector{Float64}
  bbox     :: Vector{Float64}
  attrib   :: Dict{String, String}
  colnames :: Vector{String}
  text     :: Vector{String}
  header   :: String
  comment  :: Vector{String}
  proj4    :: String
  wkt      :: String
  geom     :: Int64

  Supertype Hierarchy
  ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

  GMTdataset{T<:Real, N} <: AbstractArray{T<:Real, N} <: Any

I still think the version with descriptions is more valuable. The other option is to document each field and use DocStringExtensions to automatically merge the field docstrings into the type docstring.

Copy link
Member

Choose a reason for hiding this comment

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

Having field descriptions on REPL would be nice but no big deal. Before there no description at all of the type.
And I missed to see that you had added docstrings in gmt_main.jl, hence my previous comment.

14 changes: 7 additions & 7 deletions docs/src/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ between the GMT structures and native Julia structures, which are:
- **Grids**: Many tools consider equidistant grids a particular data type and numerous file formats
exist for saving such data. Because GMT relies on GDAL we are able to read and write almost
all such formats in addition to a native netCDF4 format that complies with both the COARDS
and CF netCDF conventions. We have designed a native Julia grid structure [Grid type](@ref)
and CF netCDF conventions. We have designed a native Julia grid structure [`GMTgrid`](@ref)
that holds header information from the GMT grid as well as the data matrix representing the
gridded values. These structures may be passed to GMT modules that expect grids and are
returned from GMT modules that produce such grids. In addition, we supply the function [mat2grid](@ref)
returned from GMT modules that produce such grids. In addition, we supply the function [`mat2grid`](@ref)
to convert a matrix and some metadata into a grid structure.

- **Images**: The raster image shares many characteristics with the grid structure except the
bytes representing each node reflect gray shade, color bands (1, 3, or 4 for indexed, RGB and
RGBA, respectively), and possibly transparency values. We therefore represent images in another
native structure [Image type](@ref) that among other items contains three components: The image
native structure [`GMTimage`](@ref) that among other items contains three components: The image
matrix, a color map (present for indexed images only), and an alpha matrix (for images specifying
transparency on a per-pixel level). As for grids, the wrapper function [mat2img](@ref) for creating
transparency on a per-pixel level). As for grids, the wrapper function [`mat2img`](@ref) for creating
the correct structure is available.

- **Segments**: GMT considers point, line, and polygon data to be organized in one or more segments
in a data table. Modules that return segments uses a native Julia segment structure [Dataset type](@ref)
in a data table. Modules that return segments uses a native Julia segment structure [`GMTdataset`](@ref)
that holds the segment data, which may be either numerical, text, or both; it also holds a segment
header string which GMT uses to pass metadata. Thus, GMT modules returning segments will typically
produce arrays of segments and you may pass these to any other module expecting points, lines, or
Expand All @@ -39,13 +39,13 @@ between the GMT structures and native Julia structures, which are:

- **Color palettes**: GMT uses its flexible Color Palette Table (CPT) format to describe how the
color (or pattern) of symbols, lines, polygons or grids should vary as a function of a state variable.
In Julia, this information is provided in another structure [CPT type](@ref) that holds the color
In Julia, this information is provided in another structure [`GMTcpt`](@ref) that holds the color
map as well as an optional alpha array for transparency values. Like grids, these structures may
be passed to GMT modules that expect CPTs and will be returned from GMT modules that normally
would produce CPT files.

- **PostScript**: While most users of the GMT.jl wrapper are unlikely to manipulate PostScript
directly, it allows for the passing of PostScript via another data structure [Postscript type](@ref).
directly, it allows for the passing of PostScript via another data structure [`GMTps`](@ref).

Given this design the Julia wrapper is designed to work in two distinct ways.

Expand Down
2 changes: 1 addition & 1 deletion src/blendimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Blend two 2D UInt8 or 2 RGB images using transparency.
### Returns
A GMT intensity Image
"""
function blendimg!(color::GMTimage{UInt8, 3}, shade::GMTimage{UInt8, 2}; new=false)
function blendimg!(color::GMTimage{AbstractArray{UInt8, 3}}, shade::GMTimage{AbstractArray{UInt8, 2}}; new=false)

blend = (new) ? Array{UInt8,3}(undef, size(shade,1), size(shade,2), 3) : color.image

Expand Down
Loading