Changeset 0b1a677 in sasview for src


Ignore:
Timestamp:
Aug 10, 2016 5:38:37 AM (8 years ago)
Author:
lewis
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
18544f8
Parents:
35488b2
Message:

Only perform writing on separate thread

Also move reader/writer classes to sascalc

Location:
src/sas
Files:
1 added
2 edited
2 moved

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/file_converter/convert_bsl_thread.py

    r35488b2 r0b1a677  
    33from sas.sascalc.data_util.calcthread import CalcThread 
    44from sas.sascalc.dataloader.data_info import Data2D 
    5 from sas.sascalc.file_converter.bsl_loader import BSLLoader 
    6 from sas.sascalc.dataloader.readers.red2d_reader import Reader as Red2DWriter 
     5from sas.sascalc.file_converter.red2d_writer import Red2DWriter 
     6 
     7import sys 
     8 
     9if sys.platform.count("darwin") > 0: 
     10    import time 
     11    stime = time.time() 
     12 
     13    def clock(): 
     14        return time.time() - stime 
     15 
     16    def sleep(t): 
     17        return time.sleep(t) 
     18else: 
     19    from time import clock 
     20    from time import sleep 
    721 
    822class ConvertBSLThread(CalcThread): 
    923 
    10     def __init__(self, parent, in_file, out_file, 
     24    def __init__(self, xy, frame_data, out_file, frame_number=None, 
    1125        updatefn=None, completefn=None): 
    1226        CalcThread.__init__(self, updatefn=updatefn, completefn=completefn) 
    13         self.parent = parent 
    14         self.in_file = in_file 
     27        (self.x_data, self.y_data) = xy 
     28        self.frame_data = frame_data 
     29        self.frame_number = frame_number 
     30        self.frame_filename = '' 
    1531        self.out_file = out_file 
    1632 
    1733    def compute(self): 
    18         self.ready(delay=0.0) 
    19         self.update(msg="Extracting data...") 
    20  
    2134        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) 
     35            completed = self._convert_to_red2d() 
    4536        except Exception as e: 
    4637            self.ready() 
     
    5142        self.complete(success=completed) 
    5243 
     44    def isquit(self): 
     45        """Check for interrupts.  Should be called frequently to 
     46        provide user responsiveness.  Also yields to other running 
     47        threads, which is required for good performance on OS X.""" 
    5348 
    54     def _extract_bsl_data(self, filename): 
    55         """ 
    56         Extracts data from a 2D BSL file 
     49        # # Only called from within the running thread so no need to lock 
     50        # if self._running and self.yieldtime > 0 \ 
     51        #     and clock() > self._time_for_nap: 
     52        #     sleep(self.yieldtime) 
     53        #     self._time_for_nap = clock() + self.worktime 
     54        return self._interrupting 
    5755 
    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): 
     56    def _convert_to_red2d(self): 
    11057        """ 
    11158        Writes Data2D objects to Red2D .dat files. If more than one frame is 
     
    12168        :return: True if export completed, False if export cancelled by user 
    12269        """ 
    123         filename = os.path.split(filepath)[-1] 
    124         filepath = os.path.split(filepath)[0] 
     70        filename = os.path.split(self.out_file)[-1] 
     71        filepath = os.path.split(self.out_file)[0] 
    12572        writer = Red2DWriter() 
    12673 
    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 
     74        if self.isquit(): 
     75            return False 
    13276 
    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 
     77        if self.frame_number is not None: 
     78            frame_filename = filename.split('.') 
     79            frame_filename[0] += str(self.frame_number) 
     80            frame_filename = '.'.join(frame_filename) 
     81        else: 
     82            frame_filename = filename 
    13983 
    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)) 
     84        self.ready() 
     85        self.update(msg="Writing file: {}".format(frame_filename)) 
     86        data_i = self.frame_data.reshape((len(self.x_data),1)) 
     87        data_info = Data2D(data=data_i, qx_data=self.x_data, qy_data=self.y_data) 
     88        success = writer.write(os.path.join(filepath, frame_filename), data_info, self) 
    14589 
    146         return True 
     90        # Used by ConverterPanel.conversion_complete to notify user that file 
     91        # has been written (or that there was an error) 
     92        self.frame_filename = frame_filename 
     93 
     94        return success 
  • src/sas/sasgui/perspectives/file_converter/converter_panel.py

    r35488b2 r0b1a677  
    2020from sas.sasgui.guiframe.dataFitting import Data1D 
    2121from sas.sasgui.guiframe.utils import check_float 
    22 from sas.sasgui.perspectives.file_converter.cansas_writer import CansasWriter 
     22from sas.sascalc.file_converter.cansas_writer import CansasWriter 
     23from sas.sascalc.file_converter.otoko_loader import OTOKOLoader 
     24from sas.sascalc.file_converter.bsl_loader import BSLLoader 
    2325from sas.sascalc.file_converter.convert_bsl_thread import ConvertBSLThread 
    24 from sas.sasgui.perspectives.file_converter.otoko_loader import OTOKOLoader 
    2526from sas.sascalc.dataloader.data_info import Detector 
    2627from sas.sascalc.dataloader.data_info import Sample 
     
    5657        self.parent = parent 
    5758        self.meta_frames = [] 
     59        self.to_convert = {} 
    5860        self.bsl_thread = None 
    5961 
     
    182184 
    183185        return qdata, iqdata 
     186 
     187    def extract_bsl_data(self, filename): 
     188        """ 
     189        Extracts data from a 2D BSL file 
     190 
     191        :param filename: The header file to extract the data from 
     192        :return x_data: A 1D array containing all the x coordinates of the data 
     193        :return y_data: A 1D array containing all the y coordinates of the data 
     194        :return frame_data: A dictionary of the form frame_number: data, where 
     195        data is a 2D numpy array containing the intensity data 
     196        """ 
     197        loader = BSLLoader(filename) 
     198        frames = [0] 
     199        should_continue = True 
     200 
     201        if loader.n_frames > 1: 
     202            params = self.ask_frame_range(loader.n_frames) 
     203            frames = params['frames'] 
     204            if len(frames) == 0: 
     205                should_continue = False 
     206        elif loader.n_rasters == 1 and loader.n_frames == 1: 
     207            message = ("The selected file is an OTOKO file. Please select the " 
     208            "'OTOKO 1D' option if you wish to convert it.") 
     209            dlg = wx.MessageDialog(self, 
     210            message, 
     211            'Error!', 
     212            wx.OK | wx.ICON_WARNING) 
     213            dlg.ShowModal() 
     214            should_continue = False 
     215            dlg.Destroy() 
     216        else: 
     217            message = ("The selected data file only has 1 frame, it might be" 
     218                " a multi-frame OTOKO file.\nContinue conversion?") 
     219            dlg = wx.MessageDialog(self, 
     220            message, 
     221            'Warning!', 
     222            wx.YES_NO | wx.ICON_WARNING) 
     223            should_continue = (dlg.ShowModal() == wx.ID_YES) 
     224            dlg.Destroy() 
     225 
     226        if not should_continue: 
     227            return None, None, None 
     228 
     229        frame_data = {} 
     230 
     231        for frame in frames: 
     232            loader.frame = frame 
     233            frame_data[frame] = loader.load_data() 
     234 
     235        # TODO: Tidy this up 
     236        # Prepare axes values (arbitrary scale) 
     237        x_data = [] 
     238        y_data = range(loader.n_pixels) * loader.n_rasters 
     239        for i in range(loader.n_rasters): 
     240            x_data += [i] * loader.n_pixels 
     241 
     242        return x_data, y_data, frame_data 
    184243 
    185244    def ask_frame_range(self, n_frames): 
     
    236295 
    237296        if self.bsl_thread is not None and self.bsl_thread.isrunning(): 
     297            self.to_convert = {} 
    238298            self.bsl_thread.stop() 
    239             self.conversion_complete(success=False) 
    240299            return 
    241300 
     
    249308                qdata, iqdata = self.extract_otoko_data(self.q_input.GetPath()) 
    250309            else: # self.data_type == 'bsl' 
    251                 self.bsl_thread = ConvertBSLThread(self, self.iq_input.GetPath(), 
    252                     self.output.GetPath(), updatefn=self.conversion_update, 
     310 
     311                x, y, frame_data = self.extract_bsl_data(self.iq_input.GetPath()) 
     312                if x == None and y == None and frame_data == None: 
     313                    # Cancelled by user 
     314                    return 
     315 
     316                self.to_convert = frame_data 
     317 
     318                frame_number, data = self.to_convert.popitem() 
     319                self.bsl_thread = ConvertBSLThread((x, y), data, 
     320                    self.output.GetPath(), frame_number=frame_number, 
     321                    updatefn=self.conversion_update, 
    253322                    completefn=self.conversion_complete) 
    254323                self.bsl_thread.queue() 
     324 
    255325                self.convert_btn.SetLabel("Stop Conversion") 
    256326                return 
     
    330400 
    331401    def conversion_complete(self, success=True): 
    332         self.convert_btn.SetLabel("Convert") 
    333         msg = "Conversion " 
     402        msg = "Conversion of {} ".format(self.bsl_thread.frame_filename) 
     403 
    334404        if success: 
    335405            msg += "completed" 
     
    338408        wx.PostEvent(self.parent.manager.parent, 
    339409            StatusEvent(status=msg)) 
     410 
     411        if len(self.to_convert) == 0: 
     412            self.convert_btn.SetLabel("Convert") 
     413            self.bsl_thread = None 
     414            wx.PostEvent(self.parent.manager.parent, 
     415                StatusEvent(status="Conversion finished")) 
     416        else: 
     417            n, data = self.to_convert.popitem() 
     418            self.bsl_thread.frame_data = data 
     419            self.bsl_thread.frame_number = n 
     420            self.bsl_thread.queue() 
    340421 
    341422 
     
    613694 
    614695    def on_close(self, event): 
     696        if self.panel.bsl_thread.isrunning(): 
     697            self.panel.bsl_thread.stop() 
    615698        if self.manager is not None: 
    616699            self.manager.converter_frame = None 
Note: See TracChangeset for help on using the changeset viewer.