Skip to content

Commit

Permalink
Update documentation and show methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
evetion committed Sep 6, 2023
1 parent d7ee24c commit 78b840a
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 171 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ Currently supports the following data products:
|--- |--- |--- |--- |
|ICESat| GLAH06 v34 | [UG](https://nsidc.org/sites/nsidc.org/files/MULTI-GLAH01-V033-V034-UserGuide.pdf) | [ATBD](https://eospso.nasa.gov/sites/default/files/atbd/ATBD-GLAS-02.pdf) |
|ICESat| GLAH14 v34 | [UG](https://nsidc.org/sites/nsidc.org/files/MULTI-GLAH01-V033-V034-UserGuide.pdf) | [ATBD](https://eospso.nasa.gov/sites/default/files/atbd/ATBD-GLAS-02.pdf) |
|ICESat-2| ATL03 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL03-V005-UserGuide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL03_ATBD_r005.pdf) |
|ICESat-2| ATL06 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL03-V005-UserGuide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL06_ATBD_r005.pdf) |
|ICESat-2| ATL08 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL08-V005-UserGuide.pdf) | [ATBD](https://nsidc.org/sites/default/files/icesat2_atl08_atbd_r005_1.pdf) |
|ICESat-2| ATL12 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL12-V005-UserGuide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL12_ATBD_r005.pdf) |
|ICESat-2| ATL03 v6 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl03-v006-userguide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL03_ATBD_r006.pdf) |
|ICESat-2| ATL06 v5 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl06-v006-userguide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL06_ATBD_r006.pdf) |
|ICESat-2| ATL08 v6 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl08-v006-userguide.pdf) | [ATBD](https://nsidc.org/sites/default/files/documents/technical-reference/icesat2_atl08_atbd_v006_0.pdf) |
|ICESat-2| ATL12 v5 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl12-v006-userguide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL12_ATBD_r006.pdf) |
|GEDI| L2A v2 | [UG](https://lpdaac.usgs.gov/documents/998/GEDI02_UserGuide_V21.pdf) | [ATBD](https://lpdaac.usgs.gov/documents/581/GEDI_WF_ATBD_v1.0.pdf) |

For an overview with code examples, see the FOSS4G Pluto notebook [here](https://www.evetion.nl/SpaceLiDAR.jl/dev/tutorial/foss4g_2021.jl.html)
Expand All @@ -26,20 +26,20 @@ If you use SpaceLiDAR.jl in your research, please consider [citing it](https://z

# Install
```julia
] add SpaceLiDAR
]add SpaceLiDAR
```

# Usage
Search for data
```julia
using SpaceLiDAR
using Extents
# Find all ATL08 granules
# Find all ATL08 granules ever
granules = search(:ICESat2, :ATL08)

# Find only ATL03 granules in a part of Vietnam
vietnam = Extent(X = (102., 107.0), Y = (8.0, 12.0))
granules = search(:ICESat2, :ATL08; bbox=vietnam, version=5)
granules = search(:ICESat2, :ATL08; extent=vietnam, version=6)

# Find GEDI granules in the same way
granules = search(:GEDI, :GEDI02_A)
Expand All @@ -58,10 +58,10 @@ SpaceLiDAR.netrc!(username, password) # replace with your credentials
fn = SpaceLiDAR.download!(granule)

# You can also load a granule from disk
granule = granule_from_file(fn)
granule = granule(fn)

# Or from a folder
local_granules = granules_from_folder(folder)
local_granules = granules(folder)

# Instantiate search results locally (useful for GEDI location indexing)
local_granules = instantiate(granules, folder)
Expand All @@ -71,7 +71,7 @@ Derive points
```julia
using DataFrames
fn = "GEDI02_A_2019242104318_O04046_01_T02343_02_003_02_V002.h5"
g = SpaceLiDAR.granule_from_file(fn)
g = SpaceLiDAR.granule(fn)
df = DataFrame(g)
149680×15 DataFrame
Row │ longitude latitude height height_error datetime intensity sensitivity surface quality nmo
Expand All @@ -92,7 +92,7 @@ Derive linestrings
```julia
using DataFrames
fn = "ATL03_20181110072251_06520101_003_01.h5"
g = SpaceLiDAR.granule_from_file(fn)
g = SpaceLiDAR.granule(fn)
tlines = DataFrame(SpaceLiDAR.lines(g, step=10000))
Table with 4 columns and 6 rows:
geom sun_angle track datetime
Expand Down
2 changes: 1 addition & 1 deletion docs/src/guides/downloads.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ In such cases it's useful to export a list of granules to a text file and use an

```julia
granules = find(:ICESat2, "ATL08")
SpaceLiDAR.write_granule_urls!("atl08_world.txt", granules)
SpaceLiDAR.write_urls("atl08_world.txt", granules)
```

In my case, I use [aria2c](https://aria2.github.io/manual/en/html/aria2c.html).
Expand Down
8 changes: 4 additions & 4 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ Currently supports the following data products:
|--- |--- |--- |--- |
|ICESat| GLAH06 v34 | [UG](https://nsidc.org/sites/nsidc.org/files/MULTI-GLAH01-V033-V034-UserGuide.pdf) | [ATBD](https://eospso.nasa.gov/sites/default/files/atbd/ATBD-GLAS-02.pdf) |
|ICESat| GLAH14 v34 | [UG](https://nsidc.org/sites/nsidc.org/files/MULTI-GLAH01-V033-V034-UserGuide.pdf) | [ATBD](https://eospso.nasa.gov/sites/default/files/atbd/ATBD-GLAS-02.pdf) |
|ICESat-2| ATL03 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL03-V005-UserGuide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL03_ATBD_r005.pdf) |
|ICESat-2| ATL06 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL03-V005-UserGuide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL06_ATBD_r005.pdf) |
|ICESat-2| ATL08 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL08-V005-UserGuide.pdf) | [ATBD](https://nsidc.org/sites/default/files/icesat2_atl08_atbd_r005_1.pdf) |
|ICESat-2| ATL12 v5 | [UG](https://nsidc.org/sites/nsidc.org/files/ATL12-V005-UserGuide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL12_ATBD_r005.pdf) |
|ICESat-2| ATL03 v6 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl03-v006-userguide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL03_ATBD_r006.pdf) |
|ICESat-2| ATL06 v5 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl06-v006-userguide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL06_ATBD_r006.pdf) |
|ICESat-2| ATL08 v6 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl08-v006-userguide.pdf) | [ATBD](https://nsidc.org/sites/default/files/documents/technical-reference/icesat2_atl08_atbd_v006_0.pdf) |
|ICESat-2| ATL12 v5 | [UG](https://nsidc.org/sites/default/files/documents/user-guide/atl12-v006-userguide.pdf) | [ATBD](https://icesat-2.gsfc.nasa.gov/sites/default/files/page_files/ICESat2_ATL12_ATBD_r006.pdf) |
|GEDI| L2A v2 | [UG](https://lpdaac.usgs.gov/documents/998/GEDI02_UserGuide_V21.pdf) | [ATBD](https://lpdaac.usgs.gov/documents/581/GEDI_WF_ATBD_v1.0.pdf) |


Expand Down
10 changes: 5 additions & 5 deletions docs/src/tutorial/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ granules = search(:ICESat2, :ATL08)

# Find only ATL03 granules in a part of Vietnam
vietnam = Extent(X = (102., 107.0), Y = (8.0, 12.0))
granules = search(:ICESat2, :ATL08; bbox=vietnam, version=5)
granules = search(:ICESat2, :ATL08; extent=vietnam, version=6)

# Find GEDI granules in the same way
granules = search(:GEDI, :GEDI02_A)
Expand All @@ -26,10 +26,10 @@ SpaceLiDAR.netrc!(username, password) # replace with your credentials
fn = SpaceLiDAR.download!(granule)

# You can also load a granule from disk
granule = granule_from_file(fn)
granule = granule(fn)

# Or from a folder
local_granules = granules_from_folder(folder)
local_granules = granules(folder)

# Instantiate search results locally (useful for GEDI location indexing)
local_granules = instantiate(granules, folder)
Expand All @@ -40,7 +40,7 @@ local_granules = instantiate(granules, folder)
```julia
using DataFrames
fn = "GEDI02_A_2019242104318_O04046_01_T02343_02_003_02_V002.h5"
g = SpaceLiDAR.granule_from_file(fn)
g = SpaceLiDAR.granule(fn)
df = DataFrame(g)
149680×15 DataFrame
Row │ longitude latitude height height_error datetime intensity sensitivity surface quality nmo
Expand All @@ -61,7 +61,7 @@ df = DataFrame(g)
```julia
using DataFrames
fn = "ATL03_20181110072251_06520101_003_01.h5"
g = SpaceLiDAR.granule_from_file(fn)
g = SpaceLiDAR.granule(fn)
tlines = DataFrame(SpaceLiDAR.lines(g, step=10000))
Table with 4 columns and 6 rows:
geom sun_angle track datetime
Expand Down
103 changes: 8 additions & 95 deletions src/granule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ function _s3_download(url, fn, config = create_aws_config())
end

abstract type Granule end
Base.:(==)(a::Granule, b::Granule) = a.id == b.id

Base.show(io::IO, g::Granule) = _show(io, g)
Base.show(io::IO, ::MIME"text/plain", g::Granule) = _show(io, g)
function _show(io, g::T) where {T<:Granule}
print(io, "$T with id $(g.id)")

Check warning on line 58 in src/granule.jl

View check run for this annotation

Codecov / codecov/patch

src/granule.jl#L55-L58

Added lines #L55 - L58 were not covered by tests
end


MultiPolygonType = Vector{Vector{Vector{Vector{Float64}}}}

Expand Down Expand Up @@ -135,98 +143,3 @@ end
function Base.filesize(granule::T) where {T<:Granule}
filesize(granule.url)
end

abstract type AbstractTable end
struct Table{K,V,G} <: AbstractTable
table::NamedTuple{K,V}
granule::G
function Table(table::NamedTuple{K,V}, g::G) where {K,V,G}
new{K,typeof(values(table)),G}(table, g)
end
end
_table(t::Table) = getfield(t, :table)
_granule(t::AbstractTable) = getfield(t, :granule)
Base.size(table::Table) = size(_table(table))
Base.getindex(t::Table, i) = _table(t)[i]
Base.show(io::IO, t::Table) = _show(io, t)
Base.show(io::IO, ::MIME"text/plain", t::Table) = _show(io, t)
Base.haskey(table::Table, x) = haskey(_table(table), x)
Base.keys(table::Table) = keys(_table(table))
Base.values(table::Table) = values(_table(table))
Base.length(table::Table) = length(_table(table))
Base.iterate(table::Table, args...) = iterate(_table(table), args...)
Base.merge(table::Table, others...) = Table(merge(_table(table), others...))
Base.parent(table::Table) = _table(table)

function Base.getproperty(table::Table, key::Symbol)
getproperty(_table(table), key)
end

function _show(io, t::Table)
print(io, "SpaceLiDAR Table")
end

struct PartitionedTable{N,K,V,G} <: AbstractTable
tables::NTuple{N,NamedTuple{K,V}}
granule::G
end
PartitionedTable(t::NamedTuple) = PartitionedTable((t,))
Base.size(t::PartitionedTable) = (length(t.tables),)
Base.length(t::PartitionedTable{N}) where {N} = N
Base.getindex(t::PartitionedTable, i) = t.tables[i]
Base.lastindex(t::PartitionedTable{N}) where {N} = N
Base.show(io::IO, t::PartitionedTable) = _show(io, t)
Base.show(io::IO, ::MIME"text/plain", t::PartitionedTable) = _show(io, t)
Base.iterate(table::PartitionedTable, args...) = iterate(table.tables, args...)
Base.merge(table::PartitionedTable, others...) = PartitionedTable(merge.(table.tables, Ref(others...)))
Base.parent(table::PartitionedTable) = collect(table.tables)

function _show(io, t::PartitionedTable)
print(io, "SpaceLiDAR Table with $(length(t.tables)) partitions")
end

function add_info(table::PartitionedTable)
it = info(table.granule)
nts = map(table.tables) do t
nt = NamedTuple(zip(keys(it), Fill.(values(it), length(first(t)))))
merge(t, nt)
end
return PartitionedTable(nts, table.granule)
end

function add_id(table::PartitionedTable)
nts = map(table.tables) do t
nt = (; id = Fill(table.granule.id, length(first(t))))
merge(t, nt)
end
return PartitionedTable(nts, table.granule)
end

function add_id(table::Table)
g = _granule(table)
t = _table(table)
nt = (; id = Fill(g.id, length(first(t))))
nts = merge(t, nt)
return Table(nts, g)
end

function add_info(table::Table)
g = _granule(table)
it = info(g)
t = _table(table)
nt = NamedTuple(zip(keys(it), Fill.(values(it), length(first(t)))))
nts = merge(t, nt)
return Table(nts, g)
end

_info(g::Granule) = merge((; id = g.id), info(g))

DataAPI.metadatasupport(::Type{<:AbstractTable}) = (read = true, write = false)
DataAPI.metadatakeys(t::AbstractTable) = map(String, keys(pairs(_info(_granule(t)))))
function DataAPI.metadata(t::AbstractTable, k; style::Bool = false)
if style
getfield(_info(_granule(t)), Symbol(k)), :default
else
getfield(_info(_granule(t)), Symbol(k))
end
end
24 changes: 21 additions & 3 deletions src/search.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@ function search(
m::Mission{:GEDI},
product::Symbol = :GEDI02_A;
bbox::Extent = world,
extent::Extent = world,
version::Int = 2,
before::Union{Nothing,DateTime} = nothing,
after::Union{Nothing,DateTime} = nothing,
provider::String = "LPDAAC_ECS",
)::Vector{GEDI_Granule}
startswith(string(product), prefix(m)) || throw(ArgumentError("Wrong product $product for $(mission(m)) mission."))
if bbox != world
Base.depwarn("Use of `bbox` is deprecated, please use `extent` instead.", :search)
extent = bbox

Check warning on line 36 in src/search.jl

View check run for this annotation

Codecov / codecov/patch

src/search.jl#L35-L36

Added lines #L35 - L36 were not covered by tests
end

granules =
earthdata_search(short_name = string(product), bounding_box = bbox, version = version, provider = provider, before = before, after = after)
earthdata_search(short_name = string(product), bounding_box = extent, version = version, provider = provider, before = before, after = after)
length(granules) == 0 && @warn "No granules found, did you specify the correct parameters, such as version?"
filter!(g -> !isnothing(g.https_url), granules)
map(
Expand All @@ -48,15 +54,21 @@ function search(
m::Mission{:ICESat2},
product::Symbol = :ATL03;
bbox::Extent = world,
extent::Extent = world,
version::Int = 6,
before::Union{Nothing,DateTime} = nothing,
after::Union{Nothing,DateTime} = nothing,
s3::Bool = false,
provider::String = s3 ? "NSIDC_CPRD" : "NSIDC_ECS",
)::Vector{ICESat2_Granule}
startswith(string(product), prefix(m)) || throw(ArgumentError("Wrong product $product for $(mission(m)) mission."))
if bbox != world
Base.depwarn("Use of `bbox` is deprecated, please use `extent` instead.", :search)
extent = bbox

Check warning on line 67 in src/search.jl

View check run for this annotation

Codecov / codecov/patch

src/search.jl#L66-L67

Added lines #L66 - L67 were not covered by tests
end

granules =
earthdata_search(short_name = string(product), bounding_box = bbox, version = version, provider = provider, before = before, after = after)
earthdata_search(short_name = string(product), bounding_box = extent, version = version, provider = provider, before = before, after = after)
length(granules) == 0 && @warn "No granules found, did you specify the correct parameters, such as version?"
s3 ? filter!(g -> !isnothing(g.s3_url), granules) : filter!(g -> !isnothing(g.https_url), granules)
map(
Expand All @@ -73,15 +85,21 @@ function search(
m::Mission{:ICESat},
product::Symbol = :GLAH14;
bbox::Extent = world,
extent::Extent = world,
version::Int = 34,
before::Union{Nothing,DateTime} = nothing,
after::Union{Nothing,DateTime} = nothing,
s3::Bool = false,
provider::String = s3 ? "NSIDC_CPRD" : "NSIDC_ECS",
)::Vector{ICESat_Granule}
startswith(string(product), prefix(m)) || throw(ArgumentError("Wrong product $product for $(mission(m)) mission."))
if bbox != world
Base.depwarn("Use of `bbox` is deprecated, please use `extent` instead.", :search)
extent = bbox
end

granules =
earthdata_search(short_name = string(product), bounding_box = bbox, version = version, provider = provider, before = before, after = after)
earthdata_search(short_name = string(product), bounding_box = extent, version = version, provider = provider, before = before, after = after)
length(granules) == 0 && @warn "No granules found, did you specify the correct parameters, such as version?"
s3 ? filter!(g -> !isnothing(g.s3_url), granules) : filter!(g -> !isnothing(g.https_url), granules)
map(
Expand Down
Loading

0 comments on commit 78b840a

Please sign in to comment.