class LMyItem(LItem): ''' >>> item1 = LMyItem() >>> item1.pvName = 'TEST:1:AO' >>> print item1 <LMyItem: pvName='TEST:1:AO' weight=-2.0> >>> item1.toCsv() 'TEST:1:AO,2.0' >>> item2 = LMyItem() >>> item2.fromCsv(item1.toCsv()) >>> print item2 <LMyItem: pvName='TEST:1:AO' weight=-2.0> >>> item1 == item1 True >>> item1 == item2 False ''' def __init__(self): super(LMyItem, self).__init__() self.pvName = 'TEST:AO' self.weight = 2.0 self._orderedAttributes = 'pvName', 'weight' self._getitemAttributes = 'pvName', 'weight', '_setpointAtInit', '_currentSetpoint' self.setUpdateTimeout(UPDATE_TIMEOUT) self._pv = None self._currentSetpoint = None self._setpointAtInit = None self.setUpdateTimeout(UPDATE_TIMEOUT) def updateAttributes(self): if self._pv is None: self._pv = LEpicsPv(self.pvName) self._currentSetpoint = self.caget() if self._setpointAtInit is None: self._setpointAtInit = self._currentSetpoint def caget(self): return self._pv.caget() def caput(self, value, wait=False): status = self._pv.caput(value, wait) return status
class LCondition(LItem): ''' >>> c = LCondition() >>> c <LCondition: pvName='TEST:AO' minimum=-10.0 maximum=10.0 action='Skip' description='Test condition'> >>> c.connectPv() >>> c.check() ''' def __init__(self, parent = None): """ No description here because not needed at this low level """ super(LCondition, self).__init__(parent) self.pvName = "TEST:AO" self.minimum = -10.0 self.maximum = 10.0 self.action = 'Skip' self._pv = None self._orderedAttributes = 'pvName', 'minimum', 'maximum', 'action' @LInAndOut(DEBUG & ITEMS) def connectPv(self): self._pv = LEpicsPv(self.pvName) @LInAndOut(DEBUG & ITEMS) def check(self): ''' Check that the condition is met ''' exception = None pvValue = self._pv.get() if (pvValue > self.maximum): if self.action == 'Skip' : raise Exception('%s < %f (min)' % (self.pvName, self.minimum), 'Skip iteration') if self.action == 'Pause' : raise Exception('%s < %f (min)' % (self.pvName, self.minimum), 'Pause requested') if self.action == 'Stop' : raise Exception('%s < %f (min)' % (self.pvName, self.minimum), 'Stop requested') else: raise Exception('%s > %f (max)' % (self.pvName, self.maximum), 'Pv above maximum') if (pvValue < self.minimum): if self.action == 'Skip' : raise Exception('%s < %f (min)' % (self.pvName, self.minimum), 'Skipping iteration') if self.action == 'Pause' : raise Exception('%s < %f (min)' % (self.pvName, self.minimum), 'Pause requested') if self.action == 'Stop' : raise Exception('%s < %f (min)' % (self.pvName, self.minimum), 'Stop requested') else: raise Exception('%s < %f (min)' % (self.pvName, self.minimum), 'Pv below minimum') verbose(self, " %f < { %s = %f } < %f" % (self.minimum , self.pvName, pvValue, self.maximum), 2) return(True)
class LCondition(LItem): """ >>> c = LCondition() >>> c <LCondition: pvName='TEST:AO' minimum=-10.0 maximum=10.0 action='Skip' description='Test condition'> >>> c.connectPv() >>> c.check() """ def __init__(self, parent=None): super(LCondition, self).__init__(parent) self.pvName = "TEST:AO" self.minimum = -10.0 self.maximum = 10.0 self.action = "Skip" self._pv = None self._orderedAttributes = "pvName", "minimum", "maximum", "action" @LInAndOut(DEBUG & ITEMS) def connectPv(self): self._pv = LEpicsPv(self.pvName) @LInAndOut(DEBUG & ITEMS) def check(self): """ Check that the condition is met """ exception = None pvValue = self._pv.get() if pvValue > self.maximum: if self.action == "Skip": raise Exception("%s < %f (min)" % (self.pvName, self.minimum), "Skip iteration") if self.action == "Pause": raise Exception("%s < %f (min)" % (self.pvName, self.minimum), "Pause requested") if self.action == "Stop": raise Exception("%s < %f (min)" % (self.pvName, self.minimum), "Stop requested") else: raise Exception("%s > %f (max)" % (self.pvName, self.maximum), "Pv above maximum") if pvValue < self.minimum: if self.action == "Skip": raise Exception("%s < %f (min)" % (self.pvName, self.minimum), "Skipping iteration") if self.action == "Pause": raise Exception("%s < %f (min)" % (self.pvName, self.minimum), "Pause requested") if self.action == "Stop": raise Exception("%s < %f (min)" % (self.pvName, self.minimum), "Stop requested") else: raise Exception("%s < %f (min)" % (self.pvName, self.minimum), "Pv below minimum") verbose(self, " %f < { %s = %f } < %f" % (self.minimum, self.pvName, pvValue, self.maximum), 2) return True
class LMyMeasurement(LItem): ''' >>> item1 = LMyMeasurement() >>> item1 <LMyMeasurement: pvName='TEST:AI' numberOfSamples=10 operations='Maximum:Minimum:Mean:Median:Sigma:Variance'> >>> print "%s" % item1 <LMyMeasurement: pvName='TEST:AI' numberOfSamples=10 operations='Maximum:Minimum:Mean:Median:Sigma:Variance'> ''' def __init__(self): super(LMyMeasurement, self).__init__() self.pvName = 'TEST:AI' self.numberOfSamples = 10 self.operations = 'Maximum:Minimum:Mean:Median:Sigma:Variance' self._orderedAttributes = 'pvName', 'numberOfSamples', 'operations' self.samples = np.empty((0, self.numberOfSamples), dtype = 'float') self.mean = np.empty(0, dtype = 'float') self.median = np.empty(0, dtype = 'float') self.var = np.empty(0, dtype = 'float') self.std = np.empty(0, dtype = 'float') self.min = np.empty(0, dtype = 'float') self.max = np.empty(0, dtype = 'float') self.ptp = np.empty(0, dtype = 'float') self._pv = None @LInAndOut(DEBUG & ITEMS) def connectPv(self): self._pv = LEpicsPv(self.pvName) @LInAndOut(DEBUG & ITEMS) def get(self): return self._pv.caget() def getOperations(self): def mapFunc(operation): operation = operation.lower() if operation == 'variance' : operation = 'var' elif operation == 'maximum' : operation = 'max' elif operation == 'minimum' : operation = 'min' elif operation == 'peaktopeak': operation = 'ptp' elif operation == 'standarddeviation': operation = 'std' return operation operations = map(mapFunc, self.operations.split(':')) return operations
def connectPv(self): self._pv = LEpicsPv(self.pvName)
def updateAttributes(self): if self._pv is None: self._pv = LEpicsPv(self.pvName) self._currentSetpoint = self.caget() if self._setpointAtInit is None: self._setpointAtInit = self._currentSetpoint
def connectPv(self): self._pv = LEpicsPv(self.pvName) self._setpointAtInit = self._pv.caget()
class LMyKnob(LItem): ''' >>> item1 = LMyKnob() >>> item1.pvName = 'TEST:1:AO' >>> item1.pvName 'TEST:1:AO' >>> item1.setDebugLevel(0) >>> item1['pvName'] 'TEST:1:AO' >>> print item1 <LMyKnob: pvName='TEST:1:AO' start=-10.0 stop=10.0 mode='Absolute'> >>> item1.toCsv() 'TEST:1:AO,-10.0,10.0,Absolute' >>> item2 = LMyKnob() >>> item2.fromCsv(item1.toCsv()) >>> print item2 <LMyKnob: pvName='TEST:1:AO' start=-10.0 stop=10.0 mode='Absolute'> >>> item1 == item1 True >>> item1 == item2 False ''' def __init__(self): super(LMyKnob, self).__init__() self.pvName = 'TEST:AO' self.start = -10.0 self.stop = 10.0 self.mode = 'Absolute' self._orderedAttributes = 'pvName', 'start', 'stop', 'mode' self._pv = None self._setpoints = np.empty(0, dtype = 'float') self._setpointAtInit = None @LInAndOut(DEBUG & ITEMS) def connectPv(self): self._pv = LEpicsPv(self.pvName) self._setpointAtInit = self._pv.caget() @LInAndOut(DEBUG & ITEMS) def setSetpoints(self, nparray): if nparray.max() > self._pv.drvh : raise Exception("%s: Cannot go over the DRVH limit (%.2f)" % (self.pvName,self._pv.drvh), "Lower max of desired range (%.2f)" % array.max()) if nparray.min() < self._pv.drvl : raise Exception("%s: Cannot go under the DRVL limit (%.2f)" % (pv.name,pvdrvl), "Increase min of desired range (%.2f)" % setpoints.min) self._setpoints = nparray @LInAndOut(DEBUG & ITEMS) def getSetpoints(self): return self._setpoints setpoints = property(getSetpoints, setSetpoints) @LInAndOut(DEBUG & ITEMS) def set(self, setpoint, wait = True): self._pv.caput(setpoint, wait = wait) @LInAndOut(DEBUG & ITEMS) def restore(self, wait = True): self.set(self._setpointAtInit, wait = wait)
def start(self): self.emit_started() exception = None try: iterationNumber = 0 numberOfIterations = self.dataContainer.numberOfIterations numberOfSamplesPerIteration = self.dataContainer.numberOfSamplesPerIteration numberOfPreviousSamples = self.dataContainer.numberOfPreviousSamples samplingRate = self.dataContainer.samplingRate operation = self.dataContainer.operation gain = self.dataContainer.gain holdValue = self.dataContainer.holdValue lowerActionLimit = self.dataContainer.lowerActionLimit upperActionLimit = self.dataContainer.upperActionLimit lowerChangeLimit = self.dataContainer.lowerChangeLimit upperChangeLimit = self.dataContainer.upperChangeLimit pauseBetweenIterations = self.dataContainer.pauseBetweenIterations dryRun = self.dataContainer.dryRun conditions = self.dataContainer.conditions runControl = self.dataContainer.runControl # Connect Pvs _actuatorPv = LEpicsPv(self.dataContainer.actuatorPvName) _readbackPv = LEpicsPv(self.dataContainer.readbackPvName) _offsetPv = LEpicsPv(self.dataContainer.offsetPvName) time.sleep(1) if _actuatorPv.isConnected(): verbose(self, "Connected to %s" % _actuatorPv.name) else: raise Exception("Could NOT connect to Actuator Pv (%s)" % _actuatorPv.name,'PV not on network') if _readbackPv.isConnected(): verbose(self, "Connected to %s" % _readbackPv.name) else: raise Exception("Could NOT connect to Readback Pv (%s)" % _readbackPv.name, 'PV not on network') if _offsetPv.isConnected(): verbose(self, "Connected to %s" % _offsetPv.name) else: raise Exception("Could NOT connect to Readback Pv (%s)" % _offsetPv.name, 'PV not on network') for condition in conditions : condition.connectPv() # Get fifo sampleFifo = LFifoStack() sampleFifo.size = numberOfSamplesPerIteration + numberOfPreviousSamples while (self.processIsRunning and iterationNumber < numberOfIterations): if (not self.processIsPaused) : try: timestamp = time.asctime(time.localtime()) verbose(self, "+----------------------------------------------------------------------") verbose(self, "| Iteration : %d / %d " % (iterationNumber, numberOfIterations)) verbose(self, "| Time : %s" % timestamp , 2) verbose(self, "| hostname : %s" % socket.gethostname(), 2) verbose(self, "| processId : %d" % self.pid, 2) verbose(self, "+----------------------------------------------------------------------") self.emit_ping() #--- Acquire samples newSamples = list() newSamples.append(_readbackPv.caget()) while len(newSamples) < numberOfSamplesPerIteration: time.sleep(1/samplingRate) newSamples.append(_readbackPv.caget()) sampleFifo += newSamples #--- Extract golden sample if operation == 'Average' : goldenSample = sampleFifo.getAverage() elif operation == 'Minimum' : goldenSample = sampleFifo.getMinimum() elif operation == 'Maximum' : goldenSample = sampleFifo.getMaximum() else: raise Exception('Unknown operation %s' % operation,'Not a valid operation') verbose(self, "%s" % sampleFifo, 2) verbose(self, "goldenSample = %f" % goldenSample) #--- Compute action (delta) delta = holdValue - goldenSample verbose(self, "delta = %f" % delta) if abs(delta) > upperChangeLimit: if delta >= 0 : delta = upperChangeLimit else: delta = -1 * upperChangeLimit verbose(self, "delta = %f (after upperChangeLimit)" % delta) verbose(self, "") verbose(self, "changeLimits: %f < abs(%f) < %f ?" % ( lowerChangeLimit, delta , upperChangeLimit)) action = gain * delta verbose(self, "holdValue = %f" % holdValue) verbose(self, "slope/gain = %f" % gain) verbose(self, "action = %f * ( %f - %f ) = %f" % ( gain, holdValue, goldenSample, action) ) verbose(self, "") verbose(self, "actionLimits: %f < abs(%f) < %f ?" % ( lowerActionLimit, action , upperActionLimit)) if abs(action) > upperActionLimit: if action >= 0 : action = upperActionLimit else: action = -1 * upperActionLimit verbose(self, "action = %f (after upperActionLimit)" % ( action )) #--- Compute new setpoint offset = _offsetPv.caget() newSetpoint = action + offset verbose(self, "offset = %f" % offset) verbose(self, "%f = %f + %f" % ( newSetpoint, action , offset)) verbose(self, "newSetpoint = %f" % ( newSetpoint)) #--- Check conditions for condition in conditions: verbose(self, "Checking %s..." % (condition),2) condition.check() verbose(self, "All conditions are meet. Continuing...") if dryRun: verbose(self, "%f --> %s (blocked by dryRun)" % ( newSetpoint, _actuatorPv.name )) verbose(self, "dryRun = %s" % dryRun) elif abs(action) <= lowerActionLimit: verbose(self, "%f --> %s (blocked by lowerActionLimit)" % ( newSetpoint, _actuatorPv.name )) verbose(self, "action = %f <= %f" % (action, lowerActionLimit)) elif abs(delta) <= lowerChangeLimit: verbose(self, "%f --> %s (blocked by lowerChangeLimit)" % ( newSetpoint, _actuatorPv.name )) verbose(self, "delta = %f <= %f" % (delta, lowerChangeLimit)) else: currentSetpoint = _actuatorPv.caget() verbose(self, "%s @ %f" % ( _actuatorPv.name, currentSetpoint)) if newSetpoint == currentSetpoint: verbose(self, "%f --> %s (No caput processing, same setpoint)" % (newSetpoint, _actuatorPv.name)) else: verbose(self, "%f --> %s" % ( newSetpoint, _actuatorPv.name )) _actuatorPv.caput(newSetpoint) except Exception as e: print e finally: iterationNumber += 1 time.sleep(pauseBetweenIterations) # processIsRunning = False or number of iterations was reached ! # Graceful shutdown self.emit_finished(0,0) except Exception as e: #Connection issue print e