<filename>sumo/tools/contributed/sumopy/agilepy/lib_base/base.py
"""
This package contains the base classes of al relevant classes.

TODO: Following issues must be resolved in the following version

- child  - parent - ident - named
    childs of named parents should have the name in the ident...and local ident
    create 2 ident entries for arrayobj: attr+id
    use a list for ident elements instead of a string wityh string conversion
    on the fly or permanently.
    May be of advantaqge (= fast) to store instances that are on the path of the 
    ident elements
    
    in particular: distiguish between an instance on the tree that is created with parent
    and an already initialized instance that is set and usd as a link.
    idea in this case get all confuguration info from instance itself
    or better link to it!
- ident should be a sequence or list of strings
- separate classes for array type objects
- classes for metatypes 
- try to reduce type recognition during init ?? 
- MIXIN for named operation just as for plugin
- make plugin faster by overwriting get/set attribute
- print attribute must also go in classes


- make common initialization priciples in particular for classes based on mixins
  who sets the name: the parent! name is option with default
-  simplify configurationwith key setting...should appear only once 
   try to catch it from within the object with __name__
- try to remove stored type identification...careful problems are nd scalars

"""
from numpy import *
# from numpy.oldnumeric.user_array import numpy.oldnumeric.user_array as
# UserArray
from copy import copy, deepcopy

from sys import exit
import types
import string
import pickle
#import networkx as nx

try:
    flatnonzero
except:
    def flatnonzero(x):
        return nonzero(x.ravel())

CONFIG_TEMPLATE = {
    'info': '',
            'doc': '',
            'metatype': '',
            'type': '',
            'group': [],
            'save': True,
            'copy': False,
            'struct': 'scalar',
            'perm': 'w',
            'unit': '',
            'do_init_arrayobj': False,
}

ARRAYTYPES = [types.TupleType, ndarray, types.ListType, types.XRangeType]

TYPES = {
    'BooleanType': {'dtype': '?', 'perm': 'w', },
    'BufferType': {'dtype': 'O', 'perm': 'r', },
    'BuiltinFunctionType': {'dtype': 'O', 'perm': 'r', },
    'BuiltinMethodType': {'dtype': 'O', 'perm': 'r', },
    'ClassType': {'dtype': 'O', 'perm': 'r', },
    'CodeType': {'dtype': 'O', 'perm': 'r', },
    'ComplexType': {'dtype': 'D', 'perm': 'w', },
    'DictProxyType': {'dtype': 'O', 'perm': 'r', },
    'DictType': {'dtype': 'O', 'perm': 'r', },
    'DictionaryType': {'dtype': 'O', 'perm': 'r', },
    'EllipsisType': {'dtype': 'O', 'perm': 'r', },
    'FileType': {'dtype': 'O', 'perm': 'w', },
    'FloatType': {'dtype': 'd', 'perm': 'w', },
    'FrameType': {'dtype': 'O', 'perm': 'r', },
    'FunctionType': {'dtype': 'O', 'perm': 'r', },
    'GeneratorType': {'dtype': 'O', 'perm': 'r', },
    'InstanceType': {'dtype': 'O', 'perm': 'r', },
    'IntType': {'dtype': 'i', 'perm': 'w', },
    'LambdaType': {'dtype': 'O', 'perm': 'r', },
    'ListType': {'dtype': 'O', 'perm': 'r', },
    'LongType': {'dtype': 'g', 'perm': 'w', },
    'MethodType': {'dtype': 'O', 'perm': 'r', },
    'ModuleType': {'dtype': 'O', 'perm': 'r', },
    'NoneType': {'dtype': 'O', 'perm': 'r', },
    'NotImplementedType': {'dtype': 'O', 'perm': 'r', },
    'ObjectType': {'dtype': 'O', 'perm': 'r', },
    'SliceType': {'dtype': 'O', 'perm': 'r', },
    'StringType': {'dtype': 'S', 'perm': 'w', },
    'StringTypes': {'dtype': 'O', 'perm': 'w', },
    'TracebackType': {'dtype': 'O', 'perm': 'r', },
    'TupleType': {'dtype': 'O', 'perm': 'r', },
    'TypeType': {'dtype': 'O', 'perm': 'r', },
    'UnboundMethodType': {'dtype': 'O', 'perm': 'r', },
    'UnicodeType': {'dtype': 'U', 'perm': 'w', },
    'XRangeType': {'dtype': 'O', 'perm': 'r', },
    '__builtins__': {'dtype': 'O', 'perm': 'r', },
    '__doc__': {'dtype': 'O', 'perm': 'r', },
    '__file__': {'dtype': 'O', 'perm': 'r', },
    '__name__': {'dtype': 'O', 'perm': 'r', },
}

IDENTSEP = '.'


def make_arrays(**attrs):
    """
    Makes an array of same type from all attributes in attrs dictionary
    A bit slow! Avoid using this function!
    """
    for attr in attrs.keys():
        obj = attrs[attr]
        if type(attrs[attr]) == ndarray:
            attrs[attr] = attrs[attr].reshape((1,) + obj.shape)
        elif type(obj) in (types.FloatType, types.LongType):
            attrs[attr] = array([obj], float)
        elif type(obj) == types.IntType:
            attrs[attr] = array([obj], int)
        elif type(obj) == types.BooleanType:
            attrs[attr] = array([obj], bool)
        else:
            # another strange type
            dt = 'O'
            for typename in dir(types):
                if type(obj) == types.__dict__[typename]:
                    dt = get_dtype(typename)
                    break
            attrs[attr] = array([obj], dtype=dt)
    return attrs


def is_integer(n):
    """
    Returns True if n is an integer type of any kind
    """
    return type(n) in (types.IntType, int32, int64, int0, int16, int8, types.LongType)


def get_type(obj, typelist=[]):
    """
    Returns a flat list of type-string(s) which correspond to the
    (nested) type(s) of  the object obj.

    The returned type(s)  are keys of the global TYPES dictionary.
    """

    typelist = copy(typelist)
    if type(obj) == ndarray:
        typelist.append(('ArrayType', obj.shape))
        # return typelist # let's assume homogenious array types
        if len(obj.ravel()) > 0:
            return get_type(obj.flat[0], typelist)
        else:
            return typelist

    elif hasattr(obj, 'dtype'):  # obj is an array element
        # attention this is not a string but maybe this should
        # also be changed for all other types
        typelist.append(obj.dtype.str)
        return typelist

    elif type(obj) in (types.ListType, types.TupleType):
        typelist.append('ListType')
        if obj:
            return get_type(obj[0], typelist)
        else:
            return typelist

    elif type(obj) in (types.DictType, types.DictionaryType):

        if obj:
            key = obj.keys()[0]
            keytype = get_type(key)
            if len(keytype) > 0:
                typelist.append(('DictType', keytype[0]))
            else:
                typelist.append(('DictType', ''))

            return get_type(obj[key], typelist)
        else:
            typelist.append(('DictType', ''))
            return typelist

    else:
        for typename in dir(types):
            if type(obj) == types.__dict__[typename]:
                typelist.append(typename)
                return typelist
                break
        typelist.append('')
        return typelist


def get_dtype(type):
    """
    Returns dtype as used in Nummeric package.
    The argument is a string defining the python objecy type
    and is a key of the TYPES dictionary.
    If type is not found in the dictionary, dtype 'O' is
    returned, which means a generic object.
    """
    if TYPES.has_key(type):
        return TYPES[type]['dtype']
    else:
        return 'O'


def save_obj(obj, filename):
    """
    Saves python object to a file with filename.
    Filename may also include absolute or relative path.
    If operation fails a False is returned and True otherwise.
    """
    try:
        file = open(filename, 'wb')
    except:
        print 'WARNING in save: could not open', simname
        return False

    # try:
    pickle.dump(obj, file, protocol=2)
    file.close()
    return True
    # except:
    #    file.close()
    #    print 'WARNING in save: could not pickle object'
    #    return False


def load_obj(filename, parent=None):
    """
    Reads python object from a file with filename and returns object.
    Filename may also include absolute or relative path.
    If operation fails a None object is returned.
    """
    print 'load_obj', filename
    try:
        file = open(filename, 'rb')
    except:
        print 'WARNING in load_obj: could not open', filename
        return None

    # try:
    # print '  pickle.load...'
    obj = pickle.load(file)
    file.close()
    # print '  obj._link2'

    # _init2_ is to restore INTERNAL states from INTERNAL states
    obj._init2_config()

    # _init3_ is to restore INTERNAL states from EXTERNAL states
    # such as linking
    obj._init3_config()

    # _init4_ is to do misc stuff when everything is set
    obj._init4_config()

    return obj

    # except:
    #	print 'WARNING in load: could not load object'
    #	return None


def is_objconfigured(obj):
    return hasattr(obj, 'init_config')


class ArrayObj:

    """
    Mixin for Classes or Instance which are used as array-element 
    within the framework of the ArrayObjConfigurator.

    Its main function is init_arrayobj where an id gets assigned
    which corresponds to the id of the element in the parent array.

    Also __getitem__ and __setitem__ functions are implemented through which 
    array elements with the same id of other attributes of the parent object 
    can be read and changed.
    """

    def init_arrayobj(self, id, parent, ident, **args):
        """
        Initialize by defining parent instance where all the
        attributes of this instance are stored in array form.
        Also define the id of the array coresponding to this instance. 

        Function will be called automatically from ArrayObjConfigurator
        when id is assigned.

        """
        self.parent = parent
        # if ident=='':
        #    ident=parent.ident+IDENTSEP+str(id)
        # else:
        self.ident = ident
        self.id = id
        self.config_with_id()
        # print 'init_arrayobj',self.ident,id#,parent

    def config_with_id(self):
        """
        Here the instance can be inizialized..
        Function called AFTER  self.id and self.parent have been assigned.
        """
        pass

    def copy_attrs(self, targetobj, attrs=None):
        """
        Copies  given list of attributes of this object 
        to given target object.

        If no attributes are given then all attributes of this object 
        are considered for copying.

        Clearly, the array attributes corresponding to the id of this
        object are copied to the array attributes of the arrays 
        with the id of the target object.

        To copy an attribute, the foolowing conditions must be satisfied:
            - the attribute must be configured with key copy=True
            - the attribute must be configured in targetobject 

        """
        self.parent.copy_attrs(targetobj, self.id, targetobj.id, attrs=attrs)

    def __getitem__(self, key):
        return self.getparent(key)

    def __setitem__(self, key, value):
        self.setparent(key, value)

    def setparent(self, key, value):
        """
        Sets entry with id of this instance of the attribute 'key' of parent object.

        Usage:
            self['attributename']=value  


        """
        # print key,value
        self.parent[key, self.id] = value

    def getparent(self, key):
        """
        Gets entry with id of this instance of the attribute in parent object.

        Usage:
            self['attributename']  
        """
        # print 'ArrayObject.__getitem__',key
        return self.parent[key, self.id]

    def get_groupattrs_obj(self, name):
        """
        Returns a dictionary with all attributes of a group with given name. 
        Key is attribute name and value is attribute value for the given id. 
        """
        # print 'get_groupattrs_obj',name,self.id
        return self.parent.get_groupattrs(name, self.id)


class PlugoutMixin:

    """
    Mixin to provide methods to plug  callback functions into other objects.
    """

    def init_plugout(self):
        """
        Initialize basic plugout variables
        """
        # dictionary with pluginobj as key and list with plugids
        # provided by obj as value
        self._plugoutobjs = {}

    def add_plugout(self, obj, plugtype, function, attr='_all'):
        """
        Make a plugin to object and retain plugin id for later unplugg.

        Standard plug types are automatically set bu the system:
        plugtype    plugcode
        'del'       0
        'set'       1
        'get'       2
        'add'       3

        'del_items' 20
        'set_items' 21
        'get_items' 22
        'add_items' 23



        """
        if not self._plugoutobjs.has_key(obj):
            self._plugoutobjs[obj] = []
        # make plugin to object
        plugid = obj.add_plugin(obj, plugtype, function, attr)

        # add plugginid of obj to list
        self._plugoutobjs[obj].append(plugid)

        return plugid

    def del_plugout(self, obj, plugid=-1):
        """
        Plug out from specified object.
        If plugid is specified, only this plug is pulled,
        otherwise all plugs to this object are pulled at once.
        """
        if self._plugoutobjs.has_key[obj]:
            if plugid < 0:
                if self._plugoutobjs[obj].count(plugid) > 0:
                    obj.del_plugin(plugid)
                    self._plugoutobjs[obj].remove(plugid)
            else:
                for plugids in self._plugoutobjs[obj]:
                    obj.del_plugin(plugid)
                del self._plugoutobjs[obj]
        else:
            print 'WARNING: no plugout ids for object', obj
            plugids = []

    def unplugout(self):
        """
        Unplug all plugs on other objects
        """
        for obj in self._plugoutobjs.keys():
            self.del_plugout(obj)


class PluginMixin:

    """
    Mixin to provide methods to plug in callback functions
    from other objects.
    """

    def init_plugin(self):
        """
        Initialize basic plugin variables
        """
        # self._plugins={} # compulsory in configurator!
        self._counter_plugid = 0

        self._plugcode = {'test': -1}
        # print 'init_plugin',self.ident,self._plugcode

        # dictionary with obj as key and dict with plugid,plugtype,attr as
        # value
        self._pluginobjs = {}

        # add basic plugincodes
        # for scalars
        self.add_plugcodes([('del', 0), ('set', 1), ('get', 2), ('add', 3)])

        if hasattr(self, 'get_ids'):
            # print '  add_plugcodes arrays for ',self.ident
            self.add_plugcodes([('del_items', 20),
                                ('set_items', 21),
                                ('get_items', 22),
                                ('add_items', 23), ])
        self.enable_plugins()

    def execute_plugin(self, plugtype):
        """
        Execute all callbacks for the plugin of the given type
        """
        self._execute_plugins(self._plugcode[plugtype], attr='_all')

    def add_plugcodes(self, plugcodes):
        """
        Plugcodes integers that correspond to a plugtype.
        These integers are used as keys for faster access.

        Argument plugcodes is a list with tuples 
        each tuple containing plugtype and plugcode.

        Standard plug types are automatically set bu the system:
        plugtype    plugcode
        'del'       0
        'set'       1
        'get'       2
        'add'       3

        'del_items' 20
        'set_items' 21
        'get_items' 22
        'add_items' 23

        """
        # print 'add_plugcodes',plugcodes
        for plug, plugcode in plugcodes:
            if not self._plugcode.has_key(plug):
                self._plugcode[plug] = plugcode
                # self._plugins[plugcode]={'_all':{}}
                # print '  added
                # self._plugcode[plug]',plug,self._plugcode[plug]
            else:
                print 'WARNING:_add_plugcodes: already existant code',\
                    plug, self._plugcode[plug]
                print '  Refused to insert.'

    def add_plugin(self, obj, plug, callbackfunction, attr='_all'):
        # print 'add_plugin',plug,callbackfunction,attr
        self._counter_plugid += 1
        plugid = self._counter_plugid
        plugcode = self._plugcode[plug]

        if not self._plugins.has_key(plugcode):
            self._plugins[plugcode] = {}

        if not self._plugins[plugcode].has_key(attr):
            self._plugins[plugcode][attr] = {plugid: callbackfunction}
        else:
            self._plugins[plugcode][attr][plugid] = callbackfunction

        if not self._pluginobjs.has_key(obj):
            self._pluginobjs[obj] = {}

        self._pluginobjs[obj][plugid] = (plugcode, attr)
        return plugid

    def disable_plugins(self):
        """
        Prevents plugins from execution
        """
        self._enable_plugins = False

    def enable_plugins(self):
        """
        Enable plugins for execution
        """
        self._enable_plugins = True

    def del_plugin(self, obj, plugid=-1):
        """
        Remove plugin with pluginid
        """

        if plugid >= 0:
            plugids = [plugid]
        else:
            plugids = self._pluginobjs[obj].keys()

        if self._pluginobjs.has_key(obj):
            # there exist ids associated with this object
            for pid in plugids:
                if self._pluginobjs[obj].has_key(pid):
                    # remove plugin with pid
                    plugcode, attr = self._pluginobjs[obj][pid]
                    del self._plugins[plugcode][attr][pid]
                    del self._pluginobjs[obj][pid]

                    if len(self._plugins[plugcode][attr]) == 0:
                        # no more plugins for this attribute...remove it
                        del self._plugins[plugcode][attr]
                        if len(self._plugins[plugcode]) == 0:
                            # np more plugins for this plugintype...remove it
                            del self._plugins[plugcode]

            if len(self._pluginobjs[obj]) == 0:
                # no more plugin ids associated with this object
                del self._pluginobjs[obj]


class ObjConfigurator:

    """
    Base mixin class for general scalar object configuration.

    Usage:

        During initialization of class call

        self.init_config('myclass_ident_string',name='my human readable class')

        or if there is a parent object availlable:

        self.init_config('myclass_ident_string',parent)

        In this case the ident of the parent obj is prependet



    """

    def init_config(self, ident='', parent=None, name='noname', **args):
        # print '---init_config ident',ident,hasattr(self,'init_plugin')
        # print '  parent',parent
        # print '  name',name,len(name)

        if hasattr(self, 'ident'):
            ident = self.ident

        if (name == 'noname') & (len(ident) > 0):
            self.name = ident
        elif (name == 'noname') & (len(ident) == 0):
            if self.__dict__.has_key('__name__'):
                ident = self.__name__  # use class name as identifier
            self.name = ident

        elif (len(name) > 0) & (len(ident) == 0):
            if self.__dict__.has_key('__name__'):
                ident = self.__name__  # use class name as identifier
            self.name = name
        else:
            self.name = name

        self.ident = ident
        self.parent = parent
        if parent != None:

            # print 'init_config',ident,parent.ident
            # present object is a child of a parent
            # => prepend parent identifier string
            if hasattr(parent, 'ident'):
                self.ident = parent.ident + IDENTSEP + ident

        self._config = {}
        self._groups = {}
        self._functions = []

        # define a list with attribute strings that need to be saved
        # apart from the cofigured attributes
        # this list may be extended by successive initializations
        self._attrs_save = [  # 'parent',
            'name', 'ident', '_config', '_groups',
            '_functions',
        ]

        # conditional plugin import
        self._init_plugging()

        # print 'Created configuration for',self.ident

        return self.ident

    def reset_parent(self, parent):
        """
        Resets previously assigned parent.
        This method is not used during initialization.  
        """
        ident = self.get_ident(is_local=True)
        self.parent = parent
        if parent != None:
            # print 'init_config',ident,parent.ident
            # present object is a child of a parent
            # => prepend parent identifier string
            if hasattr(parent, 'ident'):
                self.ident = parent.ident + IDENTSEP + ident

    def get_ident(self, is_local=False):
        """
        Returns identity string.
        By default it returns the entire identity string
        unless is_local==True. In this case only the local, the last
        element of the global identity is returned.
        """
        if is_local:
            return string.split(self.ident, IDENTSEP)[-1]
        else:
            return self.ident

    def _link(self, parent=None):
        """
        Called after load process to link with other instances 
        in the environment.
        """

        # self.parent=parent
        # for attr in self._config.keys():
        #    obj=getattr(self,attr)
        #    if is_objconfigured():
        #        obj._link(self)
        pass

    def _init2_config(self):
        """
        Called after load and link process to do make initializations
        of constants, dependent INTERNAL attributes such as hash tables, 
        NO LINKS OR DEPENDENCIES TO EXTERNAL INSTANCES ALLOWED

        Here only the configurator internal attributes are restored.
        All object specific in _init2() in 
        """
        print '\n _init2_config', self.ident

        print '  restore unsaved attributes', self.ident
        self._functions = []
        for attr in self._config.keys():

            # check
            # if hasattr(self,attr):
            #    value=getattr(self,attr)
                # print '  attr',attr,
                # if type(value)==ndarray:
                #    print value.dtype,value.shape
                # else:
                #    print value

            config = self._config[attr]
            if config['is_function']:
                # print '    resore function',attr
                self._functions.append(attr)
            elif not config['save']:
                # print '    resore attr',attr
                self.reset(attr)
            # check
            # value=getattr(self,attr)
            # print '  after: attr',attr,
            # if type(value)==ndarray:
            #    print value.dtype,value.shape
            # else:
            #    print value

        # conditional plugin import
        self._init_plugging()

        print '  call _init2', self.ident

        self._init2()

        print '  restore children', self.ident
        for attr in self._config.keys():
            config = self._config[attr]
            if (config['save']) & (not config['is_function']):
                if config['struct'] == 'scalar':
                    obj = getattr(self, attr)
                    if is_objconfigured(obj):
                        print '    call _init2_config of', obj.ident
                        obj._init2_config()
                else:
                    # attribute is an array so init here for arrays as well
                    # TODO: should go as special in arrayconfigurator
                    for id in self.get_ids():
                        obj = self[attr, id]
                        if is_objconfigured(obj):
                            print '    call _init2_config of', obj.ident
                            obj._init2_config()

    def _init2(self):
        """
        Called after load  process to do make initializations
        of constants, dependent INTERNAL attributes such as hash tables, 
        NO LINKS OR DEPENDENCIES TO EXTERNAL INSTANCES ALLOWED

        To be overridden.
        """
        pass

    def _init3_config(self):
        """
        Called after load and link process to do make initializations
        of constants, dependent attributes such as hash tables, 
        links to external instances etc.

        """
        print '\n_init3_config', self.ident
        # link with other, now already initialized objects
        # Those attributes which have NOT been saved, but have
        # an ident in they configuration can no be recovered
        # though their ident
        for attr in self._config.keys():
            config = self._config[attr]

            if config.has_key('link'):
                # try to recover object with ident

                if config['link']:

                    if config['struct'] in ('array', 'dict', 'marray'):
                        print '   detected link array ', attr
                        # here we want to recover links to objects
                        # using a dictionary with
                        # id as key and ident as value
                        for id in self.get_ids():
                            self[attr, id] = self.get_obj_instance(
                                config['ident'][id])

                    else:
                        print '   detected link ', attr
                        setattr(self, attr, self.get_obj_instance(
                            config['ident']))

        # make specific settings
        self._init3()

        # print '  restore children',self.ident
        for attr in self._config.keys():
            config = self._config[attr]
            if (config['save']) & (not config['is_function']):
                if config['struct'] == 'scalar':
                    obj = getattr(self, attr)
                    if is_objconfigured(obj):
                        # print '    call _init3_config of',obj.ident
                        obj._init3_config()
                else:
                    # attribute is an array so init here for arrays as well
                    # TODO: should go as special in arrayconfigurator
                    for id in self.get_ids():
                        obj = self[attr, id]
                        if is_objconfigured(obj):
                            # print '    call _init3_config of',obj.ident
                            obj._init3_config()

    def _init3(self):
        """
        Called after load and internal link process to do make initializations
        of constants, dependent attributes such as hash tables, 
        links to external instances etc.

        To be overridden.
        """
        pass

    def _init4_config(self):
        """
        Called after load and link process to do make initializations
        any other initializations.

        """
        print '\n_init4_config', self.ident

        # make specific settings
        self._init4()

        # print '  restore children',self.ident
        for attr in self._config.keys():
            config = self._config[attr]
            if (config['save']) & (not config['is_function']):
                if config['struct'] == 'scalar':
                    obj = getattr(self, attr)
                    if is_objconfigured(obj):
                        # print '    call _init4_config of',obj.ident
                        obj._init4_config()
                else:
                    # attribute is an array so init here for arrays as well
                    # TODO: should go as special in arrayconfigurator
                    for id in self.get_ids():
                        obj = self[attr, id]
                        if is_objconfigured(obj):
                            # print '    call _init4_config of',obj.ident
                            obj._init4_config()

    def _init4(self):
        """
        Called after load and link process to do make initializations
        any other initializations.

        To be overridden.
        """
        pass

    def _init_plugging(self):
        """
        Initializes plugin and plugout related variables.
        This function is called during initialization 
        and after load, before reinitializeing other attrubutes. 
        """
        # print '_init_plugging',self.ident,self
        # if make_plugins:
        #    from PluginMixin import *
        if hasattr(self, 'init_plugin'):
            # print '  ini_plugin',self.ident,self
            self.init_plugin()

        if hasattr(self, 'init_plugout'):
            # print '  ini_plugout',self.ident
            self.init_plugout()
        # this plugin dictionary is always required and remains
        # empty if no plugins are made
        self._plugins = {}

    def _execute_plugins(self, plugcode, attr='_all', **args):
        """
        This method executes all callbackfunctions associated with the
        given plugcode.
        This funcion is a core part because used in various
        methods. All other methods regarding plugins in PluginMixin.
        """
        # it has been checked that self._plugins has all keys
        print '_execute_plugins', plugcode, ' for', self.ident, attr
        # print '  self._plugins=',self._plugins
        # print '  self._plugins[plugcode]=',self._plugins[plugcode]

        if self._enable_plugins:
            args['attr'] = attr
            if self._plugins[plugcode].has_key('_all'):
                for func in self._plugins[plugcode]['_all'].values():
                    # print '  => execute function',func
                    # print '     with args',args
                    func(**args)
            elif self._plugins[plugcode].has_key(attr):
                # selective plugin for specific attribute
                for func in self._plugins[plugcode][attr].values():
                    func(**args)
            # else:
            #    print '  no plugin functions for plugcode',plugcode

    def get_name():
        """
        Returns formatted name string of object.
        """
        return self.name

    def print_config(self):

        # print 'inds=',self._inds
        print '===================================================================='
        print '   Config of', self.name, ' with ident:', self.ident
        print '===================================================================='
        for attr in self._config.keys():
            self.print_attr(attr)

        # for name in self.get_groupnames():
        #    if self.get_group(name):
        #        print 'Group: ',name
        #        for attr in self.get_group(name):
        #            self.print_attr(attr)

        # print all attributes which are not in a group
        # print '--'
        # for attr in self._config.keys():
        #    if len(self._config[attr]['group'])==0:
        #        self.print_attr(attr)

    def print_attr(self, attr):
        # config=self.get_config(attr)
        # print '   ', attr,'=',self.__dict__[attr],config['unit']
        print '   ' + attr + ' = ' + self.get_string_attr_value(attr, self[attr])

    def print_attrattrs(self, attrs=None, attrattrs=['info', 'group', 'struct'], filename=None, sep='\t'):
        """
        Prints attributes of attributes.
        If 
        """
        # print 'print_attrattrs'
        lines = []
        if attrs == None:
            attrs = self._config.keys()
        attrs.sort()
        line = u'attr'
        for attrattr in attrattrs:
            line += sep + attrattr
        lines.append(line)

        for attr in attrs:
            # print '  attr',attr
            line = u'' + attr
            for attrsattr in attrattrs:
                if self._config[attr].has_key(attrsattr):
                    line += sep + str(self._config[attr][attrsattr])
                else:
                    line += sep + ''
            lines.append(line)

        if filename != None:
            file = open(filename, 'w')
            for line in lines:
                # print line
                file.write(line + '\n')
            file.close()
        else:
            for line in lines:
                print line

        return lines

    def get_string_attr_value(self, attr, value):
        """
        Returns a string with correctly formatted value of attribute.
        """
        # print '\n\nget_string_attr_value',attr,value,type(value)
        # print self.get_printformat(attr)+self.get_unit(attr)
        #print (self.get_printformat(attr)+self.get_unit(attr))%(value)
        config = self.get_config(attr)
        tt = config['type'][0]
        unit = self.get_unit(attr, show_parentesis=True)
        if tt in ('BooleanType',):
            if value:
                s = 'True'
            else:
                s = 'False'
            return s + self.get_unit(attr, show_parentesis=True)

        elif type(value) in ARRAYTYPES:
            # value is an array=> print signe items
            s = '['
            for v in value:
                s += self.get_string_attr_value(attr, v) + ','
            s += ']'
            return s

        else:
            try:
                return (self.get_printformat(attr)
                        + ' ' + self.get_unit(attr, show_parentesis=True)) % value
            except:
                print '\n WARNING could not print', attr, '=', value
                return 'Error'

    def get_printformat(self, attr):
        """
        Returnes the standad fortran stringformat for attribute.
        """
        config = self.get_config(attr)
        tt = config['type'][0]
        if tt in ('IntType', 'LongType'):
            return '%' + str(config['digits_integer']) + 'd'

        elif tt in ('FloatType', 'ComplexType'):
            return '%' + str(config['digits_integer']) + '.'\
                + str(config['digits_fraction']) + 'f'

        else:
            # its a string
            return '%s'

        return printformat

    def get_numformat(self, attr, confog=None):
        """
        Returns a dictionary with all formatting infos on attribute.
        It is tried to detect the numerical datatype and define
        formatting info, if not already defined.
        """
        # determine format of numeric value

        config = self.get_config(attr)

        # take top level type
        tt = config['type'][0]
        numformat = {}
        if tt in ('IntType', 'LongType'):
            numformat['digits_integer'] = config.get('digits_integer', 13)
            numformat['digits_fraction'] = config.get('digits_fraction', 0)
        else:
            numformat['digits_integer'] = config.get('digits_integer', 9)
            numformat['digits_fraction'] = config.get('digits_fraction', 8)

        numformat['min'] = config.get('min', None)
        numformat['max'] = config.get('max', None)

        # print 'get_numformat',attr,numformat
        return numformat

    def config(self, attr, default=None, **args):
        """
        Configure attribute for Object.
        """
        # print '\n\n\n'+70*'*'
        # print 'config',attr,default,args

        # configure attribute with template and parameters from args
        self._config[attr] = deepcopy(
            CONFIG_TEMPLATE)  # CONFIG_TEMPLATE.copy()

        # print '  after template configured attr:',attr,self._config[attr]

        # try to guess type...as default only
        t = get_type(default)
        self._config[attr]['type'] = t
        # print '  get_type(default)=',get_type(default)

        # guess read/write permissions according to toplevel type
        if TYPES.has_key(t[0]):
            self._config[attr]['perm'] = TYPES[t[0]]['perm']

        # default name
        self._config[attr]['name'] = attr

        if args.has_key('metatype'):
            # TODO: fetch here metatype info from metatype module
            pass
        else:
            self._config[attr]['metatype'] = ''  # default

        # overwrite all defaults with arguments
        self._config[attr].update(args)

        # print '  after update configured attr:',attr,self._config[attr]

        if type(self._config[attr]['type']) != types.ListType:
            self._config[attr]['type'] = [self._config[attr]['type']]

        # complete with numerical format info
        self._config[attr].update(self.get_numformat(attr))

        # store default value here,
        # in case of an array this is the value of a single entry
        self._config[attr]['default'] = default

        # check if attribute is an existing function and if yes register
        # as such in config
        self._config[attr]['is_function'] = False
        if hasattr(self, attr):
            if type(getattr(self, attr)) == types.MethodType:
                # print '  ',attr,'is a function'
                self._config[attr]['is_function'] = True
                # self._config[attr]['perm']='r' # read only

        if self._config[attr]['is_function']:
            # register attribute in function list
            self._functions.append(attr)
        else:
            self.reset(attr)

        # print '  configured attr:',attr,self._config[attr]

        # this turnes group argument in a list when given a signle string
        # TODO: would be better to introduce groups as a list with all group
        # names
        groupnames = self._config[attr]['group']
        if type(groupnames) == types.StringType:
            self._config[attr]['group'] = [groupnames, ]

        if (self._config[attr]['metatype'] == 'id'):
            # explictly declared as id
            # make sure of array structure
            self._config[attr]['struct'] = 'array'
            # TODO: better identify object as arrayobjconfiguaror

        # put attribute into id_ref or obj ref group
        # if no reference is made then put in id group
        if self._config[attr].has_key('ident_ref'):
            if self._config[attr]['struct'] == 'array':

                if 'id_ref' not in self._config[attr]['group']:
                    # print '  ident_ref detected id_ref for',attr
                    self._config[attr]['group'].append('id_ref')
                    self._config[attr]['metatype'] = 'id'
                    # print '  check template',CONFIG_TEMPLATE.copy()
            else:
                # print '  ident_ref detected obj_ref for',attr
                if 'obj_ref' not in self._config[attr]['group']:
                    self._config[attr]['group'].append('obj_ref')
                    self._config[attr]['metatype'] = 'obj'

        elif (self._config[attr]['metatype'] == 'id'):
            # and add it to id group
            if 'id' not in self._config[attr]['group']:
                self._config[attr]['group'].append('id')

        for groupname in self._config[attr]['group']:
            self.config_group(groupname, attr)

        # this is a treatment fo linked objects, which are
        # not a parent or a child of this objects
        # they ill not be saved, but recovered bu their ident during _init3
        if self._config[attr].has_key('link'):
            if self._config[attr]['link']:
                # try to recover object with ident
                # however, ident itself will only be stored during saving
                self._config[attr]['save'] = False
                self._config[attr]['perm'] = 'r'

    def reset(self, attr):
        """
        Reset atttribute attr to default values
        """
        # create attribute and if there are already arrays with entries,
        # create the same number of entries with default value
        # default=self._config[attr]['default']
        # struct=self._config[attr]['struct']

        # if self._config[attr]['is_function']:
        #    # register attribute in function list
        #    #self._functions.append(attr)
        #    # already done in config
        #    pass
        # else:
        # attr is a scalar , simply assign default
        if not self._config[attr]['is_function']:
            self.__dict__[attr] = self._get_default(attr)

    def set_default(self, attr, value):
        """
        Sets a default value for this attribute.
        """
        self._config[attr]['default'] = value

    def _get_default(self, attr):
        """
        Returns default value for attribute with name attr_name

        Usage:
            Return a scalar default 
            self._get_default('attr_name')    


        """
        default = self._config[attr]['default']
        # struct=self._config[attr]['struct']

        if type(default) == ndarray:
            obj = default  # .tolist()

        elif (type(default) == types.ClassType):
            if self._config[attr]['init']:
                # Default is a class, needs to be initialized
                # TODO: initialization and global id needs to be reviewed
                obj = default(self)

        else:
            # otherwise just copy default value
            obj = default

        # print '_get_default',obj
        return obj

    def set(self, attr, val=None):
        """
        Sets value to attribute.

        Usage:

        Set scalar variable var with value val
        self.set('var',val) 


        """

        if self._config['attr']['struct'] == 'scalar':  # exclude functions
            self.__dict__[attr] = val

        if self._plugins.has_key(1):
            self._execute_plugins(1, key)

    def is_config(self, attr):
        """
        Returns true if attribute with name attr is configured.
        """
        return self._config.has_key(attr)

    def copy_attrs(self, targetobj):
        """
        Copies  given list of scalar attributes of this object 
        to given target object.

        If no attributes are given then all attributes of this object 
        are considered for copying.

        copy an attribute, the foolowing conditions must be satisfied:
            - the attribute must be configured with key copy=True
            - the attribute must be configured in targetobject 
            - the structure of the attribute must be scalar 
                (arrays done by copy method of ArrayObjConfigurator)
        """
        if attrs == None:
            # get all attributes
            attrs = self._config.keys()

        for attr in attrs:
            config = self._config[attr]
            if config['struct'] == 'scalar':
                if config['copy']:
                    if targetobj.is_config(attr):
                        targetobj[attr] = self[attr]

    def get_attrs(self, crits_atleastone=[], crits_all=[]):
        """
        Returns list of configured attribute names.

        crits_atleastone and crits_all are lists defining one or several
        criteria that the attribute configuration must satify.
        for example: [('struct','array'),('struct','dict'),('struct','marray')]
        """
        attrs = []
        if len(crits_atleastone) > 0:
            # get attribute names for attributes where at least one criteria
            # is satisfied
            for attr in self._config.keys():
                for criteria in crits_atleastone:
                    # print 'get_attrs:',attr,criteria
                    if self._config[attr][criteria[0]] == criteria[1]:
                        attrs.append(attr)
                        break
            return attrs

        elif len(crits_all) > 0:
            # get attribute names for attributes where all criteria
            # are satisfied
            for attr in self._config.keys():
                satisfied = True
                for criteria in crits_all:
                    # print 'get_attrs:',attr,criteria
                    satisfied &= (self._config[attr][
                                  criteria[0]] == criteria[1])
                if satisfied:
                    attrs.append(attr)

            return attrs

        else:
            # no criteria spacified, return all attribute names
            return self._config.keys()

    def get_config(self, attr=''):
        # print '_get_config:',attr
        if attr:
            return self._config.get(attr, {})
        else:
            return self._config

    def get_root_instance(self):
        """
        Returns instance of root obj of the tree.
        """
        obj = self
        while obj.parent != None:
            obj = obj.parent

        return obj

    def get_obj_instance(self, ident):
        """
        Returns the instance of the object of the given identity string ident.

        The researched object must reside within the object tree where also
        the self object is a part.
        """
        if ident == '':
            return None

        elif ident[0] == '.':
            # ident starts with a . means that it is a relative link
            # starting with this object
            obj = self
            idents = string.split(self.get_ident(
                is_local=True) + ident, IDENTSEP)

        else:
            obj = self.get_root_instance()
            idents = string.split(ident, IDENTSEP)

        print 'get_obj_instance ', idents
        print '  root_instance=', obj
        if len(idents) == 1:
            # just one element identification, means this is root
            return obj

        elif idents[1] == '':
            return obj

        else:
            oldobj = obj
            oldident = ident
            for ident in idents[1:]:

                print '  get attr', ident, 'from obj', obj
                if ident.isdigit():  # it's an id so get arrayobject

                    print '    get it through object[attr,id]', oldobj, oldident, string.atoi(ident)
                    obj = oldobj[oldident, string.atoi(ident)]
                    oldobj = obj
                    oldident = ident

                elif ident == '':
                    oldobj = obj
                    # obj=obj # do not dive

                else:
                    oldobj = obj
                    oldident = ident
                    obj = getattr(obj, ident)

        return obj

    def create_group(self, name, attr_list=[]):
        # print 'create_group',name,attr_list
        if type(attr_list) == types.ListType:
            # print '  groups before=',self._groups.keys()
            self._groups[name] = attr_list
            # print '  groups after =',self._groups.keys()
        else:
            print 'WARNING: attr_list must be list type'

    def config_group(self, name, attr, **args):
        """
        Add or append attribute to given name.
        """
        # print 'config_group',self._groups,type(self._groups)
        # print '  name,attr',name,attr

        if self._groups.has_key(name):
            if attr not in self._groups[name]:
                # print '  before append',self._groups[name]
                self._groups[name].append(attr)
                # print '  after append',self._groups[name]

        else:
            self.create_group(name, [attr])

    def get_groupnames(self): return self._groups.keys()

    def get_group(self, name):
        """
        Returns a list with attribute names that belong to that group name.
        """
        # print 'get_group self._groups=\n',self._groups
        return self._groups.get(name, [])

    def get_groupattrs(self, name):
        """
        Returns a dictionary with all attributes of a group. 
        Key is attribute name and value is attribute value. 
        """
        attrs = {}
        for attr in self._groups[name]:
            attrs[attr] = self['attr']
        return attrs

    def get_perm(self, attr):
        """
        Returns current permission of attribute
        """
        return self._config[attr]['perm']

    def get_unit(self, attr, show_parentesis=True):
        """
        Returns unit of attribute
        """

        if self._config[attr].has_key('unit'):
            unit = self._config[attr]['unit']
        else:
            unit = ''

        if show_parentesis:
            if len(unit) > 0:
                unit = '[' + unit + ']'

        return unit

    def __getitem__(self, attr):
        # print '__getitem__',key

        # plugin execution
        if self._plugins.has_key(0):
            self._execute_plugins(0, attr)
        return self.__dict__[attr]

    def __setitem__(self, attr, value):
        """
        Sets a value to an attribute


        """

        # print 'setitem',key,'to',value

        self.__dict__[attr] = value

        # plugin execution
        if self._plugins.has_key(1):
            self._execute_plugins(1, attr)

    def __getstate__(self):
        # print '__getstate__',self.ident
        # print '  self.__dict__=\n',self.__dict__.keys()

        state = {}
        if hasattr(self, '_config'):

            # store ident for linked objects prior to saving
            # will be recovered in _init3
            for attr in self._config.keys():
                config = self._config[attr]

                if config.has_key('link'):
                    # try to recover object with ident
                    if config['link']:
                        if config['struct'] in ('array', 'dict', 'marray'):
                            # here we want to retain the idents of all objects
                            # in this array, using a dictionary with
                            # id as key and ident as value
                            config['ident'] = {}
                            for id in self.get_ids():
                                config['ident'][id] = self[
                                    attr, id].get_ident()
                        else:
                            config['ident'] = getattr(self, attr).get_ident()

            # print '  self._config.keys()',self._config.keys()
            for attr in self._attrs_save:
                state[attr] = getattr(self, attr)  # self.__dict__[attr]
                # print '  saved state:',attr,state[attr]

            # decide whether to save parent:
            # the root object does not save parent because outside the tree
            if len(string.split(self.ident, IDENTSEP)) > 1:
                # print '  save parent for',string.split(self.ident,IDENTSEP)
                state['parent'] = self.parent
            else:
                state['parent'] = None

            if hasattr(self, 'init_arrayobj'):
                # it is actually an array-object, save also id
                if hasattr(self, 'id'):
                    # print '  saved attr id',self.id
                    state['id'] = self.id

            # save which attributes to save
            state['_attrs_save'] = self._attrs_save

            # now save attributes which have been configured to save
            for attr in self._config.keys():
                # print '  ',self._config[attr]['save'],attr
                if self._config[attr]['save']\
                        & (not self._config[attr]['is_function'])\
                        & (not (type(getattr(self, attr)) == types.MethodType)):
                        # print '  save attr:',attr
                    state[attr] = getattr(self, attr)

            self._getstate(state)

        return state

    def _getstate(self, state):
        """
        Complete state dict with state variables which are not 
        contained in the config scheme. All attributes which are
        configured and the save option is not explicitely set
        to False are automatically inserted in the state dictionay.
        """
        pass

    def __setstate__(self, state):
        # print '__setstate__',self

        # this is always required, but will not be saved
        self._plugins = {}

        for key in state.keys():
            # print '  set state',key
            self.__dict__[key] = state[key]

        # done in init2_config...
        # set default values for all states tha have not been saved
        # for attr in self._config.keys():
        #    if (not self._config[attr]['save']) & (not hasattr(self,attr)):
        #        print '  config attr',attr
        #        self.config(attr,**self._config[attr])

        # set other states
        self._setstate(state)

    def _setstate(self, state):
        """
        Complete state settings of state variables which are not 
        contained in the config scheme. All attributes which are
        configured and the save option is not explicitely set
        to False are automatically set.
        """
        pass

    def close(self):
        """
        Should be called before desroying the object.
        Does remove pugs is existent.
        """
        if hasattr(self, unplugout):
            self.unplugout()


