From b5dec979ef4993ad521c620822bc1c5a3961c557 Mon Sep 17 00:00:00 2001 From: Nicholas Devenish Date: Wed, 26 Jul 2023 16:35:29 +0100 Subject: [PATCH] Handle PETRA P14 changing detector The E-32-0017 Eiger moved to P13 on 2021-5-22, where the goniometer axis no longer needs overriding. Check for that date in the MiniCBF, and check for the serial matching the date range. --- src/dxtbx/format/FormatCBFMini.py | 15 ++++++++ .../format/FormatCBFMiniEigerPetraP13.py | 38 ------------------- .../format/FormatCBFMiniEigerPetraP14.py | 13 ++++++- 3 files changed, 27 insertions(+), 39 deletions(-) delete mode 100644 src/dxtbx/format/FormatCBFMiniEigerPetraP13.py diff --git a/src/dxtbx/format/FormatCBFMini.py b/src/dxtbx/format/FormatCBFMini.py index 4561665fd..39060f84a 100644 --- a/src/dxtbx/format/FormatCBFMini.py +++ b/src/dxtbx/format/FormatCBFMini.py @@ -8,6 +8,7 @@ from __future__ import annotations import binascii +import datetime import os import pathlib import sys @@ -73,6 +74,20 @@ def __init__(self, image_file, **kwargs): self._raw_data = None super().__init__(image_file, **kwargs) + @staticmethod + def _get_timestamp_from_raw_header( + header: str | list[str], + ) -> datetime.datetime | None: + """Given a raw header, or lines from, attempt to extract the timestamp field""" + if isinstance(header, str): + header = header.splitlines() + timestamp = None + for record in header: + if len(record[1:].split()) <= 2 and record.count(":") == 2: + timestamp = datetime.datetime.fromisoformat(record[1:].strip()) + break + return timestamp + def _start(self): """Open the image file, read the image header, copy it into a dictionary for future reference.""" diff --git a/src/dxtbx/format/FormatCBFMiniEigerPetraP13.py b/src/dxtbx/format/FormatCBFMiniEigerPetraP13.py deleted file mode 100644 index d385435a0..000000000 --- a/src/dxtbx/format/FormatCBFMiniEigerPetraP13.py +++ /dev/null @@ -1,38 +0,0 @@ -"""An implementation of the CBF image reader for Eiger images""" - - -from __future__ import annotations - -import sys - -from dxtbx.format.FormatCBFMiniEiger import FormatCBFMiniEiger - - -class FormatCBFMiniEigerPetraP13(FormatCBFMiniEiger): - """A class for reading mini CBF format Eiger images, and correctly - constructing a model for the experiment from this. This tuned for Petra P13""" - - @staticmethod - def understand(image_file): - """Check to see if this looks like an Eiger mini CBF format image, - i.e. we can make sense of it.""" - - header = FormatCBFMiniEiger.get_cbf_header(image_file) - - for record in header.split("\n"): - if ( - "# detector" in record.lower() - and "eiger" in record.lower() - and "E-32-0107" in record - ): - return True - - return False - - def _goniometer(self): - return self._goniometer_factory.known_axis((1, 0, 0)) - - -if __name__ == "__main__": - for arg in sys.argv[1:]: - print(FormatCBFMiniEigerPetraP13.understand(arg)) diff --git a/src/dxtbx/format/FormatCBFMiniEigerPetraP14.py b/src/dxtbx/format/FormatCBFMiniEigerPetraP14.py index 15de04c1d..c6d60d02f 100644 --- a/src/dxtbx/format/FormatCBFMiniEigerPetraP14.py +++ b/src/dxtbx/format/FormatCBFMiniEigerPetraP14.py @@ -3,6 +3,7 @@ from __future__ import annotations +import datetime import sys from dxtbx.format.FormatCBFMiniEiger import FormatCBFMiniEiger @@ -19,11 +20,21 @@ def understand(image_file): header = FormatCBFMiniEiger.get_cbf_header(image_file) + # Valid from 22nd May 2021 + expected_serial = "E-32-0129" + if timestamp := FormatCBFMiniEiger._get_timestamp_from_raw_header(header): + # We have a timestamp. Let's see what detector we should expect + + # Before 22nd May 2021 + if timestamp < datetime.datetime(2021, 5, 22): + expected_serial = "E-32-017" + + # Find the line recording detector serial, and check for record in header.split("\n"): if ( "# detector" in record.lower() and "eiger" in record.lower() - and "E-32-0129" in record + and expected_serial in record ): return True