From 1f2fc4ebaae7c05abacff02f0563f60fd5f31d16 Mon Sep 17 00:00:00 2001 From: Mindo Choi Date: Thu, 21 Sep 2023 11:05:05 -0500 Subject: [PATCH] Variables for IODA format added after cleanup of the ioda converter --- utils/obsproc/NetCDFToIodaConverter.h | 37 +++++++++++++++++++++++--- utils/obsproc/Rads2Ioda.h | 38 ++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/utils/obsproc/NetCDFToIodaConverter.h b/utils/obsproc/NetCDFToIodaConverter.h index ea367b145..2bd51da2d 100644 --- a/utils/obsproc/NetCDFToIodaConverter.h +++ b/utils/obsproc/NetCDFToIodaConverter.h @@ -25,6 +25,11 @@ namespace gdasapp { Eigen::ArrayXf obsVal; Eigen::ArrayXf obsError; Eigen::ArrayXi preQc; + Eigen::ArrayXi dateVal; + Eigen::ArrayXf latVal; + Eigen::ArrayXf lonVal; + Eigen::ArrayXi cycleVal; + Eigen::ArrayXi passVal; std::string units; // reference date for epoch time }; @@ -84,24 +89,48 @@ namespace gdasapp { float_params.setFillValue(missing_value); // Create the IODA variables + // TODO(Mindo): Get the date info from the netcdf file ioda::Variable adtIodaDatetime = - ogrp.vars.createWithScales("Metadata/dateTime", + ogrp.vars.createWithScales("MetaData/dateTime", + {ogrp.vars["Location"]}, float_params); + adtIodaDatetime.atts.add("units", + {"seconds since 1858-11-17 00:00:00 UTC"}, {1}); + ioda::Variable cycleIodaVal = + ogrp.vars.createWithScales("MetaData/cycle", + {ogrp.vars["Location"]}, float_params); + ioda::Variable passIodaVal = + ogrp.vars.createWithScales("MetaData/pass", + {ogrp.vars["Location"]}, float_params); + ioda::Variable latIodaVal = + ogrp.vars.createWithScales("MetaData/latitude", + {ogrp.vars["Location"]}, float_params); + ioda::Variable lonIodaVal = + ogrp.vars.createWithScales("MetaData/longitude", {ogrp.vars["Location"]}, float_params); - // TODO(Mindo): Get the date info from the netcdf file - adtIodaDatetime.atts.add("units", {"seconds since 9999-04-15T12:00:00Z"}, {1}); - ioda::Variable adtIodaObsVal = ogrp.vars.createWithScales("ObsValue/"+variable_, {ogrp.vars["Location"]}, float_params); ioda::Variable adtIodaObsErr = ogrp.vars.createWithScales("ObsError/"+variable_, {ogrp.vars["Location"]}, float_params); + ioda::Variable adtIodaPreQCVal = + ogrp.vars.createWithScales("PreQC/absoluteDynamicTopography", + {ogrp.vars["Location"]}, float_params); + // Write metadata value to group + adtIodaDatetime.writeWithEigenRegular(iodaVars.dateVal); + cycleIodaVal.writeWithEigenRegular(iodaVars.cycleVal); + passIodaVal.writeWithEigenRegular(iodaVars.passVal); + latIodaVal.writeWithEigenRegular(iodaVars.latVal); + lonIodaVal.writeWithEigenRegular(iodaVars.lonVal); // Write adt obs value to group adtIodaObsVal.writeWithEigenRegular(iodaVars.obsVal); // Write adt obs error to group adtIodaObsErr.writeWithEigenRegular(iodaVars.obsError); + + // Write PreQC + adtIodaPreQCVal.writeWithEigenRegular(iodaVars.preQc); } private: diff --git a/utils/obsproc/Rads2Ioda.h b/utils/obsproc/Rads2Ioda.h index 0fa629c47..f7e1db8cd 100644 --- a/utils/obsproc/Rads2Ioda.h +++ b/utils/obsproc/Rads2Ioda.h @@ -39,6 +39,36 @@ namespace gdasapp { iodaVars.obsVal = Eigen::ArrayXf(iodaVars.location); iodaVars.obsError = Eigen::ArrayXf(iodaVars.location); iodaVars.preQc = Eigen::ArrayXi(iodaVars.location); + iodaVars.dateVal = Eigen::ArrayXi(iodaVars.location); + iodaVars.latVal = Eigen::ArrayXf(iodaVars.location); + iodaVars.lonVal = Eigen::ArrayXf(iodaVars.location); + iodaVars.cycleVal = Eigen::ArrayXi(iodaVars.location); + iodaVars.passVal = Eigen::ArrayXi(iodaVars.location); + + // Get dateTime + netCDF::NcVar dateTimeNcVar = ncFile.getVar("time_mjd"); + int dateTimeVal[iodaVars.location]; // NOLINT (can't pass vector to getVar below) + dateTimeNcVar.getVar(dateTimeVal); // units is controlled at NetcdfConverter.h + + // Get other metadatas + netCDF::NcVar cycleNcVar = ncFile.getVar("cycle"); + int cycleVal[iodaVars.location]; // NOLINT (can't pass vector to getVar below) + cycleNcVar.getVar(cycleVal); + netCDF::NcVar passNcVar = ncFile.getVar("pass"); + int passVal[iodaVars.location]; // NOLINT (can't pass vector to getVar below) + passNcVar.getVar(passVal); + + netCDF::NcVar latNcVar = ncFile.getVar("lat"); + int latVal[iodaVars.location]; // NOLINT (can't pass vector to getVar below) + latNcVar.getVar(latVal); + + netCDF::NcVar lonNcVar = ncFile.getVar("lon"); + int lonVal[iodaVars.location]; // NOLINT (can't pass vector to getVar below) + lonNcVar.getVar(lonVal); + std::string geounits; + lonNcVar.getAtt("units").getValues(geounits); + float geoscaleFactor; + lonNcVar.getAtt("scale_factor").getValues(&geoscaleFactor); // Get adt_egm2008 obs values and attributes netCDF::NcVar adtNcVar = ncFile.getVar("adt_egm2008"); @@ -50,11 +80,17 @@ namespace gdasapp { adtNcVar.getAtt("scale_factor").getValues(&scaleFactor); for (int i = 0; i <= iodaVars.location; i++) { iodaVars.obsVal(i) = static_cast(adtObsVal[i])*scaleFactor; + iodaVars.dateVal(i) = static_cast(dateTimeVal[i])*24*60*60; + iodaVars.cycleVal(i) = static_cast(cycleVal[i]); + iodaVars.passVal(i) = static_cast(passVal[i]); + iodaVars.latVal(i) = static_cast(latVal[i])*geoscaleFactor; + iodaVars.lonVal(i) = static_cast(lonVal[i])*geoscaleFactor; } - // Do something for obs error + // Do something for obs error and PreQC for (int i = 0; i <= iodaVars.location; i++) { iodaVars.obsError(i) = 0.1; + iodaVars.preQc(i) = 0.0; } }; }; // class Rads2Ioda