class ArrayObjConfigurator(ObjConfigurator):

    """
    Base class for general scalar object configuration.

    For usage see demo classes below.
    """

    def init_config(self, ident='', parent=None, name='noname', named=False,
                    **args):
        """
        Fore named objects use:
            self.add_id_named('name_of_id')
        """
        # print 'init_config array',ident,hasattr(self,'init_plugin')
        ObjConfigurator.init_config(self, ident, parent, name, **args)

        # else:
        # print 'no array plugins for ',self.ident

        # print 'check config'#,self.ident,self._config
        self._arrayconfig = {}
        self._dictconfig = {}
        self._inds = zeros((0,), int)
        self._ids = zeros((0,), int)
        self._marrayconfig = {}
        self._named = named
        if self._named:
            self._id_names = {}
            self.config('_name_ids', '', struct='dict',
                        info='Dictionary with id as key and name as value')
        else:
            self._id_names = None

        # save these attributes, apart from configured ones
        self._attrs_save += ['_arrayconfig', '_dictconfig', '_inds', '_ids',
                             '_marrayconfig', '_named', '_id_names']

    def is_named(self):
        """
        Returns true if array has named rows
        """
        return self._named

    def get_id_from_name(self, name):
        """
        Returns id that corresponds to name.
        """
        return self._id_names.get(name, -1)

    def get_name_from_id(self, id):
        """
        Returns name that corresponds to id.
        """
        return self._name_ids.get(id, '')

    def get_names(self):
        """
        Returns list of all named ids.
        """
        # print 'get_names',self.ident,self._id_names.keys()
        return self._id_names.keys()

    def get_named(self, attr, name):
        """
        Returns value corresponding to named id
        """
        return self[attr, self.get_id_from_name(name)]

    def get_ids(self, inds=[], ordered=False):
        """
        Return all ids corrisponding to array indexes inds.
        Options:
            if no inds are given, all ids are returnd

            if ordered is true, ids will be sorted before they are returned.

        """
        if (len(inds) > 0) & (not ordered):
            return take(self._ids, inds)

        elif len(inds) > 0:
            ids = take(self._ids, inds)

        else:
            ids = self._ids.copy()
        if ordered:
            return sort(ids)
        else:
            return ids

    def get_id(self, ind):
        """
        Returns scalar id corresponding to index ind
        """
        # print 'get_id',ind,self._ids
        return self._ids[ind]

    def is_scalarid(self, id):
        """
        Returns True if id is a zero positive scalar interger
        """
        if is_integer(id):
            if id >= 0:
                return True
            else:
                return False
        else:
            return False

    def is_idarray(self, ids):
        """
        Fast, formal chack whether ids is either a valid array with ids.
        """
        if type(ids) in (types.ListType, ndarray):
            # it is an array
            if len(ids) > 0:
                # it contains at least one id
                # return True if this id is a zaro positive integer
                return self.is_scalar_id(ids[0])
            else:
                return False
        else:
            return False

    def is_ids(self, ids):
        """
        Formal check whether ids contains either an array with ids
        or is a scalar zero positive interger.
        """
        return self.is_idarray(ids) | self.is_scalarid(ids)

    def select_ids(self, mask):
        """
        Returns an array of ids, corresponding to the True
        of the mask array.

        Usage:
            Select all ids for which array of attribute x is greater than zero.
            ids=obj.select_ids( obj.x>0 )
        """
        # print 'select_ids',mask,flatnonzero(mask)
        # print '  self._ids=',self._ids

        return take(self._ids, flatnonzero(mask))

    # def select(self,mask,ordered=False):
    #    """
    #    Returns an array of ids, corresponding to the True
    #    of the mask array.
    #
    #    Usage:
    #        Get all elements of attribute y for which array of attribute x is greater than zero.
    #        values=obj.select(obj.y, obj.x>0 )
    #    """
    #
    #
    #    return self.get_ids(flatnonzero(mask),ordered=ordered)

    def get_ids_marray(self, attr, inds_marray=[]):
        """
        Return all ids and relative indexes corresponding to m-array 
        indexes in list inds_marray.

        The relative index is the index within the array corresponding
        to an id.

        Examples:
            obj.get_ids_marray('attrname',[2,3,4])

            returns an array of the following shape:
            [[11,0],
             [11,1],
             [12,0],]

            here marray index 2 and 3 correspond to id=11 with relative index
            0 and 1 respectively, while marray index 3 corresponds to 
            element with id=12 and relative index 0 
            (means first item in element with id=12)

        """
        # print 'get_ids_marray',inds_marray
        if len(inds_marray) > 0:
            # case more complex because need to check with block pointers

            # get block pointers for this attribute
            bp = self._marrayconfig[attr]['bp']
            inds = zeros((len(inds_marray)), int)

            i = 0
            for ind_marray in inds_marray:
                # print '  bp, ind_marray',bp,ind_marray
                inds[i] = flatnonzero(
                    (bp[:, 0] <= ind_marray) & (bp[:, 1] > ind_marray))[0]
                i += 1
            inds_delta = inds_marray - take(bp[:, 0], inds)

            ids = take(self._ids, inds)
        else:
            ids = []
            inds_delta = []

        return concatenate((transpose([ids]), transpose([inds_delta])), (1))
        # return reshape(  concatenate((ids, inds_delta)) ,(-1,2) )

    def get_inds(self, ids=None):
        if ids != None:
            return self._inds[ids]
        else:
            return self._inds[self._ids]

    def get_ind(self, id):
        return self._inds[id]

    def get_inds_marray(self, attr, ids):
        """
        Returns a flat array with all array indexes of 
        marray with attribute attr that have an id contained in list ids. 
        """
        # get block pointers for this attribute
        bp = self._marrayconfig[attr]['bp']
        inds = []
        # print 'get_inds_marray: ids=',ids
        # print 'get_inds_marray: self._inds= ',self._inds
        # print 'get_inds_marray: self._inds[ids,:]= ',self._inds[ids,:]
        # Numeric
        # for i,j in take(bp, take(self._inds,ids) ):
        for i, j in bp[self._inds[ids], :]:
            # print '  i,j=',i,j
            inds += range(i, j)

        # print '  inds=',   array(inds,int)
        return array(inds, int)

    def suggest_id(self, zeroid=False):
        """
        Returns a an availlable id.

        Options:
            zeroid=True allows id to be zero.

        """
        return self.suggest_ids(1, zeroid)[0]

    def suggest_ids(self, n, zeroid=False):
        """
        Returns a list of n availlable ids.
        It returns even a list for n=1. 

        Options:
            zeroid=True allows id to be zero.
        """
        # print
        # 'suggest_ids',n,zeroid,self._inds,len(self._inds),self._inds.dtype
        ids_unused_orig = flatnonzero(less(self._inds, 0))

        if not zeroid:
            if len(self._inds) == 0:
                ids_unused = zeros(0, int)
            else:
                # avoid 0 as id:
                # ids_unused=take(ids_unused,flatnonzero(greater(ids_unused,0)))
                # print '  ids_unused_orig',ids_unused_orig,type(ids_unused_orig)
                # print '  len(ids_unused_orig)',len(ids_unused_orig),ids_unused_orig.shape
                # print '  greater(ids_unused_orig,0)',greater(ids_unused_orig,0)
                # print '  len(greater(ids_unused_orig,0))',len(greater(ids_unused_orig,0))
                # print '  flatnonzero(greater(ids_unused_orig,0))',flatnonzero(greater(ids_unused_orig,0))
                # print '
                # len(flatnonzero(greater(ids_unused_orig,0)))=',len(flatnonzero(greater(ids_unused_orig,0))
                # )
                ids_unused = ids_unused_orig[
                    flatnonzero(greater(ids_unused_orig, 0))]
            zid = 1
        else:
            if len(self._inds) == 0:
                ids_unused = zeros(0, int)
            else:
                ids_unused = ids_unused_orig.copy()

            zid = 0

        n_unused = len(ids_unused)
        n_max = len(self._inds) - 1
        # print '  ids_unused',ids_unused
        # print '  ids_unused.shape',ids_unused.shape
        # print '  len(ids_unused)',len(ids_unused)
        # print '  n_unused,n_max,zid=',n_unused,n_max,zid

        if n_max < zid:
            # first id generation
            ids = arange(zid, n + zid)

        elif n_unused > 0:
            if n_unused >= n:
                ids = ids_unused[:n]
            else:
                # print '  ids_unused',ids_unused
                # print '  from to',n_max+1,n_max+1+n-n_unused
                # print '  arange=',arange(n_max+1,n_max+1+n-n_unused)
                # print '  type(ids_unused)',type(ids_unused)
                # print '  dtype(ids_unused)',ids_unused.dtype
                ids = concatenate(
                    (ids_unused, arange(n_max + 1, n_max + 1 + n - n_unused)))

        else:
            ids = arange(n_max + 1, n_max + 1 + n)

        return ids  # .tolist()

    def add_id_named(self, name, id=-1, **args):
        """
        Creates array entries for id with given name.

        """
        if id < 0:
            id = self.suggest_id()
        # self._name_ids[name]=id
        # print 'add_id_named',self.ident,name,'with id',id
        self.create_ids(id, _name_ids=name, **args)
        return id

    def create_ids(self, ids, **args):
        """
        Creates for each id in ids list an entry for each attribute with 
        array or marray structure.

        If ids is a scalar integer, entries will be generated just for
        this id. 

        For named objects the list _name_ids_ is necessary 
        with a name correisponding to each id.  
        """
        # print 'create_ids',ids,args
        # this is a short dirty way to allow also scalars for ids and arguments
        if type(ids) not in ARRAYTYPES:
                # turn scalar ids in list-vector...
            ids = [ids]
            for key in args.keys():
                args[key] = [args[key]]

        # print '  create_ids',ids,args

        # no ids to create
        if len(ids) == 0:
            return True

        n = len(ids)
        id_max = max(ids)
        id_max_old = len(self._inds) - 1
        n_array_old = len(self)

        ids_existing = take(ids, flatnonzero(less(ids, id_max_old)))
        # print '  ids',ids,'id_max_old',id_max_old,'ids_existing',ids_existing

        # check here if ids are still available
        if sometrue(not_equal(take(self._inds, ids_existing), -1)):
            print 'WARNING in create_ids: some ids already in use', ids_existing
            return False

        # extend index map with -1 as necessary
        if id_max > id_max_old:
            # print 'ext',-1*ones(id_max-id_max_old)
            self._inds = concatenate(
                (self._inds, -1 * ones(id_max - id_max_old, int)))

        # assign n new indexes to new ids
        ind_new = arange(n_array_old, n_array_old + n)

        # print 'ind_new',ind_new
        put(self._inds, ids, ind_new)

        # print '  concat ids..',self._ids,ids
        self._ids = concatenate((self._ids, ids))

        # if each id is supposed to have a _name_ids
        # arguments must provide a list with names for each id
        if self._named:
            i = 0
            names = args['_name_ids']
            for id in ids:
                # print '  id,names[i]',id,names[i]
                self._id_names[names[i]] = id
                i += 1

        # Extend all arrays with n values from args or default
        for attr in self._arrayconfig.keys():
            # print '  attr',attr
            if args.has_key(attr):
                value = args[attr]
                if self._config[attr]['do_init_arrayobj']:
                    # newly assigned instances need to be array initialized
                    for i in range(len(ids)):
                        value[i].init_arrayobj(ids[i], self,
                                               self.make_item_ident(attr, ids[i]))
            else:
                value = self._get_default(attr, ids=ids)

            # print '
            # ',attr,'self.__dict__[attr]',self.__dict__[attr],'value',value
            if len(self.__dict__[attr]) > 0:
                # print '  concat item..',value
                self.__dict__[attr] = concatenate((self.__dict__[attr], value))
            else:
                # tc=self._config[attr]['dtype']
                # print '  first item with tc',tc,'and value',value
                # print '  ', array(value,dtype=tc)[0]
                # self.__dict__[attr]=array(value,dtype=tc)

                # print '  let NumPy, Numeric or whatever guess the first
                # arrayelement'
                self.__dict__[attr] = array(value)

        # Extend all marrays with n values from args or default
        for attr in self._marrayconfig.keys():

            # generate a scalar/list of copies of defaults
            items = args.get(attr, self._get_default(attr, ids=ids))
            self._append_items_marray(attr, ids, items)

        # assign defaults to all dicts
        for attr in self._dictconfig.keys():
            i = 0
            for id in ids:
                if args.has_key(attr):
                    value = args[attr][i]
                    if self._config[attr]['do_init_arrayobj']:
                        # print 'initialize',attr,value
                        value.init_arrayobj(
                            id, self, self.make_item_ident(attr, id))
                else:
                    value = self._get_default(attr, ids=id)

                # print '  dict attr=',attr,value
                self.__dict__[attr][id] = value

                i += 1

        if self._plugins.has_key(23):
            self._execute_plugins(23, ids=ids)

        return True

    def print_attr(self, attr):

        config = self.get_config(attr)
        if config:

            if config['struct'] == 'array':
                # print '   ', attr,'='
                for id in self.get_ids():
                    if config['is_function']:
                        val = self.__getitem__((attr, id))
                    else:
                        val = self.__getitem__((attr, id))

                    print self.get_string_arrayattr(attr, id, val)

            elif config['struct'] == 'marray':
                # print '   ', attr,'='
                for id in self.get_ids():
                    if config['is_function']:
                        val = self.__getitem__((attr, id))
                    else:
                        val = self.__getitem__((attr, id))

                    print self.get_string_arrayattr(attr, id, val)

                    # print '   ',id,self._inds[id],\
                    #    val,config['unit']

            elif config['struct'] == 'dict':
                print '   ', attr, '='
                for id in self.get_ids():
                    val = self.__dict__[attr][id]
                    print self.get_string_arrayattr(attr, id, val)

                    # print '   ',id,self._inds[id],\
                    #    self.__dict__[attr][id],config['unit']

            else:
                ObjConfigurator.print_attr(self, attr)

    def get_string_arrayattr(self, attr, id, value):
        """
        Returns a formatted string for array type attributes 
        with struct array, marray, dict 
        """
        # print 'get_string_arrayattr',attr,id,value
        return '   ' + attr + '[' + str(id) + '] = ' +\
            self.get_string_attr_value(attr, value)

    def reset(self, attr):
        """
        Reset attribute attr to default values
        """
        # create attribute and if there are already arrays with entries,
        # create the same number of entries with default value
        # print 'reset',attr,len(self)
        default = self._config[attr]['default']
        struct = self._config[attr]['struct']
        # declaredtype=self._config[attr]['type'][0]

        # configure if objects or instances need init_arrayobj with id
        # self._config[attr]['do_init_arrayobj']=False # moved to default
        if struct in ('array', 'marray', 'dict'):
            # try to detect from defaults
            if type(default) in [types.InstanceType, types.ClassType]:
                if hasattr(default, 'init_arrayobj'):
                    # print '  detected init_arrayobj!!'
                    self._config[attr]['do_init_arrayobj'] = True

                # done in config
                # elif type(default) == types.ClassType:
                #    if not self._config[attr].has_key('init'):
                #        # by default do not initialize classes
                #        # i they are nor arrayconfiguratored
                #        self._config[attr]['init']=False

            # check if instance or class type have been declared
            # if self._config[attr]['type'] in ['InstanceType','ClassType']:
            #    self._config[attr]['do_init_arrayobj']=True

        # do reset now
        if struct == 'array':
            # generate a scalar/list of copies of defaults
            defaults = self._get_default(attr, ids=self.get_ids())
            # print 'len:',self.__len__(),len(self)

            # register attribute in array database
            # currently no particular info, just key
            self._arrayconfig[attr] = {}

            # print 'reset',attr

            # all this not very clean, but works
            default = self._config[attr]['default']  # the array element
            if type(default) == ndarray:
                # use dtype given by default element which is an array
                tc = default.dtype.str
            else:
                # guess dtype from scalar types
                tc = get_dtype(self._config[attr]['type'][-1])

            self._config[attr]['dtype'] = tc

            # print '  tc=',tc,'type[-1]=',self._config[attr]['type'][-1]
            # this print causes a strange error:
            # 'FloatCanvas' object has no attribute 'this'

            self.__dict__[attr] = array(defaults, dtype=tc)

            # print '  created
            # type',self.__dict__[attr].dtype,self.__dict__[attr].shape

            # self.__dict__[attr]=array(\
            #    self._get_default(attr,ids=self.get_ids()), dtype=tc )

            # print 'new array',self.__dict__[attr]

        elif struct == 'marray':

            # register attribute in array database
            self._marrayconfig[attr] = {'bp': zeros((0, 2), int)}

            tc = get_dtype(self._config[attr]['type'][-1])
            self._config[attr]['dtype'] = tc

            # create new attribute with empty array
            # will be determined with first append
            self.__dict__[attr] = zeros((0), dtype=tc)

            # generate a scalar/list of copies of defaults
            ids = self.get_ids()
            defaults = self._get_default(attr, ids=ids)

            # print 'dtype',tc,default,'type =',self._config[attr]['type']
            if len(self._inds) > 0:
                self._append_items_marray(attr, ids, defaults)

            # print 'reset: new marray',self.__dict__[attr]

        elif struct == 'dict':
            # new attribute is a dictionary
            ids = self.get_ids()
            defaults = self._get_default(attr, ids=self.get_ids())

            # currently no particolar info, just key
            self._dictconfig[attr] = {}
            self.__dict__[attr] = {}
            # assign default value for each already existing id
            for i in range(len(ids)):
                id = ids[i]
                self.__dict__[attr][id] = defaults[i]

            # print 'reset: new dict',attr,'=',self.__dict__[attr]

        else:
            # handle other (scalar) attribute types with base configurator
            ObjConfigurator.reset(self, attr)

    def copy_attrs(self, targetobj, ids=None, targetids=None, attrs=None):
        """
        Copies  given list of attributes of this object to given target object.

        If no attributes are given then all attributes of this object 
        are considered for copying.

        To copy an attribute, the foolowing conditions must be satisfied:
            - the attribute must be configured with key copy=True
            - the attribute must be configured in targetobject 
        """
        if attrs == None:
            # get all attributes
            attrs = self._config.keys()

        if ids == None:
            # first copy all scalars
            ObjConfigurator.copy(targetobj)
            ids = self.get_ids()

        for attr in attrs:
            config = self._config[attr]
            if config['struct'] != 'scalar':
                if config['copy']:
                    if targetobj.is_config(attr):
                        targetobj[attr, targetids] = self[attr, ids]

    def add_items(self, n=0, **args):
        """
        Add new items into array structure.
        The ids for each newly created item are returned in an array.
        Usage:

            Add 3 new items:
            ids=obj.add_items(3)

            Add 3 new items and setting attributes:
            ids=obj.add_items(x=[11,22,33],v=[66,777,8888])

            Add a single new item and set values
            ids=obj.add_items(x=9,v=999)

            Add a single  multi array element composed of 2 scalar integers:
            ids=obj.add_items(s=[[111,2222]])

        """

        # determine number of items to be assigned
        if n == 0:
            if args:
                key = args.keys()[0]
                val = args[key]
                if type(val) not in ARRAYTYPES:
                    # turn scalar val in list-vector...
                    args[key] = [val]
                    n = 1
                else:
                    n = len(val)
            else:
                # add by default one item only
                n = 1
        else:
            pass  # use n from args

        # print 'base.add_items',n

        # determine new id
        ids = self.suggest_ids(n)

        # print ' create new ids',ids
        self.create_ids(ids, **args)

        # set values to attributes in arguments
