[MOAB-dev] commit/MOAB: danwu: Reduced readStarts and readCounts to 1D vectors inside ReadNC::VarData, and refactored reading variables code for all NC readers. It has passed all unit tests with make check.
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Wed Nov 27 17:25:00 CST 2013
1 new commit in MOAB:
https://bitbucket.org/fathomteam/moab/commits/846af1453390/
Changeset: 846af1453390
Branch: master
User: danwu
Date: 2013-11-28 00:24:43
Summary: Reduced readStarts and readCounts to 1D vectors inside ReadNC::VarData, and refactored reading variables code for all NC readers. It has passed all unit tests with make check.
Affected #: 4 files
diff --git a/src/io/NCHelper.cpp b/src/io/NCHelper.cpp
index 61a209c..c915382 100644
--- a/src/io/NCHelper.cpp
+++ b/src/io/NCHelper.cpp
@@ -359,23 +359,24 @@ ErrorCode NCHelper::read_variable_setup(std::vector<std::string>& var_names, std
for (unsigned int i = 0; i < vdatas.size(); i++) {
vdatas[i].varTags.resize(tstep_nums.size(), 0);
vdatas[i].varDatas.resize(tstep_nums.size());
- vdatas[i].readStarts.resize(tstep_nums.size());
- vdatas[i].readCounts.resize(tstep_nums.size());
+ vdatas[i].has_tsteps = true;
}
for (unsigned int i = 0; i < vsetdatas.size(); i++) {
if ((std::find(vsetdatas[i].varDims.begin(), vsetdatas[i].varDims.end(), tDim) != vsetdatas[i].varDims.end())
- && (vsetdatas[i].varDims.size() != 1)) {
+ && (vsetdatas[i].varDims.size() > 1)) {
+ // Set variables with timesteps: time is the first dimension, followed
+ // by other dimensions, e.g. xtime(Time, StrLen)
vsetdatas[i].varTags.resize(tstep_nums.size(), 0);
vsetdatas[i].varDatas.resize(tstep_nums.size());
- vsetdatas[i].readStarts.resize(tstep_nums.size());
- vsetdatas[i].readCounts.resize(tstep_nums.size());
+ vsetdatas[i].has_tsteps = true;
}
else {
+ // Set variables without timesteps: no time dimension, or time is the only
+ // dimension, e.g. lev(lev), xtime(Time)
vsetdatas[i].varTags.resize(1, 0);
vsetdatas[i].varDatas.resize(1);
- vsetdatas[i].readStarts.resize(1);
- vsetdatas[i].readCounts.resize(1);
+ vsetdatas[i].has_tsteps = false;
}
}
}
@@ -394,34 +395,41 @@ ErrorCode NCHelper::read_variable_to_set(std::vector<ReadNC::VarData>& vdatas, s
// Finally, read into that space
int success;
for (unsigned int i = 0; i < vdatas.size(); i++) {
+ // Note, for set variables without timesteps, loop one time and then break
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
void* data = vdatas[i].varDatas[t];
+ // Set variables with timesteps, e.g. xtime(Time, StrLen)
+ if (vdatas[i].has_tsteps) {
+ // Set readStart for each timestep along time dimension
+ vdatas[i].readStarts[0] = tstep_nums[t];
+ }
+
switch (vdatas[i].varDataType) {
case NC_BYTE:
case NC_CHAR:
- success = NCFUNCAG(_vara_text)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- (char*) data);
+ success = NCFUNCAG(_vara_text)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
+ &vdatas[i].readCounts[0], (char*) data);
ERRORS(success, "Failed to read char data.");
break;
case NC_DOUBLE:
- success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- (double*) data);
+ success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
+ &vdatas[i].readCounts[0], (double*) data);
ERRORS(success, "Failed to read double data.");
break;
case NC_FLOAT:
- success = NCFUNCAG(_vara_float)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- (float*) data);
+ success = NCFUNCAG(_vara_float)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
+ &vdatas[i].readCounts[0], (float*) data);
ERRORS(success, "Failed to read float data.");
break;
case NC_INT:
- success = NCFUNCAG(_vara_int)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- (int*) data);
+ success = NCFUNCAG(_vara_int)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
+ &vdatas[i].readCounts[0], (int*) data);
ERRORS(success, "Failed to read int data.");
break;
case NC_SHORT:
- success = NCFUNCAG(_vara_short)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- (short*) data);
+ success = NCFUNCAG(_vara_short)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0],
+ &vdatas[i].readCounts[0], (short*) data);
ERRORS(success, "Failed to read short data.");
break;
default:
@@ -458,7 +466,8 @@ ErrorCode NCHelper::read_variable_to_set(std::vector<ReadNC::VarData>& vdatas, s
}
vdatas[i].varDatas[t] = NULL;
- if (vdatas[i].varDims.size() <= 1 || !vdatas[i].has_t)
+ // Loop continues only for set variables with timesteps, e.g. xtime(Time, StrLen)
+ if (!vdatas[i].has_tsteps)
break;
}
}
@@ -600,14 +609,11 @@ ErrorCode NCHelper::get_tag_to_set(ReadNC::VarData& var_data, int tstep_num, Tag
DebugOutput& dbgOut = _readNC->dbgOut;
std::ostringstream tag_name;
- if ((!var_data.has_t) || (var_data.varDims.size() <= 1))
- tag_name << var_data.varName;
- else if (!tstep_num) {
- std::string tmp_name = var_data.varName + "0";
- tag_name << tmp_name.c_str();
- }
- else
+ if (var_data.has_tsteps)
tag_name << var_data.varName << tstep_num;
+ else
+ tag_name << var_data.varName;
+
ErrorCode rval = MB_SUCCESS;
tagh = 0;
switch (var_data.varDataType) {
@@ -640,12 +646,8 @@ ErrorCode NCHelper::get_tag_to_nonset(ReadNC::VarData& var_data, int tstep_num,
DebugOutput& dbgOut = _readNC->dbgOut;
std::ostringstream tag_name;
- if (!tstep_num) {
- std::string tmp_name = var_data.varName + "0";
- tag_name << tmp_name.c_str();
- }
- else
- tag_name << var_data.varName << tstep_num;
+ tag_name << var_data.varName << tstep_num;
+
ErrorCode rval = MB_SUCCESS;
tagh = 0;
switch (var_data.varDataType) {
@@ -792,75 +794,71 @@ ErrorCode NCHelper::read_variable_to_set_allocate(std::vector<ReadNC::VarData>&
ErrorCode rval = MB_SUCCESS;
for (unsigned int i = 0; i < vdatas.size(); i++) {
- if ((std::find(vdatas[i].varDims.begin(), vdatas[i].varDims.end(), tDim) != vdatas[i].varDims.end()))
- vdatas[i].has_t = true;
-
- for (unsigned int t = 0; t < tstep_nums.size(); t++) {
- dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
-
- // Get the tag to read into
- if (!vdatas[i].varTags[t]) {
- rval = get_tag_to_set(vdatas[i], tstep_nums[t], vdatas[i].varTags[t]);
- ERRORR(rval, "Trouble getting tag.");
- }
-
- // Assume point-based values for now?
- if (-1 == tDim || dimLens[tDim] <= (int) t)
- ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number.");
+ // Set up readStarts and readCounts
+ if (vdatas[i].has_tsteps) {
+ // First: time
+ vdatas[i].readStarts.push_back(0); // This value is timestep dependent, will be set later
+ vdatas[i].readCounts.push_back(1);
- // Set up the dimensions and counts
- // First variable dimension is time, if it exists
- if (vdatas[i].has_t) {
- if (vdatas[i].varDims.size() != 1) {
- vdatas[i].readStarts[t].push_back(tstep_nums[t]);
- vdatas[i].readCounts[t].push_back(1);
- }
- else {
- vdatas[i].readStarts[t].push_back(0);
- vdatas[i].readCounts[t].push_back(tstep_nums.size());
- }
+ // Next: other dimensions
+ for (unsigned int idx = 1; idx != vdatas[i].varDims.size(); idx++){
+ vdatas[i].readStarts.push_back(0);
+ vdatas[i].readCounts.push_back(dimLens[vdatas[i].varDims[idx]]);
}
-
- // Set up other dimensions and counts
+ }
+ else {
if (vdatas[i].varDims.empty()) {
// Scalar variable
- vdatas[i].readStarts[t].push_back(0);
- vdatas[i].readCounts[t].push_back(1);
+ vdatas[i].readStarts.push_back(0);
+ vdatas[i].readCounts.push_back(1);
}
else {
for (unsigned int idx = 0; idx != vdatas[i].varDims.size(); idx++){
- if (tDim != vdatas[i].varDims[idx]){
- // Push other variable dimensions, except time, which was already pushed
- vdatas[i].readStarts[t].push_back(0);
- vdatas[i].readCounts[t].push_back(dimLens[vdatas[i].varDims[idx]]);
- }
+ vdatas[i].readStarts.push_back(0);
+ vdatas[i].readCounts.push_back(dimLens[vdatas[i].varDims[idx]]);
}
}
+ }
+
+ // Get variable size
+ vdatas[i].sz = 1;
+ for (std::size_t idx = 0; idx != vdatas[i].readCounts.size(); idx++)
+ vdatas[i].sz *= vdatas[i].readCounts[idx];
- std::size_t sz = 1;
- for (std::size_t idx = 0; idx != vdatas[i].readCounts[t].size(); idx++)
- sz *= vdatas[i].readCounts[t][idx];
- vdatas[i].sz = sz;
+ // Note, for set variables without timesteps, loop one time and then break
+ for (unsigned int t = 0; t < tstep_nums.size(); t++) {
+ dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
+
+ if (tstep_nums[t] >= dimLens[tDim]) {
+ ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for a timestep number.");
+ }
+
+ // Get the tag to read into
+ if (!vdatas[i].varTags[t]) {
+ rval = get_tag_to_set(vdatas[i], tstep_nums[t], vdatas[i].varTags[t]);
+ ERRORR(rval, "Trouble getting tag for a set variable.");
+ }
switch (vdatas[i].varDataType) {
case NC_BYTE:
case NC_CHAR:
- vdatas[i].varDatas[t] = new char[sz];
+ vdatas[i].varDatas[t] = new char[vdatas[i].sz];
break;
case NC_DOUBLE:
case NC_FLOAT:
- vdatas[i].varDatas[t] = new double[sz];
+ vdatas[i].varDatas[t] = new double[vdatas[i].sz];
break;
case NC_INT:
case NC_SHORT:
- vdatas[i].varDatas[t] = new int[sz];
+ vdatas[i].varDatas[t] = new int[vdatas[i].sz];
break;
default:
std::cerr << "Unrecognized data type for set variable tag values" << std::endl;
rval = MB_FAILURE;
}
- if (vdatas[i].varDims.size() <= 1 || !vdatas[i].has_t)
+ // Loop continues only for set variables with timesteps, e.g. xtime(Time, StrLen)
+ if (!vdatas[i].has_tsteps)
break;
}
}
@@ -1073,70 +1071,73 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset_allocate(std::vector<ReadNC::
#endif
for (unsigned int i = 0; i < vdatas.size(); i++) {
+ // Support non-set variables with 4 dimensions like (time, lev, lat, lon)
+ assert(4 == vdatas[i].varDims.size());
+
+ // For a non-set variable, time should be the first dimension
+ assert(tDim == vdatas[i].varDims[0]);
+
+ // Set up readStarts and readCounts
+ vdatas[i].readStarts.resize(4);
+ vdatas[i].readCounts.resize(4);
+
+ // First: time
+ vdatas[i].readStarts[0] = 0; // This value is timestep dependent, will be set later
+ vdatas[i].readCounts[0] = 1;
+
+ // Next: lev
+ vdatas[i].readStarts[1] = 0;
+ vdatas[i].readCounts[1] = vdatas[i].numLev;
+
+ // Finally: lat (or slat) and lon (or slon)
+ switch (vdatas[i].entLoc) {
+ case ReadNC::ENTLOCVERT:
+ // Vertices
+ vdatas[i].readStarts[2] = lDims[1];
+ vdatas[i].readCounts[2] = lDims[4] - lDims[1] + 1;
+ vdatas[i].readStarts[3] = lDims[0];
+ vdatas[i].readCounts[3] = lDims[3] - lDims[0] + 1;
+ range = &verts;
+ break;
+ case ReadNC::ENTLOCNSEDGE:
+ ERRORR(MB_FAILURE, "Reading edge data not implemented yet.");
+ break;
+ case ReadNC::ENTLOCEWEDGE:
+ ERRORR(MB_FAILURE, "Reading edge data not implemented yet.");
+ break;
+ case ReadNC::ENTLOCFACE:
+ // Faces
+ vdatas[i].readStarts[2] = lCDims[1];
+ vdatas[i].readCounts[2] = lCDims[4] - lCDims[1] + 1;
+ vdatas[i].readStarts[3] = lCDims[0];
+ vdatas[i].readCounts[3] = lCDims[3] - lCDims[0] + 1;
+#ifdef USE_MPI
+ range = &faces_owned;
+#else
+ range = &faces;
+#endif
+ break;
+ case ReadNC::ENTLOCSET:
+ // Set
+ break;
+ default:
+ ERRORR(MB_FAILURE, "Unrecognized entity location type.");
+ break;
+ }
+
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
+ if (tstep_nums[t] >= dimLens[tDim]) {
+ ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for a timestep number.");
+ }
+
// Get the tag to read into
if (!vdatas[i].varTags[t]) {
rval = get_tag_to_nonset(vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev);
ERRORR(rval, "Trouble getting tag.");
}
- // Assume point-based values for now?
- if (-1 == tDim || dimLens[tDim] <= (int) t) {
- ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number.");
- }
- else if (vdatas[i].varDims[0] != tDim) {
- ERRORR(MB_INDEX_OUT_OF_RANGE, "Non-default timestep number given for time-independent variable.");
- }
-
- // Set up the dimensions and counts
- // First: time
- vdatas[i].readStarts[t].push_back(tstep_nums[t]);
- vdatas[i].readCounts[t].push_back(1);
-
- // Next: numLev, even if it is 1
- vdatas[i].readStarts[t].push_back(0);
- vdatas[i].readCounts[t].push_back(vdatas[i].numLev);
-
- // Finally: y and x
- switch (vdatas[i].entLoc) {
- case ReadNC::ENTLOCVERT:
- // Vertices
- vdatas[i].readStarts[t].push_back(lDims[1]);
- vdatas[i].readCounts[t].push_back(lDims[4] - lDims[1] + 1);
- vdatas[i].readStarts[t].push_back(lDims[0]);
- vdatas[i].readCounts[t].push_back(lDims[3] - lDims[0] + 1);
- assert(vdatas[i].readStarts[t].size() == vdatas[i].varDims.size());
- range = &verts;
- break;
- case ReadNC::ENTLOCNSEDGE:
- ERRORR(MB_FAILURE, "Reading edge data not implemented yet.");
- break;
- case ReadNC::ENTLOCEWEDGE:
- ERRORR(MB_FAILURE, "Reading edge data not implemented yet.");
- break;
- case ReadNC::ENTLOCFACE:
- // Faces
- vdatas[i].readStarts[t].push_back(lCDims[1]);
- vdatas[i].readCounts[t].push_back(lCDims[4] - lCDims[1] + 1);
- vdatas[i].readStarts[t].push_back(lCDims[0]);
- vdatas[i].readCounts[t].push_back(lCDims[3] - lCDims[0] + 1);
- assert(vdatas[i].readStarts[t].size() == vdatas[i].varDims.size());
-#ifdef USE_MPI
- range = &faces_owned;
-#else
- range = &faces;
-#endif
- break;
- case ReadNC::ENTLOCSET:
- // Set
- break;
- default:
- ERRORR(MB_FAILURE, "Unrecognized entity location type.");
- break;
- }
-
// Get ptr to tag space
void* data;
int count;
@@ -1146,11 +1147,10 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset_allocate(std::vector<ReadNC::
vdatas[i].varDatas[t] = data;
}
- // Calculate variable size
- std::size_t sz = 1;
- for (std::size_t idx = 0; idx != vdatas[i].readCounts[0].size(); idx++)
- sz *= vdatas[i].readCounts[0][idx];
- vdatas[i].sz = sz;
+ // Get variable size
+ vdatas[i].sz = 1;
+ for (std::size_t idx = 0; idx != vdatas[i].readCounts.size(); idx++)
+ vdatas[i].sz *= vdatas[i].readCounts[idx];
}
return rval;
@@ -1168,22 +1168,27 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset(std::vector<ReadNC::VarData>&
for (unsigned int i = 0; i < vdatas.size(); i++) {
std::size_t sz = vdatas[i].sz;
+ // A typical supported variable: float T(time, lev, lat, lon)
+ // For tag values, need transpose (lev, lat, lon) to (lat, lon, lev)
+ size_t ni = vdatas[i].readCounts[3]; // lon or slon
+ size_t nj = vdatas[i].readCounts[2]; // lat or slat
+ size_t nk = vdatas[i].readCounts[1]; // lev
+
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
+ // Tag data for this timestep
void* data = vdatas[i].varDatas[t];
- // A typical variable: float T(time, lev, lat, lon)
- // For tag values, need transpose kji to jik, i.e. (lev, lat, lon) to (lat, lon, lev)
- size_t ni = vdatas[i].readCounts[t][3]; // lon or slon
- size_t nj = vdatas[i].readCounts[t][2]; // lat or slat
- size_t nk = vdatas[i].readCounts[t][1]; // lev
+
+ // Set readStart for each timestep along time dimension
+ vdatas[i].readStarts[0] = tstep_nums[t];
switch (vdatas[i].varDataType) {
case NC_BYTE:
case NC_CHAR: {
std::vector<char> tmpchardata(sz);
- success = NCFUNCAG(_vara_text)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- &tmpchardata[0]);
+ success = NCFUNCAG(_vara_text)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
+ &tmpchardata[0]);
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, lat, lon) to (lat, lon, lev)
success = kji_to_jik(ni, nj, nk, data, &tmpchardata[0]);
else {
for (std::size_t idx = 0; idx != tmpchardata.size(); idx++)
@@ -1194,10 +1199,10 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset(std::vector<ReadNC::VarData>&
}
case NC_DOUBLE: {
std::vector<double> tmpdoubledata(sz);
- success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- &tmpdoubledata[0]);
+ success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
+ &tmpdoubledata[0]);
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, lat, lon) to (lat, lon, lev)
success = kji_to_jik(ni, nj, nk, data, &tmpdoubledata[0]);
else {
for (std::size_t idx = 0; idx != tmpdoubledata.size(); idx++)
@@ -1208,10 +1213,10 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset(std::vector<ReadNC::VarData>&
}
case NC_FLOAT: {
std::vector<float> tmpfloatdata(sz);
- success = NCFUNCAG(_vara_float)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- &tmpfloatdata[0]);
+ success = NCFUNCAG(_vara_float)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
+ &tmpfloatdata[0]);
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, lat, lon) to (lat, lon, lev)
success = kji_to_jik(ni, nj, nk, data, &tmpfloatdata[0]);
else {
for (std::size_t idx = 0; idx != tmpfloatdata.size(); idx++)
@@ -1222,10 +1227,10 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset(std::vector<ReadNC::VarData>&
}
case NC_INT: {
std::vector<int> tmpintdata(sz);
- success = NCFUNCAG(_vara_int)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- &tmpintdata[0]);
+ success = NCFUNCAG(_vara_int)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
+ &tmpintdata[0]);
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, lat, lon) to (lat, lon, lev)
success = kji_to_jik(ni, nj, nk, data, &tmpintdata[0]);
else {
for (std::size_t idx = 0; idx != tmpintdata.size(); idx++)
@@ -1236,10 +1241,10 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset(std::vector<ReadNC::VarData>&
}
case NC_SHORT: {
std::vector<short> tmpshortdata(sz);
- success = NCFUNCAG(_vara_short)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[t][0], &vdatas[i].readCounts[t][0],
- &tmpshortdata[0]);
+ success = NCFUNCAG(_vara_short)(_fileId, vdatas[i].varId, &vdatas[i].readStarts[0], &vdatas[i].readCounts[0],
+ &tmpshortdata[0]);
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, lat, lon) to (lat, lon, lev)
success = kji_to_jik(ni, nj, nk, data, &tmpshortdata[0]);
else {
for (std::size_t idx = 0; idx != tmpshortdata.size(); idx++)
diff --git a/src/io/NCHelperHOMME.cpp b/src/io/NCHelperHOMME.cpp
index 25c4441..efddb0c 100644
--- a/src/io/NCHelperHOMME.cpp
+++ b/src/io/NCHelperHOMME.cpp
@@ -525,49 +525,57 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_allocate(std::vector<ReadNC
verts.psize() == 1);
for (unsigned int i = 0; i < vdatas.size(); i++) {
- vdatas[i].numLev = nLevels;
+ // Support non-set variables with 3 dimensions like (time, lev, ncol)
+ assert(3 == vdatas[i].varDims.size());
+
+ // For a non-set variable, time should be the first dimension
+ assert(tDim == vdatas[i].varDims[0]);
+
+ // Set up readStarts and readCounts
+ vdatas[i].readStarts.resize(3);
+ vdatas[i].readCounts.resize(3);
+
+ // First: time
+ vdatas[i].readStarts[0] = 0; // This value is timestep dependent, will be set later
+ vdatas[i].readCounts[0] = 1;
+
+ // Next: lev
+ vdatas[i].readStarts[1] = 0;
+ vdatas[i].readCounts[1] = vdatas[i].numLev;
+
+ // Finally: ncol
+ switch (vdatas[i].entLoc) {
+ case ReadNC::ENTLOCVERT:
+ // Vertices
+ // Start from the first localGidVerts
+ // Actually, this will be reset later on in a loop
+ vdatas[i].readStarts[2] = localGidVerts[0] - 1;
+ vdatas[i].readCounts[2] = nLocalVertices;
+ range = &verts;
+ break;
+ default:
+ ERRORR(MB_FAILURE, "Unexpected entity location type for HOMME non-set variable.");
+ break;
+ }
+
+ // Get variable size
+ vdatas[i].sz = 1;
+ for (std::size_t idx = 0; idx != 3; idx++)
+ vdatas[i].sz *= vdatas[i].readCounts[idx];
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
+
+ if (tstep_nums[t] >= dimLens[tDim]) {
+ ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for a timestep number.");
+ }
+
// Get the tag to read into
if (!vdatas[i].varTags[t]) {
rval = get_tag_to_nonset(vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev);
ERRORR(rval, "Trouble getting tag.");
}
- // Assume point-based values for now?
- if (-1 == tDim || dimLens[tDim] <= (int) t) {
- ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number.");
- }
- else if (vdatas[i].varDims[0] != tDim) {
- ERRORR(MB_INDEX_OUT_OF_RANGE, "Non-default timestep number given for time-independent variable.");
- }
-
- // Set up the dimensions and counts
- // First: time
- vdatas[i].readStarts[t].push_back(tstep_nums[t]);
- vdatas[i].readCounts[t].push_back(1);
-
- // Next: numLev, even if it is 1
- vdatas[i].readStarts[t].push_back(0);
- vdatas[i].readCounts[t].push_back(vdatas[i].numLev);
-
- // Finally: nVertices
- switch (vdatas[i].entLoc) {
- case ReadNC::ENTLOCVERT:
- // Vertices
- // We will start from the first localGidVerts, actually; we will reset that
- // later on, anyway, in a loop
- vdatas[i].readStarts[t].push_back(localGidVerts[0] - 1);
- vdatas[i].readCounts[t].push_back(nLocalVertices);
- assert(vdatas[i].readStarts[t].size() == vdatas[i].varDims.size());
- range = &verts;
- break;
- default:
- ERRORR(MB_FAILURE, "Unexpected entity location type for HOMME non-set variable.");
- break;
- }
-
// Get ptr to tag space
void* data;
int count;
@@ -576,12 +584,6 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_allocate(std::vector<ReadNC
assert((unsigned)count == range->size());
vdatas[i].varDatas[t] = data;
}
-
- // Calculate variable size
- std::size_t sz = 1;
- for (std::size_t idx = 0; idx != vdatas[i].readCounts[0].size(); idx++)
- sz *= vdatas[i].readCounts[0][idx];
- vdatas[i].sz = sz;
}
return rval;
@@ -601,16 +603,24 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
for (unsigned int i = 0; i < vdatas.size(); i++) {
std::size_t sz = vdatas[i].sz;
+ // A typical supported variable: float T(time, lev, ncol)
+ // For tag values, need transpose (lev, ncol) to (ncol, lev)
+ size_t ni = vdatas[i].readCounts[2]; // ncol
+ size_t nj = 1; // Here we should just set nj to 1
+ size_t nk = vdatas[i].readCounts[1]; // lev
+
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
// We will synchronize all these reads with the other processors,
// so the wait will be inside this double loop; is it too much?
size_t nb_reads = localGidVerts.psize();
std::vector<int> requests(nb_reads), statuss(nb_reads);
size_t idxReq = 0;
+
+ // Tag data for this timestep
void* data = vdatas[i].varDatas[t];
- size_t ni = vdatas[i].readCounts[t][2];
- size_t nj = 1; // For HOMME, nj holds # quads, so here should set to 1
- size_t nk = vdatas[i].readCounts[t][1];
+
+ // Set readStart for each timestep along time dimension
+ vdatas[i].readStarts[0] = tstep_nums[t];
switch (vdatas[i].varDataType) {
case NC_BYTE:
@@ -619,7 +629,7 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
break;
}
case NC_DOUBLE: {
- // Copy from float case
+ // Copied from float case
std::vector<double> tmpdoubledata(sz);
// In the case of ucd mesh, and on multiple proc,
@@ -627,10 +637,6 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
// localGidVerts range;
// basically, we have to give a different point
// for data to start, for every subrange :(
- size_t nbDims = vdatas[i].readStarts[t].size();
- // assume that the last dimension is for the ncol,
- // node varying variable
-
size_t indexInDoubleArray = 0;
size_t ic = 0;
for (Range::pair_iterator pair_iter = localGidVerts.pair_begin();
@@ -638,13 +644,13 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
pair_iter++, ic++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second; // inclusive
- vdatas[i].readStarts[t][nbDims - 1] = (NCDF_SIZE) (starth - 1);
- vdatas[i].readCounts[t][nbDims - 1] = (NCDF_SIZE) (endh - starth + 1);
+ vdatas[i].readStarts[2] = (NCDF_SIZE) (starth - 1);
+ vdatas[i].readCounts[2] = (NCDF_SIZE) (endh - starth + 1);
// Do a partial read, in each subrange
// wait outside this loop
success = NCFUNCREQG(_vara_double)(_fileId, vdatas[i].varId,
- &(vdatas[i].readStarts[t][0]), &(vdatas[i].readCounts[t][0]),
+ &(vdatas[i].readStarts[0]), &(vdatas[i].readCounts[0]),
&(tmpdoubledata[indexInDoubleArray]), &requests[idxReq++]);
ERRORS(success, "Failed to read double data in loop");
// We need to increment the index in double array for the
@@ -657,7 +663,7 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
ERRORS(success, "Failed on wait_all.");
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, ncol) to (ncol, lev)
success = kji_to_jik_stride(ni, nj, nk, data, &tmpdoubledata[0], localGidVerts);
else {
for (std::size_t idx = 0; idx != tmpdoubledata.size(); idx++)
@@ -674,9 +680,6 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
// localGidVerts range;
// basically, we have to give a different point
// for data to start, for every subrange :(
- size_t nbDims = vdatas[i].readStarts[t].size();
-
- // Assume that the last dimension is for the ncol, number of vertices
size_t indexInFloatArray = 0;
size_t ic = 0;
for (Range::pair_iterator pair_iter = localGidVerts.pair_begin();
@@ -684,13 +687,13 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
pair_iter++, ic++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second; // inclusive
- vdatas[i].readStarts[t][nbDims - 1] = (NCDF_SIZE) (starth - 1);
- vdatas[i].readCounts[t][nbDims - 1] = (NCDF_SIZE) (endh - starth + 1);
+ vdatas[i].readStarts[2] = (NCDF_SIZE) (starth - 1);
+ vdatas[i].readCounts[2] = (NCDF_SIZE) (endh - starth + 1);
// Do a partial read, in each subrange
// wait outside this loop
success = NCFUNCREQG(_vara_float)(_fileId, vdatas[i].varId,
- &(vdatas[i].readStarts[t][0]), &(vdatas[i].readCounts[t][0]),
+ &(vdatas[i].readStarts[0]), &(vdatas[i].readCounts[0]),
&(tmpfloatdata[indexInFloatArray]), &requests[idxReq++]);
ERRORS(success, "Failed to read float data in loop");
// We need to increment the index in float array for the
@@ -703,7 +706,7 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
ERRORS(success, "Failed on wait_all.");
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, ncol) to (ncol, lev)
success = kji_to_jik_stride(ni, nj, nk, data, &tmpfloatdata[0], localGidVerts);
else {
for (std::size_t idx = 0; idx != tmpfloatdata.size(); idx++)
@@ -737,6 +740,7 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset_async(std::vector<ReadNC::V
rval = tmp_rval;
}
}
+
// Debug output, if requested
if (1 == dbgOut.get_verbosity()) {
dbgOut.printf(1, "Read variables: %s", vdatas.begin()->varName.c_str());
@@ -760,11 +764,18 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
for (unsigned int i = 0; i < vdatas.size(); i++) {
std::size_t sz = vdatas[i].sz;
+ // A typical supported variable: float T(time, lev, ncol)
+ // For tag values, need transpose (lev, ncol) to (ncol, lev)
+ size_t ni = vdatas[i].readCounts[2]; // ncol
+ size_t nj = 1; // Here we should just set nj to 1
+ size_t nk = vdatas[i].readCounts[1]; // lev
+
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
+ // Tag data for this timestep
void* data = vdatas[i].varDatas[t];
- size_t ni = vdatas[i].readCounts[t][2];
- size_t nj = 1; // For HOMME, nj holds # quads, so here should set to 1
- size_t nk = vdatas[i].readCounts[t][1];
+
+ // Set readStart for each timestep along time dimension
+ vdatas[i].readStarts[0] = tstep_nums[t];
switch (vdatas[i].varDataType) {
case NC_BYTE:
@@ -773,7 +784,7 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
break;
}
case NC_DOUBLE: {
- // Copy from float case
+ // Copied from float case
std::vector<double> tmpdoubledata(sz);
// In the case of ucd mesh, and on multiple proc,
@@ -781,9 +792,6 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
// localGidVerts range;
// basically, we have to give a different point
// for data to start, for every subrange :(
- size_t nbDims = vdatas[i].readStarts[t].size();
-
- // Assume that the last dimension is for the ncol, number of vertices
size_t indexInDoubleArray = 0;
size_t ic = 0;
for (Range::pair_iterator pair_iter = localGidVerts.pair_begin();
@@ -791,11 +799,11 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
pair_iter++, ic++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second; // Inclusive
- vdatas[i].readStarts[t][nbDims - 1] = (NCDF_SIZE) (starth - 1);
- vdatas[i].readCounts[t][nbDims - 1] = (NCDF_SIZE) (endh - starth + 1);
+ vdatas[i].readStarts[2] = (NCDF_SIZE) (starth - 1);
+ vdatas[i].readCounts[2] = (NCDF_SIZE) (endh - starth + 1);
success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId,
- &(vdatas[i].readStarts[t][0]), &(vdatas[i].readCounts[t][0]),
+ &(vdatas[i].readStarts[0]), &(vdatas[i].readCounts[0]),
&(tmpdoubledata[indexInDoubleArray]));
ERRORS(success, "Failed to read float data in loop");
// We need to increment the index in double array for the
@@ -805,7 +813,7 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
assert(ic == localGidVerts.psize());
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, ncol) to (ncol, lev)
success = kji_to_jik_stride(ni, nj, nk, data, &tmpdoubledata[0], localGidVerts);
else {
for (std::size_t idx = 0; idx != tmpdoubledata.size(); idx++)
@@ -822,9 +830,6 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
// localGidVerts range;
// basically, we have to give a different point
// for data to start, for every subrange :(
- size_t nbDims = vdatas[i].readStarts[t].size();
-
- // Assume that the last dimension is for the ncol
size_t indexInFloatArray = 0;
size_t ic = 0;
for (Range::pair_iterator pair_iter = localGidVerts.pair_begin();
@@ -832,11 +837,11 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
pair_iter++, ic++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second; // Inclusive
- vdatas[i].readStarts[t][nbDims-1] = (NCDF_SIZE) (starth - 1);
- vdatas[i].readCounts[t][nbDims-1] = (NCDF_SIZE) (endh - starth + 1);
+ vdatas[i].readStarts[2] = (NCDF_SIZE) (starth - 1);
+ vdatas[i].readCounts[2] = (NCDF_SIZE) (endh - starth + 1);
success = NCFUNCAG(_vara_float)(_fileId, vdatas[i].varId,
- &(vdatas[i].readStarts[t][0]), &(vdatas[i].readCounts[t][0]),
+ &(vdatas[i].readStarts[0]), &(vdatas[i].readCounts[0]),
&(tmpfloatdata[indexInFloatArray]));
ERRORS(success, "Failed to read float data in loop");
// We need to increment the index in float array for the
@@ -846,7 +851,7 @@ ErrorCode NCHelperHOMME::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData
assert(ic == localGidVerts.psize());
if (vdatas[i].numLev != 1)
- // Switch from k varying slowest to k varying fastest
+ // Transpose (lev, ncol) to (ncol, lev)
success = kji_to_jik_stride(ni, nj, nk, data, &tmpfloatdata[0], localGidVerts);
else {
for (std::size_t idx = 0; idx != tmpfloatdata.size(); idx++)
diff --git a/src/io/NCHelperMPAS.cpp b/src/io/NCHelperMPAS.cpp
index b706990..684aa4d 100644
--- a/src/io/NCHelperMPAS.cpp
+++ b/src/io/NCHelperMPAS.cpp
@@ -550,62 +550,79 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_allocate(std::vector<ReadNC:
#endif
for (unsigned int i = 0; i < vdatas.size(); i++) {
+ // Skip edge variables, if specified by the read options
if (noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE)
continue;
+ // Support non-set variables with 3 dimensions like (Time, nCells, nVertLevels), or
+ // 2 dimensions like (Time, nCells)
+ assert(3 == vdatas[i].varDims.size() || 2 == vdatas[i].varDims.size());
+
+ // For a non-set variable, time should be the first dimension
+ assert(tDim == vdatas[i].varDims[0]);
+
+ // Set up readStarts and readCounts
+ vdatas[i].readStarts.resize(3);
+ vdatas[i].readCounts.resize(3);
+
+ // First: Time
+ vdatas[i].readStarts[0] = 0; // This value is timestep dependent, will be set later
+ vdatas[i].readCounts[0] = 1;
+
+ // Next: nVertices / nCells / nEdges
+ switch (vdatas[i].entLoc) {
+ case ReadNC::ENTLOCVERT:
+ // Vertices
+ // Start from the first localGidVerts
+ // Actually, this will be reset later on in a loop
+ vdatas[i].readStarts[1] = localGidVerts[0] - 1;
+ vdatas[i].readCounts[1] = nLocalVertices;
+ range = &verts;
+ break;
+ case ReadNC::ENTLOCFACE:
+ // Faces
+ // Start from the first localGidCells
+ // Actually, this will be reset later on in a loop
+ vdatas[i].readStarts[1] = localGidCells[0] - 1;
+ vdatas[i].readCounts[1] = nLocalCells;
+ range = &facesOwned;
+ break;
+ case ReadNC::ENTLOCEDGE:
+ // Edges
+ // Start from the first localGidEdges
+ // Actually, this will be reset later on in a loop
+ vdatas[i].readStarts[1] = localGidEdges[0] - 1;
+ vdatas[i].readCounts[1] = nLocalEdges;
+ range = &edges;
+ break;
+ default:
+ ERRORR(MB_FAILURE, "Unexpected entity location type for MPAS non-set variable.");
+ break;
+ }
+
+ // Finally: nVertLevels or other optional levels, it is possible that there
+ // is no level dimension for this non-set variable
+ vdatas[i].readStarts[2] = 0;
+ vdatas[i].readCounts[2] = vdatas[i].numLev;
+
+ // Get variable size
+ vdatas[i].sz = 1;
+ for (std::size_t idx = 0; idx != 3; idx++)
+ vdatas[i].sz *= vdatas[i].readCounts[idx];
+
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
+
+ if (tstep_nums[t] >= dimLens[tDim]) {
+ ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for a timestep number.");
+ }
+
// Get the tag to read into
if (!vdatas[i].varTags[t]) {
rval = get_tag_to_nonset(vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev);
ERRORR(rval, "Trouble getting tag.");
}
- // Assume point-based values for now?
- if (-1 == tDim || dimLens[tDim] <= (int) t) {
- ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number.");
- }
- else if (vdatas[i].varDims[0] != tDim) {
- ERRORR(MB_INDEX_OUT_OF_RANGE, "Non-default timestep number given for time-independent variable.");
- }
-
- // Set up the dimensions and counts
- // First: Time
- vdatas[i].readStarts[t].push_back(tstep_nums[t]);
- vdatas[i].readCounts[t].push_back(1);
-
- // Next: nCells or nEdges or nVertices
- switch (vdatas[i].entLoc) {
- case ReadNC::ENTLOCVERT:
- // Vertices
- vdatas[i].readStarts[t].push_back(localGidVerts[0] - 1);
- vdatas[i].readCounts[t].push_back(nLocalVertices);
- range = &verts;
- break;
- case ReadNC::ENTLOCFACE:
- // Faces
- vdatas[i].readStarts[t].push_back(localGidCells[0] - 1);
- vdatas[i].readCounts[t].push_back(nLocalCells);
- range = &facesOwned;
- break;
- case ReadNC::ENTLOCEDGE:
- // Edges
- vdatas[i].readStarts[t].push_back(localGidEdges[0] - 1);
- vdatas[i].readCounts[t].push_back(nLocalEdges);
- range = &edges;
- break;
- default:
- ERRORR(MB_FAILURE, "Unexpected entity location type for MPAS non-set variable.");
- break;
- }
-
- // Last, numLev, even if it is 1
- vdatas[i].readStarts[t].push_back(0);
- vdatas[i].readCounts[t].push_back(vdatas[i].numLev);
- // Some variables have no level dimension, e.g. surface_pressure(Time, nCells)
- assert(vdatas[i].readStarts[t].size() == vdatas[i].varDims.size() ||
- vdatas[i].readStarts[t].size() == vdatas[i].varDims.size() + 1);
-
// Get ptr to tag space
if (vdatas[i].entLoc == ReadNC::ENTLOCFACE && numCellGroups > 1) {
// For a cell variable that is NOT on one contiguous chunk of faces, defer its tag space allocation
@@ -621,12 +638,6 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_allocate(std::vector<ReadNC:
vdatas[i].varDatas[t] = data;
}
}
-
- // Calculate variable size
- std::size_t sz = 1;
- for (std::size_t idx = 0; idx != vdatas[i].readCounts[0].size(); idx++)
- sz *= vdatas[i].readCounts[0][idx];
- vdatas[i].sz = sz;
}
return rval;
@@ -647,6 +658,7 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_async(std::vector<ReadNC::Va
Range* pLocalGid = NULL;
for (unsigned int i = 0; i < vdatas.size(); i++) {
+ // Skip edge variables, if specified by the read options
if (noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE)
continue;
@@ -674,6 +686,9 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_async(std::vector<ReadNC::Va
std::vector<int> requests(nb_reads), statuss(nb_reads);
size_t idxReq = 0;
+ // Set readStart for each timestep along time dimension
+ vdatas[i].readStarts[0] = tstep_nums[t];
+
switch (vdatas[i].varDataType) {
case NC_BYTE:
case NC_CHAR: {
@@ -688,9 +703,7 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_async(std::vector<ReadNC::Va
// localGid range;
// basically, we have to give a different point
// for data to start, for every subrange :(
- size_t nbDims = vdatas[i].readStarts[t].size();
- // Assume that the last dimension is for the nVertLevels
size_t indexInDoubleArray = 0;
size_t ic = 0;
for (Range::pair_iterator pair_iter = pLocalGid->pair_begin();
@@ -698,13 +711,13 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_async(std::vector<ReadNC::Va
pair_iter++, ic++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second; // inclusive
- vdatas[i].readStarts[t][nbDims - 2] = (NCDF_SIZE) (starth - 1);
- vdatas[i].readCounts[t][nbDims - 2] = (NCDF_SIZE) (endh - starth + 1);
+ vdatas[i].readStarts[1] = (NCDF_SIZE) (starth - 1);
+ vdatas[i].readCounts[1] = (NCDF_SIZE) (endh - starth + 1);
// Do a partial read, in each subrange
// wait outside this loop
success = NCFUNCREQG(_vara_double)(_fileId, vdatas[i].varId,
- &(vdatas[i].readStarts[t][0]), &(vdatas[i].readCounts[t][0]),
+ &(vdatas[i].readStarts[0]), &(vdatas[i].readCounts[0]),
&(tmpdoubledata[indexInDoubleArray]), &requests[idxReq++]);
ERRORS(success, "Failed to read double data in loop");
// We need to increment the index in double array for the
@@ -802,6 +815,7 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData>
Range* pLocalGid = NULL;
for (unsigned int i = 0; i < vdatas.size(); i++) {
+ // Skip edge variables, if specified by the read options
if (noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE)
continue;
@@ -823,6 +837,9 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData>
std::size_t sz = vdatas[i].sz;
for (unsigned int t = 0; t < tstep_nums.size(); t++) {
+ // Set readStart for each timestep along time dimension
+ vdatas[i].readStarts[0] = tstep_nums[t];
+
switch (vdatas[i].varDataType) {
case NC_BYTE:
case NC_CHAR: {
@@ -830,7 +847,6 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData>
break;
}
case NC_DOUBLE: {
- // Copy from float case
std::vector<double> tmpdoubledata(sz);
// In the case of ucd mesh, and on multiple proc,
@@ -838,9 +854,6 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData>
// localGid range;
// basically, we have to give a different point
// for data to start, for every subrange :(
- size_t nbDims = vdatas[i].readStarts[t].size();
-
- // Assume that the last dimension is for the nVertLevels
size_t indexInDoubleArray = 0;
size_t ic = 0;
for (Range::pair_iterator pair_iter = pLocalGid->pair_begin();
@@ -848,11 +861,11 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData>
pair_iter++, ic++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second; // Inclusive
- vdatas[i].readStarts[t][nbDims - 2] = (NCDF_SIZE) (starth - 1);
- vdatas[i].readCounts[t][nbDims - 2] = (NCDF_SIZE) (endh - starth + 1);
+ vdatas[i].readStarts[1] = (NCDF_SIZE) (starth - 1);
+ vdatas[i].readCounts[1] = (NCDF_SIZE) (endh - starth + 1);
success = NCFUNCAG(_vara_double)(_fileId, vdatas[i].varId,
- &(vdatas[i].readStarts[t][0]), &(vdatas[i].readCounts[t][0]),
+ &(vdatas[i].readStarts[0]), &(vdatas[i].readCounts[0]),
&(tmpdoubledata[indexInDoubleArray]));
ERRORS(success, "Failed to read double data in loop");
// We need to increment the index in double array for the
diff --git a/src/io/ReadNC.hpp b/src/io/ReadNC.hpp
index c452716..67e2aa3 100644
--- a/src/io/ReadNC.hpp
+++ b/src/io/ReadNC.hpp
@@ -111,21 +111,21 @@ private:
class VarData
{
public:
- VarData() : varId(-1), numAtts(-1), entLoc(ENTLOCSET), numLev(1), sz(0), has_t(false) {}
+ VarData() : varId(-1), numAtts(-1), entLoc(ENTLOCSET), numLev(1), sz(0), has_tsteps(false) {}
int varId;
int numAtts;
nc_type varDataType;
std::vector<int> varDims; // The dimension indices making up this multi-dimensional variable
std::map<std::string, AttData> varAtts;
std::string varName;
- std::vector<Tag> varTags; // One tag for each time step, varTags[t]
+ std::vector<Tag> varTags; // Tags created for this variable, e.g. one tag per timestep
std::vector<void*> varDatas;
- std::vector<std::vector<NCDF_SIZE> > readStarts; // Start value for this [t][dim]
- std::vector<std::vector<NCDF_SIZE> > readCounts; // Number of data values for this [t][dim]
+ std::vector<NCDF_SIZE> readStarts; // Starting index for reading data values along each dimension
+ std::vector<NCDF_SIZE> readCounts; // Number of data values to be read along each dimension
int entLoc;
int numLev;
int sz;
- bool has_t;
+ bool has_tsteps; // Indicate whether timestep numbers are appended to tag names
};
ReadUtilIface* readMeshIface;
@@ -135,7 +135,7 @@ private:
//! Get all global attributes in the file
ErrorCode get_attributes(int var_id, int num_atts, std::map<std::string, AttData>& atts,
- const char *prefix = "");
+ const char* prefix = "");
//! Get all dimensions in the file
ErrorCode get_dimensions(int file_id, std::vector<std::string>& dim_names, std::vector<int>& dim_lens);
Repository URL: https://bitbucket.org/fathomteam/moab/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the moab-dev
mailing list