Coder Social home page Coder Social logo

pcdsdevices's Introduction

PCDS Devices

Collection of Ophyd Device subclasses for IOCs unique to PCDS

Motivation โ€ข Installation

Motivation

Ophyd presents a uniform set of abstractions for EPICS devices. Many devices at the LCLS are covered by ophyd-provided classes such as EpicsMotor and AreaDetector, but there are also many more custom and unique devices.

This repository:

  • Defines unique device classes required by the LCLS, referenced by happi and our device_config database.
  • Offers LCLS-tailored solutions for functionality not provided by ophyd
  • Provides essential tools to aid in the creation of new devices for specific applications
  • Acts as a proving ground for features that may eventually be destined for ophyd
  • ... and more!

Much of the core re-used functionality can be found in pcdsdevices.device, pcdsdevices.interface, pcdsdevices.pseudopos, and pcdsdevices.signal.

Installation

Install the most recent tagged build:

$ conda install -c conda-forge pcdsdevices

Install the most recent development build:

$ conda install pcdsdevices -c pcds-dev -c lightsource2-tag -c conda-forge

Or alternatively:

# Install the tagged version for the dependencies
$ conda install -c conda-forge pcdsdevices

# Clone the master branch:
$ git clone https://github.com/pcdshub/pcdsdevices
$ cd pcdsdevices

# And perform a development install:
$ python -m pip install -e .

Testing

Testing from psbuild-rhel7

Use the pcds conda environment:

$ source /cds/group/pcds/pyps/conda/pcds_conda

Testing without PCDS servers

Ensure you have all of the development requirements available:

$ pip install -r dev-requirements.txt

General testing steps

$ git clone https://github.com/pcdshub/pcdsdevices
$ cd pcdsdevices

# Switch to a branch that reflects what you're working on:
$ git checkout -b my_feature_branch_name

# Make your changes to files
# Install pre-commit to allow for style checks before committing
$ pre-commit install

# Run the test suite
$ python run_tests.py -v

If all is well, commit and push your changes.

If pre-commit complains about an issue, you will need to resolve it and try again.

$ git commit -a -m "ENH: my new feature"
$ git remote add my_remote [email protected]:my_username/pcdsdevices
$ git push -u my_remote my_feature_branch_name

pcdsdevices's People

Contributors

aberges-slac avatar aegger13 avatar apra93 avatar baljamal avatar canismarko avatar cristinasewell avatar ghalym avatar hhslepicka avatar jozamudi avatar kaushikmalapati avatar klauer avatar matthooverslac avatar mbosum avatar mkestra avatar n-wbrown avatar nrwslac avatar rajanplumley avatar rsmm97 avatar sainyamn avatar sfsyunus avatar slacadpai avatar slactjohnson avatar spenc333 avatar tangkong avatar tongju12 avatar vespos avatar wnwright avatar yashrao99 avatar zllentz avatar zrylettc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pcdsdevices's Issues

State Cleanup

Expected Behavior

Re-examine how we are doing the StatesRecord class. This would be cleaner as a class that we inherit rather than a subcomponent. We should also see how we can generalize this further as to not be require as much re-writing for each specific device class.

MPS Limit Switches

Certain devices have an MPS bit associated with two limit switches. This should be added to the MPS model.

Unstage Should Report Failures

Calls to unstage methods that don't wait for completion should report failures to logger.info or higher (warning, error, critical), depending on the severity. This can also be done in a lower level function if appropriate, but it must happen on unstage so we can be sure the beamline has been reset after a scan.

IPM State Names

Expected Behavior

The IPM class does not work with the default IOC configuration. The class assumes that the state names are T* while the PVs are TARGET*.

Current Behavior

Assumes PV names are T*

Possible Solution

  1. Have a kwarg to pass in the state prefix i.e TARGET*, T*
  2. Set it to the default TARGET and have XPP have a special class

Create base LightDevice

There should be a base light device that attempts to implement the necessary subscriptions for the lightpath.

