source: sasview/src/sas/sascalc/file_converter/ascii2d_loader.py @ f25328a5

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 f25328a5 was f25328a5, checked in by lewis, 7 years ago

Better error messages when 2D ASCII file is incorrectly formatted

  • Property mode set to 100644
File size: 4.3 KB
Line 
1"""
2ASCII 2D Loader
3"""
4from sas.sascalc.dataloader.data_info import Data2D
5from sas.sascalc.file_converter.nxcansas_writer import NXcanSASWriter
6import numpy as np
7
8# ISIS 2D ASCII File Format
9# line: property
10# 0: File header
11# 1: q_x axis label and units
12# 2: q_y axis label and units
13# 3: Intensity axis label and units
14# 4: nUseRec - number of lines of user content following this line
15# 5 - 5+nUseRec: user content
16# Number of qx points
17# List of qx points
18# Number of qy points
19# List of qy points
20# numqx numqy scale
21
22class ASCII2DLoader(object):
23
24    def __init__(self, data_path):
25        self.data_path = data_path
26
27    def load(self):
28        file_handle = open(self.data_path, 'r')
29        file_buffer = file_handle.read()
30        all_lines = file_buffer.splitlines()
31
32        def _load_qs(lines, start_line, num_points):
33            qs = np.zeros(num_points)
34            n = start_line
35            filled = 0
36            while filled < num_points:
37                row = np.fromstring(lines[n], dtype=np.float32, sep=' ')
38                qs[filled:filled+len(row)] = row
39                filled += len(row)
40                n += 1
41            return n, qs
42
43        # Skip nUseRec lines
44        current_line = 4
45        try:
46            nUseRec = int(all_lines[current_line].strip()[0])
47            current_line += nUseRec + 1
48            # Read qx data
49            num_qs = int(all_lines[current_line].strip())
50            current_line += 1
51            current_line, qx = _load_qs(all_lines, current_line, num_qs)
52
53            # Read qy data
54            num_qs = int(all_lines[current_line].strip())
55            current_line += 1
56            current_line, qy = _load_qs(all_lines, current_line, num_qs)
57        except ValueError as e:
58            err_msg = "File incorrectly formatted.\n"
59            if str(e).find('broadcast') != -1:
60                err_msg += "Incorrect number of q data points provided. "
61                err_msg += "Expected {}.".format(num_qs)
62            elif str(e).find('invalid literal') != -1:
63                err_msg += "Expected integer on line {}. Instead got '{}'".format(current_line + 1,
64                    all_lines[current_line])
65            else:
66                err_msg += str(e)
67            raise ValueError(err_msg)
68
69        # dimensions: [width, height, scale]
70        try:
71            dimensions = np.fromstring(all_lines[current_line], dtype=np.float32, sep=' ')
72            if len(dimensions) != 3: raise ValueError()
73            width = int(dimensions[0])
74            height = int(dimensions[1])
75        except ValueError as e:
76            err_msg = "File incorrectly formatted.\n"
77            err_msg += "Expected line {} to be of the form: <num_qx> <num_qy> <scale>.".format(current_line + 1)
78            err_msg += " Instead got '{}'.".format(all_lines[current_line])
79            raise ValueError(err_msg)
80
81        if width > len(qx) or height > len(qy):
82            err_msg = "File incorrectly formatted.\n"
83            err_msg += ("Line {} says to use {}x{} points. "
84                "Only {}x{} provided.").format(current_line + 1, width, height,
85                len(qx), len(qy))
86            raise ValueError(err_msg)
87
88        # More qx and/or qy points can be provided than are actually used
89        qx = qx[:width]
90        qy = qy[:height]
91
92        current_line += 1
93        # iflag = 1 => Only intensity data (not dealt with here)
94        # iflag = 2 => q axis and intensity data
95        # iflag = 3 => q axis, intensity and error data
96        try:
97            iflag = int(all_lines[current_line].strip()[0])
98            if iflag <= 0 or iflag > 3: raise ValueError()
99        except:
100            err_msg = "File incorrectly formatted.\n"
101            iflag = all_lines[current_line].strip()[0]
102            err_msg += "Expected iflag on line {} to be 1, 2 or 3. Instead got '{}'.".format(current_line+1, iflag)
103            raise ValueError(err_msg)
104
105        current_line += 1
106
107        current_line, I = _load_qs(all_lines, current_line, width*height)
108        dI = np.zeros(width*height)
109
110        if iflag == 3:
111            _, dI = _load_qs(all_lines, current_line, width*height)
112
113        # Format data for use with Data2D
114        qx = list(qx) * height
115        qy = np.array([[y] * width for y in qy]).flatten()
116
117        data = Data2D(qx_data=qx, qy_data=qy, data=I, err_data=dI)
118
119        return data
Note: See TracBrowser for help on using the repository browser.