Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/instrument/callbacks/spec_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
from apstools.callbacks import SpecWriterCallback as callback

specwriter = callback()
specwriter.write_new_scan_header = False # issue #1032
4 changes: 2 additions & 2 deletions src/instrument/configs/iconfig.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ RUNENGINE_METADATA:
# RUN_ENGINE_SCAN_ID_PV: "8idi:bluesky_scan_id"

# permissions
ALLOW_AREA_DETECTOR_WARMUP: true
ALLOW_AREA_DETECTOR_WARMUP: false
ENABLE_AREA_DETECTOR_IMAGE_PLUGIN: true
USE_PROGRESS_BAR: false
WRITE_NEXUS_DATA_FILES: false
WRITE_NEXUS_DATA_FILES: true
NEXUS_WARN_MISSING_CONTENT: false
NEXUS_FILE_EXTENSION: hdf
WRITE_SPEC_DATA_FILES: true
Expand Down
2 changes: 1 addition & 1 deletion src/instrument/data_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from apstools.utils import * # noqa

from .callbacks import specwriter # noqa
from .callbacks import specwriter, nxwriter # noqa
from .devices import * # noqa
from .plans import * # noqa

Expand Down
3 changes: 3 additions & 0 deletions src/instrument/devices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,20 @@
from .hhl_mirrors import mr1, mr2
from .hhl_slits import wb_slit, mono_slit
from .idt_mono import idt_mono
from .labjack_support import labjack
from .meascomp_usb_ctr import mcs
from .qnw_device import qnw_env1, qnw_env2, qnw_env3
from .slit_base import sl4_base, sl5_base, sl7_base, sl8_base, sl9_base
from .slit import sl4, sl5, sl7, sl8, sl9
from .softglue import softglue_8idi
from .tetramm_picoammeter import tetramm1, tetramm2, tetramm3, tetramm4
from .transfocator_8idd import rl1
from .transfocator_8ide import rl2
from .xbpm2_in_8ide import bd6a
from .xbpm2_in_8ide import xbpm2
from .win import win_e, win_i


## Beamline Area Detectors
from .ad_eiger_4M import eiger4M
from .ad_flag1 import flag1ad
Expand Down
11 changes: 11 additions & 0 deletions src/instrument/devices/labjack_support.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""LabJack LJT705 in 8-ID-I."""

from ophyd import Component, Device, EpicsSignal


class LabJack(Device):
operation = Component(EpicsSignal, "Bo0")
logic = Component(EpicsSignal, "Bo1")


labjack = LabJack("8idiSoft:LJT705:", name="labjack")
50 changes: 50 additions & 0 deletions src/instrument/devices/softglue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from ophyd import Component, Device, EpicsSignal


class SoftGlue(Device):

acq_period = Component(EpicsSignal, "8idi:SGControl1.A", kind="config")
acq_time = Component(EpicsSignal, "8idi:SGControl1.C", kind="config")
num_triggers = Component(EpicsSignal, "8idi:SGControl1.J", kind="config")
# avoid the name 'trigger' since Device has a '.trigger()' method.
sg_trigger = Component(
EpicsSignal,
"8idi:softGlueA:MUX2-1_IN0_Signal",
kind="omitted",
string=True,
trigger_value="1!",
)

# FIXME upstream : This code uses self.trigger_value
# https://github.com/aps-8id-dys/bluesky/issues/99
def trigger(self):
"""BUGFIX - Put the acq_signal's 'trigger_value' instead of 1."""
from ophyd.status import DeviceStatus

signals = self.trigger_signals
if len(signals) > 1:
raise NotImplementedError(
"More than one trigger signal is not currently supported."
)
status = DeviceStatus(self)
if not signals:
status.set_finished()
return status

(acq_signal,) = signals

self.subscribe(status._finished, event_type=self.SUB_ACQ_DONE, run=False)

def done_acquisition(**ignored_kwargs):
# Keyword arguments are ignored here from the EpicsSignal
# subscription, as the important part is that the put completion
# has finished
self._done_acquiring()

# acq_signal.put(1, wait=False, callback=done_acquisition) # ORIGINAL
trigger_value = self._sig_attrs[acq_signal.attr_name].trigger_value
acq_signal.put(trigger_value, wait=False, callback=done_acquisition)
return status


softglue_8idi = SoftGlue("", name="softglue_8idi")
25 changes: 18 additions & 7 deletions src/instrument/plans/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@

# flake8: noqa

## sanity check plans
# beamline specific plans
from .bdp_demo import mc_test
from .bdp_demo import xpcs_bdp_demo_plan
from .bdp_demo import xpcs_reset_index
from .bdp_demo import xpcs_setup_user
# sanity check plans
from .demo_hello_world import hello_world
from .demo_sim_1d import demo_sim_1d

