Changeset 845144e in sasview for src/sas


Ignore:
Timestamp:
Oct 17, 2018 4:30:31 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:
9fb4572
Parents:
b204004 (diff), 67ed543 (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
27 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/fit/pagestate.py

    r59873e1 r863ac2c  
    640640                if len(value.strip()) == 0: 
    641641                    continue 
    642                 title = value + " [" + repo_time + "]" 
     642                title = (value + " [" + repo_time + "] [SasView v" + 
     643                         SASVIEW_VERSION + "]") 
    643644                title_name = HEADER % title 
    644645            elif name == "data": 
  • src/sas/sasgui/guiframe/aboutbox.py

    rb963b20 r1b4cb41  
    108108        self.bitmap_button_tudelft = wx.BitmapButton(self, -1, wx.NullBitmap) 
    109109        self.bitmap_button_dls = wx.BitmapButton(self, -1, wx.NullBitmap) 
     110        self.bitmap_button_bam = wx.BitmapButton(self, -1, wx.NullBitmap) 
    110111 
    111112        self.static_line_3 = wx.StaticLine(self, -1) 
     
    128129        self.Bind(wx.EVT_BUTTON, self.onTudelftLogo, self.bitmap_button_tudelft) 
    129130        self.Bind(wx.EVT_BUTTON, self.onDlsLogo, self.bitmap_button_dls) 
     131        self.Bind(wx.EVT_BUTTON, self.onBamLogo, self.bitmap_button_bam) 
    130132        # end wxGlade 
    131133        # fill in acknowledgements 
     
    226228        logo = wx.Bitmap(image) 
    227229        self.bitmap_button_dls.SetBitmapLabel(logo) 
     230 
     231        image = file_dir + "/images/bam_logo.png" 
     232        if os.path.isfile(config._bam_logo): 
     233            image = config._bam_logo 
     234        logo = wx.Bitmap(image) 
     235        self.bitmap_button_bam.SetBitmapLabel(logo) 
    228236 
    229237        # resize dialog window to fit version number nicely 
     
    258266        self.bitmap_button_tudelft.SetSize(self.bitmap_button_tudelft.GetBestSize()) 
    259267        self.bitmap_button_dls.SetSize(self.bitmap_button_dls.GetBestSize()) 
     268        self.bitmap_button_bam.SetSize(self.bitmap_button_bam.GetBestSize()) 
    260269        # end wxGlade 
    261270 
     
    325334        sizer_logos.Add(self.bitmap_button_dls, 0, 
    326335                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     336        sizer_logos.Add(self.bitmap_button_bam, 0, 
     337                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    327338 
    328339        sizer_logos.Add((10, 50), 0, wx.ADJUST_MINSIZE, 0) 
     
    430441        event.Skip() 
    431442 
     443    def onBamLogo(self, event): 
     444        """ 
     445        """ 
     446        # wxGlade: DialogAbout.<event_handler> 
     447        launchBrowser(config._bam_url) 
     448        event.Skip() 
     449 
    432450# end of class DialogAbout 
    433451 
  • src/sas/sasgui/guiframe/config.py

    r1efbc190 r1b4cb41  
    3333_do_aboutbox = True 
    3434_do_acknowledge = True 
     35_do_release = True 
    3536_do_tutorial = True 
    3637_acknowledgement_preamble =\ 
     
    4950_acknowledgement_citation = \ 
    5051'''M. Doucet et al. SasView Version 4.1.2, Zenodo, 10.5281/zenodo.825675''' 
    51  
    5252_acknowledgement =  \ 
    53 '''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS, and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: http://www.sasview.org/contact.html 
     53'''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS, BAM and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: http://www.sasview.org/contact.html 
    5454''' 
    5555 
     
    9090_tudelft_url = "http://www.tnw.tudelft.nl/en/cooperation/facilities/reactor-instituut-delft/" 
    9191_dls_url = "http://www.diamond.ac.uk/" 
     92_bam_url = "http://www.bam.de/" 
    9293_danse_url = "http://www.cacr.caltech.edu/projects/danse/release/index.html" 
    9394_inst_url = "http://www.utk.edu" 
    9495_corner_image = os.path.join(icon_path, "angles_flat.png") 
    9596_welcome_image = os.path.join(icon_path, "SVwelcome.png") 
    96 _copyright = "(c) 2009 - 2017, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, and DLS" 
     97_copyright = "(c) 2009 - 2018, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS and BAM" 
    9798marketplace_url = "http://marketplace.sasview.org/" 
    9899 
  • src/sas/sasgui/guiframe/gui_manager.py

    rb1ec23d r845144e  
    12771277 
    12781278        wx_id = wx.NewId() 
    1279         self._help_menu.Append(wx_id, '&Documentation', '') 
     1279        self._help_menu.Append(wx_id, '&Documentation', 'Help documentation for SasView') 
    12801280        wx.EVT_MENU(self, wx_id, self._onSphinxDocs) 
    12811281 
    12821282        if config._do_tutorial and (IS_WIN or sys.platform == 'darwin'): 
    12831283            wx_id = wx.NewId() 
    1284             self._help_menu.Append(wx_id, '&Tutorial', 'Software tutorial') 
     1284            # Pluralised both occurences of 'Tutorial' in the line below 
     1285            # S King, Sep 2018 
     1286            self._help_menu.Append(wx_id, '&Tutorials', 'Tutorials on how to use SasView') 
    12851287            wx.EVT_MENU(self, wx_id, self._onTutorial) 
     1288 
     1289        if config.marketplace_url: 
     1290            wx_id = wx.NewId() 
     1291            self._help_menu.Append(wx_id, '&Model marketplace', 'Plug-in fitting models for SasView') 
     1292            wx.EVT_MENU(self, wx_id, self._on_marketplace_click) 
     1293 
     1294        if config._do_release: 
     1295            wx_id = wx.NewId() 
     1296            self._help_menu.Append(wx_id, '&Release notes', 
     1297                                   'SasView release notes and known issues') 
     1298            wx.EVT_MENU(self, wx_id, self._onRelease) 
    12861299 
    12871300        if config._do_acknowledge: 
     
    12941307            logger.info("Doing help menu") 
    12951308            wx_id = wx.NewId() 
    1296             self._help_menu.Append(wx_id, '&About', 'Software information') 
     1309            self._help_menu.Append(wx_id, '&About', 'Information about SasView') 
    12971310            wx.EVT_MENU(self, wx_id, self._onAbout) 
    1298  
    1299         if config.marketplace_url: 
    1300             wx_id = wx.NewId() 
    1301             self._help_menu.Append(wx_id, '&Model marketplace', '') 
    1302             wx.EVT_MENU(self, wx_id, self._on_marketplace_click) 
    13031311 
    13041312        # Checking for updates 
     
    21382146            dialog.ShowModal() 
    21392147 
     2148    def _onRelease(self, evt): 
     2149        """ 
     2150        Pop up the release notes 
     2151 
     2152        :param evt: menu event 
     2153 
     2154        """ 
     2155        # S King, Sep 2018 
     2156 
     2157        from documentation_window import DocumentationWindow 
     2158        _TreeLocation = "user/release.html" 
     2159        DocumentationWindow(self, -1, _TreeLocation, "", 
     2160                            "SasView Documentation") 
     2161 
    21402162    def _onTutorial(self, evt): 
    21412163        """ 
     
    21452167 
    21462168        """ 
    2147         if config._do_tutorial: 
    2148             path = config.TUTORIAL_PATH 
    2149             if IS_WIN: 
    2150                 try: 
    2151                     from sas.sasgui.guiframe.pdfview import PDFFrame 
    2152                     dialog = PDFFrame(None, -1, "Tutorial", path) 
    2153                     # put icon 
    2154                     self.put_icon(dialog) 
    2155                     dialog.Show(True) 
    2156                 except: 
    2157                     logger.error("Error in _onTutorial: %s" % sys.exc_value) 
    2158                     try: 
    2159                         # Try an alternate method 
    2160                         logger.error( 
    2161                             "Could not open the tutorial pdf, trying xhtml2pdf") 
    2162                         from xhtml2pdf import pisa 
    2163                         pisa.startViewer(path) 
    2164                     except: 
    2165                         logger.error( 
    2166                             "Could not open the tutorial pdf with xhtml2pdf") 
    2167                         msg = "This feature requires 'PDF Viewer'\n" 
    2168                         wx.MessageBox(msg, 'Error') 
    2169             else: 
    2170                 try: 
    2171                     command = "open '%s'" % path 
    2172                     os.system(command) 
    2173                 except: 
    2174                     try: 
    2175                         # Try an alternate method 
    2176                         logger.error( 
    2177                             "Could not open the tutorial pdf, trying xhtml2pdf") 
    2178                         from xhtml2pdf import pisa 
    2179                         pisa.startViewer(path) 
    2180                     except: 
    2181                         logger.error( 
    2182                             "Could not open the tutorial pdf with xhtml2pdf") 
    2183                         msg = "This feature requires the Preview application\n" 
    2184                         wx.MessageBox(msg, 'Error') 
     2169        # Action changed from that in 2.x/3.x/4.0.x/4.1.x 
     2170        # Help >> Tutorial used to bring up a pdf of the 
     2171        # original 2.x tutorial. 
     2172        # Code below, implemented from 4.2.0, redirects 
     2173        # action to the Tutorials page of the help  
     2174        # documentation to give access to all available 
     2175        # tutorials 
     2176        # S King, Sep 2018 
     2177 
     2178        from documentation_window import DocumentationWindow 
     2179        _TreeLocation = "user/tutorial.html" 
     2180        DocumentationWindow(self, -1, _TreeLocation, "", 
     2181                            "SasView Documentation") 
    21852182 
    21862183    def _onSphinxDocs(self, evt): 
  • src/sas/sasgui/perspectives/corfunc/corfunc_panel.py

    r2a399ca r5652efc  
    2020 
    2121OUTPUT_STRINGS = { 
    22     'max': "Long Period / 2 (A): ", 
     22    'max': "Long Period (A): ", 
    2323    'Lc': "Average Hard Block Thickness (A): ", 
    2424    'dtr': "Average Interface Thickness (A): ", 
  • src/sas/sasgui/perspectives/corfunc/corfunc_state.py

    r1fa4f736 r5652efc  
    2828# List of output parameters, used by __str__ 
    2929output_list = [ 
    30     ['max', "Long Period / 2 (A): "], 
     30    ['max', "Long Period (A): "], 
    3131    ['Lc', "Average Hard Block Thickness (A): "], 
    3232    ['dtr', "Average Interface Thickness (A): "], 
  • src/sas/sasgui/perspectives/corfunc/media/corfunc_help.rst

    r501712f r490f790  
    3333Both analyses are performed in 3 stages: 
    3434 
    35 *  Extrapolation of the scattering curve to :math:`Q = 0` and toward  
    36    :math:`Q = \infty` 
     35*  Extrapolation of the scattering curve to :math:`q = 0` and toward  
     36   :math:`q = \infty` 
    3737*  Smoothed merging of the two extrapolations into the original data 
    3838*  Fourier / Hilbert Transform of the smoothed data to give the correlation 
     
    4747------------- 
    4848 
    49 To :math:`Q = 0` 
     49To :math:`q = 0` 
    5050................ 
    5151 
     
    6767the impact on any extrapolated parameters will be least significant. 
    6868 
    69 To :math:`Q = \infty` 
     69To :math:`q = \infty` 
    7070..................... 
    7171 
     
    145145        - do they smoothly curve onto the ordinate at x = 0? (if not check the value  
    146146          of :math:`\sigma` is sensible) 
    147         - are there ripples at x values corresponding to (2 :math:`pi` over) the two  
     147        - are there ripples at x values corresponding to (2 :math:`\pi` over) the two  
    148148          q values at which the extrapolated and experimental data are merged? 
    149         - are there any artefacts at x values corresponding to 2 :math:`pi` / q\ :sub:`max` in  
     149        - are there any artefacts at x values corresponding to 2 :math:`\pi` / q\ :sub:`max` in  
    150150          the experimental data?  
    151151        - and lastly, do the significant features/peaks in the correlation functions  
     
    158158    -q^{4} I(q) 
    159159 
    160 The IDF is proportional to the second derivative of Γ\ :sub:`1`\ (x). 
     160The IDF is proportional to the second derivative of Γ\ :sub:`1`\ (x) and represents a  
     161superposition of thickness distributions from all the contributing lamellae.  
    161162 
    162163Hilbert 
     
    192193*   Local Crystallinity :math:`= L_c/L_p` 
    193194 
     195.. warning:: If the sample does not possess lamellar morphology then "Compute  
     196    Parameters" will return garbage! 
     197         
     198 
    194199Volume Fraction Profile 
    195200....................... 
     
    213218 
    214219The reader is directed to the references for information on these parameters. 
     220 
    215221 
    216222References 
     
    263269Once the Q ranges have been set, click the "Calculate Bg" button to determine the  
    264270background level. Alternatively, enter your own value into the box. If the box turns  
    265 yellow this indicates that background subtraction has created some negative intensities. 
     271yellow this indicates that background subtraction has created some negative intensities.  
     272This may still be fine provided the peak intensity is very much greater than the  
     273background level. The important point is that the extrapolated dataset must approach  
     274zero at high-q. 
    266275 
    267276Now click the "Extrapolate" button to extrapolate the data. The graph window will update  
     
    296305 
    297306.. note:: 
    298     This help document was last changed by Steve King, 26Sep2017 
     307    This help document was last changed by Steve King, 28Sep2017 
  • src/sas/sasgui/perspectives/corfunc/media/fdr-pdfs.rst

    r959eb01 r577460c  
    77 
    88:download:`Fibre_Diffraction_Review_1994_3_25-29.pdf <Fibre_Diffraction_Review_1994_3_25-29.pdf>` 
     9 
    910:download:`Fibre_Diffraction_Review_2004_12_24.pdf <Fibre_Diffraction_Review_2004_12_24.pdf>` 
     11 
    1012:download:`Fibre_Diffraction_Review_2005_13_19-22.pdf <Fibre_Diffraction_Review_2005_13_19-22.pdf>` 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    ra4a1ac9 r5323490  
    28842884            self.magnetic_on = True 
    28852885            button.SetLabel("Magnetic OFF") 
    2886             m_value = 1.0e-06 
     2886            m_value = 1 
    28872887            for key in self.model.magnetic_params: 
    28882888                if key.count('M0') > 0: 
    28892889                    self.model.setParam(key, m_value) 
    2890                     m_value += 0.5e-06 
     2890                    m_value += 0.5 
    28912891        else: 
    28922892            self.magnetic_on = False 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    rdabcaf7 rba1c145  
    33    fitting  a model and one data 
    44""" 
     5from __future__ import print_function 
     6 
    57import sys 
    68import wx 
     
    12551257        if saved_pars: 
    12561258            self.get_paste_params(saved_pars) 
     1259 
     1260        # Make sure the model parameters correspond to the fit parameters 
     1261        self._update_paramv_on_fit() 
    12571262 
    12581263        if event is not None: 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    raf7d2e5 raba4559  
    339339        Update custom model list in the fitpage combo box 
    340340        """ 
    341         custom_model = 'Plugin Models' 
    342341        try: 
    343342            # Update edit menus 
     
    347346            if not new_pmodel_list: 
    348347                return 
    349             # Set the new plugin model list for all fit pages 
     348 
     349            # Redraws to a page not in focus are showing up as if they are 
     350            # in the current page tab. 
     351            current_page_index = self.fit_panel.GetSelection() 
     352            current_page = self.fit_panel.GetCurrentPage() 
     353            last_drawn_page = current_page 
     354 
     355            # Set the new plugin model list for all fit pages; anticipating 
     356            # categories, the updated plugin may be in either the form factor 
     357            # or the structure factor combo boxes 
    350358            for uid, page in self.fit_panel.opened_pages.iteritems(): 
    351                 if hasattr(page, "formfactorbox"): 
    352                     page.model_list_box = new_pmodel_list 
    353                     mod_cat = page.categorybox.GetStringSelection() 
    354                     if mod_cat == custom_model: 
    355                         box = page.formfactorbox 
    356                         model_name = box.GetValue() 
    357                         model = (box.GetClientData(box.GetCurrentSelection()) 
    358                                  if model_name else None) 
    359                         page._show_combox_helper() 
    360                         new_index = box.FindString(model_name) 
    361                         new_model = (box.GetClientData(new_index) 
    362                                      if new_index >= 0 else None) 
    363                         if new_index >= 0: 
    364                             box.SetStringSelection(model_name) 
    365                         else: 
    366                             box.SetStringSelection('') 
    367                         if model and new_model != model: 
    368                             page._on_select_model(keep_pars=True) 
    369                     if hasattr(page, "structurebox"): 
    370                         selected_name = page.structurebox.GetStringSelection() 
    371  
    372                         page.structurebox.Clear() 
    373                         page.initialize_combox() 
    374  
    375                         index = page.structurebox.FindString(selected_name) 
    376                         if index == -1: 
    377                             index = 0 
    378                         page.structurebox.SetSelection(index) 
    379                         page._on_select_model() 
     359                pbox = getattr(page, "formfactorbox", None) 
     360                sbox = getattr(page, "structurebox", None) 
     361                if pbox is None: 
     362                    continue 
     363 
     364                # Set the new model list for the page 
     365                page.model_list_box = new_pmodel_list 
     366 
     367                # Grab names of the P and S models from the page.  Need to do 
     368                # this before resetting the form factor box since that clears 
     369                # the structure factor box. 
     370                old_struct = old_form = None 
     371                form_name = pbox.GetValue() 
     372                struct_name = sbox.GetStringSelection() 
     373                if form_name: 
     374                    old_form = pbox.GetClientData(pbox.GetCurrentSelection()) 
     375                if struct_name: 
     376                    old_struct = sbox.GetClientData(sbox.GetCurrentSelection()) 
     377 
     378                # Reset form factor combo box.  We are doing this for all 
     379                # categories not just plugins since eventually the category 
     380                # manager will allow plugin models to be anywhere. 
     381                page._show_combox_helper() 
     382                form_index = pbox.FindString(form_name) 
     383                pbox.SetSelection(form_index) 
     384                new_form = (pbox.GetClientData(form_index) 
     385                            if form_index != wx.NOT_FOUND else None) 
     386                #print("form: %r"%form_name, old_form, new_form) 
     387 
     388                # Reset structure factor combo box; even if the model list 
     389                # hasn't changed, the model may have.  Show the structure 
     390                # factor combobox if the selected model is a form factor. 
     391                sbox.Clear() 
     392                page.initialize_combox() 
     393                if new_form is not None and getattr(new_form, 'is_form_factor', False): 
     394                    sbox.Show() 
     395                    sbox.Enable() 
     396                    page.text2.Show() 
     397                    page.text2.Enable() 
     398                struct_index = sbox.FindString(struct_name) 
     399                sbox.SetSelection(struct_index) 
     400                new_struct = (sbox.GetClientData(struct_index) 
     401                              if struct_index != wx.NOT_FOUND else None) 
     402                #print("struct: %r"%struct_name, old_struct, new_struct) 
     403 
     404                # Update the page if P or S has changed 
     405                if old_form != new_form or old_struct != new_struct: 
     406                    #print("triggering model update") 
     407                    page._on_select_model(keep_pars=True) 
     408                    last_drawn_page = page 
     409 
     410            # If last drawn is not the current, then switch the current to the 
     411            # last drawn then switch back.  Very ugly. 
     412            if last_drawn_page != current_page: 
     413                for page_index in range(self.fit_panel.PageCount): 
     414                    if self.fit_panel.GetPage(page_index) == last_drawn_page: 
     415                        self.fit_panel.SetSelection(page_index) 
     416                        break 
     417                self.fit_panel.SetSelection(current_page_index) 
     418 
    380419        except Exception: 
    381420            logger.error("update_custom_combo: %s", sys.exc_value) 
  • src/sas/sasgui/perspectives/invariant/invariant_state.py

    rfa412df re9920cd  
    130130        my_time, date = self.timestamp 
    131131        file_name = self.file 
     132        from sas.sasview.__init__ import __version__ as sasview_version 
    132133 
    133134        state_num = int(self.saved_state['state_num']) 
    134135        state = "\n[Invariant computation for %s: " % file_name 
    135         state += "performed at %s on %s] \n" % (my_time, date) 
     136        state += "performed at %s on %s] " % (my_time, date) 
     137        state += "[SasView v%s]\n" % (sasview_version) 
    136138        state += "State No.: %d \n" % state_num 
    137139        state += "\n=== Inputs ===\n" 
  • src/sas/sasview/local_config.py

    rb229a3b r1b4cb41  
    3333_do_aboutbox = True 
    3434_do_acknowledge = True 
     35_do_release = True 
    3536_do_tutorial = True 
    3637_acknowledgement_preamble =\ 
     
    4950_acknowledgement_citation = \ 
    5051'''M. Doucet et al. SasView Version 4.2, Zenodo, 10.5281/zenodo.1412041''' 
    51  
    5252_acknowledgement =  \ 
    53 '''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS, and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: http://www.sasview.org/contact.html 
     53'''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS, BAM and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: http://www.sasview.org/contact.html 
    5454''' 
    5555 
     
    7676_tudelft_logo = os.path.join(icon_path, "tudelft_logo.png") 
    7777_dls_logo = os.path.join(icon_path, "dls_logo.png") 
     78_bam_logo = os.path.join(icon_path, "bam_logo.png") 
    7879_nsf_logo = os.path.join(icon_path, "nsf_logo.png") 
    7980_danse_logo = os.path.join(icon_path, "danse_logo.png") 
     
    9495_corner_image = os.path.join(icon_path, "angles_flat.png") 
    9596_welcome_image = os.path.join(icon_path, "SVwelcome.png") 
    96 _copyright = "(c) 2009 - 2017, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, and DLS" 
     97_copyright = "(c) 2009 - 2018, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS and BAM" 
    9798marketplace_url = "http://marketplace.sasview.org/" 
    9899 
  • 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 rb1ec23d  
    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                n_rows, n_cols = data.data.shape 
     234                data.y_bins = data.qy_data[0::int(n_cols)] 
     235                data.x_bins = data.qx_data[:int(n_cols)] 
     236                data.data = data.data.flatten() 
     237                data = self._remove_nans_in_data(data) 
     238                if len(data.data) > 0: 
     239                    data.xmin = np.min(data.qx_data) 
     240                    data.xmax = np.max(data.qx_data) 
     241                    data.ymin = np.min(data.qy_data) 
     242                    data.ymax = np.max(data.qx_data) 
    205243 
    206244    @staticmethod 
     
    242280        return data 
    243281 
    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) 
     282    @staticmethod 
     283    def set_default_1d_units(data): 
     284        """ 
     285        Set the x and y axes to the default 1D units 
     286        :param data: 1D data set 
     287        :return: 
     288        """ 
     289        data.xaxis(r"\rm{Q}", '1/A') 
     290        data.yaxis(r"\rm{Intensity}", "1/cm") 
     291        return data 
     292 
     293    @staticmethod 
     294    def set_default_2d_units(data): 
     295        """ 
     296        Set the x and y axes to the default 2D units 
     297        :param data: 2D data set 
     298        :return: 
     299        """ 
     300        data.xaxis("\\rm{Q_{x}}", '1/A') 
     301        data.yaxis("\\rm{Q_{y}}", '1/A') 
     302        data.zaxis("\\rm{Intensity}", "1/cm") 
     303        return data 
     304 
     305    def convert_data_units(self, default_q_unit="1/A", default_i_unit="1/cm"): 
     306        """ 
     307        Converts al; data to the sasview default of units of A^{-1} for Q and 
     308        cm^{-1} for I. 
     309        :param default_q_unit: The default Q unit used by Sasview 
     310        :param default_i_unit: The default I unit used by Sasview 
     311        """ 
     312        new_output = [] 
     313        for data in self.output: 
     314            if data.isSesans: 
     315                new_output.append(data) 
     316                continue 
     317            file_x_unit = data._xunit 
     318            data_conv_x = Converter(file_x_unit) 
     319            file_y_unit = data._yunit 
     320            data_conv_y = Converter(file_y_unit) 
     321            if isinstance(data, Data1D): 
     322                try: 
     323                    data.x = data_conv_x(data.x, units=default_q_unit) 
     324                    data._xunit = default_q_unit 
     325                    data.x_unit = default_q_unit 
     326                    if data.dx is not None: 
     327                        data.dx = data_conv_x(data.dx, units=default_q_unit) 
     328                    if data.dxl is not None: 
     329                        data.dxl = data_conv_x(data.dxl, units=default_q_unit) 
     330                    if data.dxw is not None: 
     331                        data.dxw = data_conv_x(data.dxw, units=default_q_unit) 
     332                except KeyError: 
     333                    message = "Unable to convert Q units from {0} to 1/A." 
     334                    message.format(default_q_unit) 
     335                    data.errors.append(message) 
     336                try: 
     337                    data.y = data_conv_y(data.y, units=default_i_unit) 
     338                    data._yunit = default_i_unit 
     339                    data.y_unit = default_i_unit 
     340                    if data.dy is not None: 
     341                        data.dy = data_conv_y(data.dy, units=default_i_unit) 
     342                except KeyError: 
     343                    message = "Unable to convert I units from {0} to 1/cm." 
     344                    message.format(default_q_unit) 
     345                    data.errors.append(message) 
     346            elif isinstance(data, Data2D): 
     347                try: 
     348                    data.qx_data = data_conv_x(data.qx_data, 
     349                                               units=default_q_unit) 
     350                    if data.dqx_data is not None: 
     351                        data.dqx_data = data_conv_x(data.dqx_data, 
     352                                                    units=default_q_unit) 
     353                    data.qy_data = data_conv_y(data.qy_data, 
     354                                               units=default_q_unit) 
     355                    if data.dqy_data is not None: 
     356                        data.dqy_data = data_conv_y(data.dqy_data, 
     357                                                    units=default_q_unit) 
     358                except KeyError: 
     359                    message = "Unable to convert Q units from {0} to 1/A." 
     360                    message.format(default_q_unit) 
     361                    data.errors.append(message) 
     362                try: 
     363                    file_z_unit = data._zunit 
     364                    data_conv_z = Converter(file_z_unit) 
     365                    data.data = data_conv_z(data.data, units=default_i_unit) 
     366                    if data.err_data is not None: 
     367                        data.err_data = data_conv_z(data.err_data, 
     368                                                    units=default_i_unit) 
     369                except KeyError: 
     370                    message = "Unable to convert I units from {0} to 1/cm." 
     371                    message.format(default_q_unit) 
     372                    data.errors.append(message) 
     373            else: 
     374                # TODO: Throw error of some sort... 
     375                pass 
     376            new_output.append(data) 
     377        self.output = new_output 
    279378 
    280379    def format_unit(self, unit=None): 
     
    367466                    self.current_dataset.qy_data)) 
    368467            if has_error_dy: 
    369                 self.current_dataset.err_data = self.current_dataset.err_data[x != 0] 
     468                self.current_dataset.err_data = self.current_dataset.err_data[ 
     469                    x != 0] 
    370470            if has_error_dqx: 
    371                 self.current_dataset.dqx_data = self.current_dataset.dqx_data[x != 0] 
     471                self.current_dataset.dqx_data = self.current_dataset.dqx_data[ 
     472                    x != 0] 
    372473            if has_error_dqy: 
    373                 self.current_dataset.dqy_data = self.current_dataset.dqy_data[x != 0] 
     474                self.current_dataset.dqy_data = self.current_dataset.dqy_data[ 
     475                    x != 0] 
    374476            if has_mask: 
    375477                self.current_dataset.mask = self.current_dataset.mask[x != 0] 
  • src/sas/sascalc/dataloader/loader.py

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

    rbd5c3b1 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 rb204004  
    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_names = [] 
     107        self.mask_name = u'' 
     108        self.i_name = u'' 
     109        self.i_node = u'' 
     110        self.i_uncertainties_name = u'' 
     111        self.q_uncertainty_names = [] 
     112        self.q_resolution_names = [] 
    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_name: 
     243            self.current_dataset.dy = data_set.flatten() 
     244        elif key in self.q_names: 
     245            self.current_dataset.xaxis("Q", unit) 
     246            self.current_dataset.x = data_set.flatten() 
     247        elif key in self.q_resolution_names: 
     248            if (len(self.q_resolution_names) > 1 
     249                    and np.where(self.q_resolution_names == key)[0] == 0): 
     250                self.current_dataset.dxw = data_set.flatten() 
     251            elif (len(self.q_resolution_names) > 1 
     252                  and np.where(self.q_resolution_names == key)[0] == 1): 
     253                self.current_dataset.dxl = data_set.flatten() 
     254            else: 
     255                self.current_dataset.dx = data_set.flatten() 
     256        elif key in self.q_uncertainty_names: 
     257            if (len(self.q_uncertainty_names) > 1 
     258                    and np.where(self.q_uncertainty_names == key)[0] == 0): 
     259                self.current_dataset.dxw = data_set.flatten() 
     260            elif (len(self.q_uncertainty_names) > 1 
     261                  and np.where(self.q_uncertainty_names == key)[0] == 1): 
     262                self.current_dataset.dxl = data_set.flatten() 
     263            else: 
     264                self.current_dataset.dx = data_set.flatten() 
     265        elif key == self.mask_name: 
     266            self.current_dataset.mask = data_set.flatten() 
     267        elif key == u'wavelength': 
     268            self.current_datainfo.source.wavelength = data_set[0] 
     269            self.current_datainfo.source.wavelength_unit = unit 
     270 
     271    def process_2d_data_object(self, data_set, key, unit): 
     272        if key == self.i_name: 
     273            self.current_dataset.data = data_set 
     274            self.current_dataset.zaxis("Intensity", unit) 
     275        elif key == self.i_uncertainties_name: 
     276            self.current_dataset.err_data = data_set.flatten() 
     277        elif key in self.q_names: 
     278            self.current_dataset.xaxis("Q_x", unit) 
     279            self.current_dataset.yaxis("Q_y", unit) 
     280            if self.q_names[0] == self.q_names[1]: 
     281                # All q data in a single array 
     282                self.current_dataset.qx_data = data_set[0] 
     283                self.current_dataset.qy_data = data_set[1] 
     284            elif self.q_names.index(key) == 0: 
     285                self.current_dataset.qx_data = data_set 
     286            elif self.q_names.index(key) == 1: 
     287                self.current_dataset.qy_data = data_set 
     288        elif key in self.q_uncertainty_names or key in self.q_resolution_names: 
     289            if ((self.q_uncertainty_names[0] == self.q_uncertainty_names[1]) or 
     290                    (self.q_resolution_names[0] == self.q_resolution_names[1])): 
     291                # All q data in a single array 
     292                self.current_dataset.dqx_data = data_set[0].flatten() 
     293                self.current_dataset.dqy_data = data_set[1].flatten() 
     294            elif (self.q_uncertainty_names.index(key) == 0 or 
     295                  self.q_resolution_names.index(key) == 0): 
     296                self.current_dataset.dqx_data = data_set.flatten() 
     297            elif (self.q_uncertainty_names.index(key) == 1 or 
     298                  self.q_resolution_names.index(key) == 1): 
     299                self.current_dataset.dqy_data = data_set.flatten() 
     300                self.current_dataset.yaxis("Q_y", unit) 
     301        elif key == self.mask_name: 
     302            self.current_dataset.mask = data_set.flatten() 
     303        elif key == u'Qy': 
     304            self.current_dataset.yaxis("Q_y", unit) 
     305            self.current_dataset.qy_data = data_set.flatten() 
     306        elif key == u'Qydev': 
     307            self.current_dataset.dqy_data = data_set.flatten() 
     308        elif key == u'Qx': 
     309            self.current_dataset.xaxis("Q_x", unit) 
     310            self.current_dataset.qx_data = data_set.flatten() 
     311        elif key == u'Qxdev': 
     312            self.current_dataset.dqx_data = data_set.flatten() 
     313 
     314    def process_trans_spectrum(self, data_set, key): 
     315        """ 
     316        SAStransmission_spectrum processor 
     317        :param data_set: data from HDF5 file 
     318        :param key: canSAS_class attribute 
     319        """ 
     320        if key == u'T': 
     321            self.trans_spectrum.transmission = data_set.flatten() 
     322        elif key == u'Tdev': 
     323            self.trans_spectrum.transmission_deviation = data_set.flatten() 
     324        elif key == u'lambda': 
     325            self.trans_spectrum.wavelength = data_set.flatten() 
     326 
     327    def process_sample(self, data_point, key): 
     328        """ 
     329        SASsample processor 
     330        :param data_point: Single point from an HDF5 data file 
     331        :param key: class name data_point was taken from 
     332        """ 
     333        if key == u'Title': 
     334            self.current_datainfo.sample.name = data_point 
     335        elif key == u'name': 
     336            self.current_datainfo.sample.name = data_point 
     337        elif key == u'ID': 
     338            self.current_datainfo.sample.name = data_point 
     339        elif key == u'thickness': 
     340            self.current_datainfo.sample.thickness = data_point 
     341        elif key == u'temperature': 
     342            self.current_datainfo.sample.temperature = data_point 
     343        elif key == u'transmission': 
     344            self.current_datainfo.sample.transmission = data_point 
     345        elif key == u'x_position': 
     346            self.current_datainfo.sample.position.x = data_point 
     347        elif key == u'y_position': 
     348            self.current_datainfo.sample.position.y = data_point 
     349        elif key == u'pitch': 
     350            self.current_datainfo.sample.orientation.x = data_point 
     351        elif key == u'yaw': 
     352            self.current_datainfo.sample.orientation.y = data_point 
     353        elif key == u'roll': 
     354            self.current_datainfo.sample.orientation.z = data_point 
     355        elif key == u'details': 
     356            self.current_datainfo.sample.details.append(data_point) 
     357 
     358    def process_detector(self, data_point, key, unit): 
     359        """ 
     360        SASdetector processor 
     361        :param data_point: Single point from an HDF5 data file 
     362        :param key: class name data_point was taken from 
     363        :param unit: unit attribute from data set 
     364        """ 
     365        if key == u'name': 
     366            self.detector.name = data_point 
     367        elif key == u'SDD': 
     368            self.detector.distance = float(data_point) 
     369            self.detector.distance_unit = unit 
     370        elif key == u'slit_length': 
     371            self.detector.slit_length = float(data_point) 
     372            self.detector.slit_length_unit = unit 
     373        elif key == u'x_position': 
     374            self.detector.offset.x = float(data_point) 
     375            self.detector.offset_unit = unit 
     376        elif key == u'y_position': 
     377            self.detector.offset.y = float(data_point) 
     378            self.detector.offset_unit = unit 
     379        elif key == u'pitch': 
     380            self.detector.orientation.x = float(data_point) 
     381            self.detector.orientation_unit = unit 
     382        elif key == u'roll': 
     383            self.detector.orientation.z = float(data_point) 
     384            self.detector.orientation_unit = unit 
     385        elif key == u'yaw': 
     386            self.detector.orientation.y = float(data_point) 
     387            self.detector.orientation_unit = unit 
     388        elif key == u'beam_center_x': 
     389            self.detector.beam_center.x = float(data_point) 
     390            self.detector.beam_center_unit = unit 
     391        elif key == u'beam_center_y': 
     392            self.detector.beam_center.y = float(data_point) 
     393            self.detector.beam_center_unit = unit 
     394        elif key == u'x_pixel_size': 
     395            self.detector.pixel_size.x = float(data_point) 
     396            self.detector.pixel_size_unit = unit 
     397        elif key == u'y_pixel_size': 
     398            self.detector.pixel_size.y = float(data_point) 
     399            self.detector.pixel_size_unit = unit 
     400 
     401    def process_collimation(self, data_point, key, unit): 
     402        """ 
     403        SAScollimation processor 
     404        :param data_point: Single point from an HDF5 data file 
     405        :param key: class name data_point was taken from 
     406        :param unit: unit attribute from data set 
     407        """ 
     408        if key == u'distance': 
     409            self.collimation.length = data_point 
     410            self.collimation.length_unit = unit 
     411        elif key == u'name': 
     412            self.collimation.name = data_point 
     413 
     414    def process_aperture(self, data_point, key): 
     415        """ 
     416        SASaperture processor 
     417        :param data_point: Single point from an HDF5 data file 
     418        :param key: class name data_point was taken from 
     419        """ 
     420        if key == u'shape': 
     421            self.aperture.shape = data_point 
     422        elif key == u'x_gap': 
     423            self.aperture.size.x = data_point 
     424        elif key == u'y_gap': 
     425            self.aperture.size.y = data_point 
     426 
     427    def process_source(self, data_point, key, unit): 
     428        """ 
     429        SASsource processor 
     430        :param data_point: Single point from an HDF5 data file 
     431        :param key: class name data_point was taken from 
     432        :param unit: unit attribute from data set 
     433        """ 
     434        if key == u'incident_wavelength': 
     435            self.current_datainfo.source.wavelength = data_point 
     436            self.current_datainfo.source.wavelength_unit = unit 
     437        elif key == u'wavelength_max': 
     438            self.current_datainfo.source.wavelength_max = data_point 
     439            self.current_datainfo.source.wavelength_max_unit = unit 
     440        elif key == u'wavelength_min': 
     441            self.current_datainfo.source.wavelength_min = data_point 
     442            self.current_datainfo.source.wavelength_min_unit = unit 
     443        elif key == u'incident_wavelength_spread': 
     444            self.current_datainfo.source.wavelength_spread = data_point 
     445            self.current_datainfo.source.wavelength_spread_unit = unit 
     446        elif key == u'beam_size_x': 
     447            self.current_datainfo.source.beam_size.x = data_point 
     448            self.current_datainfo.source.beam_size_unit = unit 
     449        elif key == u'beam_size_y': 
     450            self.current_datainfo.source.beam_size.y = data_point 
     451            self.current_datainfo.source.beam_size_unit = unit 
     452        elif key == u'beam_shape': 
     453            self.current_datainfo.source.beam_shape = data_point 
     454        elif key == u'radiation': 
     455            self.current_datainfo.source.radiation = data_point 
     456 
     457    def process_process(self, data_point, key): 
     458        """ 
     459        SASprocess processor 
     460        :param data_point: Single point from an HDF5 data file 
     461        :param key: class name data_point was taken from 
     462        """ 
     463        term_match = re.compile(u'^term[0-9]+$') 
     464        if key == u'Title':  # CanSAS 2.0 
     465            self.process.name = data_point 
     466        elif key == u'name':  # NXcanSAS 
     467            self.process.name = data_point 
     468        elif key == u'description': 
     469            self.process.description = data_point 
     470        elif key == u'date': 
     471            self.process.date = data_point 
     472        elif term_match.match(key): 
     473            self.process.term.append(data_point) 
     474        else: 
     475            self.process.notes.append(data_point) 
    413476 
    414477    def add_intermediate(self): 
     
    452515            spectrum_list = [] 
    453516            for spectrum in self.current_datainfo.trans_spectrum: 
    454                 spectrum.transmission = np.delete(spectrum.transmission, [0]) 
    455517                spectrum.transmission = spectrum.transmission.astype(np.float64) 
    456                 spectrum.transmission_deviation = np.delete( 
    457                     spectrum.transmission_deviation, [0]) 
    458518                spectrum.transmission_deviation = \ 
    459519                    spectrum.transmission_deviation.astype(np.float64) 
    460                 spectrum.wavelength = np.delete(spectrum.wavelength, [0]) 
    461520                spectrum.wavelength = spectrum.wavelength.astype(np.float64) 
    462521                if len(spectrum.transmission) > 0: 
     
    490549            if dataset.data.ndim == 2: 
    491550                (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] 
     551                flat_qy = dataset.qy_data[0::n_cols].flatten() 
     552                # For 2D arrays of Qx and Qy, the Q value should be constant 
     553                # along each row -OR- each column. The direction is not 
     554                # specified in the NXcanSAS standard. 
     555                if flat_qy[0] == flat_qy[1]: 
     556                    flat_qy = np.transpose(dataset.qy_data)[0::n_cols].flatten() 
     557                dataset.y_bins = np.unique(flat_qy) 
     558                flat_qx = dataset.qx_data[0::n_rows].flatten() 
     559                # For 2D arrays of Qx and Qy, the Q value should be constant 
     560                # along each row -OR- each column. The direction is not 
     561                # specified in the NXcanSAS standard. 
     562                if flat_qx[0] == flat_qx[1]: 
     563                    flat_qx = np.transpose(dataset.qx_data)[0::n_rows].flatten() 
     564                dataset.x_bins = np.unique(flat_qx) 
    494565                dataset.data = dataset.data.flatten() 
     566                dataset.qx_data = dataset.qx_data.flatten() 
     567                dataset.qy_data = dataset.qy_data.flatten() 
    495568            self.current_dataset = dataset 
    496569            self.send_to_output() 
     
    515588        self.current_datainfo = DataInfo() 
    516589 
    517  
    518     def _initialize_new_data_set(self, parent_list=None): 
     590    def _initialize_new_data_set(self, value=None): 
    519591        """ 
    520592        A private class method to generate a new 1D or 2D data object based on 
     
    524596        :param parent_list: List of names of parent elements 
    525597        """ 
    526  
    527         if parent_list is None: 
    528             parent_list = [] 
    529         if self._find_intermediate(parent_list, "Qx"): 
     598        if self._is2d(value): 
    530599            self.current_dataset = plottable_2D() 
    531600        else: 
     
    534603            self.current_dataset = plottable_1D(x, y) 
    535604        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. 
     605        self.mask_name = u'' 
     606        self.i_name = u'' 
     607        self.i_node = u'' 
     608        self.i_uncertainties_name = u'' 
     609        self.q_names = [] 
     610        self.q_uncertainty_names = [] 
     611        self.q_resolution_names = [] 
     612 
     613    @staticmethod 
     614    def check_is_list_or_array(iterable): 
     615        try: 
     616            iter(iterable) 
     617            if (not isinstance(iterable, np.ndarray) and not isinstance( 
     618                    iterable, list)) or (isinstance(iterable, basestring)): 
     619                raise TypeError 
     620        except TypeError: 
     621            iterable = iterable.split(",") 
     622        return iterable 
     623 
     624    def _find_data_attributes(self, value): 
     625        """ 
     626        A class to find the indices for Q, the name of the Qdev and Idev, and 
     627        the name of the mask. 
     628        :param value: SASdata/NXdata HDF5 Group 
     629        """ 
     630        attrs = value.attrs 
     631        signal = attrs.get("signal", "I") 
     632        i_axes = attrs.get("I_axes", ["Q"]) 
     633        q_indices = attrs.get("Q_indices", [0]) 
     634        q_indices = map(int, self.check_is_list_or_array(q_indices)) 
     635        i_axes = self.check_is_list_or_array(i_axes) 
     636        keys = value.keys() 
     637        self.mask_name = attrs.get("mask") 
     638        for val in q_indices: 
     639            self.q_names.append(i_axes[val]) 
     640        self.i_name = signal 
     641        self.i_node = value.get(self.i_name) 
     642        for item in self.q_names: 
     643            if item in keys: 
     644                q_vals = value.get(item) 
     645                if q_vals.attrs.get("uncertainties") is not None: 
     646                    self.q_uncertainty_names = q_vals.attrs.get("uncertainties") 
     647                elif q_vals.attrs.get("uncertainty") is not None: 
     648                    self.q_uncertainty_names = q_vals.attrs.get("uncertainty") 
     649                if isinstance(self.q_uncertainty_names, basestring): 
     650                    self.q_uncertainty_names = self.q_uncertainty_names.split(",") 
     651                if q_vals.attrs.get("resolutions") is not None: 
     652                    self.q_resolution_names = q_vals.attrs.get("resolutions") 
     653                if isinstance(self.q_resolution_names, basestring): 
     654                    self.q_resolution_names = self.q_resolution_names.split(",") 
     655        if self.i_name in keys: 
     656            i_vals = value.get(self.i_name) 
     657            self.i_uncertainties_name = i_vals.attrs.get("uncertainties") 
     658            if self.i_uncertainties_name is None: 
     659                self.i_uncertainties_name = i_vals.attrs.get("uncertainty") 
     660 
     661    def _is2d(self, value, basename="I"): 
     662        """ 
     663        A private class to determine if the data set is 1d or 2d. 
    541664 
    542665        :param parent_list: List of parents nodes in the HDF5 file 
    543666        :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 
     667        :return: True if 2D, otherwise false 
     668        """ 
     669 
     670        vals = value.get(basename) 
     671        return (vals is not None and vals.shape is not None 
     672                and len(vals.shape) != 1) 
    557673 
    558674    def _create_unique_key(self, dictionary, name, numb=0): 
     
    583699        if unit is None: 
    584700            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}" 
    590701        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/local_perspectives/data_loader/data_loader.py

    r9c7e2b8 r5218180  
    205205            except NoKnownLoaderException as e: 
    206206                exception_occurred = True 
    207                 error_message = "Loading data failed!" + e.message 
     207                error_message = "Loading data failed!\n" + e.message 
    208208                file_errors[basename] = [error_message] 
    209209            except Exception as e: 
     
    224224                for message in error_array: 
    225225                    error_message += message + "\n" 
     226                error_message = error_message[:-1] 
    226227            self.load_complete(output=output, 
    227228                               message=error_message, 
     
    231232            self.load_complete(output=output, message="Loading data complete!", 
    232233                               info="info") 
    233         else: 
    234             self.load_complete(output=None, message=error_message, info="error") 
    235234 
    236235    def load_update(self, message="", info="warning"): 
Note: See TracChangeset for help on using the changeset viewer.