Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add model reader for gocart output #217

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
2 changes: 2 additions & 0 deletions monetio/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
camx,
cmaq,
fv3chem,
gocart,
hysplit,
hytraj,
icap_mme,
Expand All @@ -27,6 +28,7 @@
"cmaq",
"camx",
"fv3chem",
"gocart",
"hysplit",
"hytraj",
"icap_mme",
Expand Down
75 changes: 75 additions & 0 deletions monetio/models/gocart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""GOCART File Reader."""

import xarray as xr


def open_mfdataset(fnames):
MaggieMarvin marked this conversation as resolved.
Show resolved Hide resolved
"""Method to open GOCART netcdf files.

Parameters
----------
fnames
String glob expression or a list of files to open.

Returns
-------
xarray.Dataset
GOCART model dataset in standard format for use in MELODIES MONET

"""

ds = xr.open_mfdataset(
fnames,
concat_dim="time",
combine="nested",
drop_variables=["AOD_BC", "AOD_DU", "AOD_OC", "AOD_SS", "AOD_SU"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User might want these. If so, I guess you'd want to select and rename them too.

Suggested change
drop_variables=["AOD_BC", "AOD_DU", "AOD_OC", "AOD_SS", "AOD_SU"],

Copy link
Author

@MaggieMarvin MaggieMarvin Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! I hadn't thought of a good naming convention since these variables are also wavelength-dependent - for example could do "AOD550_DU" or something else? Unless wavelength is a required argument as above, then they can all keep their original names

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just always stick the wavelength on the end of the initial name?

)

ds["AOD470"] = ds.AOD.isel(lev=0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you set it up so the user can specify the wavelengths (in case they are different)? It can default to these four though.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's only these four wavelengths that are available from gocart - should wavelength be a required argument and then we can pass all AOD variables at that wavelength? Error if a wavelength is requested that isn't provided?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Barry told me the wavelengths are technically configurable. My thought was the wavelength list could be an optional argument (defaulting to your four if not provided), but then we make sure the list length is the same as the lev dim size.

ds["AOD550"] = ds.AOD.isel(lev=1)
ds["AOD670"] = ds.AOD.isel(lev=2)
ds["AOD870"] = ds.AOD.isel(lev=3)
ds = ds.drop_vars("AOD").drop_dims("lev")

ds = _fix(ds)

return ds


def _fix(ds):
ds = _fix_grid(ds)

ds = ds.expand_dims("z")
ds = ds.transpose("time", "z", "y", "x")

return ds


def _fix_grid(ds):
from numpy import meshgrid

# Create 2-D lat/lon grid with dims ('y', 'x') and lon in [-180, 180)
lat = ds.lat.values
lon = ds.lon.values
lon, lat = meshgrid(lon, lat)
ds = ds.rename_dims({"lat": "y", "lon": "x"}).drop_vars(["lat", "lon"])
ds["longitude"] = (
("y", "x"),
lon,
{
"long_name": "Longitude",
"units": "degree_east",
"standard_name": "longitude",
},
)
ds["latitude"] = (
("y", "x"),
lat,
{
"long_name": "Latitude",
"units": "degree_north",
"standard_name": "latitude",
},
)
ds = ds.reset_coords().set_coords(["time", "latitude", "longitude"])
return ds