Skip to content

Commit

Permalink
Ported real centring code changes from other side branch. Works with …
Browse files Browse the repository at this point in the history
…20240301
  • Loading branch information
rhfogh authored and marcus-oscarsson committed Mar 8, 2024
1 parent c5166d5 commit 5c469a8
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 15 deletions.
24 changes: 23 additions & 1 deletion mxcubecore/HardwareObjects/Gphl/GphlMessages.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,11 +488,21 @@ class CollectionDone(MessageData):

INTENT = "EVENT"

def __init__(self, proposalId, status, procWithLatticeParams=False, imageRoot=None):
def __init__(
self,
proposalId,
status,
procWithLatticeParams=False,
imageRoot=None,
scanIdMap=None,
centrings=None,
):
self._proposalId = proposalId
self._imageRoot = imageRoot
self._status = status
self._procWithLatticeParams = procWithLatticeParams
self._scanIdMap = scanIdMap
self._centrings = centrings

@property
def proposalId(self):
Expand All @@ -515,6 +525,18 @@ def procWithLatticeParams(self):
"""Boolean, whether lattice parameters should be used for processing"""
return self._procWithLatticeParams

@property
def scanIdMap(self):
"""Dict[str,str] scan.id_:GoniostatTranslation.id_"""
return self._scanIdMap

@property
def centrings(self):
"""set(GoniostatTranslation)
New GoniostatTranslations acquired during acquisition"""
return self._centrings


# Complex payloads

Expand Down
108 changes: 96 additions & 12 deletions mxcubecore/HardwareObjects/Gphl/GphlWorkflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,14 @@ def __init__(self, name):
# Subprocess names to track which subprocess is getting info
self._server_subprocess_names = {}

# Dictionary holding (directory, prefix, run_number, first_image) : motors_dict
self._scan_to_motors = OrderedDict()
# Dictionary holding (prefix, run_number, first_image) : scan_id
self._key_to_scan = OrderedDict()
# Dictionary of scan_id to id of actual translation used
self._scan_id_to_translation_id = {}
# Translation ID matching current centring
self._latest_translation_id = None
# GoniostatTranslations generated in recentring
self._recentrings = []

# Rotation axis role names, ordered from holder towards sample
self.rotation_axis_roles = []
Expand Down Expand Up @@ -803,6 +809,11 @@ def execute(self):
"collectOscillationStarted",
HWR.beamline.collect,
)
dispatcher.connect(
self.handle_collection_end,
"collectOscillationFinished",
HWR.beamline.collect,
)
try:
while True:
if self._workflow_queue is None:
Expand Down Expand Up @@ -835,6 +846,11 @@ def execute(self):
"collectOscillationStarted",
HWR.beamline.collect,
)
dispatcher.disconnect(
self.handle_collection_end,
"collectOscillationFinished",
HWR.beamline.collect,
)


