[Kst] branches/work/kst/portto4/kst/src/datasources/netcdf

Nicolas Brisset nicolas.brisset at eurocopter.com
Tue May 21 21:24:03 UTC 2013


SVN commit 1355983 by brisset:

Implement automatic "unpacking" of netCDF vectors of type ncShort if they have
scale_factor and add_offset attributes, as per the convention described
in:
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf/Attribute-Conventions.html

Leveraging all the metadata already implemented, this approach is much
more efficient and takes much less code than the one originally
proposed. And it seems to work very well.

Thanks to Patrick R. for the idea, and the code even though in the end
it was easier to rewrite it differently.

I still have to think about the other part of the patch (matrix
components as vectors)...


 M  +17 -2     netcdfsource.cpp  


--- branches/work/kst/portto4/kst/src/datasources/netcdf/netcdfsource.cpp #1355982:1355983
@@ -496,20 +496,35 @@
 
   bool oneSample = n < 0;
   int recSize = var->rec_size();
-
+  double add_offset = 1.0, scale_factor = 1.0;
   switch (dataType) {
     case ncShort:
       {
+        // Check for special attributes add_offset and scale_factor indicating the use of the convention described in
+        // <http://www.unidata.ucar.edu/software/netcdf/docs/netcdf/Attribute-Conventions.html>
+        bool packed = iv->metaScalars(field).contains("add_offset") && iv->metaScalars(field).contains("scale_factor");
+        if (packed) {
+          // Get the values into local vars
+            add_offset = iv->metaScalars(field)["add_offset"];
+            scale_factor = iv->metaScalars(field)["scale_factor"];
+        }
         if (oneSample) {
           record = var->get_rec(s);
-          v[0] = record->as_short(0);
+          v[0] = packed ? record->as_short(0)*scale_factor+add_offset : record->as_short(0);
           delete record;
         } else {
           for (int i = 0; i < n; i++) {
             record = var->get_rec(i+s);
+              if (packed) {
             for (int j = 0; j < recSize; j++) {
+                  v[i*recSize + j] = record->as_short(j)*scale_factor+add_offset;
+                }
+              }
+              else {
+                for (int j = 0; j < recSize; j++) {
               v[i*recSize + j] = record->as_short(j);
             }
+              }
             delete record;
           }
         }


More information about the Kst mailing list