def test_getRowId(self): tid = self.create_table_with_data() ftc = FeatureTableConnection(client=self.cli, tableName=self.tableName) ftc.openTable(tid) self.assertEqual(ftc.getRowId(1), 0) self.assertEqual(ftc.getRowId(3), 2) self.assertEqual(ftc.getRowId(6), 3) self.assertEqual(ftc.getRowId(8), 1) self.assertIsNone(ftc.getRowId(1000))
class FeatureTable(object): def __init__(self, client, tableName): self.tc = FeatureTableConnection(client=client, tableName=tableName) self.versiontag = None def close(self): self.tc.close(False) @property def conn(self): return self.tc.conn def createTable(self, featureNames, version): """ Initialise an OMERO.table for storing features @param featureNames Either a mapping of feature names to feature sizes, or a list of single value feature names which can be parsed using parseFeatureName """ # Unparsed list or dict? if hasattr(featureNames, 'keys'): features = featureNames else: features = featureSizes(featureNames) colNames = sorted(features.keys()) desc = [(name, features[name]) for name in colNames] self.tc.createNewTable('id', desc) self.versiontag = getVersionAnnotation(self.conn, version) if not self.versiontag: self.versiontag = createVersionAnnotation(self.conn, version) addTagTo(self.conn, self.versiontag, 'OriginalFile', self.tc.tableId) # TODO: There's a bug or race condition somewhere which means this # annotation may be lost. Closing and reopening the table seems to # avoid this. tid = self.tc.tableId self.close() self.openTable(tid, version) def openTable(self, tableId, version=None): try: vertag = getVersion(self.conn, 'OriginalFile', tableId) if not vertag: raise WndcharmStorageError( 'Table id %d has no version tag' % tableId) if version is not None: assertVersionMatch(version, vertag, 'table:%d' % tableId) self.tc.openTable(tableId) self.versiontag = vertag return True except TableConnectionError as e: print "No table found: %s" % e return False def isTableCompatible(self, features): """ Check whether an existing table is compatible with this set of features, that is whether suitable columns exist @return true if this set of features can be stored in this table """ cols = self.tc.getHeaders() colMap = dict([(c.name, c) for c in cols]) featSizes = featureSizes(features.names) for (ft, sz) in featSizes.iteritems(): if (ft not in colMap or colMap[ft].size != sz): print '%s [%d] is incompatible' % (ft, sz) return False return True def tableContainsId(self, id): """ Check whether this ID is already present in the table """ return self.tc.getRowId(id) is not None def saveFeatures(self, id, features): """ Save the features to a table @param features an object with field names holding a list of single value feature names, and values holding a list of doubles corresponding to names """ cols = self.tc.getHeaders() colMap = dict([(c.name, c) for c in cols]) cols[0].values = [id] for (name, value) in izip(features.names, features.values): ft, idx = parseFeatureName(name) col = colMap[ft] if not col.values: col.values = [[float('nan')] * col.size] col.values[0][idx] = value self.tc.addData(cols) def loadFeatures(self, id): """ Load features for an object from a table @return a (names, values) tuple where names is a list of single value features and value are the corresponding feature values """ r = self.tc.getRowId(id) # Skip the first id column colNumbers = range(1, len(self.tc.getHeaders())) cols = self.tc.readArray(colNumbers, r, r + 1) names = [] values = [] for col in cols: names.extend([createFeatureName(col.name, x) for x in xrange(col.size)]) values.extend(col.values[0]) return (names, values) def bulkLoadFeatures(self): """ Load features for all objects in a table @return a (names, values, ids) tuple where names is a list of single value features, values is a list of lists of the corresponding feature values and ids is a list of object IDs. In other words values[i] is the list of feature values corresponding to object with ID given by ids[i]. """ colNumbers = range(len(self.tc.getHeaders())) nr = self.tc.getNumberOfRows() cols = self.tc.readArray(colNumbers, 0, nr, CHUNK_SIZE) names = [] ids = cols[0].values for col in cols[1:]: names.extend([createFeatureName(col.name, x) for x in xrange(col.size)]) values = map(lambda *args: list(chain.from_iterable(args)), *[c.values for c in cols[1:]]) return (names, values, ids)