bluesky / bluesky-enhancement-proposals

0 stars 4 forks source link

Submit telemetry proposal. #12

Open danielballan opened 5 years ago

danielballan commented 5 years ago

@awalter-bnl had already done significant work on this in an ophyd PR, but we decided to go back to the drawing board to ensure we are aligned on the overall design before we get into detailed code review.

danielballan commented 5 years ago

Notes from call with @awalter-bnl:

awalter-bnl commented 5 years ago

@danielballan I have committed the changes based on our conversation this morning, please check that these agree with your recollection.

danielballan commented 5 years ago

Good eye, @mrakitin. Fixed.

teddyrendahl commented 5 years ago

I would like to consider the design choice of adding this using a RunEngine.waiting_hook. It sees all the status objects already and is very easy to configure where as once this is baked into the base Status objects it will be very hard to turn off. No need to change anything in ophyd at all with this approach. The only issue with this is how to include the component names you need to capture as device metadata (settle time, e.t.c)

EDIT: My apologies accidentally clicked the close button!

danielballan commented 5 years ago

Interesting! Speaking for myself, that option had not occurred to me. Do you think it would make sense to encode the “brains” in a new method StatusObj.generate_telemetry() that does the extra get() calls and returns a dict but does not insert it anywhere? The waiting_hook can then be used to actually call generate_telemetry() and insert the dice into whatever persistent storage. If generate_telemetry() is not called, no extra work is done.

danielballan commented 5 years ago

This does seem like a marked improvement over the module-global registry currently in the proposal.

klauer commented 5 years ago

I'm 100% with @teddyrendahl on this one. Great idea!

As an aside, it's also interesting how a solution can be so obvious in retrospect - especially when you get lost in the details of a reasonable proposal.

Edit: @danielballan does it need to be a method generate_telemetry, or can it just be some optional Status attributes indicating "look at these attributes or components/keys for more information"?

danielballan commented 5 years ago

My initial thought is that the StatusObj and the device that instantiates it are the in best position to know the significance of the telemetry-related attributes—but I can’t yet think of a reason that this matters in practice. The upside of generating the record on the bluesky side, I appreciate, is that we can make any changes to the telemetry record scheme in just one place.

awalter-bnl commented 5 years ago

I also think this idea has merit, the only down-side I see is that we will only generate telemetry for motion done through bluesky, as opposed to say device.set(...). Not saying this is a show stopper but it is worth considering the impact that may/will have.

danielballan commented 5 years ago

To pose this another way:

If we add a generate_telemetry() method on the ophyd side, then the contract between ophyd and bluesky becomes, "Status objects [SHOULD|MAY] implement a method named generate_telemetry() that returns a dict satisfying [some schema]." If we push that work to bluesky, then the contract between ophyd and bluesky becomes, "Status objects [SHOULD|MAY] implement start_time, stop_time, telemetry_components."

I don't see a clear winner here; I'm just re-posing the question in a way that was clarifying for me.

teddyrendahl commented 5 years ago

I also think this idea has merit, the only down-side I see is that we will only generate telemetry for motion done through bluesky, as opposed to say device.set(...)

I think this is a very valid point. I do however kind of like the dichotomy of having some form of IPython magic / shortcut that does all the niceties of making CTRL+C work, progress bar, e.t.c and then having .set be purely for engineering usages. This seems to fit with the waiting_hook concept in my mind.

Do you think it would make sense to encode the “brains” in a new method StatusObj.generate_telemetry() that does the extra get() calls and returns a dict but does not insert it anywhere?

does it need to be a method generate_telemetry, or can it just be some optional Status attributes indicating "look at these attributes or components/keys for more information"?

I think I'm leaning towards Kens suggestion here, but I'm not entirely sold. What I would like to avoid if possible is having to make custom Status objects for each of my devices to put the "telemetry components" in. I'm also trying to fully separate what will go in "telemetry components" and what is already in Kind.config. I guess one is configuration for your data and one is configuration for your device, but I think a very good first pass at the telemetry could probably just grab the latter.

awalter-bnl commented 5 years ago

I do however kind of like the dichotomy of having some form of IPython magic / shortcut that does all the niceties of making CTRL+C work, progress bar, e.t.c and then having .set be purely for engineering usages. This seems to fit with the waiting_hook concept in my mind.

I agree with this statement, it means we would need to add this into ophyd somehow otherwise telemetry would only be available when using ophyd and bluesky in tandem, but perhaps that is a good carrot to encourage adoption of both.

What I would like to avoid if possible is having to make custom Status objects for each of my devices to put the "telemetry components" in.

@teddyrendahl I am assuming by 'telemetry_components' you mean device_components, as opposed to status_attributes as defined in the telemetry.md file presented in this PR? (just asking to make sure we are all talking about the same thing). This point was discussed earlier and I share your concern, as a solution to this issue I was a fan of having device_components be an attribute on the device, not the Status objects, with a better name of course (perhaps @teddyrendahl's telemetry_components?) In the current proposal the status object could then access this by status_object.device.device_components. This would then limit the number of status object variants required for telemetry to two,

  1. positioner type status objects which include 'start_pos' and 'stop_pos'
  2. all others that don't have a 'start' and 'stop' position.

We could also remove any variation at all by including status_object.start_pos/ status_object.stop_pos if they exists but not if they don't.

I'm also trying to fully separate what will go in "telemetry components" and what is already in Kind.config.

I see these as fairly different. In my mind, and based on the use cases I have seen:

We have had several beamline staff indicate that the number of items in a devices default kind.config list is to much, and it is therefore hard to go through the meta-data afterwards and find the useful values. They have then reduced the amount of config attrs to only include those they think are useful to record in metadata. I would therefore be against using kind.config attributes as the starting point for a list of 'telemetry' attributes, I am not against creating another 'kind' or including the device_components as a list attribute on a device.

klauer commented 5 years ago

I agree with this statement, it means we would need to add this into ophyd somehow otherwise telemetry would only be available when using ophyd and bluesky in tandem, but perhaps that is a good carrot to encourage adoption of both.

Yeah, this isn't as much of an issue going forward since we're intending to have a bluesky dependency in ophyd. Ceding more control flow to bluesky will also mean we can leverage more bluesky features, including the proposed telemetry.

I think we might want an additional per-Component flag that indicates various things, as the proliferation of boolean attributes can get annoying:

class InternalComponentFlag(enum.Flag):
    use_for_telemetry = enum.auto()
    is_leaf_node = enum.auto()  # from an unrelated discussion with @tacaswell 
    ...
danielballan commented 5 years ago

Summary of today's discussion the call:

danielballan commented 4 years ago

@dmgav is taking up this work again. Once he has a working prototype, it would be good to check in again with the participants in this design discussion.

Notes from a phone conversation between @dmgav and me: