source: sasview/src/sas/sascalc/file_converter/convert_bsl_thread.py @ 35488b2

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.1.1release-4.1.2release-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 35488b2 was 35488b2, checked in by lewis, 6 years ago

Perform BSL file conversion on a separate thread

  • Property mode set to 100644
File size: 5.0 KB
Line 
1import os
2import wx
3from sas.sascalc.data_util.calcthread import CalcThread
4from sas.sascalc.dataloader.data_info import Data2D
5from sas.sascalc.file_converter.bsl_loader import BSLLoader
6from sas.sascalc.dataloader.readers.red2d_reader import Reader as Red2DWriter
7
8class ConvertBSLThread(CalcThread):
9
10    def __init__(self, parent, in_file, out_file,
11        updatefn=None, completefn=None):
12        CalcThread.__init__(self, updatefn=updatefn, completefn=completefn)
13        self.parent = parent
14        self.in_file = in_file
15        self.out_file = out_file
16
17    def compute(self):
18        self.ready(delay=0.0)
19        self.update(msg="Extracting data...")
20
21        try:
22            x, y, frame_data = self._extract_bsl_data(self.in_file)
23        except Exception as e:
24            self.ready()
25            self.update(exception=e)
26            self.complete(success=False)
27            return
28
29        if x == None and y == None and frame_data == None:
30            # Cancelled by user
31            self.ready()
32            self.update(msg="Conversion cancelled")
33            self.complete(success=False)
34            return
35
36        if self.isquit():
37            self.complete(success=False)
38            return
39
40        self.ready(delay=0.0)
41        self.update(msg="Exporting data...")
42
43        try:
44            completed = self._convert_to_red2d(self.out_file, x, y, frame_data)
45        except Exception as e:
46            self.ready()
47            self.update(exception=e)
48            self.complete(success=False)
49            return
50
51        self.complete(success=completed)
52
53
54    def _extract_bsl_data(self, filename):
55        """
56        Extracts data from a 2D BSL file
57
58        :param filename: The header file to extract the data from
59        :return x_data: A 1D array containing all the x coordinates of the data
60        :return y_data: A 1D array containing all the y coordinates of the data
61        :return frame_data: A dictionary of the form frame_number: data, where
62        data is a 2D numpy array containing the intensity data
63        """
64        loader = BSLLoader(filename)
65        frames = [0]
66        should_continue = True
67
68        if loader.n_frames > 1:
69            params = self.parent.ask_frame_range(loader.n_frames)
70            frames = params['frames']
71        elif loader.n_rasters == 1 and loader.n_frames == 1:
72            message = ("The selected file is an OTOKO file. Please select the "
73            "'OTOKO 1D' option if you wish to convert it.")
74            dlg = wx.MessageDialog(self.parent,
75            message,
76            'Error!',
77            wx.OK | wx.ICON_WARNING)
78            dlg.ShowModal()
79            should_continue = False
80            dlg.Destroy()
81        else:
82            message = ("The selected data file only has 1 frame, it might be"
83                " a multi-frame OTOKO file.\nContinue conversion?")
84            dlg = wx.MessageDialog(self.parent,
85            message,
86            'Warning!',
87            wx.YES_NO | wx.ICON_WARNING)
88            should_continue = (dlg.ShowModal() == wx.ID_YES)
89            dlg.Destroy()
90
91        if not should_continue:
92            return None, None, None
93
94        frame_data = {}
95
96        for frame in frames:
97            loader.frame = frame
98            frame_data[frame] = loader.load_data()
99
100        # TODO: Tidy this up
101        # Prepare axes values (arbitrary scale)
102        x_data = []
103        y_data = range(loader.n_pixels) * loader.n_rasters
104        for i in range(loader.n_rasters):
105            x_data += [i] * loader.n_pixels
106
107        return x_data, y_data, frame_data
108
109    def _convert_to_red2d(self, filepath, x, y, frame_data):
110        """
111        Writes Data2D objects to Red2D .dat files. If more than one frame is
112        provided, the frame number will be appended to the filename of each
113        file written.
114
115        :param filepath: The filepath to write to
116        :param x: The x column of the data
117        :param y: The y column of the data
118        :param frame_data: A dictionary of the form frame_number: data, where
119        data is a 2D numpy array containing the intensity data
120
121        :return: True if export completed, False if export cancelled by user
122        """
123        filename = os.path.split(filepath)[-1]
124        filepath = os.path.split(filepath)[0]
125        writer = Red2DWriter()
126
127        for i, frame in frame_data.iteritems():
128            # If more than 1 frame is being exported, append the frame
129            # number to the filename
130            if self.isquit():
131                return False
132
133            if len(frame_data) > 1:
134                frame_filename = filename.split('.')
135                frame_filename[0] += str(i+1)
136                frame_filename = '.'.join(frame_filename)
137            else:
138                frame_filename = filename
139
140            data_i = frame.reshape((len(x),1))
141            data_info = Data2D(data=data_i, qx_data=x, qy_data=y)
142            writer.write(os.path.join(filepath, frame_filename), data_info)
143            self.ready()
144            self.update(msg="Written file: {}".format(frame_filename))
145
146        return True
Note: See TracBrowser for help on using the repository browser.