source: sasview/src/sas/sascalc/dataloader/readers/sesans_reader.py @ 0ac6e11

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 0ac6e11 was 0ac6e11, checked in by Adam Washington <adam.washington@…>, 7 years ago

Start fixing sesans smearing for time of flight

  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[5e326a6]1"""
[edfc8ac]2    SESANS reader (based on ASCII reader)
[ecc8d1a8]3
[edfc8ac]4    Reader for .ses or .sesans file format
[ecc8d1a8]5
6    Jurrian Bakker
[5e326a6]7"""
[0ac6e11]8import logging
[e935ddb1]9import numpy as np
[5e326a6]10import os
[b5db35d]11from sas.sascalc.dataloader.data_info import Data1D
[5e326a6]12
13# Check whether we have a converter available
14has_converter = True
15try:
[b699768]16    from sas.sascalc.data_util.nxsunit import Converter
[5e326a6]17except:
18    has_converter = False
19_ZERO = 1e-16
20
[def97a0]21
[5e326a6]22class Reader:
23    """
24    Class to load sesans files (6 columns).
25    """
[def97a0]26    # File type
[5e326a6]27    type_name = "SESANS"
[ecc8d1a8]28
[def97a0]29    # Wildcards
[5e326a6]30    type = ["SESANS files (*.ses)|*.ses",
31            "SESANS files (*..sesans)|*.sesans"]
[def97a0]32    # List of allowed extensions
[5e326a6]33    ext = ['.ses', '.SES', '.sesans', '.SESANS']
[ecc8d1a8]34
[def97a0]35    # Flag to bypass extension check
[5e326a6]36    allow_all = True
[ecc8d1a8]37
[5e326a6]38    def read(self, path):
39        """
40        Load data file
[ecc8d1a8]41
[5e326a6]42        :param path: file path
[ecc8d1a8]43
[5e326a6]44        :return: SESANSData1D object, or None
[ecc8d1a8]45
[5e326a6]46        :raise RuntimeError: when the file can't be opened
47        :raise ValueError: when the length of the data vectors are inconsistent
48        """
49        if os.path.isfile(path):
50            basename = os.path.basename(path)
51            _, extension = os.path.splitext(basename)
[cb9feea8]52            if not (self.allow_all or extension.lower() in self.ext):
53                raise RuntimeError("{} has an unrecognized file extension".format(path))
[5e326a6]54        else:
[cb9feea8]55            raise RunetimeError("{} is not a file".format(path))
56        with open(path, 'r') as input_f:
57            # Read in binary mode since GRASP frequently has no-ascii
58            # characters that brakes the open operation
59            line = input_f.readline()
60            params = {}
[2b310602]61            while not line.startswith("BEGIN_DATA"):
62                terms = line.split()
63                if len(terms) >= 2:
64                    params[terms[0]] = " ".join(terms[1:])
[cb9feea8]65                line = input_f.readline()
[2b310602]66            self.params = params
67            headers = input_f.readline().split()
68
[cb9feea8]69            data = np.loadtxt(input_f)
70            if data.size < 1:
71                raise RuntimeError("{} is empty".format(path))
[2b310602]72            x = data[:, headers.index("SpinEchoLength")]
73            dx = data[:, headers.index("SpinEchoLength_error")]
74            lam = data[:, headers.index("Wavelength")]
75            dlam = data[:, headers.index("Wavelength_error")]
76            y = data[:, headers.index("Depolarisation")]
77            dy = data[:, headers.index("Depolarisation_error")]
78
79            lam_unit = self._unit_fetch("Wavelength")
80            x, x_unit = self._unit_conversion(x, "A", self._unit_fetch("SpinEchoLength"))
[cb9feea8]81            dx, dx_unit = self._unit_conversion(
82                dx, lam_unit,
[2b310602]83                self._unit_fetch("SpinEchoLength"))
[cb9feea8]84            dlam, dlam_unit = self._unit_conversion(
85                dlam, lam_unit,
[2b310602]86                self._unit_fetch("Wavelength"))
87            y_unit = self._unit_fetch("Depolarisation")
[cb9feea8]88
89            output = Data1D(x=x, y=y, lam=lam, dy=dy, dx=dx, dlam=dlam,
90                            isSesans=True)
[2b310602]91
92            output.y_unit = y_unit
93            output.x_unit = x_unit
[0ac6e11]94            output.source.wavelength_unit = lam_unit
95            output.source.wavelength = lam
[cb9feea8]96            self.filename = output.filename = basename
97            output.xaxis(r"\rm{z}", x_unit)
98            # Adjust label to ln P/(lam^2 t), remove lam column refs
99            output.yaxis(r"\rm{ln(P)/(t \lambda^2)}", y_unit)
100            # Store loading process information
101            output.meta_data['loader'] = self.type_name
102            output.sample.name = params["Sample"]
103            output.sample.ID = params["DataFileTitle"]
[2b310602]104            output.sample.thickness = float(
105                self._unit_conversion(
106                    params["Thickness"], "cm", self._unit_fetch("Thickness"))[0])
[cb9feea8]107
108            output.sample.zacceptance = (
[2b310602]109                float(params["Theta_zmax"]),
110                self._unit_fetch("Theta_zmax"))
[cb9feea8]111
112            output.sample.yacceptance = (
[2b310602]113                float(params["Theta_ymax"]),
114                self._unit_fetch("Theta_ymax"))
[cb9feea8]115            return output
[26d4864]116
[2d866370]117    @staticmethod
118    def _unit_conversion(value, value_unit, default_unit):
[09a0be5]119        """
120        Performs unit conversion on a measurement.
121
122        :param value: The magnitude of the measurement
123        :param value_unit: a string containing the final desired unit
124        :param default_unit: a string containing the units of the original measurement
125        :return: The magnitude of the measurement in the new units
126        """
[bc6532e]127        # (float, string, string) -> float
[def97a0]128        if has_converter and value_unit != default_unit:
[26d4864]129            data_conv_q = Converter(value_unit)
130            value = data_conv_q(value, units=default_unit)
131            new_unit = default_unit
132        else:
133            new_unit = value_unit
[e935ddb1]134        return value, new_unit
135
[2b310602]136    def _unit_fetch(self, unit):
137        return self.params[unit+"_unit"]
Note: See TracBrowser for help on using the repository browser.