Units and Time
Here we describe how units and time are handled across Sargassum.jl. The bulk of unit definitions and conversions are handled through the Julia package Unitful. Occasionally, more advanced use of this package will require entering units, hence we review this process briefly.
A Short Review of Unitful.jl
Define units with the syntax u"unit_symbol_here". For example, meters, kilometer per day and degrees are defined respectively by
u"m"
u"km/d"
u"°"Quantities are defined by multiplying a number by a unit,
5.0 * u"m"Units are converted using the uconvert(unit_target, quantity_to_convert) function, e.g.
uconvert(u"m", 2.0 * u"km") # convert 2km to m2000.0 mUnits
All units are converted internally to a consistent unit based on its function according to the global dictionary UNITS.
UNITSDict{String, Unitful.Unitlike} with 8 entries:
"distance" => km
"none" =>
"degrees" => °
"time" => d
"speed" => km d^-1
"wave_height" => m
"concentration" => mmol m^-3
"temperature" => °CFor example, distances are measured in UNITS["distance"], which is km.
Coordinates
Sargassum.jl uses both spherical (longitude/latitude) and equirectangular (x/y) coordinates as needed. The underlying physics equations must be integrated in equirectangular coordinates, but the user-facing coordinates are generally converted to spherical coordinates as much as possible.
In order to convert between spherical and equirectangular coordinates, a reference longitude lon0 and latitude lat0 are required. This is held by an EquirectangularReference object which can be constructed with lon0 and lat0 as kwargs,
EquirectangularReference(lon0 = -75, lat0 = 10)EquirectangularReference[lon0 = -75.0, lat0 = 10.0, R = 6371.0 km]Note that the EquirectangularReference also has a field for the radius of the Earth, in units of UNITS["distance"]. There is a global reference EQR that is used by default for all conversions. This reference is generally appropriate for the Caribbean region.
EQRBase.RefValue{EquirectangularReference}(EquirectangularReference[lon0 = -75.0, lat0 = 10.0, R = 6371.0 km])The primary functions for conversion are sph2xy and xy2sph. These can be applied to a variety of objects, refer to the full documentation for details. The most basic usage is sph2xy(x, y; eqr = EQR) and xy2sph(x, y; eqr = EQR).
x, y = sph2xy(-80, 15)2-element Vector{Float64}:
-547.528129275926
555.9746332227937xy2sph(x, y)2-element Vector{Float64}:
-80.0
15.0x, y = sph2xy(-80, 15, eqr = EquirectangularReference(lon0 = -80, lat0 = 15))2-element Vector{Float64}:
0.0
0.0xy2sph(x, y, eqr = EquirectangularReference(lon0 = -80, lat0 = 15))2-element Vector{Float64}:
-80.0
15.0Times
Specific times are defined using the Dates module. For Sargassum.jl, in almost all cases, the only function actually required is DateTime(year, month, day), e.g.
DateTime(2000, 1, 1) # January 1, 20002000-01-01T00:00:00All times are internally converted to UNITS["times"] (equal to days) since a reference time T_REF
T_REFBase.RefValue{DateTime}(DateTime("2000-01-01T00:00:00"))Note that T_REF is a Ref, i.e. its actual value is accessed using T_REF.x although this should generally not be required.
For conversions, the functions datetime2time and time2datetime are inverses.
t = datetime2time(DateTime(2018, 4, 14))6678.0time2datetime(t)2018-04-14T00:00:00The AFAI functionality of Sargassum.jl generally works in terms of weeks, rather than days. For this, ymw2time and time2ymw are inverses, acting on (year, month, week) tuples.
ymw = time2ymw(t)(2018, 4, 2)ymw2time(ymw)6678.0Note that only certain times can be converted to (year, month, week), in particular the day of the month must be one of [7, 14, 21, 28].
ymw = time2ymw(DateTime(2018, 4, 13)) # will errorSpherical Geometry Corrections
There are two terms, γ_sphere and τ_sphere that take into account corrections required to the differential equations due to the sphericity of the Earth. These functions should not need to be accessed directly, but their effects can be turned off via the geometry kwarg of RaftParameters.