[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