Changes in / [f560e23:c222c27] in sasview


Ignore:
Files:
14 added
12 deleted
20 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/data_util/nxsunit.py

    r574adc7 rb011ecb  
    136136    sld = { '10^-6 Angstrom^-2': 1e-6, 'Angstrom^-2': 1 } 
    137137    Q = { 'invA': 1, 'invAng': 1, 'invAngstroms': 1, '1/A': 1, 
     138          '1/Angstrom': 1, '1/angstrom': 1, 'A^{-1}': 1, 'cm^{-1}': 1e-8, 
    138139          '10^-3 Angstrom^-1': 1e-3, '1/cm': 1e-8, '1/m': 1e-10, 
    139           'nm^-1': 0.1, '1/nm': 0.1, 'n_m^-1': 0.1 } 
     140          'nm^{-1}': 1, 'nm^-1': 0.1, '1/nm': 0.1, 'n_m^-1': 0.1 } 
    140141 
    141142    _caret_optional(sld) 
     
    157158    # units for that particular dimension. 
    158159    # Note: don't have support for dimensionless units. 
    159     unknown = {None:1, '???':1, '': 1, 'a.u.': 1} 
     160    unknown = {None:1, '???':1, '': 1, 'a.u.': 1, 'Counts': 1, 'counts': 1} 
    160161 
    161162    def __init__(self, name): 
  • src/sas/sascalc/dataloader/data_info.py

    rdeaa0c6 r4fdcc65  
    954954        _str += "Data:\n" 
    955955        _str += "   Type:         %s\n" % self.__class__.__name__ 
    956         _str += "   X- & Y-axis:  %s\t[%s]\n" % (self._yaxis, self._yunit) 
     956        _str += "   X-axis:       %s\t[%s]\n" % (self._xaxis, self._xunit) 
     957        _str += "   Y-axis:       %s\t[%s]\n" % (self._yaxis, self._yunit) 
    957958        _str += "   Z-axis:       %s\t[%s]\n" % (self._zaxis, self._zunit) 
    958959        _str += "   Length:       %g \n" % (len(self.data)) 
     
    983984                           qx_data=qx_data, qy_data=qy_data, 
    984985                           q_data=q_data, mask=mask) 
     986 
     987        clone._xaxis = self._xaxis 
     988        clone._yaxis = self._yaxis 
     989        clone._zaxis = self._zaxis 
     990        clone._xunit = self._xunit 
     991        clone._yunit = self._yunit 
     992        clone._zunit = self._zunit 
     993        clone.x_bins = self.x_bins 
     994        clone.y_bins = self.y_bins 
    985995 
    986996        clone.title = self.title 
     
    11531163def combine_data_info_with_plottable(data, datainfo): 
    11541164    """ 
    1155     A function that combines the DataInfo data in self.current_datainto with a plottable_1D or 2D data object. 
     1165    A function that combines the DataInfo data in self.current_datainto with a 
     1166    plottable_1D or 2D data object. 
    11561167 
    11571168    :param data: A plottable_1D or plottable_2D data object 
     
    11711182        final_dataset.yaxis(data._yaxis, data._yunit) 
    11721183    elif isinstance(data, plottable_2D): 
    1173         final_dataset = Data2D(data.data, data.err_data, data.qx_data, data.qy_data, data.q_data, 
    1174                                data.mask, data.dqx_data, data.dqy_data) 
     1184        final_dataset = Data2D(data.data, data.err_data, data.qx_data, 
     1185                               data.qy_data, data.q_data, data.mask, 
     1186                               data.dqx_data, data.dqy_data) 
    11751187        final_dataset.xaxis(data._xaxis, data._xunit) 
    11761188        final_dataset.yaxis(data._yaxis, data._yunit) 
    11771189        final_dataset.zaxis(data._zaxis, data._zunit) 
    1178         if len(data.data.shape) == 2: 
    1179             n_rows, n_cols = data.data.shape 
    1180             final_dataset.y_bins = data.qy_data[0::int(n_cols)] 
    1181             final_dataset.x_bins = data.qx_data[:int(n_cols)] 
     1190        final_dataset.y_bins = data.y_bins 
     1191        final_dataset.x_bins = data.x_bins 
    11821192    else: 
    1183         return_string = "Should Never Happen: _combine_data_info_with_plottable input is not a plottable1d or " + \ 
    1184                         "plottable2d data object" 
     1193        return_string = ("Should Never Happen: _combine_data_info_with_plottabl" 
     1194                         "e input is not a plottable1d or plottable2d data " 
     1195                         "object") 
    11851196        return return_string 
    11861197 
  • src/sas/sascalc/dataloader/file_reader_base_class.py

    rfee520ec rfee520ec  
    1616from .data_info import Data1D, Data2D, DataInfo, plottable_1D, plottable_2D,\ 
    1717    combine_data_info_with_plottable 
     18from sas.sascalc.data_util.nxsunit import Converter 
    1819 
    1920logger = logging.getLogger(__name__) 
     
    3738                       "SasView cannot guarantee the accuracy of the data.") 
    3839 
     40 
    3941class FileReader(object): 
    4042    # String to describe the type of data this reader can load 
     
    4547    ext = ['.txt'] 
    4648    # Deprecated extensions 
    47     deprecated_extensions = ['.asc', '.nxs'] 
     49    deprecated_extensions = ['.asc'] 
    4850    # Bypass extension check and try to load anyway 
    4951    allow_all = False 
     
    98100                    if len(self.output) > 0: 
    99101                        # Sort the data that's been loaded 
    100                         self.sort_one_d_data() 
    101                         self.sort_two_d_data() 
     102                        self.convert_data_units() 
     103                        self.sort_data() 
    102104        else: 
    103105            msg = "Unable to find file at: {}\n".format(filepath) 
     
    140142        Returns the entire file as a string. 
    141143        """ 
    142         #return self.f_open.read() 
    143144        return decode(self.f_open.read()) 
    144145 
     
    166167        self.output.append(data_obj) 
    167168 
    168     def sort_one_d_data(self): 
     169    def sort_data(self): 
    169170        """ 
    170171        Sort 1D data along the X axis for consistency 
     
    174175                # Normalize the units for 
    175176                data.x_unit = self.format_unit(data.x_unit) 
     177                data._xunit = data.x_unit 
    176178                data.y_unit = self.format_unit(data.y_unit) 
     179                data._yunit = data.y_unit 
    177180                # Sort data by increasing x and remove 1st point 
    178181                ind = np.lexsort((data.y, data.x)) 
     
    203206                    data.ymin = np.min(data.y) 
    204207                    data.ymax = np.max(data.y) 
     208            elif isinstance(data, Data2D): 
     209                # Normalize the units for 
     210                data.Q_unit = self.format_unit(data.Q_unit) 
     211                data.I_unit = self.format_unit(data.I_unit) 
     212                data._xunit = data.Q_unit 
     213                data._yunit = data.Q_unit 
     214                data._zunit = data.I_unit 
     215                data.data = data.data.astype(np.float64) 
     216                data.qx_data = data.qx_data.astype(np.float64) 
     217                data.xmin = np.min(data.qx_data) 
     218                data.xmax = np.max(data.qx_data) 
     219                data.qy_data = data.qy_data.astype(np.float64) 
     220                data.ymin = np.min(data.qy_data) 
     221                data.ymax = np.max(data.qy_data) 
     222                data.q_data = np.sqrt(data.qx_data * data.qx_data 
     223                                         + data.qy_data * data.qy_data) 
     224                if data.err_data is not None: 
     225                    data.err_data = data.err_data.astype(np.float64) 
     226                if data.dqx_data is not None: 
     227                    data.dqx_data = data.dqx_data.astype(np.float64) 
     228                if data.dqy_data is not None: 
     229                    data.dqy_data = data.dqy_data.astype(np.float64) 
     230                if data.mask is not None: 
     231                    data.mask = data.mask.astype(dtype=bool) 
     232 
     233                if len(data.data.shape) == 2: 
     234                    n_rows, n_cols = data.data.shape 
     235                    data.y_bins = data.qy_data[0::int(n_cols)] 
     236                    data.x_bins = data.qx_data[:int(n_cols)] 
     237                    data.data = data.data.flatten() 
     238                data = self._remove_nans_in_data(data) 
     239                if len(data.data) > 0: 
     240                    data.xmin = np.min(data.qx_data) 
     241                    data.xmax = np.max(data.qx_data) 
     242                    data.ymin = np.min(data.qy_data) 
     243                    data.ymax = np.max(data.qy_data) 
    205244 
    206245    @staticmethod 
     
    242281        return data 
    243282 
    244     def sort_two_d_data(self): 
    245         for dataset in self.output: 
    246             if isinstance(dataset, Data2D): 
    247                 # Normalize the units for 
    248                 dataset.x_unit = self.format_unit(dataset.Q_unit) 
    249                 dataset.y_unit = self.format_unit(dataset.I_unit) 
    250                 dataset.data = dataset.data.astype(np.float64) 
    251                 dataset.qx_data = dataset.qx_data.astype(np.float64) 
    252                 dataset.xmin = np.min(dataset.qx_data) 
    253                 dataset.xmax = np.max(dataset.qx_data) 
    254                 dataset.qy_data = dataset.qy_data.astype(np.float64) 
    255                 dataset.ymin = np.min(dataset.qy_data) 
    256                 dataset.ymax = np.max(dataset.qy_data) 
    257                 dataset.q_data = np.sqrt(dataset.qx_data * dataset.qx_data 
    258                                          + dataset.qy_data * dataset.qy_data) 
    259                 if dataset.err_data is not None: 
    260                     dataset.err_data = dataset.err_data.astype(np.float64) 
    261                 if dataset.dqx_data is not None: 
    262                     dataset.dqx_data = dataset.dqx_data.astype(np.float64) 
    263                 if dataset.dqy_data is not None: 
    264                     dataset.dqy_data = dataset.dqy_data.astype(np.float64) 
    265                 if dataset.mask is not None: 
    266                     dataset.mask = dataset.mask.astype(dtype=bool) 
    267  
    268                 if len(dataset.data.shape) == 2: 
    269                     n_rows, n_cols = dataset.data.shape 
    270                     dataset.y_bins = dataset.qy_data[0::int(n_cols)] 
    271                     dataset.x_bins = dataset.qx_data[:int(n_cols)] 
    272                 dataset.data = dataset.data.flatten() 
    273                 dataset = self._remove_nans_in_data(dataset) 
    274                 if len(dataset.data) > 0: 
    275                     dataset.xmin = np.min(dataset.qx_data) 
    276                     dataset.xmax = np.max(dataset.qx_data) 
    277                     dataset.ymin = np.min(dataset.qy_data) 
    278                     dataset.ymax = np.max(dataset.qy_data) 
     283    @staticmethod 
     284    def set_default_1d_units(data): 
     285        """ 
     286        Set the x and y axes to the default 1D units 
     287        :param data: 1D data set 
     288        :return: 
     289        """ 
     290        data.xaxis(r"\rm{Q}", '1/A') 
     291        data.yaxis(r"\rm{Intensity}", "1/cm") 
     292        return data 
     293 
     294    @staticmethod 
     295    def set_default_2d_units(data): 
     296        """ 
     297        Set the x and y axes to the default 2D units 
     298        :param data: 2D data set 
     299        :return: 
     300        """ 
     301        data.xaxis("\\rm{Q_{x}}", '1/A') 
     302        data.yaxis("\\rm{Q_{y}}", '1/A') 
     303        data.zaxis("\\rm{Intensity}", "1/cm") 
     304        return data 
     305 
     306    def convert_data_units(self, default_q_unit="1/A"): 
     307        """ 
     308        Converts al; data to the sasview default of units of A^{-1} for Q and 
     309        cm^{-1} for I. 
     310        :param default_q_unit: The default Q unit used by Sasview 
     311        """ 
     312        convert_q = True 
     313        new_output = [] 
     314        for data in self.output: 
     315            if data.isSesans: 
     316                new_output.append(data) 
     317                continue 
     318            try: 
     319                file_x_unit = data._xunit 
     320                data_conv_x = Converter(file_x_unit) 
     321            except KeyError: 
     322                logger.info("Unrecognized Q units in data file. No data " 
     323                            "conversion attempted") 
     324                convert_q = False 
     325            try: 
     326 
     327                if isinstance(data, Data1D): 
     328                        if convert_q: 
     329                            data.x = data_conv_x(data.x, units=default_q_unit) 
     330                            data._xunit = default_q_unit 
     331                            data.x_unit = default_q_unit 
     332                            if data.dx is not None: 
     333                                data.dx = data_conv_x(data.dx, 
     334                                                      units=default_q_unit) 
     335                            if data.dxl is not None: 
     336                                data.dxl = data_conv_x(data.dxl, 
     337                                                       units=default_q_unit) 
     338                            if data.dxw is not None: 
     339                                data.dxw = data_conv_x(data.dxw, 
     340                                                       units=default_q_unit) 
     341                elif isinstance(data, Data2D): 
     342                    if convert_q: 
     343                        data.qx_data = data_conv_x(data.qx_data, 
     344                                                   units=default_q_unit) 
     345                        if data.dqx_data is not None: 
     346                            data.dqx_data = data_conv_x(data.dqx_data, 
     347                                                        units=default_q_unit) 
     348                        try: 
     349                            file_y_unit = data._yunit 
     350                            data_conv_y = Converter(file_y_unit) 
     351                            data.qy_data = data_conv_y(data.qy_data, 
     352                                                       units=default_q_unit) 
     353                            if data.dqy_data is not None: 
     354                                data.dqy_data = data_conv_y(data.dqy_data, 
     355                                                            units=default_q_unit) 
     356                        except KeyError: 
     357                            logger.info("Unrecognized Qy units in data file. No" 
     358                                        " data conversion attempted") 
     359            except KeyError: 
     360                message = "Unable to convert Q units from {0} to 1/A." 
     361                message.format(default_q_unit) 
     362                data.errors.append(message) 
     363            new_output.append(data) 
     364        self.output = new_output 
    279365 
    280366    def format_unit(self, unit=None): 
     
    367453                    self.current_dataset.qy_data)) 
    368454            if has_error_dy: 
    369                 self.current_dataset.err_data = self.current_dataset.err_data[x != 0] 
     455                self.current_dataset.err_data = self.current_dataset.err_data[ 
     456                    x != 0] 
    370457            if has_error_dqx: 
    371                 self.current_dataset.dqx_data = self.current_dataset.dqx_data[x != 0] 
     458                self.current_dataset.dqx_data = self.current_dataset.dqx_data[ 
     459                    x != 0] 
    372460            if has_error_dqy: 
    373                 self.current_dataset.dqy_data = self.current_dataset.dqy_data[x != 0] 
     461                self.current_dataset.dqy_data = self.current_dataset.dqy_data[ 
     462                    x != 0] 
    374463            if has_mask: 
    375464                self.current_dataset.mask = self.current_dataset.mask[x != 0] 
  • src/sas/sascalc/dataloader/loader.py

    r4a8d55c rb1ec23d  
    367367            try: 
    368368                return fn(path, data) 
    369             except Exception: 
    370                 pass  # give other loaders a chance to succeed 
    371         # If we get here it is because all loaders failed 
    372         raise  # reraises last exception 
     369            except Exception as exc: 
     370                msg = "Saving file {} using the {} writer failed.\n".format( 
     371                    path, type(fn).__name__) 
     372                msg += str(exc) 
     373                logger.exception(msg)  # give other loaders a chance to succeed 
    373374 
    374375 
  • src/sas/sascalc/dataloader/readers/abs_reader.py

    rbd5c3b1 rbd5c3b1  
    225225            raise ValueError("ascii_reader: could not load file") 
    226226 
     227        self.current_dataset = self.set_default_1d_units(self.current_dataset) 
    227228        if data_conv_q is not None: 
    228229            self.current_dataset.xaxis("\\rm{Q}", base_q_unit) 
    229         else: 
    230             self.current_dataset.xaxis("\\rm{Q}", 'A^{-1}') 
    231230        if data_conv_i is not None: 
    232231            self.current_dataset.yaxis("\\rm{Intensity}", base_i_unit) 
    233         else: 
    234             self.current_dataset.yaxis("\\rm{Intensity}", "cm^{-1}") 
    235232 
    236233        # Store loading process information 
  • src/sas/sascalc/dataloader/readers/ascii_reader.py

    r7b07fbe r3bab401  
    157157 
    158158        self.remove_empty_q_values() 
    159         self.current_dataset.xaxis("\\rm{Q}", 'A^{-1}') 
    160         self.current_dataset.yaxis("\\rm{Intensity}", "cm^{-1}") 
     159        self.current_dataset = self.set_default_1d_units(self.current_dataset) 
    161160 
    162161        # Store loading process information 
  • src/sas/sascalc/dataloader/readers/cansas_reader.py

    r2469df7 r058f6c3  
    812812            node.append(point) 
    813813            self.write_node(point, "Q", datainfo.x[i], 
    814                             {'unit': datainfo.x_unit}) 
     814                            {'unit': datainfo._xunit}) 
    815815            if len(datainfo.y) >= i: 
    816816                self.write_node(point, "I", datainfo.y[i], 
    817                                 {'unit': datainfo.y_unit}) 
     817                                {'unit': datainfo._yunit}) 
    818818            if datainfo.dy is not None and len(datainfo.dy) > i: 
    819819                self.write_node(point, "Idev", datainfo.dy[i], 
    820                                 {'unit': datainfo.y_unit}) 
     820                                {'unit': datainfo._yunit}) 
    821821            if datainfo.dx is not None and len(datainfo.dx) > i: 
    822822                self.write_node(point, "Qdev", datainfo.dx[i], 
    823                                 {'unit': datainfo.x_unit}) 
     823                                {'unit': datainfo._xunit}) 
    824824            if datainfo.dxw is not None and len(datainfo.dxw) > i: 
    825825                self.write_node(point, "dQw", datainfo.dxw[i], 
    826                                 {'unit': datainfo.x_unit}) 
     826                                {'unit': datainfo._xunit}) 
    827827            if datainfo.dxl is not None and len(datainfo.dxl) > i: 
    828828                self.write_node(point, "dQl", datainfo.dxl[i], 
    829                                 {'unit': datainfo.x_unit}) 
     829                                {'unit': datainfo._xunit}) 
    830830        if datainfo.isSesans: 
    831831            sesans_attrib = {'x_axis': datainfo._xaxis, 
  • src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py

    r61f329f0 ra165bee  
    11""" 
    2     CanSAS 2D data reader for reading HDF5 formatted CanSAS files. 
     2    NXcanSAS data reader for reading HDF5 formatted CanSAS files. 
    33""" 
    44 
     
    1212    Data1D, Data2D, DataInfo, Process, Aperture, Collimation, \ 
    1313    TransmissionSpectrum, Detector 
    14 from ..data_info import combine_data_info_with_plottable 
    1514from ..loader_exceptions import FileContentsException, DefaultReaderException 
    1615from ..file_reader_base_class import FileReader, decode 
    1716 
     17 
    1818def h5attr(node, key, default=None): 
    1919    return decode(node.attrs.get(key, default)) 
    2020 
     21 
    2122class Reader(FileReader): 
    2223    """ 
    23     A class for reading in CanSAS v2.0 data files. The existing iteration opens 
    24     Mantid generated HDF5 formatted files with file extension .h5/.H5. Any 
    25     number of data sets may be present within the file and any dimensionality 
    26     of data may be used. Currently 1D and 2D SAS data sets are supported, but 
    27     future implementations will include 1D and 2D SESANS data. 
    28  
    29     Any number of SASdata sets may be present in a SASentry and the data within 
    30     can be either 1D I(Q) or 2D I(Qx, Qy). 
    31  
    32     Also supports reading NXcanSAS formatted HDF5 files 
     24    A class for reading in NXcanSAS data files. The current implementation has 
     25    been tested to load data generated by multiple facilities, all of which are 
     26    known to produce NXcanSAS standards compliant data. Any number of data sets 
     27    may be present within the file and any dimensionality of data may be used. 
     28    Currently 1D and 2D SAS data sets are supported, but should be immediately 
     29    extensible to SESANS data. 
     30 
     31    Any number of SASdata groups  may be present in a SASentry and the data 
     32    within each SASdata group can be a single 1D I(Q), multi-framed 1D I(Q), 
     33    2D I(Qx, Qy) or multi-framed 2D I(Qx, Qy). 
    3334 
    3435    :Dependencies: 
    35         The CanSAS HDF5 reader requires h5py => v2.5.0 or later. 
     36        The NXcanSAS HDF5 reader requires h5py => v2.5.0 or later. 
    3637    """ 
    3738 
    3839    # CanSAS version 
    3940    cansas_version = 2.0 
    40     # Logged warnings or messages 
    41     logging = None 
    42     # List of errors for the current data set 
    43     errors = None 
    44     # Raw file contents to be processed 
    45     raw_data = None 
    46     # List of plottable1D objects that should be linked to the current_datainfo 
    47     data1d = None 
    48     # List of plottable2D objects that should be linked to the current_datainfo 
    49     data2d = None 
    5041    # Data type name 
    51     type_name = "CanSAS 2.0" 
     42    type_name = "NXcanSAS" 
    5243    # Wildcards 
    53     type = ["CanSAS 2.0 HDF5 Files (*.h5)|*.h5"] 
     44    type = ["NXcanSAS HDF5 Files (*.h5)|*.h5|"] 
    5445    # List of allowed extensions 
    5546    ext = ['.h5', '.H5'] 
     
    8172                except Exception as e: 
    8273                    if extension not in self.ext: 
    83                         msg = "CanSAS2.0 HDF5 Reader could not load file {}".format(basename + extension) 
     74                        msg = "NXcanSAS Reader could not load file {}".format( 
     75                            basename + extension) 
    8476                        raise DefaultReaderException(msg) 
    8577                    raise FileContentsException(e.message) 
     
    9587                    self.raw_data.close() 
    9688 
    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.") 
     89                for data_set in self.output: 
     90                    if isinstance(data_set, Data1D): 
     91                        if data_set.x.size < 5: 
     92                            exception = FileContentsException( 
     93                                "Fewer than 5 data points found.") 
     94                            data_set.errors.append(exception) 
    10295 
    10396    def reset_state(self): 
     
    109102        self.data2d = [] 
    110103        self.raw_data = None 
    111         self.errors = set() 
     104        self.multi_frame = False 
     105        self.data_frames = [] 
     106        self.data_uncertainty_frames = [] 
     107        self.errors = [] 
    112108        self.logging = [] 
     109        self.q_names = [] 
     110        self.mask_name = u'' 
     111        self.i_name = u'' 
     112        self.i_node = u'' 
     113        self.i_uncertainties_name = u'' 
     114        self.q_uncertainty_names = [] 
     115        self.q_resolution_names = [] 
    113116        self.parent_class = u'' 
    114117        self.detector = Detector() 
     
    131134            value = data.get(key) 
    132135            class_name = h5attr(value, u'canSAS_class') 
     136            if isinstance(class_name, (list, tuple, np.ndarray)): 
     137                class_name = class_name[0] 
    133138            if class_name is None: 
    134139                class_name = h5attr(value, u'NX_class') 
     
    140145            if isinstance(value, h5py.Group): 
    141146                # Set parent class before recursion 
     147                last_parent_class = self.parent_class 
    142148                self.parent_class = class_name 
    143149                parent_list.append(key) 
     
    147153                    self.add_data_set(key) 
    148154                elif class_prog.match(u'SASdata'): 
    149                     self._initialize_new_data_set(parent_list) 
     155                    self._find_data_attributes(value) 
     156                    self._initialize_new_data_set(value) 
    150157                # Recursion step to access data within the group 
    151158                self.read_children(value, parent_list) 
     159                self.add_intermediate() 
    152160                # Reset parent class when returning from recursive method 
    153                 self.parent_class = class_name 
    154                 self.add_intermediate() 
     161                self.parent_class = last_parent_class 
    155162                parent_list.remove(key) 
    156163 
    157164            elif isinstance(value, h5py.Dataset): 
    158165                # If this is a dataset, store the data appropriately 
    159                 data_set = data[key][:] 
     166                data_set = value.value 
    160167                unit = self._get_unit(value) 
    161  
    162                 # I and Q Data 
    163                 if key == u'I': 
    164                     if isinstance(self.current_dataset, plottable_2D): 
    165                         self.current_dataset.data = data_set 
    166                         self.current_dataset.zaxis("Intensity", unit) 
    167                     else: 
    168                         self.current_dataset.y = data_set.flatten() 
    169                         self.current_dataset.yaxis("Intensity", unit) 
    170                     continue 
    171                 elif key == u'Idev': 
    172                     if isinstance(self.current_dataset, plottable_2D): 
    173                         self.current_dataset.err_data = data_set.flatten() 
    174                     else: 
    175                         self.current_dataset.dy = data_set.flatten() 
    176                     continue 
    177                 elif key == u'Q': 
    178                     self.current_dataset.xaxis("Q", unit) 
    179                     if isinstance(self.current_dataset, plottable_2D): 
    180                         self.current_dataset.q = data_set.flatten() 
    181                     else: 
    182                         self.current_dataset.x = data_set.flatten() 
    183                     continue 
    184                 elif key == u'Qdev': 
    185                     self.current_dataset.dx = data_set.flatten() 
    186                     continue 
    187                 elif key == u'dQw': 
    188                     self.current_dataset.dxw = data_set.flatten() 
    189                     continue 
    190                 elif key == u'dQl': 
    191                     self.current_dataset.dxl = data_set.flatten() 
    192                     continue 
    193                 elif key == u'Qy': 
    194                     self.current_dataset.yaxis("Q_y", unit) 
    195                     self.current_dataset.qy_data = data_set.flatten() 
    196                     continue 
    197                 elif key == u'Qydev': 
    198                     self.current_dataset.dqy_data = data_set.flatten() 
    199                     continue 
    200                 elif key == u'Qx': 
    201                     self.current_dataset.xaxis("Q_x", unit) 
    202                     self.current_dataset.qx_data = data_set.flatten() 
    203                     continue 
    204                 elif key == u'Qxdev': 
    205                     self.current_dataset.dqx_data = data_set.flatten() 
    206                     continue 
    207                 elif key == u'Mask': 
    208                     self.current_dataset.mask = data_set.flatten() 
    209                     continue 
    210                 # Transmission Spectrum 
    211                 elif (key == u'T' 
    212                       and self.parent_class == u'SAStransmission_spectrum'): 
    213                     self.trans_spectrum.transmission = data_set.flatten() 
    214                     continue 
    215                 elif (key == u'Tdev' 
    216                       and self.parent_class == u'SAStransmission_spectrum'): 
    217                     self.trans_spectrum.transmission_deviation = \ 
    218                         data_set.flatten() 
    219                     continue 
    220                 elif (key == u'lambda' 
    221                       and self.parent_class == u'SAStransmission_spectrum'): 
    222                     self.trans_spectrum.wavelength = data_set.flatten() 
    223                     continue 
    224168 
    225169                for data_point in data_set: 
     
    231175                    # Top Level Meta Data 
    232176                    if key == u'definition': 
    233                         self.current_datainfo.meta_data['reader'] = data_point 
     177                        if isinstance(data_set, basestring): 
     178                            self.current_datainfo.meta_data['reader'] = data_set 
     179                            break 
     180                        else: 
     181                            self.current_datainfo.meta_data[ 
     182                                'reader'] = data_point 
     183                    # Run 
    234184                    elif key == u'run': 
    235                         self.current_datainfo.run.append(data_point) 
    236185                        try: 
    237186                            run_name = h5attr(value, 'name') 
    238                             run_dict = {data_point: run_name} 
     187                            run_dict = {data_set: run_name} 
    239188                            self.current_datainfo.run_name = run_dict 
    240189                        except Exception: 
    241190                            pass 
     191                        if isinstance(data_set, basestring): 
     192                            self.current_datainfo.run.append(data_set) 
     193                            break 
     194                        else: 
     195                            self.current_datainfo.run.append(data_point) 
     196                    # Title 
    242197                    elif key == u'title': 
    243                         self.current_datainfo.title = data_point 
     198                        if isinstance(data_set, basestring): 
     199                            self.current_datainfo.title = data_set 
     200                            break 
     201                        else: 
     202                            self.current_datainfo.title = data_point 
     203                    # Note 
    244204                    elif key == u'SASnote': 
    245                         self.current_datainfo.notes.append(data_point) 
    246  
     205                        self.current_datainfo.notes.append(data_set) 
     206                        break 
    247207                    # Sample Information 
    248                     # CanSAS 2.0 format 
    249                     elif key == u'Title' and self.parent_class == u'SASsample': 
    250                         self.current_datainfo.sample.name = data_point 
    251                     # NXcanSAS format 
    252                     elif key == u'name' and self.parent_class == u'SASsample': 
    253                         self.current_datainfo.sample.name = data_point 
    254                     # NXcanSAS format 
    255                     elif key == u'ID' and self.parent_class == u'SASsample': 
    256                         self.current_datainfo.sample.name = data_point 
    257                     elif (key == u'thickness' 
    258                           and self.parent_class == u'SASsample'): 
    259                         self.current_datainfo.sample.thickness = data_point 
    260                     elif (key == u'temperature' 
    261                           and self.parent_class == u'SASsample'): 
    262                         self.current_datainfo.sample.temperature = data_point 
    263                     elif (key == u'transmission' 
    264                           and self.parent_class == u'SASsample'): 
    265                         self.current_datainfo.sample.transmission = data_point 
    266                     elif (key == u'x_position' 
    267                           and self.parent_class == u'SASsample'): 
    268                         self.current_datainfo.sample.position.x = data_point 
    269                     elif (key == u'y_position' 
    270                           and self.parent_class == u'SASsample'): 
    271                         self.current_datainfo.sample.position.y = data_point 
    272                     elif key == u'pitch' and self.parent_class == u'SASsample': 
    273                         self.current_datainfo.sample.orientation.x = data_point 
    274                     elif key == u'yaw' and self.parent_class == u'SASsample': 
    275                         self.current_datainfo.sample.orientation.y = data_point 
    276                     elif key == u'roll' and self.parent_class == u'SASsample': 
    277                         self.current_datainfo.sample.orientation.z = data_point 
    278                     elif (key == u'details' 
    279                           and self.parent_class == u'SASsample'): 
    280                         self.current_datainfo.sample.details.append(data_point) 
    281  
     208                    elif self.parent_class == u'SASsample': 
     209                        self.process_sample(data_point, key) 
    282210                    # Instrumental Information 
    283211                    elif (key == u'name' 
    284212                          and self.parent_class == u'SASinstrument'): 
    285213                        self.current_datainfo.instrument = data_point 
    286                     elif key == u'name' and self.parent_class == u'SASdetector': 
    287                         self.detector.name = data_point 
    288                     elif key == u'SDD' and self.parent_class == u'SASdetector': 
    289                         self.detector.distance = float(data_point) 
    290                         self.detector.distance_unit = unit 
    291                     elif (key == u'slit_length' 
    292                           and self.parent_class == u'SASdetector'): 
    293                         self.detector.slit_length = float(data_point) 
    294                         self.detector.slit_length_unit = unit 
    295                     elif (key == u'x_position' 
    296                           and self.parent_class == u'SASdetector'): 
    297                         self.detector.offset.x = float(data_point) 
    298                         self.detector.offset_unit = unit 
    299                     elif (key == u'y_position' 
    300                           and self.parent_class == u'SASdetector'): 
    301                         self.detector.offset.y = float(data_point) 
    302                         self.detector.offset_unit = unit 
    303                     elif (key == u'pitch' 
    304                           and self.parent_class == u'SASdetector'): 
    305                         self.detector.orientation.x = float(data_point) 
    306                         self.detector.orientation_unit = unit 
    307                     elif key == u'roll' and self.parent_class == u'SASdetector': 
    308                         self.detector.orientation.z = float(data_point) 
    309                         self.detector.orientation_unit = unit 
    310                     elif key == u'yaw' and self.parent_class == u'SASdetector': 
    311                         self.detector.orientation.y = float(data_point) 
    312                         self.detector.orientation_unit = unit 
    313                     elif (key == u'beam_center_x' 
    314                           and self.parent_class == u'SASdetector'): 
    315                         self.detector.beam_center.x = float(data_point) 
    316                         self.detector.beam_center_unit = unit 
    317                     elif (key == u'beam_center_y' 
    318                           and self.parent_class == u'SASdetector'): 
    319                         self.detector.beam_center.y = float(data_point) 
    320                         self.detector.beam_center_unit = unit 
    321                     elif (key == u'x_pixel_size' 
    322                           and self.parent_class == u'SASdetector'): 
    323                         self.detector.pixel_size.x = float(data_point) 
    324                         self.detector.pixel_size_unit = unit 
    325                     elif (key == u'y_pixel_size' 
    326                           and self.parent_class == u'SASdetector'): 
    327                         self.detector.pixel_size.y = float(data_point) 
    328                         self.detector.pixel_size_unit = unit 
    329                     elif (key == u'distance' 
    330                           and self.parent_class == u'SAScollimation'): 
    331                         self.collimation.length = data_point 
    332                         self.collimation.length_unit = unit 
    333                     elif (key == u'name' 
    334                           and self.parent_class == u'SAScollimation'): 
    335                         self.collimation.name = data_point 
    336                     elif (key == u'shape' 
    337                           and self.parent_class == u'SASaperture'): 
    338                         self.aperture.shape = data_point 
    339                     elif (key == u'x_gap' 
    340                           and self.parent_class == u'SASaperture'): 
    341                         self.aperture.size.x = data_point 
    342                     elif (key == u'y_gap' 
    343                           and self.parent_class == u'SASaperture'): 
    344                         self.aperture.size.y = data_point 
    345  
     214                    # Detector 
     215                    elif self.parent_class == u'SASdetector': 
     216                        self.process_detector(data_point, key, unit) 
     217                    # Collimation 
     218                    elif self.parent_class == u'SAScollimation': 
     219                        self.process_collimation(data_point, key, unit) 
     220                    # Aperture 
     221                    elif self.parent_class == u'SASaperture': 
     222                        self.process_aperture(data_point, key) 
    346223                    # Process Information 
    347                     elif (key == u'Title' 
    348                           and self.parent_class == u'SASprocess'): # CanSAS 2.0 
    349                         self.process.name = data_point 
    350                     elif (key == u'name' 
    351                           and self.parent_class == u'SASprocess'): # NXcanSAS 
    352                         self.process.name = data_point 
    353                     elif (key == u'description' 
    354                           and self.parent_class == u'SASprocess'): 
    355                         self.process.description = data_point 
    356                     elif key == u'date' and self.parent_class == u'SASprocess': 
    357                         self.process.date = data_point 
    358                     elif key == u'term' and self.parent_class == u'SASprocess': 
    359                         self.process.term = data_point 
    360                     elif self.parent_class == u'SASprocess': 
    361                         self.process.notes.append(data_point) 
    362  
     224                    elif self.parent_class == u'SASprocess': # CanSAS 2.0 
     225                        self.process_process(data_point, key) 
    363226                    # Source 
    364                     elif (key == u'wavelength' 
    365                           and self.parent_class == u'SASdata'): 
    366                         self.current_datainfo.source.wavelength = data_point 
    367                         self.current_datainfo.source.wavelength_unit = unit 
    368                     elif (key == u'incident_wavelength' 
    369                           and self.parent_class == 'SASsource'): 
    370                         self.current_datainfo.source.wavelength = data_point 
    371                         self.current_datainfo.source.wavelength_unit = unit 
    372                     elif (key == u'wavelength_max' 
    373                           and self.parent_class == u'SASsource'): 
    374                         self.current_datainfo.source.wavelength_max = data_point 
    375                         self.current_datainfo.source.wavelength_max_unit = unit 
    376                     elif (key == u'wavelength_min' 
    377                           and self.parent_class == u'SASsource'): 
    378                         self.current_datainfo.source.wavelength_min = data_point 
    379                         self.current_datainfo.source.wavelength_min_unit = unit 
    380                     elif (key == u'incident_wavelength_spread' 
    381                           and self.parent_class == u'SASsource'): 
    382                         self.current_datainfo.source.wavelength_spread = \ 
    383                             data_point 
    384                         self.current_datainfo.source.wavelength_spread_unit = \ 
    385                             unit 
    386                     elif (key == u'beam_size_x' 
    387                           and self.parent_class == u'SASsource'): 
    388                         self.current_datainfo.source.beam_size.x = data_point 
    389                         self.current_datainfo.source.beam_size_unit = unit 
    390                     elif (key == u'beam_size_y' 
    391                           and self.parent_class == u'SASsource'): 
    392                         self.current_datainfo.source.beam_size.y = data_point 
    393                         self.current_datainfo.source.beam_size_unit = unit 
    394                     elif (key == u'beam_shape' 
    395                           and self.parent_class == u'SASsource'): 
    396                         self.current_datainfo.source.beam_shape = data_point 
    397                     elif (key == u'radiation' 
    398                           and self.parent_class == u'SASsource'): 
    399                         self.current_datainfo.source.radiation = data_point 
    400                     elif (key == u'transmission' 
    401                           and self.parent_class == u'SASdata'): 
    402                         self.current_datainfo.sample.transmission = data_point 
    403  
     227                    elif self.parent_class == u'SASsource': 
     228                        self.process_source(data_point, key, unit) 
    404229                    # Everything else goes in meta_data 
     230                    elif self.parent_class == u'SASdata': 
     231                        if isinstance(self.current_dataset, plottable_2D): 
     232                            self.process_2d_data_object(data_set, key, unit) 
     233                        else: 
     234                            self.process_1d_data_object(data_set, key, unit) 
     235 
     236                        break 
     237                    elif self.parent_class == u'SAStransmission_spectrum': 
     238                        self.process_trans_spectrum(data_set, key) 
     239                        break 
    405240                    else: 
    406241                        new_key = self._create_unique_key( 
     
    410245            else: 
    411246                # I don't know if this reachable code 
    412                 self.errors.add("ShouldNeverHappenException") 
     247                self.errors.append("ShouldNeverHappenException") 
     248 
     249    def process_1d_data_object(self, data_set, key, unit): 
     250        """ 
     251        SASdata processor method for 1d data items 
     252        :param data_set: data from HDF5 file 
     253        :param key: canSAS_class attribute 
     254        :param unit: unit attribute 
     255        """ 
     256        if key == self.i_name: 
     257            if self.multi_frame: 
     258                for x in range(0, data_set.shape[0]): 
     259                    self.data_frames.append(data_set[x].flatten()) 
     260            else: 
     261                self.current_dataset.y = data_set.flatten() 
     262                self.current_dataset.yaxis("Intensity", unit) 
     263        elif key == self.i_uncertainties_name: 
     264            if self.multi_frame: 
     265                for x in range(0, data_set.shape[0]): 
     266                    self.data_uncertainty_frames.append(data_set[x].flatten()) 
     267            self.current_dataset.dy = data_set.flatten() 
     268        elif key in self.q_names: 
     269            self.current_dataset.xaxis("Q", unit) 
     270            self.current_dataset.x = data_set.flatten() 
     271        elif key in self.q_resolution_names: 
     272            if (len(self.q_resolution_names) > 1 
     273                    and np.where(self.q_resolution_names == key)[0] == 0): 
     274                self.current_dataset.dxw = data_set.flatten() 
     275            elif (len(self.q_resolution_names) > 1 
     276                  and np.where(self.q_resolution_names == key)[0] == 1): 
     277                self.current_dataset.dxl = data_set.flatten() 
     278            else: 
     279                self.current_dataset.dx = data_set.flatten() 
     280        elif key in self.q_uncertainty_names: 
     281            if (len(self.q_uncertainty_names) > 1 
     282                    and np.where(self.q_uncertainty_names == key)[0] == 0): 
     283                self.current_dataset.dxw = data_set.flatten() 
     284            elif (len(self.q_uncertainty_names) > 1 
     285                  and np.where(self.q_uncertainty_names == key)[0] == 1): 
     286                self.current_dataset.dxl = data_set.flatten() 
     287            else: 
     288                self.current_dataset.dx = data_set.flatten() 
     289        elif key == self.mask_name: 
     290            self.current_dataset.mask = data_set.flatten() 
     291        elif key == u'wavelength': 
     292            self.current_datainfo.source.wavelength = data_set[0] 
     293            self.current_datainfo.source.wavelength_unit = unit 
     294 
     295    def process_2d_data_object(self, data_set, key, unit): 
     296        if key == self.i_name: 
     297            self.current_dataset.data = data_set 
     298            self.current_dataset.zaxis("Intensity", unit) 
     299        elif key == self.i_uncertainties_name: 
     300            self.current_dataset.err_data = data_set.flatten() 
     301        elif key in self.q_names: 
     302            self.current_dataset.xaxis("Q_x", unit) 
     303            self.current_dataset.yaxis("Q_y", unit) 
     304            if self.q_names[0] == self.q_names[1]: 
     305                # All q data in a single array 
     306                self.current_dataset.qx_data = data_set[0] 
     307                self.current_dataset.qy_data = data_set[1] 
     308            elif self.q_names.index(key) == 0: 
     309                self.current_dataset.qx_data = data_set 
     310            elif self.q_names.index(key) == 1: 
     311                self.current_dataset.qy_data = data_set 
     312        elif key in self.q_uncertainty_names or key in self.q_resolution_names: 
     313            if ((self.q_uncertainty_names[0] == self.q_uncertainty_names[1]) or 
     314                    (self.q_resolution_names[0] == self.q_resolution_names[1])): 
     315                # All q data in a single array 
     316                self.current_dataset.dqx_data = data_set[0].flatten() 
     317                self.current_dataset.dqy_data = data_set[1].flatten() 
     318            elif (self.q_uncertainty_names.index(key) == 0 or 
     319                  self.q_resolution_names.index(key) == 0): 
     320                self.current_dataset.dqx_data = data_set.flatten() 
     321            elif (self.q_uncertainty_names.index(key) == 1 or 
     322                  self.q_resolution_names.index(key) == 1): 
     323                self.current_dataset.dqy_data = data_set.flatten() 
     324                self.current_dataset.yaxis("Q_y", unit) 
     325        elif key == self.mask_name: 
     326            self.current_dataset.mask = data_set.flatten() 
     327        elif key == u'Qy': 
     328            self.current_dataset.yaxis("Q_y", unit) 
     329            self.current_dataset.qy_data = data_set.flatten() 
     330        elif key == u'Qydev': 
     331            self.current_dataset.dqy_data = data_set.flatten() 
     332        elif key == u'Qx': 
     333            self.current_dataset.xaxis("Q_x", unit) 
     334            self.current_dataset.qx_data = data_set.flatten() 
     335        elif key == u'Qxdev': 
     336            self.current_dataset.dqx_data = data_set.flatten() 
     337 
     338    def process_trans_spectrum(self, data_set, key): 
     339        """ 
     340        SAStransmission_spectrum processor 
     341        :param data_set: data from HDF5 file 
     342        :param key: canSAS_class attribute 
     343        """ 
     344        if key == u'T': 
     345            self.trans_spectrum.transmission = data_set.flatten() 
     346        elif key == u'Tdev': 
     347            self.trans_spectrum.transmission_deviation = data_set.flatten() 
     348        elif key == u'lambda': 
     349            self.trans_spectrum.wavelength = data_set.flatten() 
     350 
     351    def process_sample(self, data_point, key): 
     352        """ 
     353        SASsample processor 
     354        :param data_point: Single point from an HDF5 data file 
     355        :param key: class name data_point was taken from 
     356        """ 
     357        if key == u'Title': 
     358            self.current_datainfo.sample.name = data_point 
     359        elif key == u'name': 
     360            self.current_datainfo.sample.name = data_point 
     361        elif key == u'ID': 
     362            self.current_datainfo.sample.name = data_point 
     363        elif key == u'thickness': 
     364            self.current_datainfo.sample.thickness = data_point 
     365        elif key == u'temperature': 
     366            self.current_datainfo.sample.temperature = data_point 
     367        elif key == u'transmission': 
     368            self.current_datainfo.sample.transmission = data_point 
     369        elif key == u'x_position': 
     370            self.current_datainfo.sample.position.x = data_point 
     371        elif key == u'y_position': 
     372            self.current_datainfo.sample.position.y = data_point 
     373        elif key == u'pitch': 
     374            self.current_datainfo.sample.orientation.x = data_point 
     375        elif key == u'yaw': 
     376            self.current_datainfo.sample.orientation.y = data_point 
     377        elif key == u'roll': 
     378            self.current_datainfo.sample.orientation.z = data_point 
     379        elif key == u'details': 
     380            self.current_datainfo.sample.details.append(data_point) 
     381 
     382    def process_detector(self, data_point, key, unit): 
     383        """ 
     384        SASdetector processor 
     385        :param data_point: Single point from an HDF5 data file 
     386        :param key: class name data_point was taken from 
     387        :param unit: unit attribute from data set 
     388        """ 
     389        if key == u'name': 
     390            self.detector.name = data_point 
     391        elif key == u'SDD': 
     392            self.detector.distance = float(data_point) 
     393            self.detector.distance_unit = unit 
     394        elif key == u'slit_length': 
     395            self.detector.slit_length = float(data_point) 
     396            self.detector.slit_length_unit = unit 
     397        elif key == u'x_position': 
     398            self.detector.offset.x = float(data_point) 
     399            self.detector.offset_unit = unit 
     400        elif key == u'y_position': 
     401            self.detector.offset.y = float(data_point) 
     402            self.detector.offset_unit = unit 
     403        elif key == u'pitch': 
     404            self.detector.orientation.x = float(data_point) 
     405            self.detector.orientation_unit = unit 
     406        elif key == u'roll': 
     407            self.detector.orientation.z = float(data_point) 
     408            self.detector.orientation_unit = unit 
     409        elif key == u'yaw': 
     410            self.detector.orientation.y = float(data_point) 
     411            self.detector.orientation_unit = unit 
     412        elif key == u'beam_center_x': 
     413            self.detector.beam_center.x = float(data_point) 
     414            self.detector.beam_center_unit = unit 
     415        elif key == u'beam_center_y': 
     416            self.detector.beam_center.y = float(data_point) 
     417            self.detector.beam_center_unit = unit 
     418        elif key == u'x_pixel_size': 
     419            self.detector.pixel_size.x = float(data_point) 
     420            self.detector.pixel_size_unit = unit 
     421        elif key == u'y_pixel_size': 
     422            self.detector.pixel_size.y = float(data_point) 
     423            self.detector.pixel_size_unit = unit 
     424 
     425    def process_collimation(self, data_point, key, unit): 
     426        """ 
     427        SAScollimation processor 
     428        :param data_point: Single point from an HDF5 data file 
     429        :param key: class name data_point was taken from 
     430        :param unit: unit attribute from data set 
     431        """ 
     432        if key == u'distance': 
     433            self.collimation.length = data_point 
     434            self.collimation.length_unit = unit 
     435        elif key == u'name': 
     436            self.collimation.name = data_point 
     437 
     438    def process_aperture(self, data_point, key): 
     439        """ 
     440        SASaperture processor 
     441        :param data_point: Single point from an HDF5 data file 
     442        :param key: class name data_point was taken from 
     443        """ 
     444        if key == u'shape': 
     445            self.aperture.shape = data_point 
     446        elif key == u'x_gap': 
     447            self.aperture.size.x = data_point 
     448        elif key == u'y_gap': 
     449            self.aperture.size.y = data_point 
     450 
     451    def process_source(self, data_point, key, unit): 
     452        """ 
     453        SASsource processor 
     454        :param data_point: Single point from an HDF5 data file 
     455        :param key: class name data_point was taken from 
     456        :param unit: unit attribute from data set 
     457        """ 
     458        if key == u'incident_wavelength': 
     459            self.current_datainfo.source.wavelength = data_point 
     460            self.current_datainfo.source.wavelength_unit = unit 
     461        elif key == u'wavelength_max': 
     462            self.current_datainfo.source.wavelength_max = data_point 
     463            self.current_datainfo.source.wavelength_max_unit = unit 
     464        elif key == u'wavelength_min': 
     465            self.current_datainfo.source.wavelength_min = data_point 
     466            self.current_datainfo.source.wavelength_min_unit = unit 
     467        elif key == u'incident_wavelength_spread': 
     468            self.current_datainfo.source.wavelength_spread = data_point 
     469            self.current_datainfo.source.wavelength_spread_unit = unit 
     470        elif key == u'beam_size_x': 
     471            self.current_datainfo.source.beam_size.x = data_point 
     472            self.current_datainfo.source.beam_size_unit = unit 
     473        elif key == u'beam_size_y': 
     474            self.current_datainfo.source.beam_size.y = data_point 
     475            self.current_datainfo.source.beam_size_unit = unit 
     476        elif key == u'beam_shape': 
     477            self.current_datainfo.source.beam_shape = data_point 
     478        elif key == u'radiation': 
     479            self.current_datainfo.source.radiation = data_point 
     480 
     481    def process_process(self, data_point, key): 
     482        """ 
     483        SASprocess processor 
     484        :param data_point: Single point from an HDF5 data file 
     485        :param key: class name data_point was taken from 
     486        """ 
     487        term_match = re.compile(u'^term[0-9]+$') 
     488        if key == u'Title':  # CanSAS 2.0 
     489            self.process.name = data_point 
     490        elif key == u'name':  # NXcanSAS 
     491            self.process.name = data_point 
     492        elif key == u'description': 
     493            self.process.description = data_point 
     494        elif key == u'date': 
     495            self.process.date = data_point 
     496        elif term_match.match(key): 
     497            self.process.term.append(data_point) 
     498        else: 
     499            self.process.notes.append(data_point) 
    413500 
    414501    def add_intermediate(self): 
     
    440527                self.data2d.append(self.current_dataset) 
    441528            elif isinstance(self.current_dataset, plottable_1D): 
    442                 self.data1d.append(self.current_dataset) 
     529                if self.multi_frame: 
     530                    for x in range(0, len(self.data_frames)): 
     531                        self.current_dataset.y = self.data_frames[x] 
     532                        if len(self.data_uncertainty_frames) > x: 
     533                            self.current_dataset.dy = \ 
     534                                self.data_uncertainty_frames[x] 
     535                        self.data1d.append(self.current_dataset) 
     536                else: 
     537                    self.data1d.append(self.current_dataset) 
    443538 
    444539    def final_data_cleanup(self): 
     
    452547            spectrum_list = [] 
    453548            for spectrum in self.current_datainfo.trans_spectrum: 
    454                 spectrum.transmission = np.delete(spectrum.transmission, [0]) 
    455549                spectrum.transmission = spectrum.transmission.astype(np.float64) 
    456                 spectrum.transmission_deviation = np.delete( 
    457                     spectrum.transmission_deviation, [0]) 
    458550                spectrum.transmission_deviation = \ 
    459551                    spectrum.transmission_deviation.astype(np.float64) 
    460                 spectrum.wavelength = np.delete(spectrum.wavelength, [0]) 
    461552                spectrum.wavelength = spectrum.wavelength.astype(np.float64) 
    462553                if len(spectrum.transmission) > 0: 
     
    466557        # Append errors to dataset and reset class errors 
    467558        self.current_datainfo.errors = self.errors 
    468         self.errors.clear() 
     559        self.errors = [] 
    469560 
    470561        # Combine all plottables with datainfo and append each to output 
     
    476567                    zeros[i] = dataset.mask[i] 
    477568            except: 
    478                 self.errors.add(sys.exc_value) 
     569                self.errors.append(sys.exc_value) 
    479570            dataset.mask = zeros 
    480571            # Calculate the actual Q matrix 
     
    490581            if dataset.data.ndim == 2: 
    491582                (n_rows, n_cols) = dataset.data.shape 
    492                 dataset.y_bins = dataset.qy_data[0::n_cols] 
    493                 dataset.x_bins = dataset.qx_data[:n_cols] 
     583                flat_qy = dataset.qy_data[0::n_cols].flatten() 
     584                # For 2D arrays of Qx and Qy, the Q value should be constant 
     585                # along each row -OR- each column. The direction is not 
     586                # specified in the NXcanSAS standard. 
     587                if flat_qy[0] == flat_qy[1]: 
     588                    flat_qy = np.transpose(dataset.qy_data)[0::n_cols].flatten() 
     589                dataset.y_bins = np.unique(flat_qy) 
     590                flat_qx = dataset.qx_data[0::n_rows].flatten() 
     591                # For 2D arrays of Qx and Qy, the Q value should be constant 
     592                # along each row -OR- each column. The direction is not 
     593                # specified in the NXcanSAS standard. 
     594                if flat_qx[0] == flat_qx[1]: 
     595                    flat_qx = np.transpose(dataset.qx_data)[0::n_rows].flatten() 
     596                dataset.x_bins = np.unique(flat_qx) 
    494597                dataset.data = dataset.data.flatten() 
     598                dataset.qx_data = dataset.qx_data.flatten() 
     599                dataset.qy_data = dataset.qy_data.flatten() 
    495600            self.current_dataset = dataset 
    496601            self.send_to_output() 
     
    511616        if self.current_datainfo and self.current_dataset: 
    512617            self.final_data_cleanup() 
     618        self.data_frames = [] 
     619        self.data_uncertainty_frames = [] 
    513620        self.data1d = [] 
    514621        self.data2d = [] 
    515622        self.current_datainfo = DataInfo() 
    516623 
    517  
    518     def _initialize_new_data_set(self, parent_list=None): 
     624    def _initialize_new_data_set(self, value=None): 
    519625        """ 
    520626        A private class method to generate a new 1D or 2D data object based on 
     
    524630        :param parent_list: List of names of parent elements 
    525631        """ 
    526  
    527         if parent_list is None: 
    528             parent_list = [] 
    529         if self._find_intermediate(parent_list, "Qx"): 
     632        if self._is2d(value): 
    530633            self.current_dataset = plottable_2D() 
    531634        else: 
     
    535638        self.current_datainfo.filename = self.raw_data.filename 
    536639 
    537     def _find_intermediate(self, parent_list, basename=""): 
    538         """ 
    539         A private class used to find an entry by either using a direct key or 
    540         knowing the approximate basename. 
    541  
    542         :param parent_list: List of parents nodes in the HDF5 file 
     640    @staticmethod 
     641    def check_is_list_or_array(iterable): 
     642        try: 
     643            iter(iterable) 
     644            if (not isinstance(iterable, np.ndarray) and not isinstance( 
     645                    iterable, list)) or (isinstance(iterable, basestring)): 
     646                raise TypeError 
     647        except TypeError: 
     648            if isinstance(iterable, basestring): 
     649                iterable = iterable.split(",") 
     650            else: 
     651                iterable = [iterable] 
     652        return iterable 
     653 
     654    def _find_data_attributes(self, value): 
     655        """ 
     656        A class to find the indices for Q, the name of the Qdev and Idev, and 
     657        the name of the mask. 
     658        :param value: SASdata/NXdata HDF5 Group 
     659        """ 
     660        # Initialize values to base types 
     661        self.mask_name = u'' 
     662        self.i_name = u'' 
     663        self.i_node = u'' 
     664        self.i_uncertainties_name = u'' 
     665        self.q_names = [] 
     666        self.q_uncertainty_names = [] 
     667        self.q_resolution_names = [] 
     668        # Get attributes 
     669        attrs = value.attrs 
     670        signal = attrs.get("signal", "I") 
     671        i_axes = attrs.get("I_axes", ["Q"]) 
     672        q_indices = attrs.get("Q_indices", [0]) 
     673        q_indices = map(int, self.check_is_list_or_array(q_indices)) 
     674        i_axes = self.check_is_list_or_array(i_axes) 
     675        keys = value.keys() 
     676        # Assign attributes to appropriate class variables 
     677        self.mask_name = attrs.get("mask") 
     678        for val in q_indices: 
     679            self.q_names.append(i_axes[val]) 
     680        self.i_name = signal 
     681        self.i_node = value.get(self.i_name) 
     682        for item in self.q_names: 
     683            if item in keys: 
     684                q_vals = value.get(item) 
     685                if q_vals.attrs.get("uncertainties") is not None: 
     686                    self.q_uncertainty_names = q_vals.attrs.get("uncertainties") 
     687                elif q_vals.attrs.get("uncertainty") is not None: 
     688                    self.q_uncertainty_names = q_vals.attrs.get("uncertainty") 
     689                if isinstance(self.q_uncertainty_names, basestring): 
     690                    self.q_uncertainty_names = self.q_uncertainty_names.split(",") 
     691                if q_vals.attrs.get("resolutions") is not None: 
     692                    self.q_resolution_names = q_vals.attrs.get("resolutions") 
     693                if isinstance(self.q_resolution_names, basestring): 
     694                    self.q_resolution_names = self.q_resolution_names.split(",") 
     695        if self.i_name in keys: 
     696            i_vals = value.get(self.i_name) 
     697            self.i_uncertainties_name = i_vals.attrs.get("uncertainties") 
     698            if self.i_uncertainties_name is None: 
     699                self.i_uncertainties_name = i_vals.attrs.get("uncertainty") 
     700 
     701    def _is2d(self, value, i_base="", q_base=[]): 
     702        """ 
     703        A private class to determine if the data set is 1d or 2d. 
     704 
     705        :param value: Nexus/NXcanSAS data group 
    543706        :param basename: Approximate name of an entry to search for 
    544         :return: 
    545         """ 
    546  
    547         entry = False 
    548         key_prog = re.compile(basename) 
    549         top = self.raw_data 
    550         for parent in parent_list: 
    551             top = top.get(parent) 
    552         for key in top.keys(): 
    553             if key_prog.match(key): 
    554                 entry = True 
    555                 break 
    556         return entry 
     707        :return: True if 2D, otherwise false 
     708        """ 
     709        i_basename = i_base if i_base != "" else self.i_name 
     710        i_vals = value.get(i_basename) 
     711        q_basename = q_base if q_base != [] else self.q_names 
     712        q_vals = value.get(q_basename[0]) 
     713        self.multi_frame = True if (i_vals is not None and q_vals is not None 
     714                                    and len(i_vals.shape) != 1 
     715                                    and len(q_vals.shape) == 1) else False 
     716        return (i_vals is not None and i_vals.shape is not None 
     717                and len(i_vals.shape) != 1 and not self.multi_frame) 
    557718 
    558719    def _create_unique_key(self, dictionary, name, numb=0): 
     
    583744        if unit is None: 
    584745            unit = h5attr(value, u'unit') 
    585         # Convert the unit formats 
    586         if unit == "1/A": 
    587             unit = "A^{-1}" 
    588         elif unit == "1/cm": 
    589             unit = "cm^{-1}" 
    590746        return unit 
  • src/sas/sascalc/dataloader/readers/danse_reader.py

    r2469df7 rfc51d06  
    180180        detector.beam_center.y = center_y * pixel 
    181181 
    182  
    183         self.current_dataset.xaxis("\\rm{Q_{x}}", 'A^{-1}') 
    184         self.current_dataset.yaxis("\\rm{Q_{y}}", 'A^{-1}') 
    185         self.current_dataset.zaxis("\\rm{Intensity}", "cm^{-1}") 
    186  
     182        self.current_dataset = self.set_default_2d_units(self.current_dataset) 
    187183        self.current_dataset.x_bins = x_vals 
    188184        self.current_dataset.y_bins = y_vals 
  • src/sas/sascalc/dataloader/readers/red2d_reader.py

    rc8321cfc r058f6c3  
    317317 
    318318        # Units of axes 
    319         self.current_dataset.xaxis(r"\rm{Q_{x}}", 'A^{-1}') 
    320         self.current_dataset.yaxis(r"\rm{Q_{y}}", 'A^{-1}') 
    321         self.current_dataset.zaxis(r"\rm{Intensity}", "cm^{-1}") 
     319        self.current_dataset = self.set_default_2d_units(self.current_dataset) 
    322320 
    323321        # Store loading process information 
  • src/sas/sascalc/file_converter/nxcansas_writer.py

    r574adc7 r2ca5d57b  
    88import os 
    99 
    10 from sas.sascalc.dataloader.readers.cansas_reader_HDF5 import Reader as Cansas2Reader 
     10from sas.sascalc.dataloader.readers.cansas_reader_HDF5 import Reader 
    1111from sas.sascalc.dataloader.data_info import Data1D, Data2D 
    1212 
    13 class NXcanSASWriter(Cansas2Reader): 
     13class NXcanSASWriter(Reader): 
    1414    """ 
    1515    A class for writing in NXcanSAS data files. Any number of data sets may be 
     
    8787                    entry[names[2]].attrs['units'] = units 
    8888 
    89         valid_data = all([issubclass(d.__class__, (Data1D, Data2D)) for d in dataset]) 
     89        valid_data = all([issubclass(d.__class__, (Data1D, Data2D)) for d in 
     90                          dataset]) 
    9091        if not valid_data: 
    91             raise ValueError("All entries of dataset must be Data1D or Data2D objects") 
     92            raise ValueError("All entries of dataset must be Data1D or Data2D" 
     93                             "objects") 
    9294 
    9395        # Get run name and number from first Data object 
     
    109111        sasentry.attrs['version'] = '1.0' 
    110112 
    111         i = 1 
    112  
    113         for data_obj in dataset: 
    114             data_entry = sasentry.create_group("sasdata{0:0=2d}".format(i)) 
     113        for i, data_obj in enumerate(dataset): 
     114            data_entry = sasentry.create_group("sasdata{0:0=2d}".format(i+1)) 
    115115            data_entry.attrs['canSAS_class'] = 'SASdata' 
    116116            if isinstance(data_obj, Data1D): 
     
    118118            elif isinstance(data_obj, Data2D): 
    119119                self._write_2d_data(data_obj, data_entry) 
    120             i += 1 
    121120 
    122121        data_info = dataset[0] 
     
    148147                sample_entry.create_dataset('details', data=details) 
    149148 
    150         # Instrumment metadata 
     149        # Instrument metadata 
    151150        instrument_entry = sasentry.create_group('sasinstrument') 
    152151        instrument_entry.attrs['canSAS_class'] = 'SASinstrument' 
     
    176175            units=data_info.source.beam_size_unit, write_fn=_write_h5_float) 
    177176 
    178  
    179177        # Collimation metadata 
    180178        if len(data_info.collimation) > 0: 
    181             i = 1 
    182             for coll_info in data_info.collimation: 
     179            for i, coll_info in enumerate(data_info.collimation): 
    183180                collimation_entry = instrument_entry.create_group( 
    184                     'sascollimation{0:0=2d}'.format(i)) 
     181                    'sascollimation{0:0=2d}'.format(i + 1)) 
    185182                collimation_entry.attrs['canSAS_class'] = 'SAScollimation' 
    186183                if coll_info.length is not None: 
    187184                    _write_h5_float(collimation_entry, coll_info.length, 'SDD') 
    188                     collimation_entry['SDD'].attrs['units'] = coll_info.length_unit 
     185                    collimation_entry['SDD'].attrs['units'] =\ 
     186                        coll_info.length_unit 
    189187                if coll_info.name is not None: 
    190188                    collimation_entry['name'] = _h5_string(coll_info.name) 
    191189        else: 
    192             # Create a blank one - at least 1 set of collimation metadata 
    193             # required by format 
    194             collimation_entry = instrument_entry.create_group('sascollimation01') 
     190            # Create a blank one - at least 1 collimation required by format 
     191            instrument_entry.create_group('sascollimation01') 
    195192 
    196193        # Detector metadata 
    197194        if len(data_info.detector) > 0: 
    198195            i = 1 
    199             for det_info in data_info.detector: 
     196            for i, det_info in enumerate(data_info.detector): 
    200197                detector_entry = instrument_entry.create_group( 
    201                     'sasdetector{0:0=2d}'.format(i)) 
     198                    'sasdetector{0:0=2d}'.format(i + 1)) 
    202199                detector_entry.attrs['canSAS_class'] = 'SASdetector' 
    203200                if det_info.distance is not None: 
    204201                    _write_h5_float(detector_entry, det_info.distance, 'SDD') 
    205                     detector_entry['SDD'].attrs['units'] = det_info.distance_unit 
     202                    detector_entry['SDD'].attrs['units'] =\ 
     203                        det_info.distance_unit 
    206204                if det_info.name is not None: 
    207205                    detector_entry['name'] = _h5_string(det_info.name) 
     
    209207                    detector_entry['name'] = _h5_string('') 
    210208                if det_info.slit_length is not None: 
    211                     _write_h5_float(detector_entry, det_info.slit_length, 'slit_length') 
    212                     detector_entry['slit_length'].attrs['units'] = det_info.slit_length_unit 
     209                    _write_h5_float(detector_entry, det_info.slit_length, 
     210                                    'slit_length') 
     211                    detector_entry['slit_length'].attrs['units'] =\ 
     212                        det_info.slit_length_unit 
    213213                _write_h5_vector(detector_entry, det_info.offset) 
    214214                # NXcanSAS doesn't save information about pitch, only roll 
     
    224224                    names=['x_pixel_size', 'y_pixel_size'], 
    225225                    write_fn=_write_h5_float, units=det_info.pixel_size_unit) 
    226  
    227                 i += 1 
    228226        else: 
    229227            # Create a blank one - at least 1 detector required by format 
     
    231229            detector_entry.attrs['canSAS_class'] = 'SASdetector' 
    232230            detector_entry.attrs['name'] = '' 
     231 
     232        # Process meta data 
     233        for i, process in enumerate(data_info.process): 
     234            process_entry = sasentry.create_group('sasprocess{0:0=2d}'.format( 
     235                i + 1)) 
     236            process_entry.attrs['canSAS_class'] = 'SASprocess' 
     237            if process.name: 
     238                name = _h5_string(process.name) 
     239                process_entry.create_dataset('name', data=name) 
     240            if process.date: 
     241                date = _h5_string(process.date) 
     242                process_entry.create_dataset('date', data=date) 
     243            if process.description: 
     244                desc = _h5_string(process.description) 
     245                process_entry.create_dataset('description', data=desc) 
     246            for j, term in enumerate(process.term): 
     247                # Don't save empty terms 
     248                if term: 
     249                    h5_term = _h5_string(term) 
     250                    process_entry.create_dataset('term{0:0=2d}'.format( 
     251                        j + 1), data=h5_term) 
     252            for j, note in enumerate(process.notes): 
     253                # Don't save empty notes 
     254                if note: 
     255                    h5_note = _h5_string(note) 
     256                    process_entry.create_dataset('note{0:0=2d}'.format( 
     257                        j + 1), data=h5_note) 
     258 
     259        # Transmission Spectrum 
     260        for i, trans in enumerate(data_info.trans_spectrum): 
     261            trans_entry = sasentry.create_group( 
     262                'sastransmission_spectrum{0:0=2d}'.format(i + 1)) 
     263            trans_entry.attrs['canSAS_class'] = 'SAStransmission_spectrum' 
     264            trans_entry.attrs['signal'] = 'T' 
     265            trans_entry.attrs['T_axes'] = 'T' 
     266            trans_entry.attrs['name'] = trans.name 
     267            if trans.timestamp is not '': 
     268                trans_entry.attrs['timestamp'] = trans.timestamp 
     269            transmission = trans_entry.create_dataset('T', 
     270                                                      data=trans.transmission) 
     271            transmission.attrs['unertainties'] = 'Tdev' 
     272            trans_entry.create_dataset('Tdev', 
     273                                       data=trans.transmission_deviation) 
     274            trans_entry.create_dataset('lambda', data=trans.wavelength) 
    233275 
    234276        note_entry = sasentry.create_group('sasnote'.format(i)) 
     
    254296        data_entry.attrs['signal'] = 'I' 
    255297        data_entry.attrs['I_axes'] = 'Q' 
    256         data_entry.attrs['I_uncertainties'] = 'Idev' 
    257         data_entry.attrs['Q_indicies'] = 0 
    258  
    259         dI = data_obj.dy 
    260         if dI is None: 
    261             dI = np.zeros((data_obj.y.shape)) 
    262  
    263         data_entry.create_dataset('Q', data=data_obj.x) 
    264         data_entry.create_dataset('I', data=data_obj.y) 
    265         data_entry.create_dataset('Idev', data=dI) 
     298        data_entry.attrs['Q_indices'] = [0] 
     299        q_entry = data_entry.create_dataset('Q', data=data_obj.x) 
     300        q_entry.attrs['units'] = data_obj.x_unit 
     301        i_entry = data_entry.create_dataset('I', data=data_obj.y) 
     302        i_entry.attrs['units'] = data_obj.y_unit 
     303        if data_obj.dy is not None: 
     304            i_entry.attrs['uncertainties'] = 'Idev' 
     305            i_dev_entry = data_entry.create_dataset('Idev', data=data_obj.dy) 
     306            i_dev_entry.attrs['units'] = data_obj.y_unit 
     307        if data_obj.dx is not None: 
     308            q_entry.attrs['resolutions'] = 'dQ' 
     309            dq_entry = data_entry.create_dataset('dQ', data=data_obj.dx) 
     310            dq_entry.attrs['units'] = data_obj.x_unit 
     311        elif data_obj.dxl is not None: 
     312            q_entry.attrs['resolutions'] = ['dQl','dQw'] 
     313            dql_entry = data_entry.create_dataset('dQl', data=data_obj.dxl) 
     314            dql_entry.attrs['units'] = data_obj.x_unit 
     315            dqw_entry = data_entry.create_dataset('dQw', data=data_obj.dxw) 
     316            dqw_entry.attrs['units'] = data_obj.x_unit 
    266317 
    267318    def _write_2d_data(self, data, data_entry): 
     
    273324        """ 
    274325        data_entry.attrs['signal'] = 'I' 
    275         data_entry.attrs['I_axes'] = 'Q,Q' 
    276         data_entry.attrs['I_uncertainties'] = 'Idev' 
    277         data_entry.attrs['Q_indicies'] = [0,1] 
     326        data_entry.attrs['I_axes'] = 'Qx,Qy' 
     327        data_entry.attrs['Q_indices'] = [0,1] 
    278328 
    279329        (n_rows, n_cols) = (len(data.y_bins), len(data.x_bins)) 
     
    288338                raise ValueError("Unable to calculate dimensions of 2D data") 
    289339 
    290         I = np.reshape(data.data, (n_rows, n_cols)) 
    291         dI = np.zeros((n_rows, n_cols)) 
    292         if not all(data.err_data == [None]): 
    293             dI = np.reshape(data.err_data, (n_rows, n_cols)) 
    294         qx =  np.reshape(data.qx_data, (n_rows, n_cols)) 
     340        intensity = np.reshape(data.data, (n_rows, n_cols)) 
     341        qx = np.reshape(data.qx_data, (n_rows, n_cols)) 
    295342        qy = np.reshape(data.qy_data, (n_rows, n_cols)) 
    296343 
    297         I_entry = data_entry.create_dataset('I', data=I) 
    298         I_entry.attrs['units'] = data.I_unit 
    299         Qx_entry = data_entry.create_dataset('Qx', data=qx) 
    300         Qx_entry.attrs['units'] = data.Q_unit 
    301         Qy_entry = data_entry.create_dataset('Qy', data=qy) 
    302         Qy_entry.attrs['units'] = data.Q_unit 
    303         Idev_entry = data_entry.create_dataset('Idev', data=dI) 
    304         Idev_entry.attrs['units'] = data.I_unit 
     344        i_entry = data_entry.create_dataset('I', data=intensity) 
     345        i_entry.attrs['units'] = data.I_unit 
     346        qx_entry = data_entry.create_dataset('Qx', data=qx) 
     347        qx_entry.attrs['units'] = data.Q_unit 
     348        qy_entry = data_entry.create_dataset('Qy', data=qy) 
     349        qy_entry.attrs['units'] = data.Q_unit 
     350        if data.err_data is not None and not all(data.err_data == [None]): 
     351            d_i = np.reshape(data.err_data, (n_rows, n_cols)) 
     352            i_entry.attrs['uncertainties'] = 'Idev' 
     353            i_dev_entry = data_entry.create_dataset('Idev', data=d_i) 
     354            i_dev_entry.attrs['units'] = data.I_unit 
     355        if data.dqx_data is not None and not all(data.dqx_data == [None]): 
     356            qx_entry.attrs['resolutions'] = 'dQx' 
     357            dqx_entry = data_entry.create_dataset('dQx', data=data.dqx_data) 
     358            dqx_entry.attrs['units'] = data.Q_unit 
     359        if data.dqy_data is not None and not all(data.dqy_data == [None]): 
     360            qy_entry.attrs['resolutions'] = 'dQy' 
     361            dqy_entry = data_entry.create_dataset('dQy', data=data.dqy_data) 
     362            dqy_entry.attrs['units'] = data.Q_unit 
  • src/sas/sasgui/guiframe/gui_manager.py

    r8ac05a5 r9f45f83  
    4646from sas.sasgui.guiframe.CategoryManager import CategoryManager 
    4747from sas.sascalc.dataloader.loader import Loader 
     48from sas.sascalc.file_converter.nxcansas_writer import NXcanSASWriter 
    4849from sas.sasgui.guiframe.proxy import Connection 
    4950 
     
    24192420        default_name = fname 
    24202421        wildcard = "Text files (*.txt)|*.txt|"\ 
    2421                     "CanSAS 1D files(*.xml)|*.xml" 
    2422         path = None 
     2422                    "CanSAS 1D files (*.xml)|*.xml|"\ 
     2423                     "NXcanSAS files (*.h5)|*.h5|" 
     2424        options = [".txt", ".xml",".h5"] 
    24232425        dlg = wx.FileDialog(self, "Choose a file", 
    24242426                            self._default_save_location, 
     
    24302432            # This is MAC Fix 
    24312433            ext_num = dlg.GetFilterIndex() 
    2432             if ext_num == 0: 
    2433                 ext_format = '.txt' 
    2434             else: 
    2435                 ext_format = '.xml' 
     2434 
     2435            ext_format = options[ext_num] 
    24362436            path = os.path.splitext(path)[0] + ext_format 
    24372437            mypath = os.path.basename(path) 
    2438  
    2439             # Instantiate a loader 
    2440             loader = Loader() 
    2441             ext_format = ".txt" 
    2442             if os.path.splitext(mypath)[1].lower() == ext_format: 
     2438            fName = os.path.splitext(path)[0] + ext_format 
     2439 
     2440            if os.path.splitext(mypath)[1].lower() == options[0]: 
    24432441                # Make sure the ext included in the file name 
    24442442                # especially on MAC 
    2445                 fName = os.path.splitext(path)[0] + ext_format 
    24462443                self._onsaveTXT(data, fName) 
    2447             ext_format = ".xml" 
    2448             if os.path.splitext(mypath)[1].lower() == ext_format: 
     2444            elif os.path.splitext(mypath)[1].lower() == options[1]: 
    24492445                # Make sure the ext included in the file name 
    24502446                # especially on MAC 
    2451                 fName = os.path.splitext(path)[0] + ext_format 
     2447                # Instantiate a loader 
     2448                loader = Loader() 
    24522449                loader.save(fName, data, ext_format) 
     2450            elif os.path.splitext(mypath)[1].lower() == options[2]: 
     2451                nxcansaswriter = NXcanSASWriter() 
     2452                nxcansaswriter.write([data], fName) 
    24532453            try: 
    24542454                self._default_save_location = os.path.dirname(path) 
     
    24772477            if has_errors: 
    24782478                if data.dx is not None and data.dx != []: 
    2479                     out.write("<X>   <Y>   <dY>   <dX>\n") 
     2479                    out.write("<X>\t<Y>\t<dY>\t<dX>\n") 
    24802480                else: 
    2481                     out.write("<X>   <Y>   <dY>\n") 
     2481                    out.write("<X>\t<Y>\t<dY>\n") 
    24822482            else: 
    2483                 out.write("<X>   <Y>\n") 
     2483                out.write("<X>\t<Y>\n") 
    24842484 
    24852485            for i in range(len(data.x)): 
     
    25252525            text += 'dY_min = %s:  dY_max = %s\n' % (min(data.dy), max(data.dy)) 
    25262526        text += '\nData Points:\n' 
    2527         x_st = "X" 
     2527        text += "<index> \t<X> \t<Y> \t<dY> " 
     2528        text += "\t<dXl> \t<dXw>\n" if(data.dxl is not None and 
     2529                                       data.dxw is not None) else "\t<dX>\n" 
    25282530        for index in range(len(data.x)): 
    25292531            if data.dy is not None and len(data.dy) > index: 
     
    25362538                dx_val = 0.0 
    25372539            if data.dxl is not None and len(data.dxl) > index: 
    2538                 if index == 0: 
    2539                     x_st = "Xl" 
    25402540                dx_val = data.dxl[index] 
    2541             elif data.dxw is not None and len(data.dxw) > index: 
    2542                 if index == 0: 
    2543                     x_st = "Xw" 
    2544                 dx_val = data.dxw[index] 
    2545  
    2546             if index == 0: 
    2547                 text += "<index> \t<X> \t<Y> \t<dY> \t<d%s>\n" % x_st 
     2541                if data.dxw is not None and len(data.dxw) > index: 
     2542                    dx_val = "%s \t%s" % (data.dxl[index], data.dxw[index]) 
     2543 
    25482544            text += "%s \t%s \t%s \t%s \t%s\n" % (index, 
    25492545                                                  data.x[index], 
     
    25622558        """ 
    25632559        default_name = fname 
    2564         wildcard = "IGOR/DAT 2D file in Q_map (*.dat)|*.DAT" 
     2560        wildcard = "IGOR/DAT 2D file in Q_map (*.dat)|*.DAT|"\ 
     2561                   "NXcanSAS files (*.h5)|*.h5|" 
    25652562        dlg = wx.FileDialog(self, "Choose a file", 
    25662563                            self._default_save_location, 
     
    25742571            if ext_num == 0: 
    25752572                ext_format = '.dat' 
     2573            elif ext_num == 1: 
     2574                ext_format = '.h5' 
    25762575            else: 
    25772576                ext_format = '' 
     
    25812580            # Instantiate a loader 
    25822581            loader = Loader() 
    2583  
    2584             ext_format = ".dat" 
    2585             if os.path.splitext(mypath)[1].lower() == ext_format: 
     2582            if os.path.splitext(mypath)[1].lower() == '.dat': 
    25862583                # Make sure the ext included in the file name 
    25872584                # especially on MAC 
    25882585                fileName = os.path.splitext(path)[0] + ext_format 
    25892586                loader.save(fileName, data, ext_format) 
     2587            elif os.path.splitext(mypath)[1].lower() == '.h5': 
     2588                # Make sure the ext included in the file name 
     2589                # especially on MAC 
     2590                fileName = os.path.splitext(path)[0] + ext_format 
     2591                nxcansaswriter = NXcanSASWriter() 
     2592                nxcansaswriter.write([data], fileName) 
    25902593            try: 
    25912594                self._default_save_location = os.path.dirname(path) 
  • src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py

    r9c7e2b8 r9c7e2b8  
    205205            except NoKnownLoaderException as e: 
    206206                exception_occurred = True 
    207                 error_message = "Loading data failed!" + e.message 
     207                error_message = "Loading data failed!\n" + e.message 
    208208                file_errors[basename] = [error_message] 
    209209            except Exception as e: 
     
    224224                for message in error_array: 
    225225                    error_message += message + "\n" 
     226                error_message = error_message[:-1] 
    226227            self.load_complete(output=output, 
    227228                               message=error_message, 
     
    231232            self.load_complete(output=output, message="Loading data complete!", 
    232233                               info="info") 
    233         else: 
    234             self.load_complete(output=None, message=error_message, info="error") 
    235234 
    236235    def load_update(self, message="", info="warning"): 
  • test/sasdataloader/test/utest_abs_reader.py

    rbd5c3b1 rf4e2f22  
    8080        data_cor = Loader().load(find("sam14_cor.cor")) 
    8181        for i in range(0, len(data_abs) - 1): 
    82             self.assertEquals(data_abs.x[i], data_cor.x[i]) 
    83             self.assertEquals(data_abs.y[i], data_cor.y[i]) 
    84             self.assertEquals(data_abs.dxl[i], data_cor.dxl[i]) 
    85             self.assertEquals(data_abs.dxw[i], data_cor.dxw[i]) 
     82            self.assertEqual(data_abs.x[i], data_cor.x[i]) 
     83            self.assertEqual(data_abs.y[i], data_cor.y[i]) 
     84            self.assertEqual(data_abs.dxl[i], data_cor.dxl[i]) 
     85            self.assertEqual(data_abs.dxw[i], data_cor.dxw[i]) 
    8686            self.assertTrue(data_abs.dxl > 0) 
    8787 
     
    118118        self.assertEqual(self.data.detector[0].beam_center.y, center_y) 
    119119 
    120         self.assertEqual(self.data.I_unit, '1/cm') 
     120        self.assertEqual(self.data.I_unit, 'cm^{-1}') 
    121121        self.assertEqual(self.data.data[0], 1.57831) 
    122122        self.assertEqual(self.data.data[1], 2.70983) 
  • test/sasdataloader/test/utest_ascii.py

    rdb5196d r9fb4572  
    1010import unittest 
    1111from sas.sascalc.dataloader.loader import Loader 
     12from sas.sascalc.dataloader.data_info import Data2D 
    1213 
    1314 
     
    121122            self.assertFalse(math.isnan(f_1d.y[i])) 
    122123            self.assertFalse(math.isnan(f_1d.dy[i])) 
     124        self.assertTrue(isinstance(f_2d, Data2D)) 
    123125        f_2d.data = f_2d.data.flatten() 
    124126        f_2d.qx_data = f_2d.qx_data.flatten() 
  • test/sasdataloader/test/utest_averaging.py

    rf53d684 rf4e2f22  
    106106 
    107107    def setUp(self): 
    108         filepath = find('MAR07232_rest.h5') 
     108        filepath = find('test_data' + os.sep + 'MAR07232_rest.h5') 
    109109        self.data_list = Loader().load(filepath) 
    110110        self.data = self.data_list[0] 
     
    121121 
    122122        o = r(self.data) 
    123         filepath = find('ring_testdata.txt') 
     123        filepath = find('test_data' + os.sep + 'ring_testdata.txt') 
    124124        answer_list = Loader().load(filepath) 
    125125        answer = answer_list[0] 
     
    142142        o = r(self.data) 
    143143 
    144         filepath = find('avg_testdata.txt') 
     144        filepath = find('test_data' + os.sep + 'avg_testdata.txt') 
    145145        answer = Loader().load(filepath)[0] 
    146146        for i in range(r.nbins_phi): 
     
    158158        s, ds, npoints = r(self.data) 
    159159        self.assertAlmostEqual(s, 34.278990899999997, 4) 
    160         self.assertAlmostEqual(ds, 7.8007981835194293, 4) 
     160        self.assertAlmostEqual(ds, 8.237259999538685, 4) 
    161161        self.assertAlmostEqual(npoints, 324.0000, 4) 
    162162 
     
    164164        s, ds = r(self.data) 
    165165        self.assertAlmostEqual(s, 0.10579935462962962, 4) 
    166         self.assertAlmostEqual(ds, 0.024076537603455028, 4) 
     166        self.assertAlmostEqual(ds, 0.02542364197388483, 4) 
    167167 
    168168    def test_slabX(self): 
     
    177177        o = r(self.data) 
    178178 
    179         filepath = find('slabx_testdata.txt') 
     179        filepath = find('test_data' + os.sep + 'slabx_testdata.txt') 
    180180        answer = Loader().load(filepath)[0] 
    181181        for i in range(len(o.x)): 
     
    195195        o = r(self.data) 
    196196 
    197         filepath = find('slaby_testdata.txt') 
     197        filepath = find('test_data' + os.sep + 'slaby_testdata.txt') 
    198198        answer = Loader().load(filepath)[0] 
    199199        for i in range(len(o.x)): 
     
    221221        o = r(self.data) 
    222222 
    223         filepath = find('ring_testdata.txt') 
     223        filepath = find('test_data' + os.sep + 'ring_testdata.txt') 
    224224        answer = Loader().load(filepath)[0] 
    225225        for i in range(len(o.x)): 
     
    238238        o = r(self.data) 
    239239 
    240         filepath = find('sectorphi_testdata.txt') 
     240        filepath = find('test_data' + os.sep + 'sectorphi_testdata.txt') 
    241241        answer = Loader().load(filepath)[0] 
    242242        for i in range(len(o.x)): 
     
    255255        o = r(self.data) 
    256256 
    257         filepath = find('sectorq_testdata.txt') 
     257        filepath = find('test_data' + os.sep + 'sectorq_testdata.txt') 
    258258        answer = Loader().load(filepath)[0] 
    259259        for i in range(len(o.x)): 
  • test/sasdataloader/test/utest_cansas.py

    rf53d684 rf4e2f22  
    9191        reader = XMLreader(self.xml_valid, self.schema_1_0) 
    9292        valid = reader.validate_xml() 
    93         if valid: 
    94             self.assertTrue(valid) 
    95         else: 
    96             self.assertFalse(valid) 
     93        self.assertTrue(valid) 
    9794 
    9895    def _check_data(self, data): 
     
    193190    def test_save_cansas_v1_0(self): 
    194191        xmlreader = XMLreader(self.isis_1_0, self.schema_1_0) 
    195         valid = xmlreader.validate_xml() 
    196         self.assertTrue(valid) 
     192        self.assertTrue(xmlreader.validate_xml()) 
    197193        reader_generic = Loader() 
    198194        dataloader = reader_generic.load(self.isis_1_0) 
     
    207203            return_data = reader2.read(self.write_1_0_filename) 
    208204            written_data = return_data[0] 
    209             XMLreader(self.write_1_0_filename, self.schema_1_0) 
    210             valid = xmlreader.validate_xml() 
    211             self.assertTrue(valid) 
     205            xmlreader = XMLreader(self.write_1_0_filename, self.schema_1_0) 
     206            self.assertTrue(xmlreader.validate_xml()) 
    212207            self._check_data(written_data) 
    213208        if os.path.isfile(self.write_1_0_filename): 
     
    260255        self.loader = Loader() 
    261256        self.datafile_basic = find("simpleexamplefile.h5") 
    262         self.datafile_multiplesasentry = find("cansas_1Dand2D_samedatafile.h5") 
    263         self.datafile_multiplesasdata = find("cansas_1Dand2D_samesasentry.h5") 
    264         self.datafile_multiplesasdata_multiplesasentry = find("cansas_1Dand2D_multiplesasentry_multiplesasdata.h5") 
     257        self.datafile_multiplesasentry = find( 
     258            "test_data" + os.sep + "nxcansas_1Dand2D_multisasentry.h5") 
     259        self.datafile_multiplesasdata = find( 
     260            "test_data" + os.sep + "nxcansas_1Dand2D_multisasdata.h5") 
     261        self.datafile_multiplesasdata_multiplesasentry = find( 
     262            "test_data" + os.sep + "nxcansas_1Dand2D_multisasentry_multisasdata.h5") 
    265263 
    266264    def test_real_data(self): 
     
    273271        self._check_multiple_data(self.data[0]) 
    274272        self._check_multiple_data(self.data[1]) 
    275         self._check_1d_data(self.data[0]) 
     273        if isinstance(self.data[0], Data1D): 
     274            self._check_1d_data(self.data[0]) 
     275            self._check_2d_data(self.data[1]) 
     276        else: 
     277            self._check_1d_data(self.data[1]) 
     278            self._check_2d_data(self.data[0]) 
     279 
     280    def test_multiple_sasdatas(self): 
     281        self.data = self.loader.load(self.datafile_multiplesasdata) 
     282        self.assertTrue(len(self.data) == 2) 
     283        self._check_multiple_data(self.data[0]) 
     284        self._check_multiple_data(self.data[1]) 
     285        if isinstance(self.data[0], Data1D): 
     286            self._check_1d_data(self.data[0]) 
     287            self._check_2d_data(self.data[1]) 
     288        else: 
     289            self._check_1d_data(self.data[1]) 
     290            self._check_2d_data(self.data[0]) 
     291 
     292    def test_multiple_sasentries_multiplesasdatas(self): 
     293        self.data = self.loader.load( 
     294            self.datafile_multiplesasdata_multiplesasentry) 
     295        self.assertTrue(len(self.data) == 4) 
     296        self._check_multiple_data(self.data[0]) 
     297        self._check_multiple_data(self.data[1]) 
     298        self._check_multiple_data(self.data[2]) 
     299        self._check_multiple_data(self.data[3]) 
     300        for data in self.data: 
     301            if isinstance(data, Data1D): 
     302                self._check_1d_data(data) 
     303            else: 
     304                self._check_2d_data(data) 
    276305 
    277306    def _check_multiple_data(self, data): 
    278         self.assertTrue(data.title == "MH4_5deg_16T_SLOW") 
    279         self.assertTrue(data.run[0] == '33837') 
    280         self.assertTrue(len(data.run) == 1) 
    281         self.assertTrue(data.instrument == "SANS2D") 
    282         self.assertTrue(data.source.radiation == "Spallation Neutron Source") 
    283         self.assertTrue(len(data.detector) == 1) 
    284         self.assertTrue(data.detector[0].name == "rear-detector") 
    285         self.assertTrue(data.detector[0].distance == 4.385281) 
    286         self.assertTrue(data.detector[0].distance_unit == 'm') 
    287         self.assertTrue(len(data.trans_spectrum) == 1) 
     307        self.assertEqual(data.title, "MH4_5deg_16T_SLOW") 
     308        self.assertEqual(data.run[0], '33837') 
     309        self.assertEqual(len(data.run), 1) 
     310        self.assertEqual(data.instrument, "SANS2D") 
     311        self.assertEqual(data.source.radiation, "Spallation Neutron Source") 
     312        self.assertEqual(len(data.detector), 2) 
     313        self.assertTrue(data.detector[0].name == "rear-detector" 
     314                        or data.detector[1].name == "rear-detector") 
     315        self.assertTrue(data.detector[0].name == "front-detector" 
     316                        or data.detector[1].name == "front-detector") 
     317        self.assertAlmostEqual(data.detector[0].distance + 
     318                               data.detector[1].distance, 7230.54, 2) 
     319        self.assertEqual(data.detector[0].distance_unit, 'mm') 
     320        self.assertEqual(len(data.trans_spectrum), 1) 
    288321 
    289322    def _check_1d_data(self, data): 
    290         self.assertTrue(isinstance(data, Data1D)) 
    291         self.assertTrue(len(data.x) == 66) 
    292         self.assertTrue(len(data.x) == len(data.y)) 
    293         self.assertTrue(data.dy[10] == 0.20721350111248701) 
    294         self.assertTrue(data.y[10] == 24.193889608153476) 
    295         self.assertTrue(data.x[10] == 0.008981127988654792) 
     323        self.assertEqual(len(data.x), 66) 
     324        self.assertEqual(len(data.x), len(data.y)) 
     325        self.assertAlmostEqual(data.dy[10], 0.207214) 
     326        self.assertAlmostEqual(data.y[10], 24.1939) 
     327        self.assertAlmostEqual(data.x[10], 0.00898113) 
    296328 
    297329    def _check_2d_data(self, data): 
    298330        self.assertTrue(isinstance(data, Data2D)) 
    299         self.assertTrue(len(data.x) == 66) 
    300         self.assertTrue(len(data.x) == len(data.y)) 
    301         self.assertTrue(data.dy[10] == 0.20721350111248701) 
    302         self.assertTrue(data.y[10] == 24.193889608153476) 
    303         self.assertTrue(data.x[10] == 0.008981127988654792) 
     331        self.assertEqual(len(data.q_data), 150*150) 
     332        self.assertEqual(len(data.q_data), len(data.data)) 
     333        self.assertAlmostEqual(data.err_data[10], 0.186723989418) 
     334        self.assertAlmostEqual(data.data[10], 0.465181) 
     335        self.assertAlmostEqual(data.qx_data[10], -0.129) 
     336        self.assertAlmostEqual(data.qy_data[10], -0.149) 
    304337 
    305338    def _check_example_data(self, data): 
    306         self.assertTrue(data.title == "") 
    307         self.assertTrue(data.x.size == 100) 
    308         self.assertTrue(data._xunit == "A^{-1}") 
    309         self.assertTrue(data._yunit == "cm^{-1}") 
    310         self.assertTrue(data.y.size == 100) 
     339        self.assertEqual(data.title, "") 
     340        self.assertEqual(data.x.size, 100) 
     341        self.assertEqual(data._xunit, "A^{-1}") 
     342        self.assertEqual(data._yunit, "cm^{-1}") 
     343        self.assertEqual(data.y.size, 100) 
    311344        self.assertAlmostEqual(data.y[40], 0.952749011516985) 
    312345        self.assertAlmostEqual(data.x[40], 0.3834415188257777) 
  • test/sasdataloader/test/utest_generic_file_reader_class.py

    r4a8d55c r282bc3f  
    4545        last_f = f[0] 
    4646        if hasattr(last_f, "errors"): 
    47             self.assertEquals(len(last_f.errors), 1) 
     47            self.assertEqual(len(last_f.errors), 1) 
    4848        else: 
    4949            self.fail("Errors did not propogate to the file properly.") 
     
    5151    def test_same_file_unknown_extensions(self): 
    5252        # Five files, all with the same content, but different file extensions 
    53         no_ext = find("test_data//TestExtensions") 
    54         not_xml = find("test_data//TestExtensions.notxml") 
     53        no_ext = find("test_data" + os.sep + "TestExtensions") 
     54        not_xml = find("test_data" + os.sep + "TestExtensions.notxml") 
    5555        # Deprecated extensions 
    56         asc_dep = find("test_data//TestExtensions.asc") 
    57         nxs_dep = find("test_data//TestExtensions.nxs") 
     56        asc_dep = find("test_data" + os.sep + "TestExtensions.asc") 
     57        nxs_dep = find("test_data" + os.sep + "TestExtensions.nxs") 
    5858        # Native extension as a baseline 
    59         xml_native = find("test_data//TestExtensions.xml") 
     59        xml_native = find("test_data" + os.sep + "TestExtensions.xml") 
    6060        # Load the files and check contents 
    6161        no_ext_load = self.generic_reader.load(no_ext) 
     
    7070        self.check_unknown_extension(xml_load[0]) 
    7171        # Be sure the deprecation warning is passed with the file 
    72         self.assertEquals(len(asc_load[0].errors), 1) 
    73         self.assertEquals(len(nxs_load[0].errors), 1) 
     72        self.assertEqual(len(asc_load[0].errors), 1) 
     73        self.assertEqual(len(nxs_load[0].errors), 0) 
    7474 
    7575    def check_unknown_extension(self, data): 
    7676        self.assertTrue(isinstance(data, Data1D)) 
    77         self.assertEquals(len(data.x), 138) 
    78         self.assertEquals(data.sample.ID, "TK49 c10_SANS") 
    79         self.assertEquals(data.meta_data["loader"], "CanSAS XML 1D") 
     77        self.assertEqual(len(data.x), 138) 
     78        self.assertEqual(data.sample.ID, "TK49 c10_SANS") 
     79        self.assertEqual(data.meta_data["loader"], "CanSAS XML 1D") 
    8080 
    8181    def tearDown(self): 
  • test/sasdataloader/test/utest_red2d_reader.py

    rf53d684 rfc51d06  
    3131        self.assertEqual(f.qx_data[0],-0.03573497) 
    3232        self.assertEqual(f.qx_data[36863],0.2908819) 
    33         self.assertEqual(f.Q_unit, '1/A') 
    34         self.assertEqual(f.I_unit, '1/cm') 
     33        self.assertEqual(f.Q_unit, 'A^{-1}') 
     34        self.assertEqual(f.I_unit, 'cm^{-1}') 
    3535 
    3636        self.assertEqual(f.meta_data['loader'],"IGOR/DAT 2D Q_map") 
  • test/sasdataloader/test/utest_sesans.py

    rf53d684 rf4e2f22  
    2525            Test .SES in the full loader to make sure that the file type is correctly accepted 
    2626        """ 
    27         file = Loader().load(find("sesans_examples/sphere2micron.ses")) 
     27        file = Loader().load(find("sesans_examples" + os.sep + 
     28                                  "sphere2micron.ses")) 
    2829        f = file[0] 
    2930        # self.assertEqual(f, 5) 
     
    4445            Test .SES loading on a TOF dataset 
    4546        """ 
    46         file = self.loader(find("sesans_examples/sphere_isis.ses")) 
     47        file = self.loader(find("sesans_examples" + os.sep + "sphere_isis.ses")) 
    4748        f = file[0] 
    4849        self.assertEqual(len(file), 1) 
     
    6263            FileContentsException, 
    6364            self.loader, 
    64             find("sesans_examples/sesans_no_data.ses")) 
     65            find("sesans_examples" + os.sep + "sesans_no_data.ses")) 
    6566 
    6667    def test_sesans_no_spin_echo_unit(self): 
     
    7172            FileContentsException, 
    7273            self.loader, 
    73             find("sesans_examples/no_spin_echo_unit.ses")) 
     74            find("sesans_examples" + os.sep + "no_spin_echo_unit.ses")) 
    7475 
    7576    def test_sesans_future_version(self): 
     
    8081            FileContentsException, 
    8182            self.loader, 
    82             find("sesans_examples/next_gen.ses")) 
     83            find("sesans_examples" + os.sep + "next_gen.ses")) 
    8384 
    8485    def test_sesans_mandatory_headers(self): 
     
    8990            FileContentsException, 
    9091            self.loader, 
    91             find("sesans_examples/no_wavelength.ses")) 
     92            find("sesans_examples" + os.sep + "no_wavelength.ses")) 
    9293 
    9394    def test_sesans_columns_match_headers(self): 
     
    9899            FileContentsException, 
    99100            self.loader, 
    100             find("sesans_examples/too_many_headers.ses")) 
     101            find("sesans_examples" + os.sep + "too_many_headers.ses")) 
    101102 
    102103if __name__ == "__main__": 
Note: See TracChangeset for help on using the changeset viewer.