Changeset 713a047 in sasview for src/sas/sascalc/dataloader


Ignore:
Timestamp:
Aug 1, 2017 5:19:46 AM (7 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.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
b2c28a5
Parents:
a78433dd
Message:

Refactor danse_reader to use FileReader? class

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/dataloader/readers/danse_reader.py

    r235f514 r713a047  
    55#This software was developed by the University of Tennessee as part of the 
    66#Distributed Data Analysis of Neutron Scattering Experiments (DANSE) 
    7 #project funded by the US National Science Foundation.  
     7#project funded by the US National Science Foundation. 
    88#If you use DANSE applications to do scientific research that leads to 
    99#publication, we ask that you acknowledge the use of the software with the 
     
    1414import math 
    1515import os 
    16 import sys 
    1716import numpy as np 
    1817import logging 
    19 from sas.sascalc.dataloader.data_info import Data2D, Detector 
     18from sas.sascalc.dataloader.data_info import plottable_2D, DataInfo, Detector 
    2019from sas.sascalc.dataloader.manipulations import reader2D_converter 
     20from sas.sascalc.dataloader.file_reader_base_class import FileReader 
     21from sas.sascalc.dataloader.loader_exceptions import FileContentsException, DataReaderException 
    2122 
    2223logger = logging.getLogger(__name__) 
     
    3031 
    3132 
    32 class Reader: 
     33class Reader(FileReader): 
    3334    """ 
    3435    Example data manipulation 
     
    4041    ## Extension 
    4142    ext  = ['.sans', '.SANS'] 
    42          
    43     def read(self, filename=None): 
    44         """ 
    45         Open and read the data in a file 
    46         @param file: path of the file 
    47         """ 
    48          
    49         read_it = False 
    50         for item in self.ext: 
    51             if filename.lower().find(item) >= 0: 
    52                 read_it = True 
    53                  
    54         if read_it: 
     43 
     44    def get_file_contents(self): 
     45        self.current_datainfo = DataInfo() 
     46        self.current_dataset = plottable_2D() 
     47        self.output = [] 
     48 
     49        loaded_correctly = True 
     50        error_message = "" 
     51 
     52        # defaults 
     53        # wavelength in Angstrom 
     54        wavelength = 10.0 
     55        # Distance in meter 
     56        distance   = 11.0 
     57        # Pixel number of center in x 
     58        center_x   = 65 
     59        # Pixel number of center in y 
     60        center_y   = 65 
     61        # Pixel size [mm] 
     62        pixel      = 5.0 
     63        # Size in x, in pixels 
     64        size_x     = 128 
     65        # Size in y, in pixels 
     66        size_y     = 128 
     67        # Format version 
     68        fversion   = 1.0 
     69 
     70        self.current_datainfo.filename = os.path.basename(self.f_open.name) 
     71        detector = Detector() 
     72        self.current_datainfo.detector.append(detector) 
     73 
     74        self.current_dataset.data = np.zeros([size_x, size_y]) 
     75        self.current_dataset.err_data = np.zeros([size_x, size_y]) 
     76 
     77        read_on = True 
     78        data_start_line = 1 
     79        while read_on: 
     80            line = self.f_open.readline() 
     81            data_start_line += 1 
     82            if line.find("DATA:") >= 0: 
     83                read_on = False 
     84                break 
     85            toks = line.split(':') 
    5586            try: 
    56                 datafile = open(filename, 'r') 
    57             except: 
    58                 raise  RuntimeError,"danse_reader cannot open %s" % (filename) 
    59          
    60             # defaults 
    61             # wavelength in Angstrom 
    62             wavelength = 10.0 
    63             # Distance in meter 
    64             distance   = 11.0 
    65             # Pixel number of center in x 
    66             center_x   = 65 
    67             # Pixel number of center in y 
    68             center_y   = 65 
    69             # Pixel size [mm] 
    70             pixel      = 5.0 
    71             # Size in x, in pixels 
    72             size_x     = 128 
    73             # Size in y, in pixels 
    74             size_y     = 128 
    75             # Format version 
    76             fversion   = 1.0 
    77              
    78             output = Data2D() 
    79             output.filename = os.path.basename(filename) 
    80             detector = Detector() 
    81             output.detector.append(detector) 
    82              
    83             output.data = np.zeros([size_x,size_y]) 
    84             output.err_data = np.zeros([size_x, size_y]) 
    85              
    86             data_conv_q = None 
    87             data_conv_i = None 
    88              
    89             if has_converter == True and output.Q_unit != '1/A': 
    90                 data_conv_q = Converter('1/A') 
    91                 # Test it 
    92                 data_conv_q(1.0, output.Q_unit) 
    93                  
    94             if has_converter == True and output.I_unit != '1/cm': 
    95                 data_conv_i = Converter('1/cm') 
    96                 # Test it 
    97                 data_conv_i(1.0, output.I_unit) 
    98          
    99             read_on = True 
    100             while read_on: 
    101                 line = datafile.readline() 
    102                 if line.find("DATA:") >= 0: 
    103                     read_on = False 
    104                     break 
    105                 toks = line.split(':') 
    10687                if toks[0] == "FORMATVERSION": 
    10788                    fversion = float(toks[1]) 
    108                 if toks[0] == "WAVELENGTH": 
     89                elif toks[0] == "WAVELENGTH": 
    10990                    wavelength = float(toks[1]) 
    11091                elif toks[0] == "DISTANCE": 
     
    120101                elif toks[0] == "SIZE_Y": 
    121102                    size_y = int(toks[1]) 
    122              
    123             # Read the data 
    124             data = [] 
    125             error = [] 
    126             if fversion == 1.0: 
    127                 data_str = datafile.readline() 
    128                 data = data_str.split(' ') 
    129             else: 
    130                 read_on = True 
    131                 while read_on: 
    132                     data_str = datafile.readline() 
    133                     if len(data_str) == 0: 
    134                         read_on = False 
    135                     else: 
    136                         toks = data_str.split() 
    137                         try: 
    138                             val = float(toks[0]) 
    139                             err = float(toks[1]) 
    140                             if data_conv_i is not None: 
    141                                 val = data_conv_i(val, units=output._yunit) 
    142                                 err = data_conv_i(err, units=output._yunit) 
    143                             data.append(val) 
    144                             error.append(err) 
    145                         except: 
    146                             logger.info("Skipping line:%s,%s" %(data_str, 
    147                                                                 sys.exc_value)) 
    148              
    149             # Initialize 
    150             x_vals = [] 
    151             y_vals = [] 
    152             ymin = None 
    153             ymax = None 
    154             xmin = None 
    155             xmax = None 
    156              
    157             # Qx and Qy vectors 
    158             theta = pixel / distance / 100.0 
    159             stepq = 4.0 * math.pi / wavelength * math.sin(theta / 2.0) 
    160             for i_x in range(size_x): 
    161                 theta = (i_x - center_x + 1) * pixel / distance / 100.0 
    162                 qx = 4.0 * math.pi / wavelength * math.sin(theta / 2.0) 
    163                  
    164                 if has_converter == True and output.Q_unit != '1/A': 
    165                     qx = data_conv_q(qx, units=output.Q_unit) 
    166                  
    167                 x_vals.append(qx) 
    168                 if xmin is None or qx < xmin: 
    169                     xmin = qx 
    170                 if xmax is None or qx > xmax: 
    171                     xmax = qx 
    172              
    173             ymin = None 
    174             ymax = None 
    175             for i_y in range(size_y): 
    176                 theta = (i_y - center_y + 1) * pixel / distance / 100.0 
    177                 qy = 4.0 * math.pi / wavelength * math.sin(theta/2.0) 
    178                  
    179                 if has_converter == True and output.Q_unit != '1/A': 
    180                     qy = data_conv_q(qy, units=output.Q_unit) 
    181                  
    182                 y_vals.append(qy) 
    183                 if ymin is None or qy < ymin: 
    184                     ymin = qy 
    185                 if ymax is None or qy > ymax: 
    186                     ymax = qy 
    187              
    188             # Store the data in the 2D array 
    189             i_x = 0 
    190             i_y = -1 
    191              
    192             for i_pt in range(len(data)): 
    193                 try: 
    194                     value = float(data[i_pt]) 
    195                 except: 
    196                     # For version 1.0, the data were still 
    197                     # stored as strings at this point. 
    198                     msg = "Skipping entry (v1.0):%s,%s" % (str(data[i_pt]), 
    199                                                            sys.exc_value) 
    200                     logger.info(msg) 
    201                  
    202                 # Get bin number 
    203                 if math.fmod(i_pt, size_x) == 0: 
    204                     i_x = 0 
    205                     i_y += 1 
    206                 else: 
    207                     i_x += 1 
    208                      
    209                 output.data[i_y][i_x] = value 
    210                 if fversion>1.0: 
    211                     output.err_data[i_y][i_x] = error[i_pt] 
    212                  
    213             # Store all data 
    214             # Store wavelength 
    215             if has_converter == True and output.source.wavelength_unit != 'A': 
    216                 conv = Converter('A') 
    217                 wavelength = conv(wavelength, 
    218                                   units=output.source.wavelength_unit) 
    219             output.source.wavelength = wavelength 
    220                  
    221             # Store distance 
    222             if has_converter == True and detector.distance_unit != 'm': 
    223                 conv = Converter('m') 
    224                 distance = conv(distance, units=detector.distance_unit) 
    225             detector.distance = distance 
    226              
    227             # Store pixel size 
    228             if has_converter == True and detector.pixel_size_unit != 'mm': 
    229                 conv = Converter('mm') 
    230                 pixel = conv(pixel, units=detector.pixel_size_unit) 
    231             detector.pixel_size.x = pixel 
    232             detector.pixel_size.y = pixel 
    233  
    234             # Store beam center in distance units 
    235             detector.beam_center.x = center_x * pixel 
    236             detector.beam_center.y = center_y * pixel 
    237              
    238             # Store limits of the image (2D array) 
    239             xmin = xmin - stepq / 2.0 
    240             xmax = xmax + stepq / 2.0 
    241             ymin = ymin - stepq /2.0 
    242             ymax = ymax + stepq / 2.0 
    243              
    244             if has_converter == True and output.Q_unit != '1/A': 
    245                 xmin = data_conv_q(xmin, units=output.Q_unit) 
    246                 xmax = data_conv_q(xmax, units=output.Q_unit) 
    247                 ymin = data_conv_q(ymin, units=output.Q_unit) 
    248                 ymax = data_conv_q(ymax, units=output.Q_unit) 
    249             output.xmin = xmin 
    250             output.xmax = xmax 
    251             output.ymin = ymin 
    252             output.ymax = ymax 
    253              
    254             # Store x and y axis bin centers 
    255             output.x_bins = x_vals 
    256             output.y_bins = y_vals 
    257             
    258             # Units 
    259             if data_conv_q is not None: 
    260                 output.xaxis("\\rm{Q_{x}}", output.Q_unit) 
    261                 output.yaxis("\\rm{Q_{y}}", output.Q_unit) 
    262             else: 
    263                 output.xaxis("\\rm{Q_{x}}", 'A^{-1}') 
    264                 output.yaxis("\\rm{Q_{y}}", 'A^{-1}') 
    265                  
    266             if data_conv_i is not None: 
    267                 output.zaxis("\\rm{Intensity}", output.I_unit) 
    268             else: 
    269                 output.zaxis("\\rm{Intensity}", "cm^{-1}") 
    270             
    271             if not fversion >= 1.0: 
    272                 msg = "Danse_reader can't read this file %s" % filename 
    273                 raise ValueError, msg 
    274             else: 
    275                 logger.info("Danse_reader Reading %s \n" % filename) 
    276              
    277             # Store loading process information 
    278             output.meta_data['loader'] = self.type_name 
    279             output = reader2D_converter(output) 
    280             return output 
    281          
    282         return None 
     103            except ValueError as e: 
     104                error_message += "Unable to parse {}. Default value used.\n".format(toks[0]) 
     105                loaded_correctly = False 
     106 
     107        # Read the data 
     108        data = [] 
     109        error = [] 
     110        if not fversion >= 1.0: 
     111            msg = "danse_reader can't read this file {}".format(self.f_open.name) 
     112            raise FileContentsException(msg) 
     113 
     114        for line_num, data_str in enumerate(self.f_open.readlines()): 
     115            toks = data_str.split() 
     116            try: 
     117                val = float(toks[0]) 
     118                err = float(toks[1]) 
     119                data.append(val) 
     120                error.append(err) 
     121            except ValueError as exc: 
     122                msg = "Unable to parse line {}: {}".format(line_num + data_start_line, data_str.strip()) 
     123                raise FileContentsException(msg) 
     124 
     125        num_pts = size_x * size_y 
     126        if len(data) < num_pts: 
     127            msg = "Not enough data points provided. Expected {} but got {}".format( 
     128                size_x * size_y, len(data)) 
     129            raise FileContentsException(msg) 
     130        elif len(data) > num_pts: 
     131            error_message += ("Too many data points provided. Expected {0} but" 
     132                " got {1}. Only the first {0} will be used.\n").format(num_pts, len(data)) 
     133            loaded_correctly = False 
     134            data = data[:num_pts] 
     135            error = error[:num_pts] 
     136 
     137        # Qx and Qy vectors 
     138        theta = pixel / distance / 100.0 
     139        i_x = np.arange(size_x) 
     140        theta = (i_x - center_x + 1) * pixel / distance / 100.0 
     141        x_vals = 4.0 * np.pi / wavelength * np.sin(theta / 2.0) 
     142        xmin = x_vals.min() 
     143        xmax = x_vals.max() 
     144 
     145        i_y = np.arange(size_y) 
     146        theta = (i_y - center_y + 1) * pixel / distance / 100.0 
     147        y_vals = 4.0 * np.pi / wavelength * np.sin(theta / 2.0) 
     148        ymin = y_vals.min() 
     149        ymax = y_vals.max() 
     150 
     151        self.current_dataset.data = np.array(data, dtype=np.float64).reshape((size_y, size_x)) 
     152        if fversion > 1.0: 
     153            self.current_dataset.err_data = np.array(error, dtype=np.float64).reshape((size_y, size_x)) 
     154 
     155        # Store all data 
     156        # Store wavelength 
     157        if has_converter == True and self.current_datainfo.source.wavelength_unit != 'A': 
     158            conv = Converter('A') 
     159            wavelength = conv(wavelength, 
     160                              units=self.current_datainfo.source.wavelength_unit) 
     161        self.current_datainfo.source.wavelength = wavelength 
     162 
     163        # Store distance 
     164        if has_converter == True and detector.distance_unit != 'm': 
     165            conv = Converter('m') 
     166            distance = conv(distance, units=detector.distance_unit) 
     167        detector.distance = distance 
     168 
     169        # Store pixel size 
     170        if has_converter == True and detector.pixel_size_unit != 'mm': 
     171            conv = Converter('mm') 
     172            pixel = conv(pixel, units=detector.pixel_size_unit) 
     173        detector.pixel_size.x = pixel 
     174        detector.pixel_size.y = pixel 
     175 
     176        # Store beam center in distance units 
     177        detector.beam_center.x = center_x * pixel 
     178        detector.beam_center.y = center_y * pixel 
     179 
     180 
     181        self.current_dataset.xaxis("\\rm{Q_{x}}", 'A^{-1}') 
     182        self.current_dataset.yaxis("\\rm{Q_{y}}", 'A^{-1}') 
     183        self.current_dataset.zaxis("\\rm{Intensity}", "cm^{-1}") 
     184 
     185        self.current_dataset.x_bins = x_vals 
     186        self.current_dataset.y_bins = y_vals 
     187 
     188        # Reshape data 
     189        x_vals = np.tile(x_vals, (size_y, 1)).flatten() 
     190        y_vals = np.tile(y_vals, (size_x, 1)).T.flatten() 
     191        if self.current_dataset.err_data == np.all(np.array(None)) or np.any(self.current_dataset.err_data <= 0): 
     192            new_err_data = np.sqrt(np.abs(self.current_dataset.data)) 
     193        else: 
     194            new_err_data = self.current_dataset.err_data.flatten() 
     195 
     196        self.current_dataset.err_data = new_err_data 
     197        self.current_dataset.qx_data = x_vals 
     198        self.current_dataset.qy_data = y_vals 
     199        self.current_dataset.q_data = np.sqrt(x_vals**2 + y_vals**2) 
     200        self.current_dataset.mask = np.ones(len(x_vals), dtype=bool) 
     201 
     202        # Store loading process information 
     203        self.current_datainfo.meta_data['loader'] = self.type_name 
     204 
     205        self.send_to_output() 
     206 
     207        if not loaded_correctly: 
     208            raise DataReaderException(error_message) 
Note: See TracChangeset for help on using the changeset viewer.