Source code for freesas.sasio

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#    Project: FreeSAS
#             https://github.com/kif/freesas
#
#    Copyright (C) European Synchrotron Radiation Facility, Grenoble, France
#
#    Principal author:       Jérôme Kieffer (Jerome.Kieffer@ESRF.eu)
#

"""
Contains helper functions for loading SAS data from differents sources.
"""
__authors__ = ["Martha Brennich"]
__contact__ = "martha.brennich@googlemail.com"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
__date__ = "19/09/2022"
__status__ = "development"
__docformat__ = "restructuredtext"

import io
from typing import List, Union
from os import PathLike
from numpy import loadtxt, array, ndarray

PathType = Union[PathLike, str, bytes, io.StringIO, io.BytesIO]


[docs] def load_scattering_data(filename: PathType) -> ndarray: """ Load scattering data q, I, err into a numpy array. :param filename: ASCII file, 3 column (q,I,err) :return: numpy array with 3 column (q,I,err) """ try: data = loadtxt(filename) except OSError as err: raise OSError("File could not be read.") except ValueError as err: text = None if isinstance(filename, (io.StringIO, io.BytesIO)): filename.seek(0) text = filename.readlines() else: try: with open(filename) as data_file: text = data_file.readlines() except OSError: raise OSError("File could not be read.") if text is not None: try: data = parse_ascii_data(text, number_of_columns=3) except ValueError: raise ValueError( "File does not seem to be " "in the format q, I, err. " ) return data
[docs] def parse_ascii_data( input_file_text: List[str], number_of_columns: int ) -> ndarray: """ Parse data from an ascii file into an N column numpy array :param input_file_text: List containing one line of input data per element :param number_of_columns: Expected number of lines in the data file :return: numpy array with 3 column (q,I,err) """ data = [] for line in input_file_text: split = line.split() if len(split) == number_of_columns: try: data.append([float(x) for x in split]) except ValueError as err: if "could not convert string to float" in err.args[0]: pass else: raise if data == []: raise ValueError return array(data)
[docs] def convert_inverse_angstrom_to_nanometer( data_in_inverse_angstrom: ndarray, ) -> ndarray: """ Convert data with q in 1/Å to 1/nm. :param data_in_inverse_angstrom: numpy array in format (q_in_inverse_Angstrom,I,err) :return: numpy array with 3 column (q_in_inverse_nm,I,err) """ q_in_angstrom, intensity, err = data_in_inverse_angstrom.T return array([q_in_angstrom * 10.0, intensity, err]).T