diff --git a/src/base/NcFileVector.cpp b/src/base/NcFileVector.cpp index 91cb474..c0ffde3 100644 --- a/src/base/NcFileVector.cpp +++ b/src/base/NcFileVector.cpp @@ -36,6 +36,7 @@ void NcFileVector::clear() { m_vecNcFile.resize(0); m_vecFilenames.resize(0); m_vecFileType.resize(0); + m_vecFileTime.resize(0); m_time = Time(Time::CalendarUnknown); m_vecTimeIxs.resize(0); } @@ -223,12 +224,26 @@ long NcFileVector::GetTimeIx(size_t pos) const { _ASSERT(vecTimes.size() > 0); if (m_vecFileType[pos] == NcFileVector::FileType_Standard) { + + // Try to identify exact timestamp for (long t = 0; t < vecTimes.size(); t++) { if (vecTimes[t] == m_time) { return t; } } + // Use time bounds + if (vecTimes.m_vecTimeBounds.size() != 0) { + _ASSERT(vecTimes.m_vecTimeBounds.size() == vecTimes.size()); + for (long t = 0; t < vecTimes.size(); t++) { + if ((vecTimes.m_vecTimeBounds[t].first <= m_time) && + (vecTimes.m_vecTimeBounds[t].second > m_time) + ) { + return t; + } + } + } + } else if (m_vecFileType[pos] == NcFileVector::FileType_DailyMeanClimo) { Time timeDailyMean(Time::CalendarNoLeap); timeDailyMean.SetYear(1); diff --git a/src/base/NetCDFUtilities.cpp b/src/base/NetCDFUtilities.cpp index 1a4c813..61ae466 100644 --- a/src/base/NetCDFUtilities.cpp +++ b/src/base/NetCDFUtilities.cpp @@ -968,12 +968,12 @@ void ReadCFTimeDataFromNcFile( NcVar * varTime = NcGetTimeVariable(*ncfile); if (varTime == NULL) { - _EXCEPTION1("Variable \"time\" not found in file \"%s\"", + _EXCEPTION1("Variable \"time\" or equivalent not found in file \"%s\"", strFilename.c_str()); } if (dimTime == NULL) { if (varTime->num_dims() != 0) { - _EXCEPTION1("Dimension \"time\" not found in file \"%s\"", + _EXCEPTION1("Dimension \"time\" or equivalent not found in file \"%s\"", strFilename.c_str()); } lTimeCount = 1; @@ -1033,35 +1033,35 @@ void ReadCFTimeDataFromNcFile( vecTimes.m_units = attTimeUnits->as_string(0); // Load in time data - DataArray1D vecTimeInt; - DataArray1D vecTimeFloat; - DataArray1D vecTimeDouble; - DataArray1D vecTimeInt64; + std::vector vecTimeInt; + std::vector vecTimeFloat; + std::vector vecTimeDouble; + std::vector vecTimeInt64; if (varTime->type() == ncInt) { - vecTimeInt.Allocate(lTimeCount); + vecTimeInt.resize(lTimeCount); varTime->set_cur((long)0); varTime->get(&(vecTimeInt[0]), lTimeCount); } else if (varTime->type() == ncFloat) { - vecTimeFloat.Allocate(lTimeCount); + vecTimeFloat.resize(lTimeCount); varTime->set_cur((long)0); varTime->get(&(vecTimeFloat[0]), lTimeCount); } else if (varTime->type() == ncDouble) { - vecTimeDouble.Allocate(lTimeCount); + vecTimeDouble.resize(lTimeCount); varTime->set_cur((long)0); varTime->get(&(vecTimeDouble[0]), lTimeCount); } else if (varTime->type() == ncInt64) { - vecTimeInt64.Allocate(lTimeCount); + vecTimeInt64.resize(lTimeCount); varTime->set_cur((long)0); varTime->get(&(vecTimeInt64[0]), lTimeCount); } else { - _EXCEPTION1("Variable \"time\" has invalid type " + _EXCEPTION2("Variable \"%s\" has invalid type " "(expected \"int\", \"int64\", \"float\" or \"double\")" - " in file \"%s\"", strFilename.c_str()); + " in file \"%s\"", varTime->name(), strFilename.c_str()); } for (int t = 0; t < lTimeCount; t++) { @@ -1094,6 +1094,98 @@ void ReadCFTimeDataFromNcFile( vecTimes.push_back(time); } + + // Load in time bounds + NcVar * varTimeBounds = NULL; + + NcAtt * attBounds = varTime->get_att("bounds"); + if (attBounds != NULL) { + varTimeBounds = ncfile->get_var(attBounds->as_string(0)); + } + if (varTimeBounds == NULL) { + varTimeBounds = ncfile->get_var("time_bnds"); + } + if (varTimeBounds == NULL) { + varTimeBounds = ncfile->get_var("time_bounds"); + } + if (varTimeBounds != NULL) { + if (varTimeBounds->num_dims() != 2) { + _EXCEPTION1("Time bounds variable \"%s\" must have two dimensions", varTimeBounds->name()); + } + if (varTimeBounds->get_dim(0)->size() != lTimeCount) { + _EXCEPTION2("Time bounds variable \"%s\" first dimension must have same length as time variable \"%s\"", + varTimeBounds->name(), varTime->name()); + } + if (varTimeBounds->get_dim(1)->size() != 2) { + _EXCEPTION1("Time bounds variable \"%s\" second dimension must be size 2", + varTimeBounds->name()); + } + + if (varTimeBounds->type() == ncInt) { + vecTimeInt.resize(2 * lTimeCount); + varTimeBounds->set_cur(0, 0); + varTimeBounds->get(&(vecTimeInt[0]), lTimeCount, 2); + + } else if (varTime->type() == ncFloat) { + vecTimeFloat.resize(2 * lTimeCount); + varTimeBounds->set_cur(0, 0); + varTimeBounds->get(&(vecTimeFloat[0]), lTimeCount, 2); + + } else if (varTime->type() == ncDouble) { + vecTimeDouble.resize(2 * lTimeCount); + varTimeBounds->set_cur(0, 0); + varTimeBounds->get(&(vecTimeDouble[0]), lTimeCount, 2); + + } else if (varTime->type() == ncInt64) { + vecTimeInt64.resize(2 * lTimeCount); + varTimeBounds->set_cur(0, 0); + varTimeBounds->get(&(vecTimeInt64[0]), lTimeCount, 2); + + } else { + _EXCEPTION2("Variable \"%s\" has invalid type " + "(expected \"int\", \"int64\", \"float\" or \"double\")" + " in file \"%s\"", varTimeBounds->name(), strFilename.c_str()); + } + + for (int t = 0; t < lTimeCount; t++) { + std::pair prTimeBound; + for (int tb = 0; tb < 2; tb++) { + Time time(eCalendarType); + + if (varTimeBounds->type() == ncInt) { + time.FromCFCompliantUnitsOffsetInt( + vecTimes.m_units, + vecTimeInt[2*t+tb]); + + } else if (varTimeBounds->type() == ncFloat) { + time.FromCFCompliantUnitsOffsetDouble( + vecTimes.m_units, + static_cast(vecTimeFloat[2*t+tb])); + + } else if (varTimeBounds->type() == ncDouble) { + time.FromCFCompliantUnitsOffsetDouble( + vecTimes.m_units, + vecTimeDouble[2*t+tb]); + + } else if (varTimeBounds->type() == ncInt64) { + time.FromCFCompliantUnitsOffsetInt( + vecTimes.m_units, + (int)(vecTimeInt64[2*t+tb])); + } + +#if defined(ROUND_TIMES_TO_NEAREST_MINUTE) + time.RoundToNearestMinute(); +#endif + if (tb == 0) { + prTimeBound.first = time; + } else { + prTimeBound.second = time; + } + } + + vecTimes.m_vecTimeBounds.push_back(prTimeBound); + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/base/NetCDFUtilities.h b/src/base/NetCDFUtilities.h index d043732..a0a1c8a 100644 --- a/src/base/NetCDFUtilities.h +++ b/src/base/NetCDFUtilities.h @@ -191,6 +191,11 @@ class NcTimeDimension : public std::vector