Source code for pysteg.sql.features

#! /usr/bin/env python
## -*- coding: utf-8 -*-
## (C) 2012: Hans Georg Schaathun <georg@schaathun.net> 

"""
This modules provide functions to define new features, feature
vectors, and feature sets, including feature level fusion.
The functions :func:`fsconfig` and :func:`fvconfig` read 
definitions from a config file and enter them into the database.
"""

import ConfigParser 
from . import *
from pysteg.features import *

__all__ = [ "fsconfig", "fvconfig" ] 


def getFeatureCollection(key):
   """Look up a feature collection by key.  If the key is itself
   an SQLObject, this is returned as is.  Otherwise, the FeatureVector
   object is tried first, and then the FeatureSet table.  At last,
   the Feature table is checked, and if the key matches a feature,
   this is returned as a singleton list."""
   if isinstance(key,SQLObject):
      return key
   try:
      return FeatureVector.byKey( key )
   except:
      pass
   try:
      return FeatureSet.byKey( key )
   except:
      return [ Feature.byKey( key ) ]
   return f

def _idxgen(T,d):
   R = range(-T,T+1)
   if d == 1: return [ (i,) for i in R ]
   else:
      return [ x + (i,) for x in _idxgen(T,d-1) for i in R ]

def _add2d(fs,x,y):
   L = [ fs.key + "(%s,%s)" % (i,j) for i in range(x) for j in range(y) ]
   for key in L:
      Feature( cat=fs, key=key )
   return 

def addmatrix(fs,limit,dim):
   if dim == 1: return _add1d(fs,limit)
   if dim == 2: return _add2d(fs,limit,limit)
   raise TypeError, "Undefined dimension %s (%s)" % ( dim, type(dim) )

def _addsym(fs,T,d):
   for idx in _idxgen(T,d):
      key = fs.key + str(idx).replace(" ","")
      Feature( cat=fs, key=key )
   return
def _add1d(fs,N):
   for i in xrange(N):
      Feature( cat=fs, key=fs.key+"(%s)" % (i,) )
   return

def _addNames(fs,l):
   for n in l:
      Feature( cat=fs, key=n )
   return

[docs]def fsconfig( fn ): """ Define feature sets based on a config file with the given filename fn. """ cfg = ConfigParser.SafeConfigParser( ) cfg.read( fn ) for s in cfg.sections(): kw = { "key" : s } kw["func"] = cfg.get(s,"func") try: kw["description"] = cfg.get(s,"description") kw["jpeg"] = eval(cfg.get(s,"jpeg")) except ConfigParser.NoOptionError: pass scheme = cfg.get(s,"scheme") if scheme == "named": kw["matrix"] = False kw["symidx"] = False addFeatures = lambda : _addNames(fs,eval(kw["func"])(None)) elif scheme == "2d": kw["matrix"] = True kw["symidx"] = False (x,y) = eval(cfg.get(s,"limit")) addFeatures = lambda : _add2d(fs,x,y) elif scheme == "matrix": kw["matrix"] = True kw["symidx"] = False limit = eval(cfg.get(s,"limit")) dim = eval(cfg.get(s,"dimension")) addFeatures = lambda : addmatrix(fs, limit, dim) elif scheme == "sym": kw["matrix"] = True kw["symidx"] = True limit = eval(cfg.get(s,"limit")) dim = eval(cfg.get(s,"dimension")) addFeatures = lambda : _addsym(fs,limit,dim) else: raise ConfigError, "Unknown scheme" try: fs = FeatureSet( **kw ) except Exception as e: print type(e) print e print "Not allowed to add FeatureSet", kw["key"] pass else: addFeatures() return
[docs]def fvconfig( fn ): """ Define feature vectors based on a config file with the given filename fn. """ cfg = ConfigParser.SafeConfigParser( ) cfg.read( fn ) for s in cfg.sections(): kw = { "key" : s } features = None for o in cfg.options(s): if o == "features": features = cfg.get(s,o).split() elif o == "dim": kw["dim"] = int(cfg.get(s,o)) else: kw[o] = cfg.get(s,o) if features == None: raise ConfigError, "No features defined." try: fv = FeatureVector( **kw ) except Exception as e: print type(e) print e print "Not allowed to add FeatureVector", kw["key"] pass else: for fkey in features: if fkey == "": continue fs = getFeatureCollection(fkey) for f in fs: fv.addFeature(f) return