Skip to content

Commit

Permalink
all frmts implemented and tested with ref time and unit time except X…
Browse files Browse the repository at this point in the history
…mdf and Xdmf
  • Loading branch information
vcloarec committed Dec 11, 2019
1 parent 5def408 commit 19af484
Show file tree
Hide file tree
Showing 28 changed files with 335 additions and 160 deletions.
25 changes: 2 additions & 23 deletions mdal/frmts/mdal_ascii_dat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,6 @@

#define EXIT_WITH_ERROR(error) { if (status) *status = (error); return; }

static MDAL::Duration convertTimeData( double time, const std::string &originalTimeDataUnit )
{
MDAL::Duration::Unit unit = MDAL::Duration::hours;

if ( originalTimeDataUnit == "se" || originalTimeDataUnit == "2" || originalTimeDataUnit == "Seconds"
|| originalTimeDataUnit.empty() )
{
unit = MDAL::Duration::seconds;
}
else if ( originalTimeDataUnit == "mi" || originalTimeDataUnit == "1" || originalTimeDataUnit == "Minutes" )
{
unit = MDAL::Duration::minutes;
}
else if ( originalTimeDataUnit == "days" )
{
unit = MDAL::Duration::days;
}

return MDAL::Duration( time, unit );
}

MDAL::DriverAsciiDat::DriverAsciiDat( ):
Driver( "ASCII_DAT",
"DAT",
Expand Down Expand Up @@ -253,7 +232,7 @@ void MDAL::DriverAsciiDat::loadNewFormat(
}
else if ( cardType == "RT_JULIAN" && items.size() >= 2 )
{
referenceTime = MDAL::DateTime( MDAL::toDouble( items[1] ) );
referenceTime = DateTime( MDAL::toDouble( items[1] ), DateTime::JulianDay );
}
else if ( cardType == "TIMEUNITS" && items.size() >= 2 )
{
Expand All @@ -268,7 +247,7 @@ void MDAL::DriverAsciiDat::loadNewFormat(
else if ( cardType == "TS" && items.size() >= 3 )
{
double rawTime = toDouble( items[2] );
MDAL::Duration t( rawTime, MDAL::parseUnitTime( group->getMetadata( "TIMEUNITS" ) ) );
MDAL::Duration t( rawTime, MDAL::parseDurationUnitTime( group->getMetadata( "TIMEUNITS" ) ) );

if ( faceCentered )
{
Expand Down
4 changes: 2 additions & 2 deletions mdal/frmts/mdal_binary_dat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ void MDAL::DriverBinaryDat::load( const std::string &datFile, MDAL::Mesh *mesh,
return exit_with_error( status, MDAL_Status::Err_UnknownFormat, "unable to read reference time" );

referenceTime = static_cast<double>( time );
group->setReferenceTime( DateTime( referenceTime ) );
group->setReferenceTime( DateTime( referenceTime, DateTime::JulianDay ) );
break;

case CT_TIMEUNITS:
Expand Down Expand Up @@ -289,7 +289,7 @@ void MDAL::DriverBinaryDat::load( const std::string &datFile, MDAL::Mesh *mesh,
return exit_with_error( status, MDAL_Status::Err_UnknownFormat, "Invalid time step" );

double rawTime = static_cast<double>( time );
MDAL::Duration t( rawTime, MDAL::parseUnitTime( timeUnitStr ) );
MDAL::Duration t( rawTime, MDAL::parseDurationUnitTime( timeUnitStr ) );

if ( readVertexTimestep( mesh, group, groupMax, t, istat, sflg, in ) )
return exit_with_error( status, MDAL_Status::Err_UnknownFormat, "Unable to read vertex timestep" );
Expand Down
76 changes: 3 additions & 73 deletions mdal/frmts/mdal_cf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,77 +161,6 @@ static void populate_vals( bool is_vector, double *vals, size_t i,
}
}

static MDAL::DateTime parseReferenceTime( std::string timeInformation, std::string calendar )
{
auto strings = MDAL::split( timeInformation, ' ' );
if ( strings.size() < 3 )
return MDAL::DateTime();

if ( strings[1] != "since" )
return MDAL::DateTime();

std::string dateString = strings[2];

auto dateStringValues = MDAL::split( dateString, '-' );
if ( dateStringValues.size() != 3 )
return MDAL::DateTime();

int year = MDAL::toInt( dateStringValues[0] );
int month = MDAL::toInt( dateStringValues[1] );
int day = MDAL::toInt( dateStringValues[2] );

int hours = 0;
int minutes = 0;
double seconds = 0;

if ( strings.size() > 3 )
{
std::string timeString = strings[3];
auto timeStringsValue = MDAL::split( timeString, ":" );
if ( timeStringsValue.size() == 3 )
{
hours = MDAL::toInt( timeStringsValue[0] );
minutes = MDAL::toInt( timeStringsValue[0] );
seconds = MDAL::toDouble( timeStringsValue[0] );
}
}

if ( calendar == "gregorian" || calendar == "standard" || calendar.empty() )
return MDAL::DateTime( year, month, day, hours, minutes, seconds );

return MDAL::DateTime();

}

static MDAL::Duration::Unit parseUnitCFTime( std::string timeInformation )
{
auto strings = MDAL::split( timeInformation, ' ' );
if ( strings.size() < 3 )
return MDAL::Duration::hours; //default value

if ( strings[1] == "since" )
{
std::string timeUnit = strings[0];
if ( timeUnit == "month" ||
timeUnit == "months" ||
timeUnit == "mon" ||
timeUnit == "mons" )
{
return MDAL::Duration::months_CF;
}
else if ( timeUnit == "year" ||
timeUnit == "years" ||
timeUnit == "yr" ||
timeUnit == "yrs" )
{
return MDAL::Duration::exact_years;
}
return MDAL::parseUnitTime( strings[0] );
}

return MDAL::Duration::hours;//default value
}

void MDAL::DriverCF::addDatasetGroups( MDAL::Mesh *mesh, const std::vector<Duration> &times, const MDAL::cfdataset_info_map &dsinfo_map, const MDAL::DateTime &referenceTime )
{
/* PHASE 2 - add dataset groups */
Expand Down Expand Up @@ -299,6 +228,7 @@ void MDAL::DriverCF::addDatasetGroups( MDAL::Mesh *mesh, const std::vector<Durat
if ( !group->datasets.empty() )
{
group->setStatistics( MDAL::calculateStatistics( group ) );
group->setReferenceTime( referenceTime );
mesh->datasetGroups.push_back( group );
}
}
Expand All @@ -320,8 +250,8 @@ MDAL::DateTime MDAL::DriverCF::parseTime( std::vector<Duration> &times )

std::string timeUnitInformation = mNcFile->getAttrStr( timeArrName, "units" );
std::string calendar = mNcFile->getAttrStr( timeArrName, "calendar" );
MDAL::DateTime referenceTime = parseReferenceTime( timeUnitInformation, calendar );
MDAL::Duration::Unit unit = parseUnitCFTime( timeUnitInformation );
MDAL::DateTime referenceTime = parseCFReferenceTime( timeUnitInformation, calendar );
MDAL::Duration::Unit unit = parseCFTimeUnit( timeUnitInformation );

times = std::vector<Duration>( nTimesteps );
for ( size_t i = 0; i < nTimesteps; ++i )
Expand Down
2 changes: 1 addition & 1 deletion mdal/frmts/mdal_flo2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ bool MDAL::DriverFlo2D::parseHDF5Datasets( MemoryMesh *mesh, const std::string &
for ( size_t ts = 0; ts < timesteps; ++ts )
{
std::shared_ptr< MemoryDataset2D > output = std::make_shared< MemoryDataset2D >( ds.get() );
output->setTime( times[ts] );
output->setTime( times[ts], parseDurationUnitTime( timeUnitString ) );

if ( isVector )
{
Expand Down
8 changes: 5 additions & 3 deletions mdal/frmts/mdal_gdal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,12 @@ void MDAL::DriverGdal::parseRasterBands( const MDAL::GdalDataset *cfGDALDataset
metadata_hash global_metadata = parseMetadata( cfGDALDataset->mHDataset );
parseGlobals( global_metadata );


// Get metadata
metadata_hash metadata = parseMetadata( gdalBand );

std::string band_name;
double time = std::numeric_limits<double>::min();
MDAL::Duration time;
bool is_vector;
bool is_x;
if ( parseBandInfo( cfGDALDataset, metadata, band_name, &time, &is_vector, &is_x ) )
Expand All @@ -235,7 +236,6 @@ void MDAL::DriverGdal::parseRasterBands( const MDAL::GdalDataset *cfGDALDataset
raster_bands[data_index] = gdalBand;
qMap[time] = raster_bands;
mBands[band_name] = qMap;

}
else
{
Expand All @@ -247,7 +247,6 @@ void MDAL::DriverGdal::parseRasterBands( const MDAL::GdalDataset *cfGDALDataset
std::vector<GDALRasterBandH> raster_bands( data_count );
raster_bands[data_index] = gdalBand;
mBands[band_name][time] = raster_bands;

}
else
{
Expand Down Expand Up @@ -313,6 +312,8 @@ void MDAL::DriverGdal::fixRasterBands()
}
}

MDAL::DateTime MDAL::DriverGdal::referenceTime() const {return MDAL::DateTime();}

void MDAL::DriverGdal::addDataToOutput( GDALRasterBandH raster_band, std::shared_ptr<MemoryDataset2D> tos, bool is_vector, bool is_x )
{
assert( raster_band );
Expand Down Expand Up @@ -431,6 +432,7 @@ void MDAL::DriverGdal::addDatasetGroups()

// TODO use GDALComputeRasterMinMax
group->setStatistics( MDAL::calculateStatistics( group ) );
group->setReferenceTime( referenceTime() );
mMesh->datasetGroups.push_back( group );
}
}
Expand Down
8 changes: 5 additions & 3 deletions mdal/frmts/mdal_gdal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,16 @@ namespace MDAL

/* return true on failure */
virtual bool parseBandInfo( const GdalDataset *cfGDALDataset,
const metadata_hash &metadata, std::string &band_name, double *time, bool *is_vector, bool *is_x ) = 0;
const metadata_hash &metadata, std::string &band_name, MDAL::Duration *time, bool *is_vector, bool *is_x ) = 0;
virtual double parseMetadataTime( const std::string &time_s );
virtual std::string GDALFileName( const std::string &fileName ); /* some formats require e.g. adding driver name at the beginning */
virtual std::vector<std::string> parseDatasetNames( const std::string &fileName );
virtual void parseGlobals( const metadata_hash &metadata ) {MDAL_UNUSED( metadata );}

virtual
void parseBandIsVector( std::string &band_name, bool *is_vector, bool *is_x );

private:
typedef std::map<double, std::vector<GDALRasterBandH> > timestep_map; //TIME (sorted), [X, Y]
typedef std::map<MDAL::Duration, std::vector<GDALRasterBandH> > timestep_map; //TIME (sorted), [X, Y]
typedef std::map<std::string, timestep_map > data_hash; //Data Type, TIME (sorted), [X, Y]
typedef std::vector<std::shared_ptr<GdalDataset>> gdal_datasets_vector; //GDAL (Sub)Datasets,

Expand All @@ -95,6 +95,8 @@ namespace MDAL
void parseRasterBands( const GdalDataset *cfGDALDataset );
void fixRasterBands();

virtual MDAL::DateTime referenceTime() const;

std::string mFileName;
const std::string mGdalDriverName; /* GDAL driver name */
double *mPafScanline; /* temporary buffer for reading one raster line */
Expand Down
14 changes: 8 additions & 6 deletions mdal/frmts/mdal_gdal_grib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ MDAL::DriverGdalGrib::DriverGdalGrib( )
"GDAL Grib",
"*.grb;;*.grb2;;*.bin;;*.grib;;*.grib1;;*.grib2"
, "GRIB" ),
mRefTime( std::numeric_limits<double>::min() )
mRefTime( DateTime() )
{}

MDAL::DriverGdalGrib *MDAL::DriverGdalGrib::create()
Expand All @@ -27,7 +27,7 @@ MDAL::DriverGdalGrib::~DriverGdalGrib() = default;

bool MDAL::DriverGdalGrib::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset,
const metadata_hash &metadata, std::string &band_name,
double *time, bool *is_vector, bool *is_x
MDAL::Duration *time, bool *is_vector, bool *is_x
)
{
MDAL_UNUSED( cfGDALDataset );
Expand All @@ -39,21 +39,23 @@ bool MDAL::DriverGdalGrib::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset
if ( iter == metadata.end() ) return true; //FAILURE
band_name = iter->second;

if ( MDAL::equals( mRefTime, std::numeric_limits<double>::min() ) )
if ( !mRefTime.isValid() )
{
iter = metadata.find( "grib_ref_time" );
if ( iter == metadata.end() ) return true; //FAILURE
mRefTime = parseMetadataTime( iter->second );
mRefTime = DateTime( parseMetadataTime( iter->second ), DateTime::Unix );
}

// TIME
iter = metadata.find( "grib_valid_time" );
if ( iter == metadata.end() ) return true; //FAILURE
double valid_time = parseMetadataTime( iter->second );
*time = ( valid_time - mRefTime ) / 3600.0; // input times are always in seconds UTC, we need them back in hours
DateTime valid_time = DateTime( parseMetadataTime( iter->second ), DateTime::Unix );
*time = ( valid_time - mRefTime );

// Parse X, Y components if present
parseBandIsVector( band_name, is_vector, is_x );

return false; // success
}

MDAL::DateTime MDAL::DriverGdalGrib::referenceTime() const {return mRefTime;}
6 changes: 4 additions & 2 deletions mdal/frmts/mdal_gdal_grib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,19 @@ namespace MDAL
private:
bool parseBandInfo( const MDAL::GdalDataset *cfGDALDataset,
const metadata_hash &metadata, std::string &band_name,
double *time, bool *is_vector, bool *is_x
Duration *time, bool *is_vector, bool *is_x
) override;

MDAL::DateTime referenceTime() const override;

/**
* ref time (UTC sec)
*
* parsed only once, because
* some GRIB files do not use FORECAST_SEC, but VALID_TIME
* metadata, so ref time varies with dataset-to-dataset
*/
double mRefTime;
DateTime mRefTime;
};

} // namespace MDAL
Expand Down
22 changes: 15 additions & 7 deletions mdal/frmts/mdal_gdal_netcdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ std::string MDAL::DriverGdalNetCDF::GDALFileName( const std::string &fileName )
#endif
}

bool MDAL::DriverGdalNetCDF::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, const MDAL::DriverGdal::metadata_hash &metadata, std::string &band_name, double *time, bool *is_vector, bool *is_x )
bool MDAL::DriverGdalNetCDF::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, const MDAL::DriverGdal::metadata_hash &metadata, std::string &band_name, Duration *time, bool *is_vector, bool *is_x )
{
MDAL_UNUSED( cfGDALDataset );

metadata_hash::const_iterator iter;

iter = metadata.find( "netcdf_dim_time" );
if ( iter == metadata.end() ) return true; //FAILURE, skip no-time bands
*time = parseMetadataTime( iter->second ) / mTimeDiv;
*time = MDAL::Duration( parseMetadataTime( iter->second ), mTimeUnit );

// NAME
iter = metadata.find( "long_name" );
Expand Down Expand Up @@ -78,11 +78,19 @@ bool MDAL::DriverGdalNetCDF::parseBandInfo( const MDAL::GdalDataset *cfGDALDatas

void MDAL::DriverGdalNetCDF::parseGlobals( const MDAL::DriverGdal::metadata_hash &metadata )
{
metadata_hash::const_iterator iter = metadata.find( "time#units" );
if ( iter != metadata.end() )
metadata_hash::const_iterator iterTimeUnit = metadata.find( "time#units" );
metadata_hash::const_iterator iterCalendar = metadata.find( "time#calendar" );
std::string calendar;
if ( iterCalendar != metadata.end() )
calendar = iterCalendar->second;

if ( iterTimeUnit != metadata.end() )
{
std::string units = iter->second;
mTimeDiv = MDAL::parseTimeUnits( units );
// TODO store reference time from iter->second too, see crayfish_netcdf.cpp
std::string units = iterTimeUnit->second;
mTimeUnit = MDAL::parseCFTimeUnit( units );
if ( !mRefTime.isValid() )
mRefTime = MDAL::parseCFReferenceTime( units, calendar );
}
}

MDAL::DateTime MDAL::DriverGdalNetCDF::referenceTime() const {return mRefTime;}
7 changes: 6 additions & 1 deletion mdal/frmts/mdal_gdal_netcdf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ namespace MDAL
std::string GDALFileName( const std::string &fileName ) override;
bool parseBandInfo( const MDAL::GdalDataset *cfGDALDataset,
const metadata_hash &metadata, std::string &band_name,
double *time, bool *is_vector, bool *is_x
MDAL::Duration *time, bool *is_vector, bool *is_x
) override;
void parseGlobals( const metadata_hash &metadata ) override;

MDAL::DateTime referenceTime() const override;

//! delimiter to get time in hours
double mTimeDiv;
Duration::Unit mTimeUnit;
//! Take the first reference time parsed
DateTime mRefTime;
};

} // namespace MDAL
Expand Down
15 changes: 1 addition & 14 deletions mdal/frmts/mdal_hec2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,7 @@ static std::vector<MDAL::Duration> convertTimeData( std::vector<float> &times, c
{
std::vector<MDAL::Duration> convertedTime( times.size() );

MDAL::Duration::Unit unit = MDAL::Duration::hours;

if ( originalTimeDataUnit == "Seconds" )
{
unit = MDAL::Duration::seconds;
}
else if ( originalTimeDataUnit == "Minutes" )
{
unit = MDAL::Duration::minutes;
}
else if ( originalTimeDataUnit == "Days" )
{
unit = MDAL::Duration::days;
}
MDAL::Duration::Unit unit = MDAL::parseDurationUnitTime( originalTimeDataUnit );

for ( size_t i = 0; i < times.size(); i++ )
{
Expand Down
Loading

0 comments on commit 19af484

Please sign in to comment.