Changeset 9a0fc50 in sasview for src


Ignore:
Timestamp:
Sep 13, 2018 12:31:36 PM (6 years ago)
Author:
krzywon
Branches:
master, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, unittest-saveload
Children:
43313e72
Parents:
feec1cb (diff), 356af60e (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:
7 added
2 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/guiframe/report_dialog.py

    r91552b5 rd0ce666f  
    77import sys 
    88import wx.html as html 
     9from sas.sasgui.guiframe.report_image_handler import ReportImageHandler 
    910 
    1011logger = logging.getLogger(__name__) 
     
    7071        button_close = wx.Button(self, wx.ID_OK, "Close") 
    7172        button_close.SetToolTipString("Close this report window.") 
     73        button_close.Bind(wx.EVT_BUTTON, self.onClose, 
     74                          id=button_close.GetId()) 
    7275        hbox.Add(button_close) 
    7376        button_close.SetFocus() 
     
    117120 
    118121 
    119     def OnClose(self, event=None): 
     122    def onClose(self, event=None): 
    120123        """ 
    121124        Close the Dialog 
     
    123126        """ 
    124127        for fig in self.fig_urls: 
    125             self.imgRAM.RemoveFile(fig) 
     128            ReportImageHandler.remove_figure(fig) 
    126129 
    127         self.Close() 
     130        self.Destroy() 
    128131 
    129132    def HTML2PDF(self, data, filename): 
  • src/sas/sasgui/perspectives/calculator/media/slit_calculator_help.rst

    r5ed76f8 r346745a  
    1111----------- 
    1212 
    13 This tool enables X-ray users to calculate the slit size (FWHM/2) for smearing 
    14 based on their half beam profile data. 
     13This tool enables X-ray users to calculate the slit size (FWHM/2) for resolution  
     14smearing purposes based on their half beam profile data (as Q vs Intensity; any  
     15other data fields are ignored). 
    1516 
    16 *NOTE! Whilst it may have some more generic applicability, the calculator has 
    17 only been tested with beam profile data from Anton-Paar SAXSess:sup:`TM` software.* 
     17Method 
     18------ 
     19 
     20The tool works by sequentially summing 10 or more intensity values until a  
     21maximum value is attained. It then locates the Q values for the points just before,  
     22and just after, **half** of this maximum value and interpolates between them to get  
     23an accurate value for the Q value for the half maximum. 
     24 
     25NOTE! Whilst it may have some more generic applicability, the calculator has 
     26only been tested with beam profile data from Anton-Paar SAXSess\ :sup:`TM`\  software. 
     27The beam profile file does not carry any information about the units of the  
     28Q data. It is probably |nm^-1| but the resolution calculations assume the slit  
     29height/width has units of |Ang^-1|. If the beam profile data is not in these  
     30units then it, or the result, must be manually converted. 
    1831 
    1932.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    2740 
    2841   *NOTE! To see an example of the beam profile file format, visit the file 
    29    beam profile.DAT in your {installation_directory}/SasView/test folder.* 
     42   beam profile.DAT in your {installation_directory}/SasView/test_1d folder.* 
    3043 
    31443) Once a data is loaded, the slit size is automatically computed and displayed 
    3245   in the tool window. 
    3346 
    34 *NOTE! The beam profile file does not carry any information about the units of 
    35 the Q data. This calculator assumes the data has units of 1/\ |Ang|\ . If the 
    36 data is not in these units it must be manually converted beforehand.* 
    37  
    3847.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    3948 
    40 .. note::  This help document was last changed by Steve King, 01May2015 
     49.. note::  This help document was last changed by Steve King, 09Sep2018 
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    r9258c43c r9bf40e7  
    4343if sys.platform.count("win32") > 0: 
    4444    FONT_VARIANT = 0 
    45     PNL_WIDTH = 450 
     45    PNL_WIDTH = 500 
    4646    PNL_HEIGHT = 320 
    4747else: 
    4848    FONT_VARIANT = 1 
    49     PNL_WIDTH = 590 
     49    PNL_WIDTH = 500 
    5050    PNL_HEIGHT = 350 
    5151M_NAME = 'Model' 
     
    495495        Choose the equation to use depending on whether we now have 
    496496        a sum or multiply model then create the appropriate string 
     497         
     498        for the sum model the result will be: 
     499        scale_factor * (scale1 * model_1 + scale2 * model_2) + background 
     500        while for the multiply model it will just be: 
     501        scale_factor * (model_1* model_2) + background 
    497502        """ 
    498503        name = '' 
    499504        if operator == '*': 
    500505            name = 'Multi' 
    501             factor = 'background' 
     506            factor_1 = '' 
     507            factor_2 = '' 
    502508        else: 
    503509            name = 'Sum' 
    504             factor = 'scale_factor' 
     510            factor_1 = 'scale_1 * ' 
     511            factor_2 = 'scale_2 * ' 
    505512 
    506513        self._operator = operator 
    507         self.explanation = ("  Plugin_model = scale_factor * (model_1 {} " 
    508             "model_2) + background").format(operator) 
     514        self.explanation = ("  Plugin_model = scale_factor * ({}model_1 {} " 
     515            "{}model_2) + background").format(factor_1,operator,factor_2) 
    509516        self.explanationctr.SetLabel(self.explanation) 
    510517        self.name = name + M_NAME 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r8a51dea0 ra4a1ac9  
    3131 
    3232from sas.sasgui.guiframe.panel_base import PanelBase 
     33from sas.sasgui.guiframe.report_image_handler import ReportImageHandler 
    3334from sas.sasgui.guiframe.utils import format_number, check_float, IdList, \ 
    3435    check_int 
     
    651652        by plotting, putting it into wx.FileSystem image object 
    652653        """ 
    653         images = [] 
    654         refs = [] 
    655  
    656         # For no figures in the list, prepare empty plot 
    657         if figs is None or len(figs) == 0: 
    658             figs = [None] 
    659  
    660         # Loop over the list of figures 
    661         # use wx.MemoryFSHandler 
    662         imgRAM = wx.MemoryFSHandler() 
    663         for fig in figs: 
    664             if fig is not None: 
    665                 ind = figs.index(fig) 
    666                 canvas = canvases[ind] 
    667  
    668             # store the image in wx.FileSystem Object 
    669             wx.FileSystem.AddHandler(wx.MemoryFSHandler()) 
    670  
    671             # index of the fig 
    672             ind = figs.index(fig) 
    673  
    674             # AddFile, image can be retrieved with 'memory:filename' 
    675             name = 'img_fit%s.png' % ind 
    676             refs.append('memory:' + name) 
    677             imgRAM.AddFile(name, canvas.bitmap, wx.BITMAP_TYPE_PNG) 
    678             # append figs 
    679             images.append(fig) 
    680  
    681         return imgRAM, images, refs 
    682  
     654        bitmaps = [] 
     655        for canvas in canvases: 
     656            bitmaps.append(canvas.bitmap) 
     657        imgs, refs = ReportImageHandler.set_figs(figs, bitmaps, 'fit') 
     658 
     659        return ReportImageHandler.instance, imgs, refs 
    683660 
    684661    def on_save(self, event): 
     
    28012778        Function called when 'Help' button is pressed next to model 
    28022779        of interest.  This calls DocumentationWindow from 
    2803         documentation_window.py. It will load the top level of the model 
    2804         help documenation sphinx generated html if no model is presented. 
    2805         If a model IS present then if documention for that model exists 
    2806         it will load to that  point otherwise again it will go to the top. 
    2807         For Wx2.8 and below is used (i.e. non-released through installer) 
    2808         a browser is loaded and the top of the model documentation only is 
    2809         accessible because webbrowser module does not pass anything after 
    2810         the # to the browser. 
     2780        documentation_window.py. It will load the top level of the html model 
     2781        help documenation sphinx generated if either a plugin model (which 
     2782        normally does not have an html help help file) is selected or if no 
     2783        model is selected. Otherwise, if a regula model is selected, the 
     2784        documention for that model will be sent to a browser window. 
     2785 
     2786        :todo the quick fix for no documentation in plugins is the if statment. 
     2787        However, the right way to do this would be to check whether the hmtl 
     2788        file exists and load the model docs if it does and the general docs if 
     2789        it doesn't - this will become important if we ever figure out how to 
     2790        build docs for plugins on the fly.  Sep 9, 2018 -PDB 
    28112791 
    28122792        :param event: on Help Button pressed event 
    28132793        """ 
    28142794 
    2815         if self.model is not None: 
     2795        if (self.model is not None) and (self.categorybox.GetValue() 
     2796                                         != "Plugin Models"): 
    28162797            name = self.formfactorbox.GetValue() 
    28172798            _TreeLocation = 'user/models/%s.html' % name 
  • src/sas/sasgui/perspectives/fitting/gpu_options.py

    r42a6e02 r388aefb  
    139139 
    140140        test_text = wx.StaticText(self, -1, "WARNING: Running tests can take a few minutes!") 
     141        test_text2 = wx.StaticText(self, -1, "NOTE: No test will run if No OpenCL is checked") 
     142        test_text.SetForegroundColour(wx.RED) 
     143        self.vbox.Add(test_text2, 0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10) 
    141144        self.vbox.Add(test_text, 0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10) 
    142145 
  • src/sas/sasgui/perspectives/fitting/report_dialog.py

    r69a6897 r44e8f48  
    7272        filename = basename + ext 
    7373 
    74         # save figures 
    75         pictures = [] 
    76         for num in range(self.nimages): 
    77             pic_name = basename + '_img%s.png' % num 
    78             # save the image for use with pdf writer 
    79             self.report_list[2][num].savefig(pic_name) 
    80             pictures.append(pic_name) 
     74        # save the images for use with pdf writer 
     75        pictures = [ 
     76            '_'.join((basename, url.split(':')[1])) for url in self.fig_urls] 
     77        for i, pic in enumerate(pictures): 
     78            self.report_list[2][i].savefig(pic) 
    8179 
    8280        # translate png references int html from in-memory name to on-disk name 
    83         html = self.report_html.replace("memory:img_fit", basename+'_img') 
     81        html = self.report_html.replace("memory:", basename+'_') 
    8482 
    8583        #set file extensions 
  • src/sas/sasgui/perspectives/invariant/invariant_panel.py

    r2469df7 r44e8f48  
    2424from sas.sasgui.guiframe.panel_base import PanelBase 
    2525from sas.sasgui.guiframe.documentation_window import DocumentationWindow 
     26from sas.sasgui.guiframe.report_image_handler import ReportImageHandler 
    2627 
    2728logger = logging.getLogger(__name__) 
     
    783784        report_img = self.state.image 
    784785        report_list = [report_html_str, report_text_str, report_img] 
    785         dialog = ReportDialog(report_list, None, -1, "") 
     786        ReportImageHandler.check_for_empty_instance() 
     787        imgRAM = ReportImageHandler.instance.img_holder 
     788        refs = [self.state.wximgbmp] 
     789        dialog = ReportDialog(report_list, imgRAM, refs, None, wx.ID_ANY, "") 
    786790        dialog.Show() 
    787791 
  • src/sas/sasgui/perspectives/invariant/invariant_state.py

    r2469df7 rfa412df  
    1212from lxml import etree 
    1313from sas.sascalc.dataloader.readers.cansas_reader import Reader as CansasReader 
     14from sas.sasgui.guiframe.report_image_handler import ReportImageHandler 
    1415from sas.sascalc.dataloader.readers.cansas_reader import get_content 
    1516from sas.sasgui.guiframe.utils import format_number 
     
    611612        wximgbmp = wx.BitmapFromImage(wximg) 
    612613        # store the image in wx.FileSystem Object 
    613         wx.FileSystem.AddHandler(wx.MemoryFSHandler()) 
    614         # use wx.MemoryFSHandler 
    615         self.imgRAM = wx.MemoryFSHandler() 
    616         # AddFile, image can be retrieved with 'memory:filename' 
    617         self.imgRAM.AddFile('img_inv.png', wximgbmp, wx.BITMAP_TYPE_PNG) 
    618  
    619         self.wximgbmp = 'memory:img_inv.png' 
    620         self.image = fig 
     614        imgs, refs = ReportImageHandler.set_figs([fig], [wximgbmp], 'inv') 
     615 
     616        self.wximgbmp = refs[0] 
     617        self.image = imgs[0] 
    621618 
    622619class Reader(CansasReader): 
  • src/sas/sasgui/perspectives/invariant/report_dialog.py

    r959eb01 rd0ce666f  
    4141 
    4242        # put image path in the report string 
    43         self.report_html = self.report_list[0] % "memory:img_inv.png" 
     43        self.report_html = self.report_list[0] % self.fig_urls[0] 
    4444        # layout 
    4545        self._setup_layout() 
  • src/sas/sasview/__init__.py

    ra8bbba2 rb229a3b  
    1 __version__ = "4.2.0-beta" 
     1__version__ = "4.2.0" 
    22__build__ = "GIT_COMMIT" 
  • src/sas/sasview/local_config.py

    rb963b20 rb229a3b  
    4848'''This work benefited from the use of the SasView application, originally developed under NSF Award DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000.''' 
    4949_acknowledgement_citation = \ 
    50 '''M. Doucet et al. SasView Version 4.1.2, Zenodo, 10.5281/zenodo.825675''' 
     50'''M. Doucet et al. SasView Version 4.2, Zenodo, 10.5281/zenodo.1412041''' 
    5151 
    5252_acknowledgement =  \ 
  • src/sas/sasview/media/README.txt

    r914ba0a r356af60e  
     1The files in this folder are what get shipped in the installer \media folder. 
     2 
     3The help documentation gets shipped in the /doc folder. 
     4 
    15This Tutorial.pdf is what appears when you click on 'Tutorial' under 'Help' 
    2 in the menu bar. 
     6in the SasView menu bar. It has been manually copied over from sasview/docs/sasview. 
    37 
    4 The source files are in: /sasview/docs/sasview 
    5  
    6 The getting_started_with_sasview.pdf has been manually added here until the auto-generated LibreOffice doc build is up and running. 
     8The new tutorial pdfs here have been manually copied over from the website /downloads folder. 
  • 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

    r9e6aeaf 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

    r4a8d55c r8d5e11c  
    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__) 
     
    3637                       "load the file was made, but, should it be successful, " 
    3738                       "SasView cannot guarantee the accuracy of the data.") 
     39 
    3840 
    3941class FileReader(object): 
     
    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.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_q_unit: The default Q unit used by Sasview 
     311        :param default_i_unit: The default I 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, 
     350                                               units=default_q_unit) 
     351                    if data.dqx_data is not None: 
     352                        data.dqx_data = data_conv_x(data.dqx_data, 
     353                                                    units=default_q_unit) 
     354                    data.qy_data = data_conv_y(data.qy_data, 
     355                                               units=default_q_unit) 
     356                    if data.dqy_data is not None: 
     357                        data.dqy_data = data_conv_y(data.dqy_data, 
     358                                                    units=default_q_unit) 
     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                try: 
     364                    file_z_unit = data._zunit 
     365                    data_conv_z = Converter(file_z_unit) 
     366                    data.data = data_conv_z(data.data, units=default_i_unit) 
     367                    if data.err_data is not None: 
     368                        data.err_data = data_conv_z(data.err_data, 
     369                                                    units=default_i_unit) 
     370                except KeyError: 
     371                    message = "Unable to convert I units from {0} to 1/cm." 
     372                    message.format(default_q_unit) 
     373                    data.errors.append(message) 
     374            else: 
     375                # TODO: Throw error of some sort... 
     376                pass 
     377            new_output.append(data) 
     378        self.output = new_output 
    279379 
    280380    def format_unit(self, unit=None): 
     
    367467                    self.current_dataset.qy_data)) 
    368468            if has_error_dy: 
    369                 self.current_dataset.err_data = self.current_dataset.err_data[x != 0] 
     469                self.current_dataset.err_data = self.current_dataset.err_data[ 
     470                    x != 0] 
    370471            if has_error_dqx: 
    371                 self.current_dataset.dqx_data = self.current_dataset.dqx_data[x != 0] 
     472                self.current_dataset.dqx_data = self.current_dataset.dqx_data[ 
     473                    x != 0] 
    372474            if has_error_dqy: 
    373                 self.current_dataset.dqy_data = self.current_dataset.dqy_data[x != 0] 
     475                self.current_dataset.dqy_data = self.current_dataset.dqy_data[ 
     476                    x != 0] 
    374477            if has_mask: 
    375478                self.current_dataset.mask = self.current_dataset.mask[x != 0] 
  • src/sas/sascalc/dataloader/loader.py

    r4a8d55c r8d5e11c  
    367367            try: 
    368368                return fn(path, data) 
    369             except Exception: 
     369            except Exception as exep: 
    370370                pass  # give other loaders a chance to succeed 
    371371        # If we get here it is because all loaders failed 
    372         raise  # reraises last exception 
     372        raise exep # raises last exception 
    373373 
    374374 
  • src/sas/sascalc/dataloader/readers/abs_reader.py

    rbd5c3b1 r35ac8df  
    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

    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 rfeec1cb  
    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)) 
     20 
    2021 
    2122class Reader(FileReader): 
     
    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): 
     
    111104        self.errors = set() 
    112105        self.logging = [] 
     106        self.q_name = [] 
     107        self.mask_name = u'' 
     108        self.i_name = u'' 
     109        self.i_node = u'' 
     110        self.q_uncertainties = None 
     111        self.q_resolutions = None 
     112        self.i_uncertainties = u'' 
    113113        self.parent_class = u'' 
    114114        self.detector = Detector() 
     
    131131            value = data.get(key) 
    132132            class_name = h5attr(value, u'canSAS_class') 
     133            if isinstance(class_name, (list, tuple, np.ndarray)): 
     134                class_name = class_name[0] 
    133135            if class_name is None: 
    134136                class_name = h5attr(value, u'NX_class') 
     
    140142            if isinstance(value, h5py.Group): 
    141143                # Set parent class before recursion 
     144                last_parent_class = self.parent_class 
    142145                self.parent_class = class_name 
    143146                parent_list.append(key) 
     
    147150                    self.add_data_set(key) 
    148151                elif class_prog.match(u'SASdata'): 
    149                     self._initialize_new_data_set(parent_list) 
     152                    self._initialize_new_data_set(value) 
     153                    self._find_data_attributes(value) 
    150154                # Recursion step to access data within the group 
    151155                self.read_children(value, parent_list) 
     156                self.add_intermediate() 
    152157                # Reset parent class when returning from recursive method 
    153                 self.parent_class = class_name 
    154                 self.add_intermediate() 
     158                self.parent_class = last_parent_class 
    155159                parent_list.remove(key) 
    156160 
    157161            elif isinstance(value, h5py.Dataset): 
    158162                # If this is a dataset, store the data appropriately 
    159                 data_set = data[key][:] 
     163                data_set = value.value 
    160164                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 
    224165 
    225166                for data_point in data_set: 
     
    232173                    if key == u'definition': 
    233174                        self.current_datainfo.meta_data['reader'] = data_point 
     175                    # Run 
    234176                    elif key == u'run': 
    235177                        self.current_datainfo.run.append(data_point) 
     
    240182                        except Exception: 
    241183                            pass 
     184                    # Title 
    242185                    elif key == u'title': 
    243186                        self.current_datainfo.title = data_point 
     187                    # Note 
    244188                    elif key == u'SASnote': 
    245189                        self.current_datainfo.notes.append(data_point) 
    246  
    247190                    # 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  
     191                    elif self.parent_class == u'SASsample': 
     192                        self.process_sample(data_point, key) 
    282193                    # Instrumental Information 
    283194                    elif (key == u'name' 
    284195                          and self.parent_class == u'SASinstrument'): 
    285196                        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  
     197                    # Detector 
     198                    elif self.parent_class == u'SASdetector': 
     199                        self.process_detector(data_point, key, unit) 
     200                    # Collimation 
     201                    elif self.parent_class == u'SAScollimation': 
     202                        self.process_collimation(data_point, key, unit) 
     203                    # Aperture 
     204                    elif self.parent_class == u'SASaperture': 
     205                        self.process_aperture(data_point, key) 
    346206                    # 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  
     207                    elif self.parent_class == u'SASprocess': # CanSAS 2.0 
     208                        self.process_process(data_point, key) 
    363209                    # 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  
     210                    elif self.parent_class == u'SASsource': 
     211                        self.process_source(data_point, key, unit) 
    404212                    # Everything else goes in meta_data 
     213                    elif self.parent_class == u'SASdata': 
     214                        if isinstance(self.current_dataset, plottable_2D): 
     215                            self.process_2d_data_object(data_set, key, unit) 
     216                        else: 
     217                            self.process_1d_data_object(data_set, key, unit) 
     218 
     219                        break 
     220                    elif self.parent_class == u'SAStransmission_spectrum': 
     221                        self.process_trans_spectrum(data_set, key) 
     222                        break 
    405223                    else: 
    406224                        new_key = self._create_unique_key( 
     
    411229                # I don't know if this reachable code 
    412230                self.errors.add("ShouldNeverHappenException") 
     231 
     232    def process_1d_data_object(self, data_set, key, unit): 
     233        """ 
     234        SASdata processor method for 1d data items 
     235        :param data_set: data from HDF5 file 
     236        :param key: canSAS_class attribute 
     237        :param unit: unit attribute 
     238        """ 
     239        if key == self.i_name: 
     240            self.current_dataset.y = data_set.flatten() 
     241            self.current_dataset.yaxis("Intensity", unit) 
     242        elif key == self.i_uncertainties: 
     243            self.current_dataset.dy = data_set.flatten() 
     244        elif key in self.q_name: 
     245            self.current_dataset.xaxis("Q", unit) 
     246            self.current_dataset.x = data_set.flatten() 
     247        elif key in self.q_uncertainties or key in self.q_resolutions: 
     248            if (len(self.q_resolutions) > 1 
     249                    and np.where(self.q_resolutions == key)[0] == 0): 
     250                self.current_dataset.dxw = data_set.flatten() 
     251            elif (len(self.q_resolutions) > 1 
     252                  and np.where(self.q_resolutions == key)[0] == 1): 
     253                self.current_dataset.dxl = data_set.flatten() 
     254            else: 
     255                self.current_dataset.dx = data_set.flatten() 
     256        elif key == self.mask_name: 
     257            self.current_dataset.mask = data_set.flatten() 
     258        elif key == u'wavelength': 
     259            self.current_datainfo.source.wavelength = data_set[0] 
     260            self.current_datainfo.source.wavelength_unit = unit 
     261 
     262    def process_2d_data_object(self, data_set, key, unit): 
     263        if key == self.i_name: 
     264            self.current_dataset.data = data_set 
     265            self.current_dataset.zaxis("Intensity", unit) 
     266        elif key == self.i_uncertainties: 
     267            self.current_dataset.err_data = data_set.flatten() 
     268        elif key in self.q_name: 
     269            self.current_dataset.xaxis("Q_x", unit) 
     270            self.current_dataset.yaxis("Q_y", unit) 
     271            if self.q_name[0] == self.q_name[1]: 
     272                # All q data in a single array 
     273                self.current_dataset.qx_data = data_set[0] 
     274                self.current_dataset.qy_data = data_set[1] 
     275            elif self.q_name.index(key) == 0: 
     276                self.current_dataset.qx_data = data_set 
     277            elif self.q_name.index(key) == 1: 
     278                self.current_dataset.qy_data = data_set 
     279        elif key in self.q_uncertainties or key in self.q_resolutions: 
     280            if ((self.q_uncertainties[0] == self.q_uncertainties[1]) or 
     281                    (self.q_resolutions[0] == self.q_resolutions[1])): 
     282                # All q data in a single array 
     283                self.current_dataset.dqx_data = data_set[0].flatten() 
     284                self.current_dataset.dqy_data = data_set[1].flatten() 
     285            elif (self.q_uncertainties.index(key) == 0 or 
     286                  self.q_resolutions.index(key) == 0): 
     287                self.current_dataset.dqx_data = data_set.flatten() 
     288            elif (self.q_uncertainties.index(key) == 1 or 
     289                  self.q_resolutions.index(key) == 1): 
     290                self.current_dataset.dqy_data = data_set.flatten() 
     291                self.current_dataset.yaxis("Q_y", unit) 
     292        elif key == self.mask_name: 
     293            self.current_dataset.mask = data_set.flatten() 
     294        elif key == u'Qy': 
     295            self.current_dataset.yaxis("Q_y", unit) 
     296            self.current_dataset.qy_data = data_set.flatten() 
     297        elif key == u'Qydev': 
     298            self.current_dataset.dqy_data = data_set.flatten() 
     299        elif key == u'Qx': 
     300            self.current_dataset.xaxis("Q_x", unit) 
     301            self.current_dataset.qx_data = data_set.flatten() 
     302        elif key == u'Qxdev': 
     303            self.current_dataset.dqx_data = data_set.flatten() 
     304 
     305    def process_trans_spectrum(self, data_set, key): 
     306        """ 
     307        SAStransmission_spectrum processor 
     308        :param data_set: data from HDF5 file 
     309        :param key: canSAS_class attribute 
     310        """ 
     311        if key == u'T': 
     312            self.trans_spectrum.transmission = data_set.flatten() 
     313        elif key == u'Tdev': 
     314            self.trans_spectrum.transmission_deviation = data_set.flatten() 
     315        elif key == u'lambda': 
     316            self.trans_spectrum.wavelength = data_set.flatten() 
     317 
     318    def process_sample(self, data_point, key): 
     319        """ 
     320        SASsample processor 
     321        :param data_point: Single point from an HDF5 data file 
     322        :param key: class name data_point was taken from 
     323        """ 
     324        if key == u'Title': 
     325            self.current_datainfo.sample.name = data_point 
     326        elif key == u'name': 
     327            self.current_datainfo.sample.name = data_point 
     328        elif key == u'ID': 
     329            self.current_datainfo.sample.name = data_point 
     330        elif key == u'thickness': 
     331            self.current_datainfo.sample.thickness = data_point 
     332        elif key == u'temperature': 
     333            self.current_datainfo.sample.temperature = data_point 
     334        elif key == u'transmission': 
     335            self.current_datainfo.sample.transmission = data_point 
     336        elif key == u'x_position': 
     337            self.current_datainfo.sample.position.x = data_point 
     338        elif key == u'y_position': 
     339            self.current_datainfo.sample.position.y = data_point 
     340        elif key == u'pitch': 
     341            self.current_datainfo.sample.orientation.x = data_point 
     342        elif key == u'yaw': 
     343            self.current_datainfo.sample.orientation.y = data_point 
     344        elif key == u'roll': 
     345            self.current_datainfo.sample.orientation.z = data_point 
     346        elif key == u'details': 
     347            self.current_datainfo.sample.details.append(data_point) 
     348 
     349    def process_detector(self, data_point, key, unit): 
     350        """ 
     351        SASdetector processor 
     352        :param data_point: Single point from an HDF5 data file 
     353        :param key: class name data_point was taken from 
     354        :param unit: unit attribute from data set 
     355        """ 
     356        if key == u'name': 
     357            self.detector.name = data_point 
     358        elif key == u'SDD': 
     359            self.detector.distance = float(data_point) 
     360            self.detector.distance_unit = unit 
     361        elif key == u'slit_length': 
     362            self.detector.slit_length = float(data_point) 
     363            self.detector.slit_length_unit = unit 
     364        elif key == u'x_position': 
     365            self.detector.offset.x = float(data_point) 
     366            self.detector.offset_unit = unit 
     367        elif key == u'y_position': 
     368            self.detector.offset.y = float(data_point) 
     369            self.detector.offset_unit = unit 
     370        elif key == u'pitch': 
     371            self.detector.orientation.x = float(data_point) 
     372            self.detector.orientation_unit = unit 
     373        elif key == u'roll': 
     374            self.detector.orientation.z = float(data_point) 
     375            self.detector.orientation_unit = unit 
     376        elif key == u'yaw': 
     377            self.detector.orientation.y = float(data_point) 
     378            self.detector.orientation_unit = unit 
     379        elif key == u'beam_center_x': 
     380            self.detector.beam_center.x = float(data_point) 
     381            self.detector.beam_center_unit = unit 
     382        elif key == u'beam_center_y': 
     383            self.detector.beam_center.y = float(data_point) 
     384            self.detector.beam_center_unit = unit 
     385        elif key == u'x_pixel_size': 
     386            self.detector.pixel_size.x = float(data_point) 
     387            self.detector.pixel_size_unit = unit 
     388        elif key == u'y_pixel_size': 
     389            self.detector.pixel_size.y = float(data_point) 
     390            self.detector.pixel_size_unit = unit 
     391 
     392    def process_collimation(self, data_point, key, unit): 
     393        """ 
     394        SAScollimation processor 
     395        :param data_point: Single point from an HDF5 data file 
     396        :param key: class name data_point was taken from 
     397        :param unit: unit attribute from data set 
     398        """ 
     399        if key == u'distance': 
     400            self.collimation.length = data_point 
     401            self.collimation.length_unit = unit 
     402        elif key == u'name': 
     403            self.collimation.name = data_point 
     404 
     405    def process_aperture(self, data_point, key): 
     406        """ 
     407        SASaperture processor 
     408        :param data_point: Single point from an HDF5 data file 
     409        :param key: class name data_point was taken from 
     410        """ 
     411        if key == u'shape': 
     412            self.aperture.shape = data_point 
     413        elif key == u'x_gap': 
     414            self.aperture.size.x = data_point 
     415        elif key == u'y_gap': 
     416            self.aperture.size.y = data_point 
     417 
     418    def process_source(self, data_point, key, unit): 
     419        """ 
     420        SASsource processor 
     421        :param data_point: Single point from an HDF5 data file 
     422        :param key: class name data_point was taken from 
     423        :param unit: unit attribute from data set 
     424        """ 
     425        if key == u'incident_wavelength': 
     426            self.current_datainfo.source.wavelength = data_point 
     427            self.current_datainfo.source.wavelength_unit = unit 
     428        elif key == u'wavelength_max': 
     429            self.current_datainfo.source.wavelength_max = data_point 
     430            self.current_datainfo.source.wavelength_max_unit = unit 
     431        elif key == u'wavelength_min': 
     432            self.current_datainfo.source.wavelength_min = data_point 
     433            self.current_datainfo.source.wavelength_min_unit = unit 
     434        elif key == u'incident_wavelength_spread': 
     435            self.current_datainfo.source.wavelength_spread = data_point 
     436            self.current_datainfo.source.wavelength_spread_unit = unit 
     437        elif key == u'beam_size_x': 
     438            self.current_datainfo.source.beam_size.x = data_point 
     439            self.current_datainfo.source.beam_size_unit = unit 
     440        elif key == u'beam_size_y': 
     441            self.current_datainfo.source.beam_size.y = data_point 
     442            self.current_datainfo.source.beam_size_unit = unit 
     443        elif key == u'beam_shape': 
     444            self.current_datainfo.source.beam_shape = data_point 
     445        elif key == u'radiation': 
     446            self.current_datainfo.source.radiation = data_point 
     447 
     448    def process_process(self, data_point, key): 
     449        """ 
     450        SASprocess processor 
     451        :param data_point: Single point from an HDF5 data file 
     452        :param key: class name data_point was taken from 
     453        """ 
     454        term_match = re.compile(u'^term[0-9]+$') 
     455        if key == u'Title':  # CanSAS 2.0 
     456            self.process.name = data_point 
     457        elif key == u'name':  # NXcanSAS 
     458            self.process.name = data_point 
     459        elif key == u'description': 
     460            self.process.description = data_point 
     461        elif key == u'date': 
     462            self.process.date = data_point 
     463        elif term_match.match(key): 
     464            self.process.term.append(data_point) 
     465        else: 
     466            self.process.notes.append(data_point) 
    413467 
    414468    def add_intermediate(self): 
     
    452506            spectrum_list = [] 
    453507            for spectrum in self.current_datainfo.trans_spectrum: 
    454                 spectrum.transmission = np.delete(spectrum.transmission, [0]) 
    455508                spectrum.transmission = spectrum.transmission.astype(np.float64) 
    456                 spectrum.transmission_deviation = np.delete( 
    457                     spectrum.transmission_deviation, [0]) 
    458509                spectrum.transmission_deviation = \ 
    459510                    spectrum.transmission_deviation.astype(np.float64) 
    460                 spectrum.wavelength = np.delete(spectrum.wavelength, [0]) 
    461511                spectrum.wavelength = spectrum.wavelength.astype(np.float64) 
    462512                if len(spectrum.transmission) > 0: 
     
    490540            if dataset.data.ndim == 2: 
    491541                (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] 
     542                flat_qy = dataset.qy_data[0::n_cols].flatten() 
     543                if flat_qy[0] == flat_qy[1]: 
     544                    flat_qy = np.transpose(dataset.qy_data)[0::n_cols].flatten() 
     545                dataset.y_bins = np.unique(flat_qy) 
     546                flat_qx = dataset.qx_data[0::n_rows].flatten() 
     547                if flat_qx[0] == flat_qx[1]: 
     548                    flat_qx = np.transpose(dataset.qx_data)[0::n_rows].flatten() 
     549                dataset.x_bins = np.unique(flat_qx) 
    494550                dataset.data = dataset.data.flatten() 
     551                dataset.qx_data = dataset.qx_data.flatten() 
     552                dataset.qy_data = dataset.qy_data.flatten() 
    495553            self.current_dataset = dataset 
    496554            self.send_to_output() 
     
    515573        self.current_datainfo = DataInfo() 
    516574 
    517  
    518     def _initialize_new_data_set(self, parent_list=None): 
     575    def _initialize_new_data_set(self, value=None): 
    519576        """ 
    520577        A private class method to generate a new 1D or 2D data object based on 
     
    524581        :param parent_list: List of names of parent elements 
    525582        """ 
    526  
    527         if parent_list is None: 
    528             parent_list = [] 
    529         if self._find_intermediate(parent_list, "Qx"): 
     583        if self._is2d(value): 
    530584            self.current_dataset = plottable_2D() 
    531585        else: 
     
    534588            self.current_dataset = plottable_1D(x, y) 
    535589        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. 
     590        self.mask_name = "" 
     591        self.i_name = "" 
     592        self.i_node = "" 
     593        self.q_name = [] 
     594        self.q_uncertainties = [] 
     595        self.q_resolutions = [] 
     596        self.i_uncertainties = "" 
     597 
     598    @staticmethod 
     599    def check_is_list_or_array(iterable): 
     600        try: 
     601            iter(iterable) 
     602            if (not isinstance(iterable, np.ndarray) and not isinstance( 
     603                    iterable, list)) or (isinstance(iterable, str) or 
     604                                         isinstance(iterable, unicode)): 
     605                raise TypeError 
     606        except TypeError: 
     607            iterable = iterable.split(",") 
     608        return iterable 
     609 
     610    def _find_data_attributes(self, value): 
     611        """ 
     612        A class to find the indices for Q, the name of the Qdev and Idev, and 
     613        the name of the mask. 
     614        :param value: SASdata/NXdata HDF5 Group 
     615        """ 
     616        attrs = value.attrs 
     617        signal = attrs.get("signal", "I") 
     618        i_axes = attrs.get("I_axes", ["Q"]) 
     619        q_indices = attrs.get("Q_indices", [0]) 
     620        q_indices = map(int, self.check_is_list_or_array(q_indices)) 
     621        i_axes = self.check_is_list_or_array(i_axes) 
     622        keys = value.keys() 
     623        self.mask_name = attrs.get("mask") 
     624        for val in q_indices: 
     625            self.q_name.append(i_axes[val]) 
     626        self.i_name = signal 
     627        self.i_node = value.get(self.i_name) 
     628        for item in self.q_name: 
     629            if item in keys: 
     630                q_vals = value.get(item) 
     631                if q_vals.attrs.get("uncertainties") is not None: 
     632                    self.q_uncertainties = q_vals.attrs.get("uncertainties") 
     633                elif q_vals.attrs.get("uncertainty") is not None: 
     634                    self.q_uncertainties = q_vals.attrs.get("uncertainty") 
     635                if isinstance(self.q_uncertainties, str): 
     636                    self.q_uncertainties = self.q_uncertainties.split(",") 
     637                if q_vals.attrs.get("resolutions") is not None: 
     638                    self.q_resolutions = q_vals.attrs.get("resolutions") 
     639                if isinstance(self.q_resolutions, (str, unicode)): 
     640                    self.q_resolutions = self.q_resolutions.split(",") 
     641        if self.i_name in keys: 
     642            i_vals = value.get(self.i_name) 
     643            self.i_uncertainties = i_vals.attrs.get("uncertainties") 
     644            if self.i_uncertainties is None: 
     645                self.i_uncertainties = i_vals.attrs.get("uncertainty") 
     646 
     647    def _is2d(self, value, basename="I"): 
     648        """ 
     649        A private class to determine if the data set is 1d or 2d. 
    541650 
    542651        :param parent_list: List of parents nodes in the HDF5 file 
    543652        :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 
     653        :return: True if 2D, otherwise false 
     654        """ 
     655 
     656        vals = value.get(basename) 
     657        return (vals is not None and vals.shape is not None 
     658                and len(vals.shape) != 1) 
    557659 
    558660    def _create_unique_key(self, dictionary, name, numb=0): 
     
    583685        if unit is None: 
    584686            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}" 
    590687        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

    rb963b20 rfeec1cb  
    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) 
     
    25282530            text += 'dY_min = %s:  dY_max = %s\n' % (min(data.dy), max(data.dy)) 
    25292531        text += '\nData Points:\n' 
    2530         x_st = "X" 
     2532        text += "<index> \t<X> \t<Y> \t<dY> \t<dX" 
     2533        if data.dxl is not None and data.dxw is not None: 
     2534                text += "l> \t<dxw" 
     2535        text += ">\n" 
    25312536        for index in range(len(data.x)): 
    25322537            if data.dy is not None and len(data.dy) > index: 
     
    25392544                dx_val = 0.0 
    25402545            if data.dxl is not None and len(data.dxl) > index: 
    2541                 if index == 0: 
    2542                     x_st = "Xl" 
    25432546                dx_val = data.dxl[index] 
    2544             elif data.dxw is not None and len(data.dxw) > index: 
    2545                 if index == 0: 
    2546                     x_st = "Xw" 
    2547                 dx_val = data.dxw[index] 
    2548  
    2549             if index == 0: 
    2550                 text += "<index> \t<X> \t<Y> \t<dY> \t<d%s>\n" % x_st 
     2547                if data.dxw is not None and len(data.dxw) > index: 
     2548                    dx_val = "%s \t%s" % (data.dxl[index], data.dxw[index]) 
     2549 
    25512550            text += "%s \t%s \t%s \t%s \t%s\n" % (index, 
    25522551                                                  data.x[index], 
     
    25652564        """ 
    25662565        default_name = fname 
    2567         wildcard = "IGOR/DAT 2D file in Q_map (*.dat)|*.DAT" 
     2566        wildcard = "IGOR/DAT 2D file in Q_map (*.dat)|*.DAT|"\ 
     2567                   "NXcanSAS files (*.h5)|*.h5|" 
    25682568        dlg = wx.FileDialog(self, "Choose a file", 
    25692569                            self._default_save_location, 
     
    25772577            if ext_num == 0: 
    25782578                ext_format = '.dat' 
     2579            elif ext_num == 1: 
     2580                ext_format = '.h5' 
    25792581            else: 
    25802582                ext_format = '' 
     
    25842586            # Instantiate a loader 
    25852587            loader = Loader() 
    2586  
    2587             ext_format = ".dat" 
    2588             if os.path.splitext(mypath)[1].lower() == ext_format: 
     2588            if os.path.splitext(mypath)[1].lower() == '.dat': 
    25892589                # Make sure the ext included in the file name 
    25902590                # especially on MAC 
    25912591                fileName = os.path.splitext(path)[0] + ext_format 
    25922592                loader.save(fileName, data, ext_format) 
     2593            elif os.path.splitext(mypath)[1].lower() == '.h5': 
     2594                # Make sure the ext included in the file name 
     2595                # especially on MAC 
     2596                fileName = os.path.splitext(path)[0] + ext_format 
     2597                nxcansaswriter = NXcanSASWriter() 
     2598                nxcansaswriter.write([data], fileName) 
    25932599            try: 
    25942600                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.