00001 #!/usr/local/bin/python
00002 #
00003 # Copyright 2004
00004 # by
00005 # The Board of Trustees of the
00006 # Leland Stanford Junior University.
00007 # All rights reserved.
00008 #
00009
00010
00011 __facility__ = "Online"
00012 __abstract__ = "GLAST functional block base class"
00013 __author__ = "Selim Tuvi <stuvi@slac.stanford.edu> SLAC - GLAST LAT I&T/Online"
00014 __date__ = ("$Date: 2004/09/07 21:00:29 $").split(' ')[1]
00015 __version__ = "$Revision: 2.13 $"
00016 __release__ = "$Name: P04-06-05 $"
00017 __credits__ = "SLAC"
00018
00019 import LATTE.copyright_SLAC
00020
00021 import gAttr
00022 from LATTE.client.gNode import Node
00023
00024 class Gdb(Node):
00025 """\brief Base class for all GLAST LAT functional blocks.
00026
00027 Uses __getattr__ and __setattr__ methods to feature an SCL like syntax
00028 for referencing attributes
00029 """
00030 def __init__(self, client, parent, id, valid_attrs=[], addr=None):
00031 """gNode constructor.
00032
00033 \param valid_regs A list of valid attribute names.
00034 """
00035 Node.__init__(self, client)
00036 self.__parent = parent
00037 self.__id = id
00038 if addr is None:
00039 self.__addr = id
00040 else:
00041 self.__addr = addr
00042
00043 attrDict = _regList()
00044 self.__dict__['regs'] = attrDict
00045
00046 #Instantiate all attributes
00047 for attr in valid_attrs:
00048 attrDict[attr.getName()] = attr.create(self)
00049
00050 def up(self):
00051 """Return the parent of this component
00052 """
00053 return self.__parent
00054
00055 def id(self):
00056 """Return the hardware id of this component
00057 """
00058 return self.__id
00059
00060 def addr(self):
00061 """Return the hardware address of this component
00062 """
00063 return self.__addr
00064
00065 def root(self):
00066 """Return the root node in this node's hierarchy
00067
00068 \return The root node
00069 """
00070 root = self
00071 while root.up() is not None:
00072 root = root.up()
00073 return root
00074
00075 def getIdTuple(self):
00076 """Return the node id(s) in this node's hierarchy
00077
00078 \return The root node
00079 """
00080 idtuple = []
00081 root = self
00082 while root.up() is not None:
00083 idtuple.append(root.id())
00084 root = root.up()
00085 idtuple.reverse()
00086 return tuple(idtuple)
00087
00088 def getName(self):
00089 return self.__class__.__name__
00090
00091 def getOpaque(self, name=None):
00092 """\brief Retrieves the named opaque data included in the schema
00093 The opaque data needs to be associated with a node therefore this
00094 method only returns the opaque data that is associated with that
00095 node.
00096
00097 \param name Name of the opaque XML data (optional)
00098
00099 \return A list of XML DOM objects matching \a name
00100 or if \a name is None a dictionary of a list
00101 of XML DOM objects
00102 """
00103 root = self.root()
00104 rname = root.__class__.__name__
00105 rdict = root.__dict__
00106 opaque = rdict["_" + rname + '__opaque']
00107 if self in opaque:
00108 if name is None:
00109 return opaque[self]
00110 elif name in opaque[self]:
00111 return opaque[self][name]
00112
00113 def getSerialNos(self, component=None):
00114 """\brief Retrieves the serial numbers associated with the node
00115
00116 \param component Hardware component identifier (optional)
00117
00118 \return A dictionary matching \a component
00119 or if \a component is None a dictionary of all
00120 components and their serial numbers
00121 """
00122 root = self.root()
00123 rname = root.__class__.__name__
00124 rdict = root.__dict__
00125 serialnos = rdict["_" + rname + '__serialnos']
00126 if self in serialnos:
00127 if component is None:
00128 return serialnos[self]
00129 elif component in serialnos[self]:
00130 return {component: serialnos[self][component]}
00131
00132 ## private:
00133 #
00134 # The following was an attempt to optimize access for mixed case attribute
00135 # names. Unfortunately we run into trouble with the tem.regs['configuration']
00136 # type notation, and with constructs like 'for reg in regs' which returns
00137 # the attribute in each casing. We punt on it for now (Thu Aug 19 2004)
00138 #
00139 # def __setattr__(self, attribute, value):
00140 # attrDict = self.__dict__
00141 # if attribute in attrDict:
00142 # attrDict[attribute] = value
00143 # return
00144 # try:
00145 # regs = attrDict['regs']
00146 # except KeyError:
00147 # attrDict[attribute] = value
00148 # return
00149 # try:
00150 # regs[attribute].set(value, 0, self)
00151 # except KeyError:
00152 # try:
00153 # attr = regs[attribute.lower()]
00154 # except KeyError:
00155 # raise AttributeError("Attribute " + attribute + " not found")
00156 # regs[attribute] = attr
00157 # attr.set(value, 0, self)
00158
00159 # def __getattr__(self, attribute):
00160 # attrDict = self.__dict__
00161 # if attribute in attrDict:
00162 # return attrDict[attribute]
00163 # try:
00164 # regs = attrDict['regs']
00165 # return regs[attribute].get(0, self)
00166 # except KeyError:
00167 # try:
00168 # attr = regs[attribute.lower()]
00169 # except KeyError:
00170 # raise AttributeError("Attribute " + attribute + " not found")
00171 # regs[attribute] = attr
00172 # return attr.get(0, self)
00173
00174 def __setattr__(self, attribute, value):
00175 """Gets called when a syntax like 'gtem.configuration = 5' is used"""
00176 attrDict = self.__dict__
00177 try:
00178 regs = attrDict['regs']
00179 if attribute in regs:
00180 regs[attribute].set(value, 0, self)
00181 elif attribute in attrDict:
00182 attrDict[attribute] = value
00183 else:
00184 raise AttributeError("Attribute " + attribute + " not found")
00185 except KeyError:
00186 if 'regs' not in attrDict:
00187 attrDict[attribute] = value
00188 else:
00189 raise AttributeError("Attribute " + attribute + " not found")
00190
00191 def __getattr__(self, attribute):
00192 """Gets called when a syntax like 'print gtem.configuration' is used"""
00193 try:
00194 return self.__dict__['regs'][attribute].get(0, self)
00195 except KeyError:
00196 raise AttributeError("Attribute " + attribute + " not found")
00197
00198 class _regList(dict):
00199 def __init__(self):
00200 dict.__init__(self)
00201
00202 def __getitem__(self, attribute):
00203 return dict.__getitem__(self, attribute.lower())
00204
00205 def __setitem__ (self, attribute, value):
00206 dict.__setitem__(self, attribute.lower(), value)
00207
00208 def get (self, attribute, default=None):
00209 return dict.get(self, attribute.lower(), default)
00210
00211 def has_key(self, attribute):
00212 return dict.has_key(self, attribute.lower())
00213
00214 def __contains__(self, attribute):
00215 return dict.__contains__(self, attribute.lower())
00216
00217
00218 class Children(dict):
00219 BCASTID = 0xff
00220
00221 def __init__(self, parent, type):
00222 dict.__init__(self)
00223 self.__parent = parent
00224 self.__type = type
00225 self.__bcast = None
00226
00227 def remove(self, id):
00228 if id in self:
00229 self.__delitem__(id)
00230 elif id == Children.BCASTID:
00231 self.__bcast = None
00232 else:
00233 print "*** gDb: id %d not found for %s %d" %(id, self.__parent.getName(), self.__parent.id())
00234
00235 def add(self, id):
00236 if id == Children.BCASTID:
00237 if self.__bcast is not None:
00238 print "*** gDb: bcast %s already exists for %s %d" \
00239 %(self.__bcast.getName(),
00240 self.__parent.getName(), self.__parent.id())
00241 else:
00242 self.__bcast = self.__type(self.__parent.client(), self.__parent, id)
00243 return self.__bcast
00244 elif id in self:
00245 print "*** gDb: child %s %d already exists for %s %d" \
00246 %(self[id].getName(), id,
00247 self.__parent.getName(), self.__parent.id())
00248 else:
00249 self[id] = self.__type(self.__parent.client(), self.__parent, id)
00250 return self[id]
00251
00252 def down(self, id):
00253 if id in self:
00254 return self[id]
00255 elif id == Children.BCASTID:
00256 return self.__bcast
00257 else:
00258 return None
00259
00260 def exists(self, id):
00261 if id in self:
00262 return True
00263 elif id == Children.BCASTID and self.__bcast is not None:
00264 return True
00265 return False
00266
00267 def all(self):
00268 return self.__bcast