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