Giter Club home page Giter Club logo

ophyd's Introduction

Ophyd

Build Status Test Coverage Latest PyPI version BSD 3-Clause License

Ophyd is a Python library for interfacing with hardware. It provides an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control systems.

Ophyd is typically used with the Bluesky Run Engine for experiment orchestration and data acquisition. It is also sometimes used in a stand-alone fashion.

Many facilities use ophyd to integrate with control systems that use EPICS , but ophyd's design and some of its objects are also used to integrate with other control systems.

  • Put the details specific to a device or control system behind a high-level interface with methods like trigger(), read(), and set(...).
  • Group individual control channels (such as EPICS V3 PVs) into logical "Devices" to be configured and used as units with internal coordination.
  • Assign readings with names meaningful for data analysis that will propagate into metadata.
  • Categorize readings by "kind" (primary reading, configuration, engineering/debugging) which can be read selectively.
PyPI pip install ophyd
Conda conda install -c conda-forge ophyd
Source code https://github.com/bluesky/ophyd
Documentation https://blueskyproject.io/ophyd

See the tutorials for usage examples.

See https://blueskyproject.io/ophyd for more detailed documentation.

ophyd's People

Contributors

abbygi avatar ajgdls avatar awalter-bnl avatar bsobhani avatar callumforrester avatar coretl avatar danielballan avatar dchabot avatar dmgav avatar dominicoram avatar ericdill avatar gjwillms avatar gwbischof avatar hhslepicka avatar jklynch avatar jrmlhermitte avatar jwlodek avatar klauer avatar mikehart85 avatar mrakitin avatar padraic-shafer avatar prjemian avatar ronpandolfi avatar rosesyrett avatar stuartcampbell avatar stuwilkins avatar tacaswell avatar tangkong avatar tizayi avatar zllentz avatar

Stargazers

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

Watchers

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

ophyd's Issues

Bug in ophyd mesh scan

Command + stack trace:

In [17]: dscan([[theta], [delta]], [[-.1], [-.1]], [[.1], [.1]], [2, 4])
  File "build/bdist.linux-x86_64/egg/ophyd/userapi/scan_api.py", line 285, in run
    self.check_paths()
  File "build/bdist.linux-x86_64/egg/ophyd/userapi/scan_api.py", line 196, in check_paths
    pos.name, p.low_limit, p.high_limit))


Moving positioners back to start positions....... Done.
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-17-8c61004e6277> in <module>()
----> 1 dscan([[theta], [delta]], [[-.1], [-.1]], [[.1], [.1]], [2, 4])

