Fix JPK list field splitting for empty lists.
[hooke.git] / hooke / driver / jpk.py
index 760d9f1709f2f04d17a4b2c2309626204a1eeb0a..afa95704251c9fbb7a8ed214b726a38a2d45b55e 100644 (file)
@@ -85,8 +85,12 @@ class JPKDriver (Driver):
         curve_info = self._zip_translate_params(
             zip_info, segments[0].info['raw info'], version)
         for segment in segments:  # HACK, should use curve-level spring constant
-            segment.info['spring constant (N/m)'] = \
-                curve_info['spring constant (N/m)']
+            for key in ['spring constant (N/m)',
+                        'z piezo sensitivity (m/V)']:
+                if key in curve_info:
+                    segment.info['spring constant (N/m)'] = \
+                        curve_info['spring constant (N/m)']
+            
         return (segments, curve_info)
 
     def _zip_info(self, zipfile):
@@ -199,20 +203,26 @@ class JPKDriver (Driver):
             'raw info':params,
             #'time':self._time_from_TODO(raw_info[]),
             }
-        force_unit = self._zip_segment_conversion_unit(
-            chan_info['channel']['vDeflection']['conversion-set']['conversion']['force'],
+        if len(chan_info['channels']['list']) == 0:
+            return info
+        force_unit = self._zip_unit(
+            chan_info['channel']['vDeflection']['conversion-set']['conversion']['force']['scaling'],
             version)
         assert force_unit == 'N', force_unit
         force_base = chan_info['channel']['vDeflection']['conversion-set']['conversion']['force']['base-calibration-slot']
         assert force_base == 'distance', force_base
-        dist_unit = self._zip_segment_conversion_unit(
-            chan_info['channel']['vDeflection']['conversion-set']['conversion']['distance'],
+        dist_unit = self._zip_unit(
+            chan_info['channel']['vDeflection']['conversion-set']['conversion']['distance']['scaling'],
             version)
         assert dist_unit == 'm', dist_unit
         distance_base = chan_info['channel']['vDeflection']['conversion-set']['conversion']['distance']['base-calibration-slot']
         assert distance_base == 'volts', distance_base
-        # Assume volts unit is V, but it is not specified in the JPK
-        # file format.
+        base_conversion = chan_info['channel']['vDeflection']['conversion-set']['conversions']['base']
+        assert base_conversion == distance_base, base_conversion
+        distance_base_unit = self._zip_unit(
+            chan_info['channel']['vDeflection']['data'],
+            version)
+        assert distance_base_unit == 'V', distance_base_unit
         force_mult = float(
             chan_info['channel']['vDeflection']['conversion-set']['conversion']['force']['scaling']['multiplier'])
         sens_mult = float(
@@ -278,12 +288,11 @@ class JPKDriver (Driver):
         if conversion == None:
             conversion = conversion_set['conversions']['default']
         if conversion == conversion_set['conversions']['base']:
-            # Our conversion is the base data.
-            if conversion != 'volts':
-                raise NotImplementedError(
-                    'unknown units for base channel: %s' % conversion)
             segment.info['columns'][channel] = join_data_label(
-                channel_name, 'V')
+                channel_name,
+                self._zip_unit(
+                    segment.info['raw info']['channel'][channel_name]['data'],
+                    version))
             return segment
         conversion_info = conversion_set['conversion'][conversion]
         if conversion_info['base-calibration-slot'] \
@@ -312,16 +321,16 @@ class JPKDriver (Driver):
             conversion_info['scaling']['style']
         multiplier = float(conversion_info['scaling']['multiplier'])
         offset = float(conversion_info['scaling']['offset'])
-        unit = self._zip_segment_conversion_unit(conversion_info, version)
+        unit = self._zip_unit(conversion_info['scaling'], version)
         segment[:,channel] = segment[:,channel] * multiplier + offset
         segment.info['columns'][channel] = join_data_label(channel_name, unit)
         return segment
 
-    def _zip_segment_conversion_unit(self, conversion_info, version):
+    def _zip_unit(self, conversion_info, version):
         if version in ['0.%d' % i for i in range(3)]:
-            return conversion_info['scaling']['unit']
+            return conversion_info['unit']
         else:
-            return conversion_info['scaling']['unit']['unit']
+            return conversion_info['unit']['unit']
 
     def _parse_params(self, lines):
         info = {}
@@ -340,7 +349,10 @@ class JPKDriver (Driver):
                         sub_info[s] = {}
                     sub_info = sub_info[s]
                 if setting[-1] == 'list':  # split a space-delimited list
-                    sub_info[setting[-1]] = fields[1].split(' ')
+                    if fields[1]:
+                        sub_info[setting[-1]] = fields[1].split(' ')
+                    else:
+                        sub_info[setting[-1]] = []
                 else:
                     sub_info[setting[-1]] = fields[1]
         return info