From 9fc47b6642d4b58ba6dd7320e1e4783b72d925eb Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 22 Aug 2024 13:17:06 +0200 Subject: [PATCH 01/21] define climate models programatically --- src/RasterDataSources.jl | 14 +---- src/chelsa/future.jl | 112 ++++++++++++++++++++++----------------- src/types.jl | 78 +++++++-------------------- 3 files changed, 83 insertions(+), 121 deletions(-) diff --git a/src/RasterDataSources.jl b/src/RasterDataSources.jl index dca1a62..8266921 100644 --- a/src/RasterDataSources.jl +++ b/src/RasterDataSources.jl @@ -37,19 +37,6 @@ export ECO4ESIPTJPL,ECO4WUE,GEDI03,GEDI04_B,MCD12Q1,MCD12Q2,MCD15A2H, MYD17A2H, MYD17A3HGF, MYD21A2, SIF005, SIF_ANN, VNP09A1, VNP09H1, VNP13A1, VNP15A2H, VNP21A2, VNP22Q2 -# Climate models from CMIP5 (used in CHELSA) -export ACCESS1, BNUESM, CCSM4, CESM1BGC, CESM1CAM5, CMCCCMS, CMCCCM, CNRMCM5, - CSIROMk3, CanESM2, FGOALS, FIOESM, GFDLCM3, GFDLESM2G, GFDLESM2M, GISSE2HCC, - GISSE2H, GISSE2RCC, GISSE2R, HadGEM2AO, HadGEM2CC, IPSLCM5ALR, IPSLCM5AMR, - MIROCESMCHEM, MIROCESM, MIROC5, MPIESMLR, MPIESMMR, MRICGCM3, MRIESM1, NorESM1M, - BCCCSM1, Inmcm4 - -# Climate models from CMIP6 (used in WorldClim) -export BCCCSM2MR, CNRMCM61, CNRMESM21, CanESM5, GFDLESM4, IPSLCM6ALR, MIROCES2L, MIROC6, MRIESM2 - -# Climate models from CMIP6 (CHELSA) -export UKESM, MPIESMHR - export Values, Deciles export getraster @@ -63,6 +50,7 @@ include("worldclim/bioclim.jl") include("worldclim/climate.jl") include("worldclim/weather.jl") include("worldclim/elevation.jl") +include("worldclim/future.jl") include("chelsa/shared.jl") include("chelsa/climate.jl") diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index 200c730..a1a76d6 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -260,54 +260,68 @@ _scenario(::Type{<:CHELSA{F}}) where F<:Future = _scenario(F) # Climate model string formatters for CHELSA Future # CMIP5 -_format(::Type{CHELSA}, ::Type{ACCESS1}) = "ACCESS1-0" -_format(::Type{CHELSA}, ::Type{BNUESM}) = "BNU-ESM" -_format(::Type{CHELSA}, ::Type{CCSM4}) = "CCSM4" -_format(::Type{CHELSA}, ::Type{CESM1BGC}) = "CESM1-BGC" -_format(::Type{CHELSA}, ::Type{CESM1CAM5}) = "CESM1-CAM5" -_format(::Type{CHELSA}, ::Type{CMCCCMS}) = "CMCC-CMS" -_format(::Type{CHELSA}, ::Type{CMCCCM}) = "CMCC-CM" -_format(::Type{CHELSA}, ::Type{CNRMCM5}) = "CNRM-CM5" -_format(::Type{CHELSA}, ::Type{CSIROMk3}) = "CSIRO-Mk3" -_format(::Type{CHELSA}, ::Type{CanESM2}) = "CanESM2" -_format(::Type{CHELSA}, ::Type{FGOALS}) = "FGOALS-g2" -_format(::Type{CHELSA}, ::Type{FIOESM}) = "FIO-ESM" -_format(::Type{CHELSA}, ::Type{GFDLCM3}) = "GFDL-CM3" -_format(::Type{CHELSA}, ::Type{GFDLESM2G}) = "GFDL-ESM2G" -_format(::Type{CHELSA}, ::Type{GFDLESM2M}) = "GFDL-ESM2M" -_format(::Type{CHELSA}, ::Type{GISSE2HCC}) = "GISS-E2-H-CC" -_format(::Type{CHELSA}, ::Type{GISSE2H}) = "GISS-E2-H" -_format(::Type{CHELSA}, ::Type{GISSE2RCC}) = "GISS-E2-R-CC" -_format(::Type{CHELSA}, ::Type{GISSE2R}) = "GISS-E2-R" -_format(::Type{CHELSA}, ::Type{HadGEM2AO}) = "HadGEM2-AO" -_format(::Type{CHELSA}, ::Type{HadGEM2CC}) = "HadGEM2-CC" -_format(::Type{CHELSA}, ::Type{IPSLCM5ALR}) = "IPSL-CM5A-LR" -_format(::Type{CHELSA}, ::Type{IPSLCM5AMR}) = "IPSL-CM5A-MR" -_format(::Type{CHELSA}, ::Type{MIROCESMCHEM}) = "MIROC-ESM-CHEM" -_format(::Type{CHELSA}, ::Type{MIROCESM}) = "MIROC-ESM" -_format(::Type{CHELSA}, ::Type{MIROC5}) = "MIROC5" -_format(::Type{CHELSA}, ::Type{MPIESMLR}) = "MPI-ESM-LR" -_format(::Type{CHELSA}, ::Type{MPIESMMR}) = "MPI-ESM-MR" -_format(::Type{CHELSA}, ::Type{MRICGCM3}) = "MRI-CGCM3" -_format(::Type{CHELSA}, ::Type{MRIESM1}) = "MRI-ESM1" -_format(::Type{CHELSA}, ::Type{NorESM1M}) = "NorESM1-M" -_format(::Type{CHELSA}, ::Type{BCCCSM1}) = "bcc-csm-1" -_format(::Type{CHELSA}, ::Type{Inmcm4}) = "inmcm4" +const CHELSA_CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] +const CHELSA_CMIP5_MODEL_STRINGS = +[ + "ACCESS1-0" + "BNU-ESM" + "CCSM4" + "CESM1-BGC" + "CESM1-CAM5" + "CMCC-CMS" + "CMCC-CM" + "CNRM-CM5" + "CSIRO-Mk3" + "CanESM2" + "FGOALS-g2" + "FIO-ESM" + "GFDL-CM3" + "GFDL-ESM2G" + "GFDL-ESM2M" + "GISS-E2-H-CC" + "GISS-E2-H" + "GISS-E2-R-CC" + "GISS-E2-R" + "HadGEM2-AO" + "HadGEM2-CC" + "IPSL-CM5A-LR" + "IPSL-CM5A-MR" + "MIROC-ESM-CHEM" + "MIROC-ESM" + "MIROC5" + "MPI-ESM-LR" + "MPI-ESM-MR" + "MRI-CGCM3" + "MRI-ESM1" + "NorESM1-M" + "bcc-csm-1" + "inmcm4" +] # CMIP6 -_format(::Type{CHELSA}, ::Type{GFDLESM4}) = "gfdl-esm4" -_format(::Type{CHELSA}, ::Type{IPSLCM6ALR}) = "ipsl-cm6a-lr" -_format(::Type{CHELSA}, ::Type{MPIESMHR}) = "mpi-esm1-2-hr" -_format(::Type{CHELSA}, ::Type{MRIESM2}) = "mri-esm2-0" -_format(::Type{CHELSA}, ::Type{UKESM}) = "ukesm1-0-ll" - -# Format scenarios -_format(::Type{CHELSA}, ::Type{RCP26}) = "rcp26" -_format(::Type{CHELSA}, ::Type{RCP45}) = "rcp45" -_format(::Type{CHELSA}, ::Type{RCP60}) = "rcp60" -_format(::Type{CHELSA}, ::Type{RCP85}) = "rcp85" - -_format(::Type{CHELSA}, ::Type{SSP126}) = "ssp126" -_format(::Type{CHELSA}, ::Type{SSP245}) = "ssp245" -_format(::Type{CHELSA}, ::Type{SSP370}) = "ssp370" -_format(::Type{CHELSA}, ::Type{SSP585}) = "ssp585" +const CHELSA_CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] +const CHELSA_CMIP6_MODEL_STRINGS = [ + "GFDL-ESM4" + "IPSL-CM6A-LR" + "MPI-ESM1-2-HR" + "MRI-ESM2-0" + "UKESM1-0-LL" +] + +for CMIP in [:CMIP5, :CMIP6] + strings = eval(Symbol("CHELSA_$(CMIP)_MODEL_STRINGS")) + models = eval(Symbol("CHELSA_$(CMIP)_MODELS")) + for model_str in strings + type = Symbol(replace(model_str, "-" => "_")) + @eval begin + if !(@isdefined $type) + struct $type <: ClimateModel{$CMIP} end + export $type + end + _format(::Type{CHELSA}, ::Type{$type}) = lowercase($model_str) + push!($models, $type) + end + end + append!(eval(Symbol("$(CMIP)_MODELS")), models) + unique!(eval(Symbol("$(CMIP)_MODELS"))) +end \ No newline at end of file diff --git a/src/types.jl b/src/types.jl index 87996b0..3185339 100644 --- a/src/types.jl +++ b/src/types.jl @@ -165,58 +165,6 @@ See the [`getraster`](@ref) docs for implementation details. """ struct HabitatHeterogeneity <: RasterDataSet end -""" - ClimateModel - -Abstract supertype for climate models use in [`Future`](@ref) datasets. -""" -abstract type ClimateModel end - -struct ACCESS1 <: ClimateModel end -struct BNUESM <: ClimateModel end -struct CCSM4 <: ClimateModel end -struct CESM1BGC <: ClimateModel end -struct CESM1CAM5 <: ClimateModel end -struct CMCCCMS <: ClimateModel end -struct CMCCCM <: ClimateModel end -struct CNRMCM5 <: ClimateModel end -struct CSIROMk3 <: ClimateModel end -struct CanESM2 <: ClimateModel end -struct FGOALS <: ClimateModel end -struct FIOESM <: ClimateModel end -struct GFDLCM3 <: ClimateModel end -struct GFDLESM2G <: ClimateModel end -struct GFDLESM2M <: ClimateModel end -struct GISSE2HCC <: ClimateModel end -struct GISSE2H <: ClimateModel end -struct GISSE2RCC <: ClimateModel end -struct GISSE2R <: ClimateModel end -struct HadGEM2AO <: ClimateModel end -struct HadGEM2CC <: ClimateModel end -struct IPSLCM5ALR <: ClimateModel end -struct IPSLCM5AMR <: ClimateModel end -struct MIROCESMCHEM <: ClimateModel end -struct MIROCESM <: ClimateModel end -struct MIROC5 <: ClimateModel end -struct MPIESMLR <: ClimateModel end -struct MPIESMMR <: ClimateModel end -struct MRICGCM3 <: ClimateModel end -struct MRIESM1 <: ClimateModel end -struct NorESM1M <: ClimateModel end -struct BCCCSM1 <: ClimateModel end -struct Inmcm4 <: ClimateModel end -struct BCCCSM2MR <: ClimateModel end -struct CNRMCM61 <: ClimateModel end -struct CNRMESM21 <: ClimateModel end -struct CanESM5 <: ClimateModel end -struct GFDLESM4 <: ClimateModel end -struct IPSLCM6ALR <: ClimateModel end -struct MIROCES2L <: ClimateModel end -struct MIROC6 <: ClimateModel end -struct MRIESM2 <: ClimateModel end -struct UKESM <: ClimateModel end -struct MPIESMHR <: ClimateModel end - """ CMIPphase @@ -233,6 +181,7 @@ abstract type CMIPphase end The Coupled Model Intercomparison Project, Phase 5. """ struct CMIP5 <: CMIPphase end +const CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] """ CMIP6 <: CMIPphase @@ -240,6 +189,14 @@ struct CMIP5 <: CMIPphase end The Coupled Model Intercomparison Project, Phase 6. """ struct CMIP6 <: CMIPphase end +const CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] + +""" + ClimateModel + +Abstract supertype for climate models use in [`Future`](@ref) datasets. +""" +abstract type ClimateModel{CMIP<:CMIPphase} end """ ClimateScenario @@ -296,14 +253,9 @@ Can be either [`CMIP5`](@ref) or [`CMIP6`](@ref). Climate models can be chosen from: -`ACCESS1`, `BNUESM`, `CCSM4`, `CESM1BGC`, `CESM1CAM5`, `CMCCCMS`, `CMCCCM`, -`CNRMCM5`, `CSIROMk3`, `CanESM2`, `FGOALS`, `FIOESM`, `GFDLCM3`, `GFDLESM2G`, -`GFDLESM2M`, `GISSE2HCC`, `GISSE2H`, `GISSE2RCC`, `GISSE2R`, `HadGEM2AO`, -`HadGEM2CC`, `IPSLCM5ALR`, `IPSLCM5AMR`, `MIROCESMCHEM`, `MIROCESM`, `MIROC5`, -`MPIESMLR`, `MPIESMMR`, `MRICGCM3`, `MRIESM1`, `NorESM1M`, `BCCCSM1`, `Inmcm4`, -`BCCCSM2MR`, `CNRMCM61`, `CNRMESM21`, `CanESM5`, `MIROCES2L`, `MIROC6` for CMIP5; +`$(join(CMIP5_MODELS, "`, `"))` for `CMIP5`; -`UKESM`, `MPIESMHR` `IPSLCM6ALR`, `MRIESM2`, `GFDLESM4` for `CMIP6`. +`$(join(CMIP6_MODELS, "`, `"))` for `CMIP6`;" #### `ClimateScenario` @@ -335,9 +287,17 @@ struct Future{D<:RasterDataSet,C<:CMIPphase,M<:ClimateModel,S<:ClimateScenario} _dataset(::Type{<:Future{D}}) where D = D _dataset(::Type{<:Future{BioClimPlus}}) = BioClim _phase(::Type{<:Future{<:Any,P}}) where P = P +_phase(::Type{<:ClimateModel{P}}) where P = P + _model(::Type{<:Future{<:Any,<:Any,M}}) where M = M _scenario(::Type{<:Future{<:Any,<:Any,<:Any,S}}) where S = S layers(::Type{<:Future{BioClimPlus}}) = BIOCLIMPLUS_LAYERS_FUTURE + +# fallback for _format +_format(::Type, RCP::Type{<:RepresentativeConcentrationPathway}) = lowercase(string(nameof(RCP))) +_format(::Type, S::Type{<:SharedSocioeconomicPathway}) = lowercase(string(nameof(S))) +_format(::Type, S::Type{<:ClimateModel}) = replace(string(nameof(S)), "_" => "-") + """ ModisProduct <: RasterDataSet From 12f6ede3470cb3722448ec222f69663b336d28a1 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 22 Aug 2024 13:17:37 +0200 Subject: [PATCH 02/21] first draft for future wordclim climate --- src/worldclim/future.jl | 83 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/worldclim/future.jl diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl new file mode 100644 index 0000000..d774e91 --- /dev/null +++ b/src/worldclim/future.jl @@ -0,0 +1,83 @@ +const WORLDCLIM_URI_CMIP6 = URI(scheme="https", host="geodata.ucdavis.edu", path="/cmip6") + +layers(::Type{<:WorldClim{<:Future{Climate}}}) = (:tmin, :tmax, :prec) +getraster_keywords(::Type{<:WorldClim{<:Future{Climate}}}) = (:date, :res) + + +function getraster(T::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, layers::Union{Tuple,Symbol}; + res::String=defres(T), date +) + _getraster(T, layers, res, date) +end + + +function _getraster(T::Type{<:WorldClim{<:Future{Climate}}}, layer::Symbol, res::String, date) + #date_str = _date_string(T, date) + _check_layer(T, layer) + _check_res(T, res) + raster_path = rasterpath(T, layer; res, date) + if !isfile(raster_path) + _maybe_download(rasterurl(T, layer; res, date), raster_path) + end + return raster_path +end + +function rasterurl(T::Type{<:WorldClim{<:Future{Climate, CMIP6, M, S}}}, layer; res, date) where {M, S} + joinpath(WORLDCLIM_URI_CMIP6, res, _format(WorldClim, M), _format(CHELSA, S), rastername(T, layer; res, date)) +end + +function rastername(T::Type{<:WorldClim{<:Future{Climate, CMIP6, M, S}}}, layer; res, date) where {M, S} + join(["wc2.1", res, string(layer), _format(WorldClim, M), _format(CHELSA, S), date], "_") * ".tif" +end + + +function _date_string(::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, date) + if date < DateTime(2021) + _cmip6_date_error(date) + elseif date < DateTime(2041) + "2011-2040" + elseif date < DateTime(2061) + "2041-2060" + elseif date < DateTime(2081) + "2041-2080" + elseif date < DateTime(2101) + "2081-2100" + else + _cmip6_date_error(date) + end +end + +const WORDCLIM_CMIP6_MODEL_STRINGS = [ + "ACCESS-CM2" + "BCC-CSM2-MR" + "CMCC-ESM2" + "EC-Earth3-Veg" + "FIO-ESM-2-0" + "GFDL-ESM4" + "GISS-E2-1-G" + "HadGEM3-GC31-LL" + "INM-CM5-0" + "IPSL-CM6A-LR" + "MIROC6" + "MPI-ESM1-2-HR" + "MRI-ESM2-0" + "UKESM1-0-LL" +] + +WORDCLIM_CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] + +for model_str in WORDCLIM_CMIP6_MODEL_STRINGS + type = Symbol(replace(model_str, "-" => "_")) + @eval begin + export $type + if !(@isdefined $type) + struct $type <: ClimateModel{CMIP6} end + export $type + end + push!(WORDCLIM_CMIP6_MODELS, $type) + _format(::Type{WorldClim}, ::Type{$type}) = $model_str + end +end + +append!(CMIP6_MODELS, WORDCLIM_CMIP6_MODELS) +unique!(CMIP6_MODELS) \ No newline at end of file From 2e1cc4aa7aa76a59388743368719f4fed06e0fcf Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 22 Aug 2024 13:24:44 +0200 Subject: [PATCH 03/21] define ClimateModel before using it --- src/types.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.jl b/src/types.jl index 3185339..f1da0ff 100644 --- a/src/types.jl +++ b/src/types.jl @@ -181,7 +181,6 @@ abstract type CMIPphase end The Coupled Model Intercomparison Project, Phase 5. """ struct CMIP5 <: CMIPphase end -const CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] """ CMIP6 <: CMIPphase @@ -189,7 +188,6 @@ const CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] The Coupled Model Intercomparison Project, Phase 6. """ struct CMIP6 <: CMIPphase end -const CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] """ ClimateModel @@ -197,6 +195,8 @@ const CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] Abstract supertype for climate models use in [`Future`](@ref) datasets. """ abstract type ClimateModel{CMIP<:CMIPphase} end +const CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] +const CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] """ ClimateScenario From bc62db1ac13284858ebf2c36dd7d5fbcf8770073 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 22 Aug 2024 16:04:44 +0200 Subject: [PATCH 04/21] first draft for future worldclim bioclim --- src/worldclim/future.jl | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index d774e91..5ee596b 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -10,26 +10,47 @@ function getraster(T::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, layers::Union _getraster(T, layers, res, date) end - function _getraster(T::Type{<:WorldClim{<:Future{Climate}}}, layer::Symbol, res::String, date) #date_str = _date_string(T, date) _check_layer(T, layer) _check_res(T, res) - raster_path = rasterpath(T, layer; res, date) + raster_path = rasterpath(T, "bioclim"; res, date) if !isfile(raster_path) _maybe_download(rasterurl(T, layer; res, date), raster_path) end return raster_path end -function rasterurl(T::Type{<:WorldClim{<:Future{Climate, CMIP6, M, S}}}, layer; res, date) where {M, S} - joinpath(WORLDCLIM_URI_CMIP6, res, _format(WorldClim, M), _format(CHELSA, S), rastername(T, layer; res, date)) +function rasterurl(T::Type{<:WorldClim{<:Future}}, layer; res, date) + joinpath(WORLDCLIM_URI_CMIP6, res, _format(T, _model(T)), _format(T, _scenario(T)), rastername(T, layer; res, date)) +end + +function rastername(T::Type{<:WorldClim{<:Future}}, layer; res, date) + join(["wc2.1", res, string(layer), _format(T, _model(T)), _format(T, _scenario(T)), date], "_") * ".tif" end -function rastername(T::Type{<:WorldClim{<:Future{Climate, CMIP6, M, S}}}, layer; res, date) where {M, S} - join(["wc2.1", res, string(layer), _format(WorldClim, M), _format(CHELSA, S), date], "_") * ".tif" +function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}, layer::Symbol; res::String=defres(T), date) + _getraster(T, layers, res, date) end +function _getraster(T::Type{<:WorldClim{<:Future{BioClim}}}, layer::Symbol, res::String, date) + #date_str = _date_string(T, date) + #_check_layer(T, layer) + #_check_res(T, res) + raster_path = rasterpath(T; res, date) + if !isfile(raster_path) + _maybe_download(rasterurl(T, layer; res, date), raster_path) + end + return raster_path +end + +# copy-pasted in from CHELSA - must be some way to implement this abstractly? +_dataset(::Type{<:WorldClim{F}}) where F<:Future = _dataset(F) +_phase(::Type{<:WorldClim{F}}) where F<:Future = _phase(F) +_model(::Type{<:WorldClim{F}}) where F<:Future = _model(F) +_scenario(::Type{<:WorldClim{F}}) where F<:Future = _scenario(F) + + function _date_string(::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, date) if date < DateTime(2021) From af8429416c78b59c7af9a94f2b7580bc94116439 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Tue, 3 Sep 2024 09:58:54 +0200 Subject: [PATCH 05/21] move exports to main file --- src/RasterDataSources.jl | 5 +++++ src/worldclim/future.jl | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/RasterDataSources.jl b/src/RasterDataSources.jl index 8266921..d0ca92a 100644 --- a/src/RasterDataSources.jl +++ b/src/RasterDataSources.jl @@ -72,4 +72,9 @@ include("modis/products.jl") include("modis/utilities.jl") include("modis/examples.jl") +for model in [CMIP5_MODELS; CMIP6_MODELS] + symb = nameof(model) + @eval export $symb +end + end # module diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index 5ee596b..7c59f01 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -90,7 +90,6 @@ WORDCLIM_CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] for model_str in WORDCLIM_CMIP6_MODEL_STRINGS type = Symbol(replace(model_str, "-" => "_")) @eval begin - export $type if !(@isdefined $type) struct $type <: ClimateModel{CMIP6} end export $type From bc73812723f0ad5699a15cb7f5b22c92b1702c35 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Tue, 10 Sep 2024 16:54:18 +0200 Subject: [PATCH 06/21] reorganise future worldclim --- src/worldclim/future.jl | 53 +++++++++++++++++++++++++---------------- src/worldclim/shared.jl | 3 ++- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index 7c59f01..0724a07 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -3,7 +3,6 @@ const WORLDCLIM_URI_CMIP6 = URI(scheme="https", host="geodata.ucdavis.edu", path layers(::Type{<:WorldClim{<:Future{Climate}}}) = (:tmin, :tmax, :prec) getraster_keywords(::Type{<:WorldClim{<:Future{Climate}}}) = (:date, :res) - function getraster(T::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, layers::Union{Tuple,Symbol}; res::String=defres(T), date ) @@ -11,39 +10,50 @@ function getraster(T::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, layers::Union end function _getraster(T::Type{<:WorldClim{<:Future{Climate}}}, layer::Symbol, res::String, date) - #date_str = _date_string(T, date) _check_layer(T, layer) _check_res(T, res) - raster_path = rasterpath(T, "bioclim"; res, date) + raster_path = rasterpath(T, layer; res, date) if !isfile(raster_path) _maybe_download(rasterurl(T, layer; res, date), raster_path) end return raster_path end -function rasterurl(T::Type{<:WorldClim{<:Future}}, layer; res, date) - joinpath(WORLDCLIM_URI_CMIP6, res, _format(T, _model(T)), _format(T, _scenario(T)), rastername(T, layer; res, date)) -end - -function rastername(T::Type{<:WorldClim{<:Future}}, layer; res, date) - join(["wc2.1", res, string(layer), _format(T, _model(T)), _format(T, _scenario(T)), date], "_") * ".tif" -end +## Bioclim +getraster_keywords(::Type{<:WorldClim{<:Future{BioClim}}}) = (:date, :res) -function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}, layer::Symbol; res::String=defres(T), date) - _getraster(T, layers, res, date) +function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}; res::String=defres(T), date) + _getraster(T, res, date) end -function _getraster(T::Type{<:WorldClim{<:Future{BioClim}}}, layer::Symbol, res::String, date) - #date_str = _date_string(T, date) - #_check_layer(T, layer) - #_check_res(T, res) +function _getraster(T::Type{<:WorldClim{<:Future{BioClim}}}, res::String, date) + _check_res(T, res) raster_path = rasterpath(T; res, date) if !isfile(raster_path) - _maybe_download(rasterurl(T, layer; res, date), raster_path) + _maybe_download(rasterurl(T; res, date), raster_path) end return raster_path end +function rasterpath(T::Type{<:WorldClim{<:Future{Climate}}}, layer; res, date) + joinpath(_rasterpath(T), rastername(T, layer; res, date)) +end +function rasterpath(T::Type{<:WorldClim{<:Future{BioClim}}}; res, date) + joinpath(_rasterpath(T), rastername(T; res, date)) +end +function _rasterpath(T::Type{<:WorldClim{<:Future}}) + joinpath(rasterpath(WorldClim), "Future", string(_dataset(T)), string(_scenario(T)), string(_model(T))) +end + +function rasterurl(T::Type{<:WorldClim{<:Future}}, args...; res, date) + joinpath(WORLDCLIM_URI_CMIP6, res, _format(T, _model(T)), _format(T, _scenario(T)), rastername(T, args...; res, date)) +end + +function rastername(T::Type{<:WorldClim{<:Future}}, layer; res, date) + join(["wc2.1", res, string(layer), _format(T, _model(T)), _format(T, _scenario(T)), _date_string(T, date)], "_") * ".tif" +end +rastername(T::Type{<:WorldClim{<:Future{BioClim}}}; kw...) = rastername(T, :bioc, ; kw...) + # copy-pasted in from CHELSA - must be some way to implement this abstractly? _dataset(::Type{<:WorldClim{F}}) where F<:Future = _dataset(F) _phase(::Type{<:WorldClim{F}}) where F<:Future = _phase(F) @@ -51,16 +61,15 @@ _model(::Type{<:WorldClim{F}}) where F<:Future = _model(F) _scenario(::Type{<:WorldClim{F}}) where F<:Future = _scenario(F) - -function _date_string(::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, date) +function _date_string(::Type{<:WorldClim{<:Future{<:Any, CMIP6}}}, date) if date < DateTime(2021) _cmip6_date_error(date) elseif date < DateTime(2041) - "2011-2040" + "2021-2040" elseif date < DateTime(2061) "2041-2060" elseif date < DateTime(2081) - "2041-2080" + "2041-2060" elseif date < DateTime(2101) "2081-2100" else @@ -68,6 +77,8 @@ function _date_string(::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, date) end end + +## Handle all the models const WORDCLIM_CMIP6_MODEL_STRINGS = [ "ACCESS-CM2" "BCC-CSM2-MR" diff --git a/src/worldclim/shared.jl b/src/worldclim/shared.jl index 8b0d099..76cafd5 100644 --- a/src/worldclim/shared.jl +++ b/src/worldclim/shared.jl @@ -13,7 +13,8 @@ const WORLDCLIM_URI = URI(scheme="https", host="geodata.ucdavis.edu", path="/cli resolutions(::Type{<:WorldClim}) = ("30s", "2.5m", "5m", "10m") defres(::Type{<:WorldClim}) = "10m" -rasterpath(::Type{WorldClim{T}}) where T = joinpath(rasterpath(), "WorldClim", string(nameof(T))) +rasterpath(::Type{WorldClim}) = joinpath(rasterpath(), "WorldClim") +rasterpath(::Type{WorldClim{T}}) where T = joinpath(rasterpath(WorldClim), string(nameof(T))) rasterpath(T::Type{<:WorldClim}, layer; kw...) = joinpath(rasterpath(T), string(layer), rastername(T, layer; kw...)) From 9c2e729493ccf02ef364524bce4ba576b80d206f Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Tue, 1 Oct 2024 12:07:46 +0200 Subject: [PATCH 07/21] reorganise some code --- src/chelsa/future.jl | 1 + src/shared.jl | 6 + src/types.jl | 264 +++++++++++++++++++++---------------------- 3 files changed, 138 insertions(+), 133 deletions(-) diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index 7082846..1c36f47 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -254,6 +254,7 @@ _cmip5_date_error(date) = error("CMIP5 covers the period from 2041-2080, not inc _cmip6_date_error(date) = error("CMIP6 covers the period from 1981-2100, not including $date") _dataset(::Type{<:CHELSA{F}}) where F<:Future = _dataset(F) +_dataset(::Type{<:Future{BioClimPlus}}) = BioClim # to make sure bioclimplus and bioclim end up in the same folder _phase(::Type{<:CHELSA{F}}) where F<:Future = _phase(F) _model(::Type{<:CHELSA{F}}) where F<:Future = _model(F) _scenario(::Type{<:CHELSA{F}}) where F<:Future = _scenario(F) diff --git a/src/shared.jl b/src/shared.jl index cbf76c6..0d3f473 100644 --- a/src/shared.jl +++ b/src/shared.jl @@ -81,3 +81,9 @@ function _map_layers(T, layers, args...; kw...) keys = layerkeys(T, layers) return NamedTuple{keys}(filenames) end + +# fallback for _format +_format(RCP::Type{<:RepresentativeConcentrationPathway}) = lowercase(string(nameof(RCP))) +_format(S::Type{<:SharedSocioeconomicPathway}) = lowercase(string(nameof(S))) +_format(M::Type{<:ClimateModel}) = replace(string(nameof(M)), "_" => "-") +_format(::Type, T::Type) = _format(T) diff --git a/src/types.jl b/src/types.jl index f1da0ff..419e133 100644 --- a/src/types.jl +++ b/src/types.jl @@ -12,6 +12,136 @@ Abstract supertype for datasets that belong to a [`RasterDataSource`](@ref). """ abstract type RasterDataSet end +""" + CMIPphase + +Abstract supertype for phases of the CMIP, +the Coupled Model Intercomparison Project. + +Subtypes are `CMIP5` and `CMIP6`. +""" +abstract type CMIPphase end + +""" + CMIP5 <: CMIPphase + +The Coupled Model Intercomparison Project, Phase 5. +""" +struct CMIP5 <: CMIPphase end + +""" + CMIP6 <: CMIPphase + +The Coupled Model Intercomparison Project, Phase 6. +""" +struct CMIP6 <: CMIPphase end + +""" + ClimateModel + +Abstract supertype for climate models use in [`Future`](@ref) datasets. +""" +abstract type ClimateModel{CMIP<:CMIPphase} end +const CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] +const CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] + +""" + ClimateScenario + +Abstract supertype for scenarios used in [`CMIPphase`](@ref) models. +""" +abstract type ClimateScenario end + +""" + RepresentativeConcentrationPathway + +Abstract supertype for Representative Concentration Pathways (RCPs) for [`CMIP5`](@ref). + +Subtypes are: `RCP26`, `RCP45`, `RCP60`, `RCP85` +""" +abstract type RepresentativeConcentrationPathway <: ClimateScenario end + +struct RCP26 <: RepresentativeConcentrationPathway end +struct RCP45 <: RepresentativeConcentrationPathway end +struct RCP60 <: RepresentativeConcentrationPathway end +struct RCP85 <: RepresentativeConcentrationPathway end + +""" + SharedSocioeconomicPathway + +Abstract supertype for Shared Socio-economic Pathways (SSPs) for [`CMIP6`](@ref). + +Subtypes are: `SSP126`, `SSP245`, SSP370`, SSP585` +""" +abstract type SharedSocioeconomicPathway <: ClimateScenario end + +struct SSP126 <: SharedSocioeconomicPathway end +struct SSP245 <: SharedSocioeconomicPathway end +struct SSP370 <: SharedSocioeconomicPathway end +struct SSP585 <: SharedSocioeconomicPathway end + +""" + Future{<:RasterDataSet,<:CMIPphase,<:ClimateModel,<:ClimateScenario} + +Future climate datasets specified with a dataset, phase, model, and scenario. + +## Type Parameters + +#### `RasterDataSet` + +Currently [`BioClim`](@ref) and [`Climate`](@ref) are implemented +for the [`CHELSA`](@ref) data source. + +#### `CMIPphase` + +Can be either [`CMIP5`](@ref) or [`CMIP6`](@ref). + +#### `ClimateModel` + +Climate models can be chosen from: + +`$(join(CMIP5_MODELS, "`, `"))` for `CMIP5`; + +`$(join(CMIP6_MODELS, "`, `"))` for `CMIP6`;" + +#### `ClimateScenario` + +CMIP5 Climate scenarios are all [`RepresentativeConcentrationPathway`](@ref) +and can be chosen from: `RCP26`, `RCP45`, `RCP60`, `RCP85` + +CMIP6 Climate scenarios are all [`SharedSocioeconomicPathway`](@ref) and +can be chosen from: `SSP126`, `SSP245`, `SSP370`, `SSP585` + +However, note that not all climate scenarios are available for all models. + +## Example + +```jldoctest future +using RasterDataSources +dataset = Future{BioClim, CMIP5, BNUESM, RCP45} +# output +Future{BioClim, CMIP5, BNUESM, RCP45} +``` +Currently `Future` is only implented for `CHELSA` + +```jldoctest future +datasource = CHELSA{Future{BioClim, CMIP5, BNUESM, RCP45}} +``` + +""" +struct Future{D<:RasterDataSet,C<:CMIPphase,M<:ClimateModel,S<:ClimateScenario} end + +_dataset(::Type{<:Future{D}}) where D = D +_phase(::Type{<:Future{<:Any,P}}) where P = P +_phase(::Type{<:ClimateModel{P}}) where P = P + +_model(::Type{<:Future{<:Any,<:Any,M}}) where M = M +_scenario(::Type{<:Future{<:Any,<:Any,<:Any,S}}) where S = S + +# fallback for layers +layers(::Type{<:Future{T}}) where T = layers(T) # need to define this after Future is defined + +### Define types for all RasterDataSets """ BioClim <: RasterDataSet @@ -103,6 +233,7 @@ const BIOCLIMPLUS_LAYERS_FUTURE = [ ] layers(::Type{BioClimPlus}) = BIOCLIMPLUS_LAYERS +layers(::Type{Future{BioClimPlus}}) = BIOCLIMPLUS_LAYERS_FUTURE """ Climate <: RasterDataSet @@ -165,139 +296,6 @@ See the [`getraster`](@ref) docs for implementation details. """ struct HabitatHeterogeneity <: RasterDataSet end -""" - CMIPphase - -Abstract supertype for phases of the CMIP, -the Coupled Model Intercomparison Project. - -Subtypes are `CMIP5` and `CMIP6`. -""" -abstract type CMIPphase end - -""" - CMIP5 <: CMIPphase - -The Coupled Model Intercomparison Project, Phase 5. -""" -struct CMIP5 <: CMIPphase end - -""" - CMIP6 <: CMIPphase - -The Coupled Model Intercomparison Project, Phase 6. -""" -struct CMIP6 <: CMIPphase end - -""" - ClimateModel - -Abstract supertype for climate models use in [`Future`](@ref) datasets. -""" -abstract type ClimateModel{CMIP<:CMIPphase} end -const CMIP6_MODELS = Type{<:ClimateModel{CMIP6}}[] -const CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] - -""" - ClimateScenario - -Abstract supertype for scenarios used in [`CMIPphase`](@ref) models. -""" -abstract type ClimateScenario end - -""" - RepresentativeConcentrationPathway - -Abstract supertype for Representative Concentration Pathways (RCPs) for [`CMIP5`](@ref). - -Subtypes are: `RCP26`, `RCP45`, `RCP60`, `RCP85` -""" -abstract type RepresentativeConcentrationPathway <: ClimateScenario end - -struct RCP26 <: RepresentativeConcentrationPathway end -struct RCP45 <: RepresentativeConcentrationPathway end -struct RCP60 <: RepresentativeConcentrationPathway end -struct RCP85 <: RepresentativeConcentrationPathway end - -""" - SharedSocioeconomicPathway - -Abstract supertype for Shared Socio-economic Pathways (SSPs) for [`CMIP6`](@ref). - -Subtypes are: `SSP126`, `SSP245`, SSP370`, SSP585` -""" -abstract type SharedSocioeconomicPathway <: ClimateScenario end - -struct SSP126 <: SharedSocioeconomicPathway end -struct SSP245 <: SharedSocioeconomicPathway end -struct SSP370 <: SharedSocioeconomicPathway end -struct SSP585 <: SharedSocioeconomicPathway end - -""" - Future{<:RasterDataSet,<:CMIPphase,<:ClimateModel,<:ClimateScenario} - -Future climate datasets specified with a dataset, phase, model, and scenario. - -## Type Parameters - -#### `RasterDataSet` - -Currently [`BioClim`](@ref) and [`Climate`](@ref) are implemented -for the [`CHELSA`](@ref) data source. - -#### `CMIPphase` - -Can be either [`CMIP5`](@ref) or [`CMIP6`](@ref). - -#### `ClimateModel` - -Climate models can be chosen from: - -`$(join(CMIP5_MODELS, "`, `"))` for `CMIP5`; - -`$(join(CMIP6_MODELS, "`, `"))` for `CMIP6`;" - -#### `ClimateScenario` - -CMIP5 Climate scenarios are all [`RepresentativeConcentrationPathway`](@ref) -and can be chosen from: `RCP26`, `RCP45`, `RCP60`, `RCP85` - -CMIP6 Climate scenarios are all [`SharedSocioeconomicPathway`](@ref) and -can be chosen from: `SSP126`, `SSP245`, `SSP370`, `SSP585` - -However, note that not all climate scenarios are available for all models. - -## Example - -```jldoctest future -using RasterDataSources -dataset = Future{BioClim, CMIP5, BNUESM, RCP45} -# output -Future{BioClim, CMIP5, BNUESM, RCP45} -``` -Currently `Future` is only implented for `CHELSA` - -```jldoctest future -datasource = CHELSA{Future{BioClim, CMIP5, BNUESM, RCP45}} -``` - -""" -struct Future{D<:RasterDataSet,C<:CMIPphase,M<:ClimateModel,S<:ClimateScenario} end - -_dataset(::Type{<:Future{D}}) where D = D -_dataset(::Type{<:Future{BioClimPlus}}) = BioClim -_phase(::Type{<:Future{<:Any,P}}) where P = P -_phase(::Type{<:ClimateModel{P}}) where P = P - -_model(::Type{<:Future{<:Any,<:Any,M}}) where M = M -_scenario(::Type{<:Future{<:Any,<:Any,<:Any,S}}) where S = S -layers(::Type{<:Future{BioClimPlus}}) = BIOCLIMPLUS_LAYERS_FUTURE - -# fallback for _format -_format(::Type, RCP::Type{<:RepresentativeConcentrationPathway}) = lowercase(string(nameof(RCP))) -_format(::Type, S::Type{<:SharedSocioeconomicPathway}) = lowercase(string(nameof(S))) -_format(::Type, S::Type{<:ClimateModel}) = replace(string(nameof(S)), "_" => "-") - """ ModisProduct <: RasterDataSet From 4bc9ac84af62b6d80709bd96071cb35bf903c4ce Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Tue, 1 Oct 2024 12:38:19 +0200 Subject: [PATCH 08/21] always use _format not string --- src/chelsa/future.jl | 10 ++++++---- src/shared.jl | 3 +-- src/worldclim/future.jl | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index 1c36f47..a9650b8 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -194,7 +194,7 @@ function _rastername( end function rasterpath(T::Type{<:CHELSA{<:Future}}) - joinpath(rasterpath(CHELSA), "Future", string(_dataset(T)), string(_scenario(T)), string(_model(T))) + joinpath(rasterpath(CHELSA), "Future", _format(T, _dataset(T)), _format(T, _scenario(T)), _format(T, _model(T))) end function rasterpath(T::Type{<:CHELSA{<:Future}}, layer; kw...) joinpath(rasterpath(T), rastername(T, layer; kw...)) @@ -212,7 +212,7 @@ _chelsa_layer(::Type{<:BioClimPlus}, layer) = :bio _chelsa_layer(::Type{<:Climate}, layer) = layer function _urlpath(::Type{CMIP5}, T::Type{<:CHELSA{<:Future}}, name, date_str) - return "chelsa_V1/cmip5/$date_str/$name/" + return "chelsav1/cmip5/$date_str/$name/" end function _urlpath(::Type{CMIP6}, T::Type{<:CHELSA{<:Future}}, name, date_str) # The model is in uppercase in the URL for CMIP6 @@ -259,8 +259,11 @@ _phase(::Type{<:CHELSA{F}}) where F<:Future = _phase(F) _model(::Type{<:CHELSA{F}}) where F<:Future = _model(F) _scenario(::Type{<:CHELSA{F}}) where F<:Future = _scenario(F) -# Climate model string formatters for CHELSA Future +## overload _format to use lowercase +_format(::Type{CHELSA}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) +_format(::Type{CHELSA}, T::Type{<:RepresentativeConcentrationPathway}) = lowercase(_format(T)) +## Climate model string formatters for CHELSA Future # CMIP5 const CHELSA_CMIP5_MODELS = Type{<:ClimateModel{CMIP5}}[] const CHELSA_CMIP5_MODEL_STRINGS = @@ -320,7 +323,6 @@ for CMIP in [:CMIP5, :CMIP6] struct $type <: ClimateModel{$CMIP} end export $type end - _format(::Type{CHELSA}, ::Type{$type}) = lowercase($model_str) push!($models, $type) end end diff --git a/src/shared.jl b/src/shared.jl index 0d3f473..e36294a 100644 --- a/src/shared.jl +++ b/src/shared.jl @@ -83,7 +83,6 @@ function _map_layers(T, layers, args...; kw...) end # fallback for _format -_format(RCP::Type{<:RepresentativeConcentrationPathway}) = lowercase(string(nameof(RCP))) -_format(S::Type{<:SharedSocioeconomicPathway}) = lowercase(string(nameof(S))) +_format(T::Type) = string(nameof(T)) _format(M::Type{<:ClimateModel}) = replace(string(nameof(M)), "_" => "-") _format(::Type, T::Type) = _format(T) diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index 0724a07..b103091 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -42,7 +42,7 @@ function rasterpath(T::Type{<:WorldClim{<:Future{BioClim}}}; res, date) joinpath(_rasterpath(T), rastername(T; res, date)) end function _rasterpath(T::Type{<:WorldClim{<:Future}}) - joinpath(rasterpath(WorldClim), "Future", string(_dataset(T)), string(_scenario(T)), string(_model(T))) + joinpath(rasterpath(WorldClim), "Future", _format(T, _dataset(T)), _format(T, _scenario(T)), _format(T, _model(T))) end function rasterurl(T::Type{<:WorldClim{<:Future}}, args...; res, date) @@ -50,7 +50,7 @@ function rasterurl(T::Type{<:WorldClim{<:Future}}, args...; res, date) end function rastername(T::Type{<:WorldClim{<:Future}}, layer; res, date) - join(["wc2.1", res, string(layer), _format(T, _model(T)), _format(T, _scenario(T)), _date_string(T, date)], "_") * ".tif" + join(["wc2.1", res, _format(T, layer), _format(T, _model(T)), _format(T, _scenario(T)), _date_string(T, date)], "_") * ".tif" end rastername(T::Type{<:WorldClim{<:Future{BioClim}}}; kw...) = rastername(T, :bioc, ; kw...) @@ -60,6 +60,8 @@ _phase(::Type{<:WorldClim{F}}) where F<:Future = _phase(F) _model(::Type{<:WorldClim{F}}) where F<:Future = _model(F) _scenario(::Type{<:WorldClim{F}}) where F<:Future = _scenario(F) +# overload _format +_format(::Type{WorldClim}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) function _date_string(::Type{<:WorldClim{<:Future{<:Any, CMIP6}}}, date) if date < DateTime(2021) @@ -106,7 +108,6 @@ for model_str in WORDCLIM_CMIP6_MODEL_STRINGS export $type end push!(WORDCLIM_CMIP6_MODELS, $type) - _format(::Type{WorldClim}, ::Type{$type}) = $model_str end end From 8bd19757bce3c7eabbf890f5bad59f54e4688000 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 11:51:36 +0200 Subject: [PATCH 09/21] add a dispatch on worldclim future with layers argument --- src/worldclim/future.jl | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index b103091..84ca46d 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -1,7 +1,7 @@ const WORLDCLIM_URI_CMIP6 = URI(scheme="https", host="geodata.ucdavis.edu", path="/cmip6") - -layers(::Type{<:WorldClim{<:Future{Climate}}}) = (:tmin, :tmax, :prec) -getraster_keywords(::Type{<:WorldClim{<:Future{Climate}}}) = (:date, :res) +layers(::Type{WorldClim{Future{BioClim}}}) = layers(WorldClim{BioClim}) +layers(::Type{WorldClim{Future{Climate}}}) = (:tmin, :tmax, :prec) +getraster_keywords(::Type{WorldClim{Future}}) = (:date, :res) function getraster(T::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, layers::Union{Tuple,Symbol}; res::String=defres(T), date @@ -21,7 +21,17 @@ end ## Bioclim getraster_keywords(::Type{<:WorldClim{<:Future{BioClim}}}) = (:date, :res) - +# Future worldclim bioclim variables are in one big file. This is for syntax consistency +function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}, layers::Union{Tuple,Symbol,Int}; kw...) + if layers isa Tuple + for l in layers + _check_layer(WorldClim{BioClim}, bioclim_int(l)) + end + else + _check_layer(WorldClim{BioClim}, bioclim_int(layers)) + end + getraster(T; kw...) +end function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}; res::String=defres(T), date) _getraster(T, res, date) end From 06e1b0beb91d25b58b49a3de64b0cf49712229ba Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 13:08:42 +0200 Subject: [PATCH 10/21] fix some dispatches --- src/chelsa/future.jl | 4 ++-- src/worldclim/future.jl | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index 6506a15..427893a 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -260,8 +260,8 @@ _model(::Type{<:CHELSA{F}}) where F<:Future = _model(F) _scenario(::Type{<:CHELSA{F}}) where F<:Future = _scenario(F) ## overload _format to use lowercase -_format(::Type{CHELSA}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) -_format(::Type{CHELSA}, T::Type{<:RepresentativeConcentrationPathway}) = lowercase(_format(T)) +_format(::Type{<:CHELSA}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) +_format(::Type{<:CHELSA}, T::Type{<:RepresentativeConcentrationPathway}) = lowercase(_format(T)) ## Climate model string formatters for CHELSA Future # CMIP5 diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index 84ca46d..c20bf0c 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -1,7 +1,7 @@ const WORLDCLIM_URI_CMIP6 = URI(scheme="https", host="geodata.ucdavis.edu", path="/cmip6") -layers(::Type{WorldClim{Future{BioClim}}}) = layers(WorldClim{BioClim}) -layers(::Type{WorldClim{Future{Climate}}}) = (:tmin, :tmax, :prec) -getraster_keywords(::Type{WorldClim{Future}}) = (:date, :res) +layers(::Type{<:WorldClim{<:Future{BioClim}}}) = layers(WorldClim{BioClim}) +layers(::Type{<:WorldClim{<:Future{Climate}}}) = (:tmin, :tmax, :prec) +getraster_keywords(::Type{<:WorldClim{<:Future}}) = (:date, :res) function getraster(T::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, layers::Union{Tuple,Symbol}; res::String=defres(T), date @@ -45,13 +45,10 @@ function _getraster(T::Type{<:WorldClim{<:Future{BioClim}}}, res::String, date) return raster_path end -function rasterpath(T::Type{<:WorldClim{<:Future{Climate}}}, layer; res, date) - joinpath(_rasterpath(T), rastername(T, layer; res, date)) +function rasterpath(T::Type{<:WorldClim{<:Future}}, args...; res, date) # splat to make sure this works with and without layer argument + joinpath(rasterpath(T), rastername(T, args...; res, date)) end -function rasterpath(T::Type{<:WorldClim{<:Future{BioClim}}}; res, date) - joinpath(_rasterpath(T), rastername(T; res, date)) -end -function _rasterpath(T::Type{<:WorldClim{<:Future}}) +function rasterpath(T::Type{<:WorldClim{<:Future}}) joinpath(rasterpath(WorldClim), "Future", _format(T, _dataset(T)), _format(T, _scenario(T)), _format(T, _model(T))) end @@ -60,9 +57,10 @@ function rasterurl(T::Type{<:WorldClim{<:Future}}, args...; res, date) end function rastername(T::Type{<:WorldClim{<:Future}}, layer; res, date) - join(["wc2.1", res, _format(T, layer), _format(T, _model(T)), _format(T, _scenario(T)), _date_string(T, date)], "_") * ".tif" + join(["wc2.1", res, string(layer), _format(T, _model(T)), _format(T, _scenario(T)), _date_string(T, date)], "_") * ".tif" end -rastername(T::Type{<:WorldClim{<:Future{BioClim}}}; kw...) = rastername(T, :bioc, ; kw...) +rastername(T::Type{<:WorldClim{<:Future{BioClim}}}; kw...) = rastername(T, "bioc"; kw...) +rastername(T::Type{<:WorldClim{<:Future{BioClim}}}, layers::Union{Tuple,Symbol,Int}; kw...) = rastername(T, "bioc"; kw...) # copy-pasted in from CHELSA - must be some way to implement this abstractly? _dataset(::Type{<:WorldClim{F}}) where F<:Future = _dataset(F) @@ -71,7 +69,8 @@ _model(::Type{<:WorldClim{F}}) where F<:Future = _model(F) _scenario(::Type{<:WorldClim{F}}) where F<:Future = _scenario(F) # overload _format -_format(::Type{WorldClim}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) +_format(::Type{<:WorldClim}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) + function _date_string(::Type{<:WorldClim{<:Future{<:Any, CMIP6}}}, date) if date < DateTime(2021) @@ -115,7 +114,6 @@ for model_str in WORDCLIM_CMIP6_MODEL_STRINGS @eval begin if !(@isdefined $type) struct $type <: ClimateModel{CMIP6} end - export $type end push!(WORDCLIM_CMIP6_MODELS, $type) end From 3f29737cd997163914c9a897fe0c0f9b9343e205 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 13:08:48 +0200 Subject: [PATCH 11/21] add worldclim future tests --- test/worldclim-future.jl | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test/worldclim-future.jl diff --git a/test/worldclim-future.jl b/test/worldclim-future.jl new file mode 100644 index 0000000..9d24c1a --- /dev/null +++ b/test/worldclim-future.jl @@ -0,0 +1,41 @@ +using RasterDataSources, Test, Dates +using RasterDataSources: rasterurl, rastername, rasterpath + +@testset "WorldClim Future BioClim CMIP6" begin + bioclim_name = "wc2.1_10m_bioc_MRI-ESM2-0_ssp126_2041-2060.tif" + @test rastername(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, 5; date=Date(2050), res = "10m") == bioclim_name + bioclim_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "WorldClim", "Future", "BioClim", "ssp126", "MRI-ESM2-0") + @test rasterpath(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}) == bioclim_path + + raster_path = joinpath(bioclim_path, bioclim_name) + raster_path2 = joinpath(bioclim_path, "wc2.1_10m_5_MRI-ESM2-0_SSP126_2041-2060.tif") + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, 5; date=Date(2050), res = "10m") == raster_path + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, :bio5; date=Date(2050)) == raster_path + +#= + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=Date(2050), res = "10m") == (bio5=raster_path,) + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, [5]; date=Date(2050), res = "10m") == (bio5=raster_path,) + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=[Date(2050)], res = "10m") == + [(bio5=raster_path,)] + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (:bio5,); date=Date(2050)) == (bio5=raster_path,) + =# + @test isfile(raster_path) +end + +@testset "WorldClim Future Climate CMIP6" begin + date_name = "wc2.1_10m_tmin_GFDL-ESM4_ssp126_2021-2040.tif" + @test rastername(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res= "10m") == date_name + + climate_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "WorldClim", "Future", "Climate", "ssp126", "GFDL-ESM4") + @test rasterpath(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}) == climate_path + date_path = joinpath(climate_path, date_name) + @test rasterpath(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path + @test rasterpath(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path + date_url = "https://geodata.ucdavis.edu/cmip6/10m/GFDL-ESM4/ssp126/wc2.1_10m_tmin_GFDL-ESM4_ssp126_2021-2040.tif" + @test rasterurl(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") |> string == date_url + @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path +# @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, (:tmin,); date=Date(2030), res = "10m") == (tmin=date_path,) + @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path + + @test isfile(date_path) +end From 68790b4fbee8a5ea849979f5c0c204ac3d2f76d7 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 16:26:11 +0200 Subject: [PATCH 12/21] always _format(T) and no dashes in file path --- src/chelsa/future.jl | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index 427893a..1511cb5 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -155,30 +155,30 @@ function _rastername( ::Type{CMIP5}, T::Type{<:CHELSA{<:Future{BioClim}}}, layer::Integer; date ) date_string = _date_string(_phase(T), date) - mod = _format(CHELSA, _model(T)) - scen = _format(CHELSA, _scenario(T)) + mod = _format(T, _model(T)) + scen = _format(T, _scenario(T)) return "CHELSA_bio_mon_$(mod)_$(scen)_r1i1p1_g025.nc_$(layer)_$(date_string)_V1.2.tif" end function _rastername( ::Type{CMIP5}, T::Type{<:CHELSA{<:Future{Climate}}}, layer::Symbol; date, month ) date_string = _date_string(_phase(T), date) - mod = _format(CHELSA, _model(T)) - scen = _format(CHELSA, _scenario(T)) + mod = _format(T, _model(T)) + scen = _format(T, _scenario(T)) key = CHELSAKEY[layer] suffix = layer === :prec ? "" : "_V1.2" # prec filenames dont end in _V1.2 return "CHELSA_$(key)_mon_$(mod)_$(scen)_r1i1p1_g025.nc_$(month)_$(date_string)$(suffix).tif" end function _rastername(::Type{CMIP6}, T::Type{<:CHELSA{<:Future{BioClim}}}, layer::Integer; date) date_string = _date_string(_phase(T), date) - mod = _format(CHELSA, _model(T)) - scen = _format(CHELSA, _scenario(T)) + mod = _format(T, _model(T)) + scen = _format(T, _scenario(T)) return "CHELSA_bio$(layer)_$(date_string)_$(mod)_$(scen)_V.2.1.tif" end function _rastername(::Type{CMIP6}, T::Type{<:CHELSA{<:Future{BioClimPlus}}}, layer::Symbol; date) date_string = _date_string(_phase(T), date) - mod = _format(CHELSA, _model(T)) - scen = _format(CHELSA, _scenario(T)) + mod = _format(T, _model(T)) + scen = _format(T, _scenario(T)) return "CHELSA_$(layer)_$(date_string)_$(mod)_$(scen)_V.2.1.tif" end function _rastername( @@ -186,15 +186,15 @@ function _rastername( ) # CMIP6 Climate uses an underscore in the date string, of course date_string = replace(_date_string(_phase(T), date), "-" => "_") - mod = _format(CHELSA, _model(T)) - scen = _format(CHELSA, _scenario(T)) + mod = _format(T, _model(T)) + scen = _format(T, _scenario(T)) key = CHELSAKEY[layer] mon = lpad(month, 2, '0') return "CHELSA_$(mod)_r1i1p1f1_w5e5_$(scen)_$(key)_$(mon)_$(date_string)_norm.tif" end function rasterpath(T::Type{<:CHELSA{<:Future}}) - joinpath(rasterpath(CHELSA), "Future", _format(T, _dataset(T)), _format(T, _scenario(T)), _format(T, _model(T))) + joinpath(rasterpath(CHELSA), "Future", _format(T, _dataset(T)), _format(_scenario(T)), replace(_format(_model(T)), "-" => "")) end function rasterpath(T::Type{<:CHELSA{<:Future}}, layer; kw...) joinpath(rasterpath(T), rastername(T, layer; kw...)) @@ -216,8 +216,8 @@ function _urlpath(::Type{CMIP5}, T::Type{<:CHELSA{<:Future}}, name, date_str) end function _urlpath(::Type{CMIP6}, T::Type{<:CHELSA{<:Future}}, name, date_str) # The model is in uppercase in the URL for CMIP6 - mod = uppercase(_format(CHELSA, _model(T))) - scen = _format(CHELSA, _scenario(T)) + mod = uppercase(_format(T, _model(T))) + scen = _format(T, _scenario(T)) key = CHELSAKEY[name] return "chelsav2/GLOBAL/climatologies/$date_str/$mod/$scen/$key/" end @@ -262,6 +262,7 @@ _scenario(::Type{<:CHELSA{F}}) where F<:Future = _scenario(F) ## overload _format to use lowercase _format(::Type{<:CHELSA}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) _format(::Type{<:CHELSA}, T::Type{<:RepresentativeConcentrationPathway}) = lowercase(_format(T)) +_format(::Type{<:CHELSA{<:Future{<:Any, CMIP6}}}, T::Type{<:ClimateModel}) = lowercase(_format(T)) ## Climate model string formatters for CHELSA Future # CMIP5 From eb3f8c0cedd19dfe8bb282b706a9f80db7d87888 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 16:26:20 +0200 Subject: [PATCH 13/21] update chelsa future test --- test/chelsa-future.jl | 46 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/test/chelsa-future.jl b/test/chelsa-future.jl index 48a378d..467791f 100644 --- a/test/chelsa-future.jl +++ b/test/chelsa-future.jl @@ -19,25 +19,25 @@ end @testset "CHELSA Future BioClim CMIP6" begin bioclim_name = "CHELSA_bio5_2041-2070_mri-esm2-0_ssp126_V.2.1.tif" - @test rastername(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}, 5; date=Date(2050)) == bioclim_name - bioclim_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "CHELSA", "Future", "BioClim", "SSP126", "MRIESM2") - @test rasterpath(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}) == bioclim_path + @test rastername(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, 5; date=Date(2050)) == bioclim_name + bioclim_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "CHELSA", "Future", "BioClim", "SSP126", "mri-esm2-0") + @test rasterpath(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}) == bioclim_path raster_path = joinpath(bioclim_path, bioclim_name) raster_path2 = joinpath(bioclim_path, "CHELSA_bio5_2071-2100_mri-esm2-0_ssp126_V.2.1.tif") - @test getraster(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}, 5; date=Date(2050)) == raster_path - @test getraster(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}, (5,); date=Date(2050)) == (bio5=raster_path,) - @test getraster(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}, [5]; date=Date(2050)) == (bio5=raster_path,) - @test getraster(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}, (5,); date=[Date(2050)]) == + @test getraster(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, 5; date=Date(2050)) == raster_path + @test getraster(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=Date(2050)) == (bio5=raster_path,) + @test getraster(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, [5]; date=Date(2050)) == (bio5=raster_path,) + @test getraster(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=[Date(2050)]) == [(bio5=raster_path,)] - @test getraster(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}, :bio5; date=Date(2050)) == raster_path - @test getraster(CHELSA{Future{BioClim,CMIP6,MRIESM2,SSP126}}, (:bio5,); date=Date(2050)) == (bio5=raster_path,) - @test getraster(CHELSA{Future{BioClimPlus,CMIP6,MRIESM2,SSP126}}, :bio5; date=Date(2050)) == raster_path - @test getraster(CHELSA{Future{BioClimPlus,CMIP6,MRIESM2,SSP126}}, (:bio5,); date=Date(2050)) == (bio5=raster_path,) + @test getraster(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, :bio5; date=Date(2050)) == raster_path + @test getraster(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (:bio5,); date=Date(2050)) == (bio5=raster_path,) + @test getraster(CHELSA{Future{BioClimPlus,CMIP6,MRI_ESM2_0,SSP126}}, :bio5; date=Date(2050)) == raster_path + @test getraster(CHELSA{Future{BioClimPlus,CMIP6,MRI_ESM2_0,SSP126}}, (:bio5,); date=Date(2050)) == (bio5=raster_path,) @test isfile(raster_path) # bioclimplus requires symbol input - @test_throws ArgumentError getraster(CHELSA{Future{BioClimPlus,CMIP6,MRIESM2,SSP126}}, 5; date=Date(2050)) + @test_throws ArgumentError getraster(CHELSA{Future{BioClimPlus,CMIP6,MRI_ESM2_0,SSP126}}, 5; date=Date(2050)) end @testset "CHELSA Future Climate CMIP5" begin @@ -60,33 +60,33 @@ end @test isfile(raster_path) @test RasterDataSources.getraster_keywords(CHELSA{Future{Climate}}) == (:date, :month) end - +@edit rasterpath(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}) @testset "CHELSA Future Climate CMIP6" begin date_name = "CHELSA_gfdl-esm4_r1i1p1f1_w5e5_ssp585_tas_01_2011_2040_norm.tif" date_name2 = "CHELSA_gfdl-esm4_r1i1p1f1_w5e5_ssp585_tas_01_2041_2070_norm.tif" date_name3 = "CHELSA_gfdl-esm4_r1i1p1f1_w5e5_ssp585_tas_01_2071_2100_norm.tif" month_name = "CHELSA_gfdl-esm4_r1i1p1f1_w5e5_ssp585_tas_01_2011_2040_norm.tif" month_name2 = "CHELSA_gfdl-esm4_r1i1p1f1_w5e5_ssp585_tas_02_2011_2040_norm.tif" - @test rastername(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_name + @test rastername(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_name climate_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "CHELSA", "Future", "Climate", "SSP585", "GFDLESM4") - @test rasterpath(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}) == climate_path + @test rasterpath(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}) == climate_path date_path = joinpath(climate_path, date_name) date_path2 = joinpath(climate_path, date_name2) date_path3 = joinpath(climate_path, date_name3) month_path = joinpath(climate_path, month_name) month_path2 = joinpath(climate_path, month_name2) - @test rasterpath(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path - @test rasterpath(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path + @test rasterpath(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path + @test rasterpath(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path date_url = "https://os.zhdk.cloud.switch.ch/chelsav2/GLOBAL/climatologies/2011-2040/GFDL-ESM4/ssp585/tas/" * date_name - @test rasterurl(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, :temp; date=Date(2030), month=1) |> string == date_url - @test getraster(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path - @test getraster(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, (:temp,); date=Date(2030), month=1) == (temp=date_path,) - @test getraster(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path + @test rasterurl(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, :temp; date=Date(2030), month=1) |> string == date_url + @test getraster(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path + @test getraster(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, (:temp,); date=Date(2030), month=1) == (temp=date_path,) + @test getraster(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, :temp; date=Date(2030), month=1) == date_path # Month is the inner vector - @test getraster(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, [:temp]; date=[Date(2030)], month=1:2) == + @test getraster(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, [:temp]; date=[Date(2030)], month=1:2) == [[(temp=month_path,), (temp=month_path2,)]] - @test getraster(CHELSA{Future{Climate,CMIP6,GFDLESM4,SSP585}}, [:temp]; date=(Date(2030), Date(2090)), month=1:1) == + @test getraster(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}, [:temp]; date=(Date(2030), Date(2090)), month=1:1) == [[(temp=date_path,)], [(temp=date_path2,)], [(temp=date_path3,)]] @test isfile(date_path) From 29680b619ff04334bc6ef63122a7cc784425f856 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 16:39:08 +0200 Subject: [PATCH 14/21] fix a test --- test/chelsa-future.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/chelsa-future.jl b/test/chelsa-future.jl index 467791f..38f602c 100644 --- a/test/chelsa-future.jl +++ b/test/chelsa-future.jl @@ -20,7 +20,7 @@ end @testset "CHELSA Future BioClim CMIP6" begin bioclim_name = "CHELSA_bio5_2041-2070_mri-esm2-0_ssp126_V.2.1.tif" @test rastername(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, 5; date=Date(2050)) == bioclim_name - bioclim_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "CHELSA", "Future", "BioClim", "SSP126", "mri-esm2-0") + bioclim_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "CHELSA", "Future", "BioClim", "SSP126", "MRIESM20") @test rasterpath(CHELSA{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}) == bioclim_path raster_path = joinpath(bioclim_path, bioclim_name) From 81f42fdb19c00728e72974ee3cdc22e4edbf27c2 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 17:25:19 +0200 Subject: [PATCH 15/21] clean up a line outside testset --- test/chelsa-future.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/chelsa-future.jl b/test/chelsa-future.jl index 38f602c..deb53d6 100644 --- a/test/chelsa-future.jl +++ b/test/chelsa-future.jl @@ -60,7 +60,7 @@ end @test isfile(raster_path) @test RasterDataSources.getraster_keywords(CHELSA{Future{Climate}}) == (:date, :month) end -@edit rasterpath(CHELSA{Future{Climate,CMIP6,GFDL_ESM4,SSP585}}) + @testset "CHELSA Future Climate CMIP6" begin date_name = "CHELSA_gfdl-esm4_r1i1p1f1_w5e5_ssp585_tas_01_2011_2040_norm.tif" date_name2 = "CHELSA_gfdl-esm4_r1i1p1f1_w5e5_ssp585_tas_01_2041_2070_norm.tif" From 63d815c880127b10e5c9ba24f441e0cea629af2f Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 2 Oct 2024 17:28:18 +0200 Subject: [PATCH 16/21] soft document why dashes in modelname path are dropped --- src/chelsa/future.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index 1511cb5..a2bff5d 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -194,7 +194,9 @@ function _rastername( end function rasterpath(T::Type{<:CHELSA{<:Future}}) - joinpath(rasterpath(CHELSA), "Future", _format(T, _dataset(T)), _format(_scenario(T)), replace(_format(_model(T)), "-" => "")) + # drop dashes so paths are more (but not entirely!) compatibile with v0.6 + modelname = replace(_format(_model(T)), "-" => "") + joinpath(rasterpath(CHELSA), "Future", _format(T, _dataset(T)), _format(_scenario(T)), modelname) end function rasterpath(T::Type{<:CHELSA{<:Future}}, layer; kw...) joinpath(rasterpath(T), rastername(T, layer; kw...)) From 83fddeacfa1a48cd96e2aebbd1241a998e6b6614 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 3 Oct 2024 12:43:28 +0200 Subject: [PATCH 17/21] add a generic date formatter --- src/chelsa/future.jl | 50 +++++++++----------------------------------- src/shared.jl | 28 ++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index a2bff5d..d2859b4 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -4,12 +4,13 @@ layers(::Type{<:CHELSA{T}}) where T <:Future{BioClimPlus} = layers(T) layerkeys(T::Type{<:CHELSA{<:Future{BioClim}}}, args...) = layerkeys(BioClim, args...) layers(::Type{<:CHELSA{<:Future{Climate}}}) = (:prec, :temp, :tmin, :tmax) +# A modified key is used in the file name, while the key is used as-is in the path +const CHELSAKEY = (prec="pr", temp="tas", tmin="tasmin", tmax="tasmax", bio="bio") date_step(::Type{<:CHELSA{<:Future{Climate,CMIP5}}}) = Year(20) +date_range(::Type{<:CHELSA{<:Future{Climate,CMIP5}}}) = (Date(2041), Date(2080)) date_step(::Type{<:CHELSA{<:Future{Climate,CMIP6}}}) = Year(30) - -# A modified key is used in the file name, while the key is used as-is in the path -const CHELSAKEY = (prec="pr", temp="tas", tmin="tasmin", tmax="tasmax", bio="bio") +date_range(::Type{<:CHELSA{<:Future{Climate,CMIP6}}}) = (Date(1981), Date(2100)) """ getraster(T::Type{CHELSA{Future{BioClim}}}, [layer]; date) => String @@ -154,7 +155,7 @@ end function _rastername( ::Type{CMIP5}, T::Type{<:CHELSA{<:Future{BioClim}}}, layer::Integer; date ) - date_string = _date_string(_phase(T), date) + date_string = _format(T, date) mod = _format(T, _model(T)) scen = _format(T, _scenario(T)) return "CHELSA_bio_mon_$(mod)_$(scen)_r1i1p1_g025.nc_$(layer)_$(date_string)_V1.2.tif" @@ -162,7 +163,7 @@ end function _rastername( ::Type{CMIP5}, T::Type{<:CHELSA{<:Future{Climate}}}, layer::Symbol; date, month ) - date_string = _date_string(_phase(T), date) + date_string = _format(T, date) mod = _format(T, _model(T)) scen = _format(T, _scenario(T)) key = CHELSAKEY[layer] @@ -170,13 +171,13 @@ function _rastername( return "CHELSA_$(key)_mon_$(mod)_$(scen)_r1i1p1_g025.nc_$(month)_$(date_string)$(suffix).tif" end function _rastername(::Type{CMIP6}, T::Type{<:CHELSA{<:Future{BioClim}}}, layer::Integer; date) - date_string = _date_string(_phase(T), date) + date_string = _format(T, date) mod = _format(T, _model(T)) scen = _format(T, _scenario(T)) return "CHELSA_bio$(layer)_$(date_string)_$(mod)_$(scen)_V.2.1.tif" end function _rastername(::Type{CMIP6}, T::Type{<:CHELSA{<:Future{BioClimPlus}}}, layer::Symbol; date) - date_string = _date_string(_phase(T), date) + date_string = _format(T, date) mod = _format(T, _model(T)) scen = _format(T, _scenario(T)) return "CHELSA_$(layer)_$(date_string)_$(mod)_$(scen)_V.2.1.tif" @@ -185,7 +186,7 @@ function _rastername( ::Type{CMIP6}, T::Type{<:CHELSA{<:Future{Climate}}}, layer::Symbol; date, month ) # CMIP6 Climate uses an underscore in the date string, of course - date_string = replace(_date_string(_phase(T), date), "-" => "_") + date_string = replace(_format(T, date), "-" => "_") mod = _format(T, _model(T)) scen = _format(T, _scenario(T)) key = CHELSAKEY[layer] @@ -203,7 +204,7 @@ function rasterpath(T::Type{<:CHELSA{<:Future}}, layer; kw...) end function rasterurl(T::Type{<:CHELSA{<:Future}}, layer; date, kw...) - date_str = _date_string(_phase(T), date) + date_str = _format(T, date) key = _chelsa_layer(_dataset(T), layer) path = _urlpath(_phase(T), T::Type{<:CHELSA{<:Future}}, key, date_str) joinpath(rasterurl(CHELSA), path, rastername(T, layer; date, kw...)) @@ -224,37 +225,6 @@ function _urlpath(::Type{CMIP6}, T::Type{<:CHELSA{<:Future}}, name, date_str) return "chelsav2/GLOBAL/climatologies/$date_str/$mod/$scen/$key/" end -function _date_string(::Type{CMIP5}, date) - if date < DateTime(2041) - _cmip5_date_error(date) - elseif date < DateTime(2061) - "2041-2060" - elseif date < DateTime(2081) - "2061-2080" - else - _cmip5_date_error(date) - end -end - -function _date_string(::Type{CMIP6}, date) - if date < DateTime(1981) - _cmip6_date_error(date) - elseif date < DateTime(2011) - "1981-2010" - elseif date < DateTime(2041) - "2011-2040" - elseif date < DateTime(2071) - "2041-2070" - elseif date < DateTime(2101) - "2071-2100" - else - _cmip6_date_error(date) - end -end - -_cmip5_date_error(date) = error("CMIP5 covers the period from 2041-2080, not including $date") -_cmip6_date_error(date) = error("CMIP6 covers the period from 1981-2100, not including $date") - _dataset(::Type{<:CHELSA{F}}) where F<:Future = _dataset(F) _dataset(::Type{<:Future{BioClimPlus}}) = BioClim # to make sure bioclimplus and bioclim end up in the same folder _phase(::Type{<:CHELSA{F}}) where F<:Future = _phase(F) diff --git a/src/shared.jl b/src/shared.jl index e36294a..70c4825 100644 --- a/src/shared.jl +++ b/src/shared.jl @@ -32,6 +32,32 @@ _date_sequence(step, dates::AbstractArray) = dates _date_sequence(step, dates::NTuple{2}) = first(dates):step:last(dates) _date_sequence(step, date) = date:step:date +function _format(T::Type{<:RasterDataSource}, date::TimeType) + daterange = date_range(T) + datestep = date_step(T) + # check if the date is within the range + if date < first(daterange) || date > last(daterange) + _date_error(date, daterange) + end + + # find which bin it is in + r = range(daterange...; step = datestep) + idx = searchsortedfirst(r, date) + + # from here on just use integer math + startyear = Dates.year(first(daterange)) + yearstep = Dates.value(datestep) + startyear = startyear + yearstep * (idx - 2) + endyear = startyear + yearstep - 1 + return "$startyear-$endyear" +end + +function _date_error(date, daterange) + startyear = Dates.year(first(daterange)) + endyear = Dates.year(last(daterange)) + error("The requested dataset covers the period from $startyear-$endyear, which does not include $date") +end + function _maybe_download(uri::URI, filepath, headers = []) if !isfile(filepath) mkpath(dirname(filepath)) @@ -83,6 +109,6 @@ function _map_layers(T, layers, args...; kw...) end # fallback for _format +_format(::Type, T) = _format(T) _format(T::Type) = string(nameof(T)) _format(M::Type{<:ClimateModel}) = replace(string(nameof(M)), "_" => "-") -_format(::Type, T::Type) = _format(T) From 0611501c8063732c56996b77329765379d610bed Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 3 Oct 2024 12:44:48 +0200 Subject: [PATCH 18/21] make future worldclim work for multiple dates --- src/worldclim/future.jl | 67 ++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index c20bf0c..94208c1 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -1,15 +1,27 @@ -const WORLDCLIM_URI_CMIP6 = URI(scheme="https", host="geodata.ucdavis.edu", path="/cmip6") -layers(::Type{<:WorldClim{<:Future{BioClim}}}) = layers(WorldClim{BioClim}) -layers(::Type{<:WorldClim{<:Future{Climate}}}) = (:tmin, :tmax, :prec) +## Shared getraster_keywords(::Type{<:WorldClim{<:Future}}) = (:date, :res) -function getraster(T::Type{<:WorldClim{<:Future{Climate, CMIP6}}}, layers::Union{Tuple,Symbol}; +date_step(::Type{<:WorldClim{<:Future{<:Any,CMIP6}}}) = Year(20) +date_range(::Type{<:WorldClim{<:Future{<:Any,CMIP6}}}) = (Date(2021), Date(2100)) + +function getraster(T::Type{<:WorldClim{<:Future}}, layers::Union{Tuple,Symbol,Int}; res::String=defres(T), date ) _getraster(T, layers, res, date) end -function _getraster(T::Type{<:WorldClim{<:Future{Climate}}}, layer::Symbol, res::String, date) +function _getraster(T::Type{<:WorldClim{<:Future}}, layers, res::String, dates) + map(date -> _getraster(T, layers, res, date), date_sequence(T, dates)) +end + + +## Climate +layers(::Type{<:WorldClim{<:Future{Climate}}}) = (:tmin, :tmax, :prec) + +function _getraster(T::Type{<:WorldClim{<:Future{Climate}}}, layers::Tuple, res::String, date::TimeType) + _map_layers(T, layers, res, date) +end +function _getraster(T::Type{<:WorldClim{<:Future{Climate}}}, layer::Symbol, res::String, date::TimeType) _check_layer(T, layer) _check_res(T, res) raster_path = rasterpath(T, layer; res, date) @@ -19,24 +31,22 @@ function _getraster(T::Type{<:WorldClim{<:Future{Climate}}}, layer::Symbol, res: return raster_path end + ## Bioclim -getraster_keywords(::Type{<:WorldClim{<:Future{BioClim}}}) = (:date, :res) -# Future worldclim bioclim variables are in one big file. This is for syntax consistency -function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}, layers::Union{Tuple,Symbol,Int}; kw...) +layers(::Type{<:WorldClim{<:Future{BioClim}}}) = layers(WorldClim{BioClim}) + +function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}; res::String=defres(T), date) + getraster(T, :bio1; res, date) +end + +function _getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}, layers, res::String, date::TimeType) if layers isa Tuple for l in layers - _check_layer(WorldClim{BioClim}, bioclim_int(l)) + _check_layer(T, bioclim_int(l)) end else - _check_layer(WorldClim{BioClim}, bioclim_int(layers)) + _check_layer(T, bioclim_int(layers)) end - getraster(T; kw...) -end -function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}; res::String=defres(T), date) - _getraster(T, res, date) -end - -function _getraster(T::Type{<:WorldClim{<:Future{BioClim}}}, res::String, date) _check_res(T, res) raster_path = rasterpath(T; res, date) if !isfile(raster_path) @@ -53,11 +63,12 @@ function rasterpath(T::Type{<:WorldClim{<:Future}}) end function rasterurl(T::Type{<:WorldClim{<:Future}}, args...; res, date) - joinpath(WORLDCLIM_URI_CMIP6, res, _format(T, _model(T)), _format(T, _scenario(T)), rastername(T, args...; res, date)) + joinpath(rasterurl(T), res, _format(T, _model(T)), _format(T, _scenario(T)), rastername(T, args...; res, date)) end +rasterurl(T::Type{<:WorldClim{<:Future}}) = URI(scheme="https", host="geodata.ucdavis.edu", path="/cmip6") function rastername(T::Type{<:WorldClim{<:Future}}, layer; res, date) - join(["wc2.1", res, string(layer), _format(T, _model(T)), _format(T, _scenario(T)), _date_string(T, date)], "_") * ".tif" + join(["wc2.1", res, string(layer), _format(T, _model(T)), _format(T, _scenario(T)), _format(T, date)], "_") * ".tif" end rastername(T::Type{<:WorldClim{<:Future{BioClim}}}; kw...) = rastername(T, "bioc"; kw...) rastername(T::Type{<:WorldClim{<:Future{BioClim}}}, layers::Union{Tuple,Symbol,Int}; kw...) = rastername(T, "bioc"; kw...) @@ -71,24 +82,6 @@ _scenario(::Type{<:WorldClim{F}}) where F<:Future = _scenario(F) # overload _format _format(::Type{<:WorldClim}, T::Type{<:SharedSocioeconomicPathway}) = lowercase(_format(T)) - -function _date_string(::Type{<:WorldClim{<:Future{<:Any, CMIP6}}}, date) - if date < DateTime(2021) - _cmip6_date_error(date) - elseif date < DateTime(2041) - "2021-2040" - elseif date < DateTime(2061) - "2041-2060" - elseif date < DateTime(2081) - "2041-2060" - elseif date < DateTime(2101) - "2081-2100" - else - _cmip6_date_error(date) - end -end - - ## Handle all the models const WORDCLIM_CMIP6_MODEL_STRINGS = [ "ACCESS-CM2" From 809b3babeab039488d1d7e3f01cc3818a3cb7deb Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 3 Oct 2024 12:45:15 +0200 Subject: [PATCH 19/21] fix worldclim futur tests --- test/worldclim-future.jl | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/test/worldclim-future.jl b/test/worldclim-future.jl index 9d24c1a..7394296 100644 --- a/test/worldclim-future.jl +++ b/test/worldclim-future.jl @@ -9,32 +9,40 @@ using RasterDataSources: rasterurl, rastername, rasterpath raster_path = joinpath(bioclim_path, bioclim_name) raster_path2 = joinpath(bioclim_path, "wc2.1_10m_5_MRI-ESM2-0_SSP126_2041-2060.tif") + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}; date=Date(2050), res = "10m") == raster_path @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, 5; date=Date(2050), res = "10m") == raster_path @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, :bio5; date=Date(2050)) == raster_path - -#= - @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=Date(2050), res = "10m") == (bio5=raster_path,) - @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, [5]; date=Date(2050), res = "10m") == (bio5=raster_path,) - @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=[Date(2050)], res = "10m") == - [(bio5=raster_path,)] - @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (:bio5,); date=Date(2050)) == (bio5=raster_path,) - =# + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=Date(2050), res = "10m") == raster_path + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, [5]; date=Date(2050), res = "10m") == raster_path + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=[Date(2050)], res = "10m") == [raster_path] + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (5,); date=(Date(2050),Date(2050)), res = "10m") == + [raster_path] + @test getraster(WorldClim{Future{BioClim,CMIP6,MRI_ESM2_0,SSP126}}, (:bio5,); date=Date(2050)) ==raster_path + @test isfile(raster_path) end @testset "WorldClim Future Climate CMIP6" begin date_name = "wc2.1_10m_tmin_GFDL-ESM4_ssp126_2021-2040.tif" + date_name2 = "wc2.1_10m_tmin_GFDL-ESM4_ssp126_2041-2060.tif" + date_name3 = "wc2.1_10m_tmin_GFDL-ESM4_ssp126_2061-2080.tif" + date_name4 = "wc2.1_10m_tmin_GFDL-ESM4_ssp126_2081-2100.tif" + date_names = [date_name, date_name2, date_name3, date_name4] + @test rastername(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res= "10m") == date_name climate_path = joinpath(ENV["RASTERDATASOURCES_PATH"], "WorldClim", "Future", "Climate", "ssp126", "GFDL-ESM4") @test rasterpath(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}) == climate_path date_path = joinpath(climate_path, date_name) + date_paths = joinpath.(climate_path, date_names) @test rasterpath(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path @test rasterpath(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path date_url = "https://geodata.ucdavis.edu/cmip6/10m/GFDL-ESM4/ssp126/wc2.1_10m_tmin_GFDL-ESM4_ssp126_2021-2040.tif" @test rasterurl(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") |> string == date_url @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path -# @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, (:tmin,); date=Date(2030), res = "10m") == (tmin=date_path,) + @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, (:tmin,); date=Date(2030), res = "10m") == (tmin=date_path,) + @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, (:tmin,); date=(Date(2030), Date(2090)), res = "10m") == + [(tmin=date_path,) for date_path in date_paths] @test getraster(WorldClim{Future{Climate,CMIP6,GFDL_ESM4,SSP126}}, :tmin; date=Date(2030), res = "10m") == date_path @test isfile(date_path) From 2b382d105253d39f1b107d74c7114943f14756ff Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Thu, 3 Oct 2024 12:50:35 +0200 Subject: [PATCH 20/21] fix date_step and range for chelsa bioclim --- src/chelsa/future.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chelsa/future.jl b/src/chelsa/future.jl index d2859b4..fd4e6b5 100644 --- a/src/chelsa/future.jl +++ b/src/chelsa/future.jl @@ -7,10 +7,10 @@ layers(::Type{<:CHELSA{<:Future{Climate}}}) = (:prec, :temp, :tmin, :tmax) # A modified key is used in the file name, while the key is used as-is in the path const CHELSAKEY = (prec="pr", temp="tas", tmin="tasmin", tmax="tasmax", bio="bio") -date_step(::Type{<:CHELSA{<:Future{Climate,CMIP5}}}) = Year(20) -date_range(::Type{<:CHELSA{<:Future{Climate,CMIP5}}}) = (Date(2041), Date(2080)) -date_step(::Type{<:CHELSA{<:Future{Climate,CMIP6}}}) = Year(30) -date_range(::Type{<:CHELSA{<:Future{Climate,CMIP6}}}) = (Date(1981), Date(2100)) +date_step(::Type{<:CHELSA{<:Future{<:Any,CMIP5}}}) = Year(20) +date_range(::Type{<:CHELSA{<:Future{<:Any,CMIP5}}}) = (Date(2041), Date(2080)) +date_step(::Type{<:CHELSA{<:Future{<:Any,CMIP6}}}) = Year(30) +date_range(::Type{<:CHELSA{<:Future{<:Any,CMIP6}}}) = (Date(1981), Date(2100)) """ getraster(T::Type{CHELSA{Future{BioClim}}}, [layer]; date) => String From 4d0a476ee58a4289532a87ba2995cdd733fee463 Mon Sep 17 00:00:00 2001 From: tiemvanderdeure <tiemvanderdeure@gmail.com> Date: Wed, 9 Oct 2024 15:14:23 +0200 Subject: [PATCH 21/21] define layerkeys for WorldClim{Future{BioClim}} --- src/worldclim/future.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/worldclim/future.jl b/src/worldclim/future.jl index 94208c1..e3a312f 100644 --- a/src/worldclim/future.jl +++ b/src/worldclim/future.jl @@ -34,6 +34,7 @@ end ## Bioclim layers(::Type{<:WorldClim{<:Future{BioClim}}}) = layers(WorldClim{BioClim}) +layerkeys(::Type{<:WorldClim{<:Future{BioClim}}}) = layerkeys(WorldClim{BioClim}) function getraster(T::Type{<:WorldClim{<:Future{BioClim, CMIP6}}}; res::String=defres(T), date) getraster(T, :bio1; res, date)