def post_execute(self):
Expand Down Expand Up @@ -1365,6 +1381,10 @@ def setup_data_collection(self, payload, correlation_id):
"""
geometric_strategy = payload

self._key_to_scan.clear()
self._scan_id_to_translation_id.clear()
self._recentrings = []

# Set up
gphl_workflow_model = self._queue_entry.get_data_model()
wftype = gphl_workflow_model.wftype
Expand Down Expand Up @@ -1572,14 +1592,15 @@ def setup_data_collection(self, payload, correlation_id):
translation, current_pos_dict = self.execute_sample_centring(
q_e, sweepSetting
)
self._latest_translation_id = translation.id_
self._recentrings.append(translation)
# Update current position
current_okp = tuple(
current_pos_dict[role] for role in self.rotation_axis_roles
)
current_xyz = tuple(
current_pos_dict[role] for role in self.translation_axis_roles
)
goniostatTranslations.append(translation)
gphl_workflow_model.current_rotation_id = sweepSetting.id_

elif gphl_workflow_model.characterisation_done or wftype == "diffractcal":
Expand Down Expand Up @@ -1613,7 +1634,8 @@ def setup_data_collection(self, payload, correlation_id):
translation = GphlMessages.GoniostatTranslation(
rotation=sweepSetting, **translation_settings
)
goniostatTranslations.append(translation)
self._latest_translation_id = translation.id_
self._recentrings.append(translation)
gphl_workflow_model.current_rotation_id = sweepSetting.id_

else:
Expand All @@ -1624,13 +1646,14 @@ def setup_data_collection(self, payload, correlation_id):
translation = GphlMessages.GoniostatTranslation(
rotation=sweepSetting, **translation_settings
)
goniostatTranslations.append(translation)
self._latest_translation_id = None
else:
if has_recentring_file:
settings.update(translation_settings)
q_e = self.enqueue_sample_centring(motor_settings=settings)
translation, dummy = self.execute_sample_centring(q_e, sweepSetting)
goniostatTranslations.append(translation)
self._latest_translation_id = translation.id_
self._recentrings.append(translation)
gphl_workflow_model.current_rotation_id = sweepSetting.id_
if recentring_mode == "start":
# We want snapshots in this mode,
Expand All @@ -1656,8 +1679,10 @@ def setup_data_collection(self, payload, correlation_id):
requestedRotationId=sweepSetting.id_,
**translation_settings
)
goniostatTranslations.append(translation)
self._latest_translation_id = translation.id_
self._recentrings.append(translation)
gphl_workflow_model.current_rotation_id = newRotation.id_
goniostatTranslations.append(translation)

# calculate or determine centring for remaining sweeps
for sweepSetting in sweepSettings[1:]:
Expand Down Expand Up @@ -1913,6 +1938,13 @@ def collect_data(self, payload, correlation_id):
path_template.start_num = acq_parameters.first_image
path_template.num_files = acq_parameters.num_images

key = (
path_template.base_prefix,
path_template.run_number,
path_template.start_num
)
self._key_to_scan[key] = scan

# Handle orientations and (re) centring
goniostatRotation = sweep.goniostatSweepSetting
rotation_id = goniostatRotation.id_
Expand Down Expand Up @@ -2010,10 +2042,14 @@ def collect_data(self, payload, correlation_id):
else:
status = 0

failedScanIds = set(scan.id_ for scan in self._key_to_scan.values())

return GphlMessages.CollectionDone(
status=status,
proposalId=collection_proposal.id_,
procWithLatticeParams=gphl_workflow_model.use_cell_for_processing,
scanIdMap=self._scan_id_to_translation_id,
centrings=set(self._recentrings),
)

def select_lattice(self, payload, correlation_id):
Expand Down Expand Up @@ -2457,6 +2493,22 @@ def obtain_prior_information(self, payload, correlation_id):
return priorInformation


def handle_collection_end(
self, dummy1, dummy2, dummy3, dummy4, dummy5, collect_dict
):
""" Read and process collectOscillationFinished signal
which means scan finished successfully"""
key = (
collect_dict["fileinfo"].get("prefix"),
collect_dict["fileinfo"].get("run_number"),
collect_dict["oscillation_sequence"][0].get("start_image_number")
)
scan = self._key_to_scan.pop(key, None)
if scan is None:
raise RuntimeError(
"No scan matching prefix: %s, run_number: %s, start_image_number: %s at end"
% key
)
def handle_collection_start(
self, owner, blsampleid, barcode, location, collect_dict, osc_id
):
Expand All @@ -2465,14 +2517,46 @@ def handle_collection_start(
NB only collect_dict is reliably non-null"""
key = (
collect_dict["fileinfo"].get("directory"),
collect_dict["fileinfo"].get("prefix"),
collect_dict["fileinfo"].get("run_number"),
collect_dict["oscillation_sequence"].get("start_image_number")
collect_dict["oscillation_sequence"][0].get("start_image_number")
)
scan = self._key_to_scan.get(key)
if scan is None:
raise RuntimeError(
"No scan matching prefix: %s, run_number: %s, start_image_number: %s at start"
% key
)

translation_settings = dict(
(role, collect_dict["motors"].get(role))
for role in self.translation_axis_roles
)
if key in self._scan_to_motors:
raise RuntimeError("Duplicate scan found: " + str(key))
self._scan_to_motors[key] = collect_dict["motors"].copy()
if not self._scan_id_to_translation_id or None in translation_settings.values():
# First sweep or not first scan in sweep
# No new centring done
if self._latest_translation_id:
self._scan_id_to_translation_id[scan.id_] = self._latest_translation_id
else:
# NBNB RECHECK!!!
# We must be in centring mode None: No real centring known, use calculated
self._scan_id_to_translation_id[scan.id_] = None
else:
# First scan in sweep (not first sweep)
# We have recentred. Make new translation object
translation_settings = dict(
(role, HWR.beamline.diffractometer.get_motor_positions().get(role))
for role in self.translation_axis_roles
)
translation = GphlMessages.GoniostatTranslation(
requestedRotationId=scan.sweep.goniostatSweepSetting.id_,
**translation_settings
)
self._latest_translation_id = translation.id_
self._scan_id_to_translation_id[scan.id_] = translation.id_
self._recentrings.append(translation)



# Utility functions

Expand Down
20 changes: 18 additions & 2 deletions mxcubecore/HardwareObjects/Gphl/GphlWorkflowConnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,6 @@ def _GoniostatRotation_to_python(self, py4jGoniostatRotation, isSweepSetting=Fal
result = GphlMessages.GoniostatRotation(
id_=uuid.UUID(uuidString), **axisSettings
)

py4jGoniostatTranslation = py4jGoniostatRotation.getTranslation()
if py4jGoniostatTranslation:
translationAxisSettings = py4jGoniostatTranslation.getAxisSettings()
Expand Down Expand Up @@ -1046,8 +1045,25 @@ def _CollectionDone_to_java(self, collectionDone):
proposalId = jvm.java.util.UUID.fromString(
conversion.text_type(collectionDone.proposalId)
)
centrings = set(
self._GoniostatTranslation_to_java(translation)
for translation in collectionDone.centrings
)
scanIdMap = {}
for item in collectionDone.scanIdMap.items():
scanIdMap[
jvm.java.util.UUID.fromString(
conversion.text_type(item[0])
)
] = jvm.java.util.UUID.fromString(
conversion.text_type(item[1])
)
return jvm.astra.messagebus.messages.information.CollectionDoneImpl(
proposalId, collectionDone.imageRoot, collectionDone.status
proposalId,
collectionDone.status,
collectionDone.procWithLatticeParams,
scanIdMap,
centrings,
)

def _SelectedLattice_to_java(self, selectedLattice):
Expand Down

0 comments on commit 5c469a8

Please sign in to comment.