Source code for pycif.plugins.obsparsers.obspack.parse_nc
import xarray as xr
from ....utils.check.errclass import CifError
from logging import info
[docs]
def parse_nc(obs_file,flags=False):
# Open the file
ds = xr.open_dataset(obs_file)
# Construct the dataframe
col2use = ["value", "latitude", "longitude",
"altitude", "obspack_num","value_std_dev","qcflag"]
df = ds[col2use].to_dataframe().rename(
columns={
"value": "obs",
"longitude": "lon",
"latitude": "lat",
"altitude": "alt",
"value_std_dev":"obserror"
}
).set_index("obspack_num")
# Deal with dates
df.loc[:, "date"] = ds["time"].values
# Deal with time duration
if "time_interval" in ds:
df.loc[:, "duration"] = \
ds["time_interval"].dt.total_seconds().values / 3600
elif "dataset_data_frequency" in ds.attrs:
df.loc[:, "duration"] = 1. / ds.attrs["dataset_data_frequency"]
else:
raise CifError(
f"No information about obs duration in the file {obs_file}.\n"
"The variable 'time_interval' or the attribute 'dataset_data_frequency' "
"should be defined in your ObsPack file."
)
# Replace fixed parameters
df.loc[:, "station"] = ds.attrs["site_code"]
df.loc[:, "parameter"] = ds.attrs["dataset_parameter"]
df.loc[:, "network"] = "ObsPack"
#df.loc[:, "obserror"] = 0.
# Rescale depending on unit -> convert to ppb
unit = ds["value"].attrs["units"]
info(f'Obs units are {unit}')
if unit == "mol mol-1":
info(f'conversion obs from {unit} to ppb')
df.loc[:, "obs"] *= 1e9
unit = ds["value_std_dev"].attrs["units"]
info(f'Obs error units are {unit}')
if unit == "mol mol-1":
info(f'conversion obs errors from {unit} to ppb')
df.loc[:, "obserror"] *= 1e9
if flags :
df["qcflag"] = df["qcflag"].str.decode('utf-8')
info(f'Selection of data with flags into {flags}')
df = df[df["qcflag"].isin(flags)]
info(f"Data size : {len(df.index)}")
return df