Changeset 35ac8df in sasview for src/sas


Ignore:
Timestamp:
Aug 21, 2018 9:20:27 AM (6 years ago)
Author:
krzywon
Branches:
master, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, unittest-saveload
Children:
c2525bf
Parents:
96d06a4 (diff), ec52ea1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ticket-1111

Location:
src/sas
Files:
2 deleted
19 edited

Legend:

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

    r3bab401 r35ac8df  
    171171 
    172172                try: 
    173                     _x = float(toks[0]) 
     173                    _x = float(toks[4]) 
    174174                    _y = float(toks[1]) 
    175175                    _dy = float(toks[2]) 
  • src/sas/sascalc/fit/pagestate.py

    r3b070a0 r59873e1  
    1313################################################################################ 
    1414import time 
     15import re 
    1516import os 
    1617import sys 
     
    962963        if node.get('version'): 
    963964            # Get the version for model conversion purposes 
    964             self.version = tuple(int(e) for e in 
    965                                  str.split(node.get('version'), ".")) 
     965            x = re.sub('[^\d.]', '', node.get('version')) 
     966            self.version = tuple(int(e) for e in str.split(x, ".")) 
    966967            # The tuple must be at least 3 items long 
    967968            while len(self.version) < 3: 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/parameters_panel_slicer.py

    ra26f67f ra20a255  
    251251            self.bck.Add(self.batch_slicer_button, (iy, ix), (1, 1), 
    252252                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 
     253            # Help button 
     254 
     255            self.bt_help = wx.Button(self, wx.NewId(), "HELP") 
     256            self.bt_help.SetToolTipString( 
     257                "Help for the slicer parameters and batch slicing.") 
     258            self.bck.Add(self.bt_help, (iy, 1), (1, 1), 
     259                         wx.ALIGN_RIGHT | wx.ADJUST_MINSIZE, 15) 
     260            wx.EVT_BUTTON(self, self.bt_help.GetId(), self.on_help) 
     261 
    253262            iy += 1 
    254263            self.bck.Add((5, 5), (iy, ix), (1, 1), 
    255264                         wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 5) 
     265 
    256266        self.bck.Layout() 
    257267        self.bck.Fit(self) 
     
    535545            self.default_value += "_{0}".format(key).split(" [")[0] 
    536546            self.default_value += "-{:.2f}".format(params[key]) 
     547 
     548    def on_help(self, event=None): 
     549        """ 
     550        Opens a help window for the slicer parameters/batch slicing window 
     551        :param event: 
     552        :return: 
     553        """ 
     554        from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     555 
     556        _TreeLocation = "user/sasgui/guiframe/graph_help.html" 
     557        _doc_viewer = DocumentationWindow(self, wx.ID_ANY, _TreeLocation, 
     558                                          "#d-data-averaging", 
     559                                          "Data Explorer Help") 
  • src/sas/sasgui/guiframe/media/graph_help.rst

    r5ed76f8 rde68f78  
    266266 
    267267.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     268.. _d_data_averaging: 
    268269 
    2692702D data averaging 
     
    301302Alternatively, once a 'slicer' is active you can also select the region to 
    302303average by bringing back the *Dataset Menu* and selecting *Edit Slicer 
    303 Parameters*. A dialog window will appear in which you can enter values to 
    304 define a region or select the number of points to plot (*nbins*). 
     304Parameters and Batch Fitting*. A dialog window will appear in which you can 
     305enter values to define a region, select the number of points to plot (*nbins*), 
     306or apply the slicer to any or all other 2D data plots. 
    305307 
    306308A separate plot window will also have appeared, displaying the requested 
     
    315317 
    316318To remove a 'slicer', bring back the *Dataset menu* and select *Clear Slicer*. 
     319 
     320Batch Slicing 
     321^^^^^^^^^^^^^ 
     322 
     323A slicer can be applied to any or all existing 2D data plots using the 'Slicer 
     324Parameters' window. To open the window, select *Edit Slicer Parameters and Batch 
     325Fitting* in the *Dataset Menu* (see Invoking_the_dataset_menu_). Batch slicing 
     326options are available at the bottom of the window. 
     327 
     328Select the 2D plots you want to apply the slicer to. All 2D plots are selected 
     329by default. The resulting 1D data for all slicers can be saved as a text file 
     330and then sent to fitting by selecting the *Auto save generated 1D* check box. 
     331Sending data to the fitting perspective requires the data be saved. 
     332 
     333Once the auto save check box is selected, you can select where the files are 
     334saved. The file name for the saved data is the slicer name plus the file name 
     335of the original data set, plus what is in the *Append to file name* field. The 
     336default value in the append to field includes the names and values for all of 
     337the slicer parameters. 
     338 
     339The batch of slices can be sent to fitting if desired, with three options 
     340available. The first is to not fit the data, the second is to send the 
     341slices to individual fit pages, and the third is to send all sliced data to a 
     342single batch fit window. 
     343 
     344Clicking *Apply Slicer to Selected Plots* will create a slicer for each selected 
     345plot with the parameters entered in the 'Slicer Parameters' window. Depending on 
     346the options selected the data may then be saved, loaded as separate data sets in 
     347the data manager panel, and finally sent to fitting. 
    317348 
    318349Unmasked circular average 
  • src/sas/sasgui/perspectives/calculator/pyconsole.py

    r4627657 re2663b7  
    2828    Check that the model on the path can run. 
    2929    """ 
     30    # TODO: fix model caching 
     31    # model_test.run_one() is directly forcing a reload of the module, but 
     32    # sasview_model is caching models that have already been loaded. 
     33    # If the sasview load happens before the test, then the module is 
     34    # reloaded out from under it, which causes the global variables in 
     35    # the model function definitions to be cleared (at least in python 2.7). 
     36    # To fix the proximal problem of models failing on test, perform the 
     37    # run_one() tests first.  To fix the deeper problem we should either 
     38    # remove caching from sasmodels.sasview_model.load_custom_model() or 
     39    # add caching to sasmodels.custom.load_custom_kernel_module().  Another 
     40    # option is to add a runTests method to SasviewModel which runs the 
     41    # test suite directly from the model info structure.  Probably some 
     42    # combination of options: 
     43    #    (1) have this function (check_model) operate on a loaded model 
     44    #    so that caching isn't needed in sasview_models.load_custom_model 
     45    #    (2) add the runTests method to SasviewModel so that tests can 
     46    #    be run on a loaded module. 
     47    # 
     48    # Also, note that the model test suite runs the equivalent of the 
     49    # "try running the model" block below, and doesn't need to be run 
     50    # twice.  The reason for duplicating the block here is to generate 
     51    # an exception that show_model_output can catch.  Need to write the 
     52    # runTests method so that it returns success flag as well as output 
     53    # string so that the extra test is not necessary. 
     54 
     55    # check the model's unit tests run 
     56    from sasmodels.model_test import run_one 
     57    result = run_one(path) 
     58 
     59    # remove cached version of the model, if any 
     60    from sasmodels import sasview_model 
     61    sasview_model.MODEL_BY_PATH.pop(path, None) 
     62 
    3063    # try running the model 
    31     from sasmodels.sasview_model import load_custom_model 
    32     Model = load_custom_model(path) 
     64    Model = sasview_model.load_custom_model(path) 
    3365    model = Model() 
    3466    q =  np.array([0.01, 0.1]) 
     
    3668    qx, qy =  np.array([0.01, 0.01]), np.array([0.1, 0.1]) 
    3769    Iqxy = model.evalDistribution([qx, qy]) 
    38  
    39     # check the model's unit tests run 
    40     from sasmodels.model_test import run_one 
    41     result = run_one(path) 
    4270 
    4371    return result 
  • src/sas/sasgui/perspectives/calculator/slit_length_calculator_panel.py

    r7432acb rd788619  
    248248            Complete the loading and compute the slit size 
    249249        """ 
     250        if isinstance(data, list): 
     251            data = data[0] 
    250252        if data is None or data.__class__.__name__ == 'Data2D': 
    251253            if self.parent.parent is None: 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    rc192960 r8a51dea0  
    25522552            # draw 
    25532553            self._draw_model() 
     2554            self.Layout() 
    25542555            self.Refresh() 
    25552556        except Exception: 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    ra7c6f38 rdabcaf7  
    706706 
    707707                        ix = 3 
    708                         ctl2 = wx.TextCtrl(self, wx.ID_ANY, 
    709                                            size=(_BOX_WIDTH / 1.3, 20), 
    710                                            style=0) 
     708                        ctl2 = BGTextCtrl(self, wx.ID_ANY, 
     709                                           size=(_BOX_WIDTH / 1.3, 20)) 
    711710 
    712711                        self.sizer4_4.Add(ctl2, (iy, ix), (1, 1), 
     
    19981997        self.on_smear_helper() 
    19991998        self.on_set_focus(None) 
     1999        self.Layout() 
    20002000        self.Refresh() 
    20012001        # update model plot with new data information 
     
    28922892                        text2.Hide() 
    28932893                    ix += 1 
    2894                     ctl2 = wx.TextCtrl(self, wx.ID_ANY, 
    2895                                        size=(_BOX_WIDTH / 1.2, 20), style=0) 
     2894                    ctl2 = BGTextCtrl(self, wx.ID_ANY, 
     2895                                       size=(_BOX_WIDTH / 1.2, 20)) 
    28962896                    sizer.Add(ctl2, (iy, ix), (1, 1), 
    28972897                              wx.EXPAND | wx.ADJUST_MINSIZE, 0) 
  • src/sas/sasview/__init__.py

    r3ca67dcf ra8bbba2  
    1 __version__ = "4.2.0" 
     1__version__ = "4.2.0-beta" 
    22__build__ = "GIT_COMMIT" 
  • 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/file_reader_base_class.py

    r4a8d55c r8f882fe  
    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__) 
     
    9899                    if len(self.output) > 0: 
    99100                        # Sort the data that's been loaded 
    100                         self.sort_one_d_data() 
    101                         self.sort_two_d_data() 
     101                        self.convert_data_units() 
     102                        self.sort_data() 
    102103        else: 
    103104            msg = "Unable to find file at: {}\n".format(filepath) 
     
    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.qx_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.qx_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("\\rm{Q}", '1/A') 
     291        data.yaxis("\\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", default_i_unit="1/cm"): 
     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_x_unit: The default x unit used by Sasview 
     311        :param default_y_unit: The default y unit used by Sasview 
     312        """ 
     313        new_output = [] 
     314        for data in self.output: 
     315            if data.isSesans: 
     316                new_output.append(data) 
     317                continue 
     318            file_x_unit = data._xunit 
     319            data_conv_x = Converter(file_x_unit) 
     320            file_y_unit = data._yunit 
     321            data_conv_y = Converter(file_y_unit) 
     322            if isinstance(data, Data1D): 
     323                try: 
     324                    data.x = data_conv_x(data.x, units=default_q_unit) 
     325                    data._xunit = default_q_unit 
     326                    data.x_unit = default_q_unit 
     327                    if data.dx is not None: 
     328                        data.dx = data_conv_x(data.dx, units=default_q_unit) 
     329                    if data.dxl is not None: 
     330                        data.dxl = data_conv_x(data.dxl, units=default_q_unit) 
     331                    if data.dxw is not None: 
     332                        data.dxw = data_conv_x(data.dxw, units=default_q_unit) 
     333                except KeyError: 
     334                    message = "Unable to convert Q units from {0} to 1/A." 
     335                    message.format(default_q_unit) 
     336                    data.errors.append(message) 
     337                try: 
     338                    data.y = data_conv_y(data.y, units=default_i_unit) 
     339                    data._yunit = default_i_unit 
     340                    data.y_unit = default_i_unit 
     341                    if data.dy is not None: 
     342                        data.dy = data_conv_y(data.dy, units=default_i_unit) 
     343                except KeyError: 
     344                    message = "Unable to convert I units from {0} to 1/cm." 
     345                    message.format(default_q_unit) 
     346                    data.errors.append(message) 
     347            elif isinstance(data, Data2D): 
     348                try: 
     349                    data.qx_data = data_conv_x(data.qx_data, units=default_q_unit) 
     350                    if data.dqx_data is not None: 
     351                        data.dqx_data = data_conv_x(data.dqx_data, units=default_q_unit) 
     352                    data.qy_data = data_conv_y(data.qy_data, units=default_q_unit) 
     353                    if data.dqy_data is not None: 
     354                        data.dqy_data = data_conv_y(data.dqy_data, units=default_q_unit) 
     355                except KeyError: 
     356                    message = "Unable to convert Q units from {0} to 1/A." 
     357                    message.format(default_q_unit) 
     358                    data.errors.append(message) 
     359                try: 
     360                    file_z_unit = data._zunit 
     361                    data_conv_z = Converter(file_z_unit) 
     362                    data.data = data_conv_z(data.data, units=default_i_unit) 
     363                    if data.err_data is not None: 
     364                        data.err_data = data_conv_z(data.err_data, units=default_i_unit) 
     365                except KeyError: 
     366                    message = "Unable to convert I units from {0} to 1/cm." 
     367                    message.format(default_q_unit) 
     368                    data.errors.append(message) 
     369            else: 
     370                # TODO: Throw error of some sort... 
     371                pass 
     372            new_output.append(data) 
     373        self.output = new_output 
    279374 
    280375    def format_unit(self, unit=None): 
  • src/sas/sascalc/dataloader/readers/ascii_reader.py

    r9e6aeaf 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 r96d06a4  
    3838    # CanSAS version 
    3939    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 
    5040    # Data type name 
    51     type_name = "CanSAS 2.0" 
     41    type_name = "NXcanSAS" 
    5242    # Wildcards 
    53     type = ["CanSAS 2.0 HDF5 Files (*.h5)|*.h5"] 
     43    type = ["NXcanSAS HDF5 Files (*.h5)|*.h5|"] 
    5444    # List of allowed extensions 
    5545    ext = ['.h5', '.H5'] 
     
    8171                except Exception as e: 
    8272                    if extension not in self.ext: 
    83                         msg = "CanSAS2.0 HDF5 Reader could not load file {}".format(basename + extension) 
     73                        msg = "NXcanSAS HDF5 Reader could not load file {}".format(basename + extension) 
    8474                        raise DefaultReaderException(msg) 
    8575                    raise FileContentsException(e.message) 
     
    111101        self.errors = set() 
    112102        self.logging = [] 
     103        self.q_name = [] 
     104        self.mask_name = u'' 
     105        self.i_name = u'' 
     106        self.i_node = u'' 
     107        self.q_uncertainties = [] 
     108        self.q_resolutions = [] 
     109        self.i_uncertainties = u'' 
    113110        self.parent_class = u'' 
    114111        self.detector = Detector() 
     
    140137            if isinstance(value, h5py.Group): 
    141138                # Set parent class before recursion 
     139                last_parent_class = self.parent_class 
    142140                self.parent_class = class_name 
    143141                parent_list.append(key) 
     
    147145                    self.add_data_set(key) 
    148146                elif class_prog.match(u'SASdata'): 
    149                     self._initialize_new_data_set(parent_list) 
     147                    self._initialize_new_data_set(value) 
     148                    self._find_data_attributes(value) 
    150149                # Recursion step to access data within the group 
    151150                self.read_children(value, parent_list) 
     151                self.add_intermediate() 
    152152                # Reset parent class when returning from recursive method 
    153                 self.parent_class = class_name 
    154                 self.add_intermediate() 
     153                self.parent_class = last_parent_class 
    155154                parent_list.remove(key) 
    156155 
     
    159158                data_set = data[key][:] 
    160159                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 
    224160 
    225161                for data_point in data_set: 
     
    232168                    if key == u'definition': 
    233169                        self.current_datainfo.meta_data['reader'] = data_point 
     170                    # Run 
    234171                    elif key == u'run': 
    235172                        self.current_datainfo.run.append(data_point) 
     
    240177                        except Exception: 
    241178                            pass 
     179                    # Title 
    242180                    elif key == u'title': 
    243181                        self.current_datainfo.title = data_point 
     182                    # Note 
    244183                    elif key == u'SASnote': 
    245184                        self.current_datainfo.notes.append(data_point) 
    246  
    247185                    # 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  
     186                    elif self.parent_class == u'SASsample': 
     187                        self.process_sample(data_point, key) 
    282188                    # Instrumental Information 
    283189                    elif (key == u'name' 
    284190                          and self.parent_class == u'SASinstrument'): 
    285191                        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  
     192                    # Detector 
     193                    elif self.parent_class == u'SASdetector': 
     194                        self.process_detector(data_point, key, unit) 
     195                    # Collimation 
     196                    elif self.parent_class == u'SAScollimation': 
     197                        self.process_collimation(data_point, key, unit) 
     198                    # Aperture 
     199                    elif self.parent_class == u'SASaperture': 
     200                        self.process_aperture(data_point, key) 
    346201                    # 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  
     202                    elif self.parent_class == u'SASprocess': # CanSAS 2.0 
     203                        self.process_process(data_point, key) 
    363204                    # 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  
     205                    elif self.parent_class == u'SASsource': 
     206                        self.process_source(data_point, key, unit) 
    404207                    # Everything else goes in meta_data 
     208                    elif self.parent_class == u'SASdata': 
     209                        if isinstance(self.current_dataset, plottable_2D): 
     210                            self.process_2d_data_object(data_set, key, unit) 
     211                        else: 
     212                            self.process_1d_data_object(data_set, key, unit) 
     213 
     214                        break 
     215                    elif self.parent_class == u'SAStransmission_spectrum': 
     216                        self.process_trans_spectrum(data_set, key) 
     217                        break 
    405218                    else: 
    406219                        new_key = self._create_unique_key( 
     
    411224                # I don't know if this reachable code 
    412225                self.errors.add("ShouldNeverHappenException") 
     226 
     227    def process_1d_data_object(self, data_set, key, unit): 
     228        """ 
     229        SASdata processor method for 1d data items 
     230        :param data_set: data from HDF5 file 
     231        :param key: canSAS_class attribute 
     232        :param unit: unit attribute 
     233        """ 
     234        if key == self.i_name: 
     235            self.current_dataset.y = data_set.flatten() 
     236            self.current_dataset.yaxis("Intensity", unit) 
     237        elif key == self.i_uncertainties: 
     238            self.current_dataset.dy = data_set.flatten() 
     239        elif key in self.q_name: 
     240            self.current_dataset.xaxis("Q", unit) 
     241            self.current_dataset.x = data_set.flatten() 
     242        elif key in self.q_uncertainties or key in self.q_resolutions: 
     243            if (len(self.q_resolutions) > 1 
     244                    and np.where(self.q_resolutions == key)[0] == 0): 
     245                self.current_dataset.dxw = data_set.flatten() 
     246            elif (len(self.q_resolutions) > 1 
     247                  and np.where(self.q_resolutions == key)[0] == 1): 
     248                self.current_dataset.dxl = data_set.flatten() 
     249            else: 
     250                self.current_dataset.dx = data_set.flatten() 
     251        elif key == self.mask_name: 
     252            self.current_dataset.mask = data_set.flatten() 
     253        elif key == u'wavelength': 
     254            self.current_datainfo.source.wavelength = data_set[0] 
     255            self.current_datainfo.source.wavelength_unit = unit 
     256 
     257    def process_2d_data_object(self, data_set, key, unit): 
     258        if key == self.i_name: 
     259            self.current_dataset.data = data_set 
     260            self.current_dataset.zaxis("Intensity", unit) 
     261        elif key == self.i_uncertainties: 
     262            self.current_dataset.err_data = data_set.flatten() 
     263        elif key in self.q_name: 
     264            self.current_dataset.xaxis("Q", unit) 
     265            self.current_dataset.yaxis("Q", unit) 
     266            #FIXME: This is broken - need to properly handle 2D data 
     267            # TODO: Check shape of array (2d - cash money, homey!) 
     268            # TODO: 3D - check dims, etc. 
     269            # TODO: Put data where it belongs 
     270            pass 
     271        elif key in self.q_uncertainties or key in self.q_resolutions: 
     272            # FIXME: This isn't right either. 
     273            # TODO: find resolution/uncertainty specific to q_name 
     274            pass 
     275        elif key == u'Qy': 
     276            self.current_dataset.yaxis("Q_y", unit) 
     277            self.current_dataset.qy_data = data_set.flatten() 
     278        elif key == u'Qydev': 
     279            self.current_dataset.dqy_data = data_set.flatten() 
     280        elif key == u'Qx': 
     281            self.current_dataset.xaxis("Q_x", unit) 
     282            self.current_dataset.qx_data = data_set.flatten() 
     283        elif key == u'Qxdev': 
     284            self.current_dataset.dqx_data = data_set.flatten() 
     285 
     286    def process_trans_spectrum(self, data_set, key): 
     287        """ 
     288        SAStransmission_spectrum processor 
     289        :param data_set: data from HDF5 file 
     290        :param key: canSAS_class attribute 
     291        """ 
     292        if key == u'T': 
     293            self.trans_spectrum.transmission = data_set.flatten() 
     294        elif key == u'Tdev': 
     295            self.trans_spectrum.transmission_deviation = data_set.flatten() 
     296        elif key == u'lambda': 
     297            self.trans_spectrum.wavelength = data_set.flatten() 
     298 
     299    def process_sample(self, data_point, key): 
     300        """ 
     301        SASsample processor 
     302        :param data_point: Single point from an HDF5 data file 
     303        :param key: class name data_point was taken from 
     304        """ 
     305        if key == u'Title': 
     306            self.current_datainfo.sample.name = data_point 
     307        elif key == u'name': 
     308            self.current_datainfo.sample.name = data_point 
     309        elif key == u'ID': 
     310            self.current_datainfo.sample.name = data_point 
     311        elif key == u'thickness': 
     312            self.current_datainfo.sample.thickness = data_point 
     313        elif key == u'temperature': 
     314            self.current_datainfo.sample.temperature = data_point 
     315        elif key == u'transmission': 
     316            self.current_datainfo.sample.transmission = data_point 
     317        elif key == u'x_position': 
     318            self.current_datainfo.sample.position.x = data_point 
     319        elif key == u'y_position': 
     320            self.current_datainfo.sample.position.y = data_point 
     321        elif key == u'pitch': 
     322            self.current_datainfo.sample.orientation.x = data_point 
     323        elif key == u'yaw': 
     324            self.current_datainfo.sample.orientation.y = data_point 
     325        elif key == u'roll': 
     326            self.current_datainfo.sample.orientation.z = data_point 
     327        elif key == u'details': 
     328            self.current_datainfo.sample.details.append(data_point) 
     329 
     330    def process_detector(self, data_point, key, unit): 
     331        """ 
     332        SASdetector processor 
     333        :param data_point: Single point from an HDF5 data file 
     334        :param key: class name data_point was taken from 
     335        :param unit: unit attribute from data set 
     336        """ 
     337        if key == u'name': 
     338            self.detector.name = data_point 
     339        elif key == u'SDD': 
     340            self.detector.distance = float(data_point) 
     341            self.detector.distance_unit = unit 
     342        elif key == u'slit_length': 
     343            self.detector.slit_length = float(data_point) 
     344            self.detector.slit_length_unit = unit 
     345        elif key == u'x_position': 
     346            self.detector.offset.x = float(data_point) 
     347            self.detector.offset_unit = unit 
     348        elif key == u'y_position': 
     349            self.detector.offset.y = float(data_point) 
     350            self.detector.offset_unit = unit 
     351        elif key == u'pitch': 
     352            self.detector.orientation.x = float(data_point) 
     353            self.detector.orientation_unit = unit 
     354        elif key == u'roll': 
     355            self.detector.orientation.z = float(data_point) 
     356            self.detector.orientation_unit = unit 
     357        elif key == u'yaw': 
     358            self.detector.orientation.y = float(data_point) 
     359            self.detector.orientation_unit = unit 
     360        elif key == u'beam_center_x': 
     361            self.detector.beam_center.x = float(data_point) 
     362            self.detector.beam_center_unit = unit 
     363        elif key == u'beam_center_y': 
     364            self.detector.beam_center.y = float(data_point) 
     365            self.detector.beam_center_unit = unit 
     366        elif key == u'x_pixel_size': 
     367            self.detector.pixel_size.x = float(data_point) 
     368            self.detector.pixel_size_unit = unit 
     369        elif key == u'y_pixel_size': 
     370            self.detector.pixel_size.y = float(data_point) 
     371            self.detector.pixel_size_unit = unit 
     372 
     373    def process_collimation(self, data_point, key, unit): 
     374        """ 
     375        SAScollimation processor 
     376        :param data_point: Single point from an HDF5 data file 
     377        :param key: class name data_point was taken from 
     378        :param unit: unit attribute from data set 
     379        """ 
     380        if key == u'distance': 
     381            self.collimation.length = data_point 
     382            self.collimation.length_unit = unit 
     383        elif key == u'name': 
     384            self.collimation.name = data_point 
     385 
     386    def process_aperture(self, data_point, key): 
     387        """ 
     388        SASaperture processor 
     389        :param data_point: Single point from an HDF5 data file 
     390        :param key: class name data_point was taken from 
     391        """ 
     392        if key == u'shape': 
     393            self.aperture.shape = data_point 
     394        elif key == u'x_gap': 
     395            self.aperture.size.x = data_point 
     396        elif key == u'y_gap': 
     397            self.aperture.size.y = data_point 
     398 
     399    def process_source(self, data_point, key, unit): 
     400        """ 
     401        SASsource processor 
     402        :param data_point: Single point from an HDF5 data file 
     403        :param key: class name data_point was taken from 
     404        :param unit: unit attribute from data set 
     405        """ 
     406        if key == u'incident_wavelength': 
     407            self.current_datainfo.source.wavelength = data_point 
     408            self.current_datainfo.source.wavelength_unit = unit 
     409        elif key == u'wavelength_max': 
     410            self.current_datainfo.source.wavelength_max = data_point 
     411            self.current_datainfo.source.wavelength_max_unit = unit 
     412        elif key == u'wavelength_min': 
     413            self.current_datainfo.source.wavelength_min = data_point 
     414            self.current_datainfo.source.wavelength_min_unit = unit 
     415        elif key == u'incident_wavelength_spread': 
     416            self.current_datainfo.source.wavelength_spread = data_point 
     417            self.current_datainfo.source.wavelength_spread_unit = unit 
     418        elif key == u'beam_size_x': 
     419            self.current_datainfo.source.beam_size.x = data_point 
     420            self.current_datainfo.source.beam_size_unit = unit 
     421        elif key == u'beam_size_y': 
     422            self.current_datainfo.source.beam_size.y = data_point 
     423            self.current_datainfo.source.beam_size_unit = unit 
     424        elif key == u'beam_shape': 
     425            self.current_datainfo.source.beam_shape = data_point 
     426        elif key == u'radiation': 
     427            self.current_datainfo.source.radiation = data_point 
     428 
     429    def process_process(self, data_point, key): 
     430        """ 
     431        SASprocess processor 
     432        :param data_point: Single point from an HDF5 data file 
     433        :param key: class name data_point was taken from 
     434        """ 
     435        term_match = re.compile(u'^term[0-9]+$') 
     436        if key == u'Title':  # CanSAS 2.0 
     437            self.process.name = data_point 
     438        elif key == u'name':  # NXcanSAS 
     439            self.process.name = data_point 
     440        elif key == u'description': 
     441            self.process.description = data_point 
     442        elif key == u'date': 
     443            self.process.date = data_point 
     444        elif term_match.match(key): 
     445            self.process.term.append(data_point) 
     446        else: 
     447            self.process.notes.append(data_point) 
    413448 
    414449    def add_intermediate(self): 
     
    452487            spectrum_list = [] 
    453488            for spectrum in self.current_datainfo.trans_spectrum: 
    454                 spectrum.transmission = np.delete(spectrum.transmission, [0]) 
    455489                spectrum.transmission = spectrum.transmission.astype(np.float64) 
    456                 spectrum.transmission_deviation = np.delete( 
    457                     spectrum.transmission_deviation, [0]) 
    458490                spectrum.transmission_deviation = \ 
    459491                    spectrum.transmission_deviation.astype(np.float64) 
    460                 spectrum.wavelength = np.delete(spectrum.wavelength, [0]) 
    461492                spectrum.wavelength = spectrum.wavelength.astype(np.float64) 
    462493                if len(spectrum.transmission) > 0: 
     
    491522                (n_rows, n_cols) = dataset.data.shape 
    492523                dataset.y_bins = dataset.qy_data[0::n_cols] 
    493                 dataset.x_bins = dataset.qx_data[:n_cols] 
     524                dataset.x_bins = dataset.qx_data[0::n_rows] 
    494525                dataset.data = dataset.data.flatten() 
    495526            self.current_dataset = dataset 
     
    515546        self.current_datainfo = DataInfo() 
    516547 
    517  
    518     def _initialize_new_data_set(self, parent_list=None): 
     548    def _initialize_new_data_set(self, value=None): 
    519549        """ 
    520550        A private class method to generate a new 1D or 2D data object based on 
     
    524554        :param parent_list: List of names of parent elements 
    525555        """ 
    526  
    527         if parent_list is None: 
    528             parent_list = [] 
    529         if self._find_intermediate(parent_list, "Qx"): 
     556        if self._is2d(value): 
    530557            self.current_dataset = plottable_2D() 
    531558        else: 
     
    534561            self.current_dataset = plottable_1D(x, y) 
    535562        self.current_datainfo.filename = self.raw_data.filename 
    536  
    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. 
     563        self.mask_name = "" 
     564        self.i_name = "" 
     565        self.i_node = "" 
     566        self.q_name = [] 
     567        self.q_uncertainties = [] 
     568        self.q_resolutions = [] 
     569        self.i_uncertainties = "" 
     570 
     571    @staticmethod 
     572    def check_is_list_or_array(iterable): 
     573        try: 
     574            iter(iterable) 
     575            if (not isinstance(iterable, np.ndarray)) or (isinstance(iterable, str) 
     576                    or isinstance(iterable, unicode)): 
     577                raise TypeError 
     578        except TypeError: 
     579            iterable = iterable.split(",") 
     580        return iterable 
     581 
     582    def _find_data_attributes(self, value): 
     583        """ 
     584        A class to find the indices for Q, the name of the Qdev and Idev, and 
     585        the name of the mask. 
     586        :param value: SASdata/NXdata HDF5 Group 
     587        """ 
     588        attrs = value.attrs 
     589        signal = attrs.get("signal", "I") 
     590        i_axes = attrs.get("I_axes", ["Q"]) 
     591        q_indices = attrs.get("Q_indices", [0]) 
     592        q_indices = map(int, self.check_is_list_or_array(q_indices)) 
     593        i_axes = self.check_is_list_or_array(i_axes) 
     594        keys = value.keys() 
     595        self.mask_name = attrs.get("mask") 
     596        for val in q_indices: 
     597            self.q_name.append(i_axes[val]) 
     598        self.i_name = signal 
     599        self.i_node = value.get(self.i_name) 
     600        for item in self.q_name: 
     601            if item in keys: 
     602                q_vals = value.get(item) 
     603                if q_vals.attrs.get("uncertainties") is not None: 
     604                    self.q_uncertainties = q_vals.attrs.get("uncertainties") 
     605                elif q_vals.attrs.get("uncertainty") is not None: 
     606                    self.q_uncertainties = q_vals.attrs.get("uncertainty") 
     607                if isinstance(self.q_uncertainties, str) is not None: 
     608                    self.q_uncertainties = [self.q_uncertainties] 
     609                if q_vals.attrs.get("resolutions") is not None: 
     610                    self.q_resolutions = q_vals.attrs.get("resolutions") 
     611                if isinstance(self.q_resolutions, str): 
     612                    self.q_resolutions = self.q_resolutions.split(",") 
     613        if self.i_name in keys: 
     614            i_vals = value.get(self.i_name) 
     615            self.i_uncertainties = i_vals.attrs.get("uncertainties") 
     616            if self.i_uncertainties is None: 
     617                self.i_uncertainties = i_vals.attrs.get("uncertainty") 
     618 
     619    def _is2d(self, value, basename="I"): 
     620        """ 
     621        A private class to determine if the data set is 1d or 2d. 
    541622 
    542623        :param parent_list: List of parents nodes in the HDF5 file 
    543624        :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 
     625        :return: True if 2D, otherwise false 
     626        """ 
     627 
     628        vals = value.get(basename) 
     629        return (vals is not None and vals.shape is not None 
     630                and len(vals.shape) != 1) 
    557631 
    558632    def _create_unique_key(self, dictionary, name, numb=0): 
     
    583657        if unit is None: 
    584658            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}" 
    590659        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 rcf29187  
    175175            names=['beam_size_x', 'beam_size_y'], 
    176176            units=data_info.source.beam_size_unit, write_fn=_write_h5_float) 
    177  
    178177 
    179178        # Collimation metadata 
     
    232231            detector_entry.attrs['name'] = '' 
    233232 
     233        # Process meta data 
     234        if len(data_info.process) > 0 and not data_info.process[0].is_empty(): 
     235            i = 1 
     236            for process in data_info.process: 
     237                process_entry = sasentry.create_group( 
     238                    'sasprocess{0:0=2d}'.format(i)) 
     239                process_entry.attrs['canSAS_class'] = 'SASprocess' 
     240                if process.name: 
     241                    name = _h5_string(process.name) 
     242                    process_entry.create_dataset('name', data=name) 
     243                if process.date: 
     244                    date = _h5_string(process.date) 
     245                    process_entry.create_dataset('date', data=date) 
     246                if process.description: 
     247                    desc = _h5_string(process.description) 
     248                    process_entry.create_dataset('description', data=desc) 
     249                j = 1 
     250                for term in process.term: 
     251                    if term: 
     252                        h5_term = _h5_string(term) 
     253                        process_entry.create_dataset('term{0:0=2d}'.format(j), 
     254                                                     data=h5_term) 
     255                    j += 1 
     256                j = 1 
     257                for note in process.notes: 
     258                    if note: 
     259                        h5_note = _h5_string(note) 
     260                        process_entry.create_dataset('note{0:0=2d}'.format(j), 
     261                                                     data=h5_note) 
     262                    j += 1 
     263                i += 1 
     264 
     265        # Transmission Spectrum 
     266        if len(data_info.trans_spectrum) > 0: 
     267            i = 1 
     268            for trans in data_info.trans_spectrum: 
     269                trans_entry = sasentry.create_group( 
     270                    'sastransmission_spectrum{0:0=2d}'.format(i)) 
     271                trans_entry.attrs['canSAS_class'] = 'SAStransmission_spectrum' 
     272                trans_entry.attrs['signal'] = 'T' 
     273                trans_entry.attrs['T_axes'] = 'T' 
     274                trans_entry.attrs['name'] = trans.name 
     275                if trans.timestamp is not '': 
     276                    trans_entry.attrs['timestamp'] = trans.timestamp 
     277                transmission = trans_entry.create_dataset( 
     278                    'T', data=trans.transmission) 
     279                transmission.attrs['unertainties'] = 'Tdev' 
     280                trans_entry.create_dataset('Tdev', 
     281                                           data = trans.transmission_deviation) 
     282                trans_entry.create_dataset('lambda', data=trans.wavelength) 
     283 
    234284        note_entry = sasentry.create_group('sasnote'.format(i)) 
    235285        note_entry.attrs['canSAS_class'] = 'SASnote' 
     
    254304        data_entry.attrs['signal'] = 'I' 
    255305        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) 
     306        data_entry.attrs['Q_indices'] = [0] 
     307        q_entry = data_entry.create_dataset('Q', data=data_obj.x) 
     308        q_entry.attrs['units'] = data_obj.x_unit 
     309        i_entry = data_entry.create_dataset('I', data=data_obj.y) 
     310        i_entry.attrs['units'] = data_obj.y_unit 
     311        if data_obj.dy is not None: 
     312            i_entry.attrs['uncertainties'] = 'Idev' 
     313            i_dev_entry = data_entry.create_dataset('Idev', data=data_obj.dy) 
     314            i_dev_entry.attrs['units'] = data_obj.y_unit 
     315        if data_obj.dx is not None: 
     316            q_entry.attrs['resolutions'] = 'dQ' 
     317            dq_entry = data_entry.create_dataset('dQ', data=data_obj.dx) 
     318            dq_entry.attrs['units'] = data_obj.x_unit 
     319        elif data_obj.dxl is not None: 
     320            q_entry.attrs['resolutions'] = ['dQl','dQw'] 
     321            dql_entry = data_entry.create_dataset('dQl', data=data_obj.dxl) 
     322            dql_entry.attrs['units'] = data_obj.x_unit 
     323            dqw_entry = data_entry.create_dataset('dQw', data=data_obj.dxw) 
     324            dqw_entry.attrs['units'] = data_obj.x_unit 
    266325 
    267326    def _write_2d_data(self, data, data_entry): 
     
    273332        """ 
    274333        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] 
     334        data_entry.attrs['I_axes'] = 'Qx,Qy' 
     335        data_entry.attrs['Q_indices'] = [0,1] 
    278336 
    279337        (n_rows, n_cols) = (len(data.y_bins), len(data.x_bins)) 
     
    288346                raise ValueError("Unable to calculate dimensions of 2D data") 
    289347 
    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)) 
     348        intensity = np.reshape(data.data, (n_rows, n_cols)) 
     349        qx = np.reshape(data.qx_data, (n_rows, n_cols)) 
    295350        qy = np.reshape(data.qy_data, (n_rows, n_cols)) 
    296351 
    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 
     352        i_entry = data_entry.create_dataset('I', data=intensity) 
     353        i_entry.attrs['units'] = data.I_unit 
     354        qx_entry = data_entry.create_dataset('Qx', data=qx) 
     355        qx_entry.attrs['units'] = data.Q_unit 
     356        qy_entry = data_entry.create_dataset('Qy', data=qy) 
     357        qy_entry.attrs['units'] = data.Q_unit 
     358        if data.err_data is not None and not all(data.err_data == [None]): 
     359            d_i = np.reshape(data.err_data, (n_rows, n_cols)) 
     360            i_entry.attrs['uncertainties'] = 'Idev' 
     361            i_dev_entry = data_entry.create_dataset('Idev', data=d_i) 
     362            i_dev_entry.attrs['units'] = data.I_unit 
     363        if data.dqx_data is not None and not all(data.dqx_data == [None]): 
     364            qx_entry.attrs['resolutions'] = 'dQx' 
     365            dqx_entry = data_entry.create_dataset('dQx', data=data.dqx_data) 
     366            dqx_entry.attrs['units'] = data.Q_unit 
     367        if data.dqy_data is not None and not all(data.dqy_data == [None]): 
     368            qy_entry.attrs['resolutions'] = 'dQy' 
     369            dqy_entry = data_entry.create_dataset('dQy', data=data.dqy_data) 
     370            dqy_entry.attrs['units'] = data.Q_unit 
  • src/sas/sasgui/guiframe/gui_manager.py

    rb963b20 rb799f09  
    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 
     
    24222423        default_name = fname 
    24232424        wildcard = "Text files (*.txt)|*.txt|"\ 
    2424                     "CanSAS 1D files(*.xml)|*.xml" 
    2425         path = None 
     2425                    "CanSAS 1D files (*.xml)|*.xml|"\ 
     2426                     "NXcanSAS files (*.h5)|*.h5|" 
     2427        options = {0: ".txt", 
     2428                   1: ".xml", 
     2429                   2: ".h5"} 
    24262430        dlg = wx.FileDialog(self, "Choose a file", 
    24272431                            self._default_save_location, 
     
    24332437            # This is MAC Fix 
    24342438            ext_num = dlg.GetFilterIndex() 
    2435             if ext_num == 0: 
    2436                 ext_format = '.txt' 
    2437             else: 
    2438                 ext_format = '.xml' 
     2439 
     2440            ext_format = options[ext_num] 
    24392441            path = os.path.splitext(path)[0] + ext_format 
    24402442            mypath = os.path.basename(path) 
    2441  
    2442             # Instantiate a loader 
    2443             loader = Loader() 
    2444             ext_format = ".txt" 
    2445             if os.path.splitext(mypath)[1].lower() == ext_format: 
     2443            fName = os.path.splitext(path)[0] + ext_format 
     2444 
     2445            if os.path.splitext(mypath)[1].lower() == options[0]: 
    24462446                # Make sure the ext included in the file name 
    24472447                # especially on MAC 
    2448                 fName = os.path.splitext(path)[0] + ext_format 
    24492448                self._onsaveTXT(data, fName) 
    2450             ext_format = ".xml" 
    2451             if os.path.splitext(mypath)[1].lower() == ext_format: 
     2449            elif os.path.splitext(mypath)[1].lower() == options[1]: 
    24522450                # Make sure the ext included in the file name 
    24532451                # especially on MAC 
    2454                 fName = os.path.splitext(path)[0] + ext_format 
     2452                # Instantiate a loader 
     2453                loader = Loader() 
    24552454                loader.save(fName, data, ext_format) 
     2455            elif os.path.splitext(mypath)[1].lower() == options[2]: 
     2456                nxcansaswriter = NXcanSASWriter() 
     2457                nxcansaswriter.write([data], fName) 
    24562458            try: 
    24572459                self._default_save_location = os.path.dirname(path) 
     
    25652567        """ 
    25662568        default_name = fname 
    2567         wildcard = "IGOR/DAT 2D file in Q_map (*.dat)|*.DAT" 
     2569        wildcard = "IGOR/DAT 2D file in Q_map (*.dat)|*.DAT|"\ 
     2570                   "NXcanSAS files (*.h5)|*.h5|" 
    25682571        dlg = wx.FileDialog(self, "Choose a file", 
    25692572                            self._default_save_location, 
     
    25772580            if ext_num == 0: 
    25782581                ext_format = '.dat' 
     2582            elif ext_num == 1: 
     2583                ext_format = '.h5' 
    25792584            else: 
    25802585                ext_format = '' 
     
    25842589            # Instantiate a loader 
    25852590            loader = Loader() 
    2586  
    2587             ext_format = ".dat" 
    2588             if os.path.splitext(mypath)[1].lower() == ext_format: 
     2591            if os.path.splitext(mypath)[1].lower() == '.dat': 
    25892592                # Make sure the ext included in the file name 
    25902593                # especially on MAC 
    25912594                fileName = os.path.splitext(path)[0] + ext_format 
    25922595                loader.save(fileName, data, ext_format) 
     2596            elif os.path.splitext(mypath)[1].lower() == '.h5': 
     2597                # Make sure the ext included in the file name 
     2598                # especially on MAC 
     2599                fileName = os.path.splitext(path)[0] + ext_format 
     2600                nxcansaswriter = NXcanSASWriter() 
     2601                nxcansaswriter.write([data], fileName) 
    25932602            try: 
    25942603                self._default_save_location = os.path.dirname(path) 
  • src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py

    r2924532 r02c1608e  
    239239            self.load_complete(output=output, message="Loading data complete!", 
    240240                               info="info") 
    241         else: 
    242             self.load_complete(output=None, message=error_message, info="error") 
    243241 
    244242    def load_update(self, message="", info="warning"): 
Note: See TracChangeset for help on using the changeset viewer.