00001 #!/usr/local/bin/python 00002 # 00003 # Copyright 2002 00004 # by 00005 # The Board of Trustees of the 00006 # Leland Stanford Junior University. 00007 # All rights reserved. 00008 # 00009 00010 __facility__ = "Online" 00011 __abstract__ = "Classes for defining constraints" 00012 __author__ = "R. Claus <Claus@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online" 00013 __date__ = ("$Date: 2005/03/20 00:58:14 $").split(' ')[1] 00014 __version__ = "$Revision: 2.3 $" 00015 __credits__ = "SLAC" 00016 00017 import LATTE.copyright_SLAC 00018 00019 import exceptions 00020 import gGroup 00021 00022 True = (0 < 1) 00023 False = not True 00024 00025 class gConstraintViolation(exceptions.Exception): 00026 """\brief Constraint Violation Class 00027 00028 Exception class used in constraint classes 00029 """ 00030 def __init__(self, args=None): 00031 self.args = args 00032 00033 00034 class GconstraintBase(object): 00035 """\brief Base constraint class for use when no constraint is appropriate. 00036 """ 00037 def __init__(self): 00038 pass 00039 00040 def evaluate(self, value): 00041 return (value, False) 00042 00043 class Gconstraint(GconstraintBase): 00044 """\brief Base class for describing constraints 00045 """ 00046 def __init__(self, name, subsystem, category, enabled, continuous = False): 00047 """ Constructor. 00048 \param name Constraint name 00049 \param subsystem Subsystem gGroup to which the constraint belongs 00050 \param category Category gGroup to which the constraint belongs 00051 \param enabled Flag indicating whether constraint is enabled 00052 \param continuous Flag indicating whether constraint can fire repeatedly 00053 """ 00054 self.__name = name 00055 self.__subsystem = subsystem 00056 self.__category = category 00057 self.__enabled = enabled 00058 self.__continuous = continuous 00059 self.__fired = False 00060 00061 def _eval_(self, value): 00062 """Dummy evaluation method to be overridden through inheritance to implement 00063 the application specific constraint evaluation""" 00064 return (value, False) 00065 00066 def evaluate(self, value): 00067 """This method is called to evaluate the constraint on 'value'""" 00068 if self.__subsystem.enabled() and \ 00069 self.__category.enabled() and \ 00070 self.__enabled: 00071 return self._eval_(value) 00072 else: 00073 return (value, False) 00074 00075 def name(self): 00076 """Method to retrieve the constraint's name""" 00077 return self.__name 00078 00079 def subsystem(self): 00080 """Method for discovering this constraint's subsystem""" 00081 return self.__subsystem 00082 00083 def category(self): 00084 """Method for discovering this constraint's category""" 00085 return self.__category 00086 00087 def enabled(self): 00088 """Method for discovering whether this constraint is enabled""" 00089 return self.__enabled 00090 00091 def enable(self): 00092 """Method used to enable evaluation of this constraint""" 00093 self.__enabled = True 00094 00095 def disable(self): 00096 """Method used to disable evaluation of this constraint""" 00097 self.__enabled = False 00098 00099 def reset(self): 00100 """Method used to reenable evaluation of this constraint in the case of 00101 noncontinuous mode after it has been violated""" 00102 self.__fired = False 00103 00104 def reject(self, message): 00105 """Method optionally used by the constraint evaluation implementation to 00106 signal a constraint violation""" 00107 if self.__continuous or not self.__fired: 00108 self.__fired = True 00109 raise gConstraintViolation, message 00110 00111 00112 class GconstraintLimitRE(Gconstraint): 00113 """\brief On Constraint Limit Raise Exception 00114 00115 Constraint class that determines whether to raise an exception 00116 based on the passed in value being within given limits. 00117 """ 00118 def __init__(self, name, subsystem, category, enabled, continuous, 00119 low, high): 00120 Gconstraint.__init__(self, name, subsystem, category, enabled, continuous) 00121 self.__low = low 00122 self.__high = high 00123 00124 def _eval_(self, value): 00125 if value < self.__low or value > self.__high: 00126 self.reject("%s constraint: value is driven out of range" % self._Gconstraint__name) 00127 return (value, True) 00128 return (value, False) 00129 00130 00131 class GconstraintLimit(Gconstraint): 00132 """\brief Limit Constraint 00133 00134 Constraint class that limits a passed in value to given limits. If the 00135 value is outside of the constraint limits, it is pegged to the nearest limit. 00136 """ 00137 def __init__(self, name, subsystem, category, enabled, continuous, 00138 low, high): 00139 Gconstraint.__init__(self, name, subsystem, category, enabled, continuous) 00140 self.__low = low 00141 self.__high = high 00142 00143 def _eval_(self, value): 00144 if value < self.__low: 00145 print "%s constraint: value is driven to the low constraint" % self.name() 00146 return (self.__low, False) 00147 elif value > self.__high: 00148 print "%s constraint: value is driven to the high constraint" % self.name() 00149 return (self.__high, False) 00150 else: 00151 return (value, False) 00152 00153 class GconstraintLimitPegRE(Gconstraint): 00154 """\brief Pegged Limit Constraint 00155 00156 Constraint class that limits a passed in value to given limits. If the 00157 value is outside of the constraint limits, it raises an exception AND the 00158 value is pegged to the nearest limit. 00159 """ 00160 def __init__(self, name, subsystem, category, enabled, continuous, 00161 low, high): 00162 Gconstraint.__init__(self, name, subsystem, category, enabled, continuous) 00163 self.__low = low 00164 self.__high = high 00165 00166 def _eval_(self, value): 00167 if value < self.__low: 00168 violMsg = "Driven to low constraint" 00169 self.reject(violMsg) 00170 return (self.__low, True) 00171 elif value > self.__high: 00172 violMsg = "Driven to high constraint" 00173 self.reject(violMsg) 00174 return (self.__high, True) 00175 else: 00176 return (value, False)