# for attr in args.keys():
# if attr in self._config.keys():
# print attr,' before =' #,self.__dict__[attr]
# if self._config[attr]['struct']=='array':
# print '  insert in array',args[attr][0]
# print self._inds,ids,self._inds[ids]
# put(self.__dict__[attr],take(self._inds,ids),args[attr])
# print attr,' after =',self.__dict__[attr]
# elif self._config[attr]['struct']=='marray':
# for i in range(n):
# self._insert_item_marray(attr,ids[i],args[attr][i])
##
##
# elif self._config[attr]['struct']=='dict':
# for i in range(n):
# self.__dict__[attr][ids[i]]=args[attr][i]
# print '   dict',attr,self.__dict__[attr][ids[i]]
##
# else:
# print 'WARNING in add_items: unknown attribute:',attr

        return ids

    def __contains__(self, id):
        if (id < len(self._inds)) & (id >= 0):
            return self._inds[id] > -1
        else:
            return False

    def contains_name(self, name):
        return self._id_names.has_key(name)

    def __len__(self):
        """
        Determine current array length (same for all arrays)
        """

        return len(self._ids)

    # def get_index(self,ids):
    #    """
    #    returns index array from ids array
    #    Attetion thyis opration caused a crash during call from __del__
    #    """
    #    #print 'index',self._inds.dtype,type(ids),array(ids,int).dtype,len(ids)
    #
    #    return self._inds[array(ids,int)]
    #    #if type(ids) in ARRAYTYPES:
    #    #    #return take(self._inds,ids)
    #    #    return self._inds[array(ids,int)]
    #    #else:
    #    #    return self._inds[ids]

    def get_attr_named(self, attr, name):
        """
        Returns value of array element of attribute attr
        wich corresponds to id the given name.

        """
        if self._id_names.has_key(name):
            return self[attr, self._id_names[name]]
        else:
            return None

    def set_attr_named(self, attr, name, value):
        """
        Returns value of array element of attribute attr
        wich corresponds to id the given name.

        """
        self[attr, self._id_names[name]] = value

    def __getitem__(self, key):
        # print '__getitem__',key

        if type(key) != types.TupleType:
            # return entire contents of attribure for all ids
            attr = key
            struct = self._config[attr]['struct']
            if struct == 'scalar':
                if self._plugins.has_key(2):
                    self._execute_plugins(2, attr)

                if self._config[attr]['is_function']:
                    return getattr(self, attr)()
                else:
                    return self.__dict__[attr]

            else:
                # attribute is a kind of array
                # take all ids in ascending order
                ids = self.get_ids(ordered=True)
        else:
            # argument specify also id or ids to be returned
            attr, ids = key
            struct = self._config[attr]['struct']

        if type(ids) in ARRAYTYPES:
            # return array or list corresponding to ids
            # print 'get array types',attr,ids,struct
            # print '  self._inds=',self._inds
            # ids=array(ids,int)
            # print '  type (attr),type(ids)',type(self.__dict__[attr]),type(ids)
            # print '  ids.dtype 1=',ids.dtype
            # ids=array(ids,int)
            # print '  ids.dtype 2=',ids.dtype
            # print '  self._inds[ids]=',self._inds[ids]
            # print '  array(ids,int).dtype=',array(ids,int).dtype
            # executes plugins before values are returned to calling instance!!
            if self._plugins.has_key(22):
                self._execute_plugins(22, attr=attr, ids=ids)

            # this avoids problems with zero dimension arrays,
            # (bizzar but possible)

            #if ids.shape==(): ids=array([ids])
            # print '  get array type ids=',ids,struct

            if struct == 'array':
                if self._config[attr]['is_function']:
                    # print 'inds=',take(self._inds,ids)
                    return take(getattr(self, attr)(), take(self._inds, ids))
                else:
                    # print 'inds=',take(self._inds,ids)
                    # print take(self.__dict__[attr],take(self._inds,ids))
                    # return take(self.__dict__[attr],take(self._inds,ids))
                    return self.__dict__[attr][self._inds[array(ids, 'i')], :]

            elif struct == 'marray':
                # here an array is returned with all elements of the
                # those blocks that corresponds to the ids
                # Note that this is a homogenious array ,
                # arrays with single blocks can be obtained by passing
                # a single array.
                if self._config[attr]['is_function']:
                    return getattr(self, attr)()[self.get_inds_marray(attr, ids), :]
                    # Numeric:
                    # return take(getattr(self,attr)(),
                    #        self.get_inds_marray(attr,ids))
                else:

                    # print '  inds_marray=',self.get_inds_marray(attr,ids)
                    # print '  self.__dict__[attr]=\n',self.__dict__[attr]
                    # print '
                    # return=\n',self.__dict__[attr][self.get_inds_marray(attr,ids),:]
                    return self.__dict__[attr][self.get_inds_marray(attr, ids), :]
                    # Numeric:
                    # return take(self.__dict__[attr],
                    #        self.get_inds_marray(attr,ids))

            elif struct == 'dict':
                items = []
                for id in ids:
                    # print '  ',id,self.__dict__[attr][id]
                    items.append(self.__dict__[attr][id])
                return items

            # this will never be executed!!!!!!!!!!!
            # if self._plugins.has_key(22):
            #    self._execute_plugins(22,ids=ids)

        else:
            # print 'return one array element, ids is a single id'
            if self._plugins.has_key(22):
                self._execute_plugins(22, attr, ids=array([ids], int))

            if struct == 'array':
                # print 'inds=',take(self._inds,[ids]),attr,getattr(self,attr)

                if self._config[attr]['is_function']:
                    return getattr(self, attr)()[self._inds[ids]]
                else:
                    # try:
                    return self.__dict__[attr][self._inds[ids]]
                    # except:
                    #    print 'ERROR in __getitem__', attr,ids
                    #    print '  inds=',self._inds[ids]
                    #    print '  attr=',self.__dict__[attr]

            elif struct == 'marray':
                # here an array is returned with all elements of the
                # block that corresponds to this id
                if self._config[attr]['is_function']:
                    return getattr(self, attr)()[self.get_inds_marray(attr, [ids])]
                    # Numeric
                    # return take(getattr(self,attr)(),
                    #        self.get_inds_marray(attr,[ids]))
                else:
                    # print 'ids=',ids
                    # print
                    # 'self.get_inds_marray(attr,[ids]))=',self.get_inds_marray(attr,[ids])
                    return getattr(self, attr)[self.get_inds_marray(attr, [ids])]
                    # Numeric:
                    # return take(self.__dict__[attr],
                    #        self.get_inds_marray(attr,[ids]))

            elif struct == 'dict':
                # print 'attr=',attr,ids
                return self.__dict__[attr][ids]

    def __setitem__(self, key, value):
        """
        Sets a value to an attribute
        or to one or several elements of an attribute if
        a list with ids is passed.

        Usage:
            Scalar assignment
            obj['attrname']=0.0

            Single element asignment
            obj['attrname',3]=33

            Assign 11,22,33 to elements with ids 1,2,3 of attribite attrname
            obj['attrname',[1,2,3]]=[11,22,33]

            Assign 3 elements of different size to marray
            obj['attrname',[1,2,3]]=[[11,12,13],[21,22],[31]]
            Note that the assigned value must be a python list of elements
            and not a Numpy array

        """

        # print 'setitem',key,'to',value

        if type(key) != types.TupleType:
            self.__dict__[key] = value
            if self._plugins.has_key(1):
                self._execute_plugins(1, key)
            return

        else:
            attr, ids = key
            if type(ids) not in ARRAYTYPES:
                # ids is a scalar->make a list
                ids = array([ids], int)
                value = [value]

            struct = self._config[attr]['struct']
            # print 'inds=',self.get_index(ids)
            if struct == 'array':
                shape = self.__dict__[attr].shape
                if len(shape) == 1:
                    # print 'put value',value,type(value)
                    # print '  attr,type(attr)',attr,type(self.__dict__[attr])
                    # print '  dtype(attr)',self.__dict__[attr].dtype
                    # print '
                    # self.get_index(ids)=',self.get_index(ids),type(self.get_index(ids)),self.get_index(ids).dtype

                    self.__dict__[attr][self._inds[array(ids, 'i')]] = value
                    # put(self.__dict__[attr],self.get_index(ids),value)

                    if self._config[attr]['do_init_arrayobj']:
                        # newly assigned instances need to be array initialized
                        for i in range(len(ids)):
                            value[i].init_arrayobj(ids[i], self,
                                                   self.make_item_ident(attr, ids[i]))

                else:
                    # this is an array of matrix or tensors or higher order
                    # the array must be flattened and the indexes must be
                    # calculated accordingly

                    # m=product(shape[1:])
                    # print 'put marray',m,
                    #inds=ones( (len(ids),1),int )*arange(m)\
                    #    +transpose([take(self._inds,ids)])*m
                    # print inds

                    # print 'put value matrix',value,type(value)
                    # print '  attr,type(attr)',attr,type(self.__dict__[attr])
                    # print '  dtype(attr)',self.__dict__[attr].dtype
                    # print '  inds=\n',self._inds[ids]

                    if type(value) != ndarray:
                        # print 'value',value
                        value = array(value, dtype=self._config[attr]['dtype'])
                        # print 'value',value

                    self.__dict__[attr][self._inds[ids], :] = value
                    # Numeric
                    #put(self.__dict__[attr],inds.ravel(), value.ravel())

            if struct == 'marray':
                for i in range(len(ids)):
                    self._insert_item_marray(attr, ids[i], value[i])

            elif struct == 'dict':
                for i in range(len(ids)):
                    self.__dict__[attr][ids[i]] = value[i]
                    if self._config[attr]['do_init_arrayobj']:
                        # newly assigned instances need to be array initialized
                        # self.print_config()
                        value.init_arrayobj(
                            id, self, self.make_item_ident(attr, id))
                        # self.print_config()

            # print 'set_item:check plugins...',self.ident,self._plugins.keys()
            if self._plugins.has_key(21):
                self._execute_plugins(21, attr=attr, ids=ids)

            return

    def del_item_named(self, name):
        """
        Deletes id with given name from all attributes
        """
        del self[self._id_names[name]]

    def __delitem__(self, key):
        # print 'ArrayObjConfigurator.__delitem__',self.ident,'key=',key
        if key in self._config.keys():
            # delete attribute and its configuration
            if self._plugins.has_key(0):
                self._execute_plugins(0, key)

            if self._config[key]['struct'] == 'array':
                del self._arrayconfig[key]
            elif self._config[key]['struct'] == 'dict':
                del self._dictconfig[key][id]
            elif self._config[key]['is_function']:
                self._functions.remove(key)

            for groupname in self._config[key]['group']:
                self._groups[groupname].remove(key)

            del self._config[key]
            del self.__dict__[key]

        else:
            # key is one or multiple ids to be deleted from arrays
            if type(key) not in ARRAYTYPES:
                # ids is a scalar->make a list
                ids = [key]
            else:
                ids = key

            # TODO: here it is not verified whether ids exist
            #  => verify and delete element by element

            # plugin execution BEFORE entry is deleted
            if self._plugins.has_key(20):
                self._execute_plugins(20, ids=ids)

            self._del_ids(ids)

    ##########################################################################
    # private methods

    def _append_items_marray(self, attr, ids, items):
        """
        Appends a list of items to multiary with attribute attr.
        The block pointers are created automatically but
        the indexes and ids must already exist in self._inds 

        ids cannot be empty!
        """
        # print 'append_items_marray',attr
        # print '  ids=',ids
        # print '  items=',items
        marray = self.__dict__[attr]
        # print 'marray=\n',marray
        bp = self._marrayconfig[attr]['bp']
        len_bp = len(bp)

        # make sure that the bp vecor has enough index

        ind_max = max(self._inds)

        bpext = -1 * ones((ind_max - len_bp + 1, 2), int)

        if len_bp == 0:
            bp = bpext
        else:
            bp = concatenate((bp, bpext))
        # print '  after extension bp=',bp

        # set block pointers for each id according to length of each item
        i = len(marray)
        n_elems = 0  # gives the total number of elements inside all items
        for ii in range(len(ids)):
            id = ids[ii]
            ind = self._inds[id]

            # assume that id corresponds to a list with at least one item
            # thus, calculate new block pointers
            n = len(items[ii])
            j = i + n
            n_elems += n
            # print '  id,ind,i,j,len(items[ii])=',id,ind,i,j,len(items[ii])

            bp[ind] = [i, j]

            i = j

        # print '  after asssignment bp=',bp
        self._marrayconfig[attr]['bp'] = bp

        # put items in an array with coherent dimentions
        shape_elem = array(items[0], int).shape[1:]
        shape_array = [n_elems] + list(shape_elem)
        # print ' shape_elem=',shape_elem
        # print ' shape_array=',shape_array
        # extend current marray by the corrct number of new elements
        marrayext = zeros(shape_array, dtype=self._config[attr]['dtype'])
        if len(marray) > 0:
            # print '  concat extention to marray=\n',marrayext
            marray = concatenate((marray, marrayext))
        else:
            # print '  first  marray_extension=\n',marrayext
            marray = marrayext

        # now copy items into array is faster than concatenating each item
        for ii in range(len(ids)):
            id = ids[ii]
            ind = self._inds[id]
            i, j = bp[ind]
            # print '   add item items[ii]',items[ii]
            marray[i:j] = items[ii]

        self.__dict__[attr] = marray

    def _insert_item_marray(self, attr, id, item):
        # print 'insert_item_marray',attr,id,item
        # print '  attr=', self.__dict__[attr]

        # get block pointers for this attribute
        bp = self._marrayconfig[attr]['bp']

        # index of block pointers
        ind = self._inds[id]

        # get from to index of m array for this id
        [i, j] = bp[ind]

        # decide whether to overwrite existing
        if j - i != len(item):
            # first cut current data out of marray and adjust
            # block pointers
            self._del_item_marray(attr, id)

            # append data
            self._append_items_marray(attr, [id], [item])
        else:
            self.__dict__[attr][i:j] = item

        # print '  attr=', self.__dict__[attr]

    def _del_item_marray(self, attr, id):

        # get block pointers for this attribute
        bp = self._marrayconfig[attr]['bp']

        # index of block pointers
        ind = self._inds[id]

        # get from to index of m array for this id
        [i, j] = bp[ind]

        # print 'del_item_marray',attr,id,'from',i,'to',j

        # cut this piece out of the marray
        # print '  before:',self.__dict__[attr]
        self.__dict__[attr] = concatenate(
            (self.__dict__[attr][:i], self.__dict__[attr][j:]))

        # print '  after:',self.__dict__[attr]

        # indicate that block pointer does no more point to anywhere
        # calling method must take care of eliminating it or not
        bp[ind] = [-1, -1]
        # cut out index from blockpointers
        #bp=concatenate( (bp[:ind], bp[ind+1:]) )

        # now subtract j-i from all "to" index higher equal than j
        subtract(bp, (j - i) * (bp >= j), bp)

        self._marrayconfig[attr]['bp'] = bp

    # def _get_bp_marray(self,attr):
    #    """May be useful, just not used """
    #    return self._marrayconfig[attr]['bp']

    def make_item_ident(self, attr, id):
        """
        Generates the ident of attribute attr withy id.
        """
        return self.ident + IDENTSEP + attr + IDENTSEP + str(id)

    def get_groupattrs(self, name, id=-1):
        """
        Returns a dictionary with all attributes of a group. 
        Key is attribute name and value is attribute value for the given id. 
        """
        # print 'get_groupattrs  of',name,'from',self.ident,self._groups.keys()
        # print '  id=',id
        attrs = {}

        if (name in self._groups.keys()) & self.is_ids(id):
            for attr in self._groups[name]:
                # attrs[attr]=self['attr']
                struct = self._config[attr]['struct']
                if (struct in ('dict', 'array', 'marray')):
                    default = self[attr, id]
                    # if default is an initialized class or an instance
                    # and has also a dict or array structure,
                    # then try to configure array object with id

                    if type(default) == types.InstanceType:
                        # default is instance so just make a copy
                        obj = copy(default)
                        # now configure array object
                        # in this case class must have ArrayObj capabilities (mixin)
                        # if self._config[attr]['do_init_arrayobj']:
                        #    obj.init_arrayobj(id,self,self.make_item_ident(attr,id))

                    elif (type(default) == types.ClassType) & \
                            self._config[attr]['do_init_arrayobj']:
                        # default is a class that needs to be initialized first
                        obj = copy(default)
                        # obj.init_arrayobj(id,self,self.make_item_ident(attr,id))

                    elif type(default) == types.FunctionType:
                        # use base function to get other default types
                        obj = default

                    else:
                        # use base function to get other default types
                        obj = copy(default)

                else:
                    # use base function to get other default types
                    obj = self.__dict__[attr]  # attr() copy(default)

                attrs[attr] = obj
        # else:
        #    print '  no attr found',self._groups.keys()
        # print '  attrs=',attrs
        return attrs

    def _get_default(self, attr, n=1, ids=None):
        """
        Returns n default values for attribute with name attr_name
        By default a scalar is returned. 
        If n>1 a list with n defaults is returned.

        Usage:
            Return a scalar default 
            self._get_default('attr_name')    

            Return list with 5 defaults
            self._get_default('attr_name',5)

            Return list with 5 defaults, assigned with ids=[1,2,3,4,5].
            This usage makes only sense with Classes or instances
            with ArrayObj mixin.
            self._get_default('attr_name',ids=[1,2,3,4,5])

        """
        # print '_get_default',self.ident,attr

        default = self._config[attr]['default']
        struct = self._config[attr]['struct']
        defaults = []

        if ids == None:
            # create dummy ids
            ids = range(n)
            returnlist = False

        elif type(ids) not in ARRAYTYPES:
            # just a single id, do return a simple value, not a list
            ids = [ids]
            returnlist = False
        else:
            returnlist = True

        for id in ids:
            if struct in ('dict', 'array', 'marray'):
                # if default is an initialized class or an instance
                # and has also a dict or array structure,
                # then try to configure array object with id

                if type(default) == types.InstanceType:
                    # default is instance so just make a copy
                    obj = copy(default)
                    # now configure array object
                    # in this case class must have ArrayObj capabilities
                    # (mixin)
                    if self._config[attr]['do_init_arrayobj']:
                        obj.init_arrayobj(
                            id, self, self.make_item_ident(attr, id))

                elif (type(default) == types.ClassType) & \
                        self._config[attr]['do_init_arrayobj']:
                    # default is a class that needs to be initialized first
                    obj = default()
                    obj.init_arrayobj(id, self, self.make_item_ident(attr, id))

                elif type(default) == types.FunctionType:
                    # use base function to get other default types
                    obj = default

                else:
                    # use base function to get other default types
                    obj = copy(default)

            else:
                # use base function to get other default types
                obj = ObjConfigurator._get_default(self, attr)

            # append to default list
            defaults.append(obj)

        # print '_get_default array',defaults
        if (n > 1) | returnlist:

            return defaults
        else:
            return defaults[0]

    def _del_ids(self, ids):
        """
        Deletes id from all array - tpe attributes
        """

        # print 'ArrayConfigurator._del_ids',ids,'from',self.ident

        # delete ids from list , one by one
        for id in ids:
            # print '  start deleting id',id

            # print '      self._ids',self._ids
            # print '      self._inds',self._inds

            # i=self.get_index(id)
            i = self._inds[id]

            # print '     ind=',i
            # print '     del rows from array-types...'
            for attr in self._arrayconfig.keys():
                # print '      del',attr,id,i

                # print '        before=\n',self.__dict__[attr]
                self.__dict__[attr] = concatenate(
                    (self.__dict__[attr][:i], self.__dict__[attr][i + 1:]))
                # print '        after=\n',self.__dict__[attr]

            # print '    del from id lookup'
            self._ids = concatenate((self._ids[:i], self._ids[i + 1:]))

            # print '    del from dicts'
            for attr in self._dictconfig.keys():
                # print '      del',attr,id
                del self.__dict__[attr][id]

            # print '    del from marrays'
            for attr in self._marrayconfig.keys():
                self._del_item_marray(attr, id)

                # what's left is to cut out the db pointer with index i
                bp = self._marrayconfig[attr]['bp']

                # print '      del',attr,id,bp

                bp = concatenate((bp[:i], bp[i + 1:]))
                self._marrayconfig[attr]['bp'] = bp

            # print '    free index',id
            if id == len(self._inds) - 1:
                # id is highest, let's shrink index array by 1
                self._inds = self._inds[:-1]
            else:
                self._inds[id] = -1

            # get ids of all indexes which are above i
            ids_above = flatnonzero(self._inds > i)

            # decrease index from those wich are above the deleted one
            #put(self._inds, ids_above,take(self._inds,ids_above)-1)
            self._inds[ids_above] -= 1

            # print '    self._inds',self._inds

        if self._named:
            # print '  Remove named'
            for id in ids:
                name = self._name_ids[id]
                del self._id_names[name]
                # print '    removed',name,id

        # print '  del',ids,' done.'

    def __setstate__test(self, state):
        """
        This is setstate for array config only
        and overrides the scalar version.

        The main purpose is to correct a conversion error in numpy
        """
        print '__setstate__', self

        # this is alays required, but ill not be saved
        self._plugins = {}

        for key in state.keys():
            value = state[key]

            # print '  set state',key
            # print '    attr',key,type(value),
            # if type(value)==ndarray:
            #    print value.dtype,value.shape
            # else:
            #    print value

            if type(value) == ndarray:
                if value.dtype == dtype('|O4'):
                    value = array(value, '<f8')
                print '  set state', key, type(value),
                print '    dtype', value.dtype, value.shape

            self.__dict__[key] = value

        # set other states
        self._setstate(state)


# def del_manage_ids(self,ids):
# """
# Specific item delete, called before removing data.
# """
# pass

class EmptyClass:

    """
    This claass is empty and used as default.

    """

    def __init__(self, parent=None): pass

    def get_ident(self, is_local=None): return 'empty'


class IntegerQueues(ArrayObjConfigurator):

    """
    Class implements multiple queues with the following properties:
        - only integers  can be queued
        - each id can be only in one queue

    Methods are implemented to insert and remove ids in queues
    also in vectorial form.
    """

    def __init__(self, parent, key='queues', name='Queues', items=None):
        """
        Main init used for stand alone.
        """
        self.init_config(key, parent, name)

        self._init_queues(items)

    def _init_queues(self, items=None):
        """
        Queue specific initializations

        items = optional instance that is an array of the integer items
                in the integer queue. The item must inherit IntegerItems
                methods and have this (self) queue class as parent. 
        """

        self.config('ids_first', -1,
                    name='First id',
                    info='ID of first element of each queue',
                    metatype='id',
                    ident_ref='.items',
                    struct='array',
                    )

        self.config('ids_last', -1,
                    name='Last id',
                    info='ID of last element of each queue',
                    metatype='id',
                    ident_ref='.items',
                    struct='array',
                    )

        if items == None:
            # use default items class
            items = IntegerItems(self)

        self.config('items', items,
                    name='items',
                    info='Contain items that are queued in each queue',
                    ident_ref='.items',
                    group='options')

    def add_items(self, ids_item):
        """
        Add ne items for queuing in database
        """
        self.items.create_ids(ids_item)

    def is_empty(self, ids_queue):
        """
        Returns True or False for each queue in the array
        if respective queue is empty or non-empty  
        """
        return self['ids_first', ids_queue] == -1

    def pop_items(self, ids_queue):
        """
        Remove and return last items from queues in array  ids_queue
        """
        ids_items = self['ids_last', ids_queue]

        self.remove_items(ids_items[ids_items > -1])

        return ids_items

    def remove_items(self, ids_item, ids_queue=None):
        """
        Remove integers in array ids_item from queues in array ids_queue
        If no ids_queue is given, it will be recovered from the integer items 
        database. This may only be a disadvantage in terms of time.
        """
        # print 'remove_items'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue

        if ids_queue == None:
            ids_queue = self.items['ids_queue', ids_item]

        inds_queue = self.get_inds(ids_queue)
        inds_item = self.items.get_inds(ids_item)

        # identify single
        inds_single =   (self.ids_last[inds_queue] == ids_item) & \
                        (self.ids_first[inds_queue] == ids_item)

        if any(inds_single):
            # remove single item in queues
            inds_queue_single = inds_queue[inds_single]
            self.ids_last[inds_queue_single] = -1
            self.ids_first[inds_queue_single] = -1

        # identify last
        inds_last = (self.ids_last[inds_queue] == ids_item) &\
            logical_not(inds_single)

        if any(inds_last):
            # remove last items in queues
            inds_queue_last = inds_queue[inds_last]
            inds_item_last = inds_item[inds_last]

            ids_item_new_last = self.items.ids_prev[inds_item_last]
            self.items['ids_next', ids_item_new_last] = -1
            self.ids_last[inds_queue_last] = ids_item_new_last

        # identify first
        inds_first = (self.ids_first[inds_queue] == ids_item) &\
            logical_not(inds_single)

        if any(inds_first):
            # remove first items in queues
            inds_queue_first = inds_queue[inds_first]
            inds_item_first = inds_item[inds_first]

            ids_item_new_first = self.items.ids_next[inds_item_first]
            self.items['ids_prev', ids_item_new_first] = -1
            self.ids_first[inds_queue_first] = ids_item_new_first

        # identify middle
        inds_middle =   logical_not(inds_single) &\
            logical_not(inds_last) & logical_not(inds_first)

        if any(inds_middle):
            # remove first items in queues
            inds_queue_middle = inds_queue[inds_middle]
            inds_item_middle = inds_item[inds_middle]

            # cutting items out of chains
            ids_item_new_next = self.items.ids_next[inds_item_middle]
            ids_item_new_prev = self.items.ids_prev[inds_item_middle]

            self.items['ids_next', ids_item_new_prev] = ids_item_new_next
            self.items['ids_prev', ids_item_new_next] = ids_item_new_prev

        # finally remove pointer from items to queues
        self.items.ids_queue[inds_item] = -1
        self.items.ids_next[inds_item] = -1
        self.items.ids_prev[inds_item] = -1

    def insert_items_behind(self, ids_item, ids_item_beh, ids_queue):
        """
        Insert integers in array ids_item into queues in array ids_queue
        behind integers in array ids_item_beh
        """
        # print 'insert_items_beh'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue
        # print '  ids_item_beh',ids_item_beh

        # identify prepend
        inds_prepend = ids_item_beh == -1
        if any(inds_prepend):
            self.prepend_items(ids_item[inds_prepend],
                               ids_queue[inds_prepend])

        # identify append
        inds_append = (self['ids_last', ids_queue] == ids_item_beh) \
            & logical_not(inds_prepend)
        if any(inds_append):
            self.append_items(ids_item[inds_append],
                              ids_queue[inds_append])

        # select rest
        inds = logical_not(inds_prepend) & logical_not(inds_append)

        if any(inds):
            # insert items where insertion somewhere in the middle
            # of the buffer where first and last item is not effected

            # this task can therefore be handeled by item instance
            self.items.insert_items_behind(ids_item[inds],
                                           ids_item_beh[inds],
                                           ids_queue[inds],
                                           )

    def append_items(self, ids_item, ids_queue):
        """
        Append integers in array ids_items to queues in array ids_queue
        """
        # print 'append_items'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue

        # different treatmet of empty and not empty queues
        inds_empty = self.is_empty(ids_queue)
        inds_not_empty = logical_not(inds_empty)

        # treat first empty queues
        if len(inds_empty) > 0:
            # print '  inds_empty',inds_empty
            self['ids_first', ids_queue[inds_empty]] = ids_item[inds_empty]
            self['ids_last', ids_queue[inds_empty]] = ids_item[inds_empty]

        if any(inds_not_empty):

            # treat queues with at least one item
            ids_not_empty = ids_queue[inds_not_empty]
            ids_item_not_empty = ids_item[inds_not_empty]

            # fix new first and last item
            ids_item_prev = self['ids_last', ids_not_empty]
            self['ids_last', ids_not_empty] = ids_item_not_empty

            # backward chaining
            self.items['ids_prev', ids_item_not_empty] = ids_item_prev

            # forward chaining
            self.items['ids_next', ids_item_prev] = ids_item_not_empty

        # assign queue id
        self.items['ids_queue', ids_item] = ids_queue

    def prepend_items(self, ids_item, ids_queue):
        """
        Prepend integers in array ids_items to queues in array ids_queue
        """
        # print 'prepend_items'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue

        # different treatmet of empty and not empty queues
        inds_empty = self.is_empty(ids_queue)
        inds_not_empty = logical_not(inds_empty)

        # treat first empty queues
        if len(inds_empty) > 0:
            # print '  inds_empty',inds_empty
            self['ids_first', ids_queue[inds_empty]] = ids_item[inds_empty]
            self['ids_last', ids_queue[inds_empty]] = ids_item[inds_empty]

        if any(inds_not_empty):

            # treat queues with at least one item
            ids_not_empty = ids_queue[inds_not_empty]
            ids_item_not_empty = ids_item[inds_not_empty]

            # fix new first and last item
            ids_item_next = self['ids_first', ids_not_empty]
            self['ids_first', ids_not_empty] = ids_item_not_empty
            # self['ids_last',ids_not_empty] = ids_items_next # not changed

            # forward chaining
            self.items['ids_next', ids_item_not_empty] = ids_item_next

            # backward chaining
            self.items['ids_prev', ids_item_next] = ids_item_not_empty

        # assign queue id
        self.items['ids_queue', ids_item] = ids_queue

    def print_info(self):
        """
        Print all usueful info
        """
        self.print_config()
        self.items.print_config()


