Package qtcm :: Module field
[hide private]
[frames] | no frames]

Source Code for Module qtcm.field

  1  #!/usr/bin/python -tt 
  2  #======================================================================= 
  3  #                        General Documentation 
  4   
  5  """Module for class defining QTCM fields. 
  6   
  7  A field is a model parameters or variables, and includes diagnotic 
  8  and prognostic variables, run parameters, coefficients, etc. 
  9  """ 
 10   
 11  #----------------------------------------------------------------------- 
 12  #                       Additional Documentation 
 13  # 
 14  # RCS Revision Code: 
 15  #   $Id: field.py 4 2008-06-25 01:03:28Z jlin $ 
 16  # 
 17  # Modification History: 
 18  # - 29 May 2008:  Original by Johnny Lin, Physics Department, North 
 19  #   Park University.  Passed passably reasonable tests. 
 20  # 
 21  # Notes: 
 22  # - Written for Python 2.4. 
 23  # - Module docstrings can be tested using the doctest module.  To 
 24  #   test, execute "python field.py". 
 25  # - See import statements throughout for non-"built-in" packages and 
 26  #   modules required. 
 27  # 
 28  # Copyright (c) 2008 by Johnny Lin.  For licensing, distribution  
 29  # conditions, contact information, and additional documentation see 
 30  # the URL http://www.johnny-lin.com/py_pkgs/qtcm/doc/. 
 31  #======================================================================= 
 32   
 33   
 34   
 35   
 36  #---------------- Module General Import and Declarations --------------- 
 37   
 38  #- If you're importing this module in testing mode, or you're running 
 39  #  pydoc on this module via the command line, import user-specific 
 40  #  settings to make sure any non-standard libraries are found: 
 41   
 42  import os, sys 
 43  if (__name__ == "__main__") or \ 
 44     ("pydoc" in os.path.basename(sys.argv[0])): 
 45      import user 
 46  del os, sys 
 47   
 48   
 49  #- Import package version and set module version to package version: 
 50   
 51  import package_version as _package_version 
 52  __version__ = _package_version.version 
 53  __author__  = _package_version.author 
 54  __date__    = _package_version.date 
 55  __credits__ = _package_version.credits 
 56   
 57   
 58  #- Import numpy/Numeric/numarray as appropriate: 
 59   
 60  import num_settings as num 
 61  from num_settings import N 
 62   
 63   
 64  #- Other module imports: 
 65   
 66  from defaults import qtcm_fields as qtcm_defaults 
 67   
 68   
 69   
 70   
 71  #---------------------------- Class:  Field ---------------------------- 
 72   
73 -class Field(object):
74 """Class for QTCM fields. 75 76 QTCM fields are model parameters or variables, and includes 77 diagnotic and prognostic variables, run parameters, coefficients, 78 etc. They can be scalars (numeric or string) or arrays. The 79 values of these QTCM parameter objects can be changed in the 80 model by a call at the Python level, though the types of their 81 compiled model counterparts cannot be changed (without recompiling 82 the compiled model, of course). 83 84 The default values of QTCM fields that are defined in the 85 defaults module specify the type of the variables, as well as 86 the rank. This information is used by the Qtcm class to properly 87 interface with the compiled model. Thus, fields that are not 88 specified in the defaults module will not properly interface 89 with the compiled model. However, some fields only need to be 90 defined at the Python level; those fields do not have to be 91 listed in defaults. 92 93 Class Instance Attributes: 94 * id: A string naming the field (e.g., 'Qc', 'mrestart'). This 95 string should contain no whitespace. 96 * value: The value of the field. Can be of any type, though 97 typically is either a string or numeric scalar or a numeric 98 array. 99 * units: A string giving the units of the field. 100 * long_name: A string giving a description of the field. 101 102 Class Instance Methods: 103 * rank: Returns the rank of value. 104 * typecode: Returns the typecode of value. 105 """
106 - def __init__(self, *args, **kwds):
107 """Initialize Field object. 108 109 The Field object is instantiated either with one or two 110 positional input parameters, and up to two optional keyword 111 input parameters. 112 113 Positional Input Parameters: 114 * One argument: The argument is a string that specifies 115 the name of the field. The name must match a key in 116 defaults.qtcm_fields. The value of the Field instance 117 is set to the default value given in defaults.qtcm_fields. 118 119 * Two arguments: The first argument is a string specifying 120 the name of the field (as in the one argument case). The 121 second argument is the value that the Field instance is 122 set to. If the second argument is a Field object, the 123 value of that Field object is extracted as the value for 124 creating the current Field object. 125 126 Keyword Input Parameters: 127 * units: String specifying the units of the field. 128 129 * long_name: String specifying the long name of the field. 130 131 Examples: 132 >>> a = Field('dt') 133 >>> print a.id 134 dt 135 >>> print a.value 136 1200.0 137 138 >>> a = Field('dt', 1200.) 139 >>> print a.id 140 dt 141 >>> print a.value 142 1200.0 143 >>> print a.units 144 s 145 >>> print a.long_name 146 time step 147 148 >>> a = Field('dt', Field('dt'), units='h') 149 >>> print a.id 150 dt 151 >>> print a.value 152 1200.0 153 >>> print a.units 154 h 155 156 >>> a = Field(23) 157 Traceback (most recent call last): 158 ... 159 TypeError: Field id must be string 160 """ 161 if type(args[0]) != type('a'): 162 raise TypeError, self.__class__.__name__ + ' id must be string' 163 164 if len(args) == 1: 165 self.id = args[0] 166 self.value = qtcm_defaults[self.id]['value'] 167 elif len(args) == 2: 168 self.id = args[0] 169 if type(args[1]) == type(self): 170 if args[1].id != self.id: 171 raise ValueError, 'id mismatch' 172 self.value = args[1].value 173 else: 174 self.value = args[1] 175 else: 176 raise ValueError, '1-2 required arguments for ' \ 177 + self.__class__.__name__ 178 179 if kwds.has_key('units'): 180 self.units = kwds['units'] 181 else: 182 self.units = qtcm_defaults[self.id]['units'] 183 184 if kwds.has_key('long_name'): 185 self.long_name = kwds['long_name'] 186 else: 187 self.long_name = qtcm_defaults[self.id]['long_name']
188 189
190 - def rank(self):
191 """Return the rank of self.value. 192 193 If self.value does not exist, returns None. 194 """ 195 if hasattr(self, 'value'): 196 return N.rank(self.value) 197 else: 198 return None
199 200
201 - def typecode(self):
202 """Return the typecode of self.value. 203 204 The typecode is determined by first converting self.value 205 into an array, and then returning the dtype.char (in numpy). 206 This is defined in the module num_settings, and is a function 207 of what type of array package you're using. As a result, 208 you shouldn't assume this method is very precise (e.g., 209 don't use it to distinguish between single and double 210 precision float), but rather, use it to distinguish between 211 different categories of types (e.g., float vs. int). If 212 self.value does not exist, returns None. 213 """ 214 if hasattr(self, 'value'): 215 return num.typecode(self.value) 216 else: 217 return None
218 219 220 221 222 #-------------------------- Main: Test Module ------------------------- 223 224 #- Execute doctest if module is run from command line: 225 226 if __name__ == "__main__": 227 """Test the module. 228 229 Note: To help ensure that module testing of this file works, the 230 parent directory to the current directory is added to sys.path. 231 """ 232 import doctest, sys, os 233 sys.path.append(os.pardir) 234 doctest.testmod(sys.modules[__name__]) 235 236 237 238 239 # ===== end file ===== 240