ENH: Subscription Handling

Many of the devices subscribe to child EpicsSignals to form higher level subscription events. i.e if an attenuator blade is moved, the Attenuator object triggers their own subscriptions that alert users that any blade has moved.

These child subscriptions should only be made if the parent device has a relevant higher level subscription to prevent unnecessary traffic through pyepics

Status Displays

Expected Behavior

Statuses should be displayed nicely for user methods, but hidden for built-in bluesky methods

Tab Completion gets signals

Tab completing in IPython calls caget on signals and subcomponents. This is undesirable as timeouts and incorrectly configured PVs destroy this ...

Device Cleanup

  1. EVERY device should have hints, _default_read_attrs and _default_configuration_attrs. These should use the class default variables like so:
class MyDevice(ophyd.Device):
          _default_read_attrs = ['my_read']
          _default_configuration_attrs = ['my_config']
  1. NO callbacks should make EPICS calls. They should instead use the information provided in the callback
  2. NO EPICS connections on initialization (no subscribing, no gets, no puts)
  3. NO overrides to base ophyd classes.
  4. EVERY device should adhere to http://nsls-ii.github.io/bluesky/hardware.html

EVR Configuration

Expected Behavior

Optional EVR device to be attached to relevant objects

Current Behavior

  • There is no EVR device
  • There are no optional components

Inspect plan and select daq mode in daq_wrapper

Expected Behavior

It may be possible to infer from a plan whether to run the daq in on, manual, or auto mode.

Possible Solution

from collections import defaultdict

def select_mode(messages):
    counts = defaultdict(lambda: 0)
    for msg in messages:
        counts[msg.cmd] += 1
    if counts['kickoff'] > 1:
        return 'manual'
    elif counts['read'] > 0:
        return 'auto'
    else:
        return 'on'

Occasional Timeout in Status wait

There is a race condition that pops up in the tests of StateStatus. This should just be removed as it largely just checks ophyd code anyways...

Deprecate Happi

Expected Behavior

There should be no explicit dependency on happi inside pcdsdevices . Happi loads devices with no explicit dependencies.

calib_at_step plan

Expected Behavior

Many of the bluesky built-ins have a per_step hook. We should implement a calib_at_step plan that encompasses the behavior that will be repeatedly needed for including the daq in one of these built-in plans.

Possible Solution

Excerpt from one of my test ipython sessions:

def per_step(detectors, motor, step):
    yield from one_1d_step(detectors, motor, step)
    yield from calib_cycle()

Optional / Multi Suffixed Signals

Instead of having seven classes to deal with slightly different PV implementations between IOCs. We could have both an optional signal. That indicates a signal that is nice to have but might not be in every implementation. This would essentially just catch DisconnectedError and send a nice traceback i.e

try:
      self.signal.get()
except DisconnectedError as exc:
       raise OptionalPVException("This method could not find optional signal {signal.name}") from exc

We can also just have more flexible signals if we expect the same behavior but a slight different in IOC implementation so we could just do:

xwidth = MultiComponent(EpicsSignalRO, ['XWIDTH', 'X_WIDTH'])

This would just check the signal at startup and try and select the correct API. Maybe even having something intelligent where if it finds the right signal in the list it makes assumptions about other MultiComponent

Device Representations

Expected Behavior

Investigate the best way to represent an overview of the device. This should use some combination of the ophyd.Device.summary. Maybe include in this in the built-in __repr__

Setup gh-pages for pcdsddevices

Expected Behavior

Now that we have a proxy rule for pcdshub.io sites and this repository is on pcdshub we should simply be able to create gh-pages site. This is is worth it as it simplifies the beast that is the skywalker-docs. Plus I feel like this repository deserves to stand on its own.

Multiple directories underneath tests

  • Level the tests directory. No separation of epics and sim. This confuses pytest greatly
  • Remove all tests that require EPICS PVs and place them in live_tests