class IntegerItems(ArrayObjConfigurator):

    """
    Class cotaining integer items (the ids) of the integer queue.

    This class can be used as mixin in order to add customized attributes to
    each item.

    """

    def __init__(self, parent, key='items', name='Integer items'):
        """
        Main init used for stand alone.
        """
        self.init_config(key, parent, name)

        self._init_items()

    def _init_items(self):
        """
        Here the item specific states are initialized.

        queue_data is an optional database with additional information 
            on the queues where each id correspnds to a queue

        """

        self.config('ids_queue', -1,
                    name='queue id',
                    info='ID of queue',
                    metatype='id',
                    ident_ref=self.parent.ident,
                    struct='array',
                    )

        self.config('ids_next', -1,
                    name='next id',
                    info='ID of next',
                    metatype='id',
                    ident_ref='.',
                    struct='array',
                    )

        self.config('ids_prev', -1,
                    name='previous id',
                    info='ID of previous',
                    metatype='id',
                    ident_ref='.',
                    struct='array',
                    )

    def insert_items_behind(self, ids_item, ids_item_beh, ids_queue):
        """
        UNUSED!! see integerqueue!!

        Insert integers in array ids_item into queues in array ids_queue
        behind integers in array ids_item_beh.

        Please use insert_behind of the governing queue class!

        Attention this method is called by insert_behind of the 
        governing queue class, which selected already the cases where
        this insertion is in the middle of the queue and does not effect
        first or last item. 
        """
        # print 'IntegerItems.insert_items_beh'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue
        # print '  ids_item_beh',ids_item_beh

        inds_item = self.get_inds(ids_item)
        inds_item_beh = self.get_inds(ids_item_beh)

        # forward chaining
        ids_item_next = self.ids_next[inds_item_beh]
        self.ids_next[inds_item] = ids_item_next
        self.ids_next[inds_item_beh] = ids_item

        # backward chaining
        self.ids_prev[inds_item] = ids_item_beh
        self['ids_prev', ids_item_next] = ids_item

        # assign queue id to inserted elements
        self.ids_queue[inds_item] = ids_queue


class MetaList(ArrayObjConfigurator):

    """
    Empty class with ArrayObjConfigurator properties.
    Can be freely configured to contain any kind of database like,
    ordered list structures.

    Usage:
         l=MetaList()
         l.config('m',0.0,struct='marray')
         l.create_ids([1,2,3,4])
         l.print_config()
    """

    def __init__(self, **args):
        self.init_config('metalist')


class TestNamed(ArrayObjConfigurator):

    def __init__(self, **args):
        self.init_config('test', named=True)
        self.config('s', zeros((0,), float), struct='marray',
                    type=['IntType'])

        self.config('v', 0, struct='array')
        self.add_id_named('one')
        self.add_id_named('two')


class TestMod(ObjConfigurator, ArrayObj):

    """
    test
    """

    def __init__(self, **args):
        """
        Mod specific Initialization.
        self.id an parent is yet unknown 
        """
        pass
        # print 'initialized TestMod'

    def config_with_id(self):
        """
        Mod specific Initialization.
        Now id and parent is known.
        """
        self.init_config()
        # print 'config_with_id',self.ident
        self.config('y', 0.0, group=['state'], perm='w', digits_fraction=2)
        self.config('z', 'text', group=['state'], perm='w')
        self.config('cabins', Cabs(self))
        # self.print_config()


class Car(ArrayObj):

    """
    test
    """

    def __init__(self, **args):
        """
        Mod specific Initialization.
        self.id an parent is yet unknown 
        """
        print 'initialized CarMod'

    def config_with_id(self):
        """
        Mod specific Initialization.
        Now id and parent is known.
        """
        pass


class CarTest(ArrayObjConfigurator):

    """
    test
    """

    def __init__(self, **args):
        """Variable
        """
        self.init_config('carstest')
        self.config('a', 0.0, struct='array', group=[
                    'state', 'costs'], unit='m/s^2')
        # self.config('mods',TestMod,struct='dict')
        #self.config('m',[0.0, 0.0, 0.0],struct='array')
        self.config('g', zeros((3, 4)), struct='array', unit='earth accel')
        newids = self.suggest_ids(3)
        self.create_ids(newids)


class Cars(ArrayObjConfigurator):

    """
    test
    """

    def __init__(self, **args):
        """Variable
        """
        self.init_config('cars')
        self.config('x', 0.456685, group=[
                    'state'], perm='w', digits_fraction=2)

        self.config('color', [0.2, 0.8, 0.2], metatype='color',
                    struct='array', group=['parameter'], perm='w')
        self.config('load', 'user', struct='dict', perm='r')
        self.config('n', 0,  struct='array', info='number', perm='w',
                    group=['state', 'parameters'],
                    min=0, max=5)
        self.config('b', False, struct='array', perm='w',
                    info='bool...', group=['state', 'costs'])
        self.config('a', 0.0, struct='array', info='acceleration',
                    group=['state', 'costs'], digits_fraction=2)
        self.config('v', 0.0, struct='array', info='velocity',
                    group=['state'], unit='m/s', digits_fraction=2)
        self.config('d', 0.0, unit='m', struct='array',
                    info='this is \nthe distance', digits_fraction=2)
        self.config('j', 0.0, struct='array', perm='r', digits_fraction=2)
        self.add_items(v=[8.7, 5.5, 34.1, 2], a=[-8, -5, -34, -2])

        self.config('mods', TestMod, struct='dict')
        self.config('m', [0.0, 0.0, 0.0], struct='array')
        self.config('g', zeros((3, 4)), struct='array')
        self.config('coords', array([0.0, 0.0, 0.0], float),
                    # type=['FloatType'],
                    struct='array',
                    name='coordinates',
                    info='Array with xyz coordinates of each node')
        newids = self.suggest_ids(3)
        self.create_ids(newids, v=[5, 6, 7])
        # print 'config=\n',self.get_config()


class ObjConfiguratorTest(ObjConfigurator):

    """
    test
    """

    def __init__(self, parent=None, **args):
        """Variable
        """
        self.init_config('ObjConfiguratorTest', parent)
        self.config('d', [[1, 2]], type=[('ArrayType', (1, 2)), 'IntType'])


class Cabs(ArrayObjConfigurator):

    """
    test
    """

    def __init__(self, parent=None, **args):
        """Variable
        """
        self.init_config('cabs', parent)
        self.config('d', [[1, 2]], type=[
                    ('ArrayType', (1, 2)), 'IntType'], struct='dict')
        self.create_ids([1, 2, 3, 4])
        self.config('a', 0.0, struct='array', group=[
                    'state', 'costs'], unit='m/s^2')
        self.config('n', -1, struct='array')
        self.config('g', zeros((3, 4)), struct='array', perm='r')
        #self.config('v',0.0, struct='array', group=['state'])
        # self.config('d',0.0,unit='m')
        # self.config('j',0.0,struct='array')
        # self.add_items(v=[8.7,5.5,34.1,2],a=[-8,-5,-34,-2])
        # self.config('coords',array([0.0,0.0,0.0]),
        #            struct='array',
        #            name='coordinates',
        #            info='Array with xyz coordinates of each node')


class MarrayTest(ArrayObjConfigurator):

    """
    test
    from base import *;t=MarrayTest();t['s',1]=[11,22,33,44];t['s',3]=[-33,-44]
    t.get_ids_marray('s',[1,])
    t['s',2]=[22,222,2222,22222]
    t['s',[1,2]]=[[3,33,333],[55,555,5555,5555]]
    t.get_ids_marray('s',[1,2,3])
    t.get_ids_marray('s',[1,])

    """

    def __init__(self, **args):
        self.init_config('test')
        self.config('s', zeros((0,)), struct='marray',
                    type=['IntType'])

        self.config('v', 0, struct='array')

        self.config('x', [[-1, -1]],
                    name='forward star',
                    info='Dict with node id as key and forward nodes as values',
                    doc='A dictionary with node id as key and \n' +
                         'a dictionary with follower nodes as value. \n' +
                         'Each follower node is a dictionary with \n' +
                         'predecessor node id as key and arc id as value',
                    type=[('ArrayType', (1, 2)), 'IntType'],
                    struct='marray',
                    )

        self.config('f', zeros((0,), dtype='i'),
                    name='forward nodes',
                    info='Dict with node id as key and forward nodes as values',
                    doc='A dictionary with node id as key and \n' +
                         'a dictionary with follower nodes as value. \n' +
                         'Each follower node is a dictionary with \n' +
                         'predecessor node id as key and arc id as value',
                    type=[('ArrayType', (1,)), 'IntType'],
                    struct='marray',
                    )

        self.config('m', [[0.0, 0.0, 0.0], [10.0, 10.0, 0.0]], struct='marray')
        self.create_ids([1, 2, 3, 4])
        # self.config('s',[-1],struct='marray')
        self.print_config()


def test_queue():
    q = IntegerQueues(None)
    q.create_ids([1, 2, 3, 4])
    q.add_items(arange(0, 20, 2, int))

    q.print_info()

    # q.prepend_items(array([2,1],int),array([4,3],int))
    # q.prepend_items(array([2,],int),array([3,],int))
    q.insert_items_behind(array([2, ], int), array(
        [-1, ], int), array([2, ], int))

    q.print_info()

    q.insert_items_behind(array([16, ], int), array(
        [2, ], int), array([2, ], int))

    q.print_info()

    q.prepend_items(array([4, 8], int), array([3, 2], int))

    q.print_info()

    q.append_items(array([6, ], int), array([1, ], int))

    q.print_info()

    q.append_items(array([10, 12], int), array([1, 3], int))

    q.print_info()

    q.insert_items_behind(array([18, ], int), array(
        [2, ], int), array([2, ], int))

    q.print_info()

    q.remove_items(array([18, ], int))

    q.print_info()

    q.remove_items(array([16, ], int))

    q.print_info()

    q.remove_items(array([8, ], int))

    q.print_info()

    q.remove_items(array([2, ], int))

    q.print_info()

    print '\npop all', q.pop_items(q.get_ids())
    print '\npop all', q.pop_items(q.get_ids())
    print '\npop all', q.pop_items(q.get_ids())

###############################################################################
if __name__ == '__main__':
    """
    Test
    """

    test_queue()

    exit(0)

    # a=array([[1,2,3],[4,5,6],[7,8,9],[11,22,33]])
    # b=array([[1,0,1],[1,1,1],[1,0,0],[0,0,0]])

    # cd C:\Documents and Settings\joerg\Documenti\projects\its
    # import sys; sys.path[:0] = ['C:\Users\joerg\projects\sim\its']
    #from lib.base import *
    cabs = Cabs()
    cabs.print_config()

    # t=MarrayTest();t['s',1]=[11,22,33,44];t['s',3]=[-33,-44]
    # t.get_ids_marray('s',[1,])
    # t['s',2]=[22,222,2222,22222]
    # t['s',[1,2]]=[[3,33,333],[55,555,5555,5555]]
    # t.get_ids_marray('s',[1,2,3])
    # t.get_ids_marray('s',[1,])

    t = ObjConfiguratorTest()
    t.print_config()

    save_obj(t, 'test.txt')
    t = load_obj('test.txt')

<filename>sumo/tools/contributed/sumopy/agilepy/lib_base/base.py
"""
This package contains the base classes of al relevant classes.

TODO: Following issues must be resolved in the following version

- child  - parent - ident - named
    childs of named parents should have the name in the ident...and local ident
    create 2 ident entries for arrayobj: attr+id
    use a list for ident elements instead of a string wityh string conversion
    on the fly or permanently.
    May be of advantaqge (= fast) to store instances that are on the path of the 
    ident elements
    
    in particular: distiguish between an instance on the tree that is created with parent
    and an already initialized instance that is set and usd as a link.
    idea in this case get all confuguration info from instance itself
    or better link to it!
- ident should be a sequence or list of strings
- separate classes for array type objects
- classes for metatypes 
- try to reduce type recognition during init ?? 
- MIXIN for named operation just as for plugin
- make plugin faster by overwriting get/set attribute
- print attribute must also go in classes


- make common initialization priciples in particular for classes based on mixins
  who sets the name: the parent! name is option with default
-  simplify configurationwith key setting...should appear only once 
   try to catch it from within the object with __name__
- try to remove stored type identification...careful problems are nd scalars

"""
from numpy import *
# from numpy.oldnumeric.user_array import numpy.oldnumeric.user_array as
# UserArray
from copy import copy, deepcopy

from sys import exit
import types
import string
import pickle
#import networkx as nx

try:
    flatnonzero
except:
    def flatnonzero(x):
        return nonzero(x.ravel())

CONFIG_TEMPLATE = {
    'info': '',
            'doc': '',
            'metatype': '',
            'type': '',
            'group': [],
            'save': True,
            'copy': False,
            'struct': 'scalar',
            'perm': 'w',
            'unit': '',
            'do_init_arrayobj': False,
}

ARRAYTYPES = [types.TupleType, ndarray, types.ListType, types.XRangeType]

TYPES = {
    'BooleanType': {'dtype': '?', 'perm': 'w', },
    'BufferType': {'dtype': 'O', 'perm': 'r', },
    'BuiltinFunctionType': {'dtype': 'O', 'perm': 'r', },
    'BuiltinMethodType': {'dtype': 'O', 'perm': 'r', },
    'ClassType': {'dtype': 'O', 'perm': 'r', },
    'CodeType': {'dtype': 'O', 'perm': 'r', },
    'ComplexType': {'dtype': 'D', 'perm': 'w', },
    'DictProxyType': {'dtype': 'O', 'perm': 'r', },
    'DictType': {'dtype': 'O', 'perm': 'r', },
    'DictionaryType': {'dtype': 'O', 'perm': 'r', },
    'EllipsisType': {'dtype': 'O', 'perm': 'r', },
    'FileType': {'dtype': 'O', 'perm': 'w', },
    'FloatType': {'dtype': 'd', 'perm': 'w', },
    'FrameType': {'dtype': 'O', 'perm': 'r', },
    'FunctionType': {'dtype': 'O', 'perm': 'r', },
    'GeneratorType': {'dtype': 'O', 'perm': 'r', },
    'InstanceType': {'dtype': 'O', 'perm': 'r', },
    'IntType': {'dtype': 'i', 'perm': 'w', },
    'LambdaType': {'dtype': 'O', 'perm': 'r', },
    'ListType': {'dtype': 'O', 'perm': 'r', },
    'LongType': {'dtype': 'g', 'perm': 'w', },
    'MethodType': {'dtype': 'O', 'perm': 'r', },
    'ModuleType': {'dtype': 'O', 'perm': 'r', },
    'NoneType': {'dtype': 'O', 'perm': 'r', },
    'NotImplementedType': {'dtype': 'O', 'perm': 'r', },
    'ObjectType': {'dtype': 'O', 'perm': 'r', },
    'SliceType': {'dtype': 'O', 'perm': 'r', },
    'StringType': {'dtype': 'S', 'perm': 'w', },
    'StringTypes': {'dtype': 'O', 'perm': 'w', },
    'TracebackType': {'dtype': 'O', 'perm': 'r', },
    'TupleType': {'dtype': 'O', 'perm': 'r', },
    'TypeType': {'dtype': 'O', 'perm': 'r', },
    'UnboundMethodType': {'dtype': 'O', 'perm': 'r', },
    'UnicodeType': {'dtype': 'U', 'perm': 'w', },
    'XRangeType': {'dtype': 'O', 'perm': 'r', },
    '__builtins__': {'dtype': 'O', 'perm': 'r', },
    '__doc__': {'dtype': 'O', 'perm': 'r', },
    '__file__': {'dtype': 'O', 'perm': 'r', },
    '__name__': {'dtype': 'O', 'perm': 'r', },
}

IDENTSEP = '.'


def make_arrays(**attrs):
    """
    Makes an array of same type from all attributes in attrs dictionary
    A bit slow! Avoid using this function!
    """
    for attr in attrs.keys():
        obj = attrs[attr]
        if type(attrs[attr]) == ndarray:
            attrs[attr] = attrs[attr].reshape((1,) + obj.shape)
        elif type(obj) in (types.FloatType, types.LongType):
            attrs[attr] = array([obj], float)
        elif type(obj) == types.IntType:
            attrs[attr] = array([obj], int)
        elif type(obj) == types.BooleanType:
            attrs[attr] = array([obj], bool)
        else:
            # another strange type
            dt = 'O'
            for typename in dir(types):
                if type(obj) == types.__dict__[typename]:
                    dt = get_dtype(typename)
                    break
            attrs[attr] = array([obj], dtype=dt)
    return attrs


def is_integer(n):
    """
    Returns True if n is an integer type of any kind
    """
    return type(n) in (types.IntType, int32, int64, int0, int16, int8, types.LongType)


def get_type(obj, typelist=[]):
    """
    Returns a flat list of type-string(s) which correspond to the
    (nested) type(s) of  the object obj.

    The returned type(s)  are keys of the global TYPES dictionary.
    """

    typelist = copy(typelist)
    if type(obj) == ndarray:
        typelist.append(('ArrayType', obj.shape))
        # return typelist # let's assume homogenious array types
        if len(obj.ravel()) > 0:
            return get_type(obj.flat[0], typelist)
        else:
            return typelist

    elif hasattr(obj, 'dtype'):  # obj is an array element
        # attention this is not a string but maybe this should
        # also be changed for all other types
        typelist.append(obj.dtype.str)
        return typelist

    elif type(obj) in (types.ListType, types.TupleType):
        typelist.append('ListType')
        if obj:
            return get_type(obj[0], typelist)
        else:
            return typelist

    elif type(obj) in (types.DictType, types.DictionaryType):

        if obj:
            key = obj.keys()[0]
            keytype = get_type(key)
            if len(keytype) > 0:
                typelist.append(('DictType', keytype[0]))
            else:
                typelist.append(('DictType', ''))

            return get_type(obj[key], typelist)
        else:
            typelist.append(('DictType', ''))
            return typelist

    else:
        for typename in dir(types):
            if type(obj) == types.__dict__[typename]:
                typelist.append(typename)
                return typelist
                break
        typelist.append('')
        return typelist


def get_dtype(type):
    """
    Returns dtype as used in Nummeric package.
    The argument is a string defining the python objecy type
    and is a key of the TYPES dictionary.
    If type is not found in the dictionary, dtype 'O' is
    returned, which means a generic object.
    """
    if TYPES.has_key(type):
        return TYPES[type]['dtype']
    else:
        return 'O'


def save_obj(obj, filename):
    """
    Saves python object to a file with filename.
    Filename may also include absolute or relative path.
    If operation fails a False is returned and True otherwise.
    """
    try:
        file = open(filename, 'wb')
    except:
        print 'WARNING in save: could not open', simname
        return False

    # try:
    pickle.dump(obj, file, protocol=2)
    file.close()
    return True
    # except:
    #    file.close()
    #    print 'WARNING in save: could not pickle object'
    #    return False


def load_obj(filename, parent=None):
    """
    Reads python object from a file with filename and returns object.
    Filename may also include absolute or relative path.
    If operation fails a None object is returned.
    """
    print 'load_obj', filename
    try:
        file = open(filename, 'rb')
    except:
        print 'WARNING in load_obj: could not open', filename
        return None

    # try:
    # print '  pickle.load...'
    obj = pickle.load(file)
    file.close()
    # print '  obj._link2'

    # _init2_ is to restore INTERNAL states from INTERNAL states
    obj._init2_config()

    # _init3_ is to restore INTERNAL states from EXTERNAL states
    # such as linking
    obj._init3_config()

    # _init4_ is to do misc stuff when everything is set
    obj._init4_config()

    return obj

    # except:
    #	print 'WARNING in load: could not load object'
    #	return None


def is_objconfigured(obj):
    return hasattr(obj, 'init_config')


class ArrayObj:

    """
    Mixin for Classes or Instance which are used as array-element 
    within the framework of the ArrayObjConfigurator.

    Its main function is init_arrayobj where an id gets assigned
    which corresponds to the id of the element in the parent array.

    Also __getitem__ and __setitem__ functions are implemented through which 
    array elements with the same id of other attributes of the parent object 
    can be read and changed.
    """

    def init_arrayobj(self, id, parent, ident, **args):
        """
        Initialize by defining parent instance where all the
        attributes of this instance are stored in array form.
        Also define the id of the array coresponding to this instance. 

        Function will be called automatically from ArrayObjConfigurator
        when id is assigned.

        """
        self.parent = parent
        # if ident=='':
        #    ident=parent.ident+IDENTSEP+str(id)
        # else:
        self.ident = ident
        self.id = id
        self.config_with_id()
        # print 'init_arrayobj',self.ident,id#,parent

    def config_with_id(self):
        """
        Here the instance can be inizialized..
        Function called AFTER  self.id and self.parent have been assigned.
        """
        pass

    def copy_attrs(self, targetobj, attrs=None):
        """
        Copies  given list of attributes of this object 
        to given target object.

        If no attributes are given then all attributes of this object 
        are considered for copying.

        Clearly, the array attributes corresponding to the id of this
        object are copied to the array attributes of the arrays 
        with the id of the target object.

        To copy an attribute, the foolowing conditions must be satisfied:
            - the attribute must be configured with key copy=True
            - the attribute must be configured in targetobject 

        """
        self.parent.copy_attrs(targetobj, self.id, targetobj.id, attrs=attrs)

    def __getitem__(self, key):
        return self.getparent(key)

    def __setitem__(self, key, value):
        self.setparent(key, value)

    def setparent(self, key, value):
        """
        Sets entry with id of this instance of the attribute 'key' of parent object.

        Usage:
            self['attributename']=value  


        """
        # print key,value
        self.parent[key, self.id] = value

    def getparent(self, key):
        """
        Gets entry with id of this instance of the attribute in parent object.

        Usage:
            self['attributename']  
        """
        # print 'ArrayObject.__getitem__',key
        return self.parent[key, self.id]

    def get_groupattrs_obj(self, name):
        """
        Returns a dictionary with all attributes of a group with given name. 
        Key is attribute name and value is attribute value for the given id. 
        """
        # print 'get_groupattrs_obj',name,self.id
        return self.parent.get_groupattrs(name, self.id)


class PlugoutMixin:

    """
    Mixin to provide methods to plug  callback functions into other objects.
    """

    def init_plugout(self):
        """
        Initialize basic plugout variables
        """
        # dictionary with pluginobj as key and list with plugids
        # provided by obj as value
        self._plugoutobjs = {}

    def add_plugout(self, obj, plugtype, function, attr='_all'):
        """
        Make a plugin to object and retain plugin id for later unplugg.

        Standard plug types are automatically set bu the system:
        plugtype    plugcode
        'del'       0
        'set'       1
        'get'       2
        'add'       3

        'del_items' 20
        'set_items' 21
        'get_items' 22
        'add_items' 23



        """
        if not self._plugoutobjs.has_key(obj):
            self._plugoutobjs[obj] = []
        # make plugin to object
        plugid = obj.add_plugin(obj, plugtype, function, attr)

        # add plugginid of obj to list
        self._plugoutobjs[obj].append(plugid)

        return plugid

    def del_plugout(self, obj, plugid=-1):
        """
        Plug out from specified object.
        If plugid is specified, only this plug is pulled,
        otherwise all plugs to this object are pulled at once.
        """
        if self._plugoutobjs.has_key[obj]:
            if plugid < 0:
                if self._plugoutobjs[obj].count(plugid) > 0:
                    obj.del_plugin(plugid)
                    self._plugoutobjs[obj].remove(plugid)
            else:
                for plugids in self._plugoutobjs[obj]:
                    obj.del_plugin(plugid)
                del self._plugoutobjs[obj]
        else:
            print 'WARNING: no plugout ids for object', obj
            plugids = []

    def unplugout(self):
        """
        Unplug all plugs on other objects
        """
        for obj in self._plugoutobjs.keys():
            self.del_plugout(obj)


class PluginMixin:

    """
    Mixin to provide methods to plug in callback functions
    from other objects.
    """

    def init_plugin(self):
        """
        Initialize basic plugin variables
        """
        # self._plugins={} # compulsory in configurator!
        self._counter_plugid = 0

        self._plugcode = {'test': -1}
        # print 'init_plugin',self.ident,self._plugcode

        # dictionary with obj as key and dict with plugid,plugtype,attr as
        # value
        self._pluginobjs = {}

        # add basic plugincodes
        # for scalars
        self.add_plugcodes([('del', 0), ('set', 1), ('get', 2), ('add', 3)])

        if hasattr(self, 'get_ids'):
            # print '  add_plugcodes arrays for ',self.ident
            self.add_plugcodes([('del_items', 20),
                                ('set_items', 21),
                                ('get_items', 22),
                                ('add_items', 23), ])
        self.enable_plugins()

    def execute_plugin(self, plugtype):
        """
        Execute all callbacks for the plugin of the given type
        """
        self._execute_plugins(self._plugcode[plugtype], attr='_all')

    def add_plugcodes(self, plugcodes):
        """
        Plugcodes integers that correspond to a plugtype.
        These integers are used as keys for faster access.

        Argument plugcodes is a list with tuples 
        each tuple containing plugtype and plugcode.

        Standard plug types are automatically set bu the system:
        plugtype    plugcode
        'del'       0
        'set'       1
        'get'       2
        'add'       3

        'del_items' 20
        'set_items' 21
        'get_items' 22
        'add_items' 23

        """
        # print 'add_plugcodes',plugcodes
        for plug, plugcode in plugcodes:
            if not self._plugcode.has_key(plug):
                self._plugcode[plug] = plugcode
                # self._plugins[plugcode]={'_all':{}}
                # print '  added
                # self._plugcode[plug]',plug,self._plugcode[plug]
            else:
                print 'WARNING:_add_plugcodes: already existant code',\
                    plug, self._plugcode[plug]
                print '  Refused to insert.'

    def add_plugin(self, obj, plug, callbackfunction, attr='_all'):
        # print 'add_plugin',plug,callbackfunction,attr
        self._counter_plugid += 1
        plugid = self._counter_plugid
        plugcode = self._plugcode[plug]

        if not self._plugins.has_key(plugcode):
            self._plugins[plugcode] = {}

        if not self._plugins[plugcode].has_key(attr):
            self._plugins[plugcode][attr] = {plugid: callbackfunction}
        else:
            self._plugins[plugcode][attr][plugid] = callbackfunction

        if not self._pluginobjs.has_key(obj):
            self._pluginobjs[obj] = {}

        self._pluginobjs[obj][plugid] = (plugcode, attr)
        return plugid

    def disable_plugins(self):
        """
        Prevents plugins from execution
        """
        self._enable_plugins = False

    def enable_plugins(self):
        """
        Enable plugins for execution
        """
        self._enable_plugins = True

    def del_plugin(self, obj, plugid=-1):
        """
        Remove plugin with pluginid
        """

        if plugid >= 0:
            plugids = [plugid]
        else:
            plugids = self._pluginobjs[obj].keys()

        if self._pluginobjs.has_key(obj):
            # there exist ids associated with this object
            for pid in plugids:
                if self._pluginobjs[obj].has_key(pid):
                    # remove plugin with pid
                    plugcode, attr = self._pluginobjs[obj][pid]
                    del self._plugins[plugcode][attr][pid]
                    del self._pluginobjs[obj][pid]

                    if len(self._plugins[plugcode][attr]) == 0:
                        # no more plugins for this attribute...remove it
                        del self._plugins[plugcode][attr]
                        if len(self._plugins[plugcode]) == 0:
                            # np more plugins for this plugintype...remove it
                            del self._plugins[plugcode]

            if len(self._pluginobjs[obj]) == 0:
                # no more plugin ids associated with this object
                del self._pluginobjs[obj]


