Use 'Indexes' to split MFP3D curves into blocks.
authorW. Trevor King <wking@drexel.edu>
Fri, 20 Aug 2010 13:49:31 +0000 (09:49 -0400)
committerW. Trevor King <wking@drexel.edu>
Fri, 20 Aug 2010 13:49:31 +0000 (09:49 -0400)
hooke/driver/mfp3d.py

index 39ea3d3..6d2cdc5 100644 (file)
@@ -71,10 +71,10 @@ class MFP3DDriver (Driver):
     
     def read(self, path, info=None):
         data,bin_info,wave_info = loadibw(path)
-        approach,retract,info = self._translate_ibw(data, bin_info, wave_info)
+        blocks,info = self._translate_ibw(data, bin_info, wave_info)
         info['filetype'] = self.name
         info['experiment'] = experiment.VelocityClamp
-        return ([approach, retract], info)
+        return (blocks, info)
      
     def _translate_ibw(self, data, bin_info, wave_info):
         if bin_info['version'] != 5:
@@ -93,28 +93,38 @@ class MFP3DDriver (Driver):
                 value = None
             note[key] = value
         bin_info['note'] = note
+
+        # Ensure a valid MFP3D file version.
         if note['VerDate'] not in ['80501.041', '80501.0207']:
             raise Exception(note['VerDate'])
             raise NotImplementedError(
                 '%s file version %s not supported (yet!)\n%s'
                 % (self.name, note['VerDate'], pprint.pformat(note)))
 
+        # Parse known parameters into standard Hooke format.
         info = {
             'raw info':{'bin':bin_info,
                         'wave':wave_info},
-            'time':wave_info['creationDate'],
+            'time':note['Seconds'],
             'spring constant (N/m)':float(note['SpringConstant']),
             'temperature (K)':self._temperature(note),
             }
-        # MFP3D's native data dimensions match Hooke's (<point>, <column>) layout.
-        approach = self._scale_block(data[:wave_info['npnts']/2,:], info, 'approach')
-        retract = self._scale_block(data[wave_info['npnts']/2:,:], info, 'retract')
-        return (approach, retract, info)
 
-    def _scale_block(self, data, info, name):
+        # Extract data blocks
+        blocks = []
+        indexes = [int(i) for i in note['Indexes'].split(',')]
+        assert indexes[0] == 0, indexes
+        for i,start in enumerate(indexes[:-1]):
+            stop = indexes[i+1]
+            blocks.append(self._scale_block(data[start:stop+1,:], info, i))
+
+        return (blocks, info)
+
+    def _scale_block(self, data, info, index):
         """Convert the block from its native format to a `numpy.float`
         array in SI units.
         """
+        # MFP3D's native data dimensions match Hooke's (<point>, <column>) layout.
         shape = 3
         # raw column indices
         columns = info['raw info']['bin']['dimLabels'][1]
@@ -130,6 +140,14 @@ class MFP3DDriver (Driver):
             dtype=numpy.float,
             info=copy.deepcopy(info)
             )
+
+        version = info['raw info']['bin']['note']['VerDate']
+        if version == '80501.041':
+            name = ['approach', 'retract', 'pause'][index]
+        elif version == '80501.0207':
+            name = ['approach', 'pause', 'retract'][index]
+        else:
+            raise NotImplementedError()
         ret.info['name'] = name
         ret.info['raw data'] = data # store the raw data