Jupytr + Docs for DAQ How-to

Given a Daq instance and a simulated pydaq, show the user how to do:

  • basic daq configuration and control
  • include daq in the scan in on mode
  • per step calib cycles in manual mode
  • per step calib cycles in auto mode

Add a reconnect method to the daq class

Expected Behavior

You enter daq.reconnect() and it simply disconnects and reconnects.

Current Behavior

Not implemented

Context

Scientists manually disconnect() and connect() between everything they do (every scan attempt)

MFX, CXI lens stacks are special

This is a reminder to break these out into hutch-specific classes when we make the hutch repos. Suggested implementations:

# MFX DIA
# CXI DG2
class XFLS2(XFLS):
    """
    XRay Focusing Lens (Be)

    These are the stacks with common names on their states and state config PVs
    that show the focusing config
    """
    states_list = ['6K70', '7K50', '9K45', 'OUT']
    in_states = ['6K70', '7K50', '9K45']


# CXI DS1
class XFLS3(XFLS):
    """
    XRay Focusing Lens (Be)

    This is the stack in CXI with a screwed up IOC. The states list are
    numbered by lens, but the config PVs are all over the place.

    This currently behaves no differently than XFLS, but when we add in the
    state config these values will matter. I'm saving them here for later.
    """
    # Upper/lower case intentional
    _config_states = ['6K70', '7k45', '9k50']

Allow tests to run without bluesky

Expected Behavior

Tests should be skipped if bluesky is not installed

Current Behavior

Tries to import pcdsdevices.make_daq_engine which returns nothing (no exception). Then later in the test the function is referenced.

Possible Solution

Be more expansive with use of requires_bluesky decorator

Steps to Reproduce (for bugs)

  1. Uninstall bluesky
  2. Run tests

Context

Your Environment

PCDS Areadetector Setup

Expected Behavior

We should have a base AreaDetector implementation for the standard PCDS setup. This will replace all GigECam, edtCam setup scripts everywhere.

  • IMAGE1 -> Full Rate
  • IMAGE2 -> Low rate

Reformat Travis to build with Conda

Configure pcdsdevices to build and test with the recipe rather than using the requirements.txt file. This includes pushing the successful builds to pcds-tag and pcds-dev rather than the skywalker channels.

Progress Bars for DAQ Complete

Expected Behavior

Status object from daq.complete should provide an appropriate watch method for progress bar feedback

Possible Solution

For duration, we just measure start time and current time
For fixed events, we need to investigate pydaq.Control.eventnum() and pydaq.Control.l3eventnum()
We need to be able to tell which of the three we provided to pydaq.Control.begin

Named Preset Positions

Expected Behavior

  • All objects should be able to save named states that can be moved to
  • The states should be loaded automatically at the start of a session
  • Utility needs to be provided to move objects with the same state to the same state at the same time if grouped in a logical way
  • There is an expectation that these state names become dynamically configurable methods

Current Behavior

This feature was not implemented in Python 3 even though it gets heavy usage in the old hutch python libraries

Implementation Ideas

  • Perhaps something can be done to make States classes arbitrarily configurable on a axis

LODCMs in XPP and XCS have different foils

This is a reminder for later that these will need their own special classes in their respective hutch repos to handle the slight foil PV variations. Suggested implementation:

class FoilXPP(Foil):
    states_list = ['OUT', 'Mo', 'Zr', 'Zn', 'Cu', 'Ni', 'Fe', 'Ti']
    in_states = ['Mo', 'Zr', 'Zn', 'Cu', 'Ni', 'Fe', 'Ti']


class FoilXCS(Foil):
    states_list = ['OUT', 'Mo', 'Zr', 'Ge', 'Cu', 'Ni', 'Fe', 'Ti']
    in_states = ['Mo', 'Zr', 'Ge', 'Cu', 'Ni', 'Fe', 'Ti']

FEE Devices

Expected Behavior