class ObjConfigurator:

    """
    Base mixin class for general scalar object configuration.

    Usage:

        During initialization of class call

        self.init_config('myclass_ident_string',name='my human readable class')

        or if there is a parent object availlable:

        self.init_config('myclass_ident_string',parent)

        In this case the ident of the parent obj is prependet



    """

    def init_config(self, ident='', parent=None, name='noname', **args):
        # print '---init_config ident',ident,hasattr(self,'init_plugin')
        # print '  parent',parent
        # print '  name',name,len(name)

        if hasattr(self, 'ident'):
            ident = self.ident

        if (name == 'noname') & (len(ident) > 0):
            self.name = ident
        elif (name == 'noname') & (len(ident) == 0):
            if self.__dict__.has_key('__name__'):
                ident = self.__name__  # use class name as identifier
            self.name = ident

        elif (len(name) > 0) & (len(ident) == 0):
            if self.__dict__.has_key('__name__'):
                ident = self.__name__  # use class name as identifier
            self.name = name
        else:
            self.name = name

        self.ident = ident
        self.parent = parent
        if parent != None:

            # print 'init_config',ident,parent.ident
            # present object is a child of a parent
            # => prepend parent identifier string
            if hasattr(parent, 'ident'):
                self.ident = parent.ident + IDENTSEP + ident

        self._config = {}
        self._groups = {}
        self._functions = []

        # define a list with attribute strings that need to be saved
        # apart from the cofigured attributes
        # this list may be extended by successive initializations
        self._attrs_save = [  # 'parent',
            'name', 'ident', '_config', '_groups',
            '_functions',
        ]

        # conditional plugin import
        self._init_plugging()

        # print 'Created configuration for',self.ident

        return self.ident

    def reset_parent(self, parent):
        """
        Resets previously assigned parent.
        This method is not used during initialization.  
        """
        ident = self.get_ident(is_local=True)
        self.parent = parent
        if parent != None:
            # print 'init_config',ident,parent.ident
            # present object is a child of a parent
            # => prepend parent identifier string
            if hasattr(parent, 'ident'):
                self.ident = parent.ident + IDENTSEP + ident

    def get_ident(self, is_local=False):
        """
        Returns identity string.
        By default it returns the entire identity string
        unless is_local==True. In this case only the local, the last
        element of the global identity is returned.
        """
        if is_local:
            return string.split(self.ident, IDENTSEP)[-1]
        else:
            return self.ident

    def _link(self, parent=None):
        """
        Called after load process to link with other instances 
        in the environment.
        """

        # self.parent=parent
        # for attr in self._config.keys():
        #    obj=getattr(self,attr)
        #    if is_objconfigured():
        #        obj._link(self)
        pass

    def _init2_config(self):
        """
        Called after load and link process to do make initializations
        of constants, dependent INTERNAL attributes such as hash tables, 
        NO LINKS OR DEPENDENCIES TO EXTERNAL INSTANCES ALLOWED

        Here only the configurator internal attributes are restored.
        All object specific in _init2() in 
        """
        print '\n _init2_config', self.ident

        print '  restore unsaved attributes', self.ident
        self._functions = []
        for attr in self._config.keys():

            # check
            # if hasattr(self,attr):
            #    value=getattr(self,attr)
                # print '  attr',attr,
                # if type(value)==ndarray:
                #    print value.dtype,value.shape
                # else:
                #    print value

            config = self._config[attr]
            if config['is_function']:
                # print '    resore function',attr
                self._functions.append(attr)
            elif not config['save']:
                # print '    resore attr',attr
                self.reset(attr)
            # check
            # value=getattr(self,attr)
            # print '  after: attr',attr,
            # if type(value)==ndarray:
            #    print value.dtype,value.shape
            # else:
            #    print value

        # conditional plugin import
        self._init_plugging()

        print '  call _init2', self.ident

        self._init2()

        print '  restore children', self.ident
        for attr in self._config.keys():
            config = self._config[attr]
            if (config['save']) & (not config['is_function']):
                if config['struct'] == 'scalar':
                    obj = getattr(self, attr)
                    if is_objconfigured(obj):
                        print '    call _init2_config of', obj.ident
                        obj._init2_config()
                else:
                    # attribute is an array so init here for arrays as well
                    # TODO: should go as special in arrayconfigurator
                    for id in self.get_ids():
                        obj = self[attr, id]
                        if is_objconfigured(obj):
                            print '    call _init2_config of', obj.ident
                            obj._init2_config()

    def _init2(self):
        """
        Called after load  process to do make initializations
        of constants, dependent INTERNAL attributes such as hash tables, 
        NO LINKS OR DEPENDENCIES TO EXTERNAL INSTANCES ALLOWED

        To be overridden.
        """
        pass

    def _init3_config(self):
        """
        Called after load and link process to do make initializations
        of constants, dependent attributes such as hash tables, 
        links to external instances etc.

        """
        print '\n_init3_config', self.ident
        # link with other, now already initialized objects
        # Those attributes which have NOT been saved, but have
        # an ident in they configuration can no be recovered
        # though their ident
        for attr in self._config.keys():
            config = self._config[attr]

            if config.has_key('link'):
                # try to recover object with ident

                if config['link']:

                    if config['struct'] in ('array', 'dict', 'marray'):
                        print '   detected link array ', attr
                        # here we want to recover links to objects
                        # using a dictionary with
                        # id as key and ident as value
                        for id in self.get_ids():
                            self[attr, id] = self.get_obj_instance(
                                config['ident'][id])

                    else:
                        print '   detected link ', attr
                        setattr(self, attr, self.get_obj_instance(
                            config['ident']))

        # make specific settings
        self._init3()

        # print '  restore children',self.ident
        for attr in self._config.keys():
            config = self._config[attr]
            if (config['save']) & (not config['is_function']):
                if config['struct'] == 'scalar':
                    obj = getattr(self, attr)
                    if is_objconfigured(obj):
                        # print '    call _init3_config of',obj.ident
                        obj._init3_config()
                else:
                    # attribute is an array so init here for arrays as well
                    # TODO: should go as special in arrayconfigurator
                    for id in self.get_ids():
                        obj = self[attr, id]
                        if is_objconfigured(obj):
                            # print '    call _init3_config of',obj.ident
                            obj._init3_config()

    def _init3(self):
        """
        Called after load and internal link process to do make initializations
        of constants, dependent attributes such as hash tables, 
        links to external instances etc.

        To be overridden.
        """
        pass

    def _init4_config(self):
        """
        Called after load and link process to do make initializations
        any other initializations.

        """
        print '\n_init4_config', self.ident

        # make specific settings
        self._init4()

        # print '  restore children',self.ident
        for attr in self._config.keys():
            config = self._config[attr]
            if (config['save']) & (not config['is_function']):
                if config['struct'] == 'scalar':
                    obj = getattr(self, attr)
                    if is_objconfigured(obj):
                        # print '    call _init4_config of',obj.ident
                        obj._init4_config()
                else:
                    # attribute is an array so init here for arrays as well
                    # TODO: should go as special in arrayconfigurator
                    for id in self.get_ids():
                        obj = self[attr, id]
                        if is_objconfigured(obj):
                            # print '    call _init4_config of',obj.ident
                            obj._init4_config()

    def _init4(self):
        """
        Called after load and link process to do make initializations
        any other initializations.

        To be overridden.
        """
        pass

    def _init_plugging(self):
        """
        Initializes plugin and plugout related variables.
        This function is called during initialization 
        and after load, before reinitializeing other attrubutes. 
        """
        # print '_init_plugging',self.ident,self
        # if make_plugins:
        #    from PluginMixin import *
        if hasattr(self, 'init_plugin'):
            # print '  ini_plugin',self.ident,self
            self.init_plugin()

        if hasattr(self, 'init_plugout'):
            # print '  ini_plugout',self.ident
            self.init_plugout()
        # this plugin dictionary is always required and remains
        # empty if no plugins are made
        self._plugins = {}

    def _execute_plugins(self, plugcode, attr='_all', **args):
        """
        This method executes all callbackfunctions associated with the
        given plugcode.
        This funcion is a core part because used in various
        methods. All other methods regarding plugins in PluginMixin.
        """
        # it has been checked that self._plugins has all keys
        print '_execute_plugins', plugcode, ' for', self.ident, attr
        # print '  self._plugins=',self._plugins
        # print '  self._plugins[plugcode]=',self._plugins[plugcode]

        if self._enable_plugins:
            args['attr'] = attr
            if self._plugins[plugcode].has_key('_all'):
                for func in self._plugins[plugcode]['_all'].values():
                    # print '  => execute function',func
                    # print '     with args',args
                    func(**args)
            elif self._plugins[plugcode].has_key(attr):
                # selective plugin for specific attribute
                for func in self._plugins[plugcode][attr].values():
                    func(**args)
            # else:
            #    print '  no plugin functions for plugcode',plugcode

    def get_name():
        """
        Returns formatted name string of object.
        """
        return self.name

    def print_config(self):

        # print 'inds=',self._inds
        print '===================================================================='
        print '   Config of', self.name, ' with ident:', self.ident
        print '===================================================================='
        for attr in self._config.keys():
            self.print_attr(attr)

        # for name in self.get_groupnames():
        #    if self.get_group(name):
        #        print 'Group: ',name
        #        for attr in self.get_group(name):
        #            self.print_attr(attr)

        # print all attributes which are not in a group
        # print '--'
        # for attr in self._config.keys():
        #    if len(self._config[attr]['group'])==0:
        #        self.print_attr(attr)

    def print_attr(self, attr):
        # config=self.get_config(attr)
        # print '   ', attr,'=',self.__dict__[attr],config['unit']
        print '   ' + attr + ' = ' + self.get_string_attr_value(attr, self[attr])

    def print_attrattrs(self, attrs=None, attrattrs=['info', 'group', 'struct'], filename=None, sep='\t'):
        """
        Prints attributes of attributes.
        If 
        """
        # print 'print_attrattrs'
        lines = []
        if attrs == None:
            attrs = self._config.keys()
        attrs.sort()
        line = u'attr'
        for attrattr in attrattrs:
            line += sep + attrattr
        lines.append(line)

        for attr in attrs:
            # print '  attr',attr
            line = u'' + attr
            for attrsattr in attrattrs:
                if self._config[attr].has_key(attrsattr):
                    line += sep + str(self._config[attr][attrsattr])
                else:
                    line += sep + ''
            lines.append(line)

        if filename != None:
            file = open(filename, 'w')
            for line in lines:
                # print line
                file.write(line + '\n')
            file.close()
        else:
            for line in lines:
                print line

        return lines

    def get_string_attr_value(self, attr, value):
        """
        Returns a string with correctly formatted value of attribute.
        """
        # print '\n\nget_string_attr_value',attr,value,type(value)
        # print self.get_printformat(attr)+self.get_unit(attr)
        #print (self.get_printformat(attr)+self.get_unit(attr))%(value)
        config = self.get_config(attr)
        tt = config['type'][0]
        unit = self.get_unit(attr, show_parentesis=True)
        if tt in ('BooleanType',):
            if value:
                s = 'True'
            else:
                s = 'False'
            return s + self.get_unit(attr, show_parentesis=True)

        elif type(value) in ARRAYTYPES:
            # value is an array=> print signe items
            s = '['
            for v in value:
                s += self.get_string_attr_value(attr, v) + ','
            s += ']'
            return s

        else:
            try:
                return (self.get_printformat(attr)
                        + ' ' + self.get_unit(attr, show_parentesis=True)) % value
            except:
                print '\n WARNING could not print', attr, '=', value
                return 'Error'

    def get_printformat(self, attr):
        """
        Returnes the standad fortran stringformat for attribute.
        """
        config = self.get_config(attr)
        tt = config['type'][0]
        if tt in ('IntType', 'LongType'):
            return '%' + str(config['digits_integer']) + 'd'

        elif tt in ('FloatType', 'ComplexType'):
            return '%' + str(config['digits_integer']) + '.'\
                + str(config['digits_fraction']) + 'f'

        else:
            # its a string
            return '%s'

        return printformat

    def get_numformat(self, attr, confog=None):
        """
        Returns a dictionary with all formatting infos on attribute.
        It is tried to detect the numerical datatype and define
        formatting info, if not already defined.
        """
        # determine format of numeric value

        config = self.get_config(attr)

        # take top level type
        tt = config['type'][0]
        numformat = {}
        if tt in ('IntType', 'LongType'):
            numformat['digits_integer'] = config.get('digits_integer', 13)
            numformat['digits_fraction'] = config.get('digits_fraction', 0)
        else:
            numformat['digits_integer'] = config.get('digits_integer', 9)
            numformat['digits_fraction'] = config.get('digits_fraction', 8)

        numformat['min'] = config.get('min', None)
        numformat['max'] = config.get('max', None)

        # print 'get_numformat',attr,numformat
        return numformat

    def config(self, attr, default=None, **args):
        """
        Configure attribute for Object.
        """
        # print '\n\n\n'+70*'*'
        # print 'config',attr,default,args

        # configure attribute with template and parameters from args
        self._config[attr] = deepcopy(
            CONFIG_TEMPLATE)  # CONFIG_TEMPLATE.copy()

        # print '  after template configured attr:',attr,self._config[attr]

        # try to guess type...as default only
        t = get_type(default)
        self._config[attr]['type'] = t
        # print '  get_type(default)=',get_type(default)

        # guess read/write permissions according to toplevel type
        if TYPES.has_key(t[0]):
            self._config[attr]['perm'] = TYPES[t[0]]['perm']

        # default name
        self._config[attr]['name'] = attr

        if args.has_key('metatype'):
            # TODO: fetch here metatype info from metatype module
            pass
        else:
            self._config[attr]['metatype'] = ''  # default

        # overwrite all defaults with arguments
        self._config[attr].update(args)

        # print '  after update configured attr:',attr,self._config[attr]

        if type(self._config[attr]['type']) != types.ListType:
            self._config[attr]['type'] = [self._config[attr]['type']]

        # complete with numerical format info
        self._config[attr].update(self.get_numformat(attr))

        # store default value here,
        # in case of an array this is the value of a single entry
        self._config[attr]['default'] = default

        # check if attribute is an existing function and if yes register
        # as such in config
        self._config[attr]['is_function'] = False
        if hasattr(self, attr):
            if type(getattr(self, attr)) == types.MethodType:
                # print '  ',attr,'is a function'
                self._config[attr]['is_function'] = True
                # self._config[attr]['perm']='r' # read only

        if self._config[attr]['is_function']:
            # register attribute in function list
            self._functions.append(attr)
        else:
            self.reset(attr)

        # print '  configured attr:',attr,self._config[attr]

        # this turnes group argument in a list when given a signle string
        # TODO: would be better to introduce groups as a list with all group
        # names
        groupnames = self._config[attr]['group']
        if type(groupnames) == types.StringType:
            self._config[attr]['group'] = [groupnames, ]

        if (self._config[attr]['metatype'] == 'id'):
            # explictly declared as id
            # make sure of array structure
            self._config[attr]['struct'] = 'array'
            # TODO: better identify object as arrayobjconfiguaror

        # put attribute into id_ref or obj ref group
        # if no reference is made then put in id group
        if self._config[attr].has_key('ident_ref'):
            if self._config[attr]['struct'] == 'array':

                if 'id_ref' not in self._config[attr]['group']:
                    # print '  ident_ref detected id_ref for',attr
                    self._config[attr]['group'].append('id_ref')
                    self._config[attr]['metatype'] = 'id'
                    # print '  check template',CONFIG_TEMPLATE.copy()
            else:
                # print '  ident_ref detected obj_ref for',attr
                if 'obj_ref' not in self._config[attr]['group']:
                    self._config[attr]['group'].append('obj_ref')
                    self._config[attr]['metatype'] = 'obj'

        elif (self._config[attr]['metatype'] == 'id'):
            # and add it to id group
            if 'id' not in self._config[attr]['group']:
                self._config[attr]['group'].append('id')

        for groupname in self._config[attr]['group']:
            self.config_group(groupname, attr)

        # this is a treatment fo linked objects, which are
        # not a parent or a child of this objects
        # they ill not be saved, but recovered bu their ident during _init3
        if self._config[attr].has_key('link'):
            if self._config[attr]['link']:
                # try to recover object with ident
                # however, ident itself will only be stored during saving
                self._config[attr]['save'] = False
                self._config[attr]['perm'] = 'r'

    def reset(self, attr):
        """
        Reset atttribute attr to default values
        """
        # create attribute and if there are already arrays with entries,
        # create the same number of entries with default value
        # default=self._config[attr]['default']
        # struct=self._config[attr]['struct']

        # if self._config[attr]['is_function']:
        #    # register attribute in function list
        #    #self._functions.append(attr)
        #    # already done in config
        #    pass
        # else:
        # attr is a scalar , simply assign default
        if not self._config[attr]['is_function']:
            self.__dict__[attr] = self._get_default(attr)

    def set_default(self, attr, value):
        """
        Sets a default value for this attribute.
        """
        self._config[attr]['default'] = value

    def _get_default(self, attr):
        """
        Returns default value for attribute with name attr_name

        Usage:
            Return a scalar default 
            self._get_default('attr_name')    


        """
        default = self._config[attr]['default']
        # struct=self._config[attr]['struct']

        if type(default) == ndarray:
            obj = default  # .tolist()

        elif (type(default) == types.ClassType):
            if self._config[attr]['init']:
                # Default is a class, needs to be initialized
                # TODO: initialization and global id needs to be reviewed
                obj = default(self)

        else:
            # otherwise just copy default value
            obj = default

        # print '_get_default',obj
        return obj

    def set(self, attr, val=None):
        """
        Sets value to attribute.

        Usage:

        Set scalar variable var with value val
        self.set('var',val) 


        """

        if self._config['attr']['struct'] == 'scalar':  # exclude functions
            self.__dict__[attr] = val

        if self._plugins.has_key(1):
            self._execute_plugins(1, key)

    def is_config(self, attr):
        """
        Returns true if attribute with name attr is configured.
        """
        return self._config.has_key(attr)

    def copy_attrs(self, targetobj):
        """
        Copies  given list of scalar attributes of this object 
        to given target object.

        If no attributes are given then all attributes of this object 
        are considered for copying.

        copy an attribute, the foolowing conditions must be satisfied:
            - the attribute must be configured with key copy=True
            - the attribute must be configured in targetobject 
            - the structure of the attribute must be scalar 
                (arrays done by copy method of ArrayObjConfigurator)
        """
        if attrs == None:
            # get all attributes
            attrs = self._config.keys()

        for attr in attrs:
            config = self._config[attr]
            if config['struct'] == 'scalar':
                if config['copy']:
                    if targetobj.is_config(attr):
                        targetobj[attr] = self[attr]

    def get_attrs(self, crits_atleastone=[], crits_all=[]):
        """
        Returns list of configured attribute names.

        crits_atleastone and crits_all are lists defining one or several
        criteria that the attribute configuration must satify.
        for example: [('struct','array'),('struct','dict'),('struct','marray')]
        """
        attrs = []
        if len(crits_atleastone) > 0:
            # get attribute names for attributes where at least one criteria
            # is satisfied
            for attr in self._config.keys():
                for criteria in crits_atleastone:
                    # print 'get_attrs:',attr,criteria
                    if self._config[attr][criteria[0]] == criteria[1]:
                        attrs.append(attr)
                        break
            return attrs

        elif len(crits_all) > 0:
            # get attribute names for attributes where all criteria
            # are satisfied
            for attr in self._config.keys():
                satisfied = True
                for criteria in crits_all:
                    # print 'get_attrs:',attr,criteria
                    satisfied &= (self._config[attr][
                                  criteria[0]] == criteria[1])
                if satisfied:
                    attrs.append(attr)

            return attrs

        else:
            # no criteria spacified, return all attribute names
            return self._config.keys()

    def get_config(self, attr=''):
        # print '_get_config:',attr
        if attr:
            return self._config.get(attr, {})
        else:
            return self._config

    def get_root_instance(self):
        """
        Returns instance of root obj of the tree.
        """
        obj = self
        while obj.parent != None:
            obj = obj.parent

        return obj

    def get_obj_instance(self, ident):
        """
        Returns the instance of the object of the given identity string ident.

        The researched object must reside within the object tree where also
        the self object is a part.
        """
        if ident == '':
            return None

        elif ident[0] == '.':
            # ident starts with a . means that it is a relative link
            # starting with this object
            obj = self
            idents = string.split(self.get_ident(
                is_local=True) + ident, IDENTSEP)

        else:
            obj = self.get_root_instance()
            idents = string.split(ident, IDENTSEP)

        print 'get_obj_instance ', idents
        print '  root_instance=', obj
        if len(idents) == 1:
            # just one element identification, means this is root
            return obj

        elif idents[1] == '':
            return obj

        else:
            oldobj = obj
            oldident = ident
            for ident in idents[1:]:

                print '  get attr', ident, 'from obj', obj
                if ident.isdigit():  # it's an id so get arrayobject

                    print '    get it through object[attr,id]', oldobj, oldident, string.atoi(ident)
                    obj = oldobj[oldident, string.atoi(ident)]
                    oldobj = obj
                    oldident = ident

                elif ident == '':
                    oldobj = obj
                    # obj=obj # do not dive

                else:
                    oldobj = obj
                    oldident = ident
                    obj = getattr(obj, ident)

        return obj

    def create_group(self, name, attr_list=[]):
        # print 'create_group',name,attr_list
        if type(attr_list) == types.ListType:
            # print '  groups before=',self._groups.keys()
            self._groups[name] = attr_list
            # print '  groups after =',self._groups.keys()
        else:
            print 'WARNING: attr_list must be list type'

    def config_group(self, name, attr, **args):
        """
        Add or append attribute to given name.
        """
        # print 'config_group',self._groups,type(self._groups)
        # print '  name,attr',name,attr

        if self._groups.has_key(name):
            if attr not in self._groups[name]:
                # print '  before append',self._groups[name]
                self._groups[name].append(attr)
                # print '  after append',self._groups[name]

        else:
            self.create_group(name, [attr])

    def get_groupnames(self): return self._groups.keys()

    def get_group(self, name):
        """
        Returns a list with attribute names that belong to that group name.
        """
        # print 'get_group self._groups=\n',self._groups
        return self._groups.get(name, [])

    def get_groupattrs(self, name):
        """
        Returns a dictionary with all attributes of a group. 
        Key is attribute name and value is attribute value. 
        """
        attrs = {}
        for attr in self._groups[name]:
            attrs[attr] = self['attr']
        return attrs

    def get_perm(self, attr):
        """
        Returns current permission of attribute
        """
        return self._config[attr]['perm']

    def get_unit(self, attr, show_parentesis=True):
        """
        Returns unit of attribute
        """

        if self._config[attr].has_key('unit'):
            unit = self._config[attr]['unit']
        else:
            unit = ''

        if show_parentesis:
            if len(unit) > 0:
                unit = '[' + unit + ']'

        return unit

    def __getitem__(self, attr):
        # print '__getitem__',key

        # plugin execution
        if self._plugins.has_key(0):
            self._execute_plugins(0, attr)
        return self.__dict__[attr]

    def __setitem__(self, attr, value):
        """
        Sets a value to an attribute


        """

        # print 'setitem',key,'to',value

        self.__dict__[attr] = value

        # plugin execution
        if self._plugins.has_key(1):
            self._execute_plugins(1, attr)

    def __getstate__(self):
        # print '__getstate__',self.ident
        # print '  self.__dict__=\n',self.__dict__.keys()

        state = {}
        if hasattr(self, '_config'):

            # store ident for linked objects prior to saving
            # will be recovered in _init3
            for attr in self._config.keys():
                config = self._config[attr]

                if config.has_key('link'):
                    # try to recover object with ident
                    if config['link']:
                        if config['struct'] in ('array', 'dict', 'marray'):
                            # here we want to retain the idents of all objects
                            # in this array, using a dictionary with
                            # id as key and ident as value
                            config['ident'] = {}
                            for id in self.get_ids():
                                config['ident'][id] = self[
                                    attr, id].get_ident()
                        else:
                            config['ident'] = getattr(self, attr).get_ident()

            # print '  self._config.keys()',self._config.keys()
            for attr in self._attrs_save:
                state[attr] = getattr(self, attr)  # self.__dict__[attr]
                # print '  saved state:',attr,state[attr]

            # decide whether to save parent:
            # the root object does not save parent because outside the tree
            if len(string.split(self.ident, IDENTSEP)) > 1:
                # print '  save parent for',string.split(self.ident,IDENTSEP)
                state['parent'] = self.parent
            else:
                state['parent'] = None

            if hasattr(self, 'init_arrayobj'):
                # it is actually an array-object, save also id
                if hasattr(self, 'id'):
                    # print '  saved attr id',self.id
                    state['id'] = self.id

            # save which attributes to save
            state['_attrs_save'] = self._attrs_save

            # now save attributes which have been configured to save
            for attr in self._config.keys():
                # print '  ',self._config[attr]['save'],attr
                if self._config[attr]['save']\
                        & (not self._config[attr]['is_function'])\
                        & (not (type(getattr(self, attr)) == types.MethodType)):
                        # print '  save attr:',attr
                    state[attr] = getattr(self, attr)

            self._getstate(state)

        return state

    def _getstate(self, state):
        """
        Complete state dict with state variables which are not 
        contained in the config scheme. All attributes which are
        configured and the save option is not explicitely set
        to False are automatically inserted in the state dictionay.
        """
        pass

    def __setstate__(self, state):
        # print '__setstate__',self

        # this is always required, but will not be saved
        self._plugins = {}

        for key in state.keys():
            # print '  set state',key
            self.__dict__[key] = state[key]

        # done in init2_config...
        # set default values for all states tha have not been saved
        # for attr in self._config.keys():
        #    if (not self._config[attr]['save']) & (not hasattr(self,attr)):
        #        print '  config attr',attr
        #        self.config(attr,**self._config[attr])

        # set other states
        self._setstate(state)

    def _setstate(self, state):
        """
        Complete state settings of state variables which are not 
        contained in the config scheme. All attributes which are
        configured and the save option is not explicitely set
        to False are automatically set.
        """
        pass

    def close(self):
        """
        Should be called before desroying the object.
        Does remove pugs is existent.
        """
        if hasattr(self, unplugout):
            self.unplugout()


