Skip to content

Commit

Permalink
add functions for ClimaCoupler
Browse files Browse the repository at this point in the history
  • Loading branch information
juliasloan25 committed Sep 10, 2024
1 parent 97be0c5 commit 8b8ffcc
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 43 deletions.
6 changes: 4 additions & 2 deletions docs/src/callbackmanager.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ functions from Julia's [Dates](https://docs.julialang.org/en/v1/stdlib/Dates/) m
## CallbackManager API

```@docs
ClimaUtilities.CallbackManager.HourlyCallback
ClimaUtilities.CallbackManager.MonthlyCallback
ClimaUtilities.CallbackManager.Monthly
ClimaUtilities.CallbackManager.EveryTimestep
ClimaUtilities.CallbackManager.to_datetime
ClimaUtilities.CallbackManager.strdate_to_datetime
ClimaUtilities.CallbackManager.datetime_to_strdate
ClimaUtilities.CallbackManager.trigger_callback
ClimaUtilities.CallbackManager.Monthly
ClimaUtilities.CallbackManager.EveryTimestep
```
141 changes: 100 additions & 41 deletions src/CallbackManager.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,64 +8,71 @@ module CallbackManager

import Dates

export to_datetime,
strdate_to_datetime,
datetime_to_strdate,
trigger_callback,
export HourlyCallback,
MonthlyCallback,
Monthly,
EveryTimestep
EveryTimestep,
trigger_callback,
to_datetime,
strdate_to_datetime,
datetime_to_strdate

"""
to_datetime(date)
AbstractCallback
"""
abstract type AbstractCallback end

Convert a `DateTime`-like object (e.g. `DateTimeNoLeap`) to a `DateTime`.
We need this since some data files we use contain
`DateTimeNoLeap` objects for dates, which can't be used for math with `DateTime`s.
The `DateTimeNoLeap` type uses the Gregorian calendar without leap years, while
the `DateTime` type uses Gregorian calendar with leap years.
"""
HourlyCallback{FT}
For consistency, all input data files should have dates converted to `DateTime`
before being used in a simulation.
This is a callback type that triggers at intervals of 1h or multiple hours.
"""
@kwdef struct HourlyCallback{FT} <: AbstractCallback
""" Time interval at which the callback is triggered. """
dt::FT = FT(1) # hours
""" Function to be called at each trigger. """
func::Function = do_nothing
""" Reference date for the callback. """
ref_date::Array = [Dates.DateTime(0)]
""" Whether the callback is active. """
active::Bool = false
""" Data to be passed to the callback function. """
data::Array = []
end

This function is similar to `reinterpret` in CFTime.jl.
"""
MonthlyCallback{FT}
# Arguments
- `date`: `DateTime`-like object to be converted to `DateTime`
This is a callback type that triggers at intervals of 1 month or multiple months.
"""
function to_datetime(date)
return Dates.DateTime(
Dates.year(date),
Dates.month(date),
Dates.day(date),
Dates.hour(date),
Dates.minute(date),
Dates.second(date),
Dates.millisecond(date),
)
@kwdef struct MonthlyCallback{FT} <: AbstractCallback
""" Time interval at which the callback is triggered. """
dt::FT = FT(1) # months
""" Function to be called at each trigger. """
func::Function = do_nothing
""" Reference date for the callback. """
ref_date::Array = [Dates.DateTime(0)]
""" Whether the callback is active. """
active::Bool = false
""" Data to be passed to the callback function. """
data::Array = []
end

"""
strdate_to_datetime(strdate::String)
dt_cb(cb::HourlyCallback)
dt_cb(cb::MonthlyCallback)
Convert from String ("YYYYMMDD") to Date format,
required by the official AMIP input files.
This function returns the time interval for the callback.
"""
strdate_to_datetime(strdate::String) = Dates.DateTime(
parse(Int, strdate[1:4]),
parse(Int, strdate[5:6]),
parse(Int, strdate[7:8]),
)
dt_cb(cb::HourlyCallback) = Dates.Hour(cb.dt)
dt_cb(cb::MonthlyCallback) = Dates.Month(cb.dt)

"""
datetime_to_strdate(datetime::Dates.DateTime)

Convert from DateTime to String ("YYYYMMDD") format.
"""
datetime_to_strdate(datetime::Dates.DateTime) =
string(lpad(Dates.year(datetime), 4, "0")) *
string(string(lpad(Dates.month(datetime), 2, "0"))) *
string(lpad(Dates.day(datetime), 2, "0"))
AbstractFrequency
This is an abstract type for the frequency of a callback function.
"""
abstract type AbstractFrequency end
struct Monthly <: AbstractFrequency end
struct EveryTimestep <: AbstractFrequency end
Expand Down Expand Up @@ -105,4 +112,56 @@ function trigger_callback(
end
end

"""
to_datetime(date)
Convert a `DateTime`-like object (e.g. `DateTimeNoLeap`) to a `DateTime`.
We need this since some data files we use contain
`DateTimeNoLeap` objects for dates, which can't be used for math with `DateTime`s.
The `DateTimeNoLeap` type uses the Gregorian calendar without leap years, while
the `DateTime` type uses Gregorian calendar with leap years.
For consistency, all input data files should have dates converted to `DateTime`
before being used in a simulation.
This function is similar to `reinterpret` in CFTime.jl.
# Arguments
- `date`: `DateTime`-like object to be converted to `DateTime`
"""
function to_datetime(date)
return Dates.DateTime(
Dates.year(date),
Dates.month(date),
Dates.day(date),
Dates.hour(date),
Dates.minute(date),
Dates.second(date),
Dates.millisecond(date),
)
end

"""
strdate_to_datetime(strdate::String)
Convert from String ("YYYYMMDD") to Date format,
required by the official AMIP input files.
"""
strdate_to_datetime(strdate::String) = Dates.DateTime(
parse(Int, strdate[1:4]),
parse(Int, strdate[5:6]),
parse(Int, strdate[7:8]),
)

"""
datetime_to_strdate(datetime::Dates.DateTime)
Convert from DateTime to String ("YYYYMMDD") format.
"""
datetime_to_strdate(datetime::Dates.DateTime) =
string(lpad(Dates.year(datetime), 4, "0")) *
string(string(lpad(Dates.month(datetime), 2, "0"))) *
string(lpad(Dates.day(datetime), 2, "0"))


end # module CallbackManager

0 comments on commit 8b8ffcc

Please sign in to comment.