def set(self, position, *, wait=False, timeout=None, settle_time=None, moved_cb=None): # In case nothing needs to be moved, just create a finished status status = Status() status.set_finished() # Mono if abs(self.get()-position) > mono.energy.tolerance.get(): mono_status = mono.energy.set( position, wait=wait, timeout=timeout, moved_cb=moved_cb ) status = AndStatus(status, mono_status) # Phase retarders for pr in [pr1, pr2, pr3]: if pr.tracking.get(): pr_status = pr.energy.move( position, wait=wait, timeout=timeout, moved_cb=moved_cb ) status = AndStatus(status, pr_status) # Undulator if undulator.downstream.tracking.get(): und_pos = position + undulator.downstream.energy.offset.get() und_status = undulator.downstream.energy.move( und_pos, wait=wait, timeout=timeout, moved_cb=moved_cb ) status = AndStatus(status, und_status) if wait: status_wait(status) return status
def remove(self, size=None, wait=False, timeout=None, **kwargs): """ Open the slits to unblock the beam. Parameters ---------- size : float, optional Open the slits to a specific size. Defaults to `.nominal_aperture`. wait : bool, optional Wait for the status object to complete the move before returning. timeout : float, optional Maximum time to wait for the motion. If `None`, the default timeout for this positioner is used. Returns ------- Status `~ophyd.Status` object based on move completion. See Also -------- :meth:`Slits.move` """ # Use nominal_aperture by default size = size or self.nominal_aperture if size > min(self.current_aperture): return self.move(size, wait=wait, timeout=timeout, **kwargs) else: status = Status() status.set_finished() return status
def trigger(self): print("trigger!") self.next_state, self.terminal, self.reward = self.cartpole_env.execute( actions=self.action.get()) status = Status() status.set_finished() return status
def set(self, value): status = Status(obj=self, timeout=5) self.mmc.setPosition(float(value)) self.mmc.waitForDevice(self.mmc_device_name) self.position = self.mmc.getPosition() status.set_finished() return status
def test_logger_adapter_status(): log_buffer = io.StringIO() log_stream = logging.StreamHandler(stream=log_buffer) log_stream.setFormatter(log.LogFormatter()) log.logger.addHandler(log_stream) status = Status() status.log.info("here is some info") assert log_buffer.getvalue().endswith( f"[{str(status)}] here is some info\n") status.set_finished() status.log.info("here is more info") assert log_buffer.getvalue().endswith( f"[{str(status)}] here is more info\n")
def _get_end_status(self): """ Return a `Status` object that will be marked done when the DAQ has finished acquiring. This will be marked as done immediately if the daq is configured to run forever, because waiting for the end doesn't make sense in this case. Returns ------- end_status: `Status` """ logger.debug('Daq._get_end_status()') events = self._events duration = self._duration if events or duration: logger.debug('Getting end status for events=%s, duration=%s', events, duration) def finish_thread(control, status): try: logger.debug('Daq.control.end()') control.end() except RuntimeError: pass # This means we aren't running, so no need to wait self._last_stop = time.time() self._reset_begin() status.set_finished() logger.debug('Marked acquisition as complete') end_status = Status(obj=self) watcher = threading.Thread(target=finish_thread, args=(self._control, end_status)) watcher.start() return end_status else: # Configured to run forever, say we're done so we can wait for just # the other things in the scan logger.debug( 'Returning finished status for infinite run with ' 'events=%s, duration=%s', events, duration) status = Status(obj=self) status.set_finished() return status
def trigger(self): """ Called during a bluesky scan to clear the accumulated pyami data. This must be done because the pyami.Entry objects continually accumulate data forever. You can stop it by deleting the objects as in `unstage`, and you can clear it here to at least start from a clean slate. If min_duration is zero, this will return a status already marked done and successful. Otherwise, this will return a status that will be marked done after min_duration seconds. If there is a normalization detector in use and it has not been staged, it will be staged during the first trigger in a scan. """ if self._entry is None: raise RuntimeError('AmiDet %s(%s) was never staged!', self.name, self.prefix) if self._monitor is not None and self._monitor is not self: if self._monitor._staged != Staged.yes: self._monitor.unstage() self._monitor.stage() monitor_status = self._monitor.trigger() else: monitor_status = None self._entry.clear() if self.min_duration: def inner(duration, status): time.sleep(duration) status.set_finished() status = Status(obj=self) Thread(target=inner, args=(self.min_duration, status)).start() else: status = Status(obj=self) status.set_finished() if monitor_status is None: return status else: return status & monitor_status
def set(self, value): """Set value of signal. Sets value of redis key to the serialized dictionary of value and timestamp. Returns ------- st : Status The status object is set to finished on successful write to redis, or an exception is set if redis.ConnectionError is raised. """ st = Status(self) try: server_time = self._r.time() ts = server_time[0] + server_time[1] / 1000000 self._r.set( self._key, self._serializer({ "value": value, "timestamp": ts }), ) except redis.ConnectionError as e: st.set_exception(e) st.set_finished() return st
def trigger(self): """ Perform one training step: - read the next agent action from the self.action signal - execute that action in the cartpole environment - record the new state of the environment - record the agent's reward - record whether the cartpole episode has terminated - if the game has terminated reset the cartpole environment Returns ------- action_status: Status a status object in the `finished` state """ _next_state, _terminal, _reward = self.cartpole_env.execute( actions=self.action.get()) self.next_state.put(_next_state) self.terminal.put(_terminal) self.reward.put(_reward) # self.cartpole_env indicates two different terminal conditions: # terminal==1 -- the pole fell over # terminal==2 -- the maximum number of timesteps have been taken if self.terminal.get() > 0: # the game has ended, so reset the environment self.state_after_reset.put(self.cartpole_env.reset()) else: # the game is not over yet, so self.state_after_reset has no information self.state_after_reset.put( np.asarray([math.nan, math.nan, math.nan, math.nan])) action_status = Status() action_status.set_finished() return action_status
class Counter: def __init__(self, client, name="SPEC", visualize_counters=[]): """ Create a bluesky combatible detector from SPEC counters Parameters: client: An instance of the Client class name (string): Name to be used in bluesky visualize_counters (list): List of counter names to use for best-effort visualization """ if not isinstance(client, SPECClient): raise ValueError("client needs to be instance of Client") self.client = client self.name = name self.hints = {'fields': visualize_counters} self.parent = None self.data = OrderedDict() self.duration = 1 def read(self): return self.data def describe(self): out = OrderedDict() for mne in self.data.keys(): out[mne] = { 'source': "scaler/{}/value".format(mne), 'dtype': 'number', 'shape': [], 'name': self.client.counter_names[mne] } return out def _data_callback(self, rdata): self.data = OrderedDict() for key, value in rdata.items(): self.data[key] = {'value': value, 'timestamp': tm.time()} def trigger(self): self.status = Status() def run_count(): self.client.count(self.duration, callback=self._data_callback) self.status.set_finished() threading.Thread(target=run_count).start() return self.status def read_configuration(self): return OrderedDict([('duration', { 'value': self.duration, 'timestamp': tm.time() })]) def describe_configuration(self): return OrderedDict([('duration', { 'source': "User defined", 'dtype': 'number', 'shape': [] })]) def configure(self, duration: float): """ Configure the time (in seconds) to count Parameters: duration (float): Number of seconds to count """ old = self.read_configuration() self.duration = duration return (old, self.read_configuration())
class UndulatorEnergy(PVPositioner): """ Undulator energy positioner. Always move the undulator to final position from the high to low energy direction, by applying a backlash (hysteresis) correction as needed. """ # Position readback = Component(EpicsSignalRO, 'Energy', kind='hinted', auto_monitor=True) setpoint = Component(EpicsSignal, 'EnergySet', put_complete=True, auto_monitor=True, kind='normal') # Configuration deadband = Component(Signal, value=0.002, kind='config') backlash = Component(Signal, value=0.25, kind='config') offset = Component(Signal, value=0, kind='config') # Buttons actuate = Component(EpicsSignal, "Start.VAL", kind='omitted', put_complete=True) actuate_value = 3 stop_signal = Component(EpicsSignal, "Stop.VAL", kind='omitted') stop_value = 1 # TODO: Does this work!?!? # done = Component(DoneSignal, value=0, kind='omitted') # done_value = 1 done = Component(EpicsSignal, "Busy.VAL", kind="omitted") done_value = 0 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.tolerance = 0.002 self.readback.subscribe(self.done.get) self.setpoint.subscribe(self.done.get) self._status_obj = Status(self) # Make the default alias for the readback the name of the # positioner itself as in EpicsMotor. self.readback.name = self.name @deadband.sub_value def _change_tolerance(self, value=None, **kwargs): if value: self.tolerance = value # TODO: This is unnecessary if use done EpicsSignal. # @done.sub_value # def _move_changed(self, **kwargs): # super()._move_changed(**kwargs) def move(self, position, wait=True, **kwargs): """ Moves the undulator energy. Currently, the backlash has to be handled within Bluesky. The actual motion is done by `self._move` using threading. kwargs are passed to PVPositioner.move(). Parameters ---------- position : float Position to move to wait : boolean, optional Flag to block the execution until motion is completed. Returns ------- status : Status """ self._status_obj = Status(self) # If position is in the the deadband -> do nothing. if abs(position - self.readback.get()) <= self.tolerance: self._status_obj.set_finished() # Otherwise -> let's move! else: thread = Thread(target=self._move, args=(position, ), kwargs=kwargs) thread.start() if wait: status_wait(self._status_obj) return self._status_obj def _move(self, position, **kwargs): """ Moves undulator. This is meant to run using threading, so the move will block by construction. """ # Applies backlash if needed. if position > self.readback.get(): self._move_and_wait(position + self.backlash.get(), **kwargs) # Check if stop was requested during first part of the motion. if not self._status_obj.done: self._move_and_wait(position, **kwargs) self._finish_status() def _move_and_wait(self, position, **kwargs): status = super().move(position, wait=False, **kwargs) status_wait(status) def _finish_status(self): try: self._status_obj.set_finished() except InvalidState: pass def stop(self, *, success=False): super().stop(success=success) self._finish_status()
def trigger(self): status = Status(obj=self, timeout=5) # status.add_callback(self.callback) self.mmc.waitForDevice(self.mmc_device_name) status.set_finished() return status
def trigger(self): status = Status(obj=self, timeout=5) status.set_finished() return status
def trigger(self): status = Status() status.set_finished() return status