YetAnotherCoupler 3.2.0_a
Loading...
Searching...
No Matches
netcdf_reader.py

This component reads data from a netcdf file and provides the data as YAC fields.

1#!/usr/bin/env python3
2
3# Copyright (c) 2024 The YAC Authors
4#
5# SPDX-License-Identifier: BSD-3-Clause
6
7from yac import *
8from netCDF4 import Dataset
9
10import cftime
11from yac.utils import read_grid
12
13class NetCDF_Reader:
14 def __init__(self, filename, gridfile = None,
15 compname = "netcdf_reader", yac = None):
16 self.yac = yac or YAC.default_instance
17 self.comp = self.yac.predef_comp(compname)
18
19 self.dataset = Dataset(filename, "r")
20 time_var = self.dataset["time"]
21 start = cftime.num2date(time_var[0], units=time_var.units, calendar="proleptic_gregorian")
22 end = cftime.num2date(time_var[-1], units=time_var.units, calendar="proleptic_gregorian")
23 self.timestep = cftime.num2date(time_var[1], units=time_var.units, calendar="proleptic_gregorian") - start
24
25 def_calendar(Calendar.PROLEPTIC_GREGORIAN)
26 self.yac.def_datetime(start.isoformat(), end.isoformat())
27
28 # TODO: read it from dataset metadata
29 self.gridfile = gridfile or filename
30 self.compname = compname
31 self.time_counter = 0
32
33 def setup(self):
34 grid, _, _ = read_grid(self.gridfile, f"{self.compname}_grid")
35
36 self.fields = []
37 for name, v in self.dataset.variables.items():
38 if len(v.dimensions) < 2:
39 continue
40 if "time" != v.dimensions[0]:
41 continue
42 if "cell" == v.dimensions[1]:
43 assert grid.cell_points, "cells (clon, clat) not defined in the grid"
44 points = grid.cell_points
45 elif "vertex" == v.dimensions[1]:
46 points = grid.corner_points
47 else:
48 continue
49 # todo check for level o.Ä.
50 self.fields.append(Field.create(name, self.comp, points, 1,
51 str(self.timestep.seconds), TimeUnit.SECOND))
52
53 def def_couples(self):
54 pass
55
56 def step(self):
57 for field in self.fields:
58 print(f"reading {field.name} at {field.datetime}")
59 field.put(self.dataset[field.name][self.time_counter, :])
60 self.time_counter += 1
61 return self.fields[0].datetime