Need to develop and test FEE versions for a number of devices; from my count we still need:

  • PneumaticPIM
  • GateValve
  • FeeSpectrometer

Current Behavior

There is currently not tested ways to control these devices

Possible Solution

Reimplement existing devices where possible. We can also investigate whether or not we spoof missing PVs, or even change IOC versions.

Context

Necessary for a complete lightpath

Your Environment

These should just be written with ophyd > v1.0.0

InOutPVPositioner Inheritance does produce valid `device_tuple`

Current Behavior

Currently when you create a InOutPVPositioner object and call .get() the command fails with an error message such as:

__new__() got an unexpected keyword argument 'your_signal'

On further investigation, the traceback reveals that this is raised while trying to create a self._device_tuple object. If you look at what this object actually is it looks like:

YourDeviceTuple(state, _1, _2, _3, _4)

I'm guessing the MRO of these class definitions does not produce a DeviceTuple that includes the signals attached by the child class. This causes an issue because when get tries to fill the tuple with component_names there are no spots in the tuple for all the components. It is worth noting that component_names contains all the signals, probably just not in time for the _device_tuple creation.

Your Environment

ophyd == v1.1.0

MPS Factory

Create a factory function that add the mps subcomponent to devices that need it.

XPP, XCS have need for CCM states

Another reminder to include this in the hutch-specific repos:

class CCMRecordPositioner(InOutRecordPositioner):
    """ 
    Version of InOut device that has distinct states for CCM and PINK
    """
    states_list = ['OUT', 'CCM', 'PINK']
    in_states = ['PINK', 'CCM']
    _states_alias = {'PINK': 'IN'}


class PulsePickerCCM(PulsePickerInOut):
    """ 
    PulsePicker paired with a states record to control the Y position and
    manage the differing elevations for running in CCM or PINK mode.
    """
    inout = FCmp(CCMRecordPositioner, '{self._inout}')

PIMMotor in 'unknown' mode registers as inserted

Expected Behavior

If the PIMMotor is unknown it should report neither inserted or removed.

Current Behavior

If PIMMotor is 'unknown' it registers as inserted.

Possible Solution

def inserted(self):
     return self.states.value in ('IN', 'DIODE')

CI: Missing Files in Codecov

daq.py, pim.py, and mirror.py are omitted from codecov. I think this is a bug in codecov, because they show up in coverage report -m in the travis build.

Curiously, these are the files with the same names as files in the sim folder.

FakeSignal Sleep

Remove mandatory sleep from FakeSignal. Makes pswalker tests take forever

Replace IocDevice with Factory Functions

Similar to mps device, this should change because it causes issues putting it everywhere. I plan to do a PR soon-ish that removed IocDevice everywhere, then another one way later that implements this as a factory function.

Cryptic Error Message in Daq class

Expected Behavior

If daq.connect() fails, it should always give a helpful error message.

Current Behavior

@apra93 observed the following response today:

In [12]: daq.connect()
pdsdaq_connect(): get dbpath len = 0

Possible Solution

Go to a hutch, find some common failure states (wrong platform, daq not allocated), see what the response is inside the code. Make sure we catch these and give proper error messages.

Steps to Reproduce (for bugs)

  1. create a Daq object with the wrong or right platform
  2. forget to allocate the daq
  3. try to connect

Context

This bug creates extra debugging time when something goes wrong in the setup of a Daq class.

Your Environment

pcds-0.5.2

MAINT: Status Cleanup

The generation of Status objects is kind of haphazard. It would be nice to generate these in a uniform way. This might require a PR to ophyd to reference device attributes.

PR: bluesky/ophyd#442

Extra Features in Daq Class

  • Expand collect to include metadata about the daq run (run number, events recorded, etc.)
  • Implement dynamic start and stop within a run in a natural way. The goal is to have the option for the daq to record events between 'trigger' and 'save' messages and not record at other times to avoid taking useless data.
  • Implement the legacy calib cycle feature that uses the pydaq controls argument

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.