Source code for mantidimaging.core.io.instrument_log_implmentations

# Copyright (C) 2024 ISIS Rutherford Appleton Laboratory UKRI
# SPDX - License - Identifier: GPL-3.0-or-later
from __future__ import annotations

import csv
import locale
from datetime import datetime
from pathlib import Path

from mantidimaging.core.io.instrument_log import (InstrumentLogParser, LogColumn, LogDataType)
from mantidimaging.core.utility.imat_log_file_parser import IMATLogFile, IMATLogColumn


[docs] class LegacySpectraLogParser(InstrumentLogParser): """ Parser for spectra files without a header Tab separated columns of Time of flight [s], Counts """ delimiter = '\t'
[docs] @classmethod def match(cls, lines: list[str], filename: str) -> bool: if not filename.lower().endswith("spectra.txt"): return False for line in lines[:2]: if not len(line.split(cls.delimiter)) == 2: return False return True
[docs] def parse(self) -> LogDataType: data: LogDataType = {LogColumn.TIME_OF_FLIGHT: [], LogColumn.SPECTRUM_COUNTS: []} for row in csv.reader(self.cleaned_lines(), delimiter=self.delimiter): data[LogColumn.TIME_OF_FLIGHT].append(float(row[0])) data[LogColumn.SPECTRUM_COUNTS].append(int(row[1])) return data
[docs] class LegacyIMATLogFile(InstrumentLogParser): """Wrap existing IMATLogFile class"""
[docs] @classmethod def match(cls, lines: list[str], filename: str) -> bool: if filename.lower()[-4:] not in [".txt", ".csv"]: return False has_header = False for line in lines: if not has_header and cls._has_imat_header(line): has_header = True elif has_header and cls._has_imat_data_line(line): return True return False
[docs] def parse(self) -> LogDataType: imat_log_file = IMATLogFile(self.lines, Path("")) data: LogDataType = {} data[LogColumn.TIMESTAMP] = imat_log_file._data[IMATLogColumn.TIMESTAMP] data[LogColumn.PROJECTION_NUMBER] = imat_log_file._data[IMATLogColumn.PROJECTION_NUMBER] data[LogColumn.PROJECTION_ANGLE] = imat_log_file._data[IMATLogColumn.PROJECTION_ANGLE] data[LogColumn.COUNTS_BEFORE] = imat_log_file._data[IMATLogColumn.COUNTS_BEFORE] data[LogColumn.COUNTS_AFTER] = imat_log_file._data[IMATLogColumn.COUNTS_AFTER] return data
[docs] @staticmethod def read_imat_date(time_stamp: str) -> datetime: lc = locale.setlocale(locale.LC_TIME) try: locale.setlocale(locale.LC_TIME, "C") return datetime.strptime(time_stamp, "%c") finally: locale.setlocale(locale.LC_TIME, lc)
@staticmethod def _has_imat_header(line: str): HEADERS = [ "TIME STAMP,IMAGE TYPE,IMAGE COUNTER,COUNTS BM3 before image,COUNTS BM3 after image", "TIME STAMP IMAGE TYPE IMAGE COUNTER COUNTS BM3 before image COUNTS BM3 after image", ] return line.strip() in HEADERS @classmethod def _has_imat_data_line(cls, line: str): try: _ = cls.read_imat_date(line[:24]) except ValueError: return False if not ("Projection" in line or "Radiography" in line): return False return True