class ArrayObjConfigurator(ObjConfigurator):

    """
    Base class for general scalar object configuration.

    For usage see demo classes below.
    """

    def init_config(self, ident='', parent=None, name='noname', named=False,
                    **args):
        """
        Fore named objects use:
            self.add_id_named('name_of_id')
        """
        # print 'init_config array',ident,hasattr(self,'init_plugin')
        ObjConfigurator.init_config(self, ident, parent, name, **args)

        # else:
        # print 'no array plugins for ',self.ident

        # print 'check config'#,self.ident,self._config
        self._arrayconfig = {}
        self._dictconfig = {}
        self._inds = zeros((0,), int)
        self._ids = zeros((0,), int)
        self._marrayconfig = {}
        self._named = named
        if self._named:
            self._id_names = {}
            self.config('_name_ids', '', struct='dict',
                        info='Dictionary with id as key and name as value')
        else:
            self._id_names = None

        # save these attributes, apart from configured ones
        self._attrs_save += ['_arrayconfig', '_dictconfig', '_inds', '_ids',
                             '_marrayconfig', '_named', '_id_names']

    def is_named(self):
        """
        Returns true if array has named rows
        """
        return self._named

    def get_id_from_name(self, name):
        """
        Returns id that corresponds to name.
        """
        return self._id_names.get(name, -1)

    def get_name_from_id(self, id):
        """
        Returns name that corresponds to id.
        """
        return self._name_ids.get(id, '')

    def get_names(self):
        """
        Returns list of all named ids.
        """
        # print 'get_names',self.ident,self._id_names.keys()
        return self._id_names.keys()

    def get_named(self, attr, name):
        """
        Returns value corresponding to named id
        """
        return self[attr, self.get_id_from_name(name)]

    def get_ids(self, inds=[], ordered=False):
        """
        Return all ids corrisponding to array indexes inds.
        Options:
            if no inds are given, all ids are returnd

            if ordered is true, ids will be sorted before they are returned.

        """
        if (len(inds) > 0) & (not ordered):
            return take(self._ids, inds)

        elif len(inds) > 0:
            ids = take(self._ids, inds)

        else:
            ids = self._ids.copy()
        if ordered:
            return sort(ids)
        else:
            return ids

    def get_id(self, ind):
        """
        Returns scalar id corresponding to index ind
        """
        # print 'get_id',ind,self._ids
        return self._ids[ind]

    def is_scalarid(self, id):
        """
        Returns True if id is a zero positive scalar interger
        """
        if is_integer(id):
            if id >= 0:
                return True
            else:
                return False
        else:
            return False

    def is_idarray(self, ids):
        """
        Fast, formal chack whether ids is either a valid array with ids.
        """
        if type(ids) in (types.ListType, ndarray):
            # it is an array
            if len(ids) > 0:
                # it contains at least one id
                # return True if this id is a zaro positive integer
                return self.is_scalar_id(ids[0])
            else:
                return False
        else:
            return False

    def is_ids(self, ids):
        """
        Formal check whether ids contains either an array with ids
        or is a scalar zero positive interger.
        """
        return self.is_idarray(ids) | self.is_scalarid(ids)

    def select_ids(self, mask):
        """
        Returns an array of ids, corresponding to the True
        of the mask array.

        Usage:
            Select all ids for which array of attribute x is greater than zero.
            ids=obj.select_ids( obj.x>0 )
        """
        # print 'select_ids',mask,flatnonzero(mask)
        # print '  self._ids=',self._ids

        return take(self._ids, flatnonzero(mask))

    # def select(self,mask,ordered=False):
    #    """
    #    Returns an array of ids, corresponding to the True
    #    of the mask array.
    #
    #    Usage:
    #        Get all elements of attribute y for which array of attribute x is greater than zero.
    #        values=obj.select(obj.y, obj.x>0 )
    #    """
    #
    #
    #    return self.get_ids(flatnonzero(mask),ordered=ordered)

    def get_ids_marray(self, attr, inds_marray=[]):
        """
        Return all ids and relative indexes corresponding to m-array 
        indexes in list inds_marray.

        The relative index is the index within the array corresponding
        to an id.

        Examples:
            obj.get_ids_marray('attrname',[2,3,4])

            returns an array of the following shape:
            [[11,0],
             [11,1],
             [12,0],]

            here marray index 2 and 3 correspond to id=11 with relative index
            0 and 1 respectively, while marray index 3 corresponds to 
            element with id=12 and relative index 0 
            (means first item in element with id=12)

        """
        # print 'get_ids_marray',inds_marray
        if len(inds_marray) > 0:
            # case more complex because need to check with block pointers

            # get block pointers for this attribute
            bp = self._marrayconfig[attr]['bp']
            inds = zeros((len(inds_marray)), int)

            i = 0
            for ind_marray in inds_marray:
                # print '  bp, ind_marray',bp,ind_marray
                inds[i] = flatnonzero(
                    (bp[:, 0] <= ind_marray) & (bp[:, 1] > ind_marray))[0]
                i += 1
            inds_delta = inds_marray - take(bp[:, 0], inds)

            ids = take(self._ids, inds)
        else:
            ids = []
            inds_delta = []

        return concatenate((transpose([ids]), transpose([inds_delta])), (1))
        # return reshape(  concatenate((ids, inds_delta)) ,(-1,2) )

    def get_inds(self, ids=None):
        if ids != None:
            return self._inds[ids]
        else:
            return self._inds[self._ids]

    def get_ind(self, id):
        return self._inds[id]

    def get_inds_marray(self, attr, ids):
        """
        Returns a flat array with all array indexes of 
        marray with attribute attr that have an id contained in list ids. 
        """
        # get block pointers for this attribute
        bp = self._marrayconfig[attr]['bp']
        inds = []
        # print 'get_inds_marray: ids=',ids
        # print 'get_inds_marray: self._inds= ',self._inds
        # print 'get_inds_marray: self._inds[ids,:]= ',self._inds[ids,:]
        # Numeric
        # for i,j in take(bp, take(self._inds,ids) ):
        for i, j in bp[self._inds[ids], :]:
            # print '  i,j=',i,j
            inds += range(i, j)

        # print '  inds=',   array(inds,int)
        return array(inds, int)

    def suggest_id(self, zeroid=False):
        """
        Returns a an availlable id.

        Options:
            zeroid=True allows id to be zero.

        """
        return self.suggest_ids(1, zeroid)[0]

    def suggest_ids(self, n, zeroid=False):
        """
        Returns a list of n availlable ids.
        It returns even a list for n=1. 

        Options:
            zeroid=True allows id to be zero.
        """
        # print
        # 'suggest_ids',n,zeroid,self._inds,len(self._inds),self._inds.dtype
        ids_unused_orig = flatnonzero(less(self._inds, 0))

        if not zeroid:
            if len(self._inds) == 0:
                ids_unused = zeros(0, int)
            else:
                # avoid 0 as id:
                # ids_unused=take(ids_unused,flatnonzero(greater(ids_unused,0)))
                # print '  ids_unused_orig',ids_unused_orig,type(ids_unused_orig)
                # print '  len(ids_unused_orig)',len(ids_unused_orig),ids_unused_orig.shape
                # print '  greater(ids_unused_orig,0)',greater(ids_unused_orig,0)
                # print '  len(greater(ids_unused_orig,0))',len(greater(ids_unused_orig,0))
                # print '  flatnonzero(greater(ids_unused_orig,0))',flatnonzero(greater(ids_unused_orig,0))
                # print '
                # len(flatnonzero(greater(ids_unused_orig,0)))=',len(flatnonzero(greater(ids_unused_orig,0))
                # )
                ids_unused = ids_unused_orig[
                    flatnonzero(greater(ids_unused_orig, 0))]
            zid = 1
        else:
            if len(self._inds) == 0:
                ids_unused = zeros(0, int)
            else:
                ids_unused = ids_unused_orig.copy()

            zid = 0

        n_unused = len(ids_unused)
        n_max = len(self._inds) - 1
        # print '  ids_unused',ids_unused
        # print '  ids_unused.shape',ids_unused.shape
        # print '  len(ids_unused)',len(ids_unused)
        # print '  n_unused,n_max,zid=',n_unused,n_max,zid

        if n_max < zid:
            # first id generation
            ids = arange(zid, n + zid)

        elif n_unused > 0:
            if n_unused >= n:
                ids = ids_unused[:n]
            else:
                # print '  ids_unused',ids_unused
                # print '  from to',n_max+1,n_max+1+n-n_unused
                # print '  arange=',arange(n_max+1,n_max+1+n-n_unused)
                # print '  type(ids_unused)',type(ids_unused)
                # print '  dtype(ids_unused)',ids_unused.dtype
                ids = concatenate(
                    (ids_unused, arange(n_max + 1, n_max + 1 + n - n_unused)))

        else:
            ids = arange(n_max + 1, n_max + 1 + n)

        return ids  # .tolist()

    def add_id_named(self, name, id=-1, **args):
        """
        Creates array entries for id with given name.

        """
        if id < 0:
            id = self.suggest_id()
        # self._name_ids[name]=id
        # print 'add_id_named',self.ident,name,'with id',id
        self.create_ids(id, _name_ids=name, **args)
        return id

    def create_ids(self, ids, **args):
        """
        Creates for each id in ids list an entry for each attribute with 
        array or marray structure.

        If ids is a scalar integer, entries will be generated just for
        this id. 

        For named objects the list _name_ids_ is necessary 
        with a name correisponding to each id.  
        """
        # print 'create_ids',ids,args
        # this is a short dirty way to allow also scalars for ids and arguments
        if type(ids) not in ARRAYTYPES:
                # turn scalar ids in list-vector...
            ids = [ids]
            for key in args.keys():
                args[key] = [args[key]]

        # print '  create_ids',ids,args

        # no ids to create
        if len(ids) == 0:
            return True

        n = len(ids)
        id_max = max(ids)
        id_max_old = len(self._inds) - 1
        n_array_old = len(self)

        ids_existing = take(ids, flatnonzero(less(ids, id_max_old)))
        # print '  ids',ids,'id_max_old',id_max_old,'ids_existing',ids_existing

        # check here if ids are still available
        if sometrue(not_equal(take(self._inds, ids_existing), -1)):
            print 'WARNING in create_ids: some ids already in use', ids_existing
            return False

        # extend index map with -1 as necessary
        if id_max > id_max_old:
            # print 'ext',-1*ones(id_max-id_max_old)
            self._inds = concatenate(
                (self._inds, -1 * ones(id_max - id_max_old, int)))

        # assign n new indexes to new ids
        ind_new = arange(n_array_old, n_array_old + n)

        # print 'ind_new',ind_new
        put(self._inds, ids, ind_new)

        # print '  concat ids..',self._ids,ids
        self._ids = concatenate((self._ids, ids))

        # if each id is supposed to have a _name_ids
        # arguments must provide a list with names for each id
        if self._named:
            i = 0
            names = args['_name_ids']
            for id in ids:
                # print '  id,names[i]',id,names[i]
                self._id_names[names[i]] = id
                i += 1

        # Extend all arrays with n values from args or default
        for attr in self._arrayconfig.keys():
            # print '  attr',attr
            if args.has_key(attr):
                value = args[attr]
                if self._config[attr]['do_init_arrayobj']:
                    # newly assigned instances need to be array initialized
                    for i in range(len(ids)):
                        value[i].init_arrayobj(ids[i], self,
                                               self.make_item_ident(attr, ids[i]))
            else:
                value = self._get_default(attr, ids=ids)

            # print '
            # ',attr,'self.__dict__[attr]',self.__dict__[attr],'value',value
            if len(self.__dict__[attr]) > 0:
                # print '  concat item..',value
                self.__dict__[attr] = concatenate((self.__dict__[attr], value))
            else:
                # tc=self._config[attr]['dtype']
                # print '  first item with tc',tc,'and value',value
                # print '  ', array(value,dtype=tc)[0]
                # self.__dict__[attr]=array(value,dtype=tc)

                # print '  let NumPy, Numeric or whatever guess the first
                # arrayelement'
                self.__dict__[attr] = array(value)

        # Extend all marrays with n values from args or default
        for attr in self._marrayconfig.keys():

            # generate a scalar/list of copies of defaults
            items = args.get(attr, self._get_default(attr, ids=ids))
            self._append_items_marray(attr, ids, items)

        # assign defaults to all dicts
        for attr in self._dictconfig.keys():
            i = 0
            for id in ids:
                if args.has_key(attr):
                    value = args[attr][i]
                    if self._config[attr]['do_init_arrayobj']:
                        # print 'initialize',attr,value
                        value.init_arrayobj(
                            id, self, self.make_item_ident(attr, id))
                else:
                    value = self._get_default(attr, ids=id)

                # print '  dict attr=',attr,value
                self.__dict__[attr][id] = value

                i += 1

        if self._plugins.has_key(23):
            self._execute_plugins(23, ids=ids)

        return True

    def print_attr(self, attr):

        config = self.get_config(attr)
        if config:

            if config['struct'] == 'array':
                # print '   ', attr,'='
                for id in self.get_ids():
                    if config['is_function']:
                        val = self.__getitem__((attr, id))
                    else:
                        val = self.__getitem__((attr, id))

                    print self.get_string_arrayattr(attr, id, val)

            elif config['struct'] == 'marray':
                # print '   ', attr,'='
                for id in self.get_ids():
                    if config['is_function']:
                        val = self.__getitem__((attr, id))
                    else:
                        val = self.__getitem__((attr, id))

                    print self.get_string_arrayattr(attr, id, val)

                    # print '   ',id,self._inds[id],\
                    #    val,config['unit']

            elif config['struct'] == 'dict':
                print '   ', attr, '='
                for id in self.get_ids():
                    val = self.__dict__[attr][id]
                    print self.get_string_arrayattr(attr, id, val)

                    # print '   ',id,self._inds[id],\
                    #    self.__dict__[attr][id],config['unit']

            else:
                ObjConfigurator.print_attr(self, attr)

    def get_string_arrayattr(self, attr, id, value):
        """
        Returns a formatted string for array type attributes 
        with struct array, marray, dict 
        """
        # print 'get_string_arrayattr',attr,id,value
        return '   ' + attr + '[' + str(id) + '] = ' +\
            self.get_string_attr_value(attr, value)

    def reset(self, attr):
        """
        Reset attribute attr to default values
        """
        # create attribute and if there are already arrays with entries,
        # create the same number of entries with default value
        # print 'reset',attr,len(self)
        default = self._config[attr]['default']
        struct = self._config[attr]['struct']
        # declaredtype=self._config[attr]['type'][0]

        # configure if objects or instances need init_arrayobj with id
        # self._config[attr]['do_init_arrayobj']=False # moved to default
        if struct in ('array', 'marray', 'dict'):
            # try to detect from defaults
            if type(default) in [types.InstanceType, types.ClassType]:
                if hasattr(default, 'init_arrayobj'):
                    # print '  detected init_arrayobj!!'
                    self._config[attr]['do_init_arrayobj'] = True

                # done in config
                # elif type(default) == types.ClassType:
                #    if not self._config[attr].has_key('init'):
                #        # by default do not initialize classes
                #        # i they are nor arrayconfiguratored
                #        self._config[attr]['init']=False

            # check if instance or class type have been declared
            # if self._config[attr]['type'] in ['InstanceType','ClassType']:
            #    self._config[attr]['do_init_arrayobj']=True

        # do reset now
        if struct == 'array':
            # generate a scalar/list of copies of defaults
            defaults = self._get_default(attr, ids=self.get_ids())
            # print 'len:',self.__len__(),len(self)

            # register attribute in array database
            # currently no particular info, just key
            self._arrayconfig[attr] = {}

            # print 'reset',attr

            # all this not very clean, but works
            default = self._config[attr]['default']  # the array element
            if type(default) == ndarray:
                # use dtype given by default element which is an array
                tc = default.dtype.str
            else:
                # guess dtype from scalar types
                tc = get_dtype(self._config[attr]['type'][-1])

            self._config[attr]['dtype'] = tc

            # print '  tc=',tc,'type[-1]=',self._config[attr]['type'][-1]
            # this print causes a strange error:
            # 'FloatCanvas' object has no attribute 'this'

            self.__dict__[attr] = array(defaults, dtype=tc)

            # print '  created
            # type',self.__dict__[attr].dtype,self.__dict__[attr].shape

            # self.__dict__[attr]=array(\
            #    self._get_default(attr,ids=self.get_ids()), dtype=tc )

            # print 'new array',self.__dict__[attr]

        elif struct == 'marray':

            # register attribute in array database
            self._marrayconfig[attr] = {'bp': zeros((0, 2), int)}

            tc = get_dtype(self._config[attr]['type'][-1])
            self._config[attr]['dtype'] = tc

            # create new attribute with empty array
            # will be determined with first append
            self.__dict__[attr] = zeros((0), dtype=tc)

            # generate a scalar/list of copies of defaults
            ids = self.get_ids()
            defaults = self._get_default(attr, ids=ids)

            # print 'dtype',tc,default,'type =',self._config[attr]['type']
            if len(self._inds) > 0:
                self._append_items_marray(attr, ids, defaults)

            # print 'reset: new marray',self.__dict__[attr]

        elif struct == 'dict':
            # new attribute is a dictionary
            ids = self.get_ids()
            defaults = self._get_default(attr, ids=self.get_ids())

            # currently no particolar info, just key
            self._dictconfig[attr] = {}
            self.__dict__[attr] = {}
            # assign default value for each already existing id
            for i in range(len(ids)):
                id = ids[i]
                self.__dict__[attr][id] = defaults[i]

            # print 'reset: new dict',attr,'=',self.__dict__[attr]

        else:
            # handle other (scalar) attribute types with base configurator
            ObjConfigurator.reset(self, attr)

    def copy_attrs(self, targetobj, ids=None, targetids=None, attrs=None):
        """
        Copies  given list of attributes of this object to given target object.

        If no attributes are given then all attributes of this object 
        are considered for copying.

        To copy an attribute, the foolowing conditions must be satisfied:
            - the attribute must be configured with key copy=True
            - the attribute must be configured in targetobject 
        """
        if attrs == None:
            # get all attributes
            attrs = self._config.keys()

        if ids == None:
            # first copy all scalars
            ObjConfigurator.copy(targetobj)
            ids = self.get_ids()

        for attr in attrs:
            config = self._config[attr]
            if config['struct'] != 'scalar':
                if config['copy']:
                    if targetobj.is_config(attr):
                        targetobj[attr, targetids] = self[attr, ids]

    def add_items(self, n=0, **args):
        """
        Add new items into array structure.
        The ids for each newly created item are returned in an array.
        Usage:

            Add 3 new items:
            ids=obj.add_items(3)

            Add 3 new items and setting attributes:
            ids=obj.add_items(x=[11,22,33],v=[66,777,8888])

            Add a single new item and set values
            ids=obj.add_items(x=9,v=999)

            Add a single  multi array element composed of 2 scalar integers:
            ids=obj.add_items(s=[[111,2222]])

        """

        # determine number of items to be assigned
        if n == 0:
            if args:
                key = args.keys()[0]
                val = args[key]
                if type(val) not in ARRAYTYPES:
                    # turn scalar val in list-vector...
                    args[key] = [val]
                    n = 1
                else:
                    n = len(val)
            else:
                # add by default one item only
                n = 1
        else:
            pass  # use n from args

        # print 'base.add_items',n

        # determine new id
        ids = self.suggest_ids(n)

        # print ' create new ids',ids
        self.create_ids(ids, **args)

        # set values to attributes in arguments
# for attr in args.keys():
# if attr in self._config.keys():
# print attr,' before =' #,self.__dict__[attr]
# if self._config[attr]['struct']=='array':
# print '  insert in array',args[attr][0]
# print self._inds,ids,self._inds[ids]
# put(self.__dict__[attr],take(self._inds,ids),args[attr])
# print attr,' after =',self.__dict__[attr]
# elif self._config[attr]['struct']=='marray':
# for i in range(n):
# self._insert_item_marray(attr,ids[i],args[attr][i])
##
##
# elif self._config[attr]['struct']=='dict':
# for i in range(n):
# self.__dict__[attr][ids[i]]=args[attr][i]
# print '   dict',attr,self.__dict__[attr][ids[i]]
##
# else:
# print 'WARNING in add_items: unknown attribute:',attr

        return ids

    def __contains__(self, id):
        if (id < len(self._inds)) & (id >= 0):
            return self._inds[id] > -1
        else:
            return False

    def contains_name(self, name):
        return self._id_names.has_key(name)

    def __len__(self):
        """
        Determine current array length (same for all arrays)
        """

        return len(self._ids)

    # def get_index(self,ids):
    #    """
    #    returns index array from ids array
    #    Attetion thyis opration caused a crash during call from __del__
    #    """
    #    #print 'index',self._inds.dtype,type(ids),array(ids,int).dtype,len(ids)
    #
    #    return self._inds[array(ids,int)]
    #    #if type(ids) in ARRAYTYPES:
    #    #    #return take(self._inds,ids)
    #    #    return self._inds[array(ids,int)]
    #    #else:
    #    #    return self._inds[ids]

    def get_attr_named(self, attr, name):
        """
        Returns value of array element of attribute attr
        wich corresponds to id the given name.

        """
        if self._id_names.has_key(name):
            return self[attr, self._id_names[name]]
        else:
            return None

    def set_attr_named(self, attr, name, value):
        """
        Returns value of array element of attribute attr
        wich corresponds to id the given name.

        """
        self[attr, self._id_names[name]] = value

    def __getitem__(self, key):
        # print '__getitem__',key

        if type(key) != types.TupleType:
            # return entire contents of attribure for all ids
            attr = key
            struct = self._config[attr]['struct']
            if struct == 'scalar':
                if self._plugins.has_key(2):
                    self._execute_plugins(2, attr)

                if self._config[attr]['is_function']:
                    return getattr(self, attr)()
                else:
                    return self.__dict__[attr]

            else:
                # attribute is a kind of array
                # take all ids in ascending order
                ids = self.get_ids(ordered=True)
        else:
            # argument specify also id or ids to be returned
            attr, ids = key
            struct = self._config[attr]['struct']

        if type(ids) in ARRAYTYPES:
            # return array or list corresponding to ids
            # print 'get array types',attr,ids,struct
            # print '  self._inds=',self._inds
            # ids=array(ids,int)
            # print '  type (attr),type(ids)',type(self.__dict__[attr]),type(ids)
            # print '  ids.dtype 1=',ids.dtype
            # ids=array(ids,int)
            # print '  ids.dtype 2=',ids.dtype
            # print '  self._inds[ids]=',self._inds[ids]
            # print '  array(ids,int).dtype=',array(ids,int).dtype
            # executes plugins before values are returned to calling instance!!
            if self._plugins.has_key(22):
                self._execute_plugins(22, attr=attr, ids=ids)

            # this avoids problems with zero dimension arrays,
            # (bizzar but possible)

            #if ids.shape==(): ids=array([ids])
            # print '  get array type ids=',ids,struct

            if struct == 'array':
                if self._config[attr]['is_function']:
                    # print 'inds=',take(self._inds,ids)
                    return take(getattr(self, attr)(), take(self._inds, ids))
                else:
                    # print 'inds=',take(self._inds,ids)
                    # print take(self.__dict__[attr],take(self._inds,ids))
                    # return take(self.__dict__[attr],take(self._inds,ids))
                    return self.__dict__[attr][self._inds[array(ids, 'i')], :]

            elif struct == 'marray':
                # here an array is returned with all elements of the
                # those blocks that corresponds to the ids
                # Note that this is a homogenious array ,
                # arrays with single blocks can be obtained by passing
                # a single array.
                if self._config[attr]['is_function']:
                    return getattr(self, attr)()[self.get_inds_marray(attr, ids), :]
                    # Numeric:
                    # return take(getattr(self,attr)(),
                    #        self.get_inds_marray(attr,ids))
                else:

                    # print '  inds_marray=',self.get_inds_marray(attr,ids)
                    # print '  self.__dict__[attr]=\n',self.__dict__[attr]
                    # print '
                    # return=\n',self.__dict__[attr][self.get_inds_marray(attr,ids),:]
                    return self.__dict__[attr][self.get_inds_marray(attr, ids), :]
                    # Numeric:
                    # return take(self.__dict__[attr],
                    #        self.get_inds_marray(attr,ids))

            elif struct == 'dict':
                items = []
                for id in ids:
                    # print '  ',id,self.__dict__[attr][id]
                    items.append(self.__dict__[attr][id])
                return items

            # this will never be executed!!!!!!!!!!!
            # if self._plugins.has_key(22):
            #    self._execute_plugins(22,ids=ids)

        else:
            # print 'return one array element, ids is a single id'
            if self._plugins.has_key(22):
                self._execute_plugins(22, attr, ids=array([ids], int))

            if struct == 'array':
                # print 'inds=',take(self._inds,[ids]),attr,getattr(self,attr)

                if self._config[attr]['is_function']:
                    return getattr(self, attr)()[self._inds[ids]]
                else:
                    # try:
                    return self.__dict__[attr][self._inds[ids]]
                    # except:
                    #    print 'ERROR in __getitem__', attr,ids
                    #    print '  inds=',self._inds[ids]
                    #    print '  attr=',self.__dict__[attr]

            elif struct == 'marray':
                # here an array is returned with all elements of the
                # block that corresponds to this id
                if self._config[attr]['is_function']:
                    return getattr(self, attr)()[self.get_inds_marray(attr, [ids])]
                    # Numeric
                    # return take(getattr(self,attr)(),
                    #        self.get_inds_marray(attr,[ids]))
                else:
                    # print 'ids=',ids
                    # print
                    # 'self.get_inds_marray(attr,[ids]))=',self.get_inds_marray(attr,[ids])
                    return getattr(self, attr)[self.get_inds_marray(attr, [ids])]
                    # Numeric:
                    # return take(self.__dict__[attr],
                    #        self.get_inds_marray(attr,[ids]))

            elif struct == 'dict':
                # print 'attr=',attr,ids
                return self.__dict__[attr][ids]

    def __setitem__(self, key, value):
        """
        Sets a value to an attribute
        or to one or several elements of an attribute if
        a list with ids is passed.

        Usage:
            Scalar assignment
            obj['attrname']=0.0

            Single element asignment
            obj['attrname',3]=33

            Assign 11,22,33 to elements with ids 1,2,3 of attribite attrname
            obj['attrname',[1,2,3]]=[11,22,33]

            Assign 3 elements of different size to marray
            obj['attrname',[1,2,3]]=[[11,12,13],[21,22],[31]]
            Note that the assigned value must be a python list of elements
            and not a Numpy array

        """

        # print 'setitem',key,'to',value

        if type(key) != types.TupleType:
            self.__dict__[key] = value
            if self._plugins.has_key(1):
                self._execute_plugins(1, key)
            return

        else:
            attr, ids = key
            if type(ids) not in ARRAYTYPES:
                # ids is a scalar->make a list
                ids = array([ids], int)
                value = [value]

            struct = self._config[attr]['struct']
            # print 'inds=',self.get_index(ids)
            if struct == 'array':
                shape = self.__dict__[attr].shape
                if len(shape) == 1:
                    # print 'put value',value,type(value)
                    # print '  attr,type(attr)',attr,type(self.__dict__[attr])
                    # print '  dtype(attr)',self.__dict__[attr].dtype
                    # print '
                    # self.get_index(ids)=',self.get_index(ids),type(self.get_index(ids)),self.get_index(ids).dtype

                    self.__dict__[attr][self._inds[array(ids, 'i')]] = value
                    # put(self.__dict__[attr],self.get_index(ids),value)

                    if self._config[attr]['do_init_arrayobj']:
                        # newly assigned instances need to be array initialized
                        for i in range(len(ids)):
                            value[i].init_arrayobj(ids[i], self,
                                                   self.make_item_ident(attr, ids[i]))

                else:
                    # this is an array of matrix or tensors or higher order
                    # the array must be flattened and the indexes must be
                    # calculated accordingly

                    # m=product(shape[1:])
                    # print 'put marray',m,
                    #inds=ones( (len(ids),1),int )*arange(m)\
                    #    +transpose([take(self._inds,ids)])*m
                    # print inds

                    # print 'put value matrix',value,type(value)
                    # print '  attr,type(attr)',attr,type(self.__dict__[attr])
                    # print '  dtype(attr)',self.__dict__[attr].dtype
                    # print '  inds=\n',self._inds[ids]

                    if type(value) != ndarray:
                        # print 'value',value
                        value = array(value, dtype=self._config[attr]['dtype'])
                        # print 'value',value

                    self.__dict__[attr][self._inds[ids], :] = value
                    # Numeric
                    #put(self.__dict__[attr],inds.ravel(), value.ravel())

            if struct == 'marray':
                for i in range(len(ids)):
                    self._insert_item_marray(attr, ids[i], value[i])

            elif struct == 'dict':
                for i in range(len(ids)):
                    self.__dict__[attr][ids[i]] = value[i]
                    if self._config[attr]['do_init_arrayobj']:
                        # newly assigned instances need to be array initialized
                        # self.print_config()
                        value.init_arrayobj(
                            id, self, self.make_item_ident(attr, id))
                        # self.print_config()

            # print 'set_item:check plugins...',self.ident,self._plugins.keys()
            if self._plugins.has_key(21):
                self._execute_plugins(21, attr=attr, ids=ids)

            return

    def del_item_named(self, name):
        """
        Deletes id with given name from all attributes
        """
        del self[self._id_names[name]]

    def __delitem__(self, key):
        # print 'ArrayObjConfigurator.__delitem__',self.ident,'key=',key
        if key in self._config.keys():
            # delete attribute and its configuration
            if self._plugins.has_key(0):
                self._execute_plugins(0, key)

            if self._config[key]['struct'] == 'array':
                del self._arrayconfig[key]
            elif self._config[key]['struct'] == 'dict':
                del self._dictconfig[key][id]
            elif self._config[key]['is_function']:
                self._functions.remove(key)

            for groupname in self._config[key]['group']:
                self._groups[groupname].remove(key)

            del self._config[key]
            del self.__dict__[key]

        else:
            # key is one or multiple ids to be deleted from arrays
            if type(key) not in ARRAYTYPES:
                # ids is a scalar->make a list
                ids = [key]
            else:
                ids = key

            # TODO: here it is not verified whether ids exist
            #  => verify and delete element by element

            # plugin execution BEFORE entry is deleted
            if self._plugins.has_key(20):
                self._execute_plugins(20, ids=ids)

            self._del_ids(ids)

    ##########################################################################
    # private methods

    def _append_items_marray(self, attr, ids, items):
        """
        Appends a list of items to multiary with attribute attr.
        The block pointers are created automatically but
        the indexes and ids must already exist in self._inds 

        ids cannot be empty!
        """
        # print 'append_items_marray',attr
        # print '  ids=',ids
        # print '  items=',items
        marray = self.__dict__[attr]
        # print 'marray=\n',marray
        bp = self._marrayconfig[attr]['bp']
        len_bp = len(bp)

        # make sure that the bp vecor has enough index

        ind_max = max(self._inds)

        bpext = -1 * ones((ind_max - len_bp + 1, 2), int)

        if len_bp == 0:
            bp = bpext
        else:
            bp = concatenate((bp, bpext))
        # print '  after extension bp=',bp

        # set block pointers for each id according to length of each item
        i = len(marray)
        n_elems = 0  # gives the total number of elements inside all items
        for ii in range(len(ids)):
            id = ids[ii]
            ind = self._inds[id]

            # assume that id corresponds to a list with at least one item
            # thus, calculate new block pointers
            n = len(items[ii])
            j = i + n
            n_elems += n
            # print '  id,ind,i,j,len(items[ii])=',id,ind,i,j,len(items[ii])

            bp[ind] = [i, j]

            i = j

        # print '  after asssignment bp=',bp
        self._marrayconfig[attr]['bp'] = bp

        # put items in an array with coherent dimentions
        shape_elem = array(items[0], int).shape[1:]
        shape_array = [n_elems] + list(shape_elem)
        # print ' shape_elem=',shape_elem
        # print ' shape_array=',shape_array
        # extend current marray by the corrct number of new elements
        marrayext = zeros(shape_array, dtype=self._config[attr]['dtype'])
        if len(marray) > 0:
            # print '  concat extention to marray=\n',marrayext
            marray = concatenate((marray, marrayext))
        else:
            # print '  first  marray_extension=\n',marrayext
            marray = marrayext

        # now copy items into array is faster than concatenating each item
        for ii in range(len(ids)):
            id = ids[ii]
            ind = self._inds[id]
            i, j = bp[ind]
            # print '   add item items[ii]',items[ii]
            marray[i:j] = items[ii]

        self.__dict__[attr] = marray

    def _insert_item_marray(self, attr, id, item):
        # print 'insert_item_marray',attr,id,item
        # print '  attr=', self.__dict__[attr]

        # get block pointers for this attribute
        bp = self._marrayconfig[attr]['bp']

        # index of block pointers
        ind = self._inds[id]

        # get from to index of m array for this id
        [i, j] = bp[ind]

        # decide whether to overwrite existing
        if j - i != len(item):
            # first cut current data out of marray and adjust
            # block pointers
            self._del_item_marray(attr, id)

            # append data
            self._append_items_marray(attr, [id], [item])
        else:
            self.__dict__[attr][i:j] = item

        # print '  attr=', self.__dict__[attr]

    def _del_item_marray(self, attr, id):

        # get block pointers for this attribute
        bp = self._marrayconfig[attr]['bp']

        # index of block pointers
        ind = self._inds[id]

        # get from to index of m array for this id
        [i, j] = bp[ind]

        # print 'del_item_marray',attr,id,'from',i,'to',j

        # cut this piece out of the marray
        # print '  before:',self.__dict__[attr]
        self.__dict__[attr] = concatenate(
            (self.__dict__[attr][:i], self.__dict__[attr][j:]))

        # print '  after:',self.__dict__[attr]

        # indicate that block pointer does no more point to anywhere
        # calling method must take care of eliminating it or not
        bp[ind] = [-1, -1]
        # cut out index from blockpointers
        #bp=concatenate( (bp[:ind], bp[ind+1:]) )

        # now subtract j-i from all "to" index higher equal than j
        subtract(bp, (j - i) * (bp >= j), bp)

        self._marrayconfig[attr]['bp'] = bp

    # def _get_bp_marray(self,attr):
    #    """May be useful, just not used """
    #    return self._marrayconfig[attr]['bp']

    def make_item_ident(self, attr, id):
        """
        Generates the ident of attribute attr withy id.
        """
        return self.ident + IDENTSEP + attr + IDENTSEP + str(id)

    def get_groupattrs(self, name, id=-1):
        """
        Returns a dictionary with all attributes of a group. 
        Key is attribute name and value is attribute value for the given id. 
        """
        # print 'get_groupattrs  of',name,'from',self.ident,self._groups.keys()
        # print '  id=',id
        attrs = {}

        if (name in self._groups.keys()) & self.is_ids(id):
            for attr in self._groups[name]:
                # attrs[attr]=self['attr']
                struct = self._config[attr]['struct']
                if (struct in ('dict', 'array', 'marray')):
                    default = self[attr, id]
                    # if default is an initialized class or an instance
                    # and has also a dict or array structure,
                    # then try to configure array object with id

                    if type(default) == types.InstanceType:
                        # default is instance so just make a copy
                        obj = copy(default)
                        # now configure array object
                        # in this case class must have ArrayObj capabilities (mixin)
                        # if self._config[attr]['do_init_arrayobj']:
                        #    obj.init_arrayobj(id,self,self.make_item_ident(attr,id))

                    elif (type(default) == types.ClassType) & \
                            self._config[attr]['do_init_arrayobj']:
                        # default is a class that needs to be initialized first
                        obj = copy(default)
                        # obj.init_arrayobj(id,self,self.make_item_ident(attr,id))

                    elif type(default) == types.FunctionType:
                        # use base function to get other default types
                        obj = default

                    else:
                        # use base function to get other default types
                        obj = copy(default)

                else:
                    # use base function to get other default types
                    obj = self.__dict__[attr]  # attr() copy(default)

                attrs[attr] = obj
        # else:
        #    print '  no attr found',self._groups.keys()
        # print '  attrs=',attrs
        return attrs

    def _get_default(self, attr, n=1, ids=None):
        """
        Returns n default values for attribute with name attr_name
        By default a scalar is returned. 
        If n>1 a list with n defaults is returned.

        Usage:
            Return a scalar default 
            self._get_default('attr_name')    

            Return list with 5 defaults
            self._get_default('attr_name',5)

            Return list with 5 defaults, assigned with ids=[1,2,3,4,5].
            This usage makes only sense with Classes or instances
            with ArrayObj mixin.
            self._get_default('attr_name',ids=[1,2,3,4,5])

        """
        # print '_get_default',self.ident,attr

        default = self._config[attr]['default']
        struct = self._config[attr]['struct']
        defaults = []

        if ids == None:
            # create dummy ids
            ids = range(n)
            returnlist = False

        elif type(ids) not in ARRAYTYPES:
            # just a single id, do return a simple value, not a list
            ids = [ids]
            returnlist = False
        else:
            returnlist = True

        for id in ids:
            if struct in ('dict', 'array', 'marray'):
                # if default is an initialized class or an instance
                # and has also a dict or array structure,
                # then try to configure array object with id

                if type(default) == types.InstanceType:
                    # default is instance so just make a copy
                    obj = copy(default)
                    # now configure array object
                    # in this case class must have ArrayObj capabilities
                    # (mixin)
                    if self._config[attr]['do_init_arrayobj']:
                        obj.init_arrayobj(
                            id, self, self.make_item_ident(attr, id))

                elif (type(default) == types.ClassType) & \
                        self._config[attr]['do_init_arrayobj']:
                    # default is a class that needs to be initialized first
                    obj = default()
                    obj.init_arrayobj(id, self, self.make_item_ident(attr, id))

                elif type(default) == types.FunctionType:
                    # use base function to get other default types
                    obj = default

                else:
                    # use base function to get other default types
                    obj = copy(default)

            else:
                # use base function to get other default types
                obj = ObjConfigurator._get_default(self, attr)

            # append to default list
            defaults.append(obj)

        # print '_get_default array',defaults
        if (n > 1) | returnlist:

            return defaults
        else:
            return defaults[0]

    def _del_ids(self, ids):
        """
        Deletes id from all array - tpe attributes
        """

        # print 'ArrayConfigurator._del_ids',ids,'from',self.ident

        # delete ids from list , one by one
        for id in ids:
            # print '  start deleting id',id

            # print '      self._ids',self._ids
            # print '      self._inds',self._inds

            # i=self.get_index(id)
            i = self._inds[id]

            # print '     ind=',i
            # print '     del rows from array-types...'
            for attr in self._arrayconfig.keys():
                # print '      del',attr,id,i

                # print '        before=\n',self.__dict__[attr]
                self.__dict__[attr] = concatenate(
                    (self.__dict__[attr][:i], self.__dict__[attr][i + 1:]))
                # print '        after=\n',self.__dict__[attr]

            # print '    del from id lookup'
            self._ids = concatenate((self._ids[:i], self._ids[i + 1:]))

            # print '    del from dicts'
            for attr in self._dictconfig.keys():
                # print '      del',attr,id
                del self.__dict__[attr][id]

            # print '    del from marrays'
            for attr in self._marrayconfig.keys():
                self._del_item_marray(attr, id)

                # what's left is to cut out the db pointer with index i
                bp = self._marrayconfig[attr]['bp']

                # print '      del',attr,id,bp

                bp = concatenate((bp[:i], bp[i + 1:]))
                self._marrayconfig[attr]['bp'] = bp

            # print '    free index',id
            if id == len(self._inds) - 1:
                # id is highest, let's shrink index array by 1
                self._inds = self._inds[:-1]
            else:
                self._inds[id] = -1

            # get ids of all indexes which are above i
            ids_above = flatnonzero(self._inds > i)

            # decrease index from those wich are above the deleted one
            #put(self._inds, ids_above,take(self._inds,ids_above)-1)
            self._inds[ids_above] -= 1

            # print '    self._inds',self._inds

        if self._named:
            # print '  Remove named'
            for id in ids:
                name = self._name_ids[id]
                del self._id_names[name]
                # print '    removed',name,id

        # print '  del',ids,' done.'

    def __setstate__test(self, state):
        """
        This is setstate for array config only
        and overrides the scalar version.

        The main purpose is to correct a conversion error in numpy
        """
        print '__setstate__', self

        # this is alays required, but ill not be saved
        self._plugins = {}

        for key in state.keys():
            value = state[key]

            # print '  set state',key
            # print '    attr',key,type(value),
            # if type(value)==ndarray:
            #    print value.dtype,value.shape
            # else:
            #    print value

            if type(value) == ndarray:
                if value.dtype == dtype('|O4'):
                    value = array(value, '<f8')
                print '  set state', key, type(value),
                print '    dtype', value.dtype, value.shape

            self.__dict__[key] = value

        # set other states
        self._setstate(state)


