Skip to content

Commit

Permalink
Merge pull request DiamondLightSource/hyperion#1368 from DiamondLight…
Browse files Browse the repository at this point in the history
…Source/1360_handle_characterisation

Correctly handle passed-in ISPyB experiment type (i.e. "characterization")
  • Loading branch information
d-perl authored May 14, 2024
2 parents f7a8435 + c96911b commit be8808c
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
)
from hyperion.external_interaction.ispyb.data_model import (
DataCollectionInfo,
ExperimentType,
ScanDataInfo,
)
from hyperion.external_interaction.ispyb.ispyb_store import (
IspybIds,
StoreInIspyb,
)
from hyperion.log import ISPYB_LOGGER, set_dcgid_tag
from hyperion.parameters.components import IspybExperimentType
from hyperion.parameters.constants import CONST
from hyperion.parameters.plan_specific.rotation_scan_internal_params import (
RotationInternalParameters,
Expand Down Expand Up @@ -92,10 +92,12 @@ def activity_gated_start(self, doc: RunStart):
if experiment_type:
self.ispyb = StoreInIspyb(
self.ispyb_config,
ExperimentType(experiment_type),
IspybExperimentType(experiment_type),
)
else:
self.ispyb = StoreInIspyb(self.ispyb_config, ExperimentType.ROTATION)
self.ispyb = StoreInIspyb(
self.ispyb_config, IspybExperimentType.ROTATION
)
ISPYB_LOGGER.info("Beginning ispyb deposition")
data_collection_group_info = populate_data_collection_group(
self.ispyb.experiment_type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
from hyperion.external_interaction.exceptions import ISPyBDepositionNotMade
from hyperion.external_interaction.ispyb.data_model import (
DataCollectionInfo,
ExperimentType,
ScanDataInfo,
)
from hyperion.external_interaction.ispyb.ispyb_store import (
IspybIds,
StoreInIspyb,
)
from hyperion.log import ISPYB_LOGGER, set_dcgid_tag
from hyperion.parameters.components import IspybExperimentType
from hyperion.parameters.constants import CONST
from hyperion.parameters.plan_specific.gridscan_internal_params import (
GridscanInternalParameters,
Expand Down Expand Up @@ -93,7 +93,9 @@ def activity_gated_start(self, doc: RunStart):
)
json_params = doc.get("hyperion_internal_parameters")
self.params = GridscanInternalParameters.from_json(json_params)
self.ispyb = StoreInIspyb(self.ispyb_config, ExperimentType.GRIDSCAN_3D)
self.ispyb = StoreInIspyb(
self.ispyb_config, IspybExperimentType.GRIDSCAN_3D
)
data_collection_group_info = populate_data_collection_group(
self.ispyb.experiment_type,
self.params.hyperion_params.detector_params,
Expand Down
46 changes: 0 additions & 46 deletions src/hyperion/external_interaction/ispyb/data_model.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,9 @@
from dataclasses import asdict, dataclass
from enum import Enum
from typing import Optional

from hyperion.external_interaction.ispyb.ispyb_dataclass import Orientation


class ExperimentType(Enum):
# Enum values from ispyb column data type
SAD = "SAD" # at or slightly above the peak
SAD_INVERSE_BEAM = "SAD - Inverse Beam"
OSC = "OSC" # "native" (in the absence of a heavy atom)
COLLECT_MULTIWEDGE = (
"Collect - Multiwedge" # "poorly determined" ~ EDNA complex strategy???
)
MAD = "MAD"
HELICAL = "Helical"
MULTI_POSITIONAL = "Multi-positional"
MESH = "Mesh"
BURN = "Burn"
MAD_INVERSE_BEAM = "MAD - Inverse Beam"
CHARACTERIZATION = "Characterization"
DEHYDRATION = "Dehydration"
TOMO = "tomo"
EXPERIMENT = "experiment"
EM = "EM"
PDF = "PDF"
PDF_BRAGG = "PDF+Bragg"
BRAGG = "Bragg"
SINGLE_PARTICLE = "single particle"
SERIAL_FIXED = "Serial Fixed"
SERIAL_JET = "Serial Jet"
STANDARD = "Standard" # Routine structure determination experiment
TIME_RESOLVED = "Time Resolved" # Investigate the change of a system over time
DLS_ANVIL_HP = "Diamond Anvil High Pressure" # HP sample environment pressure cell
CUSTOM = "Custom" # Special or non-standard data collection
XRF_MAP = "XRF map"
ENERGY_SCAN = "Energy scan"
XRF_SPECTRUM = "XRF spectrum"
XRF_MAP_XAS = "XRF map xas"
MESH_3D = "Mesh3D"
SCREENING = "Screening"
STILL = "Still"
SSX_CHIP = "SSX-Chip"
SSX_JET = "SSX-Jet"

# Aliases for historic hyperion experiment type mapping
ROTATION = "SAD"
GRIDSCAN_2D = "mesh"
GRIDSCAN_3D = "Mesh3D"


@dataclass()
class DataCollectionGroupInfo:
visit_string: str
Expand Down
4 changes: 2 additions & 2 deletions src/hyperion/external_interaction/ispyb/ispyb_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
DataCollectionGridInfo,
DataCollectionGroupInfo,
DataCollectionInfo,
ExperimentType,
ScanDataInfo,
)
from hyperion.external_interaction.ispyb.ispyb_utils import (
get_current_time_string,
get_session_id_from_visit,
)
from hyperion.log import ISPYB_LOGGER
from hyperion.parameters.components import IspybExperimentType
from hyperion.tracing import TRACER

if TYPE_CHECKING:
Expand All @@ -39,7 +39,7 @@ class IspybIds(BaseModel):


class StoreInIspyb(ABC):
def __init__(self, ispyb_config: str, experiment_type: ExperimentType) -> None:
def __init__(self, ispyb_config: str, experiment_type: IspybExperimentType) -> None:
self.ISPYB_CONFIG_PATH: str = ispyb_config
self._data_collection_group_id: int | None
self._experiment_type = experiment_type
Expand Down
53 changes: 49 additions & 4 deletions src/hyperion/parameters/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import datetime
from abc import abstractmethod
from enum import Enum
from enum import StrEnum
from pathlib import Path
from typing import Sequence, SupportsInt, TypeVar

Expand Down Expand Up @@ -45,19 +45,64 @@ def __modify_schema__(cls, field_schema):
PARAMETER_VERSION = ParameterVersion.parse("5.0.0")


class RotationAxis(str, Enum):
class RotationAxis(StrEnum):
OMEGA = "omega"
PHI = "phi"
CHI = "chi"
KAPPA = "kappa"


class XyzAxis(str, Enum):
class XyzAxis(StrEnum):
X = "sam_x"
Y = "sam_y"
Z = "sam_z"


class IspybExperimentType(StrEnum):
# Enum values from ispyb column data type
SAD = "SAD" # at or slightly above the peak
SAD_INVERSE_BEAM = "SAD - Inverse Beam"
OSC = "OSC" # "native" (in the absence of a heavy atom)
COLLECT_MULTIWEDGE = (
"Collect - Multiwedge" # "poorly determined" ~ EDNA complex strategy???
)
MAD = "MAD"
HELICAL = "Helical"
MULTI_POSITIONAL = "Multi-positional"
MESH = "Mesh"
BURN = "Burn"
MAD_INVERSE_BEAM = "MAD - Inverse Beam"
CHARACTERIZATION = "Characterization"
DEHYDRATION = "Dehydration"
TOMO = "tomo"
EXPERIMENT = "experiment"
EM = "EM"
PDF = "PDF"
PDF_BRAGG = "PDF+Bragg"
BRAGG = "Bragg"
SINGLE_PARTICLE = "single particle"
SERIAL_FIXED = "Serial Fixed"
SERIAL_JET = "Serial Jet"
STANDARD = "Standard" # Routine structure determination experiment
TIME_RESOLVED = "Time Resolved" # Investigate the change of a system over time
DLS_ANVIL_HP = "Diamond Anvil High Pressure" # HP sample environment pressure cell
CUSTOM = "Custom" # Special or non-standard data collection
XRF_MAP = "XRF map"
ENERGY_SCAN = "Energy scan"
XRF_SPECTRUM = "XRF spectrum"
XRF_MAP_XAS = "XRF map xas"
MESH_3D = "Mesh3D"
SCREENING = "Screening"
STILL = "Still"
SSX_CHIP = "SSX-Chip"
SSX_JET = "SSX-Jet"

# Aliases for historic hyperion experiment type mapping
ROTATION = "SAD"
GRIDSCAN_2D = "mesh"
GRIDSCAN_3D = "Mesh3D"


class HyperionParameters(BaseModel):
class Config:
arbitrary_types_allowed = True
Expand Down Expand Up @@ -103,6 +148,7 @@ class DiffractionExperiment(HyperionParameters):
detector_distance_mm: float | None = Field(default=None, gt=0)
demand_energy_ev: float | None = Field(default=None, gt=0)
run_number: int | None = Field(default=None, ge=0)
ispyb_experiment_type: IspybExperimentType | None = None
storage_directory: str

@property
Expand Down Expand Up @@ -202,4 +248,3 @@ class Config:
xtal_snapshots_omega_start: list[str] | None = None
xtal_snapshots_omega_end: list[str] | None = None
xtal_snapshots: list[str] | None = None
ispyb_experiment_type: str | None = None
2 changes: 1 addition & 1 deletion src/hyperion/parameters/gridscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def ispyb_params(self):
xtal_snapshots_omega_start=self.ispyb_extras.xtal_snapshots_omega_start
or [],
xtal_snapshots_omega_end=self.ispyb_extras.xtal_snapshots_omega_end or [],
ispyb_experiment_type=self.ispyb_extras.ispyb_experiment_type,
ispyb_experiment_type=self.ispyb_experiment_type,
)

@property
Expand Down
6 changes: 5 additions & 1 deletion src/hyperion/parameters/rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from hyperion.external_interaction.ispyb.ispyb_dataclass import RotationIspybParams
from hyperion.parameters.components import (
DiffractionExperiment,
IspybExperimentType,
OptionalGonioAngleStarts,
OptionalXyzStarts,
RotationAxis,
Expand Down Expand Up @@ -46,6 +47,9 @@ class RotationScan(
scan_width_deg: float = Field(default=360, gt=0)
rotation_increment_deg: float = Field(default=0.1, gt=0)
rotation_direction: RotationDirection = Field(default=RotationDirection.NEGATIVE)
ispyb_experiment_type: IspybExperimentType = Field(
default=IspybExperimentType.ROTATION
)
transmission_frac: float
ispyb_extras: TemporaryIspybExtras

Expand Down Expand Up @@ -92,7 +96,7 @@ def ispyb_params(self): # pyright: ignore
undulator_gap=self.ispyb_extras.undulator_gap,
xtal_snapshots_omega_start=self.ispyb_extras.xtal_snapshots_omega_start,
xtal_snapshots_omega_end=self.ispyb_extras.xtal_snapshots_omega_end,
ispyb_experiment_type="SAD",
ispyb_experiment_type=self.ispyb_experiment_type,
)

@property
Expand Down
10 changes: 7 additions & 3 deletions tests/system_tests/external_interaction/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from hyperion.external_interaction.ispyb.data_model import ExperimentType
from hyperion.external_interaction.ispyb.ispyb_store import StoreInIspyb
from hyperion.parameters.components import IspybExperimentType
from hyperion.parameters.constants import CONST
from hyperion.parameters.plan_specific.gridscan_internal_params import (
GridscanInternalParameters,
Expand Down Expand Up @@ -159,12 +159,16 @@ def dummy_params():

@pytest.fixture
def dummy_ispyb(dummy_params) -> StoreInIspyb:
return StoreInIspyb(CONST.SIM.DEV_ISPYB_DATABASE_CFG, ExperimentType.GRIDSCAN_2D)
return StoreInIspyb(
CONST.SIM.DEV_ISPYB_DATABASE_CFG, IspybExperimentType.GRIDSCAN_2D
)


@pytest.fixture
def dummy_ispyb_3d(dummy_params) -> StoreInIspyb:
return StoreInIspyb(CONST.SIM.DEV_ISPYB_DATABASE_CFG, ExperimentType.GRIDSCAN_3D)
return StoreInIspyb(
CONST.SIM.DEV_ISPYB_DATABASE_CFG, IspybExperimentType.GRIDSCAN_3D
)


@pytest.fixture
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@
)
from hyperion.external_interaction.ispyb.data_model import (
DataCollectionGridInfo,
ExperimentType,
ScanDataInfo,
)
from hyperion.external_interaction.ispyb.ispyb_dataclass import Orientation
from hyperion.external_interaction.ispyb.ispyb_store import (
IspybIds,
StoreInIspyb,
)
from hyperion.parameters.components import IspybExperimentType
from hyperion.parameters.constants import CONST
from hyperion.parameters.gridscan import GridScanWithEdgeDetect
from hyperion.parameters.plan_specific.rotation_scan_internal_params import (
Expand Down Expand Up @@ -205,7 +205,7 @@
@pytest.fixture
def dummy_data_collection_group_info(dummy_params):
return populate_data_collection_group(
ExperimentType.GRIDSCAN_2D.value,
IspybExperimentType.GRIDSCAN_2D.value,
dummy_params.hyperion_params.detector_params,
dummy_params.hyperion_params.ispyb_params,
)
Expand Down Expand Up @@ -491,7 +491,7 @@ def test_ispyb_deposition_comment_correct_for_3D_on_failure(
scan_data_infos = generate_scan_data_infos(
dummy_params,
dummy_scan_data_info_for_begin,
ExperimentType.GRIDSCAN_3D,
IspybExperimentType.GRIDSCAN_3D,
ispyb_ids,
)
ispyb_ids = dummy_ispyb_3d.update_deposition(ispyb_ids, scan_data_infos)
Expand All @@ -512,10 +512,10 @@ def test_ispyb_deposition_comment_correct_for_3D_on_failure(
@pytest.mark.parametrize(
"experiment_type, exp_num_of_grids, success",
[
(ExperimentType.GRIDSCAN_2D, 1, False),
(ExperimentType.GRIDSCAN_2D, 1, True),
(ExperimentType.GRIDSCAN_3D, 2, False),
(ExperimentType.GRIDSCAN_3D, 2, True),
(IspybExperimentType.GRIDSCAN_2D, 1, False),
(IspybExperimentType.GRIDSCAN_2D, 1, True),
(IspybExperimentType.GRIDSCAN_3D, 2, False),
(IspybExperimentType.GRIDSCAN_3D, 2, True),
],
)
def test_can_store_2D_ispyb_data_correctly_when_in_error(
Expand Down Expand Up @@ -573,14 +573,14 @@ def test_can_store_2D_ispyb_data_correctly_when_in_error(
def generate_scan_data_infos(
dummy_params,
dummy_scan_data_info_for_begin: ScanDataInfo,
experiment_type: ExperimentType,
experiment_type: IspybExperimentType,
ispyb_ids: IspybIds,
) -> Sequence[ScanDataInfo]:
xy_scan_data_info = scan_xy_data_info_for_update(
ispyb_ids.data_collection_group_id, dummy_params, dummy_scan_data_info_for_begin
)
xy_scan_data_info.data_collection_id = ispyb_ids.data_collection_ids[0]
if experiment_type == ExperimentType.GRIDSCAN_3D:
if experiment_type == IspybExperimentType.GRIDSCAN_3D:
scan_data_infos = scan_data_infos_for_update_3d(
ispyb_ids, xy_scan_data_info, dummy_params
)
Expand Down
Loading

0 comments on commit be8808c

Please sign in to comment.