Source code for ewoksid14.tasks.io

import os
import datetime
import numbers
from itertools import zip_longest
from typing import Sequence, Optional, Dict, Union


[docs] def mca_data_to_spec_string( mca: Sequence[float], title: Optional[str] = None, filename: Optional[str] = None, date: Optional[Union[str, datetime.datetime, datetime.date]] = None, calibration: Optional[Sequence[float]] = None, detector_name: Optional[str] = None, metadata: Optional[Dict] = None, ) -> str: """Official file format specs: https://certif.com/downloads/css_docs/spec_man.pdf :param mca: MCA spectrum :param title: scan title :param filename: name by which the file will be created :param date: start date of the scan :param calibration: MCA calibration as the sequence [zero, gain, quad], all of them optional so that energy = zero + gain*channels + quad*channels^2 :param detector_name: name of the MCA detector :param metadata: saved as comments :returns: SPEC serialized string """ nchan_per_line = 16 nchan_tot = len(mca) if title is None: title = "ct" if filename is None: filename = "unspecified" if detector_name is None: detector_name = "MCA0" if date is None: date = datetime.datetime.now() calib = [0, 1, 0] # zero, gain, quad if calibration: if len(calibration) > 3: raise ValueError("MCA calibration requires 3 only coefficients") calib = [ p if p is not None else pdefault for p, pdefault in zip_longest(calibration, calib) ] header = [f"#F {filename}", f"#D {date}", "", f"#S {title}", f"#D {date}"] if metadata: for k, v in metadata.items(): header.append(f"#C {k} = {v}") header.append("#N 1") header.append(f"#@MCA {nchan_per_line}C") header.append(f"#@CHANN {nchan_tot} 0 {nchan_tot-1} 1") header.append(f"#@CALIB {' '.join(map(str, calib))}") header.append("#@MCA_NB 1") header.append(f"#L {detector_name}") mcastring = "\n".join(header) mcastring += "\n@A" if isinstance(mca[0], numbers.Integral): fmt = " %d" else: # fmt = " %.4f" fmt = " %.8g" for idx in range(0, nchan_tot, nchan_per_line): if idx + nchan_per_line - 1 < nchan_tot: for i in range(0, nchan_per_line): mcastring += fmt % mca[idx + i] if idx + nchan_per_line != nchan_tot: mcastring += "\\" else: for i in range(idx, nchan_tot): mcastring += fmt % mca[i] mcastring += "\n" return mcastring
[docs] def save_as_spec(filename, mca: Sequence[float], **kwargs) -> None: dirname = os.path.dirname(filename) if dirname: os.makedirs(dirname, exist_ok=True) content = mca_data_to_spec_string(mca, filename=filename, **kwargs) with open(filename, "w") as f: f.write(content)