Changeset c222c27 in sasview for src/sas/sascalc


Ignore:
Timestamp:
Nov 15, 2018 2:09:18 PM (6 years ago)
Author:
Jeff Krzywon <jkrzywon@…>
Branches:
master, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249
Children:
9220e89c
Parents:
a165bee (diff), f560e23 (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/sascalc
Files:
3 deleted
20 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/calculator/c_extensions/sld2i_module.c

    ra1daf86 r7ba6470  
    22  SLD2I module to perform point and I calculations 
    33 */ 
     4#include <stdio.h> 
     5 
     6//#define Py_LIMITED_API 0x03020000 
    47#include <Python.h> 
    5 #include <stdio.h> 
     8 
    69#include "sld2i.h" 
    710 
     
    1316#endif 
    1417 
    15  
    16 // Utilities 
    17 #define INVECTOR(obj,buf,len)                                                                           \ 
    18     do { \ 
    19         int err = PyObject_AsReadBuffer(obj, (const void **)(&buf), &len); \ 
    20         if (err < 0) return NULL; \ 
    21         len /= sizeof(*buf); \ 
    22     } while (0) 
    23  
    24 #define OUTVECTOR(obj,buf,len) \ 
    25     do { \ 
    26         int err = PyObject_AsWriteBuffer(obj, (void **)(&buf), &len); \ 
    27         if (err < 0) return NULL; \ 
    28         len /= sizeof(*buf); \ 
    29     } while (0) 
    30  
     18// Vector binding glue 
     19#if (PY_VERSION_HEX > 0x03000000) && !defined(Py_LIMITED_API) 
     20  // Assuming that a view into a writable vector points to a  
     21  // non-changing pointer for the duration of the C call, capture  
     22  // the view pointer and immediately free the view. 
     23  #define VECTOR(VEC_obj, VEC_buf, VEC_len) do { \ 
     24    Py_buffer VEC_view; \ 
     25    int VEC_err = PyObject_GetBuffer(VEC_obj, &VEC_view, PyBUF_WRITABLE|PyBUF_FORMAT); \ 
     26    if (VEC_err < 0 || sizeof(*VEC_buf) != VEC_view.itemsize) return NULL; \ 
     27    VEC_buf = (typeof(VEC_buf))VEC_view.buf; \ 
     28    VEC_len = VEC_view.len/sizeof(*VEC_buf); \ 
     29    PyBuffer_Release(&VEC_view); \ 
     30  } while (0) 
     31#else 
     32  #define VECTOR(VEC_obj, VEC_buf, VEC_len) do { \ 
     33    int VEC_err = PyObject_AsWriteBuffer(VEC_obj, (void **)(&VEC_buf), &VEC_len); \ 
     34    if (VEC_err < 0) return NULL; \ 
     35    VEC_len /= sizeof(*VEC_buf); \ 
     36  } while (0) 
     37#endif 
    3138 
    3239/** 
     
    7380        //printf("new GenI\n"); 
    7481        if (!PyArg_ParseTuple(args, "iOOOOOOOOddd", &is_avg, &x_val_obj, &y_val_obj, &z_val_obj, &sldn_val_obj, &mx_val_obj, &my_val_obj, &mz_val_obj, &vol_pix_obj, &inspin, &outspin, &stheta)) return NULL; 
    75         INVECTOR(x_val_obj, x_val, n_x); 
    76         INVECTOR(y_val_obj, y_val, n_y); 
    77         INVECTOR(z_val_obj, z_val, n_z); 
    78         INVECTOR(sldn_val_obj, sldn_val, n_sld); 
    79         INVECTOR(mx_val_obj, mx_val, n_mx); 
    80         INVECTOR(my_val_obj, my_val, n_my); 
    81         INVECTOR(mz_val_obj, mz_val, n_mz); 
    82         INVECTOR(vol_pix_obj, vol_pix, n_vol_pix); 
     82        VECTOR(x_val_obj, x_val, n_x); 
     83        VECTOR(y_val_obj, y_val, n_y); 
     84        VECTOR(z_val_obj, z_val, n_z); 
     85        VECTOR(sldn_val_obj, sldn_val, n_sld); 
     86        VECTOR(mx_val_obj, mx_val, n_mx); 
     87        VECTOR(my_val_obj, my_val, n_my); 
     88        VECTOR(mz_val_obj, mz_val, n_mz); 
     89        VECTOR(vol_pix_obj, vol_pix, n_vol_pix); 
    8390        sld2i = PyMem_Malloc(sizeof(GenI)); 
    8491        //printf("sldi:%p\n", sld2i); 
     
    108115        if (!PyArg_ParseTuple(args, "OOOO",  &gen_obj, &qx_obj, &qy_obj, &I_out_obj)) return NULL; 
    109116        sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI"); 
    110         INVECTOR(qx_obj, qx, n_qx); 
    111         INVECTOR(qy_obj, qy, n_qy); 
    112         OUTVECTOR(I_out_obj, I_out, n_out); 
     117        VECTOR(qx_obj, qx, n_qx); 
     118        VECTOR(qy_obj, qy, n_qy); 
     119        VECTOR(I_out_obj, I_out, n_out); 
    113120        //printf("qx, qy, I_out: %d %d %d, %d %d %d\n", qx, qy, I_out, n_qx, n_qy, n_out); 
    114121 
     
    136143        if (!PyArg_ParseTuple(args, "OOO",  &gen_obj, &q_obj, &I_out_obj)) return NULL; 
    137144        sld2i = (GenI *)PyCapsule_GetPointer(gen_obj, "GenI"); 
    138         INVECTOR(q_obj, q, n_q); 
    139         OUTVECTOR(I_out_obj, I_out, n_out); 
     145        VECTOR(q_obj, q, n_q); 
     146        VECTOR(I_out_obj, I_out, n_out); 
    140147 
    141148        // Sanity check 
     
    160167 
    161168#define MODULE_DOC "Sld2i C Library" 
    162 #define MODULE_NAME "sld2i" 
    163 #define MODULE_INIT2 initsld2i 
    164 #define MODULE_INIT3 PyInit_sld2i 
     169#define MODULE_NAME "_sld2i" 
     170#define MODULE_INIT2 init_sld2i 
     171#define MODULE_INIT3 PyInit__sld2i 
    165172#define MODULE_METHODS module_methods 
    166173 
  • src/sas/sascalc/calculator/sas_gen.py

    r144e032a r952ea1f  
    1414import numpy as np 
    1515 
    16 from .core import sld2i as mod 
     16from . import _sld2i 
    1717from .BaseComponent import BaseComponent 
    1818 
     
    145145            self.params['Up_frac_out'], 
    146146            self.params['Up_theta']) 
    147         model = mod.new_GenI(*args) 
     147        model = _sld2i.new_GenI(*args) 
    148148        if len(qy): 
    149149            qx, qy = _vec(qx), _vec(qy) 
    150150            I_out = np.empty_like(qx) 
    151151            #print("npoints", qx.shape, "npixels", pos_x.shape) 
    152             mod.genicomXY(model, qx, qy, I_out) 
     152            _sld2i.genicomXY(model, qx, qy, I_out) 
    153153            #print("I_out after", I_out) 
    154154        else: 
    155155            qx = _vec(qx) 
    156156            I_out = np.empty_like(qx) 
    157             mod.genicom(model, qx, I_out) 
     157            _sld2i.genicom(model, qx, I_out) 
    158158        vol_correction = self.data_total_volume / self.params['total_volume'] 
    159159        result = (self.params['scale'] * vol_correction * I_out 
     
    304304                z_dir2 *= z_dir2 
    305305                mask = (x_dir2 + y_dir2 + z_dir2) <= 1.0 
    306             except Exception: 
    307                 logger.error(sys.exc_value) 
     306            except Exception as exc: 
     307                logger.error(exc) 
    308308        self.output = MagSLD(self.pos_x[mask], self.pos_y[mask], 
    309309                             self.pos_z[mask], self.sld_n[mask], 
     
    600600                        y_lines.append(y_line) 
    601601                        z_lines.append(z_line) 
    602                 except Exception: 
    603                     logger.error(sys.exc_value) 
     602                except Exception as exc: 
     603                    logger.error(exc) 
    604604 
    605605            output = MagSLD(pos_x, pos_y, pos_z, sld_n, sld_mx, sld_my, sld_mz) 
     
    691691                            _vol_pix = float(toks[7]) 
    692692                            vol_pix = np.append(vol_pix, _vol_pix) 
    693                         except Exception: 
     693                        except Exception as exc: 
    694694                            vol_pix = None 
    695                     except Exception: 
     695                    except Exception as exc: 
    696696                        # Skip non-data lines 
    697                         logger.error(sys.exc_value) 
     697                        logger.error(exc) 
    698698            output = MagSLD(pos_x, pos_y, pos_z, sld_n, 
    699699                            sld_mx, sld_my, sld_mz) 
  • src/sas/sascalc/dataloader/file_reader_base_class.py

    r9b08354 rc222c27  
    241241                    data.xmax = np.max(data.qx_data) 
    242242                    data.ymin = np.min(data.qy_data) 
    243                     data.ymax = np.max(data.qx_data) 
     243                    data.ymax = np.max(data.qy_data) 
    244244 
    245245    @staticmethod 
  • src/sas/sascalc/file_converter/bsl_loader.py

    rf00691d4 r952ea1f  
    1 from sas.sascalc.file_converter.core.bsl_loader import CLoader 
     1from sas.sascalc.file_converter._bsl_loader import CLoader 
    22from sas.sascalc.dataloader.data_info import Data2D 
    33from copy import deepcopy 
     
    6767                    'swap_bytes': int(metadata[3]) 
    6868                } 
    69             except: 
     69            except Exception: 
    7070                is_valid = False 
    7171                err_msg = "Invalid metadata in header file for {}" 
  • src/sas/sascalc/file_converter/c_ext/bsl_loader.c

    rd5aeaa3 r952ea1f  
     1#include <stdio.h> 
     2#include <stdlib.h> 
     3 
     4//#define Py_LIMITED_API 0x03020000 
    15#include <Python.h> 
     6#include <structmember.h> 
    27#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 
    38#include <numpy/arrayobject.h> 
    4 #include <stdio.h> 
    5 #include <stdlib.h> 
    6 #include "structmember.h" 
     9 
    710#include "bsl_loader.h" 
    811 
     
    292295 
    293296#define MODULE_DOC "C module for loading bsl." 
    294 #define MODULE_NAME "bsl_loader" 
    295 #define MODULE_INIT2 initbsl_loader 
    296 #define MODULE_INIT3 PyInit_bsl_loader 
     297#define MODULE_NAME "_bsl_loader" 
     298#define MODULE_INIT2 init_bsl_loader 
     299#define MODULE_INIT3 PyInit__bsl_loader 
    297300#define MODULE_METHODS module_methods 
    298301 
  • src/sas/sascalc/pr/c_extensions/Cinvertor.c

    ra52f32f r7ba6470  
    55 * 
    66 */ 
    7 #include <Python.h> 
    8 #include "structmember.h" 
    97#include <stdio.h> 
    108#include <stdlib.h> 
     
    1210#include <time.h> 
    1311 
     12//#define Py_LIMITED_API 0x03050000 
     13#include <Python.h> 
     14#include <structmember.h> 
     15 
     16// Vector binding glue 
     17#if (PY_VERSION_HEX > 0x03000000) && !defined(Py_LIMITED_API) 
     18  // Assuming that a view into a writable vector points to a 
     19  // non-changing pointer for the duration of the C call, capture 
     20  // the view pointer and immediately free the view. 
     21  #define VECTOR(VEC_obj, VEC_buf, VEC_len) do { \ 
     22    Py_buffer VEC_view; \ 
     23    int VEC_err = PyObject_GetBuffer(VEC_obj, &VEC_view, PyBUF_WRITABLE|PyBUF_FORMAT); \ 
     24    if (VEC_err < 0 || sizeof(*VEC_buf) != VEC_view.itemsize) return NULL; \ 
     25    VEC_buf = (typeof(VEC_buf))VEC_view.buf; \ 
     26    VEC_len = VEC_view.len/sizeof(*VEC_buf); \ 
     27    PyBuffer_Release(&VEC_view); \ 
     28  } while (0) 
     29#else 
     30  #define VECTOR(VEC_obj, VEC_buf, VEC_len) do { \ 
     31    int VEC_err = PyObject_AsWriteBuffer(VEC_obj, (void **)(&VEC_buf), &VEC_len); \ 
     32    if (VEC_err < 0) return NULL; \ 
     33    VEC_len /= sizeof(*VEC_buf); \ 
     34  } while (0) 
     35#endif 
     36 
    1437#include "invertor.h" 
    15  
    1638 
    1739/// Error object for raised exceptions 
    1840PyObject * CinvertorError; 
    19  
    20 #define INVECTOR(obj,buf,len)                                                                           \ 
    21     do { \ 
    22         int err = PyObject_AsReadBuffer(obj, (const void **)(&buf), &len); \ 
    23         if (err < 0) return NULL; \ 
    24         len /= sizeof(*buf); \ 
    25     } while (0) 
    26  
    27 #define OUTVECTOR(obj,buf,len) \ 
    28     do { \ 
    29         int err = PyObject_AsWriteBuffer(obj, (void **)(&buf), &len); \ 
    30         if (err < 0) return NULL; \ 
    31         len /= sizeof(*buf); \ 
    32     } while (0) 
    33  
    3441 
    3542// Class definition 
     
    99106 
    100107        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    101         OUTVECTOR(data_obj,data,ndata); 
     108        VECTOR(data_obj,data,ndata); 
    102109 
    103110        free(self->params.x); 
     
    131138 
    132139        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    133         OUTVECTOR(data_obj, data, ndata); 
     140        VECTOR(data_obj, data, ndata); 
    134141 
    135142        // Check that the input array is large enough 
     
    164171 
    165172        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    166         OUTVECTOR(data_obj,data,ndata); 
     173        VECTOR(data_obj,data,ndata); 
    167174 
    168175        free(self->params.y); 
     
    196203 
    197204        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    198         OUTVECTOR(data_obj, data, ndata); 
     205        VECTOR(data_obj, data, ndata); 
    199206 
    200207        // Check that the input array is large enough 
     
    229236 
    230237        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    231         OUTVECTOR(data_obj,data,ndata); 
     238        VECTOR(data_obj,data,ndata); 
    232239 
    233240        free(self->params.err); 
     
    261268 
    262269        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    263         OUTVECTOR(data_obj, data, ndata); 
     270        VECTOR(data_obj, data, ndata); 
    264271 
    265272        // Check that the input array is large enough 
     
    517524        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    518525 
    519         OUTVECTOR(data_obj,pars,npars); 
     526        VECTOR(data_obj,pars,npars); 
    520527 
    521528    // PyList of residuals 
     
    568575        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    569576 
    570         OUTVECTOR(data_obj,pars,npars); 
     577        VECTOR(data_obj,pars,npars); 
    571578 
    572579        // Should create this list only once and refill it 
     
    609616 
    610617        if (!PyArg_ParseTuple(args, "Od", &data_obj, &q)) return NULL; 
    611         OUTVECTOR(data_obj,pars,npars); 
     618        VECTOR(data_obj,pars,npars); 
    612619 
    613620        iq_value = iq(pars, self->params.d_max, (int)npars, q); 
     
    634641 
    635642        if (!PyArg_ParseTuple(args, "Od", &data_obj, &q)) return NULL; 
    636         OUTVECTOR(data_obj,pars,npars); 
     643        VECTOR(data_obj,pars,npars); 
    637644 
    638645        iq_value = iq_smeared(pars, self->params.d_max, (int)npars, 
     
    659666 
    660667        if (!PyArg_ParseTuple(args, "Od", &data_obj, &r)) return NULL; 
    661         OUTVECTOR(data_obj,pars,npars); 
     668        VECTOR(data_obj,pars,npars); 
    662669 
    663670        pr_value = pr(pars, self->params.d_max, (int)npars, r); 
     
    686693 
    687694        if (!PyArg_ParseTuple(args, "OOd", &data_obj, &err_obj, &r)) return NULL; 
    688         OUTVECTOR(data_obj,pars,npars); 
     695        VECTOR(data_obj,pars,npars); 
    689696 
    690697        if (err_obj == Py_None) { 
     
    692699                pr_err_value = 0.0; 
    693700        } else { 
    694                 OUTVECTOR(err_obj,pars_err,npars2); 
     701                VECTOR(err_obj,pars_err,npars2); 
    695702                pr_err(pars, pars_err, self->params.d_max, (int)npars, r, &pr_value, &pr_err_value); 
    696703        } 
     
    726733 
    727734        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    728         OUTVECTOR(data_obj,pars,npars); 
     735        VECTOR(data_obj,pars,npars); 
    729736 
    730737        oscill = reg_term(pars, self->params.d_max, (int)npars, 100); 
     
    747754 
    748755        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    749         OUTVECTOR(data_obj,pars,npars); 
     756        VECTOR(data_obj,pars,npars); 
    750757 
    751758        count = npeaks(pars, self->params.d_max, (int)npars, 100); 
     
    768775 
    769776        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    770         OUTVECTOR(data_obj,pars,npars); 
     777        VECTOR(data_obj,pars,npars); 
    771778 
    772779        fraction = positive_integral(pars, self->params.d_max, (int)npars, 100); 
     
    792799 
    793800        if (!PyArg_ParseTuple(args, "OO", &data_obj, &err_obj)) return NULL; 
    794         OUTVECTOR(data_obj,pars,npars); 
    795         OUTVECTOR(err_obj,pars_err,npars2); 
     801        VECTOR(data_obj,pars,npars); 
     802        VECTOR(err_obj,pars_err,npars2); 
    796803 
    797804        fraction = positive_errors(pars, pars_err, self->params.d_max, (int)npars, 51); 
     
    813820 
    814821        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    815         OUTVECTOR(data_obj,pars,npars); 
     822        VECTOR(data_obj,pars,npars); 
    816823 
    817824        value = rg(pars, self->params.d_max, (int)npars, 101); 
     
    833840 
    834841        if (!PyArg_ParseTuple(args, "O", &data_obj)) return NULL; 
    835         OUTVECTOR(data_obj,pars,npars); 
     842        VECTOR(data_obj,pars,npars); 
    836843 
    837844        value = 4.0*acos(-1.0)*int_pr(pars, self->params.d_max, (int)npars, 101); 
     
    874881 
    875882        if (!PyArg_ParseTuple(args, "iiOO", &nfunc, &nr, &a_obj, &b_obj)) return NULL; 
    876         OUTVECTOR(a_obj,a,n_a); 
    877         OUTVECTOR(b_obj,b,n_b); 
     883        VECTOR(a_obj,a,n_a); 
     884        VECTOR(b_obj,b,n_b); 
    878885 
    879886        assert(n_b>=nfunc); 
     
    947954 
    948955        if (!PyArg_ParseTuple(args, "iiOO", &nfunc, &nr, &a_obj, &cov_obj)) return NULL; 
    949         OUTVECTOR(a_obj,a,n_a); 
    950         OUTVECTOR(cov_obj,inv_cov,n_cov); 
     956        VECTOR(a_obj,a,n_a); 
     957        VECTOR(cov_obj,inv_cov,n_cov); 
    951958 
    952959        assert(n_cov>=nfunc*nfunc); 
     
    981988 
    982989        if (!PyArg_ParseTuple(args, "iiO", &nfunc, &nr, &a_obj)) return NULL; 
    983         OUTVECTOR(a_obj,a,n_a); 
     990        VECTOR(a_obj,a,n_a); 
    984991 
    985992        assert(n_a>=nfunc*(nr+self->params.npoints)); 
     
    11211128 
    11221129#define MODULE_DOC "C extension module for inversion to P(r)." 
    1123 #define MODULE_NAME "pr_inversion" 
    1124 #define MODULE_INIT2 initpr_inversion 
    1125 #define MODULE_INIT3 PyInit_pr_inversion 
     1130#define MODULE_NAME "_pr_inversion" 
     1131#define MODULE_INIT2 init_pr_inversion 
     1132#define MODULE_INIT3 PyInit__pr_inversion 
    11261133#define MODULE_METHODS module_methods 
    11271134 
  • src/sas/sascalc/pr/fit/BumpsFitting.py

    r9a5097c r3e6829d  
    22BumpsFitting module runs the bumps optimizer. 
    33""" 
     4from __future__ import division 
     5 
    46import os 
    57from datetime import timedelta, datetime 
     
    3436class Progress(object): 
    3537    def __init__(self, history, max_step, pars, dof): 
    36         remaining_time = int(history.time[0]*(float(max_step)/history.step[0]-1)) 
     38        remaining_time = int(history.time[0]*(max_step/history.step[0]-1)) 
    3739        # Depending on the time remaining, either display the expected 
    3840        # time of completion, or the amount of time remaining.  Use precision 
  • src/sas/sascalc/pr/fit/Loader.py

    r574adc7 r57e48ca  
     1""" 
     2class Loader  to load any kind of file 
     3""" 
     4 
    15from __future__ import print_function 
    26 
    3 # class Loader  to load any king of file 
    4 #import wx 
    5 #import string 
    67import numpy as np 
    78 
  • src/sas/sascalc/pr/invertor.py

    r2469df7 r57e48ca  
    66FIXME: The way the Invertor interacts with its C component should be cleaned up 
    77""" 
     8from __future__ import division 
    89 
    910import numpy as np 
     
    1718from numpy.linalg import lstsq 
    1819from scipy import optimize 
    19 from sas.sascalc.pr.core.pr_inversion import Cinvertor 
     20from sas.sascalc.pr._pr_inversion import Cinvertor 
    2021 
    2122logger = logging.getLogger(__name__) 
     
    7172        A[j][i] = (Fourier transformed base function for point j) 
    7273 
    73     We them choose a number of r-points, n_r, to evaluate the second 
     74    We then choose a number of r-points, n_r, to evaluate the second 
    7475    derivative of P(r) at. This is used as our regularization term. 
    7576    For a vector r of length n_r, the following n_r rows are set to :: 
     
    144145        x, y, err, d_max, q_min, q_max and alpha 
    145146        """ 
    146         if   name == 'x': 
     147        if name == 'x': 
    147148            if 0.0 in value: 
    148149                msg = "Invertor: one of your q-values is zero. " 
     
    268269            A[i][j] = (Fourier transformed base function for point j) 
    269270 
    270         We them choose a number of r-points, n_r, to evaluate the second 
     271        We then choose a number of r-points, n_r, to evaluate the second 
    271272        derivative of P(r) at. This is used as our regularization term. 
    272273        For a vector r of length n_r, the following n_r rows are set to :: 
     
    416417            A[i][j] = (Fourier transformed base function for point j) 
    417418 
    418         We them choose a number of r-points, n_r, to evaluate the second 
     419        We then choose a number of r-points, n_r, to evaluate the second 
    419420        derivative of P(r) at. This is used as our regularization term. 
    420421        For a vector r of length n_r, the following n_r rows are set to :: 
     
    473474 
    474475        # Perform the inversion (least square fit) 
    475         c, chi2, _, _ = lstsq(a, b) 
     476        c, chi2, _, _ = lstsq(a, b, rcond=-1) 
    476477        # Sanity check 
    477478        try: 
     
    496497        try: 
    497498            cov = np.linalg.pinv(inv_cov) 
    498             err = math.fabs(chi2 / float(npts - nfunc)) * cov 
    499         except: 
     499            err = math.fabs(chi2 / (npts - nfunc)) * cov 
     500        except Exception as exc: 
    500501            # We were not able to estimate the errors 
    501502            # Return an empty error matrix 
    502             logger.error(sys.exc_value) 
     503            logger.error(exc) 
    503504 
    504505        # Keep a copy of the last output 
     
    537538 
    538539        """ 
    539         from num_term import NTermEstimator 
     540        from .num_term import NTermEstimator 
    540541        estimator = NTermEstimator(self.clone()) 
    541542        try: 
    542543            return estimator.num_terms(isquit_func) 
    543         except: 
     544        except Exception as exc: 
    544545            # If we fail, estimate alpha and return the default 
    545546            # number of terms 
    546547            best_alpha, _, _ = self.estimate_alpha(self.nfunc) 
    547             logger.warning("Invertor.estimate_numterms: %s" % sys.exc_value) 
     548            logger.warning("Invertor.estimate_numterms: %s" % exc) 
    548549            return self.nfunc, best_alpha, "Could not estimate number of terms" 
    549550 
     
    631632                return best_alpha, message, elapsed 
    632633 
    633         except: 
    634             message = "Invertor.estimate_alpha: %s" % sys.exc_value 
     634        except Exception as exc: 
     635            message = "Invertor.estimate_alpha: %s" % exc 
    635636            return 0, message, elapsed 
    636637 
     
    748749                        self.cov[i][i] = float(toks2[1]) 
    749750 
    750             except: 
    751                 msg = "Invertor.from_file: corrupted file\n%s" % sys.exc_value 
     751            except Exception as exc: 
     752                msg = "Invertor.from_file: corrupted file\n%s" % exc 
    752753                raise RuntimeError(msg) 
    753754        else: 
  • src/sas/sascalc/pr/num_term.py

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

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

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

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