mx-bluesky 0.0.1__py3-none-any.whl → 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. mx_bluesky/__main__.py +1 -2
  2. mx_bluesky/_version.py +14 -2
  3. mx_bluesky/example.py +4 -4
  4. mx_bluesky/i04/__init__.py +3 -0
  5. mx_bluesky/i04/callbacks/murko_callback.py +45 -0
  6. mx_bluesky/i04/thawing_plan.py +84 -0
  7. mx_bluesky/i24/serial/__init__.py +49 -0
  8. mx_bluesky/i24/serial/blueapi_config.yaml +12 -0
  9. mx_bluesky/{I24 → i24}/serial/dcid.py +53 -41
  10. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/DetStage.edl +1 -2
  11. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/DiamondExtruder-I24-py3v1.edl +28 -32
  12. mx_bluesky/{I24 → i24}/serial/extruder/EX-gui-edm/microdrop_alignment.edl +0 -1
  13. mx_bluesky/i24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +513 -0
  14. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/CustomChip_py3v1.edl +1 -2
  15. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/DetStage.edl +1 -2
  16. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/DiamondChipI24-py3v1.edl +46 -41
  17. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/ME14E-GeneralPurpose.edl +0 -1
  18. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/MappingLite-oxford_py3v1.edl +10 -11
  19. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/PMAC_Command.edl +0 -1
  20. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/Shutter_Control.edl +0 -1
  21. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/microdrop_alignment.edl +0 -1
  22. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/nudgechip.edl +0 -1
  23. mx_bluesky/{I24 → i24}/serial/fixed_target/FT-gui-edm/pumpprobe-py3v1.edl +300 -119
  24. mx_bluesky/i24/serial/fixed_target/FT-gui-edm/short1-laser.png +0 -0
  25. mx_bluesky/i24/serial/fixed_target/FT-gui-edm/short2-laser.png +0 -0
  26. mx_bluesky/{I24 → i24}/serial/fixed_target/ft_utils.py +24 -1
  27. mx_bluesky/i24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +798 -0
  28. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_Chip_Manager_py3v1.py +374 -408
  29. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_Chip_Mapping_py3v1.py +34 -40
  30. mx_bluesky/i24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +325 -0
  31. mx_bluesky/{I24 → i24}/serial/fixed_target/i24ssx_moveonclick.py +40 -45
  32. mx_bluesky/i24/serial/log.py +156 -0
  33. mx_bluesky/i24/serial/parameters/__init__.py +15 -0
  34. mx_bluesky/i24/serial/parameters/constants.py +47 -0
  35. mx_bluesky/i24/serial/parameters/experiment_parameters.py +124 -0
  36. mx_bluesky/i24/serial/parameters/fixed_target/cs/cs_maker.json +9 -0
  37. mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/cs/motor_direction.txt +1 -1
  38. mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/pvar_files/minichip-oxford.pvar +1 -1
  39. mx_bluesky/i24/serial/parameters/utils.py +40 -0
  40. mx_bluesky/i24/serial/run_extruder.sh +19 -0
  41. mx_bluesky/i24/serial/run_fixed_target.sh +22 -0
  42. mx_bluesky/i24/serial/run_serial.py +36 -0
  43. mx_bluesky/{I24 → i24}/serial/set_visit_directory.sh +6 -1
  44. mx_bluesky/{I24 → i24}/serial/setup_beamline/pv.py +1 -62
  45. mx_bluesky/{I24 → i24}/serial/setup_beamline/pv_abstract.py +6 -7
  46. mx_bluesky/{I24 → i24}/serial/setup_beamline/setup_beamline.py +90 -269
  47. mx_bluesky/{I24 → i24}/serial/setup_beamline/setup_detector.py +47 -40
  48. mx_bluesky/i24/serial/setup_beamline/setup_zebra_plans.py +459 -0
  49. mx_bluesky/i24/serial/start_blueapi.sh +28 -0
  50. mx_bluesky/i24/serial/write_nexus.py +102 -0
  51. mx_bluesky/parameters/__init__.py +31 -0
  52. mx_bluesky/parameters/components.py +200 -0
  53. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/METADATA +37 -26
  54. mx_bluesky-0.3.1.dist-info/RECORD +67 -0
  55. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/WHEEL +1 -1
  56. mx_bluesky-0.3.1.dist-info/entry_points.txt +4 -0
  57. mx_bluesky/I24/serial/extruder/i24ssx_Extruder_Collect_py3v2.py +0 -476
  58. mx_bluesky/I24/serial/fixed_target/FT-gui-edm/ME14E-motors.edl +0 -1874
  59. mx_bluesky/I24/serial/fixed_target/__init__.py +0 -0
  60. mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_Collect_py3v1.py +0 -695
  61. mx_bluesky/I24/serial/fixed_target/i24ssx_Chip_StartUp_py3v1.py +0 -463
  62. mx_bluesky/I24/serial/log.py +0 -101
  63. mx_bluesky/I24/serial/parameters/__init__.py +0 -5
  64. mx_bluesky/I24/serial/parameters/constants.py +0 -39
  65. mx_bluesky/I24/serial/parameters/fixed_target/cs/cs_maker.json +0 -9
  66. mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_1.txt +0 -4
  67. mx_bluesky/I24/serial/parameters/fixed_target/cs/fiducial_2.txt +0 -4
  68. mx_bluesky/I24/serial/parameters/fixed_target/litemaps/currentchip.map +0 -81
  69. mx_bluesky/I24/serial/parameters/fixed_target/parameters.txt +0 -13
  70. mx_bluesky/I24/serial/run_serial.py +0 -52
  71. mx_bluesky/I24/serial/write_nexus.py +0 -113
  72. mx_bluesky-0.0.1.dist-info/RECORD +0 -58
  73. mx_bluesky-0.0.1.dist-info/entry_points.txt +0 -4
  74. /mx_bluesky/{I24 → i24}/__init__.py +0 -0
  75. /mx_bluesky/{I24/serial → i24/serial/extruder}/__init__.py +0 -0
  76. /mx_bluesky/{I24/serial/extruder → i24/serial/fixed_target}/__init__.py +0 -0
  77. /mx_bluesky/{I24 → i24}/serial/parameters/fixed_target/pvar_files/oxford.pvar +0 -0
  78. /mx_bluesky/{I24 → i24}/serial/run_ssx.sh +0 -0
  79. /mx_bluesky/{I24 → i24}/serial/setup_beamline/__init__.py +0 -0
  80. /mx_bluesky/{I24 → i24}/serial/setup_beamline/ca.py +0 -0
  81. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/LICENSE +0 -0
  82. {mx_bluesky-0.0.1.dist-info → mx_bluesky-0.3.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,156 @@
1
+ import functools
2
+ import logging
3
+ import logging.config
4
+ from os import environ
5
+ from pathlib import Path
6
+
7
+ from bluesky.log import logger as bluesky_logger
8
+ from dodal.log import (
9
+ ERROR_LOG_BUFFER_LINES,
10
+ set_up_all_logging_handlers,
11
+ )
12
+ from dodal.log import LOGGER as dodal_logger
13
+ from ophyd_async.log import logger as ophyd_async_logger
14
+
15
+ VISIT_PATH = Path("/dls_sw/i24/etc/ssx_current_visit.txt")
16
+
17
+
18
+ class OphydDebugFilter(logging.Filter): # NOTE yet to be fully tested
19
+ """Do not send ophyd debug log messages to stream handler."""
20
+
21
+ def filter(self, record):
22
+ return "ophyd" not in record.getMessage().lower()
23
+
24
+
25
+ # Logging set up
26
+ logger = logging.getLogger("I24ssx")
27
+ logger.addHandler(logging.NullHandler())
28
+ logger.parent = dodal_logger
29
+
30
+ logging_config = {
31
+ "version": 1,
32
+ "disable_existing_loggers": False,
33
+ "filters": {
34
+ "ophyd_filter": {
35
+ "()": OphydDebugFilter,
36
+ }
37
+ },
38
+ "formatters": {
39
+ "default": {
40
+ "class": "logging.Formatter",
41
+ "format": "%(message)s",
42
+ }
43
+ },
44
+ "handlers": {
45
+ "console": {
46
+ "level": "DEBUG",
47
+ "class": "logging.StreamHandler",
48
+ "formatter": "default",
49
+ "filters": ["ophyd_filter"],
50
+ "stream": "ext://sys.stdout",
51
+ }
52
+ },
53
+ "loggers": {
54
+ "I24ssx": {
55
+ "handlers": ["console"],
56
+ "level": "DEBUG",
57
+ "propagate": True,
58
+ }
59
+ },
60
+ }
61
+
62
+ logging.config.dictConfig(logging_config)
63
+
64
+
65
+ def _read_visit_directory_from_file() -> Path:
66
+ with open(VISIT_PATH) as f:
67
+ visit = f.readline().rstrip()
68
+ return Path(visit)
69
+
70
+
71
+ def _get_logging_file_path() -> Path:
72
+ """Get the path to write the artemis log files to.
73
+ If on a beamline, this will be written to the according area depending on the
74
+ BEAMLINE envrionment variable. If no envrionment variable is found it will default
75
+ it to the tmp/dev directory.
76
+ Returns:
77
+ logging_path (Path): Path to the log file for the file handler to write to.
78
+ """
79
+ beamline: str | None = environ.get("BEAMLINE")
80
+ logging_path: Path
81
+
82
+ if beamline:
83
+ logging_path = _read_visit_directory_from_file() / "tmp/serial/logs"
84
+ else:
85
+ logging_path = Path("./tmp/logs/")
86
+
87
+ Path(logging_path).mkdir(parents=True, exist_ok=True)
88
+ return logging_path
89
+
90
+
91
+ def integrate_bluesky_and_ophyd_logging(parent_logger: logging.Logger):
92
+ """Integrate only bluesky and ophyd_async loggers."""
93
+ for logger in [bluesky_logger, ophyd_async_logger]:
94
+ logger.parent = parent_logger
95
+ logger.setLevel(logging.DEBUG)
96
+
97
+
98
+ def default_logging_setup(dev_mode: bool = False):
99
+ """ Default log setup for i24 serial.
100
+
101
+ - Set up handlers for parent logger (from dodal)
102
+ - integrate bluesky and ophyd loggers
103
+ - Remove dodal stream handler to avoid double messages (for now, use only the \
104
+ i24ssx default stream to keep the output expected by the scientists.)
105
+ """
106
+ handlers = set_up_all_logging_handlers( # noqa: F841
107
+ dodal_logger,
108
+ _get_logging_file_path(),
109
+ "dodal.log",
110
+ dev_mode,
111
+ ERROR_LOG_BUFFER_LINES,
112
+ )
113
+ integrate_bluesky_and_ophyd_logging(dodal_logger)
114
+ # Remove dodal StreamHandler to avoid duplication of messages above debug
115
+ dodal_logger.removeHandler(dodal_logger.handlers[0])
116
+
117
+
118
+ def config(
119
+ logfile: str | None = None,
120
+ write_mode: str = "a",
121
+ delayed: bool = False,
122
+ dev_mode: bool = False,
123
+ ):
124
+ """
125
+ Configure the logging.
126
+
127
+ Args:
128
+ logfile (str, optional): Filename for logfile. If passed, create a file handler\
129
+ for the logger to write to file the log output. Defaults to None.
130
+ write_mode (str, optional): String indicating writing mode for the output \
131
+ .log file. Defaults to "a".
132
+ dev_mode (bool, optional): If true, will log to graylog on localhost instead \
133
+ of production. Defaults to False.
134
+ """
135
+ default_logging_setup(dev_mode=dev_mode)
136
+
137
+ if logfile:
138
+ logs = _get_logging_file_path() / logfile
139
+ fileFormatter = logging.Formatter(
140
+ "%(asctime)s %(levelname)s: \t(%(name)s) %(message)s",
141
+ datefmt="%d-%m-%Y %I:%M:%S",
142
+ )
143
+ FH = logging.FileHandler(logs, mode=write_mode, encoding="utf-8", delay=delayed)
144
+ FH.setLevel(logging.DEBUG)
145
+ FH.setFormatter(fileFormatter)
146
+ logger.addHandler(FH)
147
+
148
+
149
+ def log_on_entry(func):
150
+ @functools.wraps(func)
151
+ def decorator(*args, **kwargs):
152
+ name = func.__name__
153
+ logger.debug(f"Running {name} ")
154
+ return func(*args, **kwargs)
155
+
156
+ return decorator
@@ -0,0 +1,15 @@
1
+ from mx_bluesky.i24.serial.parameters.constants import SSXType
2
+ from mx_bluesky.i24.serial.parameters.experiment_parameters import (
3
+ ChipDescription,
4
+ ExtruderParameters,
5
+ FixedTargetParameters,
6
+ )
7
+ from mx_bluesky.i24.serial.parameters.utils import get_chip_format
8
+
9
+ __all__ = [
10
+ "SSXType",
11
+ "ExtruderParameters",
12
+ "ChipDescription",
13
+ "FixedTargetParameters",
14
+ "get_chip_format",
15
+ ]
@@ -0,0 +1,47 @@
1
+ from enum import Enum
2
+ from os import environ
3
+ from pathlib import Path
4
+
5
+ from mx_bluesky.i24.serial.log import _read_visit_directory_from_file
6
+
7
+
8
+ class SSXType(Enum):
9
+ FIXED = "Serial Fixed"
10
+ EXTRUDER = "Serial Jet"
11
+
12
+
13
+ OAV_CONFIG_FILES = {
14
+ "zoom_params_file": "/dls_sw/i24/software/gda_versions/gda_9_34/config/xml/jCameraManZoomLevels.xml",
15
+ "oav_config_json": "/dls_sw/i24/software/daq_configuration/json/OAVCentring.json",
16
+ "display_config": "/dls_sw/i24/software/gda_versions/var/display.configuration",
17
+ }
18
+ OAV1_CAM = "http://bl24i-di-serv-01.diamond.ac.uk:8080/OAV1.mjpg.mjpg"
19
+
20
+ HEADER_FILES_PATH = Path("/dls_sw/i24/scripts/fastchips/").expanduser().resolve()
21
+
22
+ INTERNAL_FILES_PATH = Path(__file__).absolute().parent
23
+
24
+
25
+ def _params_file_location() -> Path:
26
+ beamline: str | None = environ.get("BEAMLINE")
27
+ filepath: Path
28
+
29
+ if beamline:
30
+ filepath = _read_visit_directory_from_file() / "tmp/serial/parameters"
31
+ else:
32
+ filepath = INTERNAL_FILES_PATH
33
+
34
+ filepath.mkdir(parents=True, exist_ok=True)
35
+
36
+ return filepath
37
+
38
+
39
+ PARAM_FILE_NAME = "parameters.json"
40
+ # Paths for rw - these should have been created on startup
41
+ PARAM_FILE_PATH = _params_file_location()
42
+ PARAM_FILE_PATH_FT = PARAM_FILE_PATH / "fixed_target"
43
+ LITEMAP_PATH = PARAM_FILE_PATH_FT / "litemaps"
44
+ FULLMAP_PATH = PARAM_FILE_PATH_FT / "fullmaps"
45
+ # Paths for r only
46
+ PVAR_FILE_PATH = INTERNAL_FILES_PATH / "fixed_target/pvar_files"
47
+ CS_FILES_PATH = INTERNAL_FILES_PATH / "fixed_target/cs"
@@ -0,0 +1,124 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Literal
4
+
5
+ from pydantic import BaseModel, ConfigDict, validator
6
+
7
+ from mx_bluesky.i24.serial.fixed_target.ft_utils import (
8
+ ChipType,
9
+ MappingType,
10
+ PumpProbeSetting,
11
+ )
12
+
13
+
14
+ class SerialExperiment(BaseModel):
15
+ """Generic parameters common to all serial experiments."""
16
+
17
+ visit: Path
18
+ directory: str
19
+ filename: str
20
+ exposure_time_s: float
21
+ detector_distance_mm: float
22
+ detector_name: Literal["eiger", "pilatus"]
23
+
24
+ @validator("visit", pre=True)
25
+ def _parse_visit(cls, visit: str | Path):
26
+ if isinstance(visit, str):
27
+ return Path(visit)
28
+ return visit
29
+
30
+ @property
31
+ def collection_directory(self) -> Path:
32
+ return Path(self.visit) / self.directory
33
+
34
+
35
+ class LaserExperiment(BaseModel):
36
+ """Laser settings for pump probe serial collections."""
37
+
38
+ laser_dwell_s: float | None = None # pump exposure time
39
+ laser_delay_s: float | None = None # pump delay
40
+ pre_pump_exposure_s: float | None = None # Pre illumination, just for chip
41
+
42
+
43
+ class ExtruderParameters(SerialExperiment, LaserExperiment):
44
+ """Extruder parameter model."""
45
+
46
+ num_images: int
47
+ pump_status: bool
48
+
49
+ @classmethod
50
+ def from_file(cls, filename: str | Path):
51
+ with open(filename) as fh:
52
+ raw_params = json.load(fh)
53
+ return cls(**raw_params)
54
+
55
+
56
+ class ChipDescription(BaseModel):
57
+ """Parameters defining the chip in use for FT collection."""
58
+
59
+ model_config = ConfigDict(use_enum_values=True)
60
+
61
+ chip_type: ChipType
62
+ x_num_steps: int
63
+ y_num_steps: int
64
+ x_step_size: float
65
+ y_step_size: float
66
+ x_blocks: int
67
+ y_blocks: int
68
+ b2b_horz: float
69
+ b2b_vert: float
70
+
71
+ @validator("chip_type", pre=True)
72
+ def _parse_chip(cls, chip_type: str | int):
73
+ if isinstance(chip_type, str):
74
+ return ChipType[chip_type]
75
+ else:
76
+ return ChipType(chip_type)
77
+
78
+ @property
79
+ def chip_format(self) -> list[int]:
80
+ return [self.x_blocks, self.y_blocks, self.x_num_steps, self.y_num_steps]
81
+
82
+ @property
83
+ def x_block_size(self) -> float:
84
+ if self.chip_type.name == "Custom":
85
+ return 0.0 # placeholder
86
+ else:
87
+ return ((self.x_num_steps - 1) * self.x_step_size) + self.b2b_horz
88
+
89
+ @property
90
+ def y_block_size(self) -> float:
91
+ if self.chip_type.name == "Custom":
92
+ return 0.0 # placeholder
93
+ else:
94
+ return ((self.y_num_steps - 1) * self.y_step_size) + self.b2b_vert
95
+
96
+
97
+ class FixedTargetParameters(SerialExperiment, LaserExperiment):
98
+ """Fixed target parameter model."""
99
+
100
+ model_config = ConfigDict(use_enum_values=True)
101
+
102
+ num_exposures: int
103
+ chip: ChipDescription
104
+ map_type: MappingType
105
+ pump_repeat: PumpProbeSetting
106
+ checker_pattern: bool = False
107
+ total_num_images: int = 0 # Calculated in the code for now
108
+
109
+ @validator("map_type", pre=True)
110
+ def _parse_map(cls, map_type: str | int):
111
+ if isinstance(map_type, str):
112
+ return MappingType[map_type]
113
+ else:
114
+ return MappingType(map_type)
115
+
116
+ @validator("pump_repeat", pre=True)
117
+ def _parse_pump(cls, pump_repeat: int):
118
+ return PumpProbeSetting(pump_repeat)
119
+
120
+ @classmethod
121
+ def from_file(cls, filename: str | Path):
122
+ with open(filename) as fh:
123
+ raw_params = json.load(fh)
124
+ return cls(**raw_params)
@@ -0,0 +1,9 @@
1
+ {
2
+ "scalex": 10004.0,
3
+ "scaley": 10005.2,
4
+ "scalez": 10000.0,
5
+ "skew": -0.01,
6
+ "Sx_dir": 1,
7
+ "Sy_dir": 1,
8
+ "Sz_dir": 1
9
+ }
@@ -6,5 +6,5 @@
6
6
  # motor number * (dir) = positive chip direction
7
7
 
8
8
  mtr1_dir=1
9
- mtr2_dir=1
9
+ mtr2_dir=-1
10
10
  mtr3_dir=-1
@@ -16,4 +16,4 @@ P3062=1.250 P3063=0.000
16
16
 
17
17
  P3072=2.375 P3073=0.000
18
18
  P3082=2.375 P3083=1.250
19
- P3092=2.375 P3093=2.375
19
+ P3092=2.375 P3093=2.375
@@ -0,0 +1,40 @@
1
+ from typing import Any
2
+
3
+ from mx_bluesky.i24.serial.fixed_target.ft_utils import ChipType
4
+ from mx_bluesky.i24.serial.parameters.experiment_parameters import ChipDescription
5
+ from mx_bluesky.i24.serial.setup_beamline import caget, pv
6
+
7
+
8
+ def get_chip_format(chip_type: ChipType) -> ChipDescription:
9
+ """Default parameter values."""
10
+ defaults: dict[str, int | float] = {}
11
+ match chip_type:
12
+ case ChipType.Oxford:
13
+ defaults["x_num_steps"] = defaults["y_num_steps"] = 20
14
+ defaults["x_step_size"] = defaults["y_step_size"] = 0.125
15
+ defaults["x_blocks"] = defaults["y_blocks"] = 8
16
+ defaults["b2b_horz"] = defaults["b2b_vert"] = 0.800
17
+ case ChipType.OxfordInner:
18
+ defaults["x_num_steps"] = defaults["y_num_steps"] = 25
19
+ defaults["x_step_size"] = defaults["y_step_size"] = 0.600
20
+ defaults["x_blocks"] = defaults["y_blocks"] = 1
21
+ defaults["b2b_horz"] = defaults["b2b_vert"] = 0.0
22
+ case ChipType.Minichip:
23
+ defaults["x_num_steps"] = defaults["y_num_steps"] = 20
24
+ defaults["x_step_size"] = defaults["y_step_size"] = 0.125
25
+ defaults["x_blocks"] = defaults["y_blocks"] = 1
26
+ defaults["b2b_horz"] = defaults["b2b_vert"] = 0.0
27
+ case ChipType.Custom:
28
+ defaults["x_num_steps"] = int(caget(pv.me14e_gp6))
29
+ defaults["y_num_steps"] = int(caget(pv.me14e_gp7))
30
+ defaults["x_step_size"] = float(caget(pv.me14e_gp8))
31
+ defaults["y_step_size"] = float(caget(pv.me14e_gp99))
32
+ defaults["x_blocks"] = defaults["y_blocks"] = 1
33
+ defaults["b2b_horz"] = defaults["b2b_vert"] = 0.0
34
+ case ChipType.MISP:
35
+ defaults["x_num_steps"] = defaults["y_num_steps"] = 78
36
+ defaults["x_step_size"] = defaults["y_step_size"] = 0.1193
37
+ defaults["x_blocks"] = defaults["y_blocks"] = 1
38
+ defaults["b2b_horz"] = defaults["b2b_vert"] = 0.0
39
+ chip_params: dict[str, Any] = {"chip_type": chip_type, **defaults}
40
+ return ChipDescription(**chip_params)
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+
3
+ # Get edm path from input
4
+ edm_path=$1
5
+
6
+ # Get the directory of this script
7
+ current=$( realpath "$( dirname "$0" )" )
8
+
9
+ # Run script to start blueapi serve
10
+ . $current/start_blueapi.sh
11
+
12
+ # Open the edm screen for an extruder serial collection
13
+ echo "Starting extruder edm screen."
14
+ edm -x "${edm_path}/EX-gui/DiamondExtruder-I24-py3v1.edl"
15
+
16
+ echo "Edm screen closed, bye!"
17
+
18
+ pgrep blueapi | xargs kill
19
+ echo "Blueapi process killed"
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+
3
+ # Get edm path from input
4
+ edm_path=$1
5
+
6
+ # Export env variable for the stages edm to work properly
7
+ export EDMDATAFILES="/dls_sw/prod/R3.14.12.3/support/motor/6-7-1dls14/motorApp/opi/edl"
8
+
9
+ # Get the directory of this script
10
+ current=$( realpath "$( dirname "$0" )" )
11
+
12
+ # Run script to start blueapi serve
13
+ . $current/start_blueapi.sh
14
+
15
+ # Open the edm screen for a fixed target serial collection
16
+ echo "Starting fixed target edm screen."
17
+ edm -x "${edm_path}/FT-gui/DiamondChipI24-py3v1.edl"
18
+
19
+ echo "Edm screen closed, bye!"
20
+
21
+ pgrep blueapi | xargs kill
22
+ echo "Blueapi process killed"
@@ -0,0 +1,36 @@
1
+ import logging
2
+ import subprocess
3
+ from os import environ
4
+ from pathlib import Path
5
+
6
+ logger = logging.getLogger("I24ssx.run")
7
+
8
+
9
+ def get_location(default: str = "dev") -> str:
10
+ return environ.get("BEAMLINE") or default
11
+
12
+
13
+ def get_edm_path() -> Path:
14
+ return Path(__file__).parents[4] / "edm_serial"
15
+
16
+
17
+ def _get_file_path() -> Path:
18
+ return Path(__file__).parent
19
+
20
+
21
+ def run_extruder():
22
+ loc = get_location()
23
+ logger.debug(f"Running on {loc}.")
24
+ edm_path = get_edm_path()
25
+ filepath = _get_file_path()
26
+ logger.debug(f"Running {filepath}/run_extruder.sh")
27
+ subprocess.run(["sh", filepath / "run_extruder.sh", edm_path.as_posix()])
28
+
29
+
30
+ def run_fixed_target():
31
+ loc = get_location()
32
+ logger.info(f"Running on {loc}.")
33
+ edm_path = get_edm_path()
34
+ filepath = _get_file_path()
35
+ logger.debug(f"Running {filepath}/run_fixed_target.sh")
36
+ subprocess.run(["sh", filepath / "run_fixed_target.sh", edm_path.as_posix()])
@@ -30,6 +30,11 @@ echo "Reading visit from file: $filename"
30
30
  visit=$(sed -n '1p' $filename)
31
31
  expt_type=${1:-FT}
32
32
 
33
+ # Append a / to the visit if missing to avoid filepaths issues later on
34
+ if [[ "${visit: -1}" != "/" ]]; then
35
+ visit="${visit}/"
36
+ fi
37
+
33
38
  ex_pv=BL24I-EA-IOC-12:GP1
34
39
  ft_pv=ME14E-MO-IOC-01:GP100
35
40
 
@@ -48,4 +53,4 @@ then
48
53
  else
49
54
  echo -e "Unknown experiment type, visit PV not set. \nValid experiment values: fixed-target, extruder."
50
55
  exit 1
51
- fi
56
+ fi
@@ -19,7 +19,7 @@ def __show__(name):
19
19
  def __which__():
20
20
  """Return script directory, used for finding which pv.py you are running"""
21
21
  pathname, scriptname = os.path.split(sys.argv[0])
22
- print(("Current dir: " + os.path.abspath(pathname)))
22
+ print("Current dir: " + os.path.abspath(pathname))
23
23
  print("path to pv.py: ")
24
24
 
25
25
 
@@ -90,60 +90,6 @@ eiger_beamy = "BL24I-EA-EIGER-01:CAM:BeamY"
90
90
  eiger_omegaincr = "BL24I-EA-EIGER-01:CAM:OmegaIncr"
91
91
  eiger_ODfilenameRBV = "BL24I-EA-EIGER-01:OD:FP:FileName_RBV"
92
92
 
93
- # eiger_filenumber = 'BL24I-EA-PILAT-01:cam1:FileNumber'
94
- # eiger_imagemode = 'BL24I-EA-PILAT-01:cam1:ImageMode'
95
- # eiger_filetemplate = 'BL24I-EA-PILAT-01:cam1:FileTemplate'
96
- # eiger_delaytime = 'BL24I-EA-PILAT-01:cam1:DelayTime'
97
- # eiger_filtertrasm = 'BL24I-EA-PILAT-01:cam1:FilterTransm'
98
- # eiger_filetemplate = 'BL24I-EA-PILAT-01:cam1:FileTemplate'
99
- # eiger_startangle = 'BL24I-EA-PILAT-01:cam1:StartAngle'
100
- # eiger_angleincr = 'BL24I-EA-PILAT-01:cam1:AngleIncr'
101
-
102
- # eiger_cbftemplate = 'BL24I-EA-PILAT-01:cam1:CbfTemplateFile'
103
-
104
- # ZEBRA
105
- zebra1_and2_inp1 = "BL24I-EA-ZEBRA-01:AND2_INP1"
106
- zebra1_and2_inp2 = "BL24I-EA-ZEBRA-01:AND2_INP2"
107
- zebra1_and3_inp1 = "BL24I-EA-ZEBRA-01:AND3_INP1"
108
- zebra1_and3_inp2 = "BL24I-EA-ZEBRA-01:AND3_INP2"
109
- zebra1_and4_inp1 = "BL24I-EA-ZEBRA-01:AND4_INP1"
110
- zebra1_and4_inp2 = "BL24I-EA-ZEBRA-01:AND4_INP2"
111
- zebra1_out1_ttl = "BL24I-EA-ZEBRA-01:OUT1_TTL"
112
- zebra1_out2_ttl = "BL24I-EA-ZEBRA-01:OUT2_TTL"
113
- zebra1_out3_ttl = "BL24I-EA-ZEBRA-01:OUT3_TTL"
114
- zebra1_out4_ttl = "BL24I-EA-ZEBRA-01:OUT4_TTL"
115
- zebra1_pc_arm_out = "BL24I-EA-ZEBRA-01:PC_ARM_OUT"
116
- zebra1_pc_arm = "BL24I-EA-ZEBRA-01:PC_ARM"
117
- zebra1_pc_disarm = "BL24I-EA-ZEBRA-01:PC_DISARM"
118
- zebra1_pc_arm_sel = "BL24I-EA-ZEBRA-01:PC_ARM_SEL"
119
- zebra1_pc_gate_sel = "BL24I-EA-ZEBRA-01:PC_GATE_SEL"
120
- zebra1_pc_gate_inp = "BL24I-EA-ZEBRA-01:PC_GATE_INP"
121
- zebra1_pc_gate_start = "BL24I-EA-ZEBRA-01:PC_GATE_START"
122
- zebra1_pc_gate_width = "BL24I-EA-ZEBRA-01:PC_GATE_WID"
123
- zebra1_pc_gate_step = "BL24I-EA-ZEBRA-01:PC_GATE_STEP"
124
- zebra1_pc_gate_ngate = "BL24I-EA-ZEBRA-01:PC_GATE_NGATE"
125
- zebra1_pc_pulse_sel = "BL24I-EA-ZEBRA-01:PC_PULSE_SEL"
126
- zebra1_pc_pulse_inp = "BL24I-EA-ZEBRA-01:PC_PULSE_INP"
127
- zebra1_pc_pulse_start = "BL24I-EA-ZEBRA-01:PC_PULSE_START"
128
- zebra1_pc_pulse_width = "BL24I-EA-ZEBRA-01:PC_PULSE_WID"
129
- zebra1_pc_pulse_step = "BL24I-EA-ZEBRA-01:PC_PULSE_STEP"
130
- zebra1_pc_pulse_max = "BL24I-EA-ZEBRA-01:PC_PULSE_MAX"
131
- zebra1_soft_in_b0 = "BL24I-EA-ZEBRA-01:SOFT_IN:B0"
132
- zebra1_soft_in_b1 = "BL24I-EA-ZEBRA-01:SOFT_IN:B1"
133
- zebra1_soft_in_b2 = "BL24I-EA-ZEBRA-01:SOFT_IN:B2"
134
- zebra1_soft_in_b3 = "BL24I-EA-ZEBRA-01:SOFT_IN:B3"
135
- zebra1_pc_enc = "BL24I-EA-ZEBRA-01:PC_ENC"
136
- zebra1_pc_dir = "BL24I-EA-ZEBRA-01:PC_DIR"
137
- zebra1_reset_proc = "BL24I-EA-ZEBRA-01:SYS_RESET.PROC"
138
- zebra1_config_read_proc = "BL24I-EA-ZEBRA-01:CONFIG_READ.PROC"
139
- zebra1_or1_ena_b0 = "BL24I-EA-ZEBRA-01:OR1_ENA:B0"
140
- zebra1_pulse1_inp = "BL24I-EA-ZEBRA-01:PULSE1_INP"
141
- zebra1_pulse1_delay = "BL24I-EA-ZEBRA-01:PULSE1_DLY"
142
- zebra1_pulse1_width = "BL24I-EA-ZEBRA-01:PULSE1_WID"
143
- zebra1_pulse2_inp = "BL24I-EA-ZEBRA-01:PULSE2_INP"
144
- zebra1_pulse2_delay = "BL24I-EA-ZEBRA-01:PULSE2_DLY"
145
- zebra1_pulse2_width = "BL24I-EA-ZEBRA-01:PULSE2_WID"
146
-
147
93
  # BPMs
148
94
  qbpm1_inten = "BL24I-DI-QBPM-01:INTEN"
149
95
  qbpm1_intenN = "BL24I-DI-QBPM-01:INTEN_N"
@@ -209,13 +155,6 @@ dcm_pitch2 = "BL24I-MO-DCM-01:XTAL2:PITCH"
209
155
  dcm_lambda = "BL24I-MO-DCM-01:LAMBDA"
210
156
  dcm_energy = "BL24I-MO-DCM-01:ENERGY"
211
157
 
212
- # OLD Mono. Left for short term reference only 10Nov21
213
- # dcm_bragg = 'BL24I-OP-DCM-01:BRAGG'
214
- # dcm_t2 = 'BL24I-OP-DCM-01:T2'
215
- # dcm_roll1 = 'BL24I-OP-DCM-01:ROLL1'
216
- # dcm_pitch2 = 'BL24I-OP-DCM-01:PITCH2'
217
- # dcm_lambda = 'BL24I-OP-DCM-01:LAMBDA'
218
- # dcm_energy = 'BL24I-OP-DCM-01:ENERGY'
219
158
  # S2
220
159
  s2_x_plus = "BL24I-AL-SLITS-02:X:PLUS"
221
160
  s2_x_minus = "BL24I-AL-SLITS-02:X:MINUS"
@@ -4,11 +4,8 @@ Cleaner abstractions of the PV table.
4
4
  Takes the PV tables from I24's setup_beamline and wraps a slightly more
5
5
  abstract wrapper around them.
6
6
  """
7
- from __future__ import annotations
8
7
 
9
- from typing import Union
10
-
11
- from mx_bluesky.I24.serial.setup_beamline import pv
8
+ from mx_bluesky.i24.serial.setup_beamline import pv
12
9
 
13
10
 
14
11
  class Pilatus:
@@ -19,7 +16,7 @@ class Pilatus:
19
16
  image_size_pixels = (2463, 2527)
20
17
  pixel_size_mm = (0.172, 0.172)
21
18
  image_size_mm = tuple(
22
- round(a * b, 3) for a, b in zip(image_size_pixels, pixel_size_mm)
19
+ round(a * b, 3) for a, b in zip(image_size_pixels, pixel_size_mm, strict=False)
23
20
  )
24
21
 
25
22
  det_y_threshold = 560.0
@@ -48,7 +45,7 @@ class Eiger:
48
45
  image_size_pixels = (3108, 3262)
49
46
 
50
47
  image_size_mm = tuple(
51
- round(a * b, 3) for a, b in zip(image_size_pixels, pixel_size_mm)
48
+ round(a * b, 3) for a, b in zip(image_size_pixels, pixel_size_mm, strict=False)
52
49
  )
53
50
 
54
51
  det_y_threshold = -10.0
@@ -58,15 +55,17 @@ class Eiger:
58
55
  detector_distance = pv.eiger_detdist
59
56
  wavelength = pv.eiger_wavelength
60
57
  transmission = "BL24I-EA-PILAT-01:cam1:FilterTransm"
58
+ filenameRBV = pv.eiger_ODfilenameRBV
61
59
  file_name = pv.eiger_ODfilename
62
60
  file_path = pv.eiger_ODfilepath
63
61
  file_template = None
64
62
  sequence_id = pv.eiger_seqID
65
63
  beamx = pv.eiger_beamx
66
64
  beamy = pv.eiger_beamy
65
+ bit_depth = pv.eiger_bitdepthrbv
67
66
 
68
67
  def __str__(self) -> str:
69
68
  return self.name
70
69
 
71
70
 
72
- Detector = Union[Pilatus, Eiger]
71
+ Detector = Pilatus | Eiger