# def del_manage_ids(self,ids):
# """
# Specific item delete, called before removing data.
# """
# pass

class EmptyClass:

    """
    This claass is empty and used as default.

    """

    def __init__(self, parent=None): pass

    def get_ident(self, is_local=None): return 'empty'


class IntegerQueues(ArrayObjConfigurator):

    """
    Class implements multiple queues with the following properties:
        - only integers  can be queued
        - each id can be only in one queue

    Methods are implemented to insert and remove ids in queues
    also in vectorial form.
    """

    def __init__(self, parent, key='queues', name='Queues', items=None):
        """
        Main init used for stand alone.
        """
        self.init_config(key, parent, name)

        self._init_queues(items)

    def _init_queues(self, items=None):
        """
        Queue specific initializations

        items = optional instance that is an array of the integer items
                in the integer queue. The item must inherit IntegerItems
                methods and have this (self) queue class as parent. 
        """

        self.config('ids_first', -1,
                    name='First id',
                    info='ID of first element of each queue',
                    metatype='id',
                    ident_ref='.items',
                    struct='array',
                    )

        self.config('ids_last', -1,
                    name='Last id',
                    info='ID of last element of each queue',
                    metatype='id',
                    ident_ref='.items',
                    struct='array',
                    )

        if items == None:
            # use default items class
            items = IntegerItems(self)

        self.config('items', items,
                    name='items',
                    info='Contain items that are queued in each queue',
                    ident_ref='.items',
                    group='options')

    def add_items(self, ids_item):
        """
        Add ne items for queuing in database
        """
        self.items.create_ids(ids_item)

    def is_empty(self, ids_queue):
        """
        Returns True or False for each queue in the array
        if respective queue is empty or non-empty  
        """
        return self['ids_first', ids_queue] == -1

    def pop_items(self, ids_queue):
        """
        Remove and return last items from queues in array  ids_queue
        """
        ids_items = self['ids_last', ids_queue]

        self.remove_items(ids_items[ids_items > -1])

        return ids_items

    def remove_items(self, ids_item, ids_queue=None):
        """
        Remove integers in array ids_item from queues in array ids_queue
        If no ids_queue is given, it will be recovered from the integer items 
        database. This may only be a disadvantage in terms of time.
        """
        # print 'remove_items'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue

        if ids_queue == None:
            ids_queue = self.items['ids_queue', ids_item]

        inds_queue = self.get_inds(ids_queue)
        inds_item = self.items.get_inds(ids_item)

        # identify single
        inds_single =   (self.ids_last[inds_queue] == ids_item) & \
                        (self.ids_first[inds_queue] == ids_item)

        if any(inds_single):
            # remove single item in queues
            inds_queue_single = inds_queue[inds_single]
            self.ids_last[inds_queue_single] = -1
            self.ids_first[inds_queue_single] = -1

        # identify last
        inds_last = (self.ids_last[inds_queue] == ids_item) &\
            logical_not(inds_single)

        if any(inds_last):
            # remove last items in queues
            inds_queue_last = inds_queue[inds_last]
            inds_item_last = inds_item[inds_last]

            ids_item_new_last = self.items.ids_prev[inds_item_last]
            self.items['ids_next', ids_item_new_last] = -1
            self.ids_last[inds_queue_last] = ids_item_new_last

        # identify first
        inds_first = (self.ids_first[inds_queue] == ids_item) &\
            logical_not(inds_single)

        if any(inds_first):
            # remove first items in queues
            inds_queue_first = inds_queue[inds_first]
            inds_item_first = inds_item[inds_first]

            ids_item_new_first = self.items.ids_next[inds_item_first]
            self.items['ids_prev', ids_item_new_first] = -1
            self.ids_first[inds_queue_first] = ids_item_new_first

        # identify middle
        inds_middle =   logical_not(inds_single) &\
            logical_not(inds_last) & logical_not(inds_first)

        if any(inds_middle):
            # remove first items in queues
            inds_queue_middle = inds_queue[inds_middle]
            inds_item_middle = inds_item[inds_middle]

            # cutting items out of chains
            ids_item_new_next = self.items.ids_next[inds_item_middle]
            ids_item_new_prev = self.items.ids_prev[inds_item_middle]

            self.items['ids_next', ids_item_new_prev] = ids_item_new_next
            self.items['ids_prev', ids_item_new_next] = ids_item_new_prev

        # finally remove pointer from items to queues
        self.items.ids_queue[inds_item] = -1
        self.items.ids_next[inds_item] = -1
        self.items.ids_prev[inds_item] = -1

    def insert_items_behind(self, ids_item, ids_item_beh, ids_queue):
        """
        Insert integers in array ids_item into queues in array ids_queue
        behind integers in array ids_item_beh
        """
        # print 'insert_items_beh'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue
        # print '  ids_item_beh',ids_item_beh

        # identify prepend
        inds_prepend = ids_item_beh == -1
        if any(inds_prepend):
            self.prepend_items(ids_item[inds_prepend],
                               ids_queue[inds_prepend])

        # identify append
        inds_append = (self['ids_last', ids_queue] == ids_item_beh) \
            & logical_not(inds_prepend)
        if any(inds_append):
            self.append_items(ids_item[inds_append],
                              ids_queue[inds_append])

        # select rest
        inds = logical_not(inds_prepend) & logical_not(inds_append)

        if any(inds):
            # insert items where insertion somewhere in the middle
            # of the buffer where first and last item is not effected

            # this task can therefore be handeled by item instance
            self.items.insert_items_behind(ids_item[inds],
                                           ids_item_beh[inds],
                                           ids_queue[inds],
                                           )

    def append_items(self, ids_item, ids_queue):
        """
        Append integers in array ids_items to queues in array ids_queue
        """
        # print 'append_items'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue

        # different treatmet of empty and not empty queues
        inds_empty = self.is_empty(ids_queue)
        inds_not_empty = logical_not(inds_empty)

        # treat first empty queues
        if len(inds_empty) > 0:
            # print '  inds_empty',inds_empty
            self['ids_first', ids_queue[inds_empty]] = ids_item[inds_empty]
            self['ids_last', ids_queue[inds_empty]] = ids_item[inds_empty]

        if any(inds_not_empty):

            # treat queues with at least one item
            ids_not_empty = ids_queue[inds_not_empty]
            ids_item_not_empty = ids_item[inds_not_empty]

            # fix new first and last item
            ids_item_prev = self['ids_last', ids_not_empty]
            self['ids_last', ids_not_empty] = ids_item_not_empty

            # backward chaining
            self.items['ids_prev', ids_item_not_empty] = ids_item_prev

            # forward chaining
            self.items['ids_next', ids_item_prev] = ids_item_not_empty

        # assign queue id
        self.items['ids_queue', ids_item] = ids_queue

    def prepend_items(self, ids_item, ids_queue):
        """
        Prepend integers in array ids_items to queues in array ids_queue
        """
        # print 'prepend_items'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue

        # different treatmet of empty and not empty queues
        inds_empty = self.is_empty(ids_queue)
        inds_not_empty = logical_not(inds_empty)

        # treat first empty queues
        if len(inds_empty) > 0:
            # print '  inds_empty',inds_empty
            self['ids_first', ids_queue[inds_empty]] = ids_item[inds_empty]
            self['ids_last', ids_queue[inds_empty]] = ids_item[inds_empty]

        if any(inds_not_empty):

            # treat queues with at least one item
            ids_not_empty = ids_queue[inds_not_empty]
            ids_item_not_empty = ids_item[inds_not_empty]

            # fix new first and last item
            ids_item_next = self['ids_first', ids_not_empty]
            self['ids_first', ids_not_empty] = ids_item_not_empty
            # self['ids_last',ids_not_empty] = ids_items_next # not changed

            # forward chaining
            self.items['ids_next', ids_item_not_empty] = ids_item_next

            # backward chaining
            self.items['ids_prev', ids_item_next] = ids_item_not_empty

        # assign queue id
        self.items['ids_queue', ids_item] = ids_queue

    def print_info(self):
        """
        Print all usueful info
        """
        self.print_config()
        self.items.print_config()


class IntegerItems(ArrayObjConfigurator):

    """
    Class cotaining integer items (the ids) of the integer queue.

    This class can be used as mixin in order to add customized attributes to
    each item.

    """

    def __init__(self, parent, key='items', name='Integer items'):
        """
        Main init used for stand alone.
        """
        self.init_config(key, parent, name)

        self._init_items()

    def _init_items(self):
        """
        Here the item specific states are initialized.

        queue_data is an optional database with additional information 
            on the queues where each id correspnds to a queue

        """

        self.config('ids_queue', -1,
                    name='queue id',
                    info='ID of queue',
                    metatype='id',
                    ident_ref=self.parent.ident,
                    struct='array',
                    )

        self.config('ids_next', -1,
                    name='next id',
                    info='ID of next',
                    metatype='id',
                    ident_ref='.',
                    struct='array',
                    )

        self.config('ids_prev', -1,
                    name='previous id',
                    info='ID of previous',
                    metatype='id',
                    ident_ref='.',
                    struct='array',
                    )

    def insert_items_behind(self, ids_item, ids_item_beh, ids_queue):
        """
        UNUSED!! see integerqueue!!

        Insert integers in array ids_item into queues in array ids_queue
        behind integers in array ids_item_beh.

        Please use insert_behind of the governing queue class!

        Attention this method is called by insert_behind of the 
        governing queue class, which selected already the cases where
        this insertion is in the middle of the queue and does not effect
        first or last item. 
        """
        # print 'IntegerItems.insert_items_beh'
        # print '  ids_item',ids_item
        # print '  ids_queue',ids_queue
        # print '  ids_item_beh',ids_item_beh

        inds_item = self.get_inds(ids_item)
        inds_item_beh = self.get_inds(ids_item_beh)

        # forward chaining
        ids_item_next = self.ids_next[inds_item_beh]
        self.ids_next[inds_item] = ids_item_next
        self.ids_next[inds_item_beh] = ids_item

        # backward chaining
        self.ids_prev[inds_item] = ids_item_beh
        self['ids_prev', ids_item_next] = ids_item

        # assign queue id to inserted elements
        self.ids_queue[inds_item] = ids_queue


class MetaList(ArrayObjConfigurator):

    """
    Empty class with ArrayObjConfigurator properties.
    Can be freely configured to contain any kind of database like,
    ordered list structures.

    Usage:
         l=MetaList()
         l.config('m',0.0,struct='marray')
         l.create_ids([1,2,3,4])
         l.print_config()
    """

    def __init__(self, **args):
        self.init_config('metalist')


class TestNamed(ArrayObjConfigurator):

    def __init__(self, **args):
        self.init_config('test', named=True)
        self.config('s', zeros((0,), float), struct='marray',
                    type=['IntType'])

        self.config('v', 0, struct='array')
        self.add_id_named('one')
        self.add_id_named('two')


class TestMod(ObjConfigurator, ArrayObj):

    """
    test
    """

    def __init__(self, **args):
        """
        Mod specific Initialization.
        self.id an parent is yet unknown 
        """
        pass
        # print 'initialized TestMod'

    def config_with_id(self):
        """
        Mod specific Initialization.
        Now id and parent is known.
        """
        self.init_config()
        # print 'config_with_id',self.ident
        self.config('y', 0.0, group=['state'], perm='w', digits_fraction=2)
        self.config('z', 'text', group=['state'], perm='w')
        self.config('cabins', Cabs(self))
        # self.print_config()


class Car(ArrayObj):

    """
    test
    """

    def __init__(self, **args):
        """
        Mod specific Initialization.
        self.id an parent is yet unknown 
        """
        print 'initialized CarMod'

    def config_with_id(self):
        """
        Mod specific Initialization.
        Now id and parent is known.
        """
        pass


class CarTest(ArrayObjConfigurator):

    """
    test
    """

    def __init__(self, **args):
        """Variable
        """
        self.init_config('carstest')
        self.config('a', 0.0, struct='array', group=[
                    'state', 'costs'], unit='m/s^2')
        # self.config('mods',TestMod,struct='dict')
        #self.config('m',[0.0, 0.0, 0.0],struct='array')
        self.config('g', zeros((3, 4)), struct='array', unit='earth accel')
        newids = self.suggest_ids(3)
        self.create_ids(newids)


class Cars(ArrayObjConfigurator):

    """
    test
    """

    def __init__(self, **args):
        """Variable
        """
        self.init_config('cars')
        self.config('x', 0.456685, group=[
                    'state'], perm='w', digits_fraction=2)

        self.config('color', [0.2, 0.8, 0.2], metatype='color',
                    struct='array', group=['parameter'], perm='w')
        self.config('load', 'user', struct='dict', perm='r')
        self.config('n', 0,  struct='array', info='number', perm='w',
                    group=['state', 'parameters'],
                    min=0, max=5)
        self.config('b', False, struct='array', perm='w',
                    info='bool...', group=['state', 'costs'])
        self.config('a', 0.0, struct='array', info='acceleration',
                    group=['state', 'costs'], digits_fraction=2)
        self.config('v', 0.0, struct='array', info='velocity',
                    group=['state'], unit='m/s', digits_fraction=2)
        self.config('d', 0.0, unit='m', struct='array',
                    info='this is \nthe distance', digits_fraction=2)
        self.config('j', 0.0, struct='array', perm='r', digits_fraction=2)
        self.add_items(v=[8.7, 5.5, 34.1, 2], a=[-8, -5, -34, -2])

        self.config('mods', TestMod, struct='dict')
        self.config('m', [0.0, 0.0, 0.0], struct='array')
        self.config('g', zeros((3, 4)), struct='array')
        self.config('coords', array([0.0, 0.0, 0.0], float),
                    # type=['FloatType'],
                    struct='array',
                    name='coordinates',
                    info='Array with xyz coordinates of each node')
        newids = self.suggest_ids(3)
        self.create_ids(newids, v=[5, 6, 7])
        # print 'config=\n',self.get_config()


class ObjConfiguratorTest(ObjConfigurator):

    """
    test
    """

    def __init__(self, parent=None, **args):
        """Variable
        """
        self.init_config('ObjConfiguratorTest', parent)
        self.config('d', [[1, 2]], type=[('ArrayType', (1, 2)), 'IntType'])


class Cabs(ArrayObjConfigurator):

    """
    test
    """

    def __init__(self, parent=None, **args):
        """Variable
        """
        self.init_config('cabs', parent)
        self.config('d', [[1, 2]], type=[
                    ('ArrayType', (1, 2)), 'IntType'], struct='dict')
        self.create_ids([1, 2, 3, 4])
        self.config('a', 0.0, struct='array', group=[
                    'state', 'costs'], unit='m/s^2')
        self.config('n', -1, struct='array')
        self.config('g', zeros((3, 4)), struct='array', perm='r')
        #self.config('v',0.0, struct='array', group=['state'])
        # self.config('d',0.0,unit='m')
        # self.config('j',0.0,struct='array')
        # self.add_items(v=[8.7,5.5,34.1,2],a=[-8,-5,-34,-2])
        # self.config('coords',array([0.0,0.0,0.0]),
        #            struct='array',
        #            name='coordinates',
        #            info='Array with xyz coordinates of each node')


class MarrayTest(ArrayObjConfigurator):

    """
    test
    from base import *;t=MarrayTest();t['s',1]=[11,22,33,44];t['s',3]=[-33,-44]
    t.get_ids_marray('s',[1,])
    t['s',2]=[22,222,2222,22222]
    t['s',[1,2]]=[[3,33,333],[55,555,5555,5555]]
    t.get_ids_marray('s',[1,2,3])
    t.get_ids_marray('s',[1,])

    """

    def __init__(self, **args):
        self.init_config('test')
        self.config('s', zeros((0,)), struct='marray',
                    type=['IntType'])

        self.config('v', 0, struct='array')

        self.config('x', [[-1, -1]],
                    name='forward star',
                    info='Dict with node id as key and forward nodes as values',
                    doc='A dictionary with node id as key and \n' +
                         'a dictionary with follower nodes as value. \n' +
                         'Each follower node is a dictionary with \n' +
                         'predecessor node id as key and arc id as value',
                    type=[('ArrayType', (1, 2)), 'IntType'],
                    struct='marray',
                    )

        self.config('f', zeros((0,), dtype='i'),
                    name='forward nodes',
                    info='Dict with node id as key and forward nodes as values',
                    doc='A dictionary with node id as key and \n' +
                         'a dictionary with follower nodes as value. \n' +
                         'Each follower node is a dictionary with \n' +
                         'predecessor node id as key and arc id as value',
                    type=[('ArrayType', (1,)), 'IntType'],
                    struct='marray',
                    )

        self.config('m', [[0.0, 0.0, 0.0], [10.0, 10.0, 0.0]], struct='marray')
        self.create_ids([1, 2, 3, 4])
        # self.config('s',[-1],struct='marray')
        self.print_config()


def test_queue():
    q = IntegerQueues(None)
    q.create_ids([1, 2, 3, 4])
    q.add_items(arange(0, 20, 2, int))

    q.print_info()

    # q.prepend_items(array([2,1],int),array([4,3],int))
    # q.prepend_items(array([2,],int),array([3,],int))
    q.insert_items_behind(array([2, ], int), array(
        [-1, ], int), array([2, ], int))

    q.print_info()

    q.insert_items_behind(array([16, ], int), array(
        [2, ], int), array([2, ], int))

    q.print_info()

    q.prepend_items(array([4, 8], int), array([3, 2], int))

    q.print_info()

    q.append_items(array([6, ], int), array([1, ], int))

    q.print_info()

    q.append_items(array([10, 12], int), array([1, 3], int))

    q.print_info()

    q.insert_items_behind(array([18, ], int), array(
        [2, ], int), array([2, ], int))

    q.print_info()

    q.remove_items(array([18, ], int))

    q.print_info()

    q.remove_items(array([16, ], int))

    q.print_info()

    q.remove_items(array([8, ], int))

    q.print_info()

    q.remove_items(array([2, ], int))

    q.print_info()

    print '\npop all', q.pop_items(q.get_ids())
    print '\npop all', q.pop_items(q.get_ids())
    print '\npop all', q.pop_items(q.get_ids())

###############################################################################
if __name__ == '__main__':
    """
    Test
    """

    test_queue()

    exit(0)

    # a=array([[1,2,3],[4,5,6],[7,8,9],[11,22,33]])
    # b=array([[1,0,1],[1,1,1],[1,0,0],[0,0,0]])

    # cd C:\Documents and Settings\joerg\Documenti\projects\its
    # import sys; sys.path[:0] = ['C:\Users\joerg\projects\sim\its']
    #from lib.base import *
    cabs = Cabs()
    cabs.print_config()

    # t=MarrayTest();t['s',1]=[11,22,33,44];t['s',3]=[-33,-44]
    # t.get_ids_marray('s',[1,])
    # t['s',2]=[22,222,2222,22222]
    # t['s',[1,2]]=[[3,33,333],[55,555,5555,5555]]
    # t.get_ids_marray('s',[1,2,3])
    # t.get_ids_marray('s',[1,])

    t = ObjConfiguratorTest()
    t.print_config()

    save_obj(t, 'test.txt')
    t = load_obj('test.txt')

