diff --git a/src/aare/common/find_xtal.py b/src/aare/common/find_xtal.py index 6433fa10..c149434c 100644 --- a/src/aare/common/find_xtal.py +++ b/src/aare/common/find_xtal.py @@ -280,20 +280,30 @@ def get_com_image_number(com, images): return image.number return None - - def raster_centre_of_mass(result_array, images) -> CenterOfMassModel | None: # grid_mm_x and grid_mm_y are relative to the top left corner of raster grid - com = ndimage.center_of_mass(result_array) + # com = ndimage.center_of_mass(result_array) + # if com and not np.isnan(com[0]) and not np.isnan(com[1]): + # logger.info(f"Center of mass: {com}") + # max_image = get_com_image_number(com, images) + # return CenterOfMassModel(n_x=com[0], n_y=com[1], max_image=max_image) + # elif com and np.isnan(com[0]) and np.isnan(com[1]): + # logger.warning(f"Center of mass is nan: {com[0]}, {com[1]}") + # return None + # else: + # logger.warning("No valid center of mass found") + # return None + score_array = compute_crystal_score_array(images) + com = _max_cell(score_array) if com and not np.isnan(com[0]) and not np.isnan(com[1]): - logger.info(f"Center of mass: {com}") + logger.info(f"Highest score: {com}") max_image = get_com_image_number(com, images) return CenterOfMassModel(n_x=com[0], n_y=com[1], max_image=max_image) elif com and np.isnan(com[0]) and np.isnan(com[1]): - logger.warning(f"Center of mass is nan: {com[0]}, {com[1]}") + logger.warning(f"Highest score is nan: {com[0]}, {com[1]}") return None else: - logger.warning("No valid center of mass found") + logger.warning("No valid score found") return None def has_sufficient_low_res_spots( diff --git a/src/aare/daq/daq.py b/src/aare/daq/daq.py index 58e84370..22628291 100644 --- a/src/aare/daq/daq.py +++ b/src/aare/daq/daq.py @@ -1353,6 +1353,10 @@ class AareDAQ: ), ) else: + # Resolve + validate the requested dtz (sets cfg.dtz, requires + # request.dtz) BEFORE configuring JFJoch, so JFJoch receives the + # commanded target rather than the live, still-in-transit position. + self.__setup_datacollection(request=grid_request) logger.debug(f"Is detector simulated? {self.__cfg.simulated_detector}") if not self.__cfg.simulated_detector: logger.info(f"initialise detector for raster") @@ -1362,7 +1366,6 @@ class AareDAQ: else: logger.info("Simulated detector mode enabled; using fake raster result.") - self.__setup_datacollection(request=grid_request) self.__set_state(BeamlineStateEnum.DataCollection) raster_result = raster_service.execute(grid_request) result = CompletedRasterGrid(r=[raster_result]) @@ -2052,8 +2055,15 @@ class AareDAQ: self.__devs.aerotech_omega = request_omega if request.dtz is not None: + if request.dtz < self.__cfg.cached_dtz_low: + raise ValueError(f"Requested DTZ {request.dtz} is less than low detector limit {self.__cfg.cached_dtz_low}") + elif request.dtz > self.__cfg.cached_dtz_high: + raise ValueError(f"Requested DTZ {request.dtz} exceeds high detector limit {self.__cfg.cached_dtz_high}") logger.info(f'requesting dtz to move to {request.dtz}') self.__cfg.dtz = request.dtz + else: + raise ValueError("No DTZ specified") + if self.sample is not None and self.sample.db_id is not None: sample_id = self.sample.db_id diff --git a/src/aare/daq/workflows.py b/src/aare/daq/workflows.py index 99dcdfed..e4a0d797 100644 --- a/src/aare/daq/workflows.py +++ b/src/aare/daq/workflows.py @@ -85,13 +85,13 @@ def sa2rse(devs: BeamlineDevices, cfg: BeamlineConfig): def sa2xtal_snapshot(devs:BeamlineDevices, cfg:BeamlineConfig): logger.info("SA to Xtal Snapshot") - devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.0005) + devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.001) logger.debug(f"new sam cam settings: {devs.samcam_settings}") devs.bec_worker.move_to(BeamlineState.XTAL_SNAPSHOT) def dc2xtal_snapshot(devs:BeamlineDevices, cfg:BeamlineConfig): logger.debug("DC to Xtal Snapshot") - devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.0005) + devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.001) logger.debug(f"new sam cam settings: {devs.samcam_settings}") devs.bec_worker.move_to(BeamlineState.XTAL_SNAPSHOT) diff --git a/src/aare/gui/panels/raster_data_collection.py b/src/aare/gui/panels/raster_data_collection.py index ad77223f..fc6f65a9 100644 --- a/src/aare/gui/panels/raster_data_collection.py +++ b/src/aare/gui/panels/raster_data_collection.py @@ -93,10 +93,11 @@ class RasterDataCollectionPanel(ScanSettingsPanel): self.metric_combo.addItem("Spot ratio (ice/low res.)", RasterGridMetric.SPOTS_ICE_LOW_RES) self.metric_combo.addItem("Background estimate", RasterGridMetric.BKG) self.metric_combo.addItem("Indexing result", RasterGridMetric.INDEXING) - self.metric_combo.addItem("Profile Radius", RasterGridMetric.PR) + self.metric_combo.addItem("Profile Radius (Score)", RasterGridMetric.PR) # JD: repurposing PR for testing scoring self.metric_combo.addItem("B-factor", RasterGridMetric.BFACTOR) self.metric_combo.addItem("Resolution (ML est.)", RasterGridMetric.RES) + self.metric_combo.setCurrentIndex(self.metric_combo.findData(RasterGridMetric.PR)) # JD: repurposing PR for testing scoring self.metric_combo.currentIndexChanged.connect(self.metric_changed) self._layout.addWidget(self.metric_combo, 7, 1, 1, 3) diff --git a/src/aare/gui/scan_logic/raster_grid_manager.py b/src/aare/gui/scan_logic/raster_grid_manager.py index 627d7646..ca1503da 100644 --- a/src/aare/gui/scan_logic/raster_grid_manager.py +++ b/src/aare/gui/scan_logic/raster_grid_manager.py @@ -10,6 +10,7 @@ from typing import List, Tuple from aare.common.beamline import mx_beamline, get_jfjoch_url from aare.common.coordinate import Coordinate, SmargonCoordinate from aare.common.models import DAQStatusModel +from aare.common.find_xtal import compute_crystal_score_array from aare.common.raster_grid import RasterGridRequest, CompletedRasterGrid, CompletedRasterGridElem from aare.common.sample_geometry import SampleGeometryModel @@ -22,7 +23,7 @@ class RasterGridMetric(Enum): BKG = 0 SPOTS = 1 INDEXING = 2 - PR = 3 + PR = 3 # JD: repurposing PR for testing scoring BFACTOR = 4 SPOTS_LOW_RES = 5 RES = 6 @@ -121,7 +122,8 @@ class RasterGridManager(QObject): self.__beam_size_mm = geom.beam_size_mm self.__geom = geom - self.__metric = RasterGridMetric.SPOTS_LOW_RES + # self.__metric = RasterGridMetric.SPOTS_LOW_RES + self.__metric = RasterGridMetric.PR # JD: repurposing PR for testing scoring self.__loaded_image_prefix = None self.__loaded_image_index = None @@ -373,8 +375,11 @@ class RasterGridManager(QObject): if grid.result.images[cell].b is not None and grid.result.images[cell].b >= 0: txt += f"B-factor {grid.result.images[cell].b:.2f}
" - if grid.result.images[cell].pr is not None and grid.result.images[cell].pr >= 0: - txt += f"Profile Radius {grid.result.images[cell].pr:.2f}" + # if grid.result.images[cell].pr is not None and grid.result.images[cell].pr >= 0: # JD: repurposing PR for testing scoring + # txt += f"Profile Radius {grid.result.images[cell].pr:.2f}" + if grid.result.images[cell].nx is not None and grid.result.images[cell].ny is not None: + score = compute_crystal_score_array(grid.result.images) + txt += f"Profile Radius (Score) {score[grid.result.images[cell].nx, grid.result.images[cell].ny]:.2f}" return txt return None @@ -461,8 +466,10 @@ class RasterGridManager(QObject): v = [obj.bkg for obj in i.result.images] case RasterGridMetric.INDEXING: v = [obj.index for obj in i.result.images] - case RasterGridMetric.PR: - v = [obj.index / max(obj.spots_low_res, 1) for obj in i.result.images] + case RasterGridMetric.PR: # JD: repurposing PR for testing scoring + # v = [obj.index / max(obj.spots_low_res, 1) for obj in i.result.images] + score = compute_crystal_score_array(i.result.images) + v = [score[obj.nx, obj.ny] if obj.nx is not None and obj.ny is not None else None for obj in i.result.images] case RasterGridMetric.BFACTOR: v = [obj.b for obj in i.result.images] case RasterGridMetric.RES: