Changeset f80b416e in sasview for src/sas/sascalc


Ignore:
Timestamp:
Sep 20, 2017 10:21:41 AM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
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, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
fca1f50
Parents:
2746eab (diff), ce0a245 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ticket-639-katex

Location:
src/sas/sascalc
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sascalc/corfunc/corfunc_calculator.py

    rff11b21 ra859f99  
    3434 
    3535        def __call__(self, x): 
    36             if self._lastx == [] or x.tolist() != self._lastx.tolist(): 
     36            # If input is a single number, evaluate the function at that number 
     37            # and return a single number 
     38            if type(x) == float or type(x) == int: 
     39                return self._smoothed_function(np.array([x]))[0] 
     40            # If input is a list, and is different to the last input, evaluate 
     41            # the function at each point. If the input is the same as last time 
     42            # the function was called, return the result that was calculated 
     43            # last time instead of explicity evaluating the function again. 
     44            elif self._lastx == [] or x.tolist() != self._lastx.tolist(): 
    3745                self._lasty = self._smoothed_function(x) 
    3846                self._lastx = x 
     
    121129        extrapolation = Data1D(qs, iqs) 
    122130 
    123         return params, extrapolation 
     131        return params, extrapolation, s2 
    124132 
    125133    def compute_transform(self, extrapolation, trans_type, background=None, 
     
    131139        :param background: The background value (if not provided, previously 
    132140            calculated value will be used) 
     141        :param extrap_fn: A callable function representing the extraoplated data 
    133142        :param completefn: The function to call when the transform calculation 
    134             is complete` 
     143            is complete 
    135144        :param updatefn: The function to call to update the GUI with the status 
    136145            of the transform calculation 
     
    144153        if trans_type == 'fourier': 
    145154            self._transform_thread = FourierThread(self._data, extrapolation, 
    146             background, completefn=completefn, updatefn=updatefn) 
     155            background, completefn=completefn, 
     156            updatefn=updatefn) 
    147157        elif trans_type == 'hilbert': 
    148158            self._transform_thread = HilbertThread(self._data, extrapolation, 
  • src/sas/sascalc/corfunc/transform_thread.py

    rd03228e ra859f99  
    22from sas.sascalc.dataloader.data_info import Data1D 
    33from scipy.fftpack import dct 
     4from scipy.integrate import trapz, cumtrapz 
    45import numpy as np 
    56from time import sleep 
     
    1314        self.extrapolation = extrapolated_data 
    1415 
     16    def check_if_cancelled(self): 
     17        if self.isquit(): 
     18            self.update("Fourier transform cancelled.") 
     19            self.complete(transforms=None) 
     20            return True 
     21        return False 
     22 
    1523    def compute(self): 
    1624        qs = self.extrapolation.x 
     
    1927        background = self.background 
    2028 
     29        xs = np.pi*np.arange(len(qs),dtype=np.float32)/(q[1]-q[0])/len(qs) 
     30 
    2131        self.ready(delay=0.0) 
    22         self.update(msg="Starting Fourier transform.") 
     32        self.update(msg="Fourier transform in progress.") 
    2333        self.ready(delay=0.0) 
    24         if self.isquit(): 
    25             return 
     34 
     35        if self.check_if_cancelled(): return 
    2636        try: 
    27             gamma = dct((iqs-background)*qs**2) 
    28             gamma = gamma / gamma.max() 
    29         except: 
     37            # ----- 1D Correlation Function ----- 
     38            gamma1 = dct((iqs-background)*qs**2) 
     39            Q = gamma1.max() 
     40            gamma1 /= Q 
     41 
     42            if self.check_if_cancelled(): return 
     43 
     44            # ----- 3D Correlation Function ----- 
     45            # gamma3(R) = 1/R int_{0}^{R} gamma1(x) dx 
     46            # trapz uses the trapezium rule to calculate the integral 
     47            mask = xs <= 200.0 # Only calculate gamma3 up to x=200 (as this is all that's plotted) 
     48            # gamma3 = [trapz(gamma1[:n], xs[:n])/xs[n-1] for n in range(2, len(xs[mask]) + 1)]j 
     49            # gamma3.insert(0, 1.0) # Gamma_3(0) is defined as 1 
     50            n = len(xs[mask]) 
     51            gamma3 = cumtrapz(gamma1[:n], xs[:n])/xs[1:n] 
     52            gamma3 = np.hstack((1.0, gamma3)) # Gamma_3(0) is defined as 1 
     53 
     54            if self.check_if_cancelled(): return 
     55 
     56            # ----- Interface Distribution function ----- 
     57            idf = dct(-qs**4 * (iqs-background)) 
     58 
     59            if self.check_if_cancelled(): return 
     60 
     61            # Manually calculate IDF(0.0), since scipy DCT tends to give us a 
     62            # very large negative value. 
     63            # IDF(x) = int_0^inf q^4 * I(q) * cos(q*x) * dq 
     64            # => IDF(0) = int_0^inf q^4 * I(q) * dq 
     65            idf[0] = trapz(-qs**4 * (iqs-background), qs) 
     66            idf /= Q # Normalise using scattering invariant 
     67 
     68        except Exception as e: 
     69            import logging 
     70            logger = logging.getLogger(__name__) 
     71            logger.error(e) 
     72 
    3073            self.update(msg="Fourier transform failed.") 
    31             self.complete(transform=None) 
     74            self.complete(transforms=None) 
    3275            return 
    3376        if self.isquit(): 
     
    3578        self.update(msg="Fourier transform completed.") 
    3679 
    37         xs = np.pi*np.arange(len(qs),dtype=np.float32)/(q[1]-q[0])/len(qs) 
    38         transform = Data1D(xs, gamma) 
     80        transform1 = Data1D(xs, gamma1) 
     81        transform3 = Data1D(xs[xs <= 200], gamma3) 
     82        idf = Data1D(xs, idf) 
    3983 
    40         self.complete(transform=transform) 
     84        transforms = (transform1, transform3, idf) 
     85 
     86        self.complete(transforms=transforms) 
    4187 
    4288class HilbertThread(CalcThread): 
     
    64110        self.update(msg="Hilbert transform completed.") 
    65111 
    66         self.complete(transform=None) 
     112        self.complete(transforms=None) 
  • src/sas/sascalc/dataloader/file_reader_base_class.py

    ra78a02f rae69c690  
    115115                data.y = np.asarray([data.y[i] for i in ind]).astype(np.float64) 
    116116                if data.dx is not None: 
     117                    if len(data.dx) == 0: 
     118                        data.dx = None 
     119                        continue 
    117120                    data.dx = np.asarray([data.dx[i] for i in ind]).astype(np.float64) 
    118121                if data.dxl is not None: 
     
    121124                    data.dxw = np.asarray([data.dxw[i] for i in ind]).astype(np.float64) 
    122125                if data.dy is not None: 
     126                    if len(data.dy) == 0: 
     127                        data.dy = None 
     128                        continue 
    123129                    data.dy = np.asarray([data.dy[i] for i in ind]).astype(np.float64) 
    124130                if data.lam is not None: 
     
    185191        self.output = [] 
    186192 
    187     def remove_empty_q_values(self, has_error_dx=False, has_error_dy=False): 
     193    def remove_empty_q_values(self, has_error_dx=False, has_error_dy=False, 
     194                              has_error_dxl=False, has_error_dxw=False): 
    188195        """ 
    189196        Remove any point where Q == 0 
     
    192199        self.current_dataset.x = self.current_dataset.x[x != 0] 
    193200        self.current_dataset.y = self.current_dataset.y[x != 0] 
    194         self.current_dataset.dy = self.current_dataset.dy[x != 0] if \ 
    195             has_error_dy else np.zeros(len(self.current_dataset.y)) 
    196         self.current_dataset.dx = self.current_dataset.dx[x != 0] if \ 
    197             has_error_dx else np.zeros(len(self.current_dataset.x)) 
     201        if has_error_dy: 
     202            self.current_dataset.dy = self.current_dataset.dy[x != 0] 
     203        if has_error_dx: 
     204            self.current_dataset.dx = self.current_dataset.dx[x != 0] 
     205        if has_error_dxl: 
     206            self.current_dataset.dxl = self.current_dataset.dxl[x != 0] 
     207        if has_error_dxw: 
     208            self.current_dataset.dxw = self.current_dataset.dxw[x != 0] 
    198209 
    199210    def reset_data_list(self, no_lines=0): 
     
    204215        x = np.zeros(no_lines) 
    205216        y = np.zeros(no_lines) 
     217        dx = np.zeros(no_lines) 
    206218        dy = np.zeros(no_lines) 
    207         dx = np.zeros(no_lines) 
    208219        self.current_dataset = plottable_1D(x, y, dx, dy) 
    209220 
  • src/sas/sascalc/dataloader/readers/cansas_reader.py

    ra78a02f rae69c690  
    130130                self.current_datainfo.meta_data[PREPROCESS] = self.processing_instructions 
    131131                self._parse_entry(entry) 
    132                 has_error_dx = self.current_dataset.dx is not None 
    133                 has_error_dy = self.current_dataset.dy is not None 
    134                 self.remove_empty_q_values(has_error_dx=has_error_dx, 
    135                     has_error_dy=has_error_dy) 
    136                 self.send_to_output() # Combine datasets with DataInfo 
    137                 self.current_datainfo = DataInfo() # Reset DataInfo 
     132                self.data_cleanup() 
    138133        except FileContentsException as fc_exc: 
    139134            # File doesn't meet schema - try loading with a less strict schema 
     
    154149                    self.load_file_and_schema(xml_file) # Reload strict schema so we can find where error are in file 
    155150                    invalid_xml = self.find_invalid_xml() 
    156                     invalid_xml = INVALID_XML.format(basename + self.extension) + invalid_xml 
    157                     raise DataReaderException(invalid_xml) # Handled by base class 
     151                    if invalid_xml != "": 
     152                        invalid_xml = INVALID_XML.format(basename + self.extension) + invalid_xml 
     153                        raise DataReaderException(invalid_xml) # Handled by base class 
    158154                except FileContentsException as fc_exc: 
    159155                    msg = "CanSAS Reader could not load the file {}".format(xml_file) 
     
    279275                # I and Q points 
    280276                elif tagname == 'I' and isinstance(self.current_dataset, plottable_1D): 
    281                     unit_list = unit.split("|") 
    282                     if len(unit_list) > 1: 
    283                         self.current_dataset.yaxis(unit_list[0].strip(), 
    284                                                    unit_list[1].strip()) 
    285                     else: 
    286                         self.current_dataset.yaxis("Intensity", unit) 
     277                    self.current_dataset.yaxis("Intensity", unit) 
    287278                    self.current_dataset.y = np.append(self.current_dataset.y, data_point) 
    288279                elif tagname == 'Idev' and isinstance(self.current_dataset, plottable_1D): 
    289280                    self.current_dataset.dy = np.append(self.current_dataset.dy, data_point) 
    290281                elif tagname == 'Q': 
    291                     unit_list = unit.split("|") 
    292                     if len(unit_list) > 1: 
    293                         self.current_dataset.xaxis(unit_list[0].strip(), 
    294                                                    unit_list[1].strip()) 
    295                     else: 
    296                         self.current_dataset.xaxis("Q", unit) 
     282                    self.current_dataset.xaxis("Q", unit) 
    297283                    self.current_dataset.x = np.append(self.current_dataset.x, data_point) 
    298284                elif tagname == 'Qdev': 
    299285                    self.current_dataset.dx = np.append(self.current_dataset.dx, data_point) 
    300286                elif tagname == 'dQw': 
    301                     if self.current_dataset.dxw is None: 
    302                         self.current_dataset.dxw = np.empty(0) 
    303                     self.current_dataset.dxw = np.append(self.current_dataset.dxw, data_point) 
     287                   self.current_dataset.dxw = np.append(self.current_dataset.dxw, data_point) 
    304288                elif tagname == 'dQl': 
    305                     if self.current_dataset.dxl is None: 
    306                         self.current_dataset.dxl = np.empty(0) 
    307289                    self.current_dataset.dxl = np.append(self.current_dataset.dxl, data_point) 
    308290                elif tagname == 'Qmean': 
     
    312294                elif tagname == 'Sesans': 
    313295                    self.current_datainfo.isSesans = bool(data_point) 
     296                    self.current_dataset.xaxis(attr.get('x_axis'), 
     297                                                attr.get('x_unit')) 
     298                    self.current_dataset.yaxis(attr.get('y_axis'), 
     299                                                attr.get('y_unit')) 
    314300                elif tagname == 'yacceptance': 
    315301                    self.current_datainfo.sample.yacceptance = (data_point, unit) 
     
    512498            for error in self.errors: 
    513499                self.current_datainfo.errors.add(error) 
    514             self.errors.clear() 
    515             self.send_to_output() 
     500            self.data_cleanup() 
     501            self.sort_one_d_data() 
     502            self.sort_two_d_data() 
     503            self.reset_data_list() 
    516504            empty = None 
    517505            return self.output[0], empty 
     506 
     507    def data_cleanup(self): 
     508        """ 
     509        Clean up the data sets and refresh everything 
     510        :return: None 
     511        """ 
     512        has_error_dx = self.current_dataset.dx is not None 
     513        has_error_dxl = self.current_dataset.dxl is not None 
     514        has_error_dxw = self.current_dataset.dxw is not None 
     515        has_error_dy = self.current_dataset.dy is not None 
     516        self.remove_empty_q_values(has_error_dx=has_error_dx, 
     517                                   has_error_dxl=has_error_dxl, 
     518                                   has_error_dxw=has_error_dxw, 
     519                                   has_error_dy=has_error_dy) 
     520        self.send_to_output()  # Combine datasets with DataInfo 
     521        self.current_datainfo = DataInfo()  # Reset DataInfo 
    518522 
    519523    def _is_call_local(self): 
     
    642646                    value_unit = local_unit 
    643647            except KeyError: 
    644                 err_msg = "CanSAS reader: unexpected " 
    645                 err_msg += "\"{0}\" unit [{1}]; " 
    646                 err_msg = err_msg.format(tagname, local_unit) 
    647                 err_msg += "expecting [{0}]".format(default_unit) 
     648                # Do not throw an error for loading Sesans data in cansas xml 
     649                # This is a temporary fix. 
     650                if local_unit != "A" and local_unit != 'pol': 
     651                    err_msg = "CanSAS reader: unexpected " 
     652                    err_msg += "\"{0}\" unit [{1}]; " 
     653                    err_msg = err_msg.format(tagname, local_unit) 
     654                    err_msg += "expecting [{0}]".format(default_unit) 
    648655                value_unit = local_unit 
    649656            except: 
     
    675682            di_exists = True 
    676683        if dqw_exists and not dql_exists: 
    677             array_size = self.current_dataset.dxw.size - 1 
    678             self.current_dataset.dxl = np.append(self.current_dataset.dxl, 
    679                                                  np.zeros([array_size])) 
     684            array_size = self.current_dataset.dxw.size 
     685            self.current_dataset.dxl = np.zeros(array_size) 
    680686        elif dql_exists and not dqw_exists: 
    681             array_size = self.current_dataset.dxl.size - 1 
    682             self.current_dataset.dxw = np.append(self.current_dataset.dxw, 
    683                                                  np.zeros([array_size])) 
     687            array_size = self.current_dataset.dxl.size 
     688            self.current_dataset.dxw = np.zeros(array_size) 
    684689        elif not dql_exists and not dqw_exists and not dq_exists: 
    685             array_size = self.current_dataset.x.size - 1 
     690            array_size = self.current_dataset.x.size 
    686691            self.current_dataset.dx = np.append(self.current_dataset.dx, 
    687692                                                np.zeros([array_size])) 
    688693        if not di_exists: 
    689             array_size = self.current_dataset.y.size - 1 
     694            array_size = self.current_dataset.y.size 
    690695            self.current_dataset.dy = np.append(self.current_dataset.dy, 
    691696                                                np.zeros([array_size])) 
     
    857862            node.append(point) 
    858863            self.write_node(point, "Q", datainfo.x[i], 
    859                             {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
     864                            {'unit': datainfo.x_unit}) 
    860865            if len(datainfo.y) >= i: 
    861866                self.write_node(point, "I", datainfo.y[i], 
    862                                 {'unit': datainfo._yaxis + " | " + datainfo._yunit}) 
     867                                {'unit': datainfo.y_unit}) 
    863868            if datainfo.dy is not None and len(datainfo.dy) > i: 
    864869                self.write_node(point, "Idev", datainfo.dy[i], 
    865                                 {'unit': datainfo._yaxis + " | " + datainfo._yunit}) 
     870                                {'unit': datainfo.y_unit}) 
    866871            if datainfo.dx is not None and len(datainfo.dx) > i: 
    867872                self.write_node(point, "Qdev", datainfo.dx[i], 
    868                                 {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
     873                                {'unit': datainfo.x_unit}) 
    869874            if datainfo.dxw is not None and len(datainfo.dxw) > i: 
    870875                self.write_node(point, "dQw", datainfo.dxw[i], 
    871                                 {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
     876                                {'unit': datainfo.x_unit}) 
    872877            if datainfo.dxl is not None and len(datainfo.dxl) > i: 
    873878                self.write_node(point, "dQl", datainfo.dxl[i], 
    874                                 {'unit': datainfo._xaxis + " | " + datainfo._xunit}) 
     879                                {'unit': datainfo.x_unit}) 
    875880        if datainfo.isSesans: 
    876             sesans = self.create_element("Sesans") 
     881            sesans_attrib = {'x_axis': datainfo._xaxis, 
     882                             'y_axis': datainfo._yaxis, 
     883                             'x_unit': datainfo.x_unit, 
     884                             'y_unit': datainfo.y_unit} 
     885            sesans = self.create_element("Sesans", attrib=sesans_attrib) 
    877886            sesans.text = str(datainfo.isSesans) 
    878             node.append(sesans) 
    879             self.write_node(node, "yacceptance", datainfo.sample.yacceptance[0], 
     887            entry_node.append(sesans) 
     888            self.write_node(entry_node, "yacceptance", datainfo.sample.yacceptance[0], 
    880889                             {'unit': datainfo.sample.yacceptance[1]}) 
    881             self.write_node(node, "zacceptance", datainfo.sample.zacceptance[0], 
     890            self.write_node(entry_node, "zacceptance", datainfo.sample.zacceptance[0], 
    882891                             {'unit': datainfo.sample.zacceptance[1]}) 
    883892 
  • src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py

    rdcb91cf rcd57c7d4  
    140140 
    141141            if isinstance(value, h5py.Group): 
     142                # Set parent class before recursion 
    142143                self.parent_class = class_name 
    143144                parent_list.append(key) 
     
    150151                # Recursion step to access data within the group 
    151152                self.read_children(value, parent_list) 
     153                # Reset parent class when returning from recursive method 
     154                self.parent_class = class_name 
    152155                self.add_intermediate() 
    153156                parent_list.remove(key) 
  • src/sas/sascalc/dataloader/readers/xml_reader.py

    rfafe52a rcd57c7d4  
    134134            first_error = schema.assertValid(self.xmldoc) 
    135135        except etree.DocumentInvalid as err: 
     136            # Suppress errors for <'any'> elements 
     137            if "##other" in str(err): 
     138                return first_error 
    136139            first_error = str(err) 
    137140        return first_error 
  • src/sas/sascalc/invariant/invariant.py

    r7432acb rb1f20d1  
    610610        # Data boundaries for fitting 
    611611        qmin = self._data.x[0] 
    612         qmax = self._data.x[self._low_extrapolation_npts - 1] 
     612        qmax = self._data.x[int(self._low_extrapolation_npts - 1)] 
    613613 
    614614        # Extrapolate the low-Q data 
     
    649649        # Data boundaries for fitting 
    650650        x_len = len(self._data.x) - 1 
    651         qmin = self._data.x[x_len - (self._high_extrapolation_npts - 1)] 
    652         qmax = self._data.x[x_len] 
     651        qmin = self._data.x[int(x_len - (self._high_extrapolation_npts - 1))] 
     652        qmax = self._data.x[int(x_len)] 
    653653 
    654654        # fit the data with a model to get the appropriate parameters 
     
    688688        if npts_in is None: 
    689689            npts_in = self._low_extrapolation_npts 
    690         q_end = self._data.x[max(0, npts_in - 1)] 
     690        q_end = self._data.x[max(0, int(npts_in - 1))] 
    691691 
    692692        if q_start >= q_end: 
     
    714714        # Get extrapolation range 
    715715        if npts_in is None: 
    716             npts_in = self._high_extrapolation_npts 
     716            npts_in = int(self._high_extrapolation_npts) 
    717717        _npts = len(self._data.x) 
    718         q_start = self._data.x[min(_npts, _npts - npts_in)] 
     718        q_start = self._data.x[min(_npts, int(_npts - npts_in))] 
    719719 
    720720        if q_start >= q_end: 
  • src/sas/sascalc/calculator/sas_gen.py

    ra1b8fee rf2ea95a  
    913913    def set_sldms(self, sld_mx, sld_my, sld_mz): 
    914914        r""" 
    915         Sets (\|m\|, m_theta, m_phi) 
    916         """ 
     915        Sets mx, my, mz and abs(m). 
     916        """ # Note: escaping 
    917917        if sld_mx.__class__.__name__ == 'float': 
    918918            self.sld_mx = np.ones(len(self.pos_x)) * sld_mx 
  • src/sas/sascalc/realspace/__init__.py

    r959eb01 rf2ea95a  
    11""" 
    22    Real-Space Modeling for SAS 
    3 """  
     3""" 
    44## \mainpage Real-Space Modeling for SAS 
    55# 
    66# \section intro_sec Introduction 
    7 # This module provides SAS scattering intensity simulation  
     7# This module provides SAS scattering intensity simulation 
    88# based on real-space modeling. 
    99# 
    10 # Documentation can be found here:  
     10# Documentation can be found here: 
    1111#    http://danse.us/trac/sas/wiki/RealSpaceModeling 
    1212# 
     
    3737# 
    3838# \section overview_sec Package Overview 
    39 #  
     39# 
    4040# \subsection class Class Diagram: 
    4141# \image html real-space-class-diagram.png 
    4242# 
    4343# \subsection behav Behavior Enumeration: 
    44 # \image html enum.gif 
     44# \image html enum.png 
    4545# 
    4646# \subsection Tutorial 
     
    7878# \section help_sec Contact Info 
    7979# Code and Documentation by Jing Zhou as part of the DANSE project. 
    80  
Note: See TracChangeset for help on using the changeset viewer.