## beamline specific plans
from .bdp_demo import xpcs_bdp_demo_plan, xpcs_setup_user, xpcs_reset_index, mc_test
# from .independent import kickoff_dm_workflow
# from .independent import setup_detector
from .independent_test import kickoff_dm_workflow
from .independent_test import pre_align
from .independent_test import setup_det_ext_trig
from .independent_test import setup_softglue_ext_trig
from .independent_test import simple_acquire
# from .independent import simple_acquire
from .mesh_plans import xpcs_mesh

# from .select_sample_env import select_sample_env
from .select_sample import select_sample, open_shutter, close_shutter
from .qnw_plans import set_qnw
# from .select_sample_env import select_sample_env
from .select_sample import close_shutter
from .select_sample import open_shutter
from .select_sample import select_sample
2 changes: 1 addition & 1 deletion src/instrument/plans/bdp_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def _pick_area_detector(detector_name):


def _header_index():
return f"{xpcs_header.get()}_{xpcs_index.get():03d}"
return f"{xpcs_header.get()}_{xpcs_index.get():05d}"


def _xpcsDataDir(title: str, nframes: int = 0):
Expand Down
131 changes: 131 additions & 0 deletions src/instrument/plans/independent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"""
Data acquisition steps as independent bluesky plans.

.. autosummary::
~kickoff_dm_workflow
~setup_detector
~simple_acquire

This plan is an example that combines the above plans.

.. autosummary::
~example_full_acquisition
"""

import pathlib

from apstools.devices import DM_WorkflowConnector
from apstools.utils import share_bluesky_metadata_with_dm
from bluesky import plan_stubs as bps
from bluesky import plans as bp
from bluesky import preprocessors as bpp

from ..callbacks.nexus_data_file_writer import nxwriter
from ..devices.ad_eiger_4M import eiger4M
from ..initialize_bs_tools import cat

EMPTY_DICT = {} # Defined as symbol to pass the style checks.


def simple_acquire(det, md: dict = EMPTY_DICT):
"""Just run the acquisition, nothing else."""

nxwriter.warn_on_missing_content = False
# nxwriter.file_path = data_path
# nxwriter.file_name = data_path / (file_name_base + ".hdf")

md["metadatafile"] = nxwriter.file_name.name

@bpp.subs_decorator(nxwriter.receiver)
def acquire():
yield from bp.count([det], md=md)

yield from acquire()

# Wait for NeXus metadata file content to flush to disk.
# If next acquisition proceeds without waiting, the
# metadata file will be spoiled.
yield from nxwriter.wait_writer_plan_stub()


def setup_detector(det, acq_time, num_frames, file_name):
"""Setup the acquisition,"""
yield from bps.mv(det.cam.acquire_time, acq_time)
yield from bps.mv(det.cam.num_images, num_frames)
yield from bps.mv(det.hdf1.file_name, file_name)


def kickoff_dm_workflow(
experiment_name,
file_name,
qmap_file,
run,
analysisMachine="amazonite",
):
"""Start a DM workflow for this bluesky run."""
dm_workflow = DM_WorkflowConnector(name="dm_workflow")
forever = 999_999_999_999 # long time, s, disables periodic reports
workflow_name = "xpcs8-02-gladier-boost"

yield from bps.mv(dm_workflow.concise_reporting, True)
yield from bps.mv(dm_workflow.reporting_period, forever)

# DM argsDict content
argsDict = dict(
filePath=file_name,
experimentName=experiment_name,
qmap=qmap_file,
smooth="sqmap",
gpuID=-1,
beginFrame=1,
endFrame=-1,
strideFrame=1,
avgFrame=1,
type="Multitau",
dq="all",
verbose=False,
saveG2=False,
overwrite=False,
analysisMachine=analysisMachine,
)

yield from dm_workflow.run_as_plan(
workflow=workflow_name,
wait=False,
timeout=forever,
**argsDict,
)

# Upload bluesky run metadata to APS DM.
share_bluesky_metadata_with_dm(experiment_name, workflow_name, run)

# Users requested the DM workflow job ID be printed to the console.
dm_workflow._update_processing_data()
job_id = dm_workflow.job_id.get()
job_stage = dm_workflow.stage_id.get()
job_status = dm_workflow.status.get()
print(f"DM workflow id: {job_id!r} status: {job_status} stage: {job_stage}")


def example_full_acquisition():
"""These are the data acquisition steps for a user."""
det = eiger4M
yield from setup_detector(det, 0.1, 1000, "A001_001")

uids = yield from simple_acquire(det)
print(f"Bluesky run: {uids=}")
run = cat[uids[0]]

try:
image_file_name = pathlib.Path(det.hdf1.full_file_name.get()).name
print(f"{image_file_name=!r}")

yield from kickoff_dm_workflow(
"my_dm_experiment",
image_file_name,
"my_qmap_file.h5",
run,
analysisMachine="amazonite",
)
except Exception as exc:
print(f"Exception: {exc}")
Loading