/home/xf23id1/anaconda/envs/ophyd/lib/python2.7/site-packages/ophyd-0.0.2-py2.7.egg/ophyd/userapi/scan_api.pyc in __call__(self, positioners, start, stop, npts, **kwargs)
    535         """
    536         self.setup_scan(positioners, start, stop, npts, **kwargs)
--> 537         self.run(**kwargs)
    538 
    539     def setup_scan(self, positioners, start, stop, npts, **kwargs):

/home/xf23id1/anaconda/envs/ophyd/lib/python2.7/site-packages/ophyd-0.0.2-py2.7.egg/ophyd/userapi/scan_api.pyc in run(self, **kwargs)
    283 
    284         with self:
--> 285             self.check_paths()
    286             self.setup_detectors(self.detectors)
    287             self.setup_triggers(self.triggers)

/home/xf23id1/anaconda/envs/ophyd/lib/python2.7/site-packages/ophyd-0.0.2-py2.7.egg/ophyd/userapi/scan_api.pyc in check_paths(self)
    194                     raise ValueError('Scan moves positioner {} \
    195                                      out of limits {},{}'.format(
--> 196                                      pos.name, p.low_limit, p.high_limit))
    197 
    198     def __enter__(self):

AttributeError: 'numpy.float64' object has no attribute 'low_limit'

Potential key to start storing with user scans

It would be useful to start storing the data values that should be used to normalize detector columns during the ophyd scan. Something like normalize would work. I would assume that, for beamlines who need detector normalization, this should probably start getting dumped into the events automatically?

Scan.detectors is not what a naive user thinks it is

I think that there's a semantic problem with the detectors property in that it is intrinsically read-only. A user will be likely to attempt to add a new detector with, e.g., Count.detectors.append([my_detector]), rather than adding it to the user_detectors list. I offer up a few possible changes (in order of reversed personal preference):

  1. move this property name to _detectors so that a user has some warning that you don't intend to have this changed outside of the class methods,
  2. provide a setter that raises "AttributeError", indicating that appending to this list is not supported, or
  3. provide a setter that transparently adds the provided detector list to the user_detectors list.

Add diagnostic dump function

Dump all configuration in painful detail to the screen. The main purpose of this is for bug reporting/post mortem. I am thinking wh_pos + PV mapping would be enough.

BUG: investigate non-blocking Positioner moves incorrectly reporting 'in-motion' status

Non-blocking moves of Positioners (EpicsMotors, in particular) incorrectly report status as 'not-moving' immediately after the move is initiated.

Test (using sim motor m1):
m1.move(5, wait=False)
print m1.moving # prints false

Contributions to this problem include network (CA) delays, threading delays (context switching to CA monitor-handler thread), and EPICS device support reporting delays (i.e. poll rate of motor controller).

Timestamps, Processing and areaDetector

Ok, putting this as an issue so that we can discuss look at it. Attn. @dchabot @gjwillms @tacaswell .

After some discussion with Mark Rivers and playing with the AD Driver for the FastCCD I have managed to work out the issue with timestamps, and blocking. So, Firstly if you need to use the stats plugins (for example) you need to set them to blocking $(P)$(R)BlockingCallbacks. This will ensure that the put complete doesn't come back until the stats have processed.

Now in areaDetector 2.0 there is support for the epics records having the detector timestamp by setting the "TSE" field of those records. I tested this with the fastCCD (I take the timestamp of the first packet arriving at the detector electronics) and it looks good, even at 100Hz. Also all stats plugins have the same timestamp.

Also, the new HDF5 file plugin stores this info (timestamps) in the HDF5 file.

The info is here:

areaDetector timestamps

ENH: Triggering of detector classes.

Hi, @dchabot, @klauer,

I have been looking at 2 issues. 1 Time-stamping of data and secondly triggering detectors. Currently in the run_engine it is only possible to trigger a single EpicsSignal (it uses the put method). This doesn't allow the nice new detector classes to be used such as EpicsScaler or the area detector zoo.

I wonder if it is time to start thinking about adding a trigger() method to these type of detectors which could be called by the run_engine. I would also suggest at this time having a trigger_timestamp property which is the timestamp of the trigger. Even EpicsSignals could have this which would just do a self.put(1). Thoughts?

I am also starting to think about timestamps. It appears that we have 2 different type of detectors. Those that require triggering and have been done so in a step scan. We also have things that get added to the run which are asynchronous. It would appear that we need to distinguish between these two. I think that an event should always have a timestamp and contain only data which was at that timestamp, with the caveat that software triggers still group them together in one event descriptor.

I would propose the following:

We have 3 types of event:

  1. In a step scan there is always a trigger event, taken from the system clock which is executed just before ophyd starts triggering and at the end of reading detectors. This event would look like:
trigger {
    start : (float of start from time.time())
    stop : (float of stop)
}

This is useful in data collection because it is the execution window of the step scan.

For detectors that are triggered, they are grouped into a single event descriptor which would look like:

detector_group_1 {
    pos1 : (value of motor)
    sclr_1 : (scalar channel 1)
    ...
    timestamp : (earliest trigger value)
}

The timestamp would be taken from the minimum value of the trigger timestamps (there is no good way to do this.

Lastly, EpicsSignals which are not triggered are recorded as separate events with there own timestamp:

temp_a {
    temp_a : (value)
    timestamp : (earliest trigger value)
}

I think this could be achieved with a little config. This pushes some work onto the data side but provides the truest representation of what actually happened without having each detector have a single event. I don't know if @tacaswell, @ericdill or @danielballan think this is what we discussed at length yesterday.

Also, this could be configurable, with the option to just record each detector as its own event as an advanced option.

While this may not be the long term goal of the run_engine. I wonder if this could be tested (I would be happy to implement a test branch) so that we can see how this runs and what the pitfalls on the data collection side are. Thoughts?

ENH: flesh out cli_api for motion

Add procedural api for motion, including:

def mov(positioner, position)
''' Blocking, absolute move with position reporting while in progress. '''

def movr(positioner, delta)
''' Blocking, relative move with position reporting while in progress. '''

def set_limits(positioner, plim, mlim)
''' Set +ve/-ve soft-limits on a EpicsMotor object (using caput, etc?). '''

def set_position(positioner, position, offset=None)
''' Adjust EpicsMotor position (so-called User position). '''

etc, etc

BUG: order of operations in DScan.

DScan.pre_scan( ) method adds the relative positions to the absolute positions after Scan.check_paths( ) is called. Thus, check_paths( ) is actually trying to verify if the deltas are within the (low_limit, high_limit) of a Positioner.

Clear as mud...?

Demonstrated (safely!!!) at xf23id1 with:

 dscan(pgm_energy, -15, 30, 40)

Sort out scan_ids

The mechanism for producing scan_ids needs to be investigated. As of now, the scan_id seems to reset to an old number on CSX. The behavior should be that the scan_id defaults to something like

   session_manager.scan_id = int(DataBroker[-1].scan_id) + 1

On ophyd startup go grab the last scan_id from DataBroker. This scan_id can be overridden by the user at run time.

Reported by Claudio at CSX

Use weak references in session manager

I think our objects should be only held in the session manager as weak references, otherwise we're holding onto objects that should be garbage collected.

For example, if you create a temporary EpicsSignal() while in a function, the signal will be registered with the session and then consequently never deleted (even after leaving the scope of the function).

ENH: Positioners need a concept of limits

I suggest that all positioners have the concept of limit. This could be the limits of a Motor Record or the DRVH/DRVL fields of an ao for example. Then when setting the tradj. this should raise an exception that we can catch in the scanning API. This stops starting a scan which will go outside positioner limits.

Personally, i would prefer doing this in the positioner and throwing an exception than checking in the scan. This way we can catch it on moves etc. also.

Thoughts?

S

BUG : Debug using print must go away

Looking through the current master branch there is a lot of debug using print() I think this should all be removed. We should use either the logging (after all that is what it is for!) or when a PR is created to master this should be stripped.

Beamline control philosophy, ipython, and ophyd

@stuwilkins @dchabot @klauer
Gentlemen, I find myself in the midst of an existential crisis. Normally, this would not affect you--unless you were unfortunate enough to find yourselves in my immediate vicinity; however, I was, rather unfortunately, thinking about ophyd during its onset. As a result. I have a design question.

I believe that there is merit in considering beam line control the problem of interfacing a small number of discrete systems: e.g., the white beam slit, the horizontal offset mirror, the monochrometer. These are, of course, comprised of many individual axes of control, but I believe that we do ourselves a disservice by attempting to control the beam line this way; doing so is micromanagement of the worst sort. Said differently, we seem to be building, in ophyd, a rigidly functional approach to control on top of a flamboyantly object-oriented environment.

As an example, suppose I wish to know the horizontal position and size of a slit. In ophyd, I could accomplish this with "wh_pos([slt_pb_hcen,slt_pb_hsize])." Would it not be better to encapsulate these properties of a slit in the object, calling them forth as "slt_pb.hpos.wh()"?

Opinions?

Compare results from ophyd and qxrd

Refer to:

Scan ID : 126

Detector | Value

em_ch1 [ 0.00915527]
em_ch2 [ 0.00944138]
em_ch3 [ 0.01058578]
em_ch4 [ 0.01058578]
pe1_acquire_period [ 5.]
pe1_acquire_time [ 0.2]
pe1_image_lightfield ['c9281f96-091c-4122-8860-d5af4a2ac887']
shctl1 [ 1.]

Scalar data has wrong shape

Reminder that scalar data from SRX was coming in with the shape [2] where it should be None. I have not looked into why that is happening yet.

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.