Changeset c5251f6 in sasview for src/sas


Ignore:
Timestamp:
Apr 1, 2017 4:43:32 PM (7 years ago)
Author:
gonzalezm
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
80a49c2
Parents:
51335d7 (diff), 7cbbacd (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' of https://github.com/SasView/sasview

Location:
src/sas
Files:
32 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/calculator/slit_length_calculator.py

    rb699768 rbfba720  
    1616        # y data 
    1717        self.y = None 
    18         #default slit length 
     18        # default slit length 
    1919        self.slit_length = 0.0 
    2020 
     
    4242        """ 
    4343        # None data do nothing 
    44         if self.y == None or self.x == None: 
     44        if self.y is None or self.x is None: 
    4545            return 
    4646        # set local variable 
     
    5454        y_sum = 0.0 
    5555        y_max = 0.0 
    56         ind = 0.0 
     56        ind = 0 
    5757 
    5858        # sum 10 or more y values until getting max_y, 
     
    7070        # defaults 
    7171        y_half_d = 0.0 
    72         ind = 0.0 
     72        ind = 0 
    7373        # find indices where it crosses y = y_half. 
    7474        while True: 
     
    8181 
    8282        # y value and ind just before passed the spot of the half height 
    83         y_half_u = y[ind-1] 
     83        y_half_u = y[ind - 1] 
    8484 
    8585        # get corresponding x values 
    8686        x_half_d = x[ind] 
    87         x_half_u = x[ind-1] 
     87        x_half_u = x[ind - 1] 
    8888 
    8989        # calculate x at y = y_half using linear interpolation 
     
    9191            x_half = (x_half_d + x_half_u)/2.0 
    9292        else: 
    93             x_half = (x_half_u * (y_half - y_half_d)  \ 
    94                        + x_half_d * (y_half_u - y_half)) \ 
    95                         / (y_half_u - y_half_d) 
     93            x_half = ((x_half_u * (y_half - y_half_d) 
     94                       + x_half_d * (y_half_u - y_half)) 
     95                       / (y_half_u - y_half_d)) 
    9696 
    9797        # Our slit length is half width, so just give half beam value 
  • src/sas/sascalc/data_util/qsmearing.py

    rd3911e3 r775e0b7  
    1414import sys 
    1515 
     16import numpy as np  # type: ignore 
     17from numpy import pi, exp # type:ignore 
     18 
    1619from sasmodels.resolution import Slit1D, Pinhole1D 
     20from sasmodels.sesans import SesansTransform 
    1721from sasmodels.resolution2d import Pinhole2D 
     22from .nxsunit import Converter 
    1823 
    1924def smear_selection(data, model = None): 
     
    3641    # Sanity check. If we are not dealing with a SAS Data1D 
    3742    # object, just return None 
     43    # This checks for 2D data (does not throw exception because fail is common) 
    3844    if  data.__class__.__name__ not in ['Data1D', 'Theory1D']: 
    3945        if data == None: 
     
    4147        elif data.dqx_data == None or data.dqy_data == None: 
    4248            return None 
    43         return PySmear2D(data, model) 
    44  
     49        return PySmear2D(data) 
     50    # This checks for 1D data with smearing info in the data itself (again, fail is likely; no exceptions) 
    4551    if  not hasattr(data, "dx") and not hasattr(data, "dxl")\ 
    4652         and not hasattr(data, "dxw"): 
     
    4854 
    4955    # Look for resolution smearing data 
     56    # This is the code that checks for SESANS data; it looks for the file loader 
     57    # TODO: change other sanity checks to check for file loader instead of data structure? 
     58    _found_sesans = False 
     59    #if data.dx is not None and data.meta_data['loader']=='SESANS': 
     60    if data.dx is not None and data.isSesans: 
     61        #if data.dx[0] > 0.0: 
     62        if numpy.size(data.dx[data.dx <= 0]) == 0: 
     63            _found_sesans = True 
     64        # if data.dx[0] <= 0.0: 
     65        if numpy.size(data.dx[data.dx <= 0]) > 0: 
     66            raise ValueError('one or more of your dx values are negative, please check the data file!') 
     67 
     68    if _found_sesans == True: 
     69        #Pre-compute the Hankel matrix (H) 
     70        qmax, qunits = data.sample.zacceptance 
     71        SElength = Converter(data._xunit)(data.x, "A") 
     72        zaccept = Converter(qunits)(qmax, "1/A"), 
     73        Rmax = 10000000 
     74        hankel = SesansTransform(data.x, SElength, zaccept, Rmax) 
     75        # Then return the actual transform, as if it were a smearing function 
     76        return PySmear(hankel, model, offset=0) 
     77 
    5078    _found_resolution = False 
    5179    if data.dx is not None and len(data.dx) == len(data.x): 
     
    89117    Wrapper for pure python sasmodels resolution functions. 
    90118    """ 
    91     def __init__(self, resolution, model): 
     119    def __init__(self, resolution, model, offset=None): 
    92120        self.model = model 
    93121        self.resolution = resolution 
    94         self.offset = numpy.searchsorted(self.resolution.q_calc, self.resolution.q[0]) 
     122        if offset is None: 
     123            offset = numpy.searchsorted(self.resolution.q_calc, self.resolution.q[0]) 
     124        self.offset = offset 
    95125 
    96126    def apply(self, iq_in, first_bin=0, last_bin=None): 
  • src/sas/sascalc/dataloader/data_info.py

    r345e7e4 r2ffe241  
    2525import numpy 
    2626import math 
    27  
    28 class plottable_sesans1D(object): 
    29     """ 
    30     SESANS is a place holder for 1D SESANS plottables. 
    31  
    32     #TODO: This was directly copied from the plottables_1D. Modified Somewhat. 
    33     #Class has been updated. 
    34     """ 
    35     # The presence of these should be mutually 
    36     # exclusive with the presence of Qdev (dx) 
    37     x = None 
    38     y = None 
    39     lam = None 
    40     dx = None 
    41     dy = None 
    42     dlam = None 
    43     ## Slit smearing length 
    44     dxl = None 
    45     ## Slit smearing width 
    46     dxw = None 
    47  
    48     # Units 
    49     _xaxis = '' 
    50     _xunit = '' 
    51     _yaxis = '' 
    52     _yunit = '' 
    53  
    54     def __init__(self, x, y, lam, dx=None, dy=None, dlam=None): 
    55 #        print "SESANS plottable working" 
    56         self.x = numpy.asarray(x) 
    57         self.y = numpy.asarray(y) 
    58         self.lam = numpy.asarray(lam) 
    59         if dx is not None: 
    60             self.dx = numpy.asarray(dx) 
    61         if dy is not None: 
    62             self.dy = numpy.asarray(dy) 
    63         if dlam is not None: 
    64             self.dlam = numpy.asarray(dlam) 
    65  
    66     def xaxis(self, label, unit): 
    67         """ 
    68         set the x axis label and unit 
    69         """ 
    70         self._xaxis = label 
    71         self._xunit = unit 
    72  
    73     def yaxis(self, label, unit): 
    74         """ 
    75         set the y axis label and unit 
    76         """ 
    77         self._yaxis = label 
    78         self._yunit = unit 
    79  
    8027 
    8128class plottable_1D(object): 
     
    9340    ## Slit smearing width 
    9441    dxw = None 
     42    ## SESANS specific params (wavelengths for spin echo length calculation) 
     43    lam = None 
     44    dlam = None 
    9545 
    9646    # Units 
     
    10050    _yunit = '' 
    10151 
    102     def __init__(self, x, y, dx=None, dy=None, dxl=None, dxw=None): 
     52    def __init__(self, x, y, dx=None, dy=None, dxl=None, dxw=None, lam=None, dlam=None): 
    10353        self.x = numpy.asarray(x) 
    10454        self.y = numpy.asarray(y) 
     
    11161        if dxw is not None: 
    11262            self.dxw = numpy.asarray(dxw) 
     63        if lam is not None: 
     64            self.lam = numpy.asarray(lam) 
     65        if dlam is not None: 
     66            self.dlam = numpy.asarray(dlam) 
    11367 
    11468    def xaxis(self, label, unit): 
     
    398352    ## Details 
    399353    details = None 
     354    ## SESANS zacceptance 
     355    zacceptance = None 
    400356 
    401357    def __init__(self): 
     
    535491    ## Loading errors 
    536492    errors = None 
     493    ## SESANS data check 
     494    isSesans = None 
     495 
    537496 
    538497    def __init__(self): 
     
    567526        ## Loading errors 
    568527        self.errors = [] 
     528        ## SESANS data check 
     529        self.isSesans = False 
    569530 
    570531    def append_empty_process(self): 
     
    586547        _str += "Title:           %s\n" % self.title 
    587548        _str += "Run:             %s\n" % str(self.run) 
     549        _str += "SESANS:          %s\n" % str(self.isSesans) 
    588550        _str += "Instrument:      %s\n" % str(self.instrument) 
    589551        _str += "%s\n" % str(self.sample) 
     
    736698        return self._perform_union(other) 
    737699 
    738 class SESANSData1D(plottable_sesans1D, DataInfo): 
    739     """ 
    740     SESANS 1D data class 
    741     """ 
    742     x_unit = 'nm' 
    743     y_unit = 'pol' 
    744  
    745     def __init__(self, x=None, y=None, lam=None, dx=None, dy=None, dlam=None): 
     700class Data1D(plottable_1D, DataInfo): 
     701    """ 
     702    1D data class 
     703    """ 
     704    def __init__(self, x=None, y=None, dx=None, dy=None, lam=None, dlam=None, isSesans=None): 
    746705        DataInfo.__init__(self) 
    747         plottable_sesans1D.__init__(self, x, y, lam, dx, dy, dlam) 
     706        plottable_1D.__init__(self, x, y, dx, dy,None, None, lam, dlam) 
     707        self.isSesans = isSesans 
     708        try: 
     709            if self.isSesans: # the data is SESANS 
     710                self.x_unit = 'A' 
     711                self.y_unit = 'pol' 
     712            elif not self.isSesans: # the data is SANS 
     713                self.x_unit = '1/A' 
     714                self.y_unit = '1/cm' 
     715        except: # the data is not recognized/supported, and the user is notified 
     716            raise(TypeError, 'data not recognized, check documentation for supported 1D data formats') 
    748717 
    749718    def __str__(self): 
     
    759728        return _str 
    760729 
    761     def clone_without_data(self, length=0, clone=None): 
    762         """ 
    763         Clone the current object, without copying the data (which 
    764         will be filled out by a subsequent operation). 
    765         The data arrays will be initialized to zero. 
    766  
    767         :param length: length of the data array to be initialized 
    768         :param clone: if provided, the data will be copied to clone 
    769         """ 
    770         from copy import deepcopy 
    771         if clone is None or not issubclass(clone.__class__, Data1D): 
    772             x = numpy.zeros(length) 
    773             dx = numpy.zeros(length) 
    774             y = numpy.zeros(length) 
    775             dy = numpy.zeros(length) 
    776             clone = Data1D(x, y, dx=dx, dy=dy) 
    777  
    778         clone.title = self.title 
    779         clone.run = self.run 
    780         clone.filename = self.filename 
    781         clone.instrument = self.instrument 
    782         clone.notes = deepcopy(self.notes) 
    783         clone.process = deepcopy(self.process) 
    784         clone.detector = deepcopy(self.detector) 
    785         clone.sample = deepcopy(self.sample) 
    786         clone.source = deepcopy(self.source) 
    787         clone.collimation = deepcopy(self.collimation) 
    788         clone.trans_spectrum = deepcopy(self.trans_spectrum) 
    789         clone.meta_data = deepcopy(self.meta_data) 
    790         clone.errors = deepcopy(self.errors) 
    791  
    792         return clone 
    793  
    794 class Data1D(plottable_1D, DataInfo): 
    795     """ 
    796     1D data class 
    797     """ 
    798     x_unit = '1/A' 
    799     y_unit = '1/cm' 
    800  
    801     def __init__(self, x, y, dx=None, dy=None): 
    802         DataInfo.__init__(self) 
    803         plottable_1D.__init__(self, x, y, dx, dy) 
    804  
    805     def __str__(self): 
    806         """ 
    807         Nice printout 
    808         """ 
    809         _str = "%s\n" % DataInfo.__str__(self) 
    810         _str += "Data:\n" 
    811         _str += "   Type:         %s\n" % self.__class__.__name__ 
    812         _str += "   X-axis:       %s\t[%s]\n" % (self._xaxis, self._xunit) 
    813         _str += "   Y-axis:       %s\t[%s]\n" % (self._yaxis, self._yunit) 
    814         _str += "   Length:       %g\n" % len(self.x) 
    815         return _str 
    816  
    817730    def is_slit_smeared(self): 
    818731        """ 
     
    843756            y = numpy.zeros(length) 
    844757            dy = numpy.zeros(length) 
    845             clone = Data1D(x, y, dx=dx, dy=dy) 
     758            lam = numpy.zeros(length) 
     759            dlam = numpy.zeros(length) 
     760            clone = Data1D(x, y, lam=lam, dx=dx, dy=dy, dlam=dlam) 
    846761 
    847762        clone.title = self.title 
     
    1018933    ## Vector of Q-values at the center of each bin in y 
    1019934    y_bins = None 
     935    ## No 2D SESANS data as of yet. Always set it to False 
     936    isSesans = False 
    1020937 
    1021938    def __init__(self, data=None, err_data=None, qx_data=None, 
    1022939                 qy_data=None, q_data=None, mask=None, 
    1023940                 dqx_data=None, dqy_data=None): 
    1024         self.y_bins = [] 
    1025         self.x_bins = [] 
    1026941        DataInfo.__init__(self) 
    1027942        plottable_2D.__init__(self, data, err_data, qx_data, 
    1028943                              qy_data, q_data, mask, dqx_data, dqy_data) 
     944        self.y_bins = [] 
     945        self.x_bins = [] 
     946 
    1029947        if len(self.detector) > 0: 
    1030948            raise RuntimeError, "Data2D: Detector bank already filled at init" 
     
    12651183    final_dataset.xmin = data.xmin 
    12661184    final_dataset.ymin = data.ymin 
     1185    final_dataset.isSesans = datainfo.isSesans 
    12671186    final_dataset.title = datainfo.title 
    12681187    final_dataset.run = datainfo.run 
  • src/sas/sascalc/dataloader/readers/cansas_constants.py

    r250fec92 rad4632c  
    133133               "variable" : None, 
    134134               "children" : {"Idata" : SASDATA_IDATA, 
     135                             "Sesans": {"storeas": "content"}, 
     136                             "zacceptance": {"storeas": "float"}, 
    135137                             "<any>" : ANY 
    136138                            } 
  • src/sas/sascalc/dataloader/readers/cansas_reader.py

    r0639476 r8434365  
    2020import inspect 
    2121# For saving individual sections of data 
    22 from sas.sascalc.dataloader.data_info import Data1D, DataInfo, plottable_1D 
    23 from sas.sascalc.dataloader.data_info import Collimation, TransmissionSpectrum, Detector, Process, Aperture 
    24 from sas.sascalc.dataloader.data_info import combine_data_info_with_plottable as combine_data 
     22from sas.sascalc.dataloader.data_info import Data1D, Data2D, DataInfo, \ 
     23    plottable_1D, plottable_2D 
     24from sas.sascalc.dataloader.data_info import Collimation, TransmissionSpectrum, \ 
     25    Detector, Process, Aperture 
     26from sas.sascalc.dataloader.data_info import \ 
     27    combine_data_info_with_plottable as combine_data 
    2528import sas.sascalc.dataloader.readers.xml_reader as xml_reader 
    2629from sas.sascalc.dataloader.readers.xml_reader import XMLreader 
     
    5659        The CanSAS reader requires PyXML 0.8.4 or later. 
    5760    """ 
    58     ## CanSAS version - defaults to version 1.0 
     61    # CanSAS version - defaults to version 1.0 
    5962    cansas_version = "1.0" 
    6063    base_ns = "{cansas1d/1.0}" 
     
    6366    invalid = True 
    6467    frm = "" 
    65     ## Log messages and errors 
     68    # Log messages and errors 
    6669    logging = None 
    6770    errors = set() 
    68     ## Namespace hierarchy for current xml_file object 
     71    # Namespace hierarchy for current xml_file object 
    6972    names = None 
    7073    ns_list = None 
    71     ## Temporary storage location for loading multiple data sets in a single file 
     74    # Temporary storage location for loading multiple data sets in a single file 
    7275    current_datainfo = None 
    7376    current_dataset = None 
    7477    current_data1d = None 
    7578    data = None 
    76     ## List of data1D objects to be sent back to SasView 
     79    # List of data1D objects to be sent back to SasView 
    7780    output = None 
    78     ## Wildcards 
     81    # Wildcards 
    7982    type = ["XML files (*.xml)|*.xml", "SasView Save Files (*.svs)|*.svs"] 
    80     ## List of allowed extensions 
     83    # List of allowed extensions 
    8184    ext = ['.xml', '.XML', '.svs', '.SVS'] 
    82     ## Flag to bypass extension check 
     85    # Flag to bypass extension check 
    8386    allow_all = True 
    8487 
     
    220223                self.parent_class = tagname_original 
    221224                if tagname == 'SASdata': 
    222                     self._initialize_new_data_set() 
    223                 ## Recursion step to access data within the group 
     225                    self._initialize_new_data_set(node) 
     226                    if isinstance(self.current_dataset, plottable_2D): 
     227                        x_bins = attr.get("x_bins", "") 
     228                        y_bins = attr.get("y_bins", "") 
     229                        if x_bins is not "" and y_bins is not "": 
     230                            self.current_dataset.shape = (x_bins, y_bins) 
     231                        else: 
     232                            self.current_dataset.shape = () 
     233                # Recursion step to access data within the group 
    224234                self._parse_entry(node, True) 
    225235                if tagname == "SASsample": 
     
    234244                self.add_intermediate() 
    235245            else: 
    236                 data_point, unit = self._get_node_value(node, tagname) 
    237  
    238                 ## If this is a dataset, store the data appropriately 
     246                if isinstance(self.current_dataset, plottable_2D): 
     247                    data_point = node.text 
     248                    unit = attr.get('unit', '') 
     249                else: 
     250                    data_point, unit = self._get_node_value(node, tagname) 
     251 
     252                # If this is a dataset, store the data appropriately 
    239253                if tagname == 'Run': 
    240254                    self.current_datainfo.run_name[data_point] = name 
     
    245259                    self.current_datainfo.notes.append(data_point) 
    246260 
    247                 ## I and Q Data 
    248                 elif tagname == 'I': 
    249                     self.current_dataset.yaxis("Intensity", unit) 
     261                # I and Q - 1D data 
     262                elif tagname == 'I' and isinstance(self.current_dataset, plottable_1D): 
     263                    unit_list = unit.split("|") 
     264                    if len(unit_list) > 1: 
     265                        self.current_dataset.yaxis(unit_list[0].strip(), 
     266                                                   unit_list[1].strip()) 
     267                    else: 
     268                        self.current_dataset.yaxis("Intensity", unit) 
    250269                    self.current_dataset.y = np.append(self.current_dataset.y, data_point) 
    251                 elif tagname == 'Idev': 
     270                elif tagname == 'Idev' and isinstance(self.current_dataset, plottable_1D): 
    252271                    self.current_dataset.dy = np.append(self.current_dataset.dy, data_point) 
    253272                elif tagname == 'Q': 
    254                     self.current_dataset.xaxis("Q", unit) 
     273                    unit_list = unit.split("|") 
     274                    if len(unit_list) > 1: 
     275                        self.current_dataset.xaxis(unit_list[0].strip(), 
     276                                                   unit_list[1].strip()) 
     277                    else: 
     278                        self.current_dataset.xaxis("Q", unit) 
    255279                    self.current_dataset.x = np.append(self.current_dataset.x, data_point) 
    256280                elif tagname == 'Qdev': 
     
    264288                elif tagname == 'Shadowfactor': 
    265289                    pass 
    266  
    267                 ## Sample Information 
     290                elif tagname == 'Sesans': 
     291                    self.current_datainfo.isSesans = bool(data_point) 
     292                elif tagname == 'zacceptance': 
     293                    self.current_datainfo.sample.zacceptance = (data_point, unit) 
     294 
     295                # I and Qx, Qy - 2D data 
     296                elif tagname == 'I' and isinstance(self.current_dataset, plottable_2D): 
     297                    self.current_dataset.yaxis("Intensity", unit) 
     298                    self.current_dataset.data = np.fromstring(data_point, dtype=float, sep=",") 
     299                elif tagname == 'Idev' and isinstance(self.current_dataset, plottable_2D): 
     300                    self.current_dataset.err_data = np.fromstring(data_point, dtype=float, sep=",") 
     301                elif tagname == 'Qx': 
     302                    self.current_dataset.xaxis("Qx", unit) 
     303                    self.current_dataset.qx_data = np.fromstring(data_point, dtype=float, sep=",") 
     304                elif tagname == 'Qy': 
     305                    self.current_dataset.yaxis("Qy", unit) 
     306                    self.current_dataset.qy_data = np.fromstring(data_point, dtype=float, sep=",") 
     307                elif tagname == 'Qxdev': 
     308                    self.current_dataset.xaxis("Qxdev", unit) 
     309                    self.current_dataset.dqx_data = np.fromstring(data_point, dtype=float, sep=",") 
     310                elif tagname == 'Qydev': 
     311                    self.current_dataset.yaxis("Qydev", unit) 
     312                    self.current_dataset.dqy_data = np.fromstring(data_point, dtype=float, sep=",") 
     313                elif tagname == 'Mask': 
     314                    inter = [item == "1" for item in data_point.split(",")] 
     315                    self.current_dataset.mask = np.asarray(inter, dtype=bool) 
     316 
     317                # Sample Information 
    268318                elif tagname == 'ID' and self.parent_class == 'SASsample': 
    269319                    self.current_datainfo.sample.ID = data_point 
     
    299349                    self.current_datainfo.sample.orientation_unit = unit 
    300350 
    301                 ## Instrumental Information 
     351                # Instrumental Information 
    302352                elif tagname == 'name' and self.parent_class == 'SASinstrument': 
    303353                    self.current_datainfo.instrument = data_point 
    304                 ## Detector Information 
     354                # Detector Information 
    305355                elif tagname == 'name' and self.parent_class == 'SASdetector': 
    306356                    self.detector.name = data_point 
     
    347397                    self.detector.orientation.z = data_point 
    348398                    self.detector.orientation_unit = unit 
    349                 ## Collimation and Aperture 
     399                # Collimation and Aperture 
    350400                elif tagname == 'length' and self.parent_class == 'SAScollimation': 
    351401                    self.collimation.length = data_point 
     
    366416                    self.collimation.size_unit = unit 
    367417 
    368                 ## Process Information 
     418                # Process Information 
    369419                elif tagname == 'name' and self.parent_class == 'SASprocess': 
    370420                    self.process.name = data_point 
     
    386436                    self.process.term.append(dic) 
    387437 
    388                 ## Transmission Spectrum 
     438                # Transmission Spectrum 
    389439                elif tagname == 'T' and self.parent_class == 'Tdata': 
    390440                    self.transspectrum.transmission = np.append(self.transspectrum.transmission, data_point) 
     
    397447                    self.transspectrum.wavelength_unit = unit 
    398448 
    399                 ## Source Information 
     449                # Source Information 
    400450                elif tagname == 'wavelength' and (self.parent_class == 'SASsource' or self.parent_class == 'SASData'): 
    401451                    self.current_datainfo.source.wavelength = data_point 
     
    424474                    self.current_datainfo.source.beam_shape = data_point 
    425475 
    426                 ## Everything else goes in meta_data 
     476                # Everything else goes in meta_data 
    427477                else: 
    428478                    new_key = self._create_unique_key(self.current_datainfo.meta_data, tagname) 
     
    438488            self.add_data_set() 
    439489            empty = None 
    440             if self.output[0].dx is not None: 
    441                 self.output[0].dxl = np.empty(0) 
    442                 self.output[0].dxw = np.empty(0) 
    443             else: 
    444                 self.output[0].dx = np.empty(0) 
    445490            return self.output[0], empty 
    446491 
     
    514559        self.current_datainfo = DataInfo() 
    515560 
    516     def _initialize_new_data_set(self, parent_list=None): 
     561    def _initialize_new_data_set(self, node=None): 
    517562        """ 
    518563        A private class method to generate a new 1D data object. 
    519564        Outside methods should call add_data_set() to be sure any existing data is stored properly. 
    520565 
    521         :param parent_list: List of names of parent elements 
    522         """ 
    523  
    524         if parent_list is None: 
    525             parent_list = [] 
     566        :param node: XML node to determine if 1D or 2D data 
     567        """ 
    526568        x = np.array(0) 
    527569        y = np.array(0) 
     570        for child in node: 
     571            if child.tag.replace(self.base_ns, "") == "Idata": 
     572                for i_child in child: 
     573                    if i_child.tag.replace(self.base_ns, "") == "Qx": 
     574                        self.current_dataset = plottable_2D() 
     575                        return 
    528576        self.current_dataset = plottable_1D(x, y) 
    529577 
     
    560608        """ 
    561609 
    562         ## Append errors to dataset and reset class errors 
     610        # Append errors to dataset and reset class errors 
    563611        self.current_datainfo.errors = set() 
    564612        for error in self.errors: 
     
    566614        self.errors.clear() 
    567615 
    568         ## Combine all plottables with datainfo and append each to output 
    569         ## Type cast data arrays to float64 and find min/max as appropriate 
     616        # Combine all plottables with datainfo and append each to output 
     617        # Type cast data arrays to float64 and find min/max as appropriate 
    570618        for dataset in self.data: 
    571             if dataset.x is not None: 
    572                 dataset.x = np.delete(dataset.x, [0]) 
    573                 dataset.x = dataset.x.astype(np.float64) 
    574                 dataset.xmin = np.min(dataset.x) 
    575                 dataset.xmax = np.max(dataset.x) 
    576             if dataset.y is not None: 
    577                 dataset.y = np.delete(dataset.y, [0]) 
    578                 dataset.y = dataset.y.astype(np.float64) 
    579                 dataset.ymin = np.min(dataset.y) 
    580                 dataset.ymax = np.max(dataset.y) 
    581             if dataset.dx is not None: 
    582                 dataset.dx = np.delete(dataset.dx, [0]) 
    583                 dataset.dx = dataset.dx.astype(np.float64) 
    584             if dataset.dxl is not None: 
    585                 dataset.dxl = np.delete(dataset.dxl, [0]) 
    586                 dataset.dxl = dataset.dxl.astype(np.float64) 
    587             if dataset.dxw is not None: 
    588                 dataset.dxw = np.delete(dataset.dxw, [0]) 
    589                 dataset.dxw = dataset.dxw.astype(np.float64) 
    590             if dataset.dy is not None: 
    591                 dataset.dy = np.delete(dataset.dy, [0]) 
    592                 dataset.dy = dataset.dy.astype(np.float64) 
    593             np.trim_zeros(dataset.x) 
    594             np.trim_zeros(dataset.y) 
    595             np.trim_zeros(dataset.dy) 
     619            if isinstance(dataset, plottable_1D): 
     620                if dataset.x is not None: 
     621                    dataset.x = np.delete(dataset.x, [0]) 
     622                    dataset.x = dataset.x.astype(np.float64) 
     623                    dataset.xmin = np.min(dataset.x) 
     624                    dataset.xmax = np.max(dataset.x) 
     625                if dataset.y is not None: 
     626                    dataset.y = np.delete(dataset.y, [0]) 
     627                    dataset.y = dataset.y.astype(np.float64) 
     628                    dataset.ymin = np.min(dataset.y) 
     629                    dataset.ymax = np.max(dataset.y) 
     630                if dataset.dx is not None: 
     631                    dataset.dx = np.delete(dataset.dx, [0]) 
     632                    dataset.dx = dataset.dx.astype(np.float64) 
     633                if dataset.dxl is not None: 
     634                    dataset.dxl = np.delete(dataset.dxl, [0]) 
     635                    dataset.dxl = dataset.dxl.astype(np.float64) 
     636                if dataset.dxw is not None: 
     637                    dataset.dxw = np.delete(dataset.dxw, [0]) 
     638                    dataset.dxw = dataset.dxw.astype(np.float64) 
     639                if dataset.dy is not None: 
     640                    dataset.dy = np.delete(dataset.dy, [0]) 
     641                    dataset.dy = dataset.dy.astype(np.float64) 
     642                np.trim_zeros(dataset.x) 
     643                np.trim_zeros(dataset.y) 
     644                np.trim_zeros(dataset.dy) 
     645            elif isinstance(dataset, plottable_2D): 
     646                dataset.data = dataset.data.astype(np.float64) 
     647                dataset.qx_data = dataset.qx_data.astype(np.float64) 
     648                dataset.xmin = np.min(dataset.qx_data) 
     649                dataset.xmax = np.max(dataset.qx_data) 
     650                dataset.qy_data = dataset.qy_data.astype(np.float64) 
     651                dataset.ymin = np.min(dataset.qy_data) 
     652                dataset.ymax = np.max(dataset.qy_data) 
     653                dataset.q_data = np.sqrt(dataset.qx_data * dataset.qx_data 
     654                                         + dataset.qy_data * dataset.qy_data) 
     655                if dataset.err_data is not None: 
     656                    dataset.err_data = dataset.err_data.astype(np.float64) 
     657                if dataset.dqx_data is not None: 
     658                    dataset.dqx_data = dataset.dqx_data.astype(np.float64) 
     659                if dataset.dqy_data is not None: 
     660                    dataset.dqy_data = dataset.dqy_data.astype(np.float64) 
     661                if dataset.mask is not None: 
     662                    dataset.mask = dataset.mask.astype(dtype=bool) 
     663 
     664                if len(dataset.shape) == 2: 
     665                    n_rows, n_cols = dataset.shape 
     666                    dataset.y_bins = dataset.qy_data[0::int(n_cols)] 
     667                    dataset.x_bins = dataset.qx_data[:int(n_cols)] 
     668                    dataset.data = dataset.data.flatten() 
     669                else: 
     670                    dataset.y_bins = [] 
     671                    dataset.x_bins = [] 
     672                    dataset.data = dataset.data.flatten() 
     673 
    596674            final_dataset = combine_data(dataset, self.current_datainfo) 
    597675            self.output.append(final_dataset) 
     
    693771                        and local_unit.lower() != "none": 
    694772                    if HAS_CONVERTER == True: 
    695                         ## Check local units - bad units raise KeyError 
     773                        # Check local units - bad units raise KeyError 
    696774                        data_conv_q = Converter(local_unit) 
    697775                        value_unit = default_unit 
     
    740818        A method to check all resolution data sets are the same size as I and Q 
    741819        """ 
    742         dql_exists = False 
    743         dqw_exists = False 
    744         dq_exists = False 
    745         di_exists = False 
    746         if self.current_dataset.dxl is not None: 
    747             dql_exists = True 
    748         if self.current_dataset.dxw is not None: 
    749             dqw_exists = True 
    750         if self.current_dataset.dx is not None: 
    751             dq_exists = True 
    752         if self.current_dataset.dy is not None: 
    753             di_exists = True 
    754         if dqw_exists and not dql_exists: 
    755             array_size = self.current_dataset.dxw.size - 1 
    756             self.current_dataset.dxl = np.append(self.current_dataset.dxl, np.zeros([array_size])) 
    757         elif dql_exists and not dqw_exists: 
    758             array_size = self.current_dataset.dxl.size - 1 
    759             self.current_dataset.dxw = np.append(self.current_dataset.dxw, np.zeros([array_size])) 
    760         elif not dql_exists and not dqw_exists and not dq_exists: 
    761             array_size = self.current_dataset.x.size - 1 
    762             self.current_dataset.dx = np.append(self.current_dataset.dx, np.zeros([array_size])) 
    763         if not di_exists: 
    764             array_size = self.current_dataset.y.size - 1 
    765             self.current_dataset.dy = np.append(self.current_dataset.dy, np.zeros([array_size])) 
    766  
     820        if isinstance(self.current_dataset, plottable_1D): 
     821            dql_exists = False 
     822            dqw_exists = False 
     823            dq_exists = False 
     824            di_exists = False 
     825            if self.current_dataset.dxl is not None: 
     826                dql_exists = True 
     827            if self.current_dataset.dxw is not None: 
     828                dqw_exists = True 
     829            if self.current_dataset.dx is not None: 
     830                dq_exists = True 
     831            if self.current_dataset.dy is not None: 
     832                di_exists = True 
     833            if dqw_exists and not dql_exists: 
     834                array_size = self.current_dataset.dxw.size - 1 
     835                self.current_dataset.dxl = np.append(self.current_dataset.dxl, 
     836                                                     np.zeros([array_size])) 
     837            elif dql_exists and not dqw_exists: 
     838                array_size = self.current_dataset.dxl.size - 1 
     839                self.current_dataset.dxw = np.append(self.current_dataset.dxw, 
     840                                                     np.zeros([array_size])) 
     841            elif not dql_exists and not dqw_exists and not dq_exists: 
     842                array_size = self.current_dataset.x.size - 1 
     843                self.current_dataset.dx = np.append(self.current_dataset.dx, 
     844                                                    np.zeros([array_size])) 
     845            if not di_exists: 
     846                array_size = self.current_dataset.y.size - 1 
     847                self.current_dataset.dy = np.append(self.current_dataset.dy, 
     848                                                    np.zeros([array_size])) 
     849        elif isinstance(self.current_dataset, plottable_2D): 
     850            dqx_exists = False 
     851            dqy_exists = False 
     852            di_exists = False 
     853            mask_exists = False 
     854            if self.current_dataset.dqx_data is not None: 
     855                dqx_exists = True 
     856            if self.current_dataset.dqy_data is not None: 
     857                dqy_exists = True 
     858            if self.current_dataset.err_data is not None: 
     859                di_exists = True 
     860            if self.current_dataset.mask is not None: 
     861                mask_exists = True 
     862            if not dqy_exists: 
     863                array_size = self.current_dataset.qy_data.size - 1 
     864                self.current_dataset.dqy_data = np.append( 
     865                    self.current_dataset.dqy_data, np.zeros([array_size])) 
     866            if not dqx_exists: 
     867                array_size = self.current_dataset.qx_data.size - 1 
     868                self.current_dataset.dqx_data = np.append( 
     869                    self.current_dataset.dqx_data, np.zeros([array_size])) 
     870            if not di_exists: 
     871                array_size = self.current_dataset.data.size - 1 
     872                self.current_dataset.err_data = np.append( 
     873                    self.current_dataset.err_data, np.zeros([array_size])) 
     874            if not mask_exists: 
     875                array_size = self.current_dataset.data.size - 1 
     876                self.current_dataset.mask = np.append( 
     877                    self.current_dataset.mask, 
     878                    np.ones([array_size] ,dtype=bool)) 
    767879 
    768880    ####### All methods below are for writing CanSAS XML files ####### 
    769  
    770881 
    771882    def write(self, filename, datainfo): 
     
    792903        :param datainfo: Data1D object 
    793904        """ 
    794         if not issubclass(datainfo.__class__, Data1D): 
    795             raise RuntimeError, "The cansas writer expects a Data1D instance" 
     905        is_2d = False 
     906        if issubclass(datainfo.__class__, Data2D): 
     907            is_2d = True 
    796908 
    797909        # Get PIs and create root element 
     
    813925        self._write_run_names(datainfo, entry_node) 
    814926        # Add Data info to SASEntry 
    815         self._write_data(datainfo, entry_node) 
     927        if is_2d: 
     928            self._write_data_2d(datainfo, entry_node) 
     929        else: 
     930            self._write_data(datainfo, entry_node) 
    816931        # Transmission Spectrum Info 
    817         self._write_trans_spectrum(datainfo, entry_node) 
     932        # TODO: fix the writer to linearize all data, including T_spectrum 
     933        # self._write_trans_spectrum(datainfo, entry_node) 
    818934        # Sample info 
    819935        self._write_sample_info(datainfo, entry_node) 
     
    9071023    def _write_data(self, datainfo, entry_node): 
    9081024        """ 
    909         Writes the I and Q data to the XML file 
     1025        Writes 1D I and Q data to the XML file 
    9101026 
    9111027        :param datainfo: The Data1D object the information is coming from 
     
    9191035            node.append(point) 
    9201036            self.write_node(point, "Q", datainfo.x[i], 
    921                             {'unit': datainfo.x_unit}) 
     1037                            {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
    9221038            if len(datainfo.y) >= i: 
    9231039                self.write_node(point, "I", datainfo.y[i], 
    924                                 {'unit': datainfo.y_unit}) 
     1040                                {'unit': datainfo._yaxis + " | " + datainfo._yunit}) 
    9251041            if datainfo.dy is not None and len(datainfo.dy) > i: 
    9261042                self.write_node(point, "Idev", datainfo.dy[i], 
    927                                 {'unit': datainfo.y_unit}) 
     1043                                {'unit': datainfo._yaxis + " | " + datainfo._yunit}) 
    9281044            if datainfo.dx is not None and len(datainfo.dx) > i: 
    9291045                self.write_node(point, "Qdev", datainfo.dx[i], 
    930                                 {'unit': datainfo.x_unit}) 
     1046                                {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
    9311047            if datainfo.dxw is not None and len(datainfo.dxw) > i: 
    9321048                self.write_node(point, "dQw", datainfo.dxw[i], 
    933                                 {'unit': datainfo.x_unit}) 
     1049                                {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
    9341050            if datainfo.dxl is not None and len(datainfo.dxl) > i: 
    9351051                self.write_node(point, "dQl", datainfo.dxl[i], 
    936                                 {'unit': datainfo.x_unit}) 
     1052                                {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
     1053        if datainfo.isSesans: 
     1054            sesans = self.create_element("Sesans") 
     1055            sesans.text = str(datainfo.isSesans) 
     1056            node.append(sesans) 
     1057            self.write_node(node, "zacceptance", datainfo.sample.zacceptance[0], 
     1058                             {'unit': datainfo.sample.zacceptance[1]}) 
     1059 
     1060 
     1061    def _write_data_2d(self, datainfo, entry_node): 
     1062        """ 
     1063        Writes 2D data to the XML file 
     1064 
     1065        :param datainfo: The Data2D object the information is coming from 
     1066        :param entry_node: lxml node ElementTree object to be appended to 
     1067        """ 
     1068        attr = {} 
     1069        if datainfo.data.shape: 
     1070            attr["x_bins"] = str(len(datainfo.x_bins)) 
     1071            attr["y_bins"] = str(len(datainfo.y_bins)) 
     1072        node = self.create_element("SASdata", attr) 
     1073        self.append(node, entry_node) 
     1074 
     1075        point = self.create_element("Idata") 
     1076        node.append(point) 
     1077        qx = ','.join([str(datainfo.qx_data[i]) for i in xrange(len(datainfo.qx_data))]) 
     1078        qy = ','.join([str(datainfo.qy_data[i]) for i in xrange(len(datainfo.qy_data))]) 
     1079        intensity = ','.join([str(datainfo.data[i]) for i in xrange(len(datainfo.data))]) 
     1080 
     1081        self.write_node(point, "Qx", qx, 
     1082                        {'unit': datainfo._xunit}) 
     1083        self.write_node(point, "Qy", qy, 
     1084                        {'unit': datainfo._yunit}) 
     1085        self.write_node(point, "I", intensity, 
     1086                        {'unit': datainfo._zunit}) 
     1087        if datainfo.err_data is not None: 
     1088            err = ','.join([str(datainfo.err_data[i]) for i in 
     1089                            xrange(len(datainfo.err_data))]) 
     1090            self.write_node(point, "Idev", err, 
     1091                            {'unit': datainfo._zunit}) 
     1092        if datainfo.dqy_data is not None: 
     1093            dqy = ','.join([str(datainfo.dqy_data[i]) for i in 
     1094                            xrange(len(datainfo.dqy_data))]) 
     1095            self.write_node(point, "Qydev", dqy, 
     1096                            {'unit': datainfo._yunit}) 
     1097        if datainfo.dqx_data is not None: 
     1098            dqx = ','.join([str(datainfo.dqx_data[i]) for i in 
     1099                            xrange(len(datainfo.dqx_data))]) 
     1100            self.write_node(point, "Qxdev", dqx, 
     1101                            {'unit': datainfo._xunit}) 
     1102        if datainfo.mask is not None: 
     1103            mask = ','.join( 
     1104                ["1" if datainfo.mask[i] else "0" 
     1105                 for i in xrange(len(datainfo.mask))]) 
     1106            self.write_node(point, "Mask", mask) 
    9371107 
    9381108    def _write_trans_spectrum(self, datainfo, entry_node): 
  • src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py

    rbbd0f37 rc94280c  
    99import sys 
    1010 
    11 from sas.sascalc.dataloader.data_info import plottable_1D, plottable_2D, Data1D, Data2D, DataInfo, Process, Aperture 
    12 from sas.sascalc.dataloader.data_info import Collimation, TransmissionSpectrum, Detector 
     11from sas.sascalc.dataloader.data_info import plottable_1D, plottable_2D,\ 
     12    Data1D, Data2D, DataInfo, Process, Aperture, Collimation, \ 
     13    TransmissionSpectrum, Detector 
    1314from sas.sascalc.dataloader.data_info import combine_data_info_with_plottable 
    14  
    1515 
    1616 
    1717class Reader(): 
    1818    """ 
    19     A class for reading in CanSAS v2.0 data files. The existing iteration opens Mantid generated HDF5 formatted files 
    20     with file extension .h5/.H5. Any number of data sets may be present within the file and any dimensionality of data 
    21     may be used. Currently 1D and 2D SAS data sets are supported, but future implementations will include 1D and 2D 
    22     SESANS data. 
    23  
    24     Any number of SASdata sets may be present in a SASentry and the data within can be either 1D I(Q) or 2D I(Qx, Qy). 
     19    A class for reading in CanSAS v2.0 data files. The existing iteration opens 
     20    Mantid generated HDF5 formatted files with file extension .h5/.H5. Any 
     21    number of data sets may be present within the file and any dimensionality 
     22    of data may be used. Currently 1D and 2D SAS data sets are supported, but 
     23    future implementations will include 1D and 2D SESANS data. 
     24 
     25    Any number of SASdata sets may be present in a SASentry and the data within 
     26    can be either 1D I(Q) or 2D I(Qx, Qy). 
    2527 
    2628    Also supports reading NXcanSAS formatted HDF5 files 
     
    3032    """ 
    3133 
    32     ## CanSAS version 
     34    # CanSAS version 
    3335    cansas_version = 2.0 
    34     ## Logged warnings or messages 
     36    # Logged warnings or messages 
    3537    logging = None 
    36     ## List of errors for the current data set 
     38    # List of errors for the current data set 
    3739    errors = None 
    38     ## Raw file contents to be processed 
     40    # Raw file contents to be processed 
    3941    raw_data = None 
    40     ## Data info currently being read in 
     42    # Data info currently being read in 
    4143    current_datainfo = None 
    42     ## SASdata set currently being read in 
     44    # SASdata set currently being read in 
    4345    current_dataset = None 
    44     ## List of plottable1D objects that should be linked to the current_datainfo 
     46    # List of plottable1D objects that should be linked to the current_datainfo 
    4547    data1d = None 
    46     ## List of plottable2D objects that should be linked to the current_datainfo 
     48    # List of plottable2D objects that should be linked to the current_datainfo 
    4749    data2d = None 
    48     ## Data type name 
     50    # Data type name 
    4951    type_name = "CanSAS 2.0" 
    50     ## Wildcards 
     52    # Wildcards 
    5153    type = ["CanSAS 2.0 HDF5 Files (*.h5)|*.h5"] 
    52     ## List of allowed extensions 
     54    # List of allowed extensions 
    5355    ext = ['.h5', '.H5'] 
    54     ## Flag to bypass extension check 
    55     allow_all = False 
    56     ## List of files to return 
     56    # Flag to bypass extension check 
     57    allow_all = True 
     58    # List of files to return 
    5759    output = None 
    5860 
     
    6466        :return: List of Data1D/2D objects and/or a list of errors. 
    6567        """ 
    66         ## Reinitialize the class when loading a new data file to reset all class variables 
     68        # Reinitialize when loading a new data file to reset all class variables 
    6769        self.reset_class_variables() 
    68         ## Check that the file exists 
     70        # Check that the file exists 
    6971        if os.path.isfile(filename): 
    7072            basename = os.path.basename(filename) 
     
    7274            # If the file type is not allowed, return empty list 
    7375            if extension in self.ext or self.allow_all: 
    74                 ## Load the data file 
     76                # Load the data file 
    7577                self.raw_data = h5py.File(filename, 'r') 
    76                 ## Read in all child elements of top level SASroot 
     78                # Read in all child elements of top level SASroot 
    7779                self.read_children(self.raw_data, []) 
    78                 ## Add the last data set to the list of outputs 
     80                # Add the last data set to the list of outputs 
    7981                self.add_data_set() 
    80                 ## Close the data file 
     82                # Close the data file 
    8183                self.raw_data.close() 
    82         ## Return data set(s) 
     84        # Return data set(s) 
    8385        return self.output 
    8486 
     
    110112        """ 
    111113 
    112         ## Loop through each element of the parent and process accordingly 
     114        # Loop through each element of the parent and process accordingly 
    113115        for key in data.keys(): 
    114             ## Get all information for the current key 
     116            # Get all information for the current key 
    115117            value = data.get(key) 
    116118            if value.attrs.get(u'canSAS_class') is not None: 
     
    126128                self.parent_class = class_name 
    127129                parent_list.append(key) 
    128                 ## If this is a new sasentry, store the current data sets and create a fresh Data1D/2D object 
     130                # If a new sasentry, store the current data sets and create 
     131                # a fresh Data1D/2D object 
    129132                if class_prog.match(u'SASentry'): 
    130133                    self.add_data_set(key) 
    131134                elif class_prog.match(u'SASdata'): 
    132135                    self._initialize_new_data_set(parent_list) 
    133                 ## Recursion step to access data within the group 
     136                # Recursion step to access data within the group 
    134137                self.read_children(value, parent_list) 
    135138                self.add_intermediate() 
     
    137140 
    138141            elif isinstance(value, h5py.Dataset): 
    139                 ## If this is a dataset, store the data appropriately 
     142                # If this is a dataset, store the data appropriately 
    140143                data_set = data[key][:] 
    141144                unit = self._get_unit(value) 
    142145 
    143                 ## I and Q Data 
     146                # I and Q Data 
    144147                if key == u'I': 
    145                     if type(self.current_dataset) is plottable_2D: 
     148                    if isinstance(self.current_dataset, plottable_2D): 
    146149                        self.current_dataset.data = data_set 
    147150                        self.current_dataset.zaxis("Intensity", unit) 
     
    151154                    continue 
    152155                elif key == u'Idev': 
    153                     if type(self.current_dataset) is plottable_2D: 
     156                    if isinstance(self.current_dataset, plottable_2D): 
    154157                        self.current_dataset.err_data = data_set.flatten() 
    155158                    else: 
     
    158161                elif key == u'Q': 
    159162                    self.current_dataset.xaxis("Q", unit) 
    160                     if type(self.current_dataset) is plottable_2D: 
     163                    if isinstance(self.current_dataset, plottable_2D): 
    161164                        self.current_dataset.q = data_set.flatten() 
    162165                    else: 
     
    166169                    self.current_dataset.dx = data_set.flatten() 
    167170                    continue 
     171                elif key == u'dQw': 
     172                    self.current_dataset.dxw = data_set.flatten() 
     173                    continue 
     174                elif key == u'dQl': 
     175                    self.current_dataset.dxl = data_set.flatten() 
     176                    continue 
    168177                elif key == u'Qy': 
    169178                    self.current_dataset.yaxis("Q_y", unit) 
     
    183192                    self.current_dataset.mask = data_set.flatten() 
    184193                    continue 
     194                # Transmission Spectrum 
     195                elif (key == u'T' 
     196                      and self.parent_class == u'SAStransmission_spectrum'): 
     197                    self.trans_spectrum.transmission = data_set.flatten() 
     198                    continue 
     199                elif (key == u'Tdev' 
     200                      and self.parent_class == u'SAStransmission_spectrum'): 
     201                    self.trans_spectrum.transmission_deviation = \ 
     202                        data_set.flatten() 
     203                    continue 
     204                elif (key == u'lambda' 
     205                      and self.parent_class == u'SAStransmission_spectrum'): 
     206                    self.trans_spectrum.wavelength = data_set.flatten() 
     207                    continue 
    185208 
    186209                for data_point in data_set: 
    187                     ## Top Level Meta Data 
     210                    # Top Level Meta Data 
    188211                    if key == u'definition': 
    189212                        self.current_datainfo.meta_data['reader'] = data_point 
     
    201224                        self.current_datainfo.notes.append(data_point) 
    202225 
    203                     ## Sample Information 
    204                     elif key == u'Title' and self.parent_class == u'SASsample': # CanSAS 2.0 format 
     226                    # Sample Information 
     227                    # CanSAS 2.0 format 
     228                    elif key == u'Title' and self.parent_class == u'SASsample': 
    205229                        self.current_datainfo.sample.name = data_point 
    206                     elif key == u'ID' and self.parent_class == u'SASsample': # NXcanSAS format 
     230                    # NXcanSAS format 
     231                    elif key == u'name' and self.parent_class == u'SASsample': 
    207232                        self.current_datainfo.sample.name = data_point 
    208                     elif key == u'thickness' and self.parent_class == u'SASsample': 
     233                    # NXcanSAS format 
     234                    elif key == u'ID' and self.parent_class == u'SASsample': 
     235                        self.current_datainfo.sample.name = data_point 
     236                    elif (key == u'thickness' 
     237                          and self.parent_class == u'SASsample'): 
    209238                        self.current_datainfo.sample.thickness = data_point 
    210                     elif key == u'temperature' and self.parent_class == u'SASsample': 
     239                    elif (key == u'temperature' 
     240                          and self.parent_class == u'SASsample'): 
    211241                        self.current_datainfo.sample.temperature = data_point 
    212                     elif key == u'transmission' and self.parent_class == u'SASsample': 
     242                    elif (key == u'transmission' 
     243                          and self.parent_class == u'SASsample'): 
    213244                        self.current_datainfo.sample.transmission = data_point 
    214                     elif key == u'x_position' and self.parent_class == u'SASsample': 
     245                    elif (key == u'x_position' 
     246                          and self.parent_class == u'SASsample'): 
    215247                        self.current_datainfo.sample.position.x = data_point 
    216                     elif key == u'y_position' and self.parent_class == u'SASsample': 
     248                    elif (key == u'y_position' 
     249                          and self.parent_class == u'SASsample'): 
    217250                        self.current_datainfo.sample.position.y = data_point 
    218                     elif key == u'polar_angle' and self.parent_class == u'SASsample': 
     251                    elif key == u'pitch' and self.parent_class == u'SASsample': 
    219252                        self.current_datainfo.sample.orientation.x = data_point 
    220                     elif key == u'azimuthal_angle' and self.parent_class == u'SASsample': 
     253                    elif key == u'yaw' and self.parent_class == u'SASsample': 
     254                        self.current_datainfo.sample.orientation.y = data_point 
     255                    elif key == u'roll' and self.parent_class == u'SASsample': 
    221256                        self.current_datainfo.sample.orientation.z = data_point 
    222                     elif key == u'details' and self.parent_class == u'SASsample': 
     257                    elif (key == u'details' 
     258                          and self.parent_class == u'SASsample'): 
    223259                        self.current_datainfo.sample.details.append(data_point) 
    224260 
    225                     ## Instrumental Information 
    226                     elif key == u'name' and self.parent_class == u'SASinstrument': 
     261                    # Instrumental Information 
     262                    elif (key == u'name' 
     263                          and self.parent_class == u'SASinstrument'): 
    227264                        self.current_datainfo.instrument = data_point 
    228265                    elif key == u'name' and self.parent_class == u'SASdetector': 
     
    231268                        self.detector.distance = float(data_point) 
    232269                        self.detector.distance_unit = unit 
    233                     elif key == u'slit_length' and self.parent_class == u'SASdetector': 
     270                    elif (key == u'slit_length' 
     271                          and self.parent_class == u'SASdetector'): 
    234272                        self.detector.slit_length = float(data_point) 
    235273                        self.detector.slit_length_unit = unit 
    236                     elif key == u'x_position' and self.parent_class == u'SASdetector': 
     274                    elif (key == u'x_position' 
     275                          and self.parent_class == u'SASdetector'): 
    237276                        self.detector.offset.x = float(data_point) 
    238277                        self.detector.offset_unit = unit 
    239                     elif key == u'y_position' and self.parent_class == u'SASdetector': 
     278                    elif (key == u'y_position' 
     279                          and self.parent_class == u'SASdetector'): 
    240280                        self.detector.offset.y = float(data_point) 
    241281                        self.detector.offset_unit = unit 
    242                     elif key == u'polar_angle' and self.parent_class == u'SASdetector': 
     282                    elif (key == u'pitch' 
     283                          and self.parent_class == u'SASdetector'): 
    243284                        self.detector.orientation.x = float(data_point) 
    244285                        self.detector.orientation_unit = unit 
    245                     elif key == u'azimuthal_angle' and self.parent_class == u'SASdetector': 
     286                    elif key == u'roll' and self.parent_class == u'SASdetector': 
    246287                        self.detector.orientation.z = float(data_point) 
    247288                        self.detector.orientation_unit = unit 
    248                     elif key == u'beam_center_x' and self.parent_class == u'SASdetector': 
     289                    elif key == u'yaw' and self.parent_class == u'SASdetector': 
     290                        self.detector.orientation.y = float(data_point) 
     291                        self.detector.orientation_unit = unit 
     292                    elif (key == u'beam_center_x' 
     293                          and self.parent_class == u'SASdetector'): 
    249294                        self.detector.beam_center.x = float(data_point) 
    250295                        self.detector.beam_center_unit = unit 
    251                     elif key == u'beam_center_y' and self.parent_class == u'SASdetector': 
     296                    elif (key == u'beam_center_y' 
     297                          and self.parent_class == u'SASdetector'): 
    252298                        self.detector.beam_center.y = float(data_point) 
    253299                        self.detector.beam_center_unit = unit 
    254                     elif key == u'x_pixel_size' and self.parent_class == u'SASdetector': 
     300                    elif (key == u'x_pixel_size' 
     301                          and self.parent_class == u'SASdetector'): 
    255302                        self.detector.pixel_size.x = float(data_point) 
    256303                        self.detector.pixel_size_unit = unit 
    257                     elif key == u'y_pixel_size' and self.parent_class == u'SASdetector': 
     304                    elif (key == u'y_pixel_size' 
     305                          and self.parent_class == u'SASdetector'): 
    258306                        self.detector.pixel_size.y = float(data_point) 
    259307                        self.detector.pixel_size_unit = unit 
    260                     elif key == u'SSD' and self.parent_class == u'SAScollimation': 
     308                    elif (key == u'distance' 
     309                          and self.parent_class == u'SAScollimation'): 
    261310                        self.collimation.length = data_point 
    262311                        self.collimation.length_unit = unit 
    263                     elif key == u'name' and self.parent_class == u'SAScollimation': 
     312                    elif (key == u'name' 
     313                          and self.parent_class == u'SAScollimation'): 
    264314                        self.collimation.name = data_point 
    265  
    266                     ## Process Information 
    267                     elif key == u'name' and self.parent_class == u'SASprocess': 
     315                    elif (key == u'shape' 
     316                          and self.parent_class == u'SASaperture'): 
     317                        self.aperture.shape = data_point 
     318                    elif (key == u'x_gap' 
     319                          and self.parent_class == u'SASaperture'): 
     320                        self.aperture.size.x = data_point 
     321                    elif (key == u'y_gap' 
     322                          and self.parent_class == u'SASaperture'): 
     323                        self.aperture.size.y = data_point 
     324 
     325                    # Process Information 
     326                    elif (key == u'Title' 
     327                          and self.parent_class == u'SASprocess'): # CanSAS 2.0 
    268328                        self.process.name = data_point 
    269                     elif key == u'Title' and self.parent_class == u'SASprocess': # CanSAS 2.0 format 
     329                    elif (key == u'name' 
     330                          and self.parent_class == u'SASprocess'): # NXcanSAS 
    270331                        self.process.name = data_point 
    271                     elif key == u'name' and self.parent_class == u'SASprocess': # NXcanSAS format 
    272                         self.process.name = data_point 
    273                     elif key == u'description' and self.parent_class == u'SASprocess': 
     332                    elif (key == u'description' 
     333                          and self.parent_class == u'SASprocess'): 
    274334                        self.process.description = data_point 
    275335                    elif key == u'date' and self.parent_class == u'SASprocess': 
    276336                        self.process.date = data_point 
     337                    elif key == u'term' and self.parent_class == u'SASprocess': 
     338                        self.process.term = data_point 
    277339                    elif self.parent_class == u'SASprocess': 
    278340                        self.process.notes.append(data_point) 
    279341 
    280                     ## Transmission Spectrum 
    281                     elif key == u'T' and self.parent_class == u'SAStransmission_spectrum': 
    282                         self.trans_spectrum.transmission.append(data_point) 
    283                     elif key == u'Tdev' and self.parent_class == u'SAStransmission_spectrum': 
    284                         self.trans_spectrum.transmission_deviation.append(data_point) 
    285                     elif key == u'lambda' and self.parent_class == u'SAStransmission_spectrum': 
    286                         self.trans_spectrum.wavelength.append(data_point) 
    287  
    288                     ## Source 
    289                     elif key == u'wavelength' and self.parent_class == u'SASdata': 
     342                    # Source 
     343                    elif (key == u'wavelength' 
     344                          and self.parent_class == u'SASdata'): 
    290345                        self.current_datainfo.source.wavelength = data_point 
    291346                        self.current_datainfo.source.wavelength_unit = unit 
    292                     elif key == u'incident_wavelength' and self.parent_class == u'SASsource': 
     347                    elif (key == u'incident_wavelength' 
     348                          and self.parent_class == 'SASsource'): 
    293349                        self.current_datainfo.source.wavelength = data_point 
    294350                        self.current_datainfo.source.wavelength_unit = unit 
    295                     elif key == u'wavelength_max' and self.parent_class == u'SASsource': 
     351                    elif (key == u'wavelength_max' 
     352                          and self.parent_class == u'SASsource'): 
    296353                        self.current_datainfo.source.wavelength_max = data_point 
    297354                        self.current_datainfo.source.wavelength_max_unit = unit 
    298                     elif key == u'wavelength_min' and self.parent_class == u'SASsource': 
     355                    elif (key == u'wavelength_min' 
     356                          and self.parent_class == u'SASsource'): 
    299357                        self.current_datainfo.source.wavelength_min = data_point 
    300358                        self.current_datainfo.source.wavelength_min_unit = unit 
    301                     elif key == u'wavelength_spread' and self.parent_class == u'SASsource': 
    302                         self.current_datainfo.source.wavelength_spread = data_point 
    303                         self.current_datainfo.source.wavelength_spread_unit = unit 
    304                     elif key == u'beam_size_x' and self.parent_class == u'SASsource': 
     359                    elif (key == u'incident_wavelength_spread' 
     360                          and self.parent_class == u'SASsource'): 
     361                        self.current_datainfo.source.wavelength_spread = \ 
     362                            data_point 
     363                        self.current_datainfo.source.wavelength_spread_unit = \ 
     364                            unit 
     365                    elif (key == u'beam_size_x' 
     366                          and self.parent_class == u'SASsource'): 
    305367                        self.current_datainfo.source.beam_size.x = data_point 
    306368                        self.current_datainfo.source.beam_size_unit = unit 
    307                     elif key == u'beam_size_y' and self.parent_class == u'SASsource': 
     369                    elif (key == u'beam_size_y' 
     370                          and self.parent_class == u'SASsource'): 
    308371                        self.current_datainfo.source.beam_size.y = data_point 
    309372                        self.current_datainfo.source.beam_size_unit = unit 
    310                     elif key == u'beam_shape' and self.parent_class == u'SASsource': 
     373                    elif (key == u'beam_shape' 
     374                          and self.parent_class == u'SASsource'): 
    311375                        self.current_datainfo.source.beam_shape = data_point 
    312                     elif key == u'radiation' and self.parent_class == u'SASsource': 
     376                    elif (key == u'radiation' 
     377                          and self.parent_class == u'SASsource'): 
    313378                        self.current_datainfo.source.radiation = data_point 
    314                     elif key == u'transmission' and self.parent_class == u'SASdata': 
     379                    elif (key == u'transmission' 
     380                          and self.parent_class == u'SASdata'): 
    315381                        self.current_datainfo.sample.transmission = data_point 
    316382 
    317                     ## Everything else goes in meta_data 
     383                    # Everything else goes in meta_data 
    318384                    else: 
    319                         new_key = self._create_unique_key(self.current_datainfo.meta_data, key) 
     385                        new_key = self._create_unique_key( 
     386                            self.current_datainfo.meta_data, key) 
    320387                        self.current_datainfo.meta_data[new_key] = data_point 
    321388 
    322389            else: 
    323                 ## I don't know if this reachable code 
     390                # I don't know if this reachable code 
    324391                self.errors.add("ShouldNeverHappenException") 
    325392 
    326393    def add_intermediate(self): 
    327394        """ 
    328         This method stores any intermediate objects within the final data set after fully reading the set. 
    329  
    330         :param parent: The NXclass name for the h5py Group object that just finished being processed 
     395        This method stores any intermediate objects within the final data set 
     396        after fully reading the set. 
     397 
     398        :param parent: The NXclass name for the h5py Group object that just 
     399                       finished being processed 
    331400        """ 
    332401 
     
    347416            self.aperture = Aperture() 
    348417        elif self.parent_class == u'SASdata': 
    349             if type(self.current_dataset) is plottable_2D: 
     418            if isinstance(self.current_dataset, plottable_2D): 
    350419                self.data2d.append(self.current_dataset) 
    351             elif type(self.current_dataset) is plottable_1D: 
     420            elif isinstance(self.current_dataset, plottable_1D): 
    352421                self.data1d.append(self.current_dataset) 
    353422 
    354423    def final_data_cleanup(self): 
    355424        """ 
    356         Does some final cleanup and formatting on self.current_datainfo and all data1D and data2D objects and then 
    357         combines the data and info into Data1D and Data2D objects 
    358         """ 
    359  
    360         ## Type cast data arrays to float64 
     425        Does some final cleanup and formatting on self.current_datainfo and 
     426        all data1D and data2D objects and then combines the data and info into 
     427        Data1D and Data2D objects 
     428        """ 
     429 
     430        # Type cast data arrays to float64 
    361431        if len(self.current_datainfo.trans_spectrum) > 0: 
    362432            spectrum_list = [] 
     
    364434                spectrum.transmission = np.delete(spectrum.transmission, [0]) 
    365435                spectrum.transmission = spectrum.transmission.astype(np.float64) 
    366                 spectrum.transmission_deviation = np.delete(spectrum.transmission_deviation, [0]) 
    367                 spectrum.transmission_deviation = spectrum.transmission_deviation.astype(np.float64) 
     436                spectrum.transmission_deviation = np.delete( 
     437                    spectrum.transmission_deviation, [0]) 
     438                spectrum.transmission_deviation = \ 
     439                    spectrum.transmission_deviation.astype(np.float64) 
    368440                spectrum.wavelength = np.delete(spectrum.wavelength, [0]) 
    369441                spectrum.wavelength = spectrum.wavelength.astype(np.float64) 
     
    372444            self.current_datainfo.trans_spectrum = spectrum_list 
    373445 
    374         ## Append errors to dataset and reset class errors 
     446        # Append errors to dataset and reset class errors 
    375447        self.current_datainfo.errors = self.errors 
    376448        self.errors.clear() 
    377449 
    378         ## Combine all plottables with datainfo and append each to output 
    379         ## Type cast data arrays to float64 and find min/max as appropriate 
     450        # Combine all plottables with datainfo and append each to output 
     451        # Type cast data arrays to float64 and find min/max as appropriate 
    380452        for dataset in self.data2d: 
    381453            dataset.data = dataset.data.astype(np.float64) 
     
    397469            zeros = np.ones(dataset.data.size, dtype=bool) 
    398470            try: 
    399                 for i in range (0, dataset.mask.size - 1): 
     471                for i in range(0, dataset.mask.size - 1): 
    400472                    zeros[i] = dataset.mask[i] 
    401473            except: 
    402474                self.errors.add(sys.exc_value) 
    403475            dataset.mask = zeros 
    404             ## Calculate the actual Q matrix 
     476            # Calculate the actual Q matrix 
    405477            try: 
    406478                if dataset.q_data.size <= 1: 
    407                     dataset.q_data = np.sqrt(dataset.qx_data * dataset.qx_data + dataset.qy_data * dataset.qy_data) 
     479                    dataset.q_data = np.sqrt(dataset.qx_data 
     480                                             * dataset.qx_data 
     481                                             + dataset.qy_data 
     482                                             * dataset.qy_data) 
    408483            except: 
    409484                dataset.q_data = None 
     
    415490                dataset.data = dataset.data.flatten() 
    416491 
    417             final_dataset = combine_data_info_with_plottable(dataset, self.current_datainfo) 
     492            final_dataset = combine_data_info_with_plottable( 
     493                dataset, self.current_datainfo) 
    418494            self.output.append(final_dataset) 
    419495 
     
    435511            if dataset.dy is not None: 
    436512                dataset.dy = dataset.dy.astype(np.float64) 
    437             final_dataset = combine_data_info_with_plottable(dataset, self.current_datainfo) 
     513            final_dataset = combine_data_info_with_plottable( 
     514                dataset, self.current_datainfo) 
    438515            self.output.append(final_dataset) 
    439516 
    440517    def add_data_set(self, key=""): 
    441518        """ 
    442         Adds the current_dataset to the list of outputs after preforming final processing on the data and then calls a 
    443         private method to generate a new data set. 
     519        Adds the current_dataset to the list of outputs after preforming final 
     520        processing on the data and then calls a private method to generate a 
     521        new data set. 
    444522 
    445523        :param key: NeXus group name for current tree level 
     
    453531 
    454532 
    455     def _initialize_new_data_set(self, parent_list = None): 
    456         """ 
    457         A private class method to generate a new 1D or 2D data object based on the type of data within the set. 
    458         Outside methods should call add_data_set() to be sure any existing data is stored properly. 
     533    def _initialize_new_data_set(self, parent_list=None): 
     534        """ 
     535        A private class method to generate a new 1D or 2D data object based on 
     536        the type of data within the set. Outside methods should call 
     537        add_data_set() to be sure any existing data is stored properly. 
    459538 
    460539        :param parent_list: List of names of parent elements 
     
    473552    def _find_intermediate(self, parent_list, basename=""): 
    474553        """ 
    475         A private class used to find an entry by either using a direct key or knowing the approximate basename. 
    476  
    477         :param parent_list: List of parents to the current level in the HDF5 file 
     554        A private class used to find an entry by either using a direct key or 
     555        knowing the approximate basename. 
     556 
     557        :param parent_list: List of parents nodes in the HDF5 file 
    478558        :param basename: Approximate name of an entry to search for 
    479559        :return: 
     
    486566            top = top.get(parent) 
    487567        for key in top.keys(): 
    488             if (key_prog.match(key)): 
     568            if key_prog.match(key): 
    489569                entry = True 
    490570                break 
     
    516596        """ 
    517597        unit = value.attrs.get(u'units') 
    518         if unit == None: 
     598        if unit is None: 
    519599            unit = value.attrs.get(u'unit') 
    520         ## Convert the unit formats 
     600        # Convert the unit formats 
    521601        if unit == "1/A": 
    522602            unit = "A^{-1}" 
  • src/sas/sascalc/dataloader/readers/schema/cansas1d_invalid_v1_0.xsd

    r250fec92 raf08e55  
    2424 
    2525        <complexType name="IdataType"> 
     26                <xsd:choice> 
    2627                <sequence> 
    2728                        <element name="Q" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     
    4041                        <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax" namespace="##other" /> 
    4142                </sequence> 
     43                <sequence> 
     44                        <element name="Qx" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     45                        <element name="Qy" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     46                        <element name="I" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     47                        <element name="Idev" minOccurs="0" maxOccurs="1" type="tns:floatUnitType" default="0" /> 
     48                        <element name="Qydev" minOccurs="0" maxOccurs="1" type="tns:floatUnitType" default="0" /> 
     49                        <element name="Qxdev" minOccurs="0" maxOccurs="1" type="tns:floatUnitType" default="0" /> 
     50                        <element name="Mask" minOccurs="0" maxOccurs="1" type="string" default="0" /> 
     51                </sequence> 
     52                </xsd:choice> 
    4253        </complexType> 
    4354         
     
    5162                <attribute name="name" type="string" use="optional" default="" /> 
    5263                <attribute name="timestamp" type="dateTime" use="optional" /> 
     64                <attribute name="x_bins" type="string" use="optional" /> 
     65                <attribute name="y_bins" type="string" use="optional" /> 
    5366        </complexType> 
    5467 
  • src/sas/sascalc/dataloader/readers/schema/cansas1d_invalid_v1_1.xsd

    r250fec92 raf08e55  
    2424 
    2525        <complexType name="IdataType"> 
     26                <xsd:choice> 
    2627                <sequence> 
    2728                        <element name="Q" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     
    4041                        <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax" namespace="##other" /> 
    4142                </sequence> 
     43                <sequence> 
     44                        <element name="Qx" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     45                        <element name="Qy" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     46                        <element name="I" minOccurs="1" maxOccurs="1"    type="tns:floatUnitType" /> 
     47                        <element name="Idev" minOccurs="0" maxOccurs="1" type="tns:floatUnitType" default="0" /> 
     48                        <element name="Qydev" minOccurs="0" maxOccurs="1" type="tns:floatUnitType" default="0" /> 
     49                        <element name="Qxdev" minOccurs="0" maxOccurs="1" type="tns:floatUnitType" default="0" /> 
     50                        <element name="Mask" minOccurs="0" maxOccurs="1" type="string" default="0" /> 
     51                </sequence> 
     52                </xsd:choice> 
    4253        </complexType> 
    4354         
     
    5162                <attribute name="name" type="string" use="optional" default="" /> 
    5263                <attribute name="timestamp" type="dateTime" use="optional" /> 
     64                <attribute name="x_bins" type="string" use="optional" /> 
     65                <attribute name="y_bins" type="string" use="optional" /> 
    5366        </complexType> 
    5467 
  • src/sas/sascalc/dataloader/readers/sesans_reader.py

    r1c0e3b0 r7caf3e5  
    88import numpy 
    99import os 
    10 from sas.sascalc.dataloader.data_info import SESANSData1D 
     10from sas.sascalc.dataloader.data_info import Data1D 
    1111 
    1212# Check whether we have a converter available 
     
    5959                    raise  RuntimeError, "sesans_reader: cannot open %s" % path 
    6060                buff = input_f.read() 
    61 #                print buff 
    6261                lines = buff.splitlines() 
    63 #                print lines 
    64                 #Jae could not find python universal line spliter: 
    65                 #keep the below for now 
    66                 # some ascii data has \r line separator, 
    67                 # try it when the data is on only one long line 
    68 #                if len(lines) < 2 : 
    69 #                    lines = buff.split('\r') 
    70                   
    7162                x  = numpy.zeros(0) 
    7263                y  = numpy.zeros(0) 
     
    8374                tdlam = numpy.zeros(0) 
    8475                tdx = numpy.zeros(0) 
    85 #                print "all good" 
    86                 output = SESANSData1D(x=x, y=y, lam=lam, dy=dy, dx=dx, dlam=dlam) 
    87 #                print output                 
     76                output = Data1D(x=x, y=y, lam=lam, dy=dy, dx=dx, dlam=dlam, isSesans=True) 
    8877                self.filename = output.filename = basename 
    8978 
    90 #                #Initialize counters for data lines and header lines. 
    91 #                is_data = False  # Has more than 5 lines 
    92 #                # More than "5" lines of data is considered as actual 
    93 #                # data unless that is the only data 
    94 #                mum_data_lines = 5 
    95 #                # To count # of current data candidate lines 
    96 #                i = -1 
    97 #                # To count total # of previous data candidate lines 
    98 #                i1 = -1 
    99 #                # To count # of header lines 
    100 #                j = -1 
    101 #                # Helps to count # of header lines 
    102 #                j1 = -1 
    103 #                #minimum required number of columns of data; ( <= 4). 
    104 #                lentoks = 2 
    10579                paramnames=[] 
    10680                paramvals=[] 
     
    11185                Pvals=[] 
    11286                dPvals=[] 
    113 #                print x 
    114 #                print zvals 
     87 
    11588                for line in lines: 
    11689                    # Initial try for CSV (split on ,) 
     
    12295                    if len(toks)>5: 
    12396                        zvals.append(toks[0]) 
    124                         dzvals.append(toks[1]) 
    125                         lamvals.append(toks[2]) 
    126                         dlamvals.append(toks[3]) 
    127                         Pvals.append(toks[4]) 
    128                         dPvals.append(toks[5]) 
     97                        dzvals.append(toks[3]) 
     98                        lamvals.append(toks[4]) 
     99                        dlamvals.append(toks[5]) 
     100                        Pvals.append(toks[1]) 
     101                        dPvals.append(toks[2]) 
    129102                    else: 
    130103                        continue 
     
    140113                default_z_unit = "A" 
    141114                data_conv_P = None 
    142                 default_p_unit = " " 
     115                default_p_unit = " " # Adjust unit for axis (L^-3) 
    143116                lam_unit = lam_header[1].replace("[","").replace("]","") 
     117                if lam_unit == 'AA': 
     118                    lam_unit = 'A' 
    144119                varheader=[zvals[0],dzvals[0],lamvals[0],dlamvals[0],Pvals[0],dPvals[0]] 
    145120                valrange=range(1, len(zvals)) 
     
    161136                output.x, output.x_unit = self._unit_conversion(x, lam_unit, default_z_unit) 
    162137                output.y = y 
     138                output.y_unit = r'\AA^{-2} cm^{-1}'  # output y_unit added 
    163139                output.dx, output.dx_unit = self._unit_conversion(dx, lam_unit, default_z_unit) 
    164140                output.dy = dy 
    165141                output.lam, output.lam_unit = self._unit_conversion(lam, lam_unit, default_z_unit) 
    166142                output.dlam, output.dlam_unit = self._unit_conversion(dlam, lam_unit, default_z_unit) 
     143                 
     144                output.xaxis(r"\rm{z}", output.x_unit) 
     145                output.yaxis(r"\rm{ln(P)/(t \lambda^2)}", output.y_unit)  # Adjust label to ln P/(lam^2 t), remove lam column refs 
    167146 
    168                 output.xaxis("\rm{z}", output.x_unit) 
    169                 output.yaxis("\\rm{P/P0}", output.y_unit) 
    170147                # Store loading process information 
    171148                output.meta_data['loader'] = self.type_name 
    172                 output.sample.thickness = float(paramvals[6]) 
     149                #output.sample.thickness = float(paramvals[6]) 
    173150                output.sample.name = paramvals[1] 
    174151                output.sample.ID = paramvals[0] 
    175152                zaccept_unit_split = paramnames[7].split("[") 
    176153                zaccept_unit = zaccept_unit_split[1].replace("]","") 
    177                 if zaccept_unit.strip() == '\AA^-1': 
     154                if zaccept_unit.strip() == r'\AA^-1' or zaccept_unit.strip() == r'\A^-1': 
    178155                    zaccept_unit = "1/A" 
    179156                output.sample.zacceptance=(float(paramvals[7]),zaccept_unit) 
    180                 output.vars=varheader 
     157                output.vars = varheader 
    181158 
    182159                if len(output.x) < 1: 
  • src/sas/sascalc/file_converter/c_ext/bsl_loader.c

    rdc8a553 r2ab9c432  
    11#include <Python.h> 
     2//#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 
    23#include <numpy/arrayobject.h> 
    34#include <stdio.h> 
     
    2122static PyObject *CLoader_init(CLoader *self, PyObject *args, PyObject *kwds) { 
    2223    const char *filename; 
    23     const int n_frames; 
    24     const int n_pixels; 
    25     const int n_rasters; 
    26     const int swap_bytes; 
     24    int n_frames; 
     25    int n_pixels; 
     26    int n_rasters; 
     27    int swap_bytes; 
    2728 
    2829    if (self != NULL) { 
  • src/sas/sascalc/fit/AbstractFitEngine.py

    rd3911e3 ra9f579c  
    131131        a way to get residuals from data. 
    132132    """ 
    133     def __init__(self, x, y, dx=None, dy=None, smearer=None, data=None): 
     133    def __init__(self, x, y, dx=None, dy=None, smearer=None, data=None, lam=None, dlam=None): 
    134134        """ 
    135135            :param smearer: is an object of class QSmearer or SlitSmearer 
     
    152152                 
    153153        """ 
    154         Data1D.__init__(self, x=x, y=y, dx=dx, dy=dy) 
     154        Data1D.__init__(self, x=x, y=y, dx=dx, dy=dy, lam=lam, dlam=dlam) 
    155155        self.num_points = len(x) 
    156156        self.sas_data = data 
  • src/sas/sascalc/fit/BumpsFitting.py

    r345e7e4 r1a30720  
    352352    except Exception as exc: 
    353353        best, fbest = None, numpy.NaN 
    354         errors = [str(exc), traceback.traceback.format_exc()] 
     354        errors = [str(exc), traceback.format_exc()] 
    355355    finally: 
    356356        mapper.stop_mapper(fitdriver.mapper) 
  • src/sas/sasgui/guiframe/CategoryInstaller.py

    r212bfc2 rddbac66  
    123123        compile it and install 
    124124        :param homefile: Override the default home directory 
    125         :param model_list: List of model names except customized models 
     125        :param model_list: List of model names except those in Plugin Models 
     126               which are user supplied. 
    126127        """ 
    127128        _model_dict = { model.name: model for model in model_list} 
  • src/sas/sasgui/guiframe/acknowledgebox.py

    rc1fdf84 r74c8cd0  
    1111import wx.richtext 
    1212import wx.lib.hyperlink 
     13from wx.lib.expando import ExpandoTextCtrl 
    1314import random 
    1415import os.path 
     
    3637    Shows the current method for acknowledging SasView in 
    3738    scholarly publications. 
    38  
    3939    """ 
    4040 
     
    4444        wx.Dialog.__init__(self, *args, **kwds) 
    4545 
    46         self.ack = wx.TextCtrl(self, style=wx.TE_LEFT|wx.TE_MULTILINE|wx.TE_BESTWRAP|wx.TE_READONLY|wx.TE_NO_VSCROLL) 
     46        self.ack = ExpandoTextCtrl(self, style=wx.TE_LEFT|wx.TE_MULTILINE|wx.TE_BESTWRAP|wx.TE_READONLY|wx.TE_NO_VSCROLL) 
    4747        self.ack.SetValue(config._acknowledgement_publications) 
    48         self.ack.SetMinSize((-1, 55)) 
     48        #self.ack.SetMinSize((-1, 55)) 
     49        self.citation = ExpandoTextCtrl(self, style=wx.TE_LEFT|wx.TE_MULTILINE|wx.TE_BESTWRAP|wx.TE_READONLY|wx.TE_NO_VSCROLL) 
     50        self.citation.SetValue(config._acknowledgement_citation) 
    4951        self.preamble = wx.StaticText(self, -1, config._acknowledgement_preamble) 
    5052        items = [config._acknowledgement_preamble_bullet1, 
     
    5254                 config._acknowledgement_preamble_bullet3, 
    5355                 config._acknowledgement_preamble_bullet4] 
    54         self.list1 = wx.StaticText(self, -1, "\t(1) " + items[0]) 
    55         self.list2 = wx.StaticText(self, -1, "\t(2) " + items[1]) 
    56         self.list3 = wx.StaticText(self, -1, "\t(3) " + items[2]) 
    57         self.list4 = wx.StaticText(self, -1, "\t(4) " + items[3]) 
     56        self.list1 = wx.StaticText(self, -1, "(1) " + items[0]) 
     57        self.list2 = wx.StaticText(self, -1, "(2) " + items[1]) 
     58        self.list3 = wx.StaticText(self, -1, "(3) " + items[2]) 
     59        self.list4 = wx.StaticText(self, -1, "(4) " + items[3]) 
    5860        self.static_line = wx.StaticLine(self, 0) 
    5961        self.__set_properties() 
     
    6971        self.SetTitle("Acknowledging SasView") 
    7072        #Increased size of box from (525, 225), SMK, 04/10/16 
    71         self.SetSize((600, 300)) 
     73        self.SetClientSize((600, 320)) 
    7274        # end wxGlade 
    7375 
     
    8183        sizer_titles.Add(self.preamble, 0, wx.ALL|wx.EXPAND, 5) 
    8284        sizer_titles.Add(self.list1, 0, wx.ALL|wx.EXPAND, 5) 
     85        sizer_titles.Add(self.ack, 0, wx.ALL|wx.EXPAND, 5) 
    8386        sizer_titles.Add(self.list2, 0, wx.ALL|wx.EXPAND, 5) 
     87        sizer_titles.Add(self.citation, 0, wx.ALL|wx.EXPAND, 5) 
    8488        sizer_titles.Add(self.list3, 0, wx.ALL|wx.EXPAND, 5) 
     89        #sizer_titles.Add(self.static_line, 0, wx.ALL|wx.EXPAND, 0) 
    8590        sizer_titles.Add(self.list4, 0, wx.ALL|wx.EXPAND, 5) 
    86         sizer_titles.Add(self.static_line, 0, wx.ALL|wx.EXPAND, 0) 
    87         sizer_titles.Add(self.ack, 0, wx.ALL|wx.EXPAND, 5) 
    8891        sizer_main.Add(sizer_titles, -1, wx.ALL|wx.EXPAND, 5) 
    8992        self.SetAutoLayout(True) 
     
    9194        self.Layout() 
    9295        self.Centre() 
     96        #self.SetClientSize(sizer_main.GetSize()) 
    9397        # end wxGlade 
    9498 
  • src/sas/sasgui/guiframe/config.py

    rd85c194 rf9d1f60  
    11""" 
    2 Application settings 
     2    Application settings 
    33""" 
     4import time 
    45import os 
    5 import time 
    66from sas.sasgui.guiframe.gui_style import GUIFRAME 
     7import sas.sasview 
     8import logging 
     9 
    710# Version of the application 
    8 __appname__ = "DummyView" 
    9 __version__ = '0.0.0' 
    10 __build__ = '1' 
     11__appname__ = "SasView" 
     12__version__ = sas.sasview.__version__ 
     13__build__ = sas.sasview.__build__ 
    1114__download_page__ = 'https://github.com/SasView/sasview/releases' 
    1215__update_URL__ = 'http://www.sasview.org/latestversion.json' 
    1316 
    14  
    1517# Debug message flag 
    16 __EVT_DEBUG__ = True 
     18__EVT_DEBUG__ = False 
    1719 
    1820# Flag for automated testing 
     
    2931_acknowledgement_preamble =\ 
    3032'''To ensure the long term support and development of this software please''' +\ 
    31 ''' remember to do the following.''' 
     33''' remember to:''' 
    3234_acknowledgement_preamble_bullet1 =\ 
    33 '''Acknowledge its use in your publications as suggested below''' 
     35'''Acknowledge its use in your publications as :''' 
    3436_acknowledgement_preamble_bullet2 =\ 
    35 '''Reference the following website: http://www.sasview.org''' 
     37'''Reference SasView as:''' 
    3638_acknowledgement_preamble_bullet3 =\ 
    3739'''Reference the model you used if appropriate (see documentation for refs)''' 
     
    3941'''Send us your reference for our records: developers@sasview.org''' 
    4042_acknowledgement_publications = \ 
    41 '''This work benefited from the use of the SasView application, originally 
    42 developed under NSF award DMR-0520547. 
     43'''This work benefited from the use of the SasView application, originally developed under NSF Award DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000.''' 
     44_acknowledgement_citation = \ 
     45'''M. Doucet et al. SasView Version 4.1, Zenodo, 10.5281/zenodo.438138''' 
     46 
     47_acknowledgement =  \ 
     48'''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: https://github.com/orgs/SasView/people 
    4349''' 
    44 _acknowledgement =  \ 
    45 '''This work originally developed as part of the DANSE project funded by the NSF 
    46 under grant DMR-0520547, and currently maintained by NIST, UMD, ORNL, ISIS, ESS 
    47 and ILL. 
    4850 
    49 ''' 
    5051_homepage = "http://www.sasview.org" 
    51 _download = "http://sourceforge.net/projects/sasview/files/" 
     52_download = __download_page__ 
    5253_authors = [] 
    5354_paper = "http://sourceforge.net/p/sasview/tickets/" 
    5455_license = "mailto:help@sasview.org" 
    55 _nsf_logo = "images/nsf_logo.png" 
    56 _danse_logo = "images/danse_logo.png" 
    57 _inst_logo = "images/utlogo.gif" 
    58 _nist_logo = "images/nist_logo.png" 
    59 _umd_logo = "images/umd_logo.png" 
    60 _sns_logo = "images/sns_logo.png" 
    61 _isis_logo = "images/isis_logo.png" 
    62 _ess_logo = "images/ess_logo.png" 
    63 _ill_logo = "images/ill_logo.png" 
     56 
     57 
     58icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images")) 
     59logging.info("icon path: %s" % icon_path) 
     60media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) 
     61test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test")) 
     62 
     63_nist_logo = os.path.join(icon_path, "nist_logo.png") 
     64_umd_logo = os.path.join(icon_path, "umd_logo.png") 
     65_sns_logo = os.path.join(icon_path, "sns_logo.png") 
     66_ornl_logo = os.path.join(icon_path, "ornl_logo.png") 
     67_isis_logo = os.path.join(icon_path, "isis_logo.png") 
     68_ess_logo = os.path.join(icon_path, "ess_logo.png") 
     69_ill_logo = os.path.join(icon_path, "ill_logo.png") 
     70_ansto_logo = os.path.join(icon_path, "ansto_logo.png") 
     71_tudelft_logo = os.path.join(icon_path, "tudelft_logo.png") 
     72_nsf_logo = os.path.join(icon_path, "nsf_logo.png") 
     73_danse_logo = os.path.join(icon_path, "danse_logo.png") 
     74_inst_logo = os.path.join(icon_path, "utlogo.gif") 
    6475_nist_url = "http://www.nist.gov/" 
    6576_umd_url = "http://www.umd.edu/" 
    6677_sns_url = "http://neutrons.ornl.gov/" 
     78_ornl_url = "http://neutrons.ornl.gov/" 
    6779_nsf_url = "http://www.nsf.gov" 
    68 _danse_url = "http://www.cacr.caltech.edu/projects/danse/release/index.html" 
    69 _inst_url = "http://www.utk.edu" 
    7080_isis_url = "http://www.isis.stfc.ac.uk/" 
    7181_ess_url = "http://ess-scandinavia.eu/" 
    7282_ill_url = "http://www.ill.eu/" 
    73 _corner_image = "images/angles_flat.png" 
    74 _welcome_image = "images/SVwelcome.png" 
    75 _copyright = "(c) 2008, University of Tennessee" 
    76 #edit the lists below of file state your plugin can read 
    77 #for sasview this how you can edit these lists 
    78 #PLUGIN_STATE_EXTENSIONS = ['.prv','.fitv', '.inv'] 
    79 #APPLICATION_STATE_EXTENSION = '.svs' 
    80 #PLUGINS_WLIST = ['P(r) files (*.prv)|*.prv', 
    81 #                  'Fitting files (*.fitv)|*.fitv', 
    82 #                  'Invariant files (*.inv)|*.inv'] 
    83 #APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' 
    84 APPLICATION_WLIST = '' 
    85 APPLICATION_STATE_EXTENSION = None 
    86 PLUGINS_WLIST = [] 
    87 PLUGIN_STATE_EXTENSIONS = [] 
    88 SPLASH_SCREEN_PATH = "images/danse_logo.png" 
    89 DEFAULT_STYLE = GUIFRAME.SINGLE_APPLICATION 
    90 SPLASH_SCREEN_WIDTH = 500 
    91 SPLASH_SCREEN_HEIGHT = 300 
    92 WELCOME_PANEL_ON = False 
    93 TUTORIAL_PATH = None 
    94 SS_MAX_DISPLAY_TIME = 1500 
    95 PLOPANEL_WIDTH = 350 
    96 PLOPANEL_HEIGTH = 350 
    97 GUIFRAME_WIDTH = 1000 
    98 GUIFRAME_HEIGHT = 800 
    99 CONTROL_WIDTH = -1 
    100 CONTROL_HEIGHT = -1 
    101 SetupIconFile_win = os.path.join("images", "ball.ico") 
    102 SetupIconFile_mac = os.path.join("images", "ball.icns") 
    103 DefaultGroupName = "DANSE" 
    104 OutputBaseFilename = "setupGuiFrame" 
     83_ansto_url = "http://www.ansto.gov.au/" 
     84_tudelft_url = "http://www.tnw.tudelft.nl/en/cooperation/facilities/reactor-instituut-delft/" 
     85_danse_url = "http://www.cacr.caltech.edu/projects/danse/release/index.html" 
     86_inst_url = "http://www.utk.edu" 
     87_corner_image = os.path.join(icon_path, "angles_flat.png") 
     88_welcome_image = os.path.join(icon_path, "SVwelcome.png") 
     89_copyright = "(c) 2009 - 2017, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO and TU Delft" 
     90marketplace_url = "http://marketplace.sasview.org/" 
     91 
     92#edit the list of file state your plugin can read 
     93APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' 
     94APPLICATION_STATE_EXTENSION = '.svs' 
     95GUIFRAME_WIDTH = 1150 
     96GUIFRAME_HEIGHT = 840 
     97PLUGIN_STATE_EXTENSIONS = ['.fitv', '.inv', '.prv', '.crf'] 
     98PLUGINS_WLIST = ['Fitting files (*.fitv)|*.fitv', 
     99                 'Invariant files (*.inv)|*.inv', 
     100                 'P(r) files (*.prv)|*.prv', 
     101                 'Corfunc files (*.crf)|*.crf'] 
     102PLOPANEL_WIDTH = 415 
     103PLOPANEL_HEIGTH = 370 
    105104DATAPANEL_WIDTH = 235 
    106105DATAPANEL_HEIGHT = 700 
     106SPLASH_SCREEN_PATH = os.path.join(icon_path, "SVwelcome_mini.png") 
     107TUTORIAL_PATH = os.path.join(media_path, "Tutorial.pdf") 
     108DEFAULT_STYLE = GUIFRAME.MULTIPLE_APPLICATIONS|GUIFRAME.MANAGER_ON\ 
     109                    |GUIFRAME.CALCULATOR_ON|GUIFRAME.TOOLBAR_ON 
     110SPLASH_SCREEN_WIDTH = 512 
     111SPLASH_SCREEN_HEIGHT = 366 
     112SS_MAX_DISPLAY_TIME = 2000 
     113WELCOME_PANEL_ON = True 
     114WELCOME_PANEL_SHOW = False 
     115CLEANUP_PLOT = False 
     116# OPEN and SAVE project menu 
     117OPEN_SAVE_PROJECT_MENU = True 
     118#VIEW MENU 
     119VIEW_MENU = True 
     120#EDIT MENU 
     121EDIT_MENU = True 
     122 
     123SetupIconFile_win = os.path.join(icon_path, "ball.ico") 
     124SetupIconFile_mac = os.path.join(icon_path, "ball.icns") 
     125DefaultGroupName = "." 
     126OutputBaseFilename = "setupSasView" 
     127 
    107128FIXED_PANEL = True 
    108129DATALOADER_SHOW = True 
     
    113134# set a default perspective 
    114135DEFAULT_PERSPECTIVE = 'None' 
    115 # OPEN and SAVE project menu 
    116 OPEN_SAVE_PROJECT_MENU = True 
    117 CLEANUP_PLOT = False 
    118 # OPEN and SAVE project menu 
    119 OPEN_SAVE_PROJECT_MENU = False 
    120 #VIEW MENU 
    121 VIEW_MENU = False 
    122 #EDIT MENU 
    123 EDIT_MENU = False 
    124 import wx.lib.newevent 
    125 (StatusBarEvent, EVT_STATUS) = wx.lib.newevent.NewEvent() 
     136 
     137# Time out for updating sasview 
     138UPDATE_TIMEOUT = 2 
     139 
     140#OpenCL option 
     141SAS_OPENCL = None 
    126142 
    127143def printEVT(message): 
    128     """ 
    129     :TODO - need method documentation 
    130     """ 
    131144    if __EVT_DEBUG__: 
     145        """ 
     146        :TODO - Need method doc string 
     147        """ 
    132148        print "%g:  %s" % (time.clock(), message) 
    133      
     149 
    134150        if __EVT_DEBUG_2_FILE__: 
    135151            out = open(__EVT_DEBUG_FILENAME__, 'a') 
    136152            out.write("%10g:  %s\n" % (time.clock(), message)) 
    137153            out.close() 
    138              
  • src/sas/sasgui/guiframe/dataFitting.py

    r345e7e4 r68adf86  
    1717    """ 
    1818    """ 
    19     def __init__(self, x=None, y=None, dx=None, dy=None): 
     19 
     20    def __init__(self, x=None, y=None, dx=None, dy=None, lam=None, dlam=None, isSesans=False): 
    2021        """ 
    2122        """ 
     
    2425        if y is None: 
    2526            y = [] 
    26         PlotData1D.__init__(self, x, y, dx, dy) 
    27         LoadData1D.__init__(self, x, y, dx, dy) 
     27        self.isSesans = isSesans 
     28        PlotData1D.__init__(self, x, y, dx, dy, lam, dlam) 
     29        LoadData1D.__init__(self, x, y, dx, dy, lam, dlam, isSesans) 
     30 
    2831        self.id = None 
    2932        self.list_group_id = [] 
     
    3235        self.path = None 
    3336        self.xtransform = None 
     37        if self.isSesans: 
     38            self.xtransform = "x" 
    3439        self.ytransform = None 
     40        if self.isSesans: 
     41            self.ytransform = "y" 
    3542        self.title = "" 
    3643        self.scale = None 
     
    6875        # First, check the data compatibility 
    6976        dy, dy_other = self._validity_check(other) 
    70         result = Data1D(x=[], y=[], dx=None, dy=None) 
     77        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None) 
    7178        result.clone_without_data(length=len(self.x), clone=self) 
    7279        result.copy_from_datainfo(data1d=self) 
     
    115122        # First, check the data compatibility 
    116123        self._validity_check_union(other) 
    117         result = Data1D(x=[], y=[], dx=None, dy=None) 
     124        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=None) 
    118125        tot_length = len(self.x) + len(other.x) 
    119126        result = self.clone_without_data(length=tot_length, clone=result) 
     127        if self.dlam == None or other.dlam is None: 
     128            result.dlam = None 
     129        else: 
     130            result.dlam = numpy.zeros(tot_length) 
    120131        if self.dy == None or other.dy is None: 
    121132            result.dy = None 
     
    141152        result.y = numpy.append(self.y, other.y) 
    142153        result.y = result.y[ind] 
     154        result.lam = numpy.append(self.lam, other.lam) 
     155        result.lam = result.lam[ind] 
     156        if result.dlam != None: 
     157            result.dlam = numpy.append(self.dlam, other.dlam) 
     158            result.dlam = result.dlam[ind] 
    143159        if result.dy != None: 
    144160            result.dy = numpy.append(self.dy, other.dy) 
     
    260276        # First, check the data compatibility 
    261277        self._validity_check_union(other) 
    262         result = Data1D(x=[], y=[], dx=None, dy=None) 
     278        result = Data1D(x=[], y=[], lam=[], dx=None, dy=None, dlam=[]) 
    263279        tot_length = len(self.x)+len(other.x) 
    264280        result.clone_without_data(length=tot_length, clone=self) 
     281        if self.dlam == None or other.dlam is None: 
     282            result.dlam = None 
     283        else: 
     284            result.dlam = numpy.zeros(tot_length) 
    265285        if self.dy == None or other.dy is None: 
    266286            result.dy = None 
     
    285305        result.y = numpy.append(self.y, other.y) 
    286306        result.y = result.y[ind] 
     307        result.lam = numpy.append(self.lam, other.lam) 
     308        result.lam = result.lam[ind] 
    287309        if result.dy != None: 
    288310            result.dy = numpy.append(self.dy, other.dy) 
  • src/sas/sasgui/guiframe/data_manager.py

    rd85c194 r2ffe241  
    6161         
    6262        if issubclass(Data2D, data.__class__): 
    63             new_plot = Data2D(image=None, err_image=None)  
    64         else:  
    65             new_plot = Data1D(x=[], y=[], dx=None, dy=None) 
    66             
     63            new_plot = Data2D(image=None, err_image=None) # For now, isSesans for 2D data is always false 
     64        else: 
     65            new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=data.isSesans) 
     66 
     67 
     68        #elif data.meta_data['loader'] == 'SESANS': 
     69        #    new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None, isSesans=True) 
     70        #else: 
     71        #    new_plot = Data1D(x=[], y=[], dx=None, dy=None, lam=None, dlam=None) #SESANS check??? 
     72 
    6773        new_plot.copy_from_datainfo(data) 
    6874        data.clone_without_data(clone=new_plot) 
  • src/sas/sasgui/guiframe/data_panel.py

    rc8e1996 ra45a298  
    6666    IS_MAC = True 
    6767 
    68 STYLE_FLAG = wx.RAISED_BORDER | CT.TR_HAS_BUTTONS | CT.TR_HIDE_ROOT |\ 
    69                     wx.WANTS_CHARS | CT.TR_HAS_VARIABLE_ROW_HEIGHT 
     68STYLE_FLAG = (wx.RAISED_BORDER | CT.TR_HAS_BUTTONS | 
     69                    wx.WANTS_CHARS | CT.TR_HAS_VARIABLE_ROW_HEIGHT) 
    7070 
    7171 
     
    7474    Check list control to be used for Data Panel 
    7575    """ 
    76     def __init__(self, parent, *args, **kwds): 
     76    def __init__(self, parent, root, *args, **kwds): 
    7777        # agwstyle is introduced in wx.2.8.11 but is not working for mac 
    7878        if IS_MAC and wx_version < 812: 
     
    9797                    del kwds['style'] 
    9898                    CT.CustomTreeCtrl.__init__(self, parent, *args, **kwds) 
    99         self.root = self.AddRoot("Available Data") 
     99        self.root = self.AddRoot(root) 
    100100 
    101101    def OnCompareItems(self, item1, item2): 
     
    520520        Add a listcrtl in the panel 
    521521        """ 
    522         tree_ctrl_label = wx.StaticText(self, -1, "Data") 
    523         tree_ctrl_label.SetForegroundColour('blue') 
    524         self.tree_ctrl = DataTreeCtrl(parent=self, style=wx.SUNKEN_BORDER) 
     522        # Add splitter 
     523        w, h = self.parent.GetSize() 
     524        splitter = wx.SplitterWindow(self) 
     525        splitter.SetMinimumPaneSize(50) 
     526        splitter.SetSashGravity(1.0) 
     527 
     528        file_sizer = wx.BoxSizer(wx.VERTICAL) 
     529        file_sizer.SetMinSize(wx.Size(w/13, h*2/5)) 
     530        theory_sizer = wx.BoxSizer(wx.VERTICAL) 
     531        theory_sizer.SetMinSize(wx.Size(w/13, h*2/5)) 
     532 
     533        self.tree_ctrl = DataTreeCtrl(parent=splitter, 
     534                                      style=wx.SUNKEN_BORDER, 
     535                                      root="Available Data") 
     536 
    525537        self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_CHECKING, self.on_check_item) 
    526538        self.tree_ctrl.Bind(CT.EVT_TREE_ITEM_MENU, self.on_right_click_data) 
     
    557569        wx.EVT_MENU(self, self.editmask_id, self.on_edit_data) 
    558570 
    559         tree_ctrl_theory_label = wx.StaticText(self, -1, "Theory") 
    560         tree_ctrl_theory_label.SetForegroundColour('blue') 
    561         self.tree_ctrl_theory = DataTreeCtrl(parent=self, 
    562                                              style=wx.SUNKEN_BORDER) 
     571        self.tree_ctrl_theory = DataTreeCtrl(parent=splitter, 
     572                                             style=wx.SUNKEN_BORDER, 
     573                                             root="Available Theory") 
    563574        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_CHECKING, 
    564575                                   self.on_check_item) 
    565576        self.tree_ctrl_theory.Bind(CT.EVT_TREE_ITEM_MENU, 
    566577                                   self.on_right_click_theory) 
    567         self.sizer1.Add(tree_ctrl_label, 0, wx.LEFT, 10) 
    568         self.sizer1.Add(self.tree_ctrl, 1, wx.EXPAND | wx.ALL, 10) 
    569         self.sizer1.Add(tree_ctrl_theory_label, 0,  wx.LEFT, 10) 
    570         self.sizer1.Add(self.tree_ctrl_theory, 1, wx.EXPAND | wx.ALL, 10) 
     578        splitter.SplitHorizontally(self.tree_ctrl, self.tree_ctrl_theory) 
     579        self.sizer1.Add(splitter, 1, wx.EXPAND | wx.ALL, 10) 
    571580 
    572581    def on_right_click_theory(self, event): 
     
    722731            if self.tree_ctrl.root: 
    723732                self.tree_ctrl.SortChildren(self.tree_ctrl.root) 
     733            # Expand root if # of data sets > 0 
     734            if self.tree_ctrl.GetCount() > 0: 
     735                self.tree_ctrl.root.Expand() 
    724736        self.enable_remove() 
    725737        self.enable_import() 
     
    760772                                       state_id=state_id, 
    761773                                       theory_list=theory_list) 
     774        if self.tree_ctrl_theory.GetCount() > 0: 
     775            self.tree_ctrl_theory.root.Expand() 
    762776 
    763777    def append_theory_helper(self, tree, root, state_id, theory_list): 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py

    r6ffa0dd rca224b1  
    134134        """ 
    135135        for group_id in self.plot_panels.keys(): 
    136             panel = self.plot_panels[group_id] 
    137             panel.graph.reset() 
    138             self.hide_panel(group_id) 
     136            self.clear_panel_by_id(group_id) 
    139137        self.plot_panels = {} 
    140138 
  • src/sas/sasgui/perspectives/calculator/model_editor.py

    ra08b89b rddbac66  
    55function of y (usually the intensity).  It also provides a drop down of 
    66standard available math functions.  Finally a full python editor panel for 
    7 complete customizatin is provided. 
    8  
    9 :TODO the writiong of the file and name checking (and maybe some other 
    10 funtions?) should be moved to a computational module which could be called 
    11 fropm a python script.  Basically one just needs to pass the name, 
     7complete customization is provided. 
     8 
     9:TODO the writing of the file and name checking (and maybe some other 
     10functions?) should be moved to a computational module which could be called 
     11from a python script.  Basically one just needs to pass the name, 
    1212description text and function text (or in the case of the composite editor 
    1313the names of the first and second model and the operator to be used). 
     
    6161    """ 
    6262    Dialog for easy custom composite models.  Provides a wx.Dialog panel 
    63     to choose two existing models (including pre-existing custom models which 
     63    to choose two existing models (including pre-existing Plugin Models which 
    6464    may themselves be composite models) as well as an operation on those models 
    6565    (add or multiply) the resulting model will add a scale parameter for summed 
     
    380380            color = 'blue' 
    381381        except: 
    382             msg = "Easy Custom Sum/Multipy: Error occurred..." 
     382            msg = "Easy Sum/Multipy Plugin: Error occurred..." 
    383383            info = 'Error' 
    384384            color = 'red' 
     
    501501        self.factor = factor 
    502502        self._operator = operator 
    503         self.explanation = "  Custom Model = %s %s (model1 %s model2)\n" % \ 
     503        self.explanation = "  Plugin Model = %s %s (model1 %s model2)\n" % \ 
    504504                           (self.factor, f_oper, self._operator) 
    505505        self.explanationctr.SetLabel(self.explanation) 
     
    617617class EditorPanel(wx.ScrolledWindow): 
    618618    """ 
    619     Custom model function editor 
     619    Simple Plugin Model function editor 
    620620    """ 
    621621    def __init__(self, parent, base, path, title, *args, **kwds): 
     
    652652        self.msg_sizer = None 
    653653        self.warning = "" 
    654         self._description = "New Custom Model" 
     654        #This does not seem to be used anywhere so commenting out for now 
     655        #    -- PDB 2/26/17  
     656        #self._description = "New Plugin Model" 
    655657        self.function_tcl = None 
    656658        self.math_combo = None 
     
    991993        else: 
    992994            self._notes = result 
    993             msg = "Successful! Please look for %s in Customized Models."%name 
     995            msg = "Successful! Please look for %s in Plugin Models."%name 
    994996            msg += "  " + self._notes 
    995997            info = 'Info' 
     
    11381140    def on_help(self, event): 
    11391141        """ 
    1140         Bring up the Custom Model Editor Documentation whenever 
     1142        Bring up the New Plugin Model Editor Documentation whenever 
    11411143        the HELP button is clicked. 
    11421144 
     
    11901192        #self.Destroy() 
    11911193 
    1192 ## Templates for custom models 
     1194## Templates for plugin models 
    11931195 
    11941196CUSTOM_TEMPLATE = """ 
  • src/sas/sasgui/perspectives/calculator/pyconsole.py

    rd472e86 rddbac66  
    302302        success = show_model_output(self, fname) 
    303303 
    304         # Update custom model list in fitpage combobox 
     304        # Update plugin model list in fitpage combobox 
    305305        if success and self._manager != None and self.panel != None: 
    306306            self._manager.set_edit_menu_helper(self.parent) 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    r505706a rb301db9  
    5353    ON_MAC = True 
    5454 
     55CUSTOM_MODEL = 'Plugin Models' 
     56 
    5557class BasicPage(ScrolledPanel, PanelBase): 
    5658    """ 
    57     This class provide general structure of fitpanel page 
     59    This class provide general structure of the fitpanel page 
    5860    """ 
    5961    # Internal name for the AUI manager 
     
    118120        self.dxw = None 
    119121        # pinhole smear 
    120         self.dx_min = None 
    121         self.dx_max = None 
     122        self.dx_percent = None 
    122123        # smear attrbs 
    123124        self.enable_smearer = None 
     
    677678    def _copy_info(self, flag): 
    678679        """ 
    679         Send event dpemding on flag 
    680  
    681         : Param flag: flag that distinguish event 
     680        Send event depending on flag 
     681 
     682        : Param flag: flag that distinguishes the event 
    682683        """ 
    683684        # messages depending on the flag 
     
    847848        self.state.pinhole_smearer = \ 
    848849                                copy.deepcopy(self.pinhole_smearer.GetValue()) 
    849         self.state.dx_max = copy.deepcopy(self.dx_max) 
    850         self.state.dx_min = copy.deepcopy(self.dx_min) 
     850        self.state.dx_percent = copy.deepcopy(self.dx_percent) 
    851851        self.state.dxl = copy.deepcopy(self.dxl) 
    852852        self.state.dxw = copy.deepcopy(self.dxw) 
     
    11051105        """ 
    11061106        for key, value in self.master_category_dict.iteritems(): 
     1107            formfactor = state.formfactorcombobox.split(":") 
     1108            if isinstance(formfactor, list): 
     1109                formfactor = formfactor[0] 
    11071110            for list_item in value: 
    1108                 if state.formfactorcombobox in list_item: 
     1111                if formfactor in list_item: 
    11091112                    return self.categorybox.Items.index(key) 
    11101113        return 0 
     
    11161119        :precondition: the page is already drawn or created 
    11171120 
    1118         :postcondition: the state of the underlying data change as well as the 
     1121        :postcondition: the state of the underlying data changes as well as the 
    11191122            state of the graphic interface 
    11201123        """ 
     
    11521155        self._show_combox_helper() 
    11531156        # select the current model 
    1154         try: 
    1155             # to support older version 
    1156             category_pos = int(state.categorycombobox) 
    1157         except: 
    1158             state.formfactorcombobox = state.formfactorcombobox.lower() 
    1159             state.formfactorcombobox = \ 
    1160                 state.formfactorcombobox.replace('model', '') 
    1161             state.formfactorcombobox = unicode(state.formfactorcombobox) 
    1162             state.categorycombobox = unicode(state.categorycombobox) 
    1163             if state.categorycombobox in self.categorybox.Items: 
    1164                 category_pos = self.categorybox.Items.index( 
    1165                     state.categorycombobox) 
    1166             else: 
    1167                 # Look in master list for model name (model.lower) 
    1168                 category_pos = self.get_cat_combo_box_pos(state) 
     1157        state._convert_to_sasmodels() 
     1158        state.categorycombobox = unicode(state.categorycombobox) 
     1159        if state.categorycombobox in self.categorybox.Items: 
     1160            category_pos = self.categorybox.Items.index( 
     1161                state.categorycombobox) 
     1162        else: 
     1163            # Look in master list for model name (model.lower) 
     1164            category_pos = self.get_cat_combo_box_pos(state) 
    11691165 
    11701166        self.categorybox.Select(category_pos) 
    11711167        self._show_combox(None) 
    1172         try: 
    1173             # to support older version 
    1174             formfactor_pos = int(state.formfactorcombobox) 
    1175         except: 
    1176             formfactor_pos = 0 
    1177             for ind_form in range(self.formfactorbox.GetCount()): 
    1178                 if self.formfactorbox.GetString(ind_form) == \ 
    1179                                                     (state.formfactorcombobox): 
    1180                     formfactor_pos = int(ind_form) 
     1168        from models import PLUGIN_NAME_BASE 
     1169        if self.categorybox.GetValue() == CUSTOM_MODEL \ 
     1170                and PLUGIN_NAME_BASE not in state.formfactorcombobox: 
     1171            state.formfactorcombobox = \ 
     1172                PLUGIN_NAME_BASE + state.formfactorcombobox 
     1173        formfactor_pos = 0 
     1174        for ind_form in range(self.formfactorbox.GetCount()): 
     1175            if self.formfactorbox.GetString(ind_form) == \ 
     1176                                                (state.formfactorcombobox): 
     1177                formfactor_pos = int(ind_form) 
     1178                break 
     1179 
     1180        self.formfactorbox.Select(formfactor_pos) 
     1181 
     1182        structfactor_pos = 0 
     1183        if state.structurecombobox is not None: 
     1184            state.structurecombobox = unicode(state.structurecombobox) 
     1185            for ind_struct in range(self.structurebox.GetCount()): 
     1186                if self.structurebox.GetString(ind_struct) == \ 
     1187                                                (state.structurecombobox): 
     1188                    structfactor_pos = int(ind_struct) 
    11811189                    break 
    1182  
    1183         self.formfactorbox.Select(formfactor_pos) 
    1184  
    1185         structfactor_pos = 0 
    1186         try: 
    1187             # to support older version 
    1188             structfactor_pos = int(state.structurecombobox) 
    1189         except: 
    1190             if state.structurecombobox is not None: 
    1191                 state.structurecombobox = unicode(state.structurecombobox) 
    1192                 for ind_struct in range(self.structurebox.GetCount()): 
    1193                     if self.structurebox.GetString(ind_struct) == \ 
    1194                                                     (state.structurecombobox): 
    1195                         structfactor_pos = int(ind_struct) 
    1196                         break 
    11971190 
    11981191        self.structurebox.SetSelection(structfactor_pos) 
     
    12521245        # we have two more options for smearing 
    12531246        if self.pinhole_smearer.GetValue(): 
    1254             self.dx_min = state.dx_min 
    1255             self.dx_max = state.dx_max 
    1256             if self.dx_min is not None: 
    1257                 self.smear_pinhole_min.SetValue(str(self.dx_min)) 
    1258             if self.dx_max is not None: 
    1259                 self.smear_pinhole_max.SetValue(str(self.dx_max)) 
     1247            self.dx_percent = state.dx_percent 
     1248            if self.dx_percent is not None: 
     1249                if state.dx_old: 
     1250                    self.dx_percent = 100 * (self.dx_percent / self.data.x[0]) 
     1251                self.smear_pinhole_percent.SetValue("%.2f" % self.dx_percent) 
    12601252            self.onPinholeSmear(event=None) 
    12611253        elif self.slit_smearer.GetValue(): 
     
    13421334    def _selectDlg(self): 
    13431335        """ 
    1344         open a dialog file to selected the customized dispersity 
     1336        open a dialog file to select the customized polydispersity function 
    13451337        """ 
    13461338        if self.parent is not None: 
     
    13841376        # self.state.struct_rbutton = self.struct_rbutton.GetValue() 
    13851377        # self.state.plugin_rbutton = self.plugin_rbutton.GetValue() 
    1386         self.state.structurecombobox = self.structurebox.GetLabel() 
    1387         self.state.formfactorcombobox = self.formfactorbox.GetLabel() 
    1388         self.state.categorycombobox = self.categorybox.GetLabel() 
     1378        self.state.structurecombobox = self.structurebox.GetValue() 
     1379        self.state.formfactorcombobox = self.formfactorbox.GetValue() 
     1380        self.state.categorycombobox = self.categorybox.GetValue() 
    13891381 
    13901382        # post state to fit panel 
     
    15871579        if len(statelist) == 0 or len(listtorestore) == 0: 
    15881580            return 
    1589         if len(statelist) != len(listtorestore): 
    1590             return 
    15911581 
    15921582        for j in range(len(listtorestore)): 
    1593             item_page = listtorestore[j] 
    1594             item_page_info = statelist[j] 
    1595             # change the state of the check box for simple parameters 
    1596             if item_page[0] is not None: 
    1597                 item_page[0].SetValue(item_page_info[0]) 
    1598             if item_page[2] is not None: 
    1599                 item_page[2].SetValue(item_page_info[2]) 
    1600                 if item_page[2].__class__.__name__ == "ComboBox": 
    1601                     if item_page_info[2] in self.model.fun_list: 
    1602                         fun_val = self.model.fun_list[item_page_info[2]] 
    1603                         self.model.setParam(item_page_info[1], fun_val) 
    1604             if item_page[3] is not None: 
    1605                 # show or hide text +/- 
    1606                 if item_page_info[2]: 
    1607                     item_page[3].Show(True) 
    1608                 else: 
    1609                     item_page[3].Hide() 
    1610             if item_page[4] is not None: 
    1611                 # show of hide the text crtl for fitting error 
    1612                 if item_page_info[4][0]: 
    1613                     item_page[4].Show(True) 
    1614                     item_page[4].SetValue(item_page_info[4][1]) 
    1615                 else: 
    1616                     item_page[3].Hide() 
    1617             if item_page[5] is not None: 
    1618                 # show of hide the text crtl for fitting error 
    1619                 item_page[5].Show(item_page_info[5][0]) 
    1620                 item_page[5].SetValue(item_page_info[5][1]) 
    1621  
    1622             if item_page[6] is not None: 
    1623                 # show of hide the text crtl for fitting error 
    1624                 item_page[6].Show(item_page_info[6][0]) 
    1625                 item_page[6].SetValue(item_page_info[6][1]) 
     1583            for param in statelist: 
     1584                if param[1] == listtorestore[j][1]: 
     1585                    item_page = listtorestore[j] 
     1586                    item_page_info = param 
     1587                    if (item_page_info[1] == "theta" or item_page_info[1] == 
     1588                            "phi") and not self._is_2D(): 
     1589                        break 
     1590                    # change the state of the check box for simple parameters 
     1591                    if item_page[0] is not None: 
     1592                        item_page[0].SetValue(item_page_info[0]) 
     1593                    if item_page[2] is not None: 
     1594                        item_page[2].SetValue(item_page_info[2]) 
     1595                        if item_page[2].__class__.__name__ == "ComboBox": 
     1596                            if item_page_info[2] in self.model.fun_list: 
     1597                                fun_val = self.model.fun_list[item_page_info[2]] 
     1598                                self.model.setParam(item_page_info[1], fun_val) 
     1599                    if item_page[3] is not None: 
     1600                        # show or hide text +/- 
     1601                        if item_page_info[2]: 
     1602                            item_page[3].Show(True) 
     1603                        else: 
     1604                            item_page[3].Hide() 
     1605                    if item_page[4] is not None: 
     1606                        # show of hide the text crtl for fitting error 
     1607                        if item_page_info[4][0]: 
     1608                            item_page[4].Show(True) 
     1609                            item_page[4].SetValue(str(item_page_info[4][1])) 
     1610                        else: 
     1611                            item_page[3].Hide() 
     1612                    if item_page[5] is not None: 
     1613                        # show of hide the text crtl for fitting error 
     1614                        item_page[5].Show(True) 
     1615                        item_page[5].SetValue(str(item_page_info[5][1])) 
     1616                    if item_page[6] is not None: 
     1617                        # show of hide the text crtl for fitting error 
     1618                        item_page[6].Show(True) 
     1619                        item_page[6].SetValue(str(item_page_info[6][1])) 
     1620                    break 
    16261621 
    16271622    def _reset_strparam_state(self, listtorestore, statelist): 
     
    17641759    def _set_multfactor_combobox(self, multiplicity=10): 
    17651760        """ 
    1766         Set comboBox for muitfactor of CoreMultiShellModel 
     1761        Set comboBox for multitfactor of CoreMultiShellModel 
    17671762        :param multiplicit: no. of multi-functionality 
    17681763        """ 
     
    18021797        Fill panel's combo box according to the type of model selected 
    18031798        """ 
    1804         custom_model = 'Customized Models' 
     1799 
    18051800        mod_cat = self.categorybox.GetStringSelection() 
    18061801        self.structurebox.SetSelection(0) 
     
    18111806        m_list = [] 
    18121807        try: 
    1813             if mod_cat == custom_model: 
     1808            if mod_cat == CUSTOM_MODEL: 
    18141809                for model in self.model_list_box[mod_cat]: 
    18151810                    m_list.append(self.model_dict[model.name]) 
     
    34573452        fills out the category list box 
    34583453        """ 
    3459         uncat_str = 'Customized Models' 
     3454        uncat_str = 'Plugin Models' 
    34603455        self._read_category_info() 
    34613456 
     
    34863481        self.model_box.Clear() 
    34873482 
    3488         if category == 'Customized Models': 
     3483        if category == 'Plugin Models': 
    34893484            for model in self.model_list_box[category]: 
    34903485                str_m = str(model).split(".")[0] 
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r24fd27a rd85f1d8a  
    2929_BOX_WIDTH = 76 
    3030_DATA_BOX_WIDTH = 300 
    31 SMEAR_SIZE_L = 0.00 
    3231SMEAR_SIZE_H = 0.00 
    33  
     32CUSTOM_MODEL = 'Plugin Models' 
    3433 
    3534class FitPage(BasicPage): 
     
    164163        On_select_data 
    165164        """ 
    166         if event is None and self.dataSource.GetCount() > 0: 
    167             data = self.dataSource.GetClientData(0) 
    168             self.set_data(data) 
    169         elif self.dataSource.GetCount() > 0: 
    170             pos = self.dataSource.GetSelection() 
     165        if self.dataSource.GetCount() > 0: 
     166            pos = self.dataSource.GetSelection() if event is not None else 0 
    171167            data = self.dataSource.GetClientData(pos) 
    172168            self.set_data(data) 
     
    213209              "Please enter only the value of interest to customize smearing..." 
    214210        smear_message_new_psmear = \ 
    215               "Please enter both; the dQ will be generated by interpolation..." 
     211              "Please enter a fixed percentage to be applied to all Q values..." 
    216212        smear_message_2d_x_title = "<dQp>[1/A]:" 
    217213        smear_message_2d_y_title = "<dQs>[1/A]:" 
    218         smear_message_pinhole_min_title = "dQ_low[1/A]:" 
    219         smear_message_pinhole_max_title = "dQ_high[1/A]:" 
     214        smear_message_pinhole_percent_title = "dQ[%]:" 
    220215        smear_message_slit_height_title = "Slit height[1/A]:" 
    221216        smear_message_slit_width_title = "Slit width[1/A]:" 
     
    256251        self.Bind(wx.EVT_RADIOBUTTON, self.onWeighting, 
    257252                  id=self.dI_idata.GetId()) 
    258         self.dI_didata.SetValue(True) 
     253        self.dI_noweight.SetValue(True) 
    259254        # add 4 types of weighting to the sizer 
    260255        sizer_weighting.Add(self.dI_noweight, 0, wx.LEFT, 10) 
     
    266261        sizer_weighting.Add(self.dI_idata) 
    267262        sizer_weighting.Add((10, 10)) 
    268         self.dI_noweight.Enable(False) 
     263        self.dI_noweight.Enable(True) 
    269264        self.dI_didata.Enable(False) 
    270265        self.dI_sqrdata.Enable(False) 
     
    310305         
    311306        # textcntrl for custom resolution 
    312         self.smear_pinhole_max = ModelTextCtrl(self, wx.ID_ANY, 
    313                             size=(_BOX_WIDTH - 25, 20), 
    314                             style=wx.TE_PROCESS_ENTER, 
    315                             text_enter_callback=self.onPinholeSmear) 
    316         self.smear_pinhole_min = ModelTextCtrl(self, wx.ID_ANY, 
    317                             size=(_BOX_WIDTH - 25, 20), 
    318                             style=wx.TE_PROCESS_ENTER, 
    319                             text_enter_callback=self.onPinholeSmear) 
     307        self.smear_pinhole_percent = ModelTextCtrl(self, wx.ID_ANY, 
     308                                                   size=(_BOX_WIDTH - 25, 20), 
     309                                                   style=wx.TE_PROCESS_ENTER, 
     310                                                   text_enter_callback= 
     311                                                   self.onPinholeSmear) 
    320312        self.smear_slit_height = ModelTextCtrl(self, wx.ID_ANY, 
    321313                            size=(_BOX_WIDTH - 25, 20), 
     
    336328 
    337329        # set default values for smear 
    338         self.smear_pinhole_max.SetValue(str(self.dx_max)) 
    339         self.smear_pinhole_min.SetValue(str(self.dx_min)) 
     330        self.smear_pinhole_percent.SetValue(str(self.dx_percent)) 
    340331        self.smear_slit_height.SetValue(str(self.dxl)) 
    341332        self.smear_slit_width.SetValue(str(self.dxw)) 
     
    362353        self.Bind(wx.EVT_RADIOBUTTON, self.onSlitSmear, 
    363354                  id=self.slit_smearer.GetId()) 
    364         self.enable_smearer.SetValue(True) 
     355        self.disable_smearer.SetValue(True) 
    365356 
    366357        sizer_smearer.Add(self.disable_smearer, 0, wx.LEFT, 10) 
     
    429420        self.smear_description_2d_y.SetToolTipString( 
    430421                                    " dQs(perpendicular) in q_phi direction.") 
    431         self.smear_description_pin_min = wx.StaticText(self, wx.ID_ANY, 
    432                         smear_message_pinhole_min_title, style=wx.ALIGN_LEFT) 
    433         self.smear_description_pin_max = wx.StaticText(self, wx.ID_ANY, 
    434                         smear_message_pinhole_max_title, style=wx.ALIGN_LEFT) 
     422        self.smear_description_pin_percent = wx.StaticText(self, wx.ID_ANY, 
     423                                            smear_message_pinhole_percent_title, 
     424                                            style=wx.ALIGN_LEFT) 
    435425        self.smear_description_slit_height = wx.StaticText(self, wx.ID_ANY, 
    436426                        smear_message_slit_height_title, style=wx.ALIGN_LEFT) 
     
    456446        self.sizer_new_smear.Add((15, -1)) 
    457447        self.sizer_new_smear.Add(self.smear_description_2d_x, 0, wx.CENTER, 10) 
    458         self.sizer_new_smear.Add(self.smear_description_pin_min, 
    459                                  0, wx.CENTER, 10) 
    460448        self.sizer_new_smear.Add(self.smear_description_slit_height, 
    461449                                 0, wx.CENTER, 10) 
    462450 
    463         self.sizer_new_smear.Add(self.smear_pinhole_min, 0, wx.CENTER, 10) 
    464451        self.sizer_new_smear.Add(self.smear_slit_height, 0, wx.CENTER, 10) 
    465452        self.sizer_new_smear.Add(self.smear_data_left, 0, wx.CENTER, 10) 
     
    467454        self.sizer_new_smear.Add(self.smear_description_2d_y, 
    468455                                 0, wx.CENTER, 10) 
    469         self.sizer_new_smear.Add(self.smear_description_pin_max, 
     456        self.sizer_new_smear.Add(self.smear_description_pin_percent, 
    470457                                 0, wx.CENTER, 10) 
    471458        self.sizer_new_smear.Add(self.smear_description_slit_width, 
    472459                                 0, wx.CENTER, 10) 
    473460 
    474         self.sizer_new_smear.Add(self.smear_pinhole_max, 0, wx.CENTER, 10) 
     461        self.sizer_new_smear.Add(self.smear_pinhole_percent, 0, wx.CENTER, 10) 
    475462        self.sizer_new_smear.Add(self.smear_slit_width, 0, wx.CENTER, 10) 
    476463        self.sizer_new_smear.Add(self.smear_data_right, 0, wx.CENTER, 10) 
     
    11901177        self.state.slit_smearer = self.slit_smearer.GetValue() 
    11911178 
    1192         self.state.structurecombobox = self.structurebox.GetLabel() 
    1193         self.state.formfactorcombobox = self.formfactorbox.GetLabel() 
     1179        self.state.structurecombobox = self.structurebox.GetValue() 
     1180        self.state.formfactorcombobox = self.formfactorbox.GetValue() 
     1181        self.state.categorycombobox = self.categorybox.GetValue() 
    11941182        self.enable_fit_button() 
    11951183        if self.model is not None: 
     
    12481236            wx.PostEvent(self.parent, new_event) 
    12491237            # update list of plugins if new plugin is available 
    1250             custom_model = 'Customized Models' 
     1238            custom_model = CUSTOM_MODEL 
    12511239            mod_cat = self.categorybox.GetStringSelection() 
    12521240            if mod_cat == custom_model: 
     
    12701258            if copy_flag: 
    12711259                self.get_paste_params(copy_flag) 
    1272                 wx.CallAfter(self._onDraw, None) 
     1260            wx.CallAfter(self._onDraw, None) 
    12731261 
    12741262        else: 
     
    15831571        if self.dxw is None: 
    15841572            self.dxw = "" 
    1585         if self.dx_min is None: 
    1586             self.dx_min = SMEAR_SIZE_L 
    1587         if self.dx_max is None: 
    1588             self.dx_max = SMEAR_SIZE_H 
     1573        if self.dx_percent is None: 
     1574            self.dx_percent = SMEAR_SIZE_H 
    15891575 
    15901576    def _get_smear_info(self): 
     
    16261612        elif data.dxl is not None or data.dxw is not None: 
    16271613            self.smear_type = "Slit" 
    1628             if data.dxl is not None and not numpy.all(data.dxl, 0): 
     1614            if data.dxl is not None and numpy.all(data.dxl, 0): 
    16291615                self.dq_l = data.dxl[0] 
    1630             if data.dxw is not None and not numpy.all(data.dxw, 0): 
     1616            if data.dxw is not None and numpy.all(data.dxw, 0): 
    16311617                self.dq_r = data.dxw[0] 
    16321618        # return self.smear_type,self.dq_l,self.dq_r 
     
    16481634            self.smear_description_2d_y.Show(True) 
    16491635            if self.pinhole_smearer.GetValue(): 
    1650                 self.smear_pinhole_min.Show(True) 
    1651                 self.smear_pinhole_max.Show(True) 
     1636                self.smear_pinhole_percent.Show(True) 
    16521637        # smear from data 
    16531638        elif self.enable_smearer.GetValue(): 
     
    16601645                    self.smear_description_slit_width.Show(True) 
    16611646                elif self.smear_type == 'Pinhole': 
    1662                     self.smear_description_pin_min.Show(True) 
    1663                     self.smear_description_pin_max.Show(True) 
     1647                    self.smear_description_pin_percent.Show(True) 
    16641648                self.smear_description_smear_type.Show(True) 
    16651649                self.smear_description_type.Show(True) 
     
    16701654            if self.smear_type == 'Pinhole': 
    16711655                self.smear_message_new_p.Show(True) 
    1672                 self.smear_description_pin_min.Show(True) 
    1673                 self.smear_description_pin_max.Show(True) 
    1674  
    1675             self.smear_pinhole_min.Show(True) 
    1676             self.smear_pinhole_max.Show(True) 
     1656                self.smear_description_pin_percent.Show(True) 
     1657 
     1658            self.smear_pinhole_percent.Show(True) 
    16771659        # custom slit smear 
    16781660        elif self.slit_smearer.GetValue(): 
     
    16991681        self.smear_data_left.Hide() 
    17001682        self.smear_data_right.Hide() 
    1701         self.smear_description_pin_min.Hide() 
    1702         self.smear_pinhole_min.Hide() 
    1703         self.smear_description_pin_max.Hide() 
    1704         self.smear_pinhole_max.Hide() 
     1683        self.smear_description_pin_percent.Hide() 
     1684        self.smear_pinhole_percent.Hide() 
    17051685        self.smear_description_slit_height.Hide() 
    17061686        self.smear_slit_height.Hide() 
     
    19331913 
    19341914            # more disables for 2D 
     1915            di_flag = False 
     1916            dq_flag = False 
    19351917            if self.data.__class__.__name__ == "Data2D" or \ 
    19361918                        self.enable2D: 
     
    19381920                self.pinhole_smearer.Enable(True) 
    19391921                self.default_mask = copy.deepcopy(self.data.mask) 
    1940                 if self.data.err_data is None or\ 
    1941                         numpy.all(err == 1 for err in self.data.err_data) or \ 
    1942                         not numpy.any(self.data.err_data): 
    1943                     self.dI_didata.Enable(False) 
    1944                     self.dI_noweight.SetValue(True) 
    1945                     self.weightbt_string = self.dI_noweight.GetLabelText() 
    1946                 else: 
    1947                     self.dI_didata.Enable(True) 
    1948                     self.dI_didata.SetValue(True) 
    1949                     self.weightbt_string = self.dI_didata.GetLabelText() 
     1922                if self.data.err_data is not None \ 
     1923                        and numpy.any(self.data.err_data): 
     1924                    di_flag = True 
     1925                if self.data.dqx_data is not None \ 
     1926                        and numpy.any(self.data.dqx_data): 
     1927                    dq_flag = True 
    19501928            else: 
    19511929                self.slit_smearer.Enable(True) 
    19521930                self.pinhole_smearer.Enable(True) 
    1953  
    1954                 if self.data.dy is None or\ 
    1955                      numpy.all(self.data.dy == 1) or\ 
    1956                      not numpy.any(self.data.dy): 
    1957                     self.dI_didata.Enable(False) 
    1958                     self.dI_noweight.SetValue(True) 
    1959                     self.weightbt_string = self.dI_noweight.GetLabelText() 
    1960                 else: 
    1961                     self.dI_didata.Enable(True) 
    1962                     self.dI_didata.SetValue(True) 
    1963                     self.weightbt_string = self.dI_didata.GetLabelText() 
     1931                if self.data.dy is not None and numpy.any(self.data.dy): 
     1932                    di_flag = True 
     1933                if self.data.dx is not None and numpy.any(self.data.dx): 
     1934                    dq_flag = True 
     1935                elif self.data.dxl is not None and numpy.any(self.data.dxl): 
     1936                    dq_flag = True 
     1937 
     1938            if dq_flag: 
     1939                self.enable_smearer.Enable(True) 
     1940                self.enable_smearer.SetValue(True) 
     1941                self.disable_smearer.SetValue(False) 
     1942            else: 
     1943                self.enable_smearer.Disable() 
     1944                self.disable_smearer.Enable(True) 
     1945                self.disable_smearer.SetValue(True) 
     1946 
     1947            if di_flag: 
     1948                self.dI_didata.Enable(True) 
     1949                self.dI_didata.SetValue(True) 
     1950                self.weightbt_string = self.dI_didata.GetLabelText() 
     1951            else: 
     1952                self.dI_didata.Enable(False) 
     1953                self.dI_noweight.SetValue(True) 
     1954                self.weightbt_string = self.dI_noweight.GetLabelText() 
     1955 
    19641956            # Enable weighting radio buttons 
    19651957            self.dI_noweight.Enable(True) 
     
    20031995            self.EditMask_title.Disable() 
    20041996 
     1997        self.on_smear_helper() 
    20051998        self.on_set_focus(None) 
    20061999        self.Refresh() 
     
    22382231            # event case of radio button 
    22392232            if tcrtl.GetValue(): 
    2240                 self.dx_min = 0.0 
    2241                 self.dx_max = 0.0 
     2233                self.dx_percent = 0.0 
    22422234                is_new_pinhole = True 
    22432235            else: 
     
    22762268        """ 
    22772269        # get the values 
    2278         pin_min = self.smear_pinhole_min.GetValue() 
    2279         pin_max = self.smear_pinhole_max.GetValue() 
    2280  
    2281         # Check changes in slit width 
     2270        pin_percent = self.smear_pinhole_percent.GetValue() 
     2271 
     2272        # Check changes in slit heigth 
    22822273        try: 
    2283             dx_min = float(pin_min) 
     2274            dx_percent = float(pin_percent) 
    22842275        except: 
    22852276            return True 
    2286         if self.dx_min != dx_min: 
    2287             return True 
    2288  
    2289         # Check changes in slit heigth 
    2290         try: 
    2291             dx_max = float(pin_max) 
    2292         except: 
    2293             return True 
    2294         if self.dx_max != dx_max: 
     2277        if self.dx_percent != dx_percent: 
    22952278            return True 
    22962279        return False 
     
    23182301        msg = None 
    23192302 
    2320         get_pin_min = self.smear_pinhole_min 
    2321         get_pin_max = self.smear_pinhole_max 
    2322  
    2323         if not check_float(get_pin_min): 
    2324             get_pin_min.SetBackgroundColour("pink") 
    2325             msg = "Model Error:wrong value entered!!!" 
    2326         elif not check_float(get_pin_max): 
    2327             get_pin_max.SetBackgroundColour("pink") 
     2303        get_pin_percent = self.smear_pinhole_percent 
     2304 
     2305        if not check_float(get_pin_percent): 
     2306            get_pin_percent.SetBackgroundColour("pink") 
    23282307            msg = "Model Error:wrong value entered!!!" 
    23292308        else: 
    23302309            if len_data < 2: 
    23312310                len_data = 2 
    2332             self.dx_min = float(get_pin_min.GetValue()) 
    2333             self.dx_max = float(get_pin_max.GetValue()) 
    2334             if self.dx_min < 0: 
    2335                 get_pin_min.SetBackgroundColour("pink") 
     2311            self.dx_percent = float(get_pin_percent.GetValue()) 
     2312            if self.dx_percent < 0: 
     2313                get_pin_percent.SetBackgroundColour("pink") 
    23362314                msg = "Model Error:This value can not be negative!!!" 
    2337             elif self.dx_max < 0: 
    2338                 get_pin_max.SetBackgroundColour("pink") 
    2339                 msg = "Model Error:This value can not be negative!!!" 
    2340             elif self.dx_min is not None and self.dx_max is not None: 
     2315            elif self.dx_percent is not None: 
     2316                percent = self.dx_percent/100 
    23412317                if self._is_2D(): 
    2342                     data.dqx_data[data.dqx_data == 0] = self.dx_min 
    2343                     data.dqy_data[data.dqy_data == 0] = self.dx_max 
    2344                 elif self.dx_min == self.dx_max: 
    2345                     data.dx[data.dx == 0] = self.dx_min 
     2318                    data.dqx_data[data.dqx_data == 0] = percent * data.qx_data 
     2319                    data.dqy_data[data.dqy_data == 0] = percent * data.qy_data 
    23462320                else: 
    2347                     step = (self.dx_max - self.dx_min) / (len_data - 1) 
    2348                     data.dx = numpy.arange(self.dx_min, 
    2349                                            self.dx_max + step / 1.1, 
    2350                                            step) 
    2351             elif self.dx_min is not None: 
    2352                 if self._is_2D(): 
    2353                     data.dqx_data[data.dqx_data == 0] = self.dx_min 
    2354                 else: 
    2355                     data.dx[data.dx == 0] = self.dx_min 
    2356             elif self.dx_max is not None: 
    2357                 if self._is_2D(): 
    2358                     data.dqy_data[data.dqy_data == 0] = self.dx_max 
    2359                 else: 
    2360                     data.dx[data.dx == 0] = self.dx_max 
     2321                    data.dx = percent * data.x 
    23612322            self.current_smearer = smear_selection(data, self.model) 
    23622323            # 2D need to set accuracy 
     
    23682329            wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
    23692330        else: 
    2370             get_pin_min.SetBackgroundColour("white") 
    2371             get_pin_max.SetBackgroundColour("white") 
     2331            get_pin_percent.SetBackgroundColour("white") 
    23722332        # set smearing value whether or not the data contain the smearing info 
    23732333 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r73cbeec r4c5098c  
    225225 
    226226        self.id_edit = wx.NewId() 
    227         editmodel_help = "Edit customized model sample file" 
    228227        self.menu1.AppendMenu(self.id_edit, "Plugin Model Operations", 
    229                               self.edit_model_menu, editmodel_help) 
     228                              self.edit_model_menu) 
    230229        #create  menubar items 
    231230        return [(self.menu1, self.sub_menu)] 
     
    260259            self.update_custom_combo() 
    261260            if os.path.isfile(p_path): 
    262                 msg = "Sorry! Could not be able to delete the default " 
    263                 msg += "custom model... \n" 
     261                msg = "Sorry! unable to delete the default " 
     262                msg += "plugin model... \n" 
    264263                msg += "Please manually remove the files (.py, .pyc) " 
    265264                msg += "in the 'plugin_models' folder \n" 
     
    274273                    if item.GetLabel() == label: 
    275274                        self.edit_menu.DeleteItem(item) 
    276                         msg = "The custom model, %s, has been deleted." % label 
     275                        msg = "The plugin model, %s, has been deleted." % label 
    277276                        evt = StatusEvent(status=msg, type='stop', info='info') 
    278277                        wx.PostEvent(self.parent, evt) 
     
    331330            temp = self.fit_panel.reset_pmodel_list() 
    332331            if temp: 
    333                 # Set the new custom model list for all fit pages 
     332                # Set the new plugin model list for all fit pages 
    334333                for uid, page in self.fit_panel.opened_pages.iteritems(): 
    335334                    if hasattr(page, "formfactorbox"): 
     
    17561755                                          data_id="Data  " + data.name + " unsmeared", 
    17571756                                          dy=unsmeared_error) 
    1758                  
    1759             if sq_model is not None and pq_model is not None: 
    1760                 self.create_theory_1D(x, sq_model, page_id, model, data, state, 
    1761                                       data_description=model.name + " S(q)", 
    1762                                       data_id=str(page_id) + " " + data.name + " S(q)") 
    1763                 self.create_theory_1D(x, pq_model, page_id, model, data, state, 
    1764                                       data_description=model.name + " P(q)", 
    1765                                       data_id=str(page_id) + " " + data.name + " P(q)") 
    1766  
     1757            # Comment this out until we can get P*S models with correctly populated parameters 
     1758            #if sq_model is not None and pq_model is not None: 
     1759            #    self.create_theory_1D(x, sq_model, page_id, model, data, state, 
     1760            #                          data_description=model.name + " S(q)", 
     1761            #                          data_id=str(page_id) + " " + data.name + " S(q)") 
     1762            #    self.create_theory_1D(x, pq_model, page_id, model, data, state, 
     1763            #                          data_description=model.name + " P(q)", 
     1764            #                          data_id=str(page_id) + " " + data.name + " P(q)") 
    17671765 
    17681766            current_pg = self.fit_panel.get_page_by_id(page_id) 
     
    19651963                ## then kill itself but cannot.  Paul Kienzle came up with 
    19661964                ## this fix to prevent threads from stepping on each other 
    1967                 ## which was causing a simple custom model to crash Sasview. 
     1965                ## which was causing a simple custom plugin model to crash 
     1966                ##Sasview. 
    19681967                ## We still don't know why the fit sometimes lauched a second 
    19691968                ## thread -- something which should also be investigated. 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    r26c8be3 r5295cf5  
    3434*  in *Single* fit mode - individual data sets are fitted independently one-by-one 
    3535 
    36 *  in *Simultaneous* fit mode - multiple data sets are fitted simultaneously to the *same* model with/without constrained parameters (this might be useful, for example, if you have measured the same sample at different contrasts) 
     36*  in *Simultaneous* fit mode - multiple data sets are fitted simultaneously to 
     37   the *same* model with/without constrained parameters (this might be useful, 
     38   for example, if you have measured the same sample at different contrasts) 
    3739 
    3840*  in *Batch* fit mode - multiple data sets are fitted sequentially to the *same* model (this might be useful, for example, if you have performed a kinetic or time-resolved experiment and have *lots* of data sets!) 
     
    4345----------------- 
    4446 
    45 By default, the models in SasView are grouped into five categories 
    46  
    47 *  *Shapes* - models describing 'objects' (spheres, cylinders, etc) 
     47The models in SasView are grouped into categories. By default these consist of: 
     48 
     49*  *Cylinder* - cylindrical shapes (disc, right cylinder, cylinder with endcaps 
     50   etc) 
     51*  *Ellipsoid* - ellipsoidal shapes (oblate,prolate, core shell, etc) 
     52*  *Parellelepiped* - as the name implies 
     53*  *Sphere* - sheroidal shapes (sphere, core multishell, vesicle, etc) 
     54*  *Lamellae* - lamellar shapes (lamellar, core shell lamellar, stacked 
     55   lamellar, etc) 
    4856*  *Shape-Independent* - models describing structure in terms of density correlation functions, fractals, peaks, power laws, etc 
    49 *  *Customized Models* - SasView- or User-created (non-library) Python models 
    50 *  *Uncategorised* - other models (for reflectivity, etc) 
     57*  *Paracrystal* - semi ordered structures (bcc, fcc, etc) 
    5158*  *Structure Factor* - S(Q) models 
     59*  *Plugin Models* - User-created (custom/non-library) Python models 
    5260 
    5361Use the *Category* drop-down menu to chose a category of model, then select 
     
    8492.. image:: cat_fig0.bmp 
    8593 
    86 The categorization of all models except the customized models can be reassigned, 
    87 added to, and removed using *Category Manager*. Models can also be hidden from view 
    88 in the drop-down menus. 
     94The categorization of all models except the user supplied Plugin Models can be 
     95reassigned, added to, and removed using *Category Manager*. Models can also be 
     96hidden from view in the drop-down menus. 
    8997 
    9098.. image:: cat_fig1.bmp 
     
    93101^^^^^^^^^^^^^^^^^ 
    94102 
    95 To change category, highlight a model in the list by left-clicking on its entry and 
    96 then click the *Modify* button. Use the *Change Category* panel that appears to make 
    97 the required changes. 
     103To change category, highlight a model in the list by left-clicking on its entry 
     104and then click the *Modify* button. Use the *Change Category* panel that appears 
     105to make the required changes. 
    98106 
    99107.. image:: cat_fig2.bmp 
     
    106114^^^^^^^^^^^^^^^^^^^^^ 
    107115 
    108 Use the *Enable All / Disable All* buttons and the check boxes beside each model to 
    109 select the models to show/hide. To apply the selection, click *Ok*. Otherwise click 
    110 *Cancel*. 
     116Use the *Enable All / Disable All* buttons and the check boxes beside each model 
     117to select the models to show/hide. To apply the selection, click *Ok*. Otherwise 
     118click *Cancel*. 
    111119 
    112120*NB: It may be necessary to change to a different category and then back again* 
     
    118126--------------- 
    119127 
    120 For a complete list of all the library models available in SasView, see the `Model Documentation <../../../index.html>`_ . 
     128For a complete list of all the library models available in SasView, see 
     129the `Model Documentation <../../../index.html>`_ . 
    121130 
    122131It is also possible to add your own models. 
     
    131140There are essentially three ways to generate new fitting models for SasView: 
    132141 
    133 * Using the SasView :ref:`New_Plugin_Model` helper dialog (best for beginners and/or relatively simple models) 
    134 * By copying/editing an existing model (this can include models generated by the *New Plugin Model* dialog) in the :ref:`Python_shell` or :ref:`Advanced_Plugin_Editor` (suitable for all use cases) 
    135 * By writing a model from scratch outside of SasView (only recommended for code monkeys!) 
     142*  Using the SasView :ref:`New_Plugin_Model` helper dialog (best for beginners 
     143   and/or relatively simple models) 
     144*  By copying/editing an existing model (this can include models generated by 
     145   the New Plugin Model* dialog) in the :ref:`Python_shell` or  
     146   :ref:`Advanced_Plugin_Editor` (suitable for all use cases) 
     147*  By writing a model from scratch outside of SasView (only recommended for code 
     148   monkeys!) 
    136149 
    137150Please read the guidance on :ref:`Writing_a_Plugin` before proceeding. 
     
    163176^^^^^^^^^^^^^^^^ 
    164177 
    165 Relatively straightforward models can be programmed directly from the SasView GUI  
    166 using the *New Plugin Model Function*. 
     178Relatively straightforward models can be programmed directly from the SasView 
     179GUI using the *New Plugin Model Function*. 
    167180 
    168181.. image:: new_model.bmp 
     
    175188*checked*\ . 
    176189 
    177 Also note that the 'Fit Parameters' have been split into two sections: those which  
    178 can be polydisperse (shape and orientation parameters) and those which are not 
    179 (eg, scattering length densities). 
     190Also note that the 'Fit Parameters' have been split into two sections: those 
     191which can be polydisperse (shape and orientation parameters) and those which are 
     192not (eg, scattering length densities). 
    180193 
    181194A model file generated by this option can be viewed and further modified using 
     
    187200.. image:: sum_model.bmp 
    188201 
    189 This option creates a custom model of the form:: 
    190  
    191      Custom Model = scale_factor \* {(scale_1 \* model_1) \+ (scale_2 \* model_2)} \+ background 
     202This option creates a custom Plugin Model of the form:: 
     203 
     204     Plugin Model = scale_factor * {(scale_1 * model_1) +/- (scale_2 * model_2)} + background 
    192205 
    193206or:: 
    194207 
    195      Custom Model = scale_factor \* model_1 \* model_2 \+ background 
     208     Plugin Model = scale_factor * model_1 /* model_2 + background 
    196209 
    197210In the *Easy Sum/Multi Editor* give the new model a function name and brief 
     
    232245Simply highlight the plugin model to be removed. The operation is final!!! 
    233246 
    234 *NB: Plugin models shipped with SasView cannot be removed in this way.* 
     247*NB: Models shipped with SasView cannot be removed in this way.* 
    235248 
    236249Load Plugin Models 
    237250^^^^^^^^^^^^^^^^^^ 
    238251 
    239 This option loads (or re-loads) all models present in the *~\\.sasview\\plugin_models* folder. 
     252This option loads (or re-loads) all models present in the 
     253*~\\.sasview\\plugin_models* folder. 
    240254 
    241255.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    400414:ref:`Assessing_Fit_Quality`. 
    401415 
    402 *NB: If you need to use a customized model, you must ensure that model is available* 
    403 *first (see* :ref:`Adding_your_own_models` *).* 
     416*NB: If you need to use a custom Plugin Model, you must ensure that model is 
     417available first (see* :ref:`Adding_your_own_models` *).* 
    404418 
    405419Method 
     
    484498If multiple data sets are in one file, load just that file. *Unselect All Data*, then 
    485499select a single initial data set to be fitted. Fit that selected data set as described 
    486 above under :ref:`Single_Fit_Mode` . 
    487  
    488 *NB: If you need to use a customized model, you must ensure that model is available* 
    489 *first (see* :ref:`Adding_your_own_models` *).* 
     500above under :ref:`Single_Fit_Mode`. 
     501 
     502*NB: If you need to use a custom Plugin Model, you must ensure that model is 
     503available first (see* :ref:`Adding_your_own_models` *).* 
    490504 
    491505Method 
  • src/sas/sasgui/perspectives/fitting/media/plugin.rst

    rca6cbc1c r984f3fc  
    2727 
    2828the next time SasView is started it will compile the plugin and add 
    29 it to the list of *Customized Models* in a FitPage. 
     29it to the list of *Plugin Models* in a FitPage. 
    3030 
    3131SasView models can be of three types: 
     
    364364  - the limits will show up as the default limits for the fit making it easy, 
    365365    for example, to force the radius to always be greater than zero. 
     366 
     367  - these are hard limits defining the valid range of parameter values; 
     368    polydisperity distributions will be truncated at the limits. 
    366369 
    367370- **"type"** can be one of: "", "sld", "volume", or "orientation". 
  • src/sas/sasgui/perspectives/fitting/model_thread.py

    rc1681ea rc1c9929  
    177177            unsmeared_output = numpy.zeros((len(self.data.x))) 
    178178            unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 
     179            self.smearer.model = self.model 
    179180            output = self.smearer(unsmeared_output, first_bin, last_bin) 
    180181 
  • src/sas/sasgui/perspectives/fitting/models.py

    r51335d7 rc5251f6  
    2323PLUGIN_LOG = os.path.join(os.path.expanduser("~"), '.sasview', PLUGIN_DIR, 
    2424                          "plugins.log") 
     25PLUGIN_NAME_BASE = '[plug-in] ' 
    2526 
    2627def get_model_python_path(): 
     
    181182            try: 
    182183                model = load_custom_model(path) 
    183                 model.name = "[plug-in] "+model.name 
     184                model.name = PLUGIN_NAME_BASE + model.name 
    184185                plugins[model.name] = model 
    185186            except Exception: 
     
    324325                    self.plugins.append(plug) 
    325326                    self.model_dictionary[name] = plug 
    326             self.model_combobox.set_list("Customized Models", self.plugins) 
     327            self.model_combobox.set_list("Plugin Models", self.plugins) 
    327328            return self.model_combobox.get_list() 
    328329        else: 
     
    345346            self.model_dictionary[name] = plug 
    346347 
    347         self.model_combobox.reset_list("Customized Models", self.plugins) 
     348        self.model_combobox.reset_list("Plugin Models", self.plugins) 
    348349        return self.model_combobox.get_list() 
    349350 
     
    388389#                                     self.shape_indep_list) 
    389390        self.model_combobox.set_list("Structure Factors", self.struct_list) 
    390         self.model_combobox.set_list("Customized Models", self.plugins) 
     391        self.model_combobox.set_list("Plugin Models", self.plugins) 
    391392        self.model_combobox.set_list("P(Q)*S(Q)", self.multiplication_factor) 
    392393        self.model_combobox.set_list("multiplication", 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    rc8e1996 r27109e5  
    2525from lxml import etree 
    2626 
     27from sasmodels import convert 
    2728import sasmodels.weights 
    2829 
     
    3233from sas.sascalc.dataloader.data_info import Data2D, Collimation, Detector 
    3334from sas.sascalc.dataloader.data_info import Process, Aperture 
     35 
    3436# Information to read/write state as xml 
    3537FITTING_NODE_NAME = 'fitting_plug_in' 
    3638CANSAS_NS = "cansas1d/1.0" 
     39 
     40CUSTOM_MODEL = 'Plugin Models' 
     41CUSTOM_MODEL_OLD = 'Customized Models' 
    3742 
    3843LIST_OF_DATA_ATTRIBUTES = [["is_data", "is_data", "bool"], 
     
    6974                            ["dq_l", "dq_l", "float"], 
    7075                            ["dq_r", "dq_r", "float"], 
    71                             ["dx_max", "dx_max", "float"], 
    72                             ["dx_min", "dx_min", "float"], 
     76                            ["dx_percent", "dx_percent", "float"], 
    7377                            ["dxl", "dxl", "float"], 
    7478                            ["dxw", "dxw", "float"]] 
     
    210214        self.dq_l = None 
    211215        self.dq_r = None 
    212         self.dx_max = None 
    213         self.dx_min = None 
     216        self.dx_percent = None 
     217        self.dx_old = False 
    214218        self.dxl = None 
    215219        self.dxw = None 
     
    271275        # store value of chisqr 
    272276        self.tcChi = None 
     277        self.version = (1,0,0) 
    273278 
    274279    def clone(self): 
     
    337342        obj.dq_l = copy.deepcopy(self.dq_l) 
    338343        obj.dq_r = copy.deepcopy(self.dq_r) 
    339         obj.dx_max = copy.deepcopy(self.dx_max) 
    340         obj.dx_min = copy.deepcopy(self.dx_min) 
     344        obj.dx_percent = copy.deepcopy(self.dx_percent) 
     345        obj.dx_old = copy.deepcopy(self.dx_old) 
    341346        obj.dxl = copy.deepcopy(self.dxl) 
    342347        obj.dxw = copy.deepcopy(self.dxw) 
     
    349354        obj.cb1 = copy.deepcopy(self.cb1) 
    350355        obj.smearer = copy.deepcopy(self.smearer) 
     356        obj.version = copy.deepcopy(self.version) 
    351357 
    352358        for name, state in self.saved_states.iteritems(): 
     
    355361            obj.saved_states[copy_name] = copy_state 
    356362        return obj 
     363 
     364    def _old_first_model(self): 
     365        """ 
     366        Handle save states from 4.0.1 and before where the first item in the 
     367        selection boxes of category, formfactor and structurefactor were not 
     368        saved. 
     369        :return: None 
     370        """ 
     371        if self.categorycombobox == CUSTOM_MODEL_OLD: 
     372            self.categorycombobox = CUSTOM_MODEL 
     373        if self.formfactorcombobox == '': 
     374            FIRST_FORM = { 
     375                'Shapes' : 'BCCrystalModel', 
     376                'Uncategorized' : 'LineModel', 
     377                'StructureFactor' : 'HardsphereStructure', 
     378                'Ellipsoid' : 'core_shell_ellipsoid', 
     379                'Lamellae' : 'lamellar', 
     380                'Paracrystal' : 'bcc_paracrystal', 
     381                'Parallelepiped' : 'core_shell_parallelepiped', 
     382                'Shape Independent' : 'be_polyelectrolyte', 
     383                'Sphere' : 'adsorbed_layer', 
     384                'Structure Factor' : 'hardsphere', 
     385                CUSTOM_MODEL : '' 
     386            } 
     387            if self.categorycombobox == '': 
     388                if len(self.parameters) == 3: 
     389                    self.categorycombobox = "Shape-Independent" 
     390                    self.formfactorcombobox = 'PowerLawAbsModel' 
     391                elif len(self.parameters) == 9: 
     392                    self.categorycombobox = 'Cylinder' 
     393                    self.formfactorcombobox = 'barbell' 
     394                else: 
     395                    msg = "Save state does not have enough information to load" 
     396                    msg += " the all of the data." 
     397                    logging.warning(msg=msg) 
     398            else: 
     399                self.formfactorcombobox = FIRST_FORM[self.categorycombobox] 
     400 
     401    @staticmethod 
     402    def param_remap_to_sasmodels_convert(params, is_string=False): 
     403        """ 
     404        Remaps the parameters for sasmodels conversion 
     405 
     406        :param params: list of parameters (likely self.parameters) 
     407        :return: remapped dictionary of parameters 
     408        """ 
     409        p = dict() 
     410        for fittable, name, value, _, uncert, lower, upper, units in params: 
     411            if not value: 
     412                value = numpy.nan 
     413            if not uncert or uncert[1] == '' or uncert[1] == 'None': 
     414                uncert[0] = False 
     415                uncert[1] = numpy.nan 
     416            if not upper or upper[1] == '' or upper[1] == 'None': 
     417                upper[0] = False 
     418                upper[1] = numpy.nan 
     419            if not lower or lower[1] == '' or lower[1] == 'None': 
     420                lower[0] = False 
     421                lower[1] = numpy.nan 
     422            if is_string: 
     423                p[name] = str(value) 
     424            else: 
     425                p[name] = float(value) 
     426            p[name + ".fittable"] = bool(fittable) 
     427            p[name + ".std"] = float(uncert[1]) 
     428            p[name + ".upper"] = float(upper[1]) 
     429            p[name + ".lower"] = float(lower[1]) 
     430            p[name + ".units"] = units 
     431        return p 
     432 
     433    @staticmethod 
     434    def param_remap_from_sasmodels_convert(params): 
     435        """ 
     436        Converts {name : value} map back to [] param list 
     437        :param params: parameter map returned from sasmodels 
     438        :return: None 
     439        """ 
     440        p_map = [] 
     441        for name, info in params.iteritems(): 
     442            if ".fittable" in name or ".std" in name or ".upper" in name or \ 
     443                            ".lower" in name or ".units" in name: 
     444                pass 
     445            else: 
     446                fittable = params.get(name + ".fittable", True) 
     447                std = params.get(name + ".std", '0.0') 
     448                upper = params.get(name + ".upper", 'inf') 
     449                lower = params.get(name + ".lower", '-inf') 
     450                units = params.get(name + ".units") 
     451                if std is not None and std is not numpy.nan: 
     452                    std = [True, str(std)] 
     453                else: 
     454                    std = [False, ''] 
     455                if lower is not None and lower is not numpy.nan: 
     456                    lower = [True, str(lower)] 
     457                else: 
     458                    lower = [True, '-inf'] 
     459                if upper is not None and upper is not numpy.nan: 
     460                    upper = [True, str(upper)] 
     461                else: 
     462                    upper = [True, 'inf'] 
     463                param_list = [bool(fittable), str(name), str(info), 
     464                              "+/-", std, lower, upper, str(units)] 
     465                p_map.append(param_list) 
     466        return p_map 
     467 
     468    def _convert_to_sasmodels(self): 
     469        """ 
     470        Convert parameters to a form usable by sasmodels converter 
     471 
     472        :return: None 
     473        """ 
     474        # Create conversion dictionary to send to sasmodels 
     475        self._old_first_model() 
     476        p = self.param_remap_to_sasmodels_convert(self.parameters) 
     477        structurefactor, params = convert.convert_model(self.structurecombobox, 
     478                                                        p, False, self.version) 
     479        formfactor, params = convert.convert_model(self.formfactorcombobox, 
     480                                                   params, False, self.version) 
     481        if len(self.str_parameters) > 0: 
     482            str_pars = self.param_remap_to_sasmodels_convert( 
     483                self.str_parameters, True) 
     484            formfactor, str_params = convert.convert_model( 
     485                self.formfactorcombobox, str_pars, False, self.version) 
     486            for key, value in str_params.iteritems(): 
     487                params[key] = value 
     488 
     489        if self.formfactorcombobox == 'SphericalSLDModel': 
     490            self.multi_factor += 1 
     491        self.formfactorcombobox = formfactor 
     492        self.structurecombobox = structurefactor 
     493        self.parameters = [] 
     494        self.parameters = self.param_remap_from_sasmodels_convert(params) 
    357495 
    358496    def _repr_helper(self, list, rep): 
     
    423561        rep += "dq_l  : %s\n" % self.dq_l 
    424562        rep += "dq_r  : %s\n" % self.dq_r 
    425         rep += "dx_max  : %s\n" % str(self.dx_max) 
    426         rep += "dx_min : %s\n" % str(self.dx_min) 
     563        rep += "dx_percent  : %s\n" % str(self.dx_percent) 
    427564        rep += "dxl  : %s\n" % str(self.dxl) 
    428565        rep += "dxw : %s\n" % str(self.dxw) 
     
    682819 
    683820        attr = newdoc.createAttribute("version") 
    684         attr.nodeValue = '1.0' 
     821        from sas import sasview 
     822        attr.nodeValue = sasview.__version__ 
     823        # attr.nodeValue = '1.0' 
    685824        top_element.setAttributeNode(attr) 
    686825 
     
    8751014            raise RuntimeError, msg 
    8761015 
    877         if node.get('version') and node.get('version') == '1.0': 
     1016        if node.get('version'): 
     1017            # Get the version for model conversion purposes 
     1018            self.version = tuple(int(e) for e in 
     1019                                 str.split(node.get('version'), ".")) 
     1020            # The tuple must be at least 3 items long 
     1021            while len(self.version) < 3: 
     1022                ver_list = list(self.version) 
     1023                ver_list.append(0) 
     1024                self.version = tuple(ver_list) 
    8781025 
    8791026            # Get file name 
     
    8991046                    setattr(self, item[0], parse_entry_helper(node, item)) 
    9001047 
     1048                dx_old_node = get_content('ns:%s' % 'dx_min', entry) 
    9011049                for item in LIST_OF_STATE_ATTRIBUTES: 
    902                     node = get_content('ns:%s' % item[0], entry) 
    903                     setattr(self, item[0], parse_entry_helper(node, item)) 
     1050                    if item[0] == "dx_percent" and dx_old_node is not None: 
     1051                        dxmin = ["dx_min", "dx_min", "float"] 
     1052                        setattr(self, item[0], parse_entry_helper(dx_old_node, 
     1053                                                                  dxmin)) 
     1054                        self.dx_old = True 
     1055                    else: 
     1056                        node = get_content('ns:%s' % item[0], entry) 
     1057                        setattr(self, item[0], parse_entry_helper(node, item)) 
    9041058 
    9051059                for item in LIST_OF_STATE_PARAMETERS: 
     
    10331187        if self.cansas: 
    10341188            return self._read_cansas(path) 
    1035  
    1036     def _data2d_to_xml_doc(self, datainfo): 
    1037         """ 
    1038         Create an XML document to contain the content of a Data2D 
    1039  
    1040         :param datainfo: Data2D object 
    1041  
    1042         """ 
    1043         if not issubclass(datainfo.__class__, Data2D): 
    1044             raise RuntimeError, "The cansas writer expects a Data2D instance" 
    1045  
    1046         title = "cansas1d/%s" % self.version 
    1047         title += "http://svn.smallangles.net/svn/canSAS/1dwg/trunk/cansas1d.xsd" 
    1048         doc = xml.dom.minidom.Document() 
    1049         main_node = doc.createElement("SASroot") 
    1050         main_node.setAttribute("version", self.version) 
    1051         main_node.setAttribute("xmlns", "cansas1d/%s" % self.version) 
    1052         main_node.setAttribute("xmlns:xsi", 
    1053                                "http://www.w3.org/2001/XMLSchema-instance") 
    1054         main_node.setAttribute("xsi:schemaLocation", title) 
    1055  
    1056         doc.appendChild(main_node) 
    1057  
    1058         entry_node = doc.createElement("SASentry") 
    1059         main_node.appendChild(entry_node) 
    1060  
    1061         write_node(doc, entry_node, "Title", datainfo.title) 
    1062         if datainfo is not None: 
    1063             write_node(doc, entry_node, "data_class", 
    1064                        datainfo.__class__.__name__) 
    1065         for item in datainfo.run: 
    1066             runname = {} 
    1067             if item in datainfo.run_name and \ 
    1068                             len(str(datainfo.run_name[item])) > 1: 
    1069                 runname = {'name': datainfo.run_name[item]} 
    1070             write_node(doc, entry_node, "Run", item, runname) 
    1071         # Data info 
    1072         new_node = doc.createElement("SASdata") 
    1073         entry_node.appendChild(new_node) 
    1074         for item in LIST_OF_DATA_2D_ATTR: 
    1075             element = doc.createElement(item[0]) 
    1076             element.setAttribute(item[0], str(getattr(datainfo, item[1]))) 
    1077             new_node.appendChild(element) 
    1078  
    1079         for item in LIST_OF_DATA_2D_VALUES: 
    1080             root_node = doc.createElement(item[0]) 
    1081             new_node.appendChild(root_node) 
    1082             temp_list = getattr(datainfo, item[1]) 
    1083  
    1084             if temp_list is None or len(temp_list) == 0: 
    1085                 element = doc.createElement(item[0]) 
    1086                 element.appendChild(doc.createTextNode(str(temp_list))) 
    1087                 root_node.appendChild(element) 
    1088             else: 
    1089                 for value in temp_list: 
    1090                     element = doc.createElement(item[0]) 
    1091                     element.setAttribute(item[0], str(value)) 
    1092                     root_node.appendChild(element) 
    1093  
    1094         # Sample info 
    1095         sample = doc.createElement("SASsample") 
    1096         if datainfo.sample.name is not None: 
    1097             sample.setAttribute("name", str(datainfo.sample.name)) 
    1098         entry_node.appendChild(sample) 
    1099         write_node(doc, sample, "ID", str(datainfo.sample.ID)) 
    1100         write_node(doc, sample, "thickness", datainfo.sample.thickness, 
    1101                    {"unit": datainfo.sample.thickness_unit}) 
    1102         write_node(doc, sample, "transmission", datainfo.sample.transmission) 
    1103         write_node(doc, sample, "temperature", datainfo.sample.temperature, 
    1104                    {"unit": datainfo.sample.temperature_unit}) 
    1105  
    1106         for item in datainfo.sample.details: 
    1107             write_node(doc, sample, "details", item) 
    1108  
    1109         pos = doc.createElement("position") 
    1110         written = write_node(doc, pos, "x", datainfo.sample.position.x, 
    1111                              {"unit": datainfo.sample.position_unit}) 
    1112         written = written | write_node(doc, pos, "y", 
    1113                                        datainfo.sample.position.y, 
    1114                                        {"unit": datainfo.sample.position_unit}) 
    1115         written = written | write_node(doc, pos, "z", 
    1116                                        datainfo.sample.position.z, 
    1117                                        {"unit": datainfo.sample.position_unit}) 
    1118         if written: 
    1119             sample.appendChild(pos) 
    1120  
    1121         ori = doc.createElement("orientation") 
    1122         written = write_node(doc, ori, "roll", datainfo.sample.orientation.x, 
    1123                              {"unit": datainfo.sample.orientation_unit}) 
    1124         written = written | write_node(doc, ori, "pitch", 
    1125                                        datainfo.sample.orientation.y, 
    1126                                        {"unit": 
    1127                                             datainfo.sample.orientation_unit}) 
    1128         written = written | write_node(doc, ori, "yaw", 
    1129                                        datainfo.sample.orientation.z, 
    1130                                        {"unit": 
    1131                                             datainfo.sample.orientation_unit}) 
    1132         if written: 
    1133             sample.appendChild(ori) 
    1134  
    1135         # Instrument info 
    1136         instr = doc.createElement("SASinstrument") 
    1137         entry_node.appendChild(instr) 
    1138  
    1139         write_node(doc, instr, "name", datainfo.instrument) 
    1140  
    1141         #   Source 
    1142         source = doc.createElement("SASsource") 
    1143         if datainfo.source.name is not None: 
    1144             source.setAttribute("name", str(datainfo.source.name)) 
    1145         instr.appendChild(source) 
    1146  
    1147         write_node(doc, source, "radiation", datainfo.source.radiation) 
    1148         write_node(doc, source, "beam_shape", datainfo.source.beam_shape) 
    1149         size = doc.createElement("beam_size") 
    1150         if datainfo.source.beam_size_name is not None: 
    1151             size.setAttribute("name", str(datainfo.source.beam_size_name)) 
    1152         written = write_node(doc, size, "x", datainfo.source.beam_size.x, 
    1153                              {"unit": datainfo.source.beam_size_unit}) 
    1154         written = written | write_node(doc, size, "y", 
    1155                                        datainfo.source.beam_size.y, 
    1156                                        {"unit": datainfo.source.beam_size_unit}) 
    1157         written = written | write_node(doc, size, "z", 
    1158                                        datainfo.source.beam_size.z, 
    1159                                        {"unit": datainfo.source.beam_size_unit}) 
    1160         if written: 
    1161             source.appendChild(size) 
    1162  
    1163         write_node(doc, source, "wavelength", datainfo.source.wavelength, 
    1164                    {"unit": datainfo.source.wavelength_unit}) 
    1165         write_node(doc, source, "wavelength_min", 
    1166                    datainfo.source.wavelength_min, 
    1167                    {"unit": datainfo.source.wavelength_min_unit}) 
    1168         write_node(doc, source, "wavelength_max", 
    1169                    datainfo.source.wavelength_max, 
    1170                    {"unit": datainfo.source.wavelength_max_unit}) 
    1171         write_node(doc, source, "wavelength_spread", 
    1172                    datainfo.source.wavelength_spread, 
    1173                    {"unit": datainfo.source.wavelength_spread_unit}) 
    1174  
    1175         #   Collimation 
    1176         for item in datainfo.collimation: 
    1177             coll = doc.createElement("SAScollimation") 
    1178             if item.name is not None: 
    1179                 coll.setAttribute("name", str(item.name)) 
    1180             instr.appendChild(coll) 
    1181  
    1182             write_node(doc, coll, "length", item.length, 
    1183                        {"unit": item.length_unit}) 
    1184  
    1185             for apert in item.aperture: 
    1186                 ap = doc.createElement("aperture") 
    1187                 if apert.name is not None: 
    1188                     ap.setAttribute("name", str(apert.name)) 
    1189                 if apert.type is not None: 
    1190                     ap.setAttribute("type", str(apert.type)) 
    1191                 coll.appendChild(ap) 
    1192  
    1193                 write_node(doc, ap, "distance", apert.distance, 
    1194                            {"unit": apert.distance_unit}) 
    1195  
    1196                 size = doc.createElement("size") 
    1197                 if apert.size_name is not None: 
    1198                     size.setAttribute("name", str(apert.size_name)) 
    1199                 written = write_node(doc, size, "x", apert.size.x, 
    1200                                      {"unit": apert.size_unit}) 
    1201                 written = written | write_node(doc, size, "y", apert.size.y, 
    1202                                                {"unit": apert.size_unit}) 
    1203                 written = written | write_node(doc, size, "z", apert.size.z, 
    1204                                                {"unit": apert.size_unit}) 
    1205                 if written: 
    1206                     ap.appendChild(size) 
    1207  
    1208         #   Detectors 
    1209         for item in datainfo.detector: 
    1210             det = doc.createElement("SASdetector") 
    1211             written = write_node(doc, det, "name", item.name) 
    1212             written = written | write_node(doc, det, "SDD", item.distance, 
    1213                                            {"unit": item.distance_unit}) 
    1214             written = written | write_node(doc, det, "slit_length", 
    1215                                            item.slit_length, 
    1216                                            {"unit": item.slit_length_unit}) 
    1217             if written: 
    1218                 instr.appendChild(det) 
    1219  
    1220             off = doc.createElement("offset") 
    1221             written = write_node(doc, off, "x", item.offset.x, 
    1222                                  {"unit": item.offset_unit}) 
    1223             written = written | write_node(doc, off, "y", item.offset.y, 
    1224                                            {"unit": item.offset_unit}) 
    1225             written = written | write_node(doc, off, "z", item.offset.z, 
    1226                                            {"unit": item.offset_unit}) 
    1227             if written: 
    1228                 det.appendChild(off) 
    1229  
    1230             center = doc.createElement("beam_center") 
    1231             written = write_node(doc, center, "x", item.beam_center.x, 
    1232                                  {"unit": item.beam_center_unit}) 
    1233             written = written | write_node(doc, center, "y", 
    1234                                            item.beam_center.y, 
    1235                                            {"unit": item.beam_center_unit}) 
    1236             written = written | write_node(doc, center, "z", 
    1237                                            item.beam_center.z, 
    1238                                            {"unit": item.beam_center_unit}) 
    1239             if written: 
    1240                 det.appendChild(center) 
    1241  
    1242             pix = doc.createElement("pixel_size") 
    1243             written = write_node(doc, pix, "x", item.pixel_size.x, 
    1244                                  {"unit": item.pixel_size_unit}) 
    1245             written = written | write_node(doc, pix, "y", item.pixel_size.y, 
    1246                                            {"unit": item.pixel_size_unit}) 
    1247             written = written | write_node(doc, pix, "z", item.pixel_size.z, 
    1248                                            {"unit": item.pixel_size_unit}) 
    1249             if written: 
    1250                 det.appendChild(pix) 
    1251  
    1252             ori = doc.createElement("orientation") 
    1253             written = write_node(doc, ori, "roll", item.orientation.x, 
    1254                                  {"unit": item.orientation_unit}) 
    1255             written = written | write_node(doc, ori, "pitch", 
    1256                                            item.orientation.y, 
    1257                                            {"unit": item.orientation_unit}) 
    1258             written = written | write_node(doc, ori, "yaw", item.orientation.z, 
    1259                                            {"unit": item.orientation_unit}) 
    1260             if written: 
    1261                 det.appendChild(ori) 
    1262  
    1263         # Processes info 
    1264         for item in datainfo.process: 
    1265             node = doc.createElement("SASprocess") 
    1266             entry_node.appendChild(node) 
    1267  
    1268             write_node(doc, node, "name", item.name) 
    1269             write_node(doc, node, "date", item.date) 
    1270             write_node(doc, node, "description", item.description) 
    1271             for term in item.term: 
    1272                 value = term['value'] 
    1273                 del term['value'] 
    1274                 write_node(doc, node, "term", value, term) 
    1275             for note in item.notes: 
    1276                 write_node(doc, node, "SASprocessnote", note) 
    1277         # Return the document, and the SASentry node associated with 
    1278         # the data we just wrote 
    1279         return doc, entry_node 
    12801189 
    12811190    def _parse_state(self, entry): 
     
    13541263        """ 
    13551264        node = dom.xpath('ns:data_class', namespaces={'ns': CANSAS_NS}) 
    1356         if not node or node[0].text.lstrip().rstrip() != "Data2D": 
    1357             return_value, _ = self._parse_entry(dom) 
    1358             numpy.trim_zeros(return_value.x) 
    1359             numpy.trim_zeros(return_value.y) 
    1360             numpy.trim_zeros(return_value.dy) 
    1361             size_dx = return_value.dx.size 
    1362             size_dxl = return_value.dxl.size 
    1363             size_dxw = return_value.dxw.size 
    1364             if size_dxl == 0 and size_dxw == 0: 
    1365                 return_value.dxl = None 
    1366                 return_value.dxw = None 
    1367                 numpy.trim_zeros(return_value.dx) 
    1368             elif size_dx == 0: 
    1369                 return_value.dx = None 
    1370                 size_dx = size_dxl 
    1371                 numpy.trim_zeros(return_value.dxl) 
    1372                 numpy.trim_zeros(return_value.dxw) 
    1373  
    1374             return return_value, _ 
    1375  
    1376         # Parse 2D 
    1377         data_info = Data2D() 
    1378  
    1379         # Look up title 
    1380         self._store_content('ns:Title', dom, 'title', data_info) 
    1381  
    1382         # Look up run number 
    1383         nodes = dom.xpath('ns:Run', namespaces={'ns': CANSAS_NS}) 
    1384         for item in nodes: 
    1385             if item.text is not None: 
    1386                 value = item.text.strip() 
    1387                 if len(value) > 0: 
    1388                     data_info.run.append(value) 
    1389                     if item.get('name') is not None: 
    1390                         data_info.run_name[value] = item.get('name') 
    1391  
    1392         # Look up instrument name 
    1393         self._store_content('ns:SASinstrument/ns:name', dom, 
    1394                             'instrument', data_info) 
    1395  
    1396         # Notes 
    1397         note_list = dom.xpath('ns:SASnote', namespaces={'ns': CANSAS_NS}) 
    1398         for note in note_list: 
    1399             try: 
    1400                 if note.text is not None: 
    1401                     note_value = note.text.strip() 
    1402                     if len(note_value) > 0: 
    1403                         data_info.notes.append(note_value) 
    1404             except Exception: 
    1405                 err_mess = "cansas_reader.read: error processing entry notes\n" 
    1406                 err_mess += "  %s" % sys.exc_value 
    1407                 self.errors.append(err_mess) 
    1408                 logging.error(err_mess) 
    1409  
    1410         # Sample info ################### 
    1411         entry = get_content('ns:SASsample', dom) 
    1412         if entry is not None: 
    1413             data_info.sample.name = entry.get('name') 
    1414  
    1415         self._store_content('ns:SASsample/ns:ID', dom, 'ID', data_info.sample) 
    1416         self._store_float('ns:SASsample/ns:thickness', dom, 'thickness', 
    1417                           data_info.sample) 
    1418         self._store_float('ns:SASsample/ns:transmission', dom, 'transmission', 
    1419                           data_info.sample) 
    1420         self._store_float('ns:SASsample/ns:temperature', dom, 'temperature', 
    1421                           data_info.sample) 
    1422  
    1423         nodes = dom.xpath('ns:SASsample/ns:details', 
    1424                           namespaces={'ns': CANSAS_NS}) 
    1425         for item in nodes: 
    1426             try: 
    1427                 if item.text is not None: 
    1428                     detail_value = item.text.strip() 
    1429                     if len(detail_value) > 0: 
    1430                         data_info.sample.details.append(detail_value) 
    1431             except Exception: 
    1432                 err_mess = "cansas_reader.read: error processing entry notes\n" 
    1433                 err_mess += "  %s" % sys.exc_value 
    1434                 self.errors.append(err_mess) 
    1435                 logging.error(err_mess) 
    1436  
    1437         # Position (as a vector) 
    1438         self._store_float('ns:SASsample/ns:position/ns:x', dom, 'position.x', 
    1439                           data_info.sample) 
    1440         self._store_float('ns:SASsample/ns:position/ns:y', dom, 'position.y', 
    1441                           data_info.sample) 
    1442         self._store_float('ns:SASsample/ns:position/ns:z', dom, 'position.z', 
    1443                           data_info.sample) 
    1444  
    1445         # Orientation (as a vector) 
    1446         self._store_float('ns:SASsample/ns:orientation/ns:roll', 
    1447                           dom, 'orientation.x', data_info.sample) 
    1448         self._store_float('ns:SASsample/ns:orientation/ns:pitch', 
    1449                           dom, 'orientation.y', data_info.sample) 
    1450         self._store_float('ns:SASsample/ns:orientation/ns:yaw', 
    1451                           dom, 'orientation.z', data_info.sample) 
    1452  
    1453         # Source info ################### 
    1454         entry = get_content('ns:SASinstrument/ns:SASsource', dom) 
    1455         if entry is not None: 
    1456             data_info.source.name = entry.get('name') 
    1457  
    1458         self._store_content('ns:SASinstrument/ns:SASsource/ns:radiation', 
    1459                             dom, 'radiation', data_info.source) 
    1460         self._store_content('ns:SASinstrument/ns:SASsource/ns:beam_shape', 
    1461                             dom, 'beam_shape', data_info.source) 
    1462         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength', 
    1463                           dom, 'wavelength', data_info.source) 
    1464         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_min', 
    1465                           dom, 'wavelength_min', data_info.source) 
    1466         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_max', 
    1467                           dom, 'wavelength_max', data_info.source) 
    1468         self._store_float('ns:SASinstrument/ns:SASsource/ns:wavelength_spread', 
    1469                           dom, 'wavelength_spread', data_info.source) 
    1470  
    1471         # Beam size (as a vector) 
    1472         entry = get_content('ns:SASinstrument/ns:SASsource/ns:beam_size', dom) 
    1473         if entry is not None: 
    1474             data_info.source.beam_size_name = entry.get('name') 
    1475  
    1476         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:x', 
    1477                           dom, 'beam_size.x', data_info.source) 
    1478         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:y', 
    1479                           dom, 'beam_size.y', data_info.source) 
    1480         self._store_float('ns:SASinstrument/ns:SASsource/ns:beam_size/ns:z', 
    1481                           dom, 'beam_size.z', data_info.source) 
    1482  
    1483         # Collimation info ################### 
    1484         nodes = dom.xpath('ns:SASinstrument/ns:SAScollimation', 
    1485                           namespaces={'ns': CANSAS_NS}) 
    1486         for item in nodes: 
    1487             collim = Collimation() 
    1488             if item.get('name') is not None: 
    1489                 collim.name = item.get('name') 
    1490             self._store_float('ns:length', item, 'length', collim) 
    1491  
    1492             # Look for apertures 
    1493             apert_list = item.xpath('ns:aperture', 
    1494                                     namespaces={'ns': CANSAS_NS}) 
    1495             for apert in apert_list: 
    1496                 aperture = Aperture() 
    1497  
    1498                 # Get the name and type of the aperture 
    1499                 aperture.name = apert.get('name') 
    1500                 aperture.type = apert.get('type') 
    1501  
    1502                 self._store_float('ns:distance', apert, 'distance', aperture) 
    1503  
    1504                 entry = get_content('ns:size', apert) 
    1505                 if entry is not None: 
    1506                     aperture.size_name = entry.get('name') 
    1507  
    1508                 self._store_float('ns:size/ns:x', apert, 'size.x', aperture) 
    1509                 self._store_float('ns:size/ns:y', apert, 'size.y', aperture) 
    1510                 self._store_float('ns:size/ns:z', apert, 'size.z', aperture) 
    1511  
    1512                 collim.aperture.append(aperture) 
    1513  
    1514             data_info.collimation.append(collim) 
    1515  
    1516         # Detector info ###################### 
    1517         nodes = dom.xpath('ns:SASinstrument/ns:SASdetector', 
    1518                           namespaces={'ns': CANSAS_NS}) 
    1519         for item in nodes: 
    1520  
    1521             detector = Detector() 
    1522  
    1523             self._store_content('ns:name', item, 'name', detector) 
    1524             self._store_float('ns:SDD', item, 'distance', detector) 
    1525  
    1526             # Detector offset (as a vector) 
    1527             self._store_float('ns:offset/ns:x', item, 'offset.x', detector) 
    1528             self._store_float('ns:offset/ns:y', item, 'offset.y', detector) 
    1529             self._store_float('ns:offset/ns:z', item, 'offset.z', detector) 
    1530  
    1531             # Detector orientation (as a vector) 
    1532             self._store_float('ns:orientation/ns:roll', item, 
    1533                               'orientation.x', detector) 
    1534             self._store_float('ns:orientation/ns:pitch', item, 
    1535                               'orientation.y', detector) 
    1536             self._store_float('ns:orientation/ns:yaw', item, 
    1537                               'orientation.z', detector) 
    1538  
    1539             # Beam center (as a vector) 
    1540             self._store_float('ns:beam_center/ns:x', item, 
    1541                               'beam_center.x', detector) 
    1542             self._store_float('ns:beam_center/ns:y', item, 
    1543                               'beam_center.y', detector) 
    1544             self._store_float('ns:beam_center/ns:z', item, 
    1545                               'beam_center.z', detector) 
    1546  
    1547             # Pixel size (as a vector) 
    1548             self._store_float('ns:pixel_size/ns:x', item, 
    1549                               'pixel_size.x', detector) 
    1550             self._store_float('ns:pixel_size/ns:y', item, 
    1551                               'pixel_size.y', detector) 
    1552             self._store_float('ns:pixel_size/ns:z', item, 
    1553                               'pixel_size.z', detector) 
    1554  
    1555             self._store_float('ns:slit_length', item, 'slit_length', detector) 
    1556  
    1557             data_info.detector.append(detector) 
    1558  
    1559         # Processes info ###################### 
    1560         nodes = dom.xpath('ns:SASprocess', namespaces={'ns': CANSAS_NS}) 
    1561         for item in nodes: 
    1562             process = Process() 
    1563             self._store_content('ns:name', item, 'name', process) 
    1564             self._store_content('ns:date', item, 'date', process) 
    1565             self._store_content('ns:description', item, 'description', process) 
    1566  
    1567             term_list = item.xpath('ns:term', namespaces={'ns': CANSAS_NS}) 
    1568             for term in term_list: 
    1569                 try: 
    1570                     term_attr = {} 
    1571                     for attr in term.keys(): 
    1572                         term_attr[attr] = term.get(attr).strip() 
    1573                     if term.text is not None: 
    1574                         term_attr['value'] = term.text.strip() 
    1575                         process.term.append(term_attr) 
    1576                 except: 
    1577                     err_mess = "cansas_reader.read: error processing " 
    1578                     err_mess += "entry notes\n  %s" % sys.exc_value 
    1579                     self.errors.append(err_mess) 
    1580                     logging.error(err_mess) 
    1581  
    1582             note_list = item.xpath('ns:SASprocessnote', 
    1583                                    namespaces={'ns': CANSAS_NS}) 
    1584             for note in note_list: 
    1585                 if note.text is not None: 
    1586                     process.notes.append(note.text.strip()) 
    1587  
    1588             data_info.process.append(process) 
    1589  
    1590         # Data info ###################### 
    1591         nodes = dom.xpath('ns:SASdata', namespaces={'ns': CANSAS_NS}) 
    1592         if len(nodes) > 1: 
    1593             raise RuntimeError, "CanSAS reader is not compatible with" + \ 
    1594                                 " multiple SASdata entries" 
    1595  
    1596         for entry in nodes: 
    1597             for item in LIST_OF_DATA_2D_ATTR: 
    1598                 # get node 
    1599                 node = get_content('ns:%s' % item[0], entry) 
    1600                 setattr(data_info, item[1], parse_entry_helper(node, item)) 
    1601  
    1602             for item in LIST_OF_DATA_2D_VALUES: 
    1603                 field = get_content('ns:%s' % item[0], entry) 
    1604                 value_list = [] 
    1605                 if field is not None: 
    1606                     value_list = \ 
    1607                         [parse_entry_helper(node, item) for node in field] 
    1608                 if len(value_list) < 2: 
    1609                     setattr(data_info, item[0], None) 
    1610                 else: 
    1611                     setattr(data_info, item[0], numpy.array(value_list)) 
    1612  
    1613         return data_info 
     1265        return_value, _ = self._parse_entry(dom) 
     1266        return return_value, _ 
    16141267 
    16151268    def _read_cansas(self, path): 
     
    16921345                        name = original_fname 
    16931346                    state.data.group_id = name 
     1347                    state.version = fitstate.version 
    16941348                    # store state in fitting 
    16951349                    self.call_back(state=state, 
     
    17451399            state.data.run_name[0] = state.data.name 
    17461400 
    1747         if issubclass(state.data.__class__, 
    1748                       sas.sascalc.dataloader.data_info.Data1D): 
    1749             data = state.data 
    1750             doc, sasentry = self._to_xml_doc(data) 
    1751         else: 
    1752             data = state.data 
    1753             doc, sasentry = self._data2d_to_xml_doc(data) 
     1401        data = state.data 
     1402        doc, sasentry = self._to_xml_doc(data) 
    17541403 
    17551404        if state is not None: 
  • src/sas/sasgui/perspectives/invariant/invariant_state.py

    rcb93b40 rdb5294e  
    423423                    for item in DEFAULT_STATE: 
    424424                        input_field = get_content('ns:%s' % item, entry) 
    425                         val = str(input_field.text.strip()) 
     425                        if input_field.text is not None: 
     426                            val = str(input_field.text.strip()) 
     427                        else: 
     428                            val = '' 
    426429                        if input_field is not None: 
    427430                            temp_state[item] = val 
     
    433436                for item in DEFAULT_STATE: 
    434437                    input_field = get_content('ns:%s' % item, entry) 
    435                     val = str(input_field.text.strip()) 
     438                    if input_field.text is not None: 
     439                        val = str(input_field.text.strip()) 
     440                    else: 
     441                        val = '' 
    436442                    if input_field is not None: 
    437443                        self.set_saved_state(name=item, value=val) 
  • src/sas/sasgui/perspectives/pr/media/pr_help.rst

    r0391dae r1221196  
    1010----------- 
    1111 
    12 This tool calculates a real-space distance distribution function, *P(r)*, using  
    13 the inversion approach (Moore, 1908). 
     12This tool calculates a real-space distance distribution function, *P(r)*, using 
     13the inversion approach (Moore, 1980). 
    1414 
    1515*P(r)* is set to be equal to an expansion of base functions of the type 
     
    2424 
    2525  \chi^2=\frac{\sum_i (I_{meas}(Q_i)-I_{th}(Q_i))^2}{error^2}+Reg\_term 
    26    
     26 
    2727 
    2828where $I_{meas}(Q_i)$ is the measured scattering intensity and $I_{th}(Q_i)$ is 
    29 the prediction from the Fourier transform of the *P(r)* expansion.  
     29the prediction from the Fourier transform of the *P(r)* expansion. 
    3030 
    31 The $Reg\_term$ term is a regularization term set to the second derivative  
     31The $Reg\_term$ term is a regularization term set to the second derivative 
    3232$d^2P(r)/d^2r$ integrated over $r$. It is used to produce a smooth *P(r)* output. 
    3333 
     
    4040 
    4141*  *Number of terms*: the number of base functions in the P(r) expansion. 
    42     
     42 
    4343*  *Regularization constant*: a multiplicative constant to set the size of 
    4444   the regularization term. 
  • src/sas/sasgui/plottools/plottables.py

    r345e7e4 ra9f579c  
    10231023    """ 
    10241024 
    1025     def __init__(self, x, y, dx=None, dy=None): 
     1025    def __init__(self, x, y, dx=None, dy=None, lam=None, dlam=None): 
    10261026        """ 
    10271027        Draw points specified by x[i],y[i] in the current color/symbol. 
     
    10371037        self.x = x 
    10381038        self.y = y 
     1039        self.lam = lam 
    10391040        self.dx = dx 
    10401041        self.dy = dy 
     1042        self.dlam = dlam 
    10411043        self.source = None 
    10421044        self.detector = None 
Note: See TracChangeset for help on using the changeset viewer.