This package contains the base classes of al relevant classes.  TODO: Following issues must be resolved in the following version  - child  - parent - ident - named     childs of named parents should have the name in the ident...and local ident     create 2 ident entries for arrayobj: attr+id     use a list for ident elements instead of a string wityh string conversion     on the fly or permanently.     May be of advantaqge (= fast) to store instances that are on the path of the      ident elements          in particular: distiguish between an instance on the tree that is created with parent     and an already initialized instance that is set and usd as a link.     idea in this case get all confuguration info from instance itself     or better link to it! - ident should be a sequence or list of strings - separate classes for array type objects - classes for metatypes  - try to reduce type recognition during init ??  - MIXIN for named operation just as for plugin - make plugin faster by overwriting get/set attribute - print attribute must also go in classes   - make common initialization priciples in particular for classes based on mixins   who sets the name: the parent! name is option with default -  simplify configurationwith key setting...should appear only once     try to catch it from within the object with __name__ - try to remove stored type identification...careful problems are nd scalars # from numpy.oldnumeric.user_array import numpy.oldnumeric.user_array as # UserArray #import networkx as nx Makes an array of same type from all attributes in attrs dictionary     A bit slow! Avoid using this function! # another strange type Returns True if n is an integer type of any kind Returns a flat list of type-string(s) which correspond to the     (nested) type(s) of  the object obj.      The returned type(s)  are keys of the global TYPES dictionary. # return typelist # let's assume homogenious array types # obj is an array element # attention this is not a string but maybe this should # also be changed for all other types Returns dtype as used in Nummeric package.     The argument is a string defining the python objecy type     and is a key of the TYPES dictionary.     If type is not found in the dictionary, dtype 'O' is     returned, which means a generic object. Saves python object to a file with filename.     Filename may also include absolute or relative path.     If operation fails a False is returned and True otherwise. # try: # except: #    file.close() #    print 'WARNING in save: could not pickle object' #    return False Reads python object from a file with filename and returns object.     Filename may also include absolute or relative path.     If operation fails a None object is returned. # try: # print '  pickle.load...' # print '  obj._link2' # _init2_ is to restore INTERNAL states from INTERNAL states # _init3_ is to restore INTERNAL states from EXTERNAL states # such as linking # _init4_ is to do misc stuff when everything is set # except: #	print 'WARNING in load: could not load object' #	return None Mixin for Classes or Instance which are used as array-element      within the framework of the ArrayObjConfigurator.      Its main function is init_arrayobj where an id gets assigned     which corresponds to the id of the element in the parent array.      Also __getitem__ and __setitem__ functions are implemented through which      array elements with the same id of other attributes of the parent object      can be read and changed. Initialize by defining parent instance where all the         attributes of this instance are stored in array form.         Also define the id of the array coresponding to this instance.           Function will be called automatically from ArrayObjConfigurator         when id is assigned. # if ident=='': #    ident=parent.ident+IDENTSEP+str(id) # else: # print 'init_arrayobj',self.ident,id#,parent Here the instance can be inizialized..         Function called AFTER  self.id and self.parent have been assigned. Copies  given list of attributes of this object          to given target object.          If no attributes are given then all attributes of this object          are considered for copying.          Clearly, the array attributes corresponding to the id of this         object are copied to the array attributes of the arrays          with the id of the target object.          To copy an attribute, the foolowing conditions must be satisfied:             - the attribute must be configured with key copy=True             - the attribute must be configured in targetobject Sets entry with id of this instance of the attribute 'key' of parent object.          Usage:             self['attributename']=value # print key,value Gets entry with id of this instance of the attribute in parent object.          Usage:             self['attributename'] # print 'ArrayObject.__getitem__',key Returns a dictionary with all attributes of a group with given name.          Key is attribute name and value is attribute value for the given id. # print 'get_groupattrs_obj',name,self.id Mixin to provide methods to plug  callback functions into other objects. Initialize basic plugout variables # dictionary with pluginobj as key and list with plugids # provided by obj as value Make a plugin to object and retain plugin id for later unplugg.          Standard plug types are automatically set bu the system:         plugtype    plugcode         'del'       0         'set'       1         'get'       2         'add'       3          'del_items' 20         'set_items' 21         'get_items' 22         'add_items' 23 # make plugin to object # add plugginid of obj to list Plug out from specified object.         If plugid is specified, only this plug is pulled,         otherwise all plugs to this object are pulled at once. Unplug all plugs on other objects Mixin to provide methods to plug in callback functions     from other objects. Initialize basic plugin variables # self._plugins={} # compulsory in configurator! # print 'init_plugin',self.ident,self._plugcode # dictionary with obj as key and dict with plugid,plugtype,attr as # value # add basic plugincodes # for scalars # print '  add_plugcodes arrays for ',self.ident Execute all callbacks for the plugin of the given type Plugcodes integers that correspond to a plugtype.         These integers are used as keys for faster access.          Argument plugcodes is a list with tuples          each tuple containing plugtype and plugcode.          Standard plug types are automatically set bu the system:         plugtype    plugcode         'del'       0         'set'       1         'get'       2         'add'       3          'del_items' 20         'set_items' 21         'get_items' 22         'add_items' 23 # print 'add_plugcodes',plugcodes # self._plugins[plugcode]={'_all':{}} # print '  added # self._plugcode[plug]',plug,self._plugcode[plug] # print 'add_plugin',plug,callbackfunction,attr Prevents plugins from execution Enable plugins for execution Remove plugin with pluginid # there exist ids associated with this object # remove plugin with pid # no more plugins for this attribute...remove it # np more plugins for this plugintype...remove it # no more plugin ids associated with this object Base mixin class for general scalar object configuration.      Usage:          During initialization of class call          self.init_config('myclass_ident_string',name='my human readable class')          or if there is a parent object availlable:          self.init_config('myclass_ident_string',parent)          In this case the ident of the parent obj is prependet # print '---init_config ident',ident,hasattr(self,'init_plugin') # print '  parent',parent # print '  name',name,len(name) # use class name as identifier # use class name as identifier # print 'init_config',ident,parent.ident # present object is a child of a parent # => prepend parent identifier string # define a list with attribute strings that need to be saved # apart from the cofigured attributes # this list may be extended by successive initializations # 'parent', # conditional plugin import # print 'Created configuration for',self.ident Resets previously assigned parent.         This method is not used during initialization. # print 'init_config',ident,parent.ident # present object is a child of a parent # => prepend parent identifier string Returns identity string.         By default it returns the entire identity string         unless is_local==True. In this case only the local, the last         element of the global identity is returned. Called after load process to link with other instances          in the environment. # self.parent=parent # for attr in self._config.keys(): #    obj=getattr(self,attr) #    if is_objconfigured(): #        obj._link(self) Called after load and link process to do make initializations         of constants, dependent INTERNAL attributes such as hash tables,          NO LINKS OR DEPENDENCIES TO EXTERNAL INSTANCES ALLOWED          Here only the configurator internal attributes are restored.         All object specific in _init2() in # check # if hasattr(self,attr): #    value=getattr(self,attr) # print '  attr',attr, # if type(value)==ndarray: #    print value.dtype,value.shape # else: #    print value # print '    resore function',attr # print '    resore attr',attr # check # value=getattr(self,attr) # print '  after: attr',attr, # if type(value)==ndarray: #    print value.dtype,value.shape # else: #    print value # conditional plugin import # attribute is an array so init here for arrays as well # TODO: should go as special in arrayconfigurator Called after load  process to do make initializations         of constants, dependent INTERNAL attributes such as hash tables,          NO LINKS OR DEPENDENCIES TO EXTERNAL INSTANCES ALLOWED          To be overridden. Called after load and link process to do make initializations         of constants, dependent attributes such as hash tables,          links to external instances etc. # link with other, now already initialized objects # Those attributes which have NOT been saved, but have # an ident in they configuration can no be recovered # though their ident # try to recover object with ident # here we want to recover links to objects # using a dictionary with # id as key and ident as value # make specific settings # print '  restore children',self.ident # print '    call _init3_config of',obj.ident # attribute is an array so init here for arrays as well # TODO: should go as special in arrayconfigurator # print '    call _init3_config of',obj.ident Called after load and internal link process to do make initializations         of constants, dependent attributes such as hash tables,          links to external instances etc.          To be overridden. Called after load and link process to do make initializations         any other initializations. # make specific settings # print '  restore children',self.ident # print '    call _init4_config of',obj.ident # attribute is an array so init here for arrays as well # TODO: should go as special in arrayconfigurator # print '    call _init4_config of',obj.ident Called after load and link process to do make initializations         any other initializations.          To be overridden. Initializes plugin and plugout related variables.         This function is called during initialization          and after load, before reinitializeing other attrubutes. # print '_init_plugging',self.ident,self # if make_plugins: #    from PluginMixin import * # print '  ini_plugin',self.ident,self # print '  ini_plugout',self.ident # this plugin dictionary is always required and remains # empty if no plugins are made This method executes all callbackfunctions associated with the         given plugcode.         This funcion is a core part because used in various         methods. All other methods regarding plugins in PluginMixin. # it has been checked that self._plugins has all keys # print '  self._plugins=',self._plugins # print '  self._plugins[plugcode]=',self._plugins[plugcode] # print '  => execute function',func # print '     with args',args # selective plugin for specific attribute # else: #    print '  no plugin functions for plugcode',plugcode Returns formatted name string of object. # print 'inds=',self._inds # for name in self.get_groupnames(): #    if self.get_group(name): #        print 'Group: ',name #        for attr in self.get_group(name): #            self.print_attr(attr) # print all attributes which are not in a group # print '--' # for attr in self._config.keys(): #    if len(self._config[attr]['group'])==0: #        self.print_attr(attr) # config=self.get_config(attr) # print '   ', attr,'=',self.__dict__[attr],config['unit'] Prints attributes of attributes.         If # print 'print_attrattrs' # print '  attr',attr # print line Returns a string with correctly formatted value of attribute. # print '\n\nget_string_attr_value',attr,value,type(value) # print self.get_printformat(attr)+self.get_unit(attr) #print (self.get_printformat(attr)+self.get_unit(attr))%(value) # value is an array=> print signe items Returnes the standad fortran stringformat for attribute. # its a string Returns a dictionary with all formatting infos on attribute.         It is tried to detect the numerical datatype and define         formatting info, if not already defined. # determine format of numeric value # take top level type # print 'get_numformat',attr,numformat Configure attribute for Object. # print '\n\n\n'+70*'*' # print 'config',attr,default,args # configure attribute with template and parameters from args # CONFIG_TEMPLATE.copy() # print '  after template configured attr:',attr,self._config[attr] # try to guess type...as default only # print '  get_type(default)=',get_type(default) # guess read/write permissions according to toplevel type # default name # TODO: fetch here metatype info from metatype module # default # overwrite all defaults with arguments # print '  after update configured attr:',attr,self._config[attr] # complete with numerical format info # store default value here, # in case of an array this is the value of a single entry # check if attribute is an existing function and if yes register # as such in config # print '  ',attr,'is a function' # self._config[attr]['perm']='r' # read only # register attribute in function list # print '  configured attr:',attr,self._config[attr] # this turnes group argument in a list when given a signle string # TODO: would be better to introduce groups as a list with all group # names # explictly declared as id # make sure of array structure # TODO: better identify object as arrayobjconfiguaror # put attribute into id_ref or obj ref group # if no reference is made then put in id group # print '  ident_ref detected id_ref for',attr # print '  check template',CONFIG_TEMPLATE.copy() # print '  ident_ref detected obj_ref for',attr # and add it to id group # this is a treatment fo linked objects, which are # not a parent or a child of this objects # they ill not be saved, but recovered bu their ident during _init3 # try to recover object with ident # however, ident itself will only be stored during saving Reset atttribute attr to default values # create attribute and if there are already arrays with entries, # create the same number of entries with default value # default=self._config[attr]['default'] # struct=self._config[attr]['struct'] # if self._config[attr]['is_function']: #    # register attribute in function list #    #self._functions.append(attr) #    # already done in config #    pass # else: # attr is a scalar , simply assign default Sets a default value for this attribute. Returns default value for attribute with name attr_name          Usage:             Return a scalar default              self._get_default('attr_name') # struct=self._config[attr]['struct'] # .tolist() # Default is a class, needs to be initialized # TODO: initialization and global id needs to be reviewed # otherwise just copy default value # print '_get_default',obj Sets value to attribute.          Usage:          Set scalar variable var with value val         self.set('var',val) # exclude functions Returns true if attribute with name attr is configured. Copies  given list of scalar attributes of this object          to given target object.          If no attributes are given then all attributes of this object          are considered for copying.          copy an attribute, the foolowing conditions must be satisfied:             - the attribute must be configured with key copy=True             - the attribute must be configured in targetobject              - the structure of the attribute must be scalar                  (arrays done by copy method of ArrayObjConfigurator) # get all attributes Returns list of configured attribute names.          crits_atleastone and crits_all are lists defining one or several         criteria that the attribute configuration must satify.         for example: [('struct','array'),('struct','dict'),('struct','marray')] # get attribute names for attributes where at least one criteria # is satisfied # print 'get_attrs:',attr,criteria # get attribute names for attributes where all criteria # are satisfied # print 'get_attrs:',attr,criteria # no criteria spacified, return all attribute names # print '_get_config:',attr Returns instance of root obj of the tree. Returns the instance of the object of the given identity string ident.          The researched object must reside within the object tree where also         the self object is a part. # ident starts with a . means that it is a relative link # starting with this object # just one element identification, means this is root # it's an id so get arrayobject # obj=obj # do not dive # print 'create_group',name,attr_list # print '  groups before=',self._groups.keys() # print '  groups after =',self._groups.keys() Add or append attribute to given name. # print 'config_group',self._groups,type(self._groups) # print '  name,attr',name,attr # print '  before append',self._groups[name] # print '  after append',self._groups[name] Returns a list with attribute names that belong to that group name. # print 'get_group self._groups=\n',self._groups Returns a dictionary with all attributes of a group.          Key is attribute name and value is attribute value. Returns current permission of attribute Returns unit of attribute # print '__getitem__',key # plugin execution Sets a value to an attribute # print 'setitem',key,'to',value # plugin execution # print '__getstate__',self.ident # print '  self.__dict__=\n',self.__dict__.keys() # store ident for linked objects prior to saving # will be recovered in _init3 # try to recover object with ident # here we want to retain the idents of all objects # in this array, using a dictionary with # id as key and ident as value # print '  self._config.keys()',self._config.keys() # self.__dict__[attr] # print '  saved state:',attr,state[attr] # decide whether to save parent: # the root object does not save parent because outside the tree # print '  save parent for',string.split(self.ident,IDENTSEP) # it is actually an array-object, save also id # print '  saved attr id',self.id # save which attributes to save # now save attributes which have been configured to save # print '  ',self._config[attr]['save'],attr # print '  save attr:',attr Complete state dict with state variables which are not          contained in the config scheme. All attributes which are         configured and the save option is not explicitely set         to False are automatically inserted in the state dictionay. # print '__setstate__',self # this is always required, but will not be saved # print '  set state',key # done in init2_config... # set default values for all states tha have not been saved # for attr in self._config.keys(): #    if (not self._config[attr]['save']) & (not hasattr(self,attr)): #        print '  config attr',attr #        self.config(attr,**self._config[attr]) # set other states Complete state settings of state variables which are not          contained in the config scheme. All attributes which are         configured and the save option is not explicitely set         to False are automatically set. Should be called before desroying the object.         Does remove pugs is existent. Base class for general scalar object configuration.      For usage see demo classes below. Fore named objects use:             self.add_id_named('name_of_id') # print 'init_config array',ident,hasattr(self,'init_plugin') # else: # print 'no array plugins for ',self.ident # print 'check config'#,self.ident,self._config # save these attributes, apart from configured ones Returns true if array has named rows Returns id that corresponds to name. Returns name that corresponds to id. Returns list of all named ids. # print 'get_names',self.ident,self._id_names.keys() Returns value corresponding to named id Return all ids corrisponding to array indexes inds.         Options:             if no inds are given, all ids are returnd              if ordered is true, ids will be sorted before they are returned. Returns scalar id corresponding to index ind # print 'get_id',ind,self._ids Returns True if id is a zero positive scalar interger Fast, formal chack whether ids is either a valid array with ids. # it is an array # it contains at least one id # return True if this id is a zaro positive integer Formal check whether ids contains either an array with ids         or is a scalar zero positive interger. Returns an array of ids, corresponding to the True         of the mask array.          Usage:             Select all ids for which array of attribute x is greater than zero.             ids=obj.select_ids( obj.x>0 ) # print 'select_ids',mask,flatnonzero(mask) # print '  self._ids=',self._ids # def select(self,mask,ordered=False): #    """ #    Returns an array of ids, corresponding to the True #    of the mask array. # #    Usage: #        Get all elements of attribute y for which array of attribute x is greater than zero. #        values=obj.select(obj.y, obj.x>0 ) #    """ # # #    return self.get_ids(flatnonzero(mask),ordered=ordered) Return all ids and relative indexes corresponding to m-array          indexes in list inds_marray.          The relative index is the index within the array corresponding         to an id.          Examples:             obj.get_ids_marray('attrname',[2,3,4])              returns an array of the following shape:             [[11,0],              [11,1],              [12,0],]              here marray index 2 and 3 correspond to id=11 with relative index             0 and 1 respectively, while marray index 3 corresponds to              element with id=12 and relative index 0              (means first item in element with id=12) # print 'get_ids_marray',inds_marray # case more complex because need to check with block pointers # get block pointers for this attribute # print '  bp, ind_marray',bp,ind_marray # return reshape(  concatenate((ids, inds_delta)) ,(-1,2) ) Returns a flat array with all array indexes of          marray with attribute attr that have an id contained in list ids. # get block pointers for this attribute # print 'get_inds_marray: ids=',ids # print 'get_inds_marray: self._inds= ',self._inds # print 'get_inds_marray: self._inds[ids,:]= ',self._inds[ids,:] # Numeric # for i,j in take(bp, take(self._inds,ids) ): # print '  i,j=',i,j # print '  inds=',   array(inds,int) Returns a an availlable id.          Options:             zeroid=True allows id to be zero. Returns a list of n availlable ids.         It returns even a list for n=1.           Options:             zeroid=True allows id to be zero. # print # 'suggest_ids',n,zeroid,self._inds,len(self._inds),self._inds.dtype # avoid 0 as id: # ids_unused=take(ids_unused,flatnonzero(greater(ids_unused,0))) # print '  ids_unused_orig',ids_unused_orig,type(ids_unused_orig) # print '  len(ids_unused_orig)',len(ids_unused_orig),ids_unused_orig.shape # print '  greater(ids_unused_orig,0)',greater(ids_unused_orig,0) # print '  len(greater(ids_unused_orig,0))',len(greater(ids_unused_orig,0)) # print '  flatnonzero(greater(ids_unused_orig,0))',flatnonzero(greater(ids_unused_orig,0)) # print ' # len(flatnonzero(greater(ids_unused_orig,0)))=',len(flatnonzero(greater(ids_unused_orig,0)) # ) # print '  ids_unused',ids_unused # print '  ids_unused.shape',ids_unused.shape # print '  len(ids_unused)',len(ids_unused) # print '  n_unused,n_max,zid=',n_unused,n_max,zid # first id generation # print '  ids_unused',ids_unused # print '  from to',n_max+1,n_max+1+n-n_unused # print '  arange=',arange(n_max+1,n_max+1+n-n_unused) # print '  type(ids_unused)',type(ids_unused) # print '  dtype(ids_unused)',ids_unused.dtype # .tolist() Creates array entries for id with given name. # self._name_ids[name]=id # print 'add_id_named',self.ident,name,'with id',id Creates for each id in ids list an entry for each attribute with          array or marray structure.          If ids is a scalar integer, entries will be generated just for         this id.           For named objects the list _name_ids_ is necessary          with a name correisponding to each id. # print 'create_ids',ids,args # this is a short dirty way to allow also scalars for ids and arguments # turn scalar ids in list-vector... # print '  create_ids',ids,args # no ids to create # print '  ids',ids,'id_max_old',id_max_old,'ids_existing',ids_existing # check here if ids are still available # extend index map with -1 as necessary # print 'ext',-1*ones(id_max-id_max_old) # assign n new indexes to new ids # print 'ind_new',ind_new # print '  concat ids..',self._ids,ids # if each id is supposed to have a _name_ids # arguments must provide a list with names for each id # print '  id,names[i]',id,names[i] # Extend all arrays with n values from args or default # print '  attr',attr # newly assigned instances need to be array initialized # print ' # ',attr,'self.__dict__[attr]',self.__dict__[attr],'value',value # print '  concat item..',value # tc=self._config[attr]['dtype'] # print '  first item with tc',tc,'and value',value # print '  ', array(value,dtype=tc)[0] # self.__dict__[attr]=array(value,dtype=tc) # print '  let NumPy, Numeric or whatever guess the first # arrayelement' # Extend all marrays with n values from args or default # generate a scalar/list of copies of defaults # assign defaults to all dicts # print 'initialize',attr,value # print '  dict attr=',attr,value # print '   ', attr,'=' # print '   ', attr,'=' # print '   ',id,self._inds[id],\ #    val,config['unit'] # print '   ',id,self._inds[id],\ #    self.__dict__[attr][id],config['unit'] Returns a formatted string for array type attributes          with struct array, marray, dict # print 'get_string_arrayattr',attr,id,value Reset attribute attr to default values # create attribute and if there are already arrays with entries, # create the same number of entries with default value # print 'reset',attr,len(self) # declaredtype=self._config[attr]['type'][0] # configure if objects or instances need init_arrayobj with id # self._config[attr]['do_init_arrayobj']=False # moved to default # try to detect from defaults # print '  detected init_arrayobj!!' # done in config # elif type(default) == types.ClassType: #    if not self._config[attr].has_key('init'): #        # by default do not initialize classes #        # i they are nor arrayconfiguratored #        self._config[attr]['init']=False # check if instance or class type have been declared # if self._config[attr]['type'] in ['InstanceType','ClassType']: #    self._config[attr]['do_init_arrayobj']=True # do reset now # generate a scalar/list of copies of defaults # print 'len:',self.__len__(),len(self) # register attribute in array database # currently no particular info, just key # print 'reset',attr # all this not very clean, but works # the array element # use dtype given by default element which is an array # guess dtype from scalar types # print '  tc=',tc,'type[-1]=',self._config[attr]['type'][-1] # this print causes a strange error: # 'FloatCanvas' object has no attribute 'this' # print '  created # type',self.__dict__[attr].dtype,self.__dict__[attr].shape # self.__dict__[attr]=array(\ #    self._get_default(attr,ids=self.get_ids()), dtype=tc ) # print 'new array',self.__dict__[attr] # register attribute in array database # create new attribute with empty array # will be determined with first append # generate a scalar/list of copies of defaults # print 'dtype',tc,default,'type =',self._config[attr]['type'] # print 'reset: new marray',self.__dict__[attr] # new attribute is a dictionary # currently no particolar info, just key # assign default value for each already existing id # print 'reset: new dict',attr,'=',self.__dict__[attr] # handle other (scalar) attribute types with base configurator Copies  given list of attributes of this object to given target object.          If no attributes are given then all attributes of this object          are considered for copying.          To copy an attribute, the foolowing conditions must be satisfied:             - the attribute must be configured with key copy=True             - the attribute must be configured in targetobject # get all attributes # first copy all scalars Add new items into array structure.         The ids for each newly created item are returned in an array.         Usage:              Add 3 new items:             ids=obj.add_items(3)              Add 3 new items and setting attributes:             ids=obj.add_items(x=[11,22,33],v=[66,777,8888])              Add a single new item and set values             ids=obj.add_items(x=9,v=999)              Add a single  multi array element composed of 2 scalar integers:             ids=obj.add_items(s=[[111,2222]]) # determine number of items to be assigned # turn scalar val in list-vector... # add by default one item only # use n from args # print 'base.add_items',n # determine new id # print ' create new ids',ids # set values to attributes in arguments # for attr in args.keys(): # if attr in self._config.keys(): # print attr,' before =' #,self.__dict__[attr] # if self._config[attr]['struct']=='array': # print '  insert in array',args[attr][0] # print self._inds,ids,self._inds[ids] # put(self.__dict__[attr],take(self._inds,ids),args[attr]) # print attr,' after =',self.__dict__[attr] # elif self._config[attr]['struct']=='marray': # for i in range(n): # self._insert_item_marray(attr,ids[i],args[attr][i]) ## ## # elif self._config[attr]['struct']=='dict': # for i in range(n): # self.__dict__[attr][ids[i]]=args[attr][i] # print '   dict',attr,self.__dict__[attr][ids[i]] ## # else: # print 'WARNING in add_items: unknown attribute:',attr Determine current array length (same for all arrays) # def get_index(self,ids): #    """ #    returns index array from ids array #    Attetion thyis opration caused a crash during call from __del__ #    """ #    #print 'index',self._inds.dtype,type(ids),array(ids,int).dtype,len(ids) # #    return self._inds[array(ids,int)] #    #if type(ids) in ARRAYTYPES: #    #    #return take(self._inds,ids) #    #    return self._inds[array(ids,int)] #    #else: #    #    return self._inds[ids] Returns value of array element of attribute attr         wich corresponds to id the given name. Returns value of array element of attribute attr         wich corresponds to id the given name. # print '__getitem__',key # return entire contents of attribure for all ids # attribute is a kind of array # take all ids in ascending order # argument specify also id or ids to be returned # return array or list corresponding to ids # print 'get array types',attr,ids,struct # print '  self._inds=',self._inds # ids=array(ids,int) # print '  type (attr),type(ids)',type(self.__dict__[attr]),type(ids) # print '  ids.dtype 1=',ids.dtype # ids=array(ids,int) # print '  ids.dtype 2=',ids.dtype # print '  self._inds[ids]=',self._inds[ids] # print '  array(ids,int).dtype=',array(ids,int).dtype # executes plugins before values are returned to calling instance!! # this avoids problems with zero dimension arrays, # (bizzar but possible) #if ids.shape==(): ids=array([ids]) # print '  get array type ids=',ids,struct # print 'inds=',take(self._inds,ids) # print 'inds=',take(self._inds,ids) # print take(self.__dict__[attr],take(self._inds,ids)) # return take(self.__dict__[attr],take(self._inds,ids)) # here an array is returned with all elements of the # those blocks that corresponds to the ids # Note that this is a homogenious array , # arrays with single blocks can be obtained by passing # a single array. # Numeric: # return take(getattr(self,attr)(), #        self.get_inds_marray(attr,ids)) # print '  inds_marray=',self.get_inds_marray(attr,ids) # print '  self.__dict__[attr]=\n',self.__dict__[attr] # print ' # return=\n',self.__dict__[attr][self.get_inds_marray(attr,ids),:] # Numeric: # return take(self.__dict__[attr], #        self.get_inds_marray(attr,ids)) # print '  ',id,self.__dict__[attr][id] # this will never be executed!!!!!!!!!!! # if self._plugins.has_key(22): #    self._execute_plugins(22,ids=ids) # print 'return one array element, ids is a single id' # print 'inds=',take(self._inds,[ids]),attr,getattr(self,attr) # try: # except: #    print 'ERROR in __getitem__', attr,ids #    print '  inds=',self._inds[ids] #    print '  attr=',self.__dict__[attr] # here an array is returned with all elements of the # block that corresponds to this id # Numeric # return take(getattr(self,attr)(), #        self.get_inds_marray(attr,[ids])) # print 'ids=',ids # print # 'self.get_inds_marray(attr,[ids]))=',self.get_inds_marray(attr,[ids]) # Numeric: # return take(self.__dict__[attr], #        self.get_inds_marray(attr,[ids])) # print 'attr=',attr,ids Sets a value to an attribute         or to one or several elements of an attribute if         a list with ids is passed.          Usage:             Scalar assignment             obj['attrname']=0.0              Single element asignment             obj['attrname',3]=33              Assign 11,22,33 to elements with ids 1,2,3 of attribite attrname             obj['attrname',[1,2,3]]=[11,22,33]              Assign 3 elements of different size to marray             obj['attrname',[1,2,3]]=[[11,12,13],[21,22],[31]]             Note that the assigned value must be a python list of elements             and not a Numpy array # print 'setitem',key,'to',value # ids is a scalar->make a list # print 'inds=',self.get_index(ids) # print 'put value',value,type(value) # print '  attr,type(attr)',attr,type(self.__dict__[attr]) # print '  dtype(attr)',self.__dict__[attr].dtype # print ' # self.get_index(ids)=',self.get_index(ids),type(self.get_index(ids)),self.get_index(ids).dtype # put(self.__dict__[attr],self.get_index(ids),value) # newly assigned instances need to be array initialized # this is an array of matrix or tensors or higher order # the array must be flattened and the indexes must be # calculated accordingly # m=product(shape[1:]) # print 'put marray',m, #inds=ones( (len(ids),1),int )*arange(m)\ #    +transpose([take(self._inds,ids)])*m # print inds # print 'put value matrix',value,type(value) # print '  attr,type(attr)',attr,type(self.__dict__[attr]) # print '  dtype(attr)',self.__dict__[attr].dtype # print '  inds=\n',self._inds[ids] # print 'value',value # print 'value',value # Numeric #put(self.__dict__[attr],inds.ravel(), value.ravel()) # newly assigned instances need to be array initialized # self.print_config() # self.print_config() # print 'set_item:check plugins...',self.ident,self._plugins.keys() Deletes id with given name from all attributes # print 'ArrayObjConfigurator.__delitem__',self.ident,'key=',key # delete attribute and its configuration # key is one or multiple ids to be deleted from arrays # ids is a scalar->make a list # TODO: here it is not verified whether ids exist #  => verify and delete element by element # plugin execution BEFORE entry is deleted ########################################################################## # private methods Appends a list of items to multiary with attribute attr.         The block pointers are created automatically but         the indexes and ids must already exist in self._inds           ids cannot be empty! # print 'append_items_marray',attr # print '  ids=',ids # print '  items=',items # print 'marray=\n',marray # make sure that the bp vecor has enough index # print '  after extension bp=',bp # set block pointers for each id according to length of each item # gives the total number of elements inside all items # assume that id corresponds to a list with at least one item # thus, calculate new block pointers # print '  id,ind,i,j,len(items[ii])=',id,ind,i,j,len(items[ii]) # print '  after asssignment bp=',bp # put items in an array with coherent dimentions # print ' shape_elem=',shape_elem # print ' shape_array=',shape_array # extend current marray by the corrct number of new elements # print '  concat extention to marray=\n',marrayext # print '  first  marray_extension=\n',marrayext # now copy items into array is faster than concatenating each item # print '   add item items[ii]',items[ii] # print 'insert_item_marray',attr,id,item # print '  attr=', self.__dict__[attr] # get block pointers for this attribute # index of block pointers # get from to index of m array for this id # decide whether to overwrite existing # first cut current data out of marray and adjust # block pointers # append data # print '  attr=', self.__dict__[attr] # get block pointers for this attribute # index of block pointers # get from to index of m array for this id # print 'del_item_marray',attr,id,'from',i,'to',j # cut this piece out of the marray # print '  before:',self.__dict__[attr] # print '  after:',self.__dict__[attr] # indicate that block pointer does no more point to anywhere # calling method must take care of eliminating it or not # cut out index from blockpointers #bp=concatenate( (bp[:ind], bp[ind+1:]) ) # now subtract j-i from all "to" index higher equal than j # def _get_bp_marray(self,attr): #    """May be useful, just not used """ #    return self._marrayconfig[attr]['bp'] Generates the ident of attribute attr withy id. Returns a dictionary with all attributes of a group.          Key is attribute name and value is attribute value for the given id. # print 'get_groupattrs  of',name,'from',self.ident,self._groups.keys() # print '  id=',id # attrs[attr]=self['attr'] # if default is an initialized class or an instance # and has also a dict or array structure, # then try to configure array object with id # default is instance so just make a copy # now configure array object # in this case class must have ArrayObj capabilities (mixin) # if self._config[attr]['do_init_arrayobj']: #    obj.init_arrayobj(id,self,self.make_item_ident(attr,id)) # default is a class that needs to be initialized first # obj.init_arrayobj(id,self,self.make_item_ident(attr,id)) # use base function to get other default types # use base function to get other default types # use base function to get other default types # attr() copy(default) # else: #    print '  no attr found',self._groups.keys() # print '  attrs=',attrs Returns n default values for attribute with name attr_name         By default a scalar is returned.          If n>1 a list with n defaults is returned.          Usage:             Return a scalar default              self._get_default('attr_name')                  Return list with 5 defaults             self._get_default('attr_name',5)              Return list with 5 defaults, assigned with ids=[1,2,3,4,5].             This usage makes only sense with Classes or instances             with ArrayObj mixin.             self._get_default('attr_name',ids=[1,2,3,4,5]) # print '_get_default',self.ident,attr # create dummy ids # just a single id, do return a simple value, not a list # if default is an initialized class or an instance # and has also a dict or array structure, # then try to configure array object with id # default is instance so just make a copy # now configure array object # in this case class must have ArrayObj capabilities # (mixin) # default is a class that needs to be initialized first # use base function to get other default types # use base function to get other default types # use base function to get other default types # append to default list # print '_get_default array',defaults Deletes id from all array - tpe attributes # print 'ArrayConfigurator._del_ids',ids,'from',self.ident # delete ids from list , one by one # print '  start deleting id',id # print '      self._ids',self._ids # print '      self._inds',self._inds # i=self.get_index(id) # print '     ind=',i # print '     del rows from array-types...' # print '      del',attr,id,i # print '        before=\n',self.__dict__[attr] # print '        after=\n',self.__dict__[attr] # print '    del from id lookup' # print '    del from dicts' # print '      del',attr,id # print '    del from marrays' # what's left is to cut out the db pointer with index i # print '      del',attr,id,bp # print '    free index',id # id is highest, let's shrink index array by 1 # get ids of all indexes which are above i # decrease index from those wich are above the deleted one #put(self._inds, ids_above,take(self._inds,ids_above)-1) # print '    self._inds',self._inds # print '  Remove named' # print '    removed',name,id # print '  del',ids,' done.' This is setstate for array config only         and overrides the scalar version.          The main purpose is to correct a conversion error in numpy # this is alays required, but ill not be saved # print '  set state',key # print '    attr',key,type(value), # if type(value)==ndarray: #    print value.dtype,value.shape # else: #    print value # set other states # def del_manage_ids(self,ids): # """ # Specific item delete, called before removing data. # """ # pass This claass is empty and used as default. Class implements multiple queues with the following properties:         - only integers  can be queued         - each id can be only in one queue      Methods are implemented to insert and remove ids in queues     also in vectorial form. Main init used for stand alone. Queue specific initializations          items = optional instance that is an array of the integer items                 in the integer queue. The item must inherit IntegerItems                 methods and have this (self) queue class as parent. # use default items class Add ne items for queuing in database Returns True or False for each queue in the array         if respective queue is empty or non-empty Remove and return last items from queues in array  ids_queue Remove integers in array ids_item from queues in array ids_queue         If no ids_queue is given, it will be recovered from the integer items          database. This may only be a disadvantage in terms of time. # print 'remove_items' # print '  ids_item',ids_item # print '  ids_queue',ids_queue # identify single # remove single item in queues # identify last # remove last items in queues # identify first # remove first items in queues # identify middle # remove first items in queues # cutting items out of chains # finally remove pointer from items to queues Insert integers in array ids_item into queues in array ids_queue         behind integers in array ids_item_beh # print 'insert_items_beh' # print '  ids_item',ids_item # print '  ids_queue',ids_queue # print '  ids_item_beh',ids_item_beh # identify prepend # identify append # select rest # insert items where insertion somewhere in the middle # of the buffer where first and last item is not effected # this task can therefore be handeled by item instance Append integers in array ids_items to queues in array ids_queue # print 'append_items' # print '  ids_item',ids_item # print '  ids_queue',ids_queue # different treatmet of empty and not empty queues # treat first empty queues # print '  inds_empty',inds_empty # treat queues with at least one item # fix new first and last item # backward chaining # forward chaining # assign queue id Prepend integers in array ids_items to queues in array ids_queue # print 'prepend_items' # print '  ids_item',ids_item # print '  ids_queue',ids_queue # different treatmet of empty and not empty queues # treat first empty queues # print '  inds_empty',inds_empty # treat queues with at least one item # fix new first and last item # self['ids_last',ids_not_empty] = ids_items_next # not changed # forward chaining # backward chaining # assign queue id Print all usueful info Class cotaining integer items (the ids) of the integer queue.      This class can be used as mixin in order to add customized attributes to     each item. Main init used for stand alone. Here the item specific states are initialized.          queue_data is an optional database with additional information              on the queues where each id correspnds to a queue UNUSED!! see integerqueue!!          Insert integers in array ids_item into queues in array ids_queue         behind integers in array ids_item_beh.          Please use insert_behind of the governing queue class!          Attention this method is called by insert_behind of the          governing queue class, which selected already the cases where         this insertion is in the middle of the queue and does not effect         first or last item. # print 'IntegerItems.insert_items_beh' # print '  ids_item',ids_item # print '  ids_queue',ids_queue # print '  ids_item_beh',ids_item_beh # forward chaining # backward chaining # assign queue id to inserted elements Empty class with ArrayObjConfigurator properties.     Can be freely configured to contain any kind of database like,     ordered list structures.      Usage:          l=MetaList()          l.config('m',0.0,struct='marray')          l.create_ids([1,2,3,4])          l.print_config() test Mod specific Initialization.         self.id an parent is yet unknown # print 'initialized TestMod' Mod specific Initialization.         Now id and parent is known. # print 'config_with_id',self.ident # self.print_config() test Mod specific Initialization.         self.id an parent is yet unknown Mod specific Initialization.         Now id and parent is known. test Variable # self.config('mods',TestMod,struct='dict') #self.config('m',[0.0, 0.0, 0.0],struct='array') test Variable # type=['FloatType'], # print 'config=\n',self.get_config() test Variable test Variable #self.config('v',0.0, struct='array', group=['state']) # self.config('d',0.0,unit='m') # self.config('j',0.0,struct='array') # self.add_items(v=[8.7,5.5,34.1,2],a=[-8,-5,-34,-2]) # self.config('coords',array([0.0,0.0,0.0]), #            struct='array', #            name='coordinates', #            info='Array with xyz coordinates of each node') test     from base import *;t=MarrayTest();t['s',1]=[11,22,33,44];t['s',3]=[-33,-44]     t.get_ids_marray('s',[1,])     t['s',2]=[22,222,2222,22222]     t['s',[1,2]]=[[3,33,333],[55,555,5555,5555]]     t.get_ids_marray('s',[1,2,3])     t.get_ids_marray('s',[1,]) # self.config('s',[-1],struct='marray') # q.prepend_items(array([2,1],int),array([4,3],int)) # q.prepend_items(array([2,],int),array([3,],int)) ############################################################################### Test # a=array([[1,2,3],[4,5,6],[7,8,9],[11,22,33]]) # b=array([[1,0,1],[1,1,1],[1,0,0],[0,0,0]]) # cd C:\Documents and Settings\joerg\Documenti\projects\its # import sys; sys.path[:0] = ['C:\Users\joerg\projects\sim\its'] #from lib.base import * # t=MarrayTest();t['s',1]=[11,22,33,44];t['s',3]=[-33,-44] # t.get_ids_marray('s',[1,]) # t['s',2]=[22,222,2222,22222] # t['s',[1,2]]=[[3,33,333],[55,555,5555,5555]] # t.get_ids_marray('s',[1,2,3]) # t.get_ids_marray('s',[1,])