Closed prjemian closed 3 years ago
tests with adrigaku.cam.summary()
and adrigaku.cam.describe_configuration()
:
Also, match fields on the screen above:
In [5]: adrigaku.cam.file_path.get()
Out[5]: 'RigakuEpics/'
In [6]: adrigaku.cam.file_name.get()
Out[6]: 'Test_01_000010.bin'
In [7]: adrigaku.cam.image_mode.get()
Out[7]: 5
In [8]: adrigaku.cam.image_mode.get(as_string=True)
Out[8]: '2 Bit, Zero-Deadtime'
In [9]: adrigaku.cam.trigger_mode.get()
Out[9]: 4
In [10]: adrigaku.cam.trigger_mode.get(as_string=True)
Out[10]: 'ZDT Fixed Time'
In [11]: adrigaku.cam.upper_threshold.get()
Out[11]: 10.0
In [12]: adrigaku.cam.lower_threshold.get()
Out[12]: 6.0
In [13]: adrigaku.cam.calibration_label.get()
Out[13]: 'STD'
What can ophyd tell us about the detector's asyn ports?
In [16]: adrigaku.get_asyn_port_dictionary()
Out[16]: {'TEST': RigakuUfxcDetectorCam(prefix='8idRigaku:cam1:', name='adrigaku_cam', parent='adrigaku', read_attrs=[], configuration_attrs=['acquire_period', 'acquire_time', 'image_mode', 'manufacturer', 'model', 'num_exposures', 'num_images', 'trigger_mode'])}
In [17]: adrigaku.get_asyn_digraph()
Out[17]:
(<networkx.classes.digraph.DiGraph at 0x7f835a3b9e20>,
{'TEST': RigakuUfxcDetectorCam(prefix='8idRigaku:cam1:', name='adrigaku_cam', parent='adrigaku', read_attrs=[], configuration_attrs=['acquire_period', 'acquire_time', 'image_mode', 'manufacturer', 'model', 'num_exposures', 'num_images', 'trigger_mode'])})
In [18]: adrigaku.visualize_asyn_digraph()
TEST
is the asyn port of the cam plugin. So far, it is not seeing the other ports in use (Sparse0 plugin and IMM plugin)
Once ADRigaku is moved to the Area Detector repository, we can push this support to ophyd. Until then, it is support specific to the APS.
Tested by counting using Bluesky standard count()
plan; it worked the first time! (Well, after we removed the suspenders.)
@keenanlang: Thanks!
@prjemian Attached please find portions of ad_rigaku_detector.py
I wrote. How do I run the staging to see if the PVs have been implemented ccorrectly?
In addition, I have a few questions:
adrigaku
has one PV that other standard area detectors don't have: the Correction
PV (See image attached). This PV is on when running at 50 kHz so that the files are saved in Rigaku's own binary format instead of going through the .imm EPICS plugin and saved into .imm. Could you teach me how to add this attribute to the Ophyd object?adrigaku
is missing Data Type
PV. If you could show me how to add that too that would be great;adrigaku
at slow mode.Thanks!
To check the staging of ophyd Device ad_rigaku
:
ad_rigaku.stage()
ad_rigaku.unstage()
The basic staging rules are:
.stage()
once (2nd time raises an exception).unstage()
as many times as you likeI just tried adrigaku.stage()
and the PVs in the EPICS window did not change. Upon inspection, I noticed that I used lots of yield from bps.mv
when adrigaku.stage()
is called without the Run Engine. Is that what has caused problems?
Also what should I do if I want to add a if command durinng the staging to toggle between fast and slow mode? Or do you think it's better to stage both fast and slow mode and make the selection in AD_Acquire
?
Thanks
That's for sure the problem. Fundamentally, staging works by ophyd processing the .stage_sigs
dictionary.
In [10]: adrigaku.stage_sigs
Out[10]: OrderedDict()
In [11]: adrigaku.cam.stage_sigs
Out[11]: OrderedDict()
Both dictionaries are empty right now. That's why nothing changed.
additional suggestions coming...
Your code to set staging for either fast or slow should not be written as a bluesky plan. Rather, it should be modifying the adrigaku.stage_sigs
dictionary.
change to this:
class RigakuUfxcDetector(DetectorBase):
_html_docs = ["RigakuUfxcDoc.html"]
cam = ADCpt(RigakuUfxcDetectorCam, "cam1:")
# TODO: other plugins: Sparse0, IMM
staging_mode = ADCpt(Signal, value="fast", kind="config")
def staging_setup_DM(self, *args, mode=None):
"""
setup the detector's stage_sigs for acquisition with the DM workflow
from DM_DeviceMixinAreaDetector
"""
# If staging stalls, it is because one or more of the signals
# is being set by its string value instead of the enumeration
# number. This happens with EpicsSignalWithRBV when it was
# called without the string=True kwarg.
# In [13]: adrigaku.cam.image_mode.get()
# Out[13]: 9
# In [14]: adrigaku.cam.image_mode.get(as_string=True)
# Out[14]: '16 Bit, 1S'
# The fix is to set by number, not string.
if (mode == 'fast'):
self.stage_sigs = {}
self.stage_sigs["cam.acquire_time"] = 20e-6
self.stage_sigs["cam.image_mode"] = 5
self.stage_sigs["cam.trigger_mode"] = 4
self.stage_sigs["cam.num_images"] = 100_000 # "_" is a visual separator
self.stage_sigs["cam.corrections"] = "Enabled"
self.stage_sigs["cam.data_type"] = "UInt32"
# TODO: what else is needed?
elif (mode == 'slow'): self.stage_sigs = {}
self.stage_sigs["cam.image_mode"] = 9 # "16 Bit, 1S"
self.stage_sigs["cam.trigger_mode"] = 0 # "Fixed Time"
self.stage_sigs["cam.acquire_time"] = 0.1
self.stage_sigs["cam.num_images"] = 10
self.stage_sigs["cam.data_type"] = "UInt16"
self.stage_sigs["cam.corrections"] = "Disabled"
# TODO: what else is needed?
# TODO: Need the equivalent of the lines below:
# epics_put("8idRigaku:IMM1:AutoIncrement", "Yes")
# epics_put("8idRigaku:IMM1:NumCapture",10)
# epics_put("8idRigaku:IMM1:FileNumber",1)
# epics_put("8idRigaku:IMM1:FilePath","/Rigaku/bin/destination/RigakuEpics/");
# epics_put("8idRigaku:IMM1:FileName","test");
self.batch_name.put(self._file_name)
Also, add this line to class RigakuUfxcDetectorCam(CamBase):
(after upper_threshold
line):
corrections = ADCpt(EpicsSignal, "Corrections", kind="config", string=True) # has no _RBV PV
We can probably copy the IMM plugin parts from lambda_750k.py
.
BUT, rather than duplicate code, why don't I work this up on a branch and send a PR for you?
Part of that branch should be to pull out the IMM plugin support to a separate file so any of your detectors can use it.
Also need a good base class for the additional code we need to support AD_Acquire()
.
@qzhang234 : Where is the source code for the Sparse plugin? Or the source code of a screen file? I'm looking for the specific PVs to make an ophyd interface.
@prjemian I believe Keenan knows the location for the imm plugin source code. He was the one who built it
Not imm, sparse
On Wed, Mar 3, 2021, 5:18 PM Qingteng Zhang notifications@github.com wrote:
@prjemian https://github.com/prjemian I believe Keenan knows the location for the imm plugin source code. He was the one who built it
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aps-8id-dys/ipython-8idiuser/issues/251#issuecomment-790143212, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARMUMCVUEX5HZNXFORNRJLTB27S5ANCNFSM4W7GGPJA .
Sorry for the late reply. The sparse data (Rigaku-defined binary) was saved directly from detector to network drive and there is no plugin. Plugin is only used when running slow mode and saving into imm.
So is there anything to do for the sparse "plugin"?
On Wed, Mar 3, 2021, 7:39 PM Qingteng Zhang notifications@github.com wrote:
Sorry for the late reply. The sparse data (Rigaku-defined binary) was saved directly from detector to network drive and there is no plugin. Plugin is only used when running slow mode and saving into imm.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aps-8id-dys/ipython-8idiuser/issues/251#issuecomment-790216195, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARMUMBFETSSP2SIOREXWSDTB3QG5ANCNFSM4W7GGPJA .
I don't believe so.
Yeah that part could be confusing. I think Rigaku is probably one of the few area detectors that do that. The sparsification was done on the Rigaku server using their own code
@prjemian
Where is the source code for the Sparse plugin?
For the Rigaku detector, the source code is local to the server computer. There is an installed version also in /net/s8iddserv/xorApps/epics/synApps_6_1/support for the LAMBDA detectors. And I've just uploaded the source to a github repo: https://github.com/BCDA-APS/IMMPlugin
Not imm, sparse
Though implemented as separate plugins, the Sparse and the IMM plugins are both part of the same system. '
@qzhang234
The sparse data (Rigaku-defined binary) was saved directly from detector to network drive and there is no plugin. Plugin is only used when running slow mode and saving into imm.
Are you no longer using the Sparse plugin with the Rigaku slow mode? I know in testing we stopped using Scatter/Gather to try to run multiple instances of the sparse plugin, but I didn't think you got rid of sparsifying the slow data entirely.
The Sparse plugin is different from the sparsification that is done by the zero-deadtime mode. The plugin pipeline should be Rigaku -> Sparse0 -> IMM, The sparse plugin compresses the frame and then the IMM plugin writes out the compressed data. The old IMM plugin did all of this in one plugin, but I split up the two functions into separate plugins when I rewrote the code.
Oh sorry @prjemian, @keenanlang is right about the sparse plugin in the slow mode. For the fast mode the Rigaku data is indeed sparsified without EPICS plugin though
Thanks. I'll look through the new repository.
On Wed, Mar 3, 2021, 10:11 PM Qingteng Zhang notifications@github.com wrote:
Oh sorry @prjemian https://github.com/prjemian, @keenanlang https://github.com/keenanlang is right about the sparse plugin in the slow mode. For the fast mode the Rigaku data is indeed sparsified without EPICS plugin though
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aps-8id-dys/ipython-8idiuser/issues/251#issuecomment-790275183, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARMUMBYSL56XMEFSCKPTVTTB4CALANCNFSM4W7GGPJA .
@prjemian The new code worked! Attached is the code. I did have to import Signal
from Opyhd
but not a big deal.
Per your suggestion, I can't stage the detector twice so I've been using this sequence (see screenshot attached):
One bug I would like to report though: I found that if you don't uncomment the line in ad_rigaku_detector.py
that reads:
self.batch_name.put(self._file_name)
, it gives you an error (see pulldown tab). Why does staging detectors require filename/batchname?
Also do I need to always restart Bluesky for the from instrument.devices.ad_rigaku_detector import adrigaku
to work?
Hmmm... Did we miss defining batch_name
somewhere (perhaps in the base class)? The error says it is not defined. Confirm this by examining dir(adrigaku)
for the text batch_name
.
I see it defined here: https://github.com/aps-8id-dys/ipython-8idiuser/blob/5d8c30f82da1112a1316d46b9df887239faa250d/profile_bluesky/startup/instrument/devices/rigaku_ufxc.py#L167
Since batch name is associated with the data management workflow, it should be defined in the DM base class for area detector support. My recommendation is here, just after detector_number
: https://github.com/aps-8id-dys/ipython-8idiuser/blob/6441425b2fda10b4357ec7ddb58d32eca6c1bc43/profile_bluesky/startup/instrument/devices/data_management.py#L147-L151
On 2nd thought, batch_name
is only used by the non-EPICS rigaku ufxc support, right? If that's the case, then no need to keep the failing lin in the ad_rigaku_detector.py
file.
@qzhang234 : Which way?
@prjemian It seems like batch_name
is used with the nc
web command, which is something designed only for LabView PC and has become obsolete (The LabView PC is actually in a crate right now ready to be shipped back to Rigaku). So yes, you are right and there is no need to keep batch_name
in ad_rigaku_detector.py
.
Thanks for bringing it up
closed too early, there is still an open PR (#253) to be considered and merged...
Commit 4a04198 remove the call to batch_name
from ad_rigaku_detector.py
Needs ophyd classes for
RigakuDetectorCam
&RigakuDetector
See the above screen: