Skip to content

Commit

Permalink
Add a start_date attribute to NetCDFWriter
Browse files Browse the repository at this point in the history
Prior to this version, users had to go to the simution to find the start date.
It is now saved as an attribute, making it easily accessible.
  • Loading branch information
AlexisRenchon committed Oct 25, 2024
1 parent c4cbd80 commit 7b54af1
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 7 deletions.
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
v0.2.9
-------

## Features

### Add a `start_date` attribute to NetCDFWriter PR [#94](https://github.com/CliMA/ClimaDiagnostics.jl/pull/94).

Prior to this version, users had to go to the simution to find the start date.
It can now be saved as an attribute, making it easily accessible.
To do so, users need to pass the kwarg `start_date` when calling `NetCDFWriter`.

## Bug fixes

### Acquiring ownership with `compute!` PR [#88](https://github.com/CliMA/ClimaDiagnostics.jl/pull/88).
Expand Down
5 changes: 4 additions & 1 deletion docs/src/writers.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interpolation is needed.
## `NetCDFWriter`

The `NetCDFWriter` resamples the input `Field` to a rectangular grid and saves
the output to a NetCDF file.
the output to a NetCDF file.

The `NetCDFWriter` relies on the `Remappers` module in `ClimaCore` to
interpolate onto the rectangular grid. Horizontally, this interpolation is a
Expand All @@ -32,6 +32,9 @@ and the output directory where the files should be saved. By default, the
exist. The `NetCDFWriter` does not overwrite existing data and will error out if
existing data is inconsistent with the new one.

Optionally (recommended), you can pass an optional argument `start_date`, which
will be saved as an attribute of your NetCDF file, easily accessible.

`NetCDFWriter`s take as one of the inputs the desired number of points along
each of the dimensions. For the horizontal dimensions, points are sampled
linearly. For the vertical dimension, the behavior can be customized by passing
Expand Down
25 changes: 19 additions & 6 deletions src/netcdf_writer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ include("netcdf_writer_coordinates.jl")
A struct to remap `ClimaCore` `Fields` to rectangular grids and save the output to NetCDF
files.
"""
struct NetCDFWriter{T, TS, DI, SYNC, ZSM <: AbstractZSamplingMethod} <:
struct NetCDFWriter{T, TS, DI, SYNC, ZSM <: AbstractZSamplingMethod, DATE} <:
AbstractWriter
"""The base folder where to save the files."""
output_dir::String
Expand Down Expand Up @@ -64,6 +64,9 @@ struct NetCDFWriter{T, TS, DI, SYNC, ZSM <: AbstractZSamplingMethod} <:

"""Set of datasets that need to be synced. Useful when `sync_schedule` is not `nothing`."""
unsynced_datasets::Set{NCDatasets.NCDataset}

"""Date of the beginning of the simulation (it is used to convert seconds to dates)."""
start_date::DATE
end

"""
Expand Down Expand Up @@ -103,6 +106,7 @@ Keyword arguments
a boolean callable that takes as a single argument the `integrator`.
`sync_schedule` can also be set as `nothing`, in which case we let
handling buffered writes to disk.
- `start_date`: Date of the beginning of the simulation.
"""
function NetCDFWriter(
space,
Expand All @@ -112,6 +116,7 @@ function NetCDFWriter(
sync_schedule = ClimaComms.device(space) isa ClimaComms.CUDADevice ?
EveryStepSchedule() : nothing,
z_sampling_method = LevelsMethod(),
start_date = nothing,
)
horizontal_space = Spaces.horizontal_space(space)
is_horizontal_space = horizontal_space == space
Expand Down Expand Up @@ -173,6 +178,7 @@ function NetCDFWriter(
typeof(preallocated_arrays),
typeof(sync_schedule),
typeof(z_sampling_method),
typeof(start_date),
}(
output_dir,
Dict{String, Remapper}(),
Expand All @@ -184,6 +190,7 @@ function NetCDFWriter(
preallocated_arrays,
sync_schedule,
unsynced_datasets,
start_date,
)
end

Expand Down Expand Up @@ -349,6 +356,13 @@ function write_field!(writer::NetCDFWriter, field, diagnostic, u, p, t)
writer.interpolated_physical_z,
)

start_date = nothing
if isnothing(writer.start_date)
start_date = get(p, :start_date, nothing)
else
start_date = writer.start_date
end

if haskey(nc, "$(var.short_name)")
# We already have something in the file
v = nc["$(var.short_name)"]
Expand All @@ -367,9 +381,8 @@ function write_field!(writer::NetCDFWriter, field, diagnostic, u, p, t)
v.attrib["long_name"] = output_long_name(diagnostic)::String
v.attrib["units"] = var.units::String
v.attrib["comments"] = var.comments::String
if hasproperty(p, :start_date)
# FIXME: We are hardcoding p.start_date !
v.attrib["start_date"] = string(p.start_date)::String
if !isnothing(start_date) && !haskey(v.attrib, "start_date")
v.attrib["start_date"] = string(start_date)::String
end
temporal_size = 0
end
Expand All @@ -382,8 +395,8 @@ function write_field!(writer::NetCDFWriter, field, diagnostic, u, p, t)

# FIXME: We are hardcoding p.start_date !
# FIXME: We are rounding t
if hasproperty(p, :start_date)
nc["date"][time_index] = string(p.start_date + Dates.Second(round(t)))
if !isnothing(start_date)
nc["date"][time_index] = string(start_date + Dates.Millisecond(1000t))
end

# TODO: It would be nice to find a cleaner way to do this
Expand Down
5 changes: 5 additions & 0 deletions test/integration_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import NCDatasets

import ClimaDiagnostics

import Dates

import ClimaComms
@static if pkgversion(ClimaComms) >= v"0.6"
ClimaComms.@import_required_backends
Expand Down Expand Up @@ -38,6 +40,7 @@ function setup_integrator(output_dir; context, more_compute_diagnostics = 0)
space,
output_dir;
num_points = (10, 5, 3),
start_date = Dates.DateTime(2015, 2, 2),
)

function compute_my_var!(out, u, p, t)
Expand Down Expand Up @@ -126,6 +129,8 @@ end
@test nc["YO"].attrib["short_name"] == "YO"
@test nc["YO"].attrib["long_name"] == "YO YO, Instantaneous"
@test size(nc["YO"]) == (11, 10, 5, 10)
@test nc["YO"].attrib["start_date"] ==
string(Dates.DateTime(2015, 2, 2))
end

NCDatasets.NCDataset(
Expand Down

0 comments on commit 7b54af1

Please sign in to comment.