Ignore:
Timestamp:
Dec 22, 2017 12:08:53 PM (6 years ago)
Author:
krzywon
Branches:
master, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, unittest-saveload
Children:
5a4d022
Parents:
2651724 (diff), 0a88623 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ticket-976

File:
1 edited

Legend:

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

    r2651724 rd7fd7be  
    99import sys 
    1010 
    11 from sas.sascalc.dataloader.data_info import plottable_1D, plottable_2D,\ 
     11from ..data_info import plottable_1D, plottable_2D,\ 
    1212    Data1D, Data2D, DataInfo, Process, Aperture, Collimation, \ 
    1313    TransmissionSpectrum, Detector 
    14 from sas.sascalc.dataloader.data_info import combine_data_info_with_plottable 
    15  
    16  
    17 class Reader(): 
     14from ..data_info import combine_data_info_with_plottable 
     15from ..loader_exceptions import FileContentsException, DefaultReaderException 
     16from ..file_reader_base_class import FileReader, decode 
     17 
     18def h5attr(node, key, default=None): 
     19    return decode(node.attrs.get(key, default)) 
     20 
     21class Reader(FileReader): 
    1822    """ 
    1923    A class for reading in CanSAS v2.0 data files. The existing iteration opens 
     
    4044    # Raw file contents to be processed 
    4145    raw_data = None 
    42     # Data info currently being read in 
    43     current_datainfo = None 
    44     # SASdata set currently being read in 
    45     current_dataset = None 
    4646    # List of plottable1D objects that should be linked to the current_datainfo 
    4747    data1d = None 
     
    5656    # Flag to bypass extension check 
    5757    allow_all = True 
    58     # List of files to return 
    59     output = None 
    60  
    61     def read(self, filename): 
     58 
     59    def get_file_contents(self): 
    6260        """ 
    6361        This is the general read method that all SasView data_loaders must have. 
     
    6765        """ 
    6866        # Reinitialize when loading a new data file to reset all class variables 
    69         self.reset_class_variables() 
     67        self.reset_state() 
     68 
     69        filename = self.f_open.name 
     70        self.f_open.close() # IO handled by h5py 
     71 
    7072        # Check that the file exists 
    7173        if os.path.isfile(filename): 
     
    7577            if extension in self.ext or self.allow_all: 
    7678                # Load the data file 
    77                 self.raw_data = h5py.File(filename, 'r') 
    78                 # Read in all child elements of top level SASroot 
    79                 self.read_children(self.raw_data, []) 
    80                 # Add the last data set to the list of outputs 
    81                 self.add_data_set() 
    82                 # Close the data file 
    83                 self.raw_data.close() 
    84         # Return data set(s) 
    85         return self.output 
    86  
    87     def reset_class_variables(self): 
     79                try: 
     80                    self.raw_data = h5py.File(filename, 'r') 
     81                except Exception as e: 
     82                    if extension not in self.ext: 
     83                        msg = "CanSAS2.0 HDF5 Reader could not load file {}".format(basename + extension) 
     84                        raise DefaultReaderException(msg) 
     85                    raise FileContentsException(e.message) 
     86                try: 
     87                    # Read in all child elements of top level SASroot 
     88                    self.read_children(self.raw_data, []) 
     89                    # Add the last data set to the list of outputs 
     90                    self.add_data_set() 
     91                except Exception as exc: 
     92                    raise FileContentsException(exc.message) 
     93                finally: 
     94                    # Close the data file 
     95                    self.raw_data.close() 
     96 
     97                for dataset in self.output: 
     98                    if isinstance(dataset, Data1D): 
     99                        if dataset.x.size < 5: 
     100                            self.output = [] 
     101                            raise FileContentsException("Fewer than 5 data points found.") 
     102 
     103    def reset_state(self): 
    88104        """ 
    89105        Create the reader object and define initial states for class variables 
    90106        """ 
    91         self.current_datainfo = None 
    92         self.current_dataset = None 
     107        super(Reader, self).reset_state() 
    93108        self.data1d = [] 
    94109        self.data2d = [] 
     
    123138            # Get all information for the current key 
    124139            value = data.get(key) 
    125             if value.attrs.get(u'canSAS_class') is not None: 
    126                 class_name = value.attrs.get(u'canSAS_class') 
    127             elif value.attrs.get(u'NX_class') is not None: 
    128                 class_name = value.attrs.get(u'NX_class') 
    129             else: 
    130                 class_name = key 
     140            class_name = h5attr(value, u'canSAS_class') 
     141            if class_name is None: 
     142                class_name = h5attr(value, u'NX_class') 
    131143            if class_name is not None: 
    132144                class_prog = re.compile(class_name) 
     
    135147 
    136148            if isinstance(value, h5py.Group): 
     149                # Set parent class before recursion 
    137150                self.parent_class = class_name 
    138151                parent_list.append(key) 
     
    146159                # Recursion step to access data within the group 
    147160                self.read_children(value, parent_list) 
     161                # Reset parent class when returning from recursive method 
     162                self.parent_class = class_name 
    148163                self.add_intermediate() 
    149164                parent_list.remove(key) 
     
    155170 
    156171                for data_point in data_set: 
     172                    if isinstance(data_point, np.ndarray): 
     173                        if data_point.dtype.char == 'S': 
     174                            data_point = decode(bytes(data_point)) 
     175                    else: 
     176                        data_point = decode(data_point) 
    157177                    # Top Level Meta Data 
    158178                    if key == u'definition': 
     
    162182                        self.current_datainfo.run.append(data_point) 
    163183                        try: 
    164                             run_name = value.attrs['name'] 
     184                            run_name = h5attr(value, 'name') 
    165185                            run_dict = {data_point: run_name} 
    166186                            self.current_datainfo.run_name = run_dict 
    167                         except: 
     187                        except Exception: 
    168188                            pass 
    169189                    # Title 
     
    458478        Data1D and Data2D objects 
    459479        """ 
    460  
    461480        # Type cast data arrays to float64 
    462481        if len(self.current_datainfo.trans_spectrum) > 0: 
     
    482501        # Type cast data arrays to float64 and find min/max as appropriate 
    483502        for dataset in self.data2d: 
    484             dataset.data = dataset.data.astype(np.float64) 
    485             dataset.err_data = dataset.err_data.astype(np.float64) 
    486             if dataset.qx_data is not None: 
    487                 dataset.xmin = np.min(dataset.qx_data) 
    488                 dataset.xmax = np.max(dataset.qx_data) 
    489                 dataset.qx_data = dataset.qx_data.astype(np.float64) 
    490             if dataset.dqx_data is not None: 
    491                 dataset.dqx_data = dataset.dqx_data.astype(np.float64) 
    492             if dataset.qy_data is not None: 
    493                 dataset.ymin = np.min(dataset.qy_data) 
    494                 dataset.ymax = np.max(dataset.qy_data) 
    495                 dataset.qy_data = dataset.qy_data.astype(np.float64) 
    496             if dataset.dqy_data is not None: 
    497                 dataset.dqy_data = dataset.dqy_data.astype(np.float64) 
    498             if dataset.q_data is not None: 
    499                 dataset.q_data = dataset.q_data.astype(np.float64) 
    500503            zeros = np.ones(dataset.data.size, dtype=bool) 
    501504            try: 
     
    520523                dataset.x_bins = dataset.qx_data[:n_cols] 
    521524                dataset.data = dataset.data.flatten() 
    522  
    523             final_dataset = combine_data_info_with_plottable( 
    524                 dataset, self.current_datainfo) 
    525             self.output.append(final_dataset) 
     525            self.current_dataset = dataset 
     526            self.send_to_output() 
    526527 
    527528        for dataset in self.data1d: 
    528             if dataset.x is not None: 
    529                 dataset.x = dataset.x.astype(np.float64) 
    530                 dataset.xmin = np.min(dataset.x) 
    531                 dataset.xmax = np.max(dataset.x) 
    532             if dataset.y is not None: 
    533                 dataset.y = dataset.y.astype(np.float64) 
    534                 dataset.ymin = np.min(dataset.y) 
    535                 dataset.ymax = np.max(dataset.y) 
    536             if dataset.dx is not None: 
    537                 dataset.dx = dataset.dx.astype(np.float64) 
    538             if dataset.dxl is not None: 
    539                 dataset.dxl = dataset.dxl.astype(np.float64) 
    540             if dataset.dxw is not None: 
    541                 dataset.dxw = dataset.dxw.astype(np.float64) 
    542             if dataset.dy is not None: 
    543                 dataset.dy = dataset.dy.astype(np.float64) 
    544             final_dataset = combine_data_info_with_plottable( 
    545                 dataset, self.current_datainfo) 
    546             self.output.append(final_dataset) 
     529            self.current_dataset = dataset 
     530            self.send_to_output() 
    547531 
    548532    def add_data_set(self, key=""): 
     
    651635        :return: unit for the value passed to the method 
    652636        """ 
    653         unit = value.attrs.get(u'units') 
     637        unit = h5attr(value, u'units') 
    654638        if unit is None: 
    655             unit = value.attrs.get(u'unit') 
     639            unit = h5attr(value, u'unit') 
    656640        # Convert the unit formats 
    657641        if unit == "1/A": 
Note: See TracChangeset for help on using the changeset viewer.