00001 """
00002 Base Container class for plug-ins to use
00003
00004 can be used as a test class eg vector("vec.test")
00005 returns a Vector instance with a DataContainer instance
00006 """
00007
00008 __copyright__ = """
00009 Copyright 2008 Sean Ross-Ross
00010 """
00011 __license__ = """
00012 This file is part of SLIMpy .
00013
00014 SLIMpy is free software: you can redistribute it and/or modify
00015 it under the terms of the GNU Lesser General Public License as published by
00016 the Free Software Foundation, either version 3 of the License, or
00017 (at your option) any later version.
00018
00019 SLIMpy is distributed in the hope that it will be useful,
00020 but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00022 GNU Lesser General Public License for more details.
00023
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00026 """
00027
00028
00029 from slimpy_base.Core.Interface.PSpace import PSpace
00030 from slimpy_base.Core.Command.Converter import Converter
00031 from slimpy_base.Environment.InstanceManager import InstanceManager
00032 from slimpy_base.Core.Interface.node import Node
00033 from pdb import set_trace
00034
00035
00036 __env__ = InstanceManager()
00037
00038 def contain( data ):
00039 """
00040 Contain some data.
00041 Uses plug-ins associated with the keystone class
00042 to find a dataContainer compatible with data.
00043 """
00044 keystone = __env__['keystone']
00045 for plugin in keystone.getplugins().values():
00046 if plugin.isCompatibleWith( data ):
00047
00048 return plugin( data )
00049
00050 raise AttributeError, "The data '%s' could not be contained" % data
00051
00052 class ScalarMethods( object ):
00053
00054 @classmethod
00055 def __call__(cls,container,scalar,*args,**kw):
00056 scalar.set( 0 )
00057
00058 return
00059
00060 def __str__(self):
00061 return "<adc ScalarMethods>"
00062
00063 class DataContainer( object ):
00064 """
00065 vectorflie has two main purposes - to keep track of "out of core"
00066 vectors corresponding binary files on disk
00067 and to act as a wrapper to a given library.
00068 """
00069 name = "ADC"
00070 test = 0
00071 _scalar_methods = ScalarMethods( )
00072
00073 def _get_referents(self):
00074 "Return the list of objects that are directly referred to by this container"
00075 return self._referents
00076
00077 def _get_referrers(self):
00078 "Return the list of objects that directly refer to self"
00079 return self._referents
00080
00081 referents = property( _get_referents,
00082 doc="Return the list of objects that are directly referred to by this container" )
00083
00084 referrers = property( _get_referrers,
00085 doc="Return the list of objects that directly refer to self" )
00086
00087
00088 def add_referent(self, id):
00089 'add to the list of objects that are directly referred to by this container'
00090 self.referents.add( id )
00091
00092 def add_referrers(self, id ):
00093 'add to the list of objects that directly refer to self'
00094 self.referrers.add( id )
00095
00096 @classmethod
00097 def isCompatibleWith( cls, data ):
00098 """
00099 method to determine if the data is compatible with
00100 Data 'data'.
00101 """
00102 if isinstance( data, str ):
00103 if data.endswith( '.test' ):
00104 return True
00105 return False
00106
00107 def __init__( self , data=None , parameters=None, command=None, tmp=None,
00108 nodenames=None,
00109 node_info=None,
00110 target_node=None ):
00111 """
00112 create container: both data and parameters may not be none.
00113 and are mutually exclusive.
00114 if parameters is None: data is expected to exist and parameters will be generated
00115 if data is None: this instance will be assumed to need to be created.
00116 """
00117 self._referents = set( )
00118 self._referrers = set( )
00119 self.__data = data
00120 self._temporary = True
00121 self._node_names = set()
00122 self._node_info = { }
00123 self._target_node = None
00124
00125
00126 if parameters is None and data is None:
00127 raise TypeError, "parameters and data may not both be None"
00128
00129 elif data is None:
00130
00131 if tmp is None:
00132 self._temporary = True
00133 else:
00134 self._temporary = tmp
00135
00136 if nodenames:
00137 raise Exception("Data not created yet node is specified")
00138
00139 self._target_node = target_node
00140
00141
00142 self.__data = self.genName(command=command)
00143 self.__parameters = parameters
00144 else:
00145 if tmp is None:
00146 self._temporary = False
00147 else:
00148 self._temporary = tmp
00149
00150 if nodenames and target_node:
00151 raise Exception("can not specify both keyword arguments "
00152 "'nodenames' and 'target_node'")
00153 elif nodenames:
00154 self._node_names.update( nodenames )
00155 elif target_node:
00156 self._target_node = target_node
00157 if node_info:
00158 self._node_info[target_node] = node_info
00159 else:
00160 self.add_node_name( "localhost" )
00161
00162 if node_info:
00163 for node in self.nodenames:
00164 self._node_info[node] = node_info
00165
00166
00167 if parameters is None:
00168 self.__parameters = self.makeparams()
00169 else:
00170 self.__parameters = parameters
00171
00172 if node_info:
00173 for node in self.nodenames:
00174 self._node_info[node] = node_info
00175
00176 return
00177
00178 def add_target_to_current( self ):
00179 self.add_node_name( self.target_node )
00180
00181 def getScalar_methods(self):
00182 return self._scalar_methods
00183
00184 def __is_global(self):
00185 if self.nodenames:
00186 return bool( 'localhost' in self.nodenames)
00187 elif self.target_node:
00188 return bool( 'localhost' == self.target_node)
00189 else:
00190 return False
00191
00192
00193 def __is_local(self):
00194
00195 return not self.__is_global( )
00196
00197 is_global = property( __is_global )
00198 is_local = property( __is_local )
00199
00200
00201 def add_node_name(self,name):
00202 if self.is_global:
00203 self._node_names.add( 'localhost' )
00204 else:
00205 self._node_names.add( name )
00206
00207 def _get_node_names(self):
00208 return self._node_names
00209
00210 nodenames = property( _get_node_names )
00211
00212 def node_copy(self,node_name):
00213 """
00214 copy data from node to node, data container stays the same
00215 """
00216 self.add_node_name(node_name)
00217
00218 def _get_target_node(self):
00219 return self._target_node
00220
00221 target_node = property( _get_target_node )
00222
00223 def _get_data( self ):
00224 """
00225 get the data contained
00226 """
00227 return self.__data
00228
00229 def _set_data( self ,val ):
00230 """
00231 get the data contained
00232 """
00233 self.__data = val
00234
00235 def get_data( self, node_name ):
00236 return self.__data
00237
00238 def setData( self, data ):
00239
00240 self.__data = data
00241
00242 data = property( _get_data , _set_data )
00243
00244 def __setitem__( self, item, value ):
00245
00246 assert item == 'data', "can not set the item %s(item)s" % vars()
00247
00248 self.__data = value
00249
00250
00251
00252 def isempty( self ):
00253 """
00254 Returns True if the data associated with self.data does not exist
00255 """
00256 return True
00257
00258 def isfull( self ):
00259 """
00260 Returns True if the data associated with self.data exists
00261 """
00262 if self.__dict__.has_key( 'full' ) :
00263
00264 return True
00265
00266
00267 return not self.isempty()
00268
00269
00270 def tmp( self, TMP=None ):
00271 """
00272 set whether the data is temporary
00273 or not
00274 """
00275 if TMP is None:
00276 self._temporary = not self._temporary
00277
00278 else:
00279 self._temporary = TMP
00280
00281 def istmp( self ):
00282 """
00283 query whether the data is temporary
00284 """
00285 return self._temporary
00286
00287 def remove( self ):
00288 """
00289 remove the data from memory
00290 """
00291 return self.rm()
00292
00293
00294
00295
00296 def __str__( self ):
00297 """Adds the current lib's suffix to the end of filename
00298 note: if no lib is set then self.plugin.suffix returns ''
00299 """
00300 return str( self.__data )
00301
00302 def __repr__( self ):
00303 """
00304 see: __str__
00305 """
00306 return str( self )
00307
00308
00309
00310
00311
00312 @classmethod
00313 def get_converter(cls , command ):
00314 return Converter
00315
00316 def getParameters( self ):
00317 """
00318 return parameter instance
00319 """
00320 return self.__parameters
00321
00322 params = property( getParameters )
00323
00324 def available_from( self, nodename ):
00325 return true
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 def makeparams( self ):
00370 """
00371 make the parameter object from the given data
00372 should be extended for each plug-in
00373 """
00374 par= PSpace( self.__class__, self.readattr() )
00375
00376 return par
00377
00378
00379 def genName( self, command=None ):
00380 """
00381 generate a name for the data
00382 """
00383 DataContainer.test += 1
00384 return"%s_%04d.test" %( self.name, self.test )
00385
00386
00387 def __del__( self ):
00388 """ overrides the del method
00389 if the object is deleted and there is a file that corresponds to filename and self.istpm
00390 then remove will be called to remove the file
00391 """
00392
00393
00394
00395
00396
00397
00398
00399 def plot( self ):
00400 """
00401 Plot the data to view it
00402
00403 """
00404 pass
00405
00406
00407 def readattr( self ):
00408 """
00409 read the attributes of the data
00410 """
00411 return {}
00412
00413
00414 def readbin( self, i, shape ):
00415 """
00416 read the binary elements of the data
00417 """
00418 pass
00419
00420 def scalar_reduction( self, cmd, *args, **kargs ):
00421 """
00422 return the string '${SCALAR}'
00423 """
00424 return "${SCALAR}"
00425
00426 def writebin( self, data, i , j ):
00427 """
00428 write the binary elements of the data
00429 """
00430 pass
00431
00432
00433 def writeattr( self, vector_dict, file_dict ):
00434 pass
00435
00436
00437 def rm( self ):
00438 """
00439 remove the data from memory
00440 """
00441 pass
00442
00443 def diagnostic(self):
00444
00445 return True
00446
00447 scalar_methods = property( getScalar_methods )
00448
00449 def expand_meta( self, metaspace ):
00450
00451 raise Exception('this is not meta data')
00452
00453
00454 def _get_contained(self):
00455 return self._contained
00456
00457 def _set_contained(self, val ):
00458 meta_id = Node( self ).id
00459
00460 for node in [ Node(container) for container in val ]:
00461 node.add_referrers( meta_id )
00462 self.add_referent( node.id )
00463
00464 self._contained = val
00465
00466 contained = property( _get_contained, _set_contained )
00467
00468