API#
earth2mip.diagnostics module#
- class earth2mip.diagnostics.Diagnostics(group, domain, grid, diagnostic, lat, lon, device)#
Bases:
object
- get_dimensions()#
- get_dtype()#
- get_variables()#
- update()#
- class earth2mip.diagnostics.Raw(group, domain, grid, diagnostic, lat, lon, device)#
Bases:
Diagnostics
- get_dimensions()#
- get_dtype()#
- update(output, time_index, batch_id, batch_size)#
earth2mip.ensemble_utils module#
- class earth2mip.ensemble_utils.GaussianRandomFieldS2(nlat, alpha=2.0, tau=3.0, sigma=None, radius=1.0, grid='equiangular', dtype=torch.float32)#
Bases:
Module
- cuda(*args, **kwargs)#
Moves all model parameters and buffers to the GPU.
This also makes associated parameters and buffers different objects. So it should be called before constructing optimizer if the module will live on GPU while being optimized.
Note
This method modifies the module in-place.
- Parameters:
device (int, optional) – if specified, all parameters will be copied to that device
- Returns:
self
- Return type:
Module
- forward(N, xi=None)#
Sample random functions from a spherical GRF.
- Parameters:
N (int) – Number of functions to sample.
xi (torch.Tensor, default is None) – Noise is a complex tensor of size (N, nlat, nlat+1). If None, new Gaussian noise is sampled. If xi is provided, N is ignored.
Output –
------- –
u (torch.Tensor) – N random samples from the GRF returned as a tensor of size (N, nlat, 2*nlat) on a equiangular grid.
- to(*args, **kwargs)#
Moves and/or casts the parameters and buffers.
This can be called as
- to(device=None, dtype=None, non_blocking=False)
- to(dtype, non_blocking=False)
- to(tensor, non_blocking=False)
- to(memory_format=torch.channels_last)
Its signature is similar to
torch.Tensor.to()
, but only accepts floating point or complexdtype
s. In addition, this method will only cast the floating point or complex parameters and buffers todtype
(if given). The integral parameters and buffers will be moveddevice
, if that is given, but with dtypes unchanged. Whennon_blocking
is set, it tries to convert/move asynchronously with respect to the host if possible, e.g., moving CPU Tensors with pinned memory to CUDA devices.See below for examples.
Note
This method modifies the module in-place.
- Parameters:
device (
torch.device
) – the desired device of the parameters and buffers in this moduledtype (
torch.dtype
) – the desired floating point or complex dtype of the parameters and buffers in this moduletensor (torch.Tensor) – Tensor whose dtype and device are the desired dtype and device for all parameters and buffers in this module
memory_format (
torch.memory_format
) – the desired memory format for 4D parameters and buffers in this module (keyword only argument)
- Returns:
self
- Return type:
Module
Examples:
>>> # xdoctest: +IGNORE_WANT("non-deterministic") >>> linear = nn.Linear(2, 2) >>> linear.weight Parameter containing: tensor([[ 0.1913, -0.3420], [-0.5113, -0.2325]]) >>> linear.to(torch.double) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1913, -0.3420], [-0.5113, -0.2325]], dtype=torch.float64) >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA1) >>> gpu1 = torch.device("cuda:1") >>> linear.to(gpu1, dtype=torch.half, non_blocking=True) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1914, -0.3420], [-0.5112, -0.2324]], dtype=torch.float16, device='cuda:1') >>> cpu = torch.device("cpu") >>> linear.to(cpu) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1914, -0.3420], [-0.5112, -0.2324]], dtype=torch.float16) >>> linear = nn.Linear(2, 2, bias=None).to(torch.cdouble) >>> linear.weight Parameter containing: tensor([[ 0.3741+0.j, 0.2382+0.j], [ 0.5593+0.j, -0.4443+0.j]], dtype=torch.complex128) >>> linear(torch.ones(3, 2, dtype=torch.cdouble)) tensor([[0.6122+0.j, 0.1150+0.j], [0.6122+0.j, 0.1150+0.j], [0.6122+0.j, 0.1150+0.j]], dtype=torch.complex128)
- earth2mip.ensemble_utils.brown_noise(shape, reddening=2)#
- earth2mip.ensemble_utils.generate_bred_vector(x, model, noise_amplitude, time=None, integration_steps=40, inflate=False)#
- Return type:
Tensor
- earth2mip.ensemble_utils.generate_noise_grf(shape, grid, alpha, sigma, tau)#
earth2mip.filesystem module#
- earth2mip.filesystem.download_cached(path, recursive=False)#
- Return type:
str
- earth2mip.filesystem.glob(pattern, maxdepth=1)#
- Return type:
List
[str
]
- earth2mip.filesystem.ls(path)#
- earth2mip.filesystem.open(path, mode='r')#
- earth2mip.filesystem.pipe(dest, value)#
Save string to dest
earth2mip.forecast_metrics_io module#
Routines for reading and writing forecast metrics to a directory of csv files.
The csv files contain the records:
initial_time_iso, lead_time_hours, channel, metric, value
2022-01-01T00:00:00,24,t2m,rmse,25.6
- earth2mip.forecast_metrics_io.read_metrics(directory)#
Reads all csv files in the given directory and returns a pandas Series containing all the metric values.
- Return type:
Series
- earth2mip.forecast_metrics_io.write_metric(f, initial_time, lead_time, channel, metric, value)#
Writes a single metric value to the given file object in csv format.
- Return type:
None
earth2mip.forecasts module#
Forecast abstractions
A forecast is a discrete array of (n_initial_times, n_lead_times)
. However
because a forecast evolves forward in time, and we do not store the whole
forecast necessarily, algorithms in fcn-mip should access n_lead_times
in
sequential order. This is the purpose of the abstractions here.
- class earth2mip.forecasts.Forecast(*args, **kwargs)#
Bases:
Protocol
- property channel_names: List[str]#
- property grid: LatLonGrid#
- class earth2mip.forecasts.Persistence(observations)#
Bases:
object
persistence forecast. This forecast always returns the initial condition.
Yields (channel, lat, lon)
- property channel_names#
earth2mip.geo_operator module#
- class earth2mip.geo_operator.GeoOperator(*args, **kwargs)#
Bases:
Protocol
Geo Operator
This is the most primative functional of Earth-2 MIP which represents a operators on geospatial fields. This implies the following two requirements:
- The operation must define in and out channel variables representing the
fields in the input/output arrays.
The operation must define the in and out grid schemas.
Many auto-gressive models can be represented as a GeoOperator and can maintain a internal state. Diagnostic models must be a GeoOperator by definition.
Warning
Geo Function is a concept not full adopted in Earth-2 MIP and is being adopted progressively.
- property in_channel_names: list[str]#
- property in_grid: LatLonGrid#
- property out_channel_names: list[str]#
- property out_grid: LatLonGrid#
earth2mip.geometry module#
Routines for working with geometry
- earth2mip.geometry.bilinear(data, dims, source_coords, target_coords)#
- earth2mip.geometry.get_batch_size(data)#
- earth2mip.geometry.get_bounds_window(geom, lat, lon)#
- earth2mip.geometry.select_space(data, lat, lon, domain)#
earth2mip.grid module#
- class earth2mip.grid.LatLonGrid(lat, lon)#
Bases:
object
-
lat:
List
[float
]#
-
lon:
List
[float
]#
- property shape#
-
lat:
- earth2mip.grid.equiangular_lat_lon_grid(nlat, nlon, includes_south_pole=True)#
A regular lat-lon grid
Lat is ordered from 90 to -90. Includes -90 and only if if includes_south_pole is True. Lon is ordered from 0 to 360. includes 0, but not 360.
- Return type:
- earth2mip.grid.from_enum(grid_enum)#
- Return type:
earth2mip.inference_ensemble module#
earth2mip.inference_medium_range module#
earth2mip.loaders module#
- class earth2mip.loaders.LoaderProtocol(*args, **kwargs)#
Bases:
Protocol
- earth2mip.loaders.torchscript(package, pretrained=True)#
load a checkpoint into a model
earth2mip.make_job module#
- earth2mip.make_job.get_time(times)#
- earth2mip.make_job.get_time_s2s_calibration()#
- earth2mip.make_job.get_times_2018()#
- earth2mip.make_job.get_times_s2s_test()#
- earth2mip.make_job.main(model, config, output)#
earth2mip.model_registry module#
Create-read-update-delete (CRUD) operations for the FCN model registry
The location of the registry is configured using config.MODEL_REGISTRY. Both s3:// and local paths are supported.
The top-level structure of the registry is like this:
afno_26ch_v/
baseline_afno_26/
gfno_26ch_sc3_layers8_tt64/
hafno_baseline_26ch_edim512_mlp2/
modulus_afno_20/
sfno_73ch/
tfno_no-patching_lr5e-4_full_epochs/
The name of the model is the folder name. Each of these folders has the following structure:
sfno_73ch/about.txt # optional information (e.g. source path)
sfno_73ch/global_means.npy
sfno_73ch/global_stds.npy
sfno_73ch/weights.tar # model checkpoint
sfno_73ch/metadata.json
The metadata.json file contains data necessary to use the model for forecasts:
{
"architecture": "sfno_73ch",
"n_history": 0,
"grid": "721x1440",
"in_channels": [
0,
1
],
"out_channels": [
0,
1
]
}
Its schema is provided by the earth2mip.schema.Model
.
The checkpoint file weights.tar should have a dictionary of model weights and parameters in the model_state key. For backwards compatibility with FCN checkpoints produced as of March 1, 2023 the keys should include prefixed module. prefix. This checkpoint format may change in the future.
Scoring FCNs under active development#
One can use fcn-mip to score models not packaged in fcn-mip using a metadata file like this:
{
"architecture": "pickle",
...
}
This will load weights.tar
using torch.load. This is not recommended for
long-time archival of model checkpoints but does allow scoring models under
active development. Once a reasonable skill is achieved the model’s source code
can be stabilized and packaged within fcn-mip for long-term archival.
- earth2mip.model_registry.DLWPPackage(root, seperator)#
- earth2mip.model_registry.FCNPackage(root, seperator)#
- earth2mip.model_registry.FCNv2Package(root, seperator)#
- class earth2mip.model_registry.ModelRegistry(path)#
Bases:
object
-
SEPERATOR:
str
= '/'#
- get_builtin_model(name)#
Built in models that have globally buildable packages
- get_center_path(name)#
- get_metadata(name)#
- Return type:
Model
- get_model(name)#
- get_model_path(name)#
- get_path(name, *args)#
- get_scale_path(name)#
- get_weight_path(name)#
- list_models()#
- put_metadata(name, metadata)#
-
SEPERATOR:
- earth2mip.model_registry.NGCDiagnosticPackage(root, seperator, name)#
- class earth2mip.model_registry.Package(root, seperator)#
Bases:
object
A model package
Simple file system operations and quick metadata access
- get(path, recursive=False)#
- metadata()#
- Return type:
Model
- earth2mip.model_registry.PanguPackage(root, seperator)#
- earth2mip.model_registry.download_ngc_package(root, url, zip_file)#
earth2mip.netcdf module#
Routines to save domains to a netCDF file
- earth2mip.netcdf.initialize_netcdf(nc, domains, grid, n_ensemble, device)#
- Return type:
List
[List
[Diagnostics
]]
- earth2mip.netcdf.update_netcdf(data, total_diagnostics, domains, batch_id, time_count, grid, channel_names_of_data)#
earth2mip.regrid module#
- class earth2mip.regrid.Identity(*args, **kwargs)#
Bases:
Module
- forward(x)#
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class earth2mip.regrid.RegridLatLon(src_grid, dest_grid)#
Bases:
Module
- forward(x)#
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class earth2mip.regrid.TempestRegridder(file_path)#
Bases:
Module
- forward(x)#
Defines the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- to(device)#
Moves and/or casts the parameters and buffers.
This can be called as
- to(device=None, dtype=None, non_blocking=False)
- to(dtype, non_blocking=False)
- to(tensor, non_blocking=False)
- to(memory_format=torch.channels_last)
Its signature is similar to
torch.Tensor.to()
, but only accepts floating point or complexdtype
s. In addition, this method will only cast the floating point or complex parameters and buffers todtype
(if given). The integral parameters and buffers will be moveddevice
, if that is given, but with dtypes unchanged. Whennon_blocking
is set, it tries to convert/move asynchronously with respect to the host if possible, e.g., moving CPU Tensors with pinned memory to CUDA devices.See below for examples.
Note
This method modifies the module in-place.
- Parameters:
device (
torch.device
) – the desired device of the parameters and buffers in this moduledtype (
torch.dtype
) – the desired floating point or complex dtype of the parameters and buffers in this moduletensor (torch.Tensor) – Tensor whose dtype and device are the desired dtype and device for all parameters and buffers in this module
memory_format (
torch.memory_format
) – the desired memory format for 4D parameters and buffers in this module (keyword only argument)
- Returns:
self
- Return type:
Module
Examples:
>>> # xdoctest: +IGNORE_WANT("non-deterministic") >>> linear = nn.Linear(2, 2) >>> linear.weight Parameter containing: tensor([[ 0.1913, -0.3420], [-0.5113, -0.2325]]) >>> linear.to(torch.double) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1913, -0.3420], [-0.5113, -0.2325]], dtype=torch.float64) >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA1) >>> gpu1 = torch.device("cuda:1") >>> linear.to(gpu1, dtype=torch.half, non_blocking=True) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1914, -0.3420], [-0.5112, -0.2324]], dtype=torch.float16, device='cuda:1') >>> cpu = torch.device("cpu") >>> linear.to(cpu) Linear(in_features=2, out_features=2, bias=True) >>> linear.weight Parameter containing: tensor([[ 0.1914, -0.3420], [-0.5112, -0.2324]], dtype=torch.float16) >>> linear = nn.Linear(2, 2, bias=None).to(torch.cdouble) >>> linear.weight Parameter containing: tensor([[ 0.3741+0.j, 0.2382+0.j], [ 0.5593+0.j, -0.4443+0.j]], dtype=torch.complex128) >>> linear(torch.ones(3, 2, dtype=torch.cdouble)) tensor([[0.6122+0.j, 0.1150+0.j], [0.6122+0.j, 0.1150+0.j], [0.6122+0.j, 0.1150+0.j]], dtype=torch.complex128)
- earth2mip.regrid.get_regridder(src, dest)#
- Return type:
Module
earth2mip.schema module#
- class earth2mip.schema.InitialConditionSource(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#
Bases:
Enum
-
cds:
str
= 'cds'#
-
era5:
str
= 'era5'#
-
gfs:
str
= 'gfs'#
-
hrmip:
str
= 'hrmip'#
-
ifs:
str
= 'ifs'#
-
cds:
- class earth2mip.schema.WeatherEvent(**data)#
Bases:
BaseModel
-
domains:
List
[Union
[Window
,CWBDomain
,MultiPoint
]]#
-
properties:
WeatherEventProperties
#
-
domains:
earth2mip.score_ensemble_outputs module#
- earth2mip.score_ensemble_outputs.main(input_path, output_path=None, time_averaging_window='', score=True, save_ensemble=False)#
- Return type:
None
- earth2mip.score_ensemble_outputs.open_ensemble(path, group)#
- earth2mip.score_ensemble_outputs.open_verification(time)#
- earth2mip.score_ensemble_outputs.read_weather_event(dir)#
- earth2mip.score_ensemble_outputs.save_dataset(out, path)#
earth2mip.time module#
- earth2mip.time.convert_to_datetime(time)#
- Return type:
datetime
- earth2mip.time.datetime_to_timestamp(time)#
- Return type:
float
earth2mip.time_collection module#
earth2mip.time_loop module#
- class earth2mip.time_loop.TimeLoop(*args, **kwargs)#
Bases:
Protocol
Abstract protocol that a custom time loop must follow
This is a callable which yields time and output information. Some attributes are required to define the input and output data required.
The expectation is that this class and the data passed to it are on the same device. While torch modules can be moved between devices easily, this is not true for all frameworks.
- in_channel_names#
- out_channel_names#
- grid#
- n_history_levels#
- history_time_step#
- time_step#
- device#
-
device:
device
#
-
dtype:
dtype
= torch.float32#
-
grid:
LatLonGrid
#
-
history_time_step:
timedelta
= datetime.timedelta(0)#
-
in_channel_names:
List
[str
]#
-
n_history_levels:
int
= 1#
-
out_channel_names:
List
[str
]#
-
time_step:
timedelta
#
earth2mip.weather_events module#
- class earth2mip.weather_events.CWBDomain(**data)#
Bases:
BaseModel
-
diagnostics:
List
[Diagnostic
]#
-
name:
str
#
-
path:
str
#
-
type:
Literal
['CWBDomain'
]#
-
diagnostics:
- class earth2mip.weather_events.Diagnostic(**data)#
Bases:
BaseModel
-
channels:
List
[str
]#
-
function:
str
#
-
nbins:
int
#
-
type:
str
#
-
channels:
- class earth2mip.weather_events.InitialConditionSource(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#
Bases:
Enum
-
cds:
str
= 'cds'#
-
era5:
str
= 'era5'#
-
gfs:
str
= 'gfs'#
-
hrmip:
str
= 'hrmip'#
-
ifs:
str
= 'ifs'#
-
cds:
- class earth2mip.weather_events.MultiPoint(**data)#
Bases:
BaseModel
-
diagnostics:
List
[Diagnostic
]#
-
lat:
List
[float
]#
-
lon:
List
[float
]#
-
name:
str
#
-
type:
Literal
['MultiPoint'
]#
-
diagnostics:
- class earth2mip.weather_events.WeatherEvent(**data)#
Bases:
BaseModel
-
domains:
List
[Union
[Window
,CWBDomain
,MultiPoint
]]#
-
properties:
WeatherEventProperties
#
-
domains:
- class earth2mip.weather_events.WeatherEventProperties(**data)#
Bases:
BaseModel
- netcdf#
load the initial conditions from this path if given
-
initial_condition_source:
InitialConditionSource
#
-
name:
str
#
-
netcdf:
str
#
-
restart:
str
#
-
start_time:
Optional
[datetime
]#
- class earth2mip.weather_events.Window(**data)#
Bases:
BaseModel
-
diagnostics:
List
[Diagnostic
]#
-
lat_max:
float
#
-
lat_min:
float
#
-
lon_max:
float
#
-
lon_min:
float
#
-
name:
str
#
-
type:
Literal
['Window'
]#
-
diagnostics:
- earth2mip.weather_events.list_()#
- earth2mip.weather_events.read(forecast_name)#
- Return type: