Changeset 8d3d20a in sasview for src


Ignore:
Timestamp:
Oct 6, 2016 12:35:24 PM (8 years ago)
Author:
GitHub <noreply@…>
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.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
4c3be25
Parents:
0639476 (diff), e32e35a (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.
git-author:
Andrew Jackson <andrew.jackson@…> (10/06/16 12:35:24)
git-committer:
GitHub <noreply@…> (10/06/16 12:35:24)
Message:

Merge pull request #11 from SasView?/corfunc

Implement Correlation Function Perspective

Location:
src/sas
Files:
33 added
28 edited

Legend:

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

    rd85c194 r6ffa0dd  
    88# plot Qrange 
    99(PlotQrangeEvent, EVT_PLOT_QRANGE) = wx.lib.newevent.NewEvent() 
     10# set plot limits 
     11(PlotLimitEvent, EVT_PLOT_LIM) = wx.lib.newevent.NewEvent() 
    1012# print the messages on statusbar 
    1113(StatusEvent,  EVT_STATUS)   = wx.lib.newevent.NewEvent() 
    12 #create a panel slicer  
     14#create a panel slicer 
    1315(SlicerPanelEvent, EVT_SLICER_PANEL)   = wx.lib.newevent.NewEvent() 
    14 #print update paramaters for panel slicer  
     16#print update paramaters for panel slicer 
    1517(SlicerParamUpdateEvent, EVT_SLICER_PARS_UPDATE)   = wx.lib.newevent.NewEvent() 
    16 #update the slicer from the panel  
     18#update the slicer from the panel 
    1719(SlicerParameterEvent, EVT_SLICER_PARS)   = wx.lib.newevent.NewEvent() 
    1820#slicer event 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py

    r895c9cb r245ae18  
    9595        self.parent.SetFocus() 
    9696 
     97        # If true, there are 3 qrange bars 
     98        self.is_corfunc = False 
     99 
    97100 
    98101    def get_symbol_label(self): 
     
    214217        if active_ctrl == None: 
    215218            return 
     219        if hasattr(event, 'is_corfunc'): 
     220            self.is_corfunc = event.is_corfunc 
    216221        if event.id in self.plots.keys(): 
    217222            ctrl = event.ctrl 
     
    222227            values = [max(x_data.min(), float(ctrl[0].GetValue())), 
    223228                      min(x_data.max(), float(ctrl[1].GetValue()))] 
     229            if len(ctrl) == 3: 
     230                colors.append('purple') 
     231                values.append(min(x_data.max(), float(ctrl[2].GetValue()))) 
    224232            if self.ly == None: 
    225233                self.ly = [] 
     
    232240                xval = float(active_ctrl.GetValue()) 
    233241                position = self.get_data_xy_vals(xval) 
    234                 if position != None: 
     242                if position != None and not self.is_corfunc: 
    235243                    wx.PostEvent(self.parent, StatusEvent(status=position)) 
    236244            except: 
     
    293301        ly0x = ly[0].get_xdata() 
    294302        ly1x = ly[1].get_xdata() 
     303        ly2x = None 
     304        if self.is_corfunc: ly2x = ly[2].get_xdata() 
    295305        self.q_ctrl[0].SetBackgroundColour('white') 
    296306        self.q_ctrl[1].SetBackgroundColour('white') 
     
    306316                self.q_ctrl[0].SetValue(str(pos_x)) 
    307317                self.q_ctrl[1].SetBackgroundColour('pink') 
     318        elif ly2x is not None and ly1x >= ly2x: 
     319            if self.vl_ind == 1: 
     320                ly[2].set_xdata(posx) 
     321                ly[2].set_zorder(nop) 
     322                self.q_ctrl[2].SetValue(str(pos_x)) 
     323            elif self.vl_ind == 2: 
     324                ly[1].set_xdata(posx) 
     325                ly[1].set_zorder(nop) 
     326                self.q_ctrl[1].SetValue(str(pos_x)) 
     327 
    308328 
    309329    def _get_cusor_lines(self, event): 
     
    325345            dqmin = math.fabs(event.xdata - self.ly[0].get_xdata()) 
    326346            dqmax = math.fabs(event.xdata - self.ly[1].get_xdata()) 
    327             is_qmax = dqmin > dqmax 
    328             if is_qmax: 
    329                 self.vl_ind = 1 
     347            if not self.is_corfunc: 
     348                is_qmax = dqmin > dqmax 
     349                if is_qmax: 
     350                    self.vl_ind = 1 
     351                else: 
     352                    self.vl_ind = 0 
    330353            else: 
    331                 self.vl_ind = 0 
     354                dqmax2 = math.fabs(event.xdata - self.ly[2].get_xdata()) 
     355                closest = min(dqmin, dqmax, dqmax2) 
     356                self.vl_ind = { dqmin: 0, dqmax: 1, dqmax2: 2 }.get(closest) 
    332357 
    333358    def cusor_line(self, event): 
  • src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py

    rd85c194 r6ffa0dd  
    1616from sas.sasgui.guiframe.events import EVT_NEW_PLOT 
    1717from sas.sasgui.guiframe.events import EVT_PLOT_QRANGE 
     18from sas.sasgui.guiframe.events import EVT_PLOT_LIM 
    1819from sas.sasgui.guiframe.events import DeletePlotPanelEvent 
    1920from sas.sasgui.guiframe.plugin_base import PluginBase 
     
    7980        self.parent.Bind(EVT_NEW_PLOT, self._on_plot_event) 
    8081        self.parent.Bind(EVT_PLOT_QRANGE, self._on_plot_qrange) 
     82        self.parent.Bind(EVT_PLOT_LIM, self._on_plot_lim) 
    8183        # We have no initial panels for this plug-in 
    8284        return [] 
     
    9597            return 
    9698        panel.on_plot_qrange(event) 
     99 
     100    def _on_plot_lim(self, event=None): 
     101        if event == None: 
     102            return 
     103        if event.id in self.plot_panels.keys(): 
     104            panel = self.plot_panels[event.id] 
     105        elif event.group_id in self.plot_panels.keys(): 
     106            panel = self.plot_panels[event.group_id] 
     107        else: 
     108            return 
     109        if hasattr(event, 'xlim'): 
     110            panel.subplot.set_xlim(event.xlim) 
     111        if hasattr(event, 'ylim'): 
     112            panel.subplot.set_ylim(event.ylim) 
     113 
    97114 
    98115    def _on_show_panel(self, event): 
     
    312329                new_panel = self.create_2d_panel(data, group_id) 
    313330            self.create_panel_helper(new_panel, data, group_id, title) 
     331            if hasattr(event, 'xlim'): 
     332                new_panel.subplot.set_xlim(event.xlim) 
     333            if hasattr(event, 'ylim'): 
     334                new_panel.subplot.set_ylim(event.ylim) 
    314335        return 
  • src/sas/sascalc/dataloader/readers/anton_paar_saxs_reader.py

    r80c5d46 ra235f715  
    4545    output = None 
    4646 
    47     def __init__(self): 
     47    def reset_state(self): 
    4848        self.current_dataset = Data1D(np.empty(0), np.empty(0), 
    4949                                            np.empty(0), np.empty(0)) 
     
    7272 
    7373        ## Reinitialize the class when loading a new data file to reset all class variables 
    74         self.__init__() 
     74        self.reset_state() 
    7575        ## Check that the file exists 
    7676        if os.path.isfile(filename): 
     
    8484                self.raw_data = buff.splitlines() 
    8585                self.read_data() 
    86                 xml_intermediate = self.raw_data[self.upper:] 
    87                 xml = ''.join(xml_intermediate) 
    88                 self.set_xml_file(xml) 
    8986        return self.output 
    9087 
     
    10097        self.lower = 5 
    10198        self.upper = self.lower + self.data_points 
    102         self.detector.distance = float(line4[1]) 
     99        self.source.radiation = 'x-ray' 
     100        normal = float(line4[3]) 
    103101        self.current_dataset.source.radiation = "x-ray" 
    104102        self.current_dataset.source.name = "Anton Paar SAXSess Instrument" 
    105103        self.current_dataset.source.wavelength = float(line4[4]) 
    106         normal = line4[3] 
     104        xvals = [] 
     105        yvals = [] 
     106        dyvals = [] 
    107107        for i in range(self.lower, self.upper): 
     108            index = i - self.lower 
    108109            data = self.raw_data[i].split() 
    109             x_val = [float(data[0])] 
    110             y_val = [float(data[1])] 
    111             dy_val = [float(data[2])] 
    112             self.current_dataset.x = np.append(self.current_dataset.x, x_val) 
    113             self.current_dataset.y = np.append(self.current_dataset.y, y_val) 
    114             self.current_dataset.dy = np.append(self.current_dataset.dy, dy_val) 
    115         self.current_dataset.xaxis("Q (%s)" % (q_unit), q_unit) 
    116         self.current_dataset.yaxis("Intensity (%s)" % (i_unit), i_unit) 
    117         self.current_dataset.detector.append(self.detector) 
     110            xvals.insert(index, normal * float(data[0])) 
     111            yvals.insert(index, normal * float(data[1])) 
     112            dyvals.insert(index, normal * float(data[2])) 
     113        self.current_dataset.x = np.append(self.current_dataset.x, xvals) 
     114        self.current_dataset.y = np.append(self.current_dataset.y, yvals) 
     115        self.current_dataset.dy = np.append(self.current_dataset.dy, dyvals) 
     116        if self.data_points != self.current_dataset.x.size: 
     117            self.errors.add("Not all data was loaded properly.") 
     118        if self.current_dataset.dx.size != self.current_dataset.x.size: 
     119            dxvals = np.zeros(self.current_dataset.x.size) 
     120            self.current_dataset.dx = dxvals 
     121        if self.current_dataset.x.size != self.current_dataset.y.size: 
     122            self.errors.add("The x and y data sets are not the same size.") 
     123        if self.current_dataset.y.size != self.current_dataset.dy.size: 
     124            self.errors.add("The y and dy datasets are not the same size.") 
     125        self.current_dataset.errors = self.errors 
     126        self.current_dataset.xaxis("Q", q_unit) 
     127        self.current_dataset.yaxis("Intensity", i_unit) 
     128        xml_intermediate = self.raw_data[self.upper:] 
     129        xml = ''.join(xml_intermediate) 
     130        self.set_xml_string(xml) 
     131        dom = self.xmlroot.xpath('/fileinfo') 
     132        self._parse_child(dom) 
    118133        self.output.append(self.current_dataset) 
     134 
     135    def _parse_child(self, dom, parent=''): 
     136        """ 
     137        Recursive method for stepping through the embedded XML 
     138        :param dom: XML node with or without children 
     139        """ 
     140        for node in dom: 
     141            tagname = node.tag 
     142            value = node.text 
     143            attr = node.attrib 
     144            key = attr.get("key", '') 
     145            if len(node.getchildren()) > 1: 
     146                self._parse_child(node, key) 
     147                if key == "SampleDetector": 
     148                    self.current_dataset.detector.append(self.detector) 
     149                    self.detector = Detector() 
     150            else: 
     151                if key == "value": 
     152                    if parent == "Wavelength": 
     153                        self.current_dataset.source.wavelength = value 
     154                    elif parent == "SampleDetector": 
     155                        self.detector.distance = value 
     156                    elif parent == "Temperature": 
     157                        self.current_dataset.sample.temperature = value 
     158                    elif parent == "CounterSlitLength": 
     159                        self.detector.slit_length = value 
     160                elif key == "unit": 
     161                    value = value.replace("_", "") 
     162                    if parent == "Wavelength": 
     163                        self.current_dataset.source.wavelength_unit = value 
     164                    elif parent == "SampleDetector": 
     165                        self.detector.distance_unit = value 
     166                    elif parent == "X": 
     167                        self.current_dataset.xaxis(self.current_dataset._xaxis, value) 
     168                    elif parent == "Y": 
     169                        self.current_dataset.yaxis(self.current_dataset._yaxis, value) 
     170                    elif parent == "Temperature": 
     171                        self.current_dataset.sample.temperature_unit = value 
     172                    elif parent == "CounterSlitLength": 
     173                        self.detector.slit_length_unit = value 
     174                elif key == "quantity": 
     175                    if parent == "X": 
     176                        self.current_dataset.xaxis(value, self.current_dataset._xunit) 
     177                    elif parent == "Y": 
     178                        self.current_dataset.yaxis(value, self.current_dataset._yunit) 
  • src/sas/sascalc/dataloader/readers/ascii_reader.py

    rb699768 r7d94915  
    3333    ## File type 
    3434    type_name = "ASCII" 
    35      
     35 
    3636    ## Wildcards 
    3737    type = ["ASCII files (*.txt)|*.txt", 
     
    4141    ## List of allowed extensions 
    4242    ext = ['.txt', '.TXT', '.dat', '.DAT', '.abs', '.ABS', 'csv', 'CSV'] 
    43      
     43 
    4444    ## Flag to bypass extension check 
    4545    allow_all = True 
    46      
     46 
    4747    def read(self, path): 
    4848        """ 
    4949        Load data file 
    50          
     50 
    5151        :param path: file path 
    52          
    5352        :return: Data1D object, or None 
    54          
     53 
    5554        :raise RuntimeError: when the file can't be opened 
    5655        :raise ValueError: when the length of the data vectors are inconsistent 
     
    6261                try: 
    6362                    # Read in binary mode since GRASP frequently has no-ascii 
    64                     # characters that brakes the open operation 
     63                    # characters that breaks the open operation 
    6564                    input_f = open(path,'rb') 
    6665                except: 
     
    6867                buff = input_f.read() 
    6968                lines = buff.splitlines() 
    70                   
    71                 x  = numpy.zeros(0) 
    72                 y  = numpy.zeros(0) 
    73                 dy = numpy.zeros(0) 
    74                 dx = numpy.zeros(0) 
    75                  
    76                 #temp. space to sort data 
    77                 tx  = numpy.zeros(0) 
    78                 ty  = numpy.zeros(0) 
     69 
     70                # Arrays for data storage 
     71                tx = numpy.zeros(0) 
     72                ty = numpy.zeros(0) 
    7973                tdy = numpy.zeros(0) 
    8074                tdx = numpy.zeros(0) 
    81                  
    82                 output = Data1D(x, y, dy=dy, dx=dx) 
    83                 self.filename = output.filename = basename 
    84             
    85                 data_conv_q = None 
    86                 data_conv_i = None 
    87                  
    88                 if has_converter == True and output.x_unit != '1/A': 
    89                     data_conv_q = Converter('1/A') 
    90                     # Test it 
    91                     data_conv_q(1.0, output.x_unit) 
    92                      
    93                 if has_converter == True and output.y_unit != '1/cm': 
    94                     data_conv_i = Converter('1/cm') 
    95                     # Test it 
    96                     data_conv_i(1.0, output.y_unit) 
    97             
     75 
    9876                # The first good line of data will define whether 
    9977                # we have 2-column or 3-column ascii 
    10078                has_error_dx = None 
    10179                has_error_dy = None 
    102                  
     80 
    10381                #Initialize counters for data lines and header lines. 
    104                 is_data = False  # Has more than 5 lines 
     82                is_data = False 
    10583                # More than "5" lines of data is considered as actual 
    10684                # data unless that is the only data 
    107                 mum_data_lines = 5 
     85                min_data_pts = 5 
    10886                # To count # of current data candidate lines 
    109                 i = -1 
     87                candidate_lines = 0 
    11088                # To count total # of previous data candidate lines 
    111                 i1 = -1 
    112                 # To count # of header lines 
    113                 j = -1 
    114                 # Helps to count # of header lines 
    115                 j1 = -1 
    116                 #minimum required number of columns of data; ( <= 4). 
     89                candidate_lines_previous = 0 
     90                #minimum required number of columns of data 
    11791                lentoks = 2 
    11892                for line in lines: 
    119                     # Initial try for CSV (split on ,) 
    120                     toks = line.split(',') 
    121                     # Now try SCSV (split on ;) 
    122                     if len(toks) < 2: 
    123                         toks = line.split(';') 
    124                     # Now go for whitespace                     
    125                     if len(toks) < 2: 
    126                         toks = line.split() 
     93                    toks = self.splitline(line) 
     94                    # To remember the # of columns in the current line of data 
     95                    new_lentoks = len(toks) 
    12796                    try: 
     97                        if new_lentoks == 1 and not is_data: 
     98                            ## If only one item in list, no longer data 
     99                            raise ValueError 
     100                        elif new_lentoks == 0: 
     101                            ## If the line is blank, skip and continue on 
     102                            ## In case of breaks within data sets. 
     103                            continue 
     104                        elif new_lentoks != lentoks and is_data: 
     105                            ## If a footer is found, break the loop and save the data 
     106                            break 
     107                        elif new_lentoks != lentoks and not is_data: 
     108                            ## If header lines are numerical 
     109                            candidate_lines = 0 
     110                            candidate_lines_previous = 0 
     111 
    128112                        #Make sure that all columns are numbers. 
    129113                        for colnum in range(len(toks)): 
     114                            # Any non-floating point values throw ValueError 
    130115                            float(toks[colnum]) 
    131                              
     116 
     117                        candidate_lines += 1 
    132118                        _x = float(toks[0]) 
    133119                        _y = float(toks[1]) 
    134                          
    135                         #Reset the header line counters 
    136                         if j == j1: 
    137                             j = 0 
    138                             j1 = 0 
    139                              
    140                         if i > 1: 
     120                        _dx = None 
     121                        _dy = None 
     122 
     123                        #If 5 or more lines, this is considering the set data 
     124                        if candidate_lines >= min_data_pts: 
    141125                            is_data = True 
    142                          
    143                         if data_conv_q is not None: 
    144                             _x = data_conv_q(_x, units=output.x_unit) 
    145                              
    146                         if data_conv_i is not None: 
    147                             _y = data_conv_i(_y, units=output.y_unit) 
    148                          
    149                         # If we have an extra token, check 
    150                         # whether it can be interpreted as a 
    151                         # third column. 
    152                         _dy = None 
    153                         if len(toks) > 2: 
    154                             try: 
    155                                 _dy = float(toks[2]) 
    156                                  
    157                                 if data_conv_i is not None: 
    158                                     _dy = data_conv_i(_dy, units=output.y_unit) 
    159                                  
    160                             except: 
    161                                 # The third column is not a float, skip it. 
    162                                 pass 
    163                              
    164                         # If we haven't set the 3rd column 
    165                         # flag, set it now. 
    166                         if has_error_dy == None: 
    167                             has_error_dy = False if _dy == None else True 
    168                              
    169                         #Check for dx 
    170                         _dx = None 
    171                         if len(toks) > 3: 
    172                             try: 
    173                                 _dx = float(toks[3]) 
    174                                  
    175                                 if data_conv_i is not None: 
    176                                     _dx = data_conv_i(_dx, units=output.x_unit) 
    177                                  
    178                             except: 
    179                                 # The 4th column is not a float, skip it. 
    180                                 pass 
    181                              
    182                         # If we haven't set the 3rd column 
    183                         # flag, set it now. 
    184                         if has_error_dx == None: 
    185                             has_error_dx = False if _dx == None else True 
    186                          
    187                         #After talked with PB, we decided to take care of only 
    188                         # 4 columns of data for now. 
    189                         #number of columns in the current line 
    190                         #To remember the # of columns in the current 
    191                         #line of data 
    192                         new_lentoks = len(toks) 
    193                          
    194                         #If the previous columns not equal to the current, 
    195                         #mark the previous as non-data and reset the dependents. 
    196                         if lentoks != new_lentoks: 
    197                             if is_data == True: 
    198                                 break 
    199                             else: 
    200                                 i = -1 
    201                                 i1 = 0 
    202                                 j = -1 
    203                                 j1 = -1 
    204                              
    205                         #Delete the previously stored lines of data candidates 
    206                         # if is not data. 
    207                         if i < 0 and -1 < i1 < mum_data_lines and \ 
    208                             is_data == False: 
    209                             try: 
    210                                 x = numpy.zeros(0) 
    211                                 y = numpy.zeros(0) 
    212                             except: 
    213                                 pass 
    214                              
    215                         x = numpy.append(x, _x) 
    216                         y = numpy.append(y, _y) 
    217                          
    218                         if has_error_dy == True: 
    219                             #Delete the previously stored lines of 
    220                             # data candidates if is not data. 
    221                             if i < 0 and -1 < i1 < mum_data_lines and \ 
    222                                 is_data == False: 
    223                                 try: 
    224                                     dy = numpy.zeros(0) 
    225                                 except: 
    226                                     pass 
    227                             dy = numpy.append(dy, _dy) 
    228                              
    229                         if has_error_dx == True: 
    230                             #Delete the previously stored lines of 
    231                             # data candidates if is not data. 
    232                             if i < 0 and -1 < i1 < mum_data_lines and \ 
    233                                 is_data == False: 
    234                                 try: 
    235                                     dx = numpy.zeros(0) 
    236                                 except: 
    237                                     pass 
    238                             dx = numpy.append(dx, _dx) 
    239                              
    240                         #Same for temp. 
    241                         #Delete the previously stored lines of data candidates 
    242                         # if is not data. 
    243                         if i < 0 and -1 < i1 < mum_data_lines and\ 
     126 
     127                        # If a 3rd row is present, consider it dy 
     128                        if new_lentoks > 2: 
     129                            _dy = float(toks[2]) 
     130                        has_error_dy = False if _dy == None else True 
     131 
     132                        # If a 4th row is present, consider it dx 
     133                        if new_lentoks > 3: 
     134                            _dx = float(toks[3]) 
     135                        has_error_dx = False if _dx == None else True 
     136 
     137                        # Delete the previously stored lines of data candidates if 
     138                        # the list is not data 
     139                        if candidate_lines == 1 and -1 < candidate_lines_previous < min_data_pts and \ 
    244140                            is_data == False: 
    245141                            try: 
    246142                                tx = numpy.zeros(0) 
    247143                                ty = numpy.zeros(0) 
     144                                tdy = numpy.zeros(0) 
     145                                tdx = numpy.zeros(0) 
    248146                            except: 
    249147                                pass 
    250148 
     149                        if has_error_dy == True: 
     150                            tdy = numpy.append(tdy, _dy) 
     151                        if has_error_dx == True: 
     152                            tdx = numpy.append(tdx, _dx) 
    251153                        tx = numpy.append(tx, _x) 
    252154                        ty = numpy.append(ty, _y) 
    253                          
    254                         if has_error_dy == True: 
    255                             #Delete the previously stored lines of 
    256                             # data candidates if is not data. 
    257                             if i < 0 and -1 < i1 < mum_data_lines and \ 
    258                                 is_data == False: 
    259                                 try: 
    260                                     tdy = numpy.zeros(0) 
    261                                 except: 
    262                                     pass 
    263                             tdy = numpy.append(tdy, _dy) 
    264                         if has_error_dx == True: 
    265                             #Delete the previously stored lines of 
    266                             # data candidates if is not data. 
    267                             if i < 0 and -1 < i1 < mum_data_lines and \ 
    268                                 is_data == False: 
    269                                 try: 
    270                                     tdx = numpy.zeros(0) 
    271                                 except: 
    272                                     pass 
    273                             tdx = numpy.append(tdx, _dx) 
    274  
    275                         #reset i1 and flag lentoks for the next 
    276                         if lentoks < new_lentoks: 
    277                             if is_data == False: 
    278                                 i1 = -1 
     155 
    279156                        #To remember the # of columns on the current line 
    280157                        # for the next line of data 
    281                         lentoks = len(toks) 
    282                          
    283                         #Reset # of header lines and counts # 
    284                         # of data candidate lines 
    285                         if j == 0 and j1 == 0: 
    286                             i1 = i + 1 
    287                         i += 1 
    288                     except: 
     158                        lentoks = new_lentoks 
     159                        candidate_lines_previous = candidate_lines 
     160                    except ValueError: 
    289161                        # It is data and meet non - number, then stop reading 
    290162                        if is_data == True: 
    291163                            break 
    292164                        lentoks = 2 
    293                         #Counting # of header lines 
    294                         j += 1 
    295                         if j == j1 + 1: 
    296                             j1 = j 
    297                         else: 
    298                             j = -1 
     165                        has_error_dx = None 
     166                        has_error_dy = None 
    299167                        #Reset # of lines of data candidates 
    300                         i = -1 
    301                          
    302                         # Couldn't parse this line, skip it 
     168                        candidate_lines = 0 
     169                    except: 
    303170                        pass 
    304                      
     171 
    305172                input_f.close() 
     173                if not is_data: 
     174                    return None 
    306175                # Sanity check 
    307                 if has_error_dy == True and not len(y) == len(dy): 
     176                if has_error_dy == True and not len(ty) == len(tdy): 
    308177                    msg = "ascii_reader: y and dy have different length" 
    309178                    raise RuntimeError, msg 
    310                 if has_error_dx == True and not len(x) == len(dx): 
     179                if has_error_dx == True and not len(tx) == len(tdx): 
    311180                    msg = "ascii_reader: y and dy have different length" 
    312181                    raise RuntimeError, msg 
    313182                # If the data length is zero, consider this as 
    314183                # though we were not able to read the file. 
    315                 if len(x) == 0: 
     184                if len(tx) == 0: 
    316185                    raise RuntimeError, "ascii_reader: could not load file" 
    317                  
     186 
    318187                #Let's re-order the data to make cal. 
    319188                # curve look better some cases 
    320189                ind = numpy.lexsort((ty, tx)) 
     190                x = numpy.zeros(len(tx)) 
     191                y = numpy.zeros(len(ty)) 
     192                dy = numpy.zeros(len(tdy)) 
     193                dx = numpy.zeros(len(tdx)) 
     194                output = Data1D(x, y, dy=dy, dx=dx) 
     195                self.filename = output.filename = basename 
     196 
    321197                for i in ind: 
    322198                    x[i] = tx[ind[i]] 
     
    338214                output.dx = dx[x != 0] if has_error_dx == True\ 
    339215                    else numpy.zeros(len(output.x)) 
    340                                  
    341                 if data_conv_q is not None: 
    342                     output.xaxis("\\rm{Q}", output.x_unit) 
    343                 else: 
    344                     output.xaxis("\\rm{Q}", 'A^{-1}') 
    345                 if data_conv_i is not None: 
    346                     output.yaxis("\\rm{Intensity}", output.y_unit) 
    347                 else: 
    348                     output.yaxis("\\rm{Intensity}", "cm^{-1}") 
    349                      
     216 
     217                output.xaxis("\\rm{Q}", 'A^{-1}') 
     218                output.yaxis("\\rm{Intensity}", "cm^{-1}") 
     219 
    350220                # Store loading process information 
    351221                output.meta_data['loader'] = self.type_name 
     
    353223                    raise RuntimeError, "%s is empty" % path 
    354224                return output 
    355              
     225 
    356226        else: 
    357227            raise RuntimeError, "%s is not a file" % path 
    358228        return None 
     229 
     230    def splitline(self, line): 
     231        """ 
     232        Splits a line into pieces based on common delimeters 
     233        :param line: A single line of text 
     234        :return: list of values 
     235        """ 
     236        # Initial try for CSV (split on ,) 
     237        toks = line.split(',') 
     238        # Now try SCSV (split on ;) 
     239        if len(toks) < 2: 
     240            toks = line.split(';') 
     241        # Now go for whitespace 
     242        if len(toks) < 2: 
     243            toks = line.split() 
     244        return toks 
  • src/sas/sascalc/dataloader/readers/cansas_reader.py

    r5f26aa4 r0639476  
    6262    type_name = "canSAS" 
    6363    invalid = True 
     64    frm = "" 
    6465    ## Log messages and errors 
    6566    logging = None 
     
    138139                    for entry in entry_list: 
    139140                        # Create a new DataInfo object for every <SASentry> 
    140  
    141141 
    142142                        # Set the file name and then parse the entry. 
     
    183183        return self.output 
    184184 
    185     def _parse_entry(self, dom): 
     185    def _parse_entry(self, dom, recurse=False): 
    186186        """ 
    187187        Parse a SASEntry - new recursive method for parsing the dom of 
     
    192192        """ 
    193193 
    194         frm = inspect.stack()[1] 
    195         if not self._is_call_local(frm): 
     194        if not self._is_call_local() and not recurse: 
    196195            self.reset_state() 
    197196            self.add_data_set() 
     
    201200        self.base_ns = "{0}{1}{2}".format("{", \ 
    202201                            CANSAS_NS.get(self.cansas_version).get("ns"), "}") 
    203         tagname = '' 
    204         tagname_original = '' 
    205202 
    206203        # Go through each child in the parent element 
     
    225222                    self._initialize_new_data_set() 
    226223                ## Recursion step to access data within the group 
    227                 self._parse_entry(node) 
     224                self._parse_entry(node, True) 
    228225                if tagname == "SASsample": 
    229226                    self.current_datainfo.sample.name = name 
     
    437434                length = len(self.names) - 1 
    438435            self.parent_class = self.names[length] 
    439         if not self._is_call_local(frm): 
     436        if not self._is_call_local() and not recurse: 
     437            self.frm = "" 
    440438            self.add_data_set() 
    441439            empty = None 
     
    448446 
    449447 
    450     def _is_call_local(self, frm=""): 
    451         """ 
    452  
    453         :return: 
    454         """ 
    455         if frm == "": 
    456             frm = inspect.stack()[1] 
    457         mod_name = frm[1].replace("\\", "/").replace(".pyc", "") 
     448    def _is_call_local(self): 
     449        """ 
     450 
     451        """ 
     452        if self.frm == "": 
     453            inter = inspect.stack() 
     454            self.frm = inter[2] 
     455        mod_name = self.frm[1].replace("\\", "/").replace(".pyc", "") 
    458456        mod_name = mod_name.replace(".py", "") 
    459457        mod = mod_name.split("sas/") 
     
    836834        # If the calling function was not the cansas reader, return a minidom 
    837835        #      object rather than an lxml object. 
    838         frm = inspect.stack()[1] 
    839         doc, entry_node = self._check_origin(entry_node, doc, frm) 
     836        self.frm = inspect.stack()[1] 
     837        doc, entry_node = self._check_origin(entry_node, doc) 
    840838        return doc, entry_node 
    841839 
     
    11791177            written = written | self.write_node(pix, "z", item.pixel_size.z, 
    11801178                                                {"unit": item.pixel_size_unit}) 
    1181             written = written | self.write_node(det, "slit_length", 
    1182                                                 item.slit_length, 
    1183                                                 {"unit": item.slit_length_unit}) 
    11841179            if written == True: 
    11851180                self.append(pix, det) 
     1181            self.write_node(det, "slit_length", item.slit_length, 
     1182                {"unit": item.slit_length_unit}) 
     1183 
    11861184 
    11871185    def _write_process_notes(self, datainfo, entry_node): 
     
    12321230                self.append(node, entry_node) 
    12331231 
    1234     def _check_origin(self, entry_node, doc, frm): 
     1232    def _check_origin(self, entry_node, doc): 
    12351233        """ 
    12361234        Return the document, and the SASentry node associated with 
     
    12421240        :param doc: entire xml tree 
    12431241        """ 
    1244         if not frm: 
    1245             frm = inspect.stack()[1] 
    1246         mod_name = frm[1].replace("\\", "/").replace(".pyc", "") 
     1242        if not self.frm: 
     1243            self.frm = inspect.stack()[1] 
     1244        mod_name = self.frm[1].replace("\\", "/").replace(".pyc", "") 
    12471245        mod_name = mod_name.replace(".py", "") 
    12481246        mod = mod_name.split("sas/") 
  • src/sas/sascalc/dataloader/readers/cansas_reader_HDF5.py

    r479799c r5e906207  
    2323 
    2424    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). 
     25 
     26    Also supports reading NXcanSAS formatted HDF5 files 
    2527 
    2628    :Dependencies: 
     
    7678                ## Add the last data set to the list of outputs 
    7779                self.add_data_set() 
     80                ## Close the data file 
     81                self.raw_data.close() 
    7882        ## Return data set(s) 
    7983        return self.output 
     
    183187                    elif key == u'run': 
    184188                        self.current_datainfo.run.append(data_point) 
     189                        try: 
     190                            run_name = value.attrs['name'] 
     191                            run_dict = {data_point: run_name} 
     192                            self.current_datainfo.run_name = run_dict 
     193                        except: 
     194                            pass 
    185195                    elif key == u'title': 
    186196                        self.current_datainfo.title = data_point 
     
    189199 
    190200                    ## Sample Information 
    191                     elif key == u'Title' and self.parent_class == u'SASsample': 
     201                    elif key == u'Title' and self.parent_class == u'SASsample': # CanSAS 2.0 format 
     202                        self.current_datainfo.sample.name = data_point 
     203                    elif key == u'ID' and self.parent_class == u'SASsample': # NXcanSAS format 
    192204                        self.current_datainfo.sample.name = data_point 
    193205                    elif key == u'thickness' and self.parent_class == u'SASsample': 
     
    195207                    elif key == u'temperature' and self.parent_class == u'SASsample': 
    196208                        self.current_datainfo.sample.temperature = data_point 
     209                    elif key == u'transmission' and self.parent_class == u'SASsample': 
     210                        self.current_datainfo.sample.transmission = data_point 
     211                    elif key == u'x_position' and self.parent_class == u'SASsample': 
     212                        self.current_datainfo.sample.position.x = data_point 
     213                    elif key == u'y_position' and self.parent_class == u'SASsample': 
     214                        self.current_datainfo.sample.position.y = data_point 
     215                    elif key == u'polar_angle' and self.parent_class == u'SASsample': 
     216                        self.current_datainfo.sample.orientation.x = data_point 
     217                    elif key == u'azimuthal_angle' and self.parent_class == u'SASsample': 
     218                        self.current_datainfo.sample.orientation.z = data_point 
     219                    elif key == u'details' and self.parent_class == u'SASsample': 
     220                        self.current_datainfo.sample.details.append(data_point) 
    197221 
    198222                    ## Instrumental Information 
     
    204228                        self.detector.distance = float(data_point) 
    205229                        self.detector.distance_unit = unit 
     230                    elif key == u'slit_length' and self.parent_class == u'SASdetector': 
     231                        self.detector.slit_length = float(data_point) 
     232                        self.detector.slit_length_unit = unit 
     233                    elif key == u'x_position' and self.parent_class == u'SASdetector': 
     234                        self.detector.offset.x = float(data_point) 
     235                        self.detector.offset_unit = unit 
     236                    elif key == u'y_position' and self.parent_class == u'SASdetector': 
     237                        self.detector.offset.y = float(data_point) 
     238                        self.detector.offset_unit = unit 
     239                    elif key == u'polar_angle' and self.parent_class == u'SASdetector': 
     240                        self.detector.orientation.x = float(data_point) 
     241                        self.detector.orientation_unit = unit 
     242                    elif key == u'azimuthal_angle' and self.parent_class == u'SASdetector': 
     243                        self.detector.orientation.z = float(data_point) 
     244                        self.detector.orientation_unit = unit 
     245                    elif key == u'beam_center_x' and self.parent_class == u'SASdetector': 
     246                        self.detector.beam_center.x = float(data_point) 
     247                        self.detector.beam_center_unit = unit 
     248                    elif key == u'beam_center_y' and self.parent_class == u'SASdetector': 
     249                        self.detector.beam_center.y = float(data_point) 
     250                        self.detector.beam_center_unit = unit 
     251                    elif key == u'x_pixel_size' and self.parent_class == u'SASdetector': 
     252                        self.detector.pixel_size.x = float(data_point) 
     253                        self.detector.pixel_size_unit = unit 
     254                    elif key == u'y_pixel_size' and self.parent_class == u'SASdetector': 
     255                        self.detector.pixel_size.y = float(data_point) 
     256                        self.detector.pixel_size_unit = unit 
    206257                    elif key == u'SSD' and self.parent_class == u'SAScollimation': 
    207258                        self.collimation.length = data_point 
     
    213264                    elif key == u'name' and self.parent_class == u'SASprocess': 
    214265                        self.process.name = data_point 
    215                     elif key == u'Title' and self.parent_class == u'SASprocess': 
     266                    elif key == u'Title' and self.parent_class == u'SASprocess': # CanSAS 2.0 format 
     267                        self.process.name = data_point 
     268                    elif key == u'name' and self.parent_class == u'SASprocess': # NXcanSAS format 
    216269                        self.process.name = data_point 
    217270                    elif key == u'description' and self.parent_class == u'SASprocess': 
     
    230283                        self.trans_spectrum.wavelength.append(data_point) 
    231284 
    232                     ## Other Information 
     285                    ## Source 
    233286                    elif key == u'wavelength' and self.parent_class == u'SASdata': 
    234287                        self.current_datainfo.source.wavelength = data_point 
    235                         self.current_datainfo.source.wavelength.unit = unit 
     288                        self.current_datainfo.source.wavelength_unit = unit 
     289                    elif key == u'incident_wavelength' and self.parent_class == u'SASsource': 
     290                        self.current_datainfo.source.wavelength = data_point 
     291                        self.current_datainfo.source.wavelength_unit = unit 
     292                    elif key == u'wavelength_max' and self.parent_class == u'SASsource': 
     293                        self.current_datainfo.source.wavelength_max = data_point 
     294                        self.current_datainfo.source.wavelength_max_unit = unit 
     295                    elif key == u'wavelength_min' and self.parent_class == u'SASsource': 
     296                        self.current_datainfo.source.wavelength_min = data_point 
     297                        self.current_datainfo.source.wavelength_min_unit = unit 
     298                    elif key == u'wavelength_spread' and self.parent_class == u'SASsource': 
     299                        self.current_datainfo.source.wavelength_spread = data_point 
     300                        self.current_datainfo.source.wavelength_spread_unit = unit 
     301                    elif key == u'beam_size_x' and self.parent_class == u'SASsource': 
     302                        self.current_datainfo.source.beam_size.x = data_point 
     303                        self.current_datainfo.source.beam_size_unit = unit 
     304                    elif key == u'beam_size_y' and self.parent_class == u'SASsource': 
     305                        self.current_datainfo.source.beam_size.y = data_point 
     306                        self.current_datainfo.source.beam_size_unit = unit 
     307                    elif key == u'beam_shape' and self.parent_class == u'SASsource': 
     308                        self.current_datainfo.source.beam_shape = data_point 
    236309                    elif key == u'radiation' and self.parent_class == u'SASsource': 
    237310                        self.current_datainfo.source.radiation = data_point 
     
    376449        self.current_datainfo = DataInfo() 
    377450 
     451 
    378452    def _initialize_new_data_set(self, parent_list = None): 
    379453        """ 
  • src/sas/sascalc/dataloader/readers/xml_reader.py

    rb699768 ra235f715  
    7070            self.xmldoc = etree.parse(self.xml, parser=PARSER) 
    7171            self.xmlroot = self.xmldoc.getroot() 
     72        except etree.XMLSyntaxError as xml_error: 
     73            logging.info(xml_error) 
     74        except Exception: 
     75            self.xml = None 
     76            self.xmldoc = None 
     77            self.xmlroot = None 
     78 
     79    def set_xml_string(self, tag_soup): 
     80        """ 
     81        Set an XML string as the working XML. 
     82 
     83        :param tag_soup: XML formatted string 
     84        """ 
     85        try: 
     86            self.xml = tag_soup 
     87            self.xmldoc = tag_soup 
     88            self.xmlroot = etree.fromstring(tag_soup) 
    7289        except etree.XMLSyntaxError as xml_error: 
    7390            logging.info(xml_error) 
  • src/sas/sascalc/pr/invertor.py

    rb699768 r2c60f304  
    154154            return self.set_err(value2) 
    155155        elif name == 'd_max': 
     156            if value <= 0.0: 
     157                msg = "Invertor: d_max must be greater than zero." 
     158                msg += "Correct that entry before proceeding" 
     159                raise ValueError, msg 
    156160            return self.set_dmax(value) 
    157161        elif name == 'q_min': 
  • src/sas/sasgui/guiframe/aboutbox.py

    rd85c194 re0f28e6  
    106106        self.bitmap_button_nist = wx.BitmapButton(self, -1, wx.NullBitmap) 
    107107        self.bitmap_button_umd = wx.BitmapButton(self, -1, wx.NullBitmap) 
    108         self.bitmap_button_sns = wx.BitmapButton(self, -1, wx.NullBitmap) 
     108        self.bitmap_button_ornl = wx.BitmapButton(self, -1, wx.NullBitmap) 
     109        #self.bitmap_button_sns = wx.BitmapButton(self, -1, wx.NullBitmap) 
    109110        #self.bitmap_button_nsf = wx.BitmapButton(self, -1, 
    110111        #                                         wx.NullBitmap) 
     
    115116        self.bitmap_button_ess = wx.BitmapButton(self, -1, wx.NullBitmap) 
    116117        self.bitmap_button_ill = wx.BitmapButton(self, -1, wx.NullBitmap) 
     118        self.bitmap_button_ansto = wx.BitmapButton(self, -1, wx.NullBitmap) 
    117119         
    118120        self.static_line_3 = wx.StaticLine(self, -1) 
     
    124126        self.Bind(wx.EVT_BUTTON, self.onNistLogo, self.bitmap_button_nist) 
    125127        self.Bind(wx.EVT_BUTTON, self.onUmdLogo, self.bitmap_button_umd) 
    126         self.Bind(wx.EVT_BUTTON, self.onSnsLogo, self.bitmap_button_sns) 
     128        #self.Bind(wx.EVT_BUTTON, self.onSnsLogo, self.bitmap_button_sns) 
     129        self.Bind(wx.EVT_BUTTON, self.onOrnlLogo, self.bitmap_button_ornl) 
    127130        #self.Bind(wx.EVT_BUTTON, self.onNsfLogo, self.bitmap_button_nsf) 
    128131        #self.Bind(wx.EVT_BUTTON, self.onDanseLogo, self.bitmap_button_danse) 
     
    131134        self.Bind(wx.EVT_BUTTON, self.onEssLogo, self.bitmap_button_ess) 
    132135        self.Bind(wx.EVT_BUTTON, self.onIllLogo, self.bitmap_button_ill) 
     136        self.Bind(wx.EVT_BUTTON, self.onAnstoLogo, self.bitmap_button_ansto) 
    133137        # end wxGlade 
    134138        # fill in acknowledgements 
     
    163167        self.bitmap_button_umd.SetBitmapLabel(logo) 
    164168 
    165          
     169        image = file_dir + "/images/ornl_logo.png" 
     170        if os.path.isfile(config._ornl_logo): 
     171            image = config._ornl_logo 
     172        logo = wx.Bitmap(image)         
     173        self.bitmap_button_ornl.SetBitmapLabel(logo) 
     174 
     175        """ 
    166176        image = file_dir + "/images/sns_logo.png" 
    167177        if os.path.isfile(config._sns_logo): 
     
    170180        self.bitmap_button_sns.SetBitmapLabel(logo) 
    171181         
    172         """ 
    173182        image = file_dir + "/images/nsf_logo.png" 
    174183        if os.path.isfile(config._nsf_logo): 
     
    206215        logo = wx.Bitmap(image) 
    207216        self.bitmap_button_ill.SetBitmapLabel(logo) 
     217         
     218        image = file_dir + "/images/ansto_logo.png" 
     219        if os.path.isfile(config._ansto_logo): 
     220            image = config._ansto_logo 
     221        logo = wx.Bitmap(image) 
     222        self.bitmap_button_ansto.SetBitmapLabel(logo) 
    208223                 
    209224        # resize dialog window to fit version number nicely 
     
    227242        self.bitmap_button_nist.SetSize(self.bitmap_button_nist.GetBestSize()) 
    228243        self.bitmap_button_umd.SetSize(self.bitmap_button_umd.GetBestSize()) 
    229         self.bitmap_button_sns.SetSize(self.bitmap_button_sns.GetBestSize()) 
     244        self.bitmap_button_ornl.SetSize(self.bitmap_button_ornl.GetBestSize()) 
     245        #self.bitmap_button_sns.SetSize(self.bitmap_button_sns.GetBestSize()) 
    230246        #self.bitmap_button_nsf.SetSize(self.bitmap_button_nsf.GetBestSize()) 
    231247        #self.bitmap_button_danse.SetSize(self.bitmap_button_danse.GetBestSize()) 
     
    234250        self.bitmap_button_ess.SetSize(self.bitmap_button_ess.GetBestSize()) 
    235251        self.bitmap_button_ill.SetSize(self.bitmap_button_ill.GetBestSize()) 
     252        self.bitmap_button_ansto.SetSize(self.bitmap_button_ansto.GetBestSize()) 
    236253        # end wxGlade 
    237254 
     
    285302        sizer_logos.Add(self.bitmap_button_nist, 0,  
    286303                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    287         sizer_logos.Add(self.bitmap_button_sns, 0,  
     304        #sizer_logos.Add(self.bitmap_button_sns, 0,  
     305        #                wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     306        sizer_logos.Add(self.bitmap_button_ornl, 0,  
    288307                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    289308        sizer_logos.Add(self.bitmap_button_isis, 0,  
     
    292311                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    293312        sizer_logos.Add(self.bitmap_button_ill, 0,  
     313                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     314        sizer_logos.Add(self.bitmap_button_ansto, 0,  
    294315                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    295316                 
     
    321342        event.Skip() 
    322343         
     344    def onOrnlLogo(self, event):  
     345        """ 
     346        """ 
     347        # wxGlade: DialogAbout.<event_handler> 
     348        launchBrowser(config._ornl_url) 
     349        event.Skip() 
     350         
    323351    def onSnsLogo(self, event):  
    324352        """ 
     
    368396        # wxGlade: DialogAbout.<event_handler> 
    369397        launchBrowser(config._ill_url) 
     398        event.Skip() 
     399 
     400    def onAnstoLogo(self, event): 
     401        """ 
     402        """  
     403        # wxGlade: DialogAbout.<event_handler> 
     404        launchBrowser(config._ansto_url) 
    370405        event.Skip() 
    371406 
  • src/sas/sasgui/guiframe/acknowledgebox.py

    rd85c194 rc1fdf84  
    6868        self.preamble.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "")) 
    6969        self.SetTitle("Acknowledging SasView") 
    70         self.SetSize((525, 225)) 
     70        #Increased size of box from (525, 225), SMK, 04/10/16 
     71        self.SetSize((600, 300)) 
    7172        # end wxGlade 
    7273 
  • src/sas/sasgui/guiframe/gui_manager.py

    rc8a641e8 r3fac0df  
    13451345        self._help_menu.Append(wx_id, '&Documentation', '') 
    13461346        wx.EVT_MENU(self, wx_id, self._onSphinxDocs) 
     1347        self._help_menu.AppendSeparator() 
    13471348 
    13481349        if config._do_tutorial and (IS_WIN or sys.platform == 'darwin'): 
    1349             self._help_menu.AppendSeparator() 
    13501350            wx_id = wx.NewId() 
    13511351            self._help_menu.Append(wx_id, '&Tutorial', 'Software tutorial') 
    13521352            wx.EVT_MENU(self, wx_id, self._onTutorial) 
     1353            self._help_menu.AppendSeparator() 
     1354 
    13531355 
    13541356        if config._do_acknowledge: 
    1355             self._help_menu.AppendSeparator() 
    13561357            wx_id = wx.NewId() 
    13571358            self._help_menu.Append(wx_id, '&Acknowledge', 'Acknowledging SasView') 
    13581359            wx.EVT_MENU(self, wx_id, self._onAcknowledge) 
     1360            self._help_menu.AppendSeparator() 
     1361 
    13591362 
    13601363        if config._do_aboutbox: 
     1364            logging.info("Doing help menu") 
     1365            wx_id = wx.NewId() 
     1366            self._help_menu.Append(wx_id, '&About', 'Software information') 
     1367            wx.EVT_MENU(self, wx_id, self._onAbout) 
    13611368            self._help_menu.AppendSeparator() 
    1362             self._help_menu.Append(wx.ID_ABOUT, '&About', 'Software information') 
    1363             wx.EVT_MENU(self, wx.ID_ABOUT, self._onAbout) 
     1369 
    13641370 
    13651371        # Checking for updates 
  • src/sas/sasgui/guiframe/gui_statusbar.py

    rd85c194 r3a22ce7  
    66import sys 
    77import logging 
     8import datetime 
    89from wx import StatusBar as wxStatusB 
    910from wx.lib import newevent 
     
    4647 
    4748        self.msg_txt.SetEditable(False) 
    48         self.msg_txt.SetValue('No message available') 
     49        timestamp = datetime.datetime.now() 
     50        status = '{:%Y-%m-%d %H:%M:%S} : No message available'.format(timestamp) 
     51        self.msg_txt.SetValue(status) 
    4952        self.sizer.Add(self.msg_txt, 1, wx.EXPAND|wx.ALL, 10) 
    5053        self.SetSizer(self.sizer) 
     
    6063        if status.strip() == "": 
    6164            return 
     65        # Add timestamp 
     66        timestamp = datetime.datetime.now() 
     67        status = '{:%Y-%m-%d %H:%M:%S} : '.format(timestamp) + status 
    6268        color = (0, 0, 0) #black 
    6369        icon_bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_TOOLBAR) 
  • src/sas/sasgui/guiframe/media/data_formats_help.rst

    rd85c194 r280f929  
    33.. This is a port of the original SasView html help file to ReSTructured text 
    44.. by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 
     5.. WG Bouwman, DUT, added during CodeCamp-V in Oct 2016 the SESANS data format 
    56 
    67.. _Formats: 
     
    910============ 
    1011 
    11 SasView reads several different 1D (I(Q) vs Q) and 2D (I(Qx,Qy) vs (Qx,Qy)) 
     12SasView reads several different 1D (I(Q) vs Q), 2D SANS(I(Qx,Qy) vs (Qx,Qy)) 
     13and SESANS (P(z) vs z) 
    1214data files. But please note that SasView does not at present load data where 
    1315the Q and I(Q) data are in separate files. 
    1416 
    15 1D Formats 
    16 ---------- 
     171D Formats SANS 
     18--------------- 
    1719 
    1820SasView will read files with 2 to 4 columns of numbers in the following order:  
     
    4648.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    4749 
    48 2D Formats 
    49 ---------- 
     502D Formats SANS 
     51--------------- 
    5052 
    5153SasView will only read files in the NIST 2D format with the extensions  
     
    6062.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    6163 
    62 .. note::  This help document was last changed by Steve King, 01May2015 
     64SESANS Format 
     65------------- 
     66 
     67The current file extension is .ses or .sesans (not case sensitive). 
     68 
     69The file format is to have a list of name-value pairs as a header at the top of the file, detailing general experimental parameters necessary for fitting and analyzing data. This list should contain all information necessary for the file to be 'portable' between users. 
     70 
     71Following that is a 6 column list of instrument experimental variables: 
     72 
     73- Spin echo length (z, in Angstroms) 
     74- Spin echo length error (:math:`\Delta` z, in Angstroms) (experimental resolution) 
     75- neutron wavelength (:math:`\lambda`, in Angstroms) (essential for ToF instruments) 
     76- neutron wavelength error (:math:`\Delta \lambda`, in Angstroms) 
     77- Normalized polarization (:math:`P/P_0`, unitless) 
     78- Normalized polarization error (:math:`\Delta(P/P_0)`, unitless) (measurement error) 
     79 
     80 
     81.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     82 
     83.. note::  This help document was last changed by Wim Bouwman, 05Oct2016 
  • src/sas/sasgui/guiframe/media/graph_help.rst

    re68c9bf rf9b0c81  
    4242plot window. 
    4343 
    44 *NOTE! If a residuals graph (when fitting data) is hidden, it will not show up 
    45 after computation.* 
     44.. note::  
     45    *If a residuals graph (when fitting data) is hidden, it will not show up 
     46    after computation.* 
    4647 
    4748Dragging a plot 
     
    6768After zooming in on a a region, the *left arrow* or *right arrow* buttons on 
    6869the toolbar will switch between recent views. 
     70 
     71The axis range can also be specified manually.  To do so go to the *Graph Menu* 
     72(see Invoking_the_graph_menu_ for further details), choose the *Set Graph Range* 
     73option and enter the limits in the pop box. 
    6974 
    7075*NOTE! If a wheel mouse is available scrolling the wheel will zoom in/out 
     
    116121^^^^^^^^^^^^^^^^^^^ 
    117122 
    118 From the *Graph Menu* (see Invoking_the_graph_menu_) it is also possible to 
    119 make some custom modifications to plots, including: 
     123It is possible to make custom modifications to plots including: 
    120124 
    121125*  changing the plot window title 
    122 *  changing the axis legend locations 
    123 *  changing the axis legend label text 
    124 *  changing the axis legend label units 
    125 *  changing the axis legend label font & font colour 
     126*  changing the default legend location and toggling it on/off 
     127*  changing the axis label text 
     128*  changing the axis label units 
     129*  changing the axis label font & font colour 
    126130*  adding/removing a text string 
    127131*  adding a grid overlay 
     132 
     133The legend and text strings can be drag and dropped around the plot 
     134 
     135These options are accessed through the *Graph Menu* (see Invoking_the_graph_menu_) 
     136and selecting *Modify Graph Appearance* (for axis labels, grid overlay and 
     137legend position) or *Add Text* to add textual annotations, selecting font, color, 
     138style and size. *Remove Text* will remove the last annotation added. To change 
     139the legend. *Window Title* allows a custom title to be entered instead of Graph 
     140x.  
    128141 
    129142Changing scales 
     
    234247selected data will be removed from the plot. 
    235248 
    236 *NOTE! This action cannot be undone.* 
     249.. note:: 
     250    The Remove data set action cannot be undone. 
    237251 
    238252Show-Hide error bars 
     
    248262In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Modify Plot 
    249263Property* to change the size, color, or shape of the displayed marker for the 
    250 chosen dataset, or to change the dataset label that appears on the plot. 
     264chosen dataset, or to change the dataset label that appears in the plot legend 
     265box. 
    251266 
    252267.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    292307average. 
    293308 
    294 *NOTE! The displayed average only updates when input focus is moved back to 
    295 that window; ie, when the mouse pointer is moved onto that plot.* 
     309.. note:: 
     310    The displayed average only updates when input focus is moved back to 
     311    that window; ie, when the mouse pointer is moved onto that plot. 
    296312 
    297313Selecting *Box Sum* automatically brings up the 'Slicer Parameters' dialog in 
     
    359375.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    360376 
    361 .. note::  This help document was last changed by Steve King, 01May2015 
     377.. note::  This help document was last modified by Paul Butler, 05 September, 2016 
  • src/sas/sasgui/guiframe/utils.py

    rd85c194 ra0373d5  
    4646    return flag 
    4747 
    48      
     48 
     49def check_int(item): 
     50    """ 
     51    :param item: txtcrtl containing a value 
     52    """ 
     53    flag = True 
     54    try: 
     55        mini = int(item.GetValue()) 
     56        item.SetBackgroundColour(wx.WHITE) 
     57        item.Refresh() 
     58    except: 
     59        flag = False 
     60        item.SetBackgroundColour("pink") 
     61        item.Refresh() 
     62    return flag 
     63 
     64 
    4965class PanelMenu(wx.Menu): 
    5066    """ 
  • src/sas/sasgui/perspectives/fitting/basepage.py

    re4c897b rc65a265  
    1717from wx.lib.scrolledpanel import ScrolledPanel 
    1818 
    19 import sasmodels.sasview_model 
     19from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 
     20 
    2021from sas.sasgui.guiframe.panel_base import PanelBase 
    21 from sas.sasgui.guiframe.utils import format_number, check_float, IdList 
     22from sas.sasgui.guiframe.utils import format_number, check_float, IdList, check_int 
    2223from sas.sasgui.guiframe.events import PanelOnFocusEvent 
    2324from sas.sasgui.guiframe.events import StatusEvent 
     
    626627        self.disp_help_bt.Bind(wx.EVT_BUTTON, self.on_pd_help_clicked, 
    627628                               id=self.disp_help_bt.GetId()) 
    628         self.disp_help_bt.SetToolTipString("Helps for Polydispersion.") 
     629        self.disp_help_bt.SetToolTipString("Help for polydispersion.") 
    629630 
    630631        self.Bind(wx.EVT_RADIOBUTTON, self._set_dipers_Param, 
     
    932933        if len(self._disp_obj_dict) > 0: 
    933934            for k, v in self._disp_obj_dict.iteritems(): 
    934                 self.state._disp_obj_dict[k] = v 
     935                self.state._disp_obj_dict[k] = v.type 
    935936 
    936937            self.state.values = copy.deepcopy(self.values) 
     
    10091010            if len(self._disp_obj_dict) > 0: 
    10101011                for k, v in self._disp_obj_dict.iteritems(): 
    1011                     self.state._disp_obj_dict[k] = v 
     1012                    self.state._disp_obj_dict[k] = v.type 
    10121013 
    10131014            self.state.values = copy.deepcopy(self.values) 
     
    11231124                                                    state.disp_cb_dict[item]) 
    11241125                        # Create the dispersion objects 
    1125                         from sas.models.dispersion_models import ArrayDispersion 
    1126                         disp_model = ArrayDispersion() 
     1126                        disp_model = POLYDISPERSITY_MODELS['array']() 
    11271127                        if hasattr(state, "values") and \ 
    11281128                                 self.disp_cb_dict[item].GetValue() == True: 
     
    13791379        self.weights = copy.deepcopy(state.weights) 
    13801380 
    1381         for key, disp in state._disp_obj_dict.iteritems(): 
    1382             # From saved file, disp_model can not be sent in model obj. 
    1383             # it will be sent as a string here, then converted to model object. 
    1384             if disp.__class__.__name__ == 'str': 
    1385                 disp_model = None 
    1386                 com_str = "from sasmodels.weights " 
    1387                 com_str += "import %s as disp_func \ndisp_model = disp_func()" 
    1388                 exec com_str % disp 
    1389             else: 
    1390                 disp_model = disp 
     1381        for key, disp_type in state._disp_obj_dict.iteritems(): 
     1382            #disp_model = disp 
     1383            disp_model = POLYDISPERSITY_MODELS[disp_type]() 
    13911384            self._disp_obj_dict[key] = disp_model 
    13921385            param_name = key.split('.')[0] 
     
    15041497            is_2Ddata = True 
    15051498        if self.model != None: 
    1506             try: 
    1507                 is_modified = self._check_value_enter(self.fittable_param, 
    1508                                                       is_modified) 
    1509                 is_modified = self._check_value_enter(self.fixed_param, 
    1510                                                       is_modified) 
    1511                 is_modified = self._check_value_enter(self.parameters, 
    1512                                                       is_modified) 
    1513             except Exception: 
    1514                 logging.error(traceback.format_exc()) 
     1499            is_modified = (self._check_value_enter(self.fittable_param) 
     1500                           or self._check_value_enter(self.fixed_param) 
     1501                           or self._check_value_enter(self.parameters)) 
    15151502 
    15161503            # Here we should check whether the boundaries have been modified. 
     
    15331520            else: 
    15341521                self.fitrange = False 
    1535  
    1536             if not self.data.is_data: 
    1537                 is_modified = True 
    15381522 
    15391523            ## if any value is modify draw model with new value 
     
    15521536                self._draw_model() 
    15531537                self.Refresh() 
     1538 
     1539        logging.info("is_modified flag set to %g",is_modified) 
    15541540        return is_modified 
    15551541 
     
    15611547        flag = True 
    15621548        self.fitrange = True 
    1563         is_modified = False 
    15641549 
    15651550        #wx.PostEvent(self._manager.parent, StatusEvent(status=" \ 
     
    15741559                                                                [self.data]) 
    15751560            ##Check the values 
    1576             self._check_value_enter(self.fittable_param, is_modified) 
    1577             self._check_value_enter(self.fixed_param, is_modified) 
    1578             self._check_value_enter(self.parameters, is_modified) 
     1561            self._check_value_enter(self.fittable_param) 
     1562            self._check_value_enter(self.fixed_param) 
     1563            self._check_value_enter(self.parameters) 
    15791564 
    15801565            # If qmin and qmax have been modified, update qmin and qmax and 
     
    16601645        return flag 
    16611646 
    1662     def _is_modified(self, is_modified): 
    1663         """ 
    1664         return to self._is_modified 
    1665         """ 
    1666         return is_modified 
    1667  
    16681647    def _reset_parameters_state(self, listtorestore, statelist): 
    16691648        """ 
     
    19641943        wx.PostEvent(self.parent, StatusEvent(status=msg)) 
    19651944        # Flag to register when a parameter has changed. 
    1966         #is_modified = False 
    19671945        if tcrtl.GetValue().lstrip().rstrip() != "": 
    19681946            try: 
     
    19941972                    if temp_npts != self.num_points: 
    19951973                        self.num_points = temp_npts 
    1996                         #is_modified = True 
    19971974                else: 
    19981975                    msg = "Cannot plot: No points in Q range!!!  " 
     
    21702147        self.Layout() 
    21712148 
     2149 
    21722150    def _validate_qrange(self, qmin_ctrl, qmax_ctrl): 
    21732151        """ 
     
    22762254        return flag 
    22772255 
    2278     def _check_value_enter(self, list, modified): 
     2256    def _check_value_enter(self, list): 
    22792257        """ 
    22802258        :param list: model parameter and panel info 
     
    22862264                parameter's maximum value , 
    22872265                parameter's units] 
    2288         """ 
    2289         is_modified = modified 
    2290         if len(list) == 0: 
    2291             return is_modified 
     2266 
     2267        Returns True if the model parameters have changed. 
     2268        """ 
     2269        is_modified = False 
    22922270        for item in list: 
    22932271            #skip angle parameters for 1D 
    2294             if not self.enable2D: 
    2295                 if item in self.orientation_params: 
     2272            if not self.enable2D and item in self.orientation_params: 
     2273                continue 
     2274 
     2275            value_ctrl = item[2] 
     2276            if not value_ctrl.IsEnabled(): 
     2277                # ArrayDispersion disables PD, Min, Max, Npts, Nsigs 
     2278                continue 
     2279 
     2280            name = item[1] 
     2281            value_str = value_ctrl.GetValue().strip() 
     2282            if name.endswith(".npts"): 
     2283                validity = check_int(value_ctrl) 
     2284                if not validity: 
    22962285                    continue 
    2297             #try: 
    2298             name = str(item[1]) 
    2299  
    2300             if string.find(name, ".npts") == -1 and \ 
    2301                                         string.find(name, ".nsigmas") == -1: 
    2302                 ## check model parameters range 
    2303                 param_min = None 
    2304                 param_max = None 
    2305  
    2306                 ## check minimun value 
    2307                 if item[5] != None and item[5] != "": 
    2308                     if item[5].GetValue().lstrip().rstrip() != "": 
    2309                         try: 
    2310                             param_min = float(item[5].GetValue()) 
    2311                             if not self._validate_qrange(item[5], item[2]): 
    2312                                 if numpy.isfinite(param_min): 
    2313                                     item[2].SetValue(format_number(param_min)) 
    2314  
    2315                             item[5].SetBackgroundColour(wx.WHITE) 
    2316                             item[2].SetBackgroundColour(wx.WHITE) 
    2317  
    2318                         except: 
    2319                             msg = "Wrong fit parameter range entered" 
    2320                             wx.PostEvent(self._manager.parent, 
    2321                                          StatusEvent(status=msg)) 
    2322                             raise ValueError, msg 
    2323                         is_modified = True 
    2324                 ## check maximum value 
    2325                 if item[6] != None and item[6] != "": 
    2326                     if item[6].GetValue().lstrip().rstrip() != "": 
    2327                         try: 
    2328                             param_max = float(item[6].GetValue()) 
    2329                             if not self._validate_qrange(item[2], item[6]): 
    2330                                 if numpy.isfinite(param_max): 
    2331                                     item[2].SetValue(format_number(param_max)) 
    2332  
    2333                             item[6].SetBackgroundColour(wx.WHITE) 
    2334                             item[2].SetBackgroundColour(wx.WHITE) 
    2335                         except: 
    2336                             msg = "Wrong Fit parameter range entered " 
    2337                             wx.PostEvent(self._manager.parent, 
    2338                                          StatusEvent(status=msg)) 
    2339                             raise ValueError, msg 
    2340                         is_modified = True 
    2341  
    2342                 if param_min != None and param_max != None: 
    2343                     if not self._validate_qrange(item[5], item[6]): 
    2344                         msg = "Wrong Fit range entered for parameter " 
    2345                         msg += "name %s of model %s " % (name, self.model.name) 
    2346                         wx.PostEvent(self._manager.parent, 
    2347                                      StatusEvent(status=msg)) 
    2348  
    2349                 if name in self.model.details.keys(): 
    2350                     self.model.details[name][1:3] = param_min, param_max 
    2351                     is_modified = True 
    2352                 else: 
    2353                     self.model.details[name] = ["", param_min, param_max] 
    2354                     is_modified = True 
    2355             try: 
    2356                 # Check if the textctr is enabled 
    2357                 if item[2].IsEnabled(): 
    2358                     value = float(item[2].GetValue()) 
    2359                     item[2].SetBackgroundColour("white") 
    2360                     # If the value of the parameter has changed, 
    2361                     # +update the model and set the is_modified flag 
    2362                     if value != self.model.getParam(name) and \ 
    2363                                                 numpy.isfinite(value): 
    2364                         self.model.setParam(name, value) 
    2365             except: 
    2366                 item[2].SetBackgroundColour("pink") 
    2367                 msg = "Wrong Fit parameter value entered " 
    2368                 wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
     2286                value = int(value_str) 
     2287 
     2288            elif name.endswith(".nsigmas"): 
     2289                validity = check_float(value_ctrl) 
     2290                if not validity: 
     2291                    continue 
     2292                value = float(value_str) 
     2293 
     2294            else:  # value or polydispersity 
     2295 
     2296                # Check that min, max and value are floats 
     2297                min_ctrl, max_ctrl = item[5], item[6] 
     2298                min_str = min_ctrl.GetValue().strip() 
     2299                max_str = max_ctrl.GetValue().strip() 
     2300                validity = check_float(value_ctrl) 
     2301                if min_str != "": 
     2302                    validity = validity and check_float(min_ctrl) 
     2303                if max_str != "": 
     2304                    validity = validity and check_float(max_ctrl) 
     2305                if not validity: 
     2306                    continue 
     2307 
     2308                # Check that min is less than max 
     2309                low = -numpy.inf if min_str == "" else float(min_str) 
     2310                high = numpy.inf if max_str == "" else float(max_str) 
     2311                if high < low: 
     2312                    min_ctrl.SetBackgroundColour("pink") 
     2313                    min_ctrl.Refresh() 
     2314                    max_ctrl.SetBackgroundColour("pink") 
     2315                    max_ctrl.Refresh() 
     2316                    #msg = "Invalid fit range for %s: min must be smaller than max"%name 
     2317                    #wx.PostEvent(self._manager.parent, StatusEvent(status=msg)) 
     2318                    continue 
     2319 
     2320                # Force value between min and max 
     2321                value = float(value_str) 
     2322                if value < low: 
     2323                    value = low 
     2324                    value_ctrl.SetValue(format_number(value)) 
     2325                elif value > high: 
     2326                    value = high 
     2327                    value_ctrl.SetValue(format_number(value)) 
     2328 
     2329                if name not in self.model.details.keys(): 
     2330                    self.model.details[name] = ["", None, None] 
     2331                old_low, old_high = self.model.details[name][1:3] 
     2332                if old_low != low or old_high != high: 
     2333                    # The configuration has changed but it won't change the 
     2334                    # computed curve so no need to set is_modified to True 
     2335                    #is_modified = True 
     2336                    self.model.details[name][1:3] = low, high 
     2337 
     2338            # Update value in model if it has changed 
     2339            if value != self.model.getParam(name): 
     2340                self.model.setParam(name, value) 
     2341                is_modified = True 
    23692342 
    23702343        return is_modified 
     
    25392512                self._disp_obj_dict[name1] = disp_model 
    25402513                self.model.set_dispersion(param_name, disp_model) 
    2541                 self.state._disp_obj_dict[name1] = disp_model 
     2514                self.state._disp_obj_dict[name1] = disp_model.type 
    25422515 
    25432516                value1 = str(format_number(self.model.getParam(name1), True)) 
     
    25622535                        item[0].Enable() 
    25632536                        item[2].Enable() 
     2537                        item[3].Show(True) 
     2538                        item[4].Show(True) 
    25642539                        item[5].Enable() 
    25652540                        item[6].Enable() 
     
    26542629        self._disp_obj_dict[name] = disp 
    26552630        self.model.set_dispersion(name.split('.')[0], disp) 
    2656         self.state._disp_obj_dict[name] = disp 
     2631        self.state._disp_obj_dict[name] = disp.type 
    26572632        self.values[name] = values 
    26582633        self.weights[name] = weights 
     
    27222697        :param disp_function: dispersion distr. function 
    27232698        """ 
    2724         # List of the poly_model name in the combobox 
    2725         list = ["RectangleDispersion", "ArrayDispersion", 
    2726                 "LogNormalDispersion", "GaussianDispersion", 
    2727                 "SchulzDispersion"] 
    2728  
    27292699        # Find the selection 
    2730         try: 
    2731             selection = list.index(disp_func.__class__.__name__) 
    2732             return selection 
    2733         except: 
    2734             return 3 
     2700        if disp_func is not None: 
     2701            try: 
     2702                return POLYDISPERSITY_MODELS.values().index(disp_func.__class__) 
     2703            except ValueError: 
     2704                pass  # Fall through to default class 
     2705        return POLYDISPERSITY_MODELS.keys().index('gaussian') 
    27352706 
    27362707    def on_reset_clicked(self, event): 
     
    33193290                    pd = content[name][1] 
    33203291                    if name.count('.') > 0: 
     3292                        # If this is parameter.width, then pd may be a floating 
     3293                        # point value or it may be an array distribution. 
     3294                        # Nothing to do for parameter.npts or parameter.nsigmas. 
    33213295                        try: 
    33223296                            float(pd) 
    3323                         except: 
     3297                            if name.endswith('.npts'): 
     3298                                pd = int(pd) 
     3299                        except Exception: 
    33243300                            #continue 
    33253301                            if not pd and pd != '': 
     
    33293305                        # Only array func has pd == '' case. 
    33303306                        item[2].Enable(False) 
     3307                    else: 
     3308                        item[2].Enable(True) 
    33313309                    if item[2].__class__.__name__ == "ComboBox": 
    33323310                        if content[name][1] in self.model.fun_list: 
     
    33553333                        pd = value[0] 
    33563334                        if name.count('.') > 0: 
     3335                            # If this is parameter.width, then pd may be a floating 
     3336                            # point value or it may be an array distribution. 
     3337                            # Nothing to do for parameter.npts or parameter.nsigmas. 
    33573338                            try: 
    33583339                                pd = float(pd) 
     3340                                if name.endswith('.npts'): 
     3341                                    pd = int(pd) 
    33593342                            except: 
    33603343                                #continue 
     
    33653348                            # Only array func has pd == '' case. 
    33663349                            item[2].Enable(False) 
     3350                        else: 
     3351                            item[2].Enable(True) 
    33673352                        if item[2].__class__.__name__ == "ComboBox": 
    33683353                            if value[0] in self.model.fun_list: 
     
    33843369        Helps get paste for poly function 
    33853370 
    3386         :param item: Gui param items 
    3387         :param value: the values for parameter ctrols 
    3388         """ 
    3389         is_array = False 
    3390         if len(value[1]) > 0: 
    3391             # Only for dispersion func.s 
    3392             try: 
    3393                 item[7].SetValue(value[1]) 
    3394                 selection = item[7].GetCurrentSelection() 
    3395                 name = item[7].Name 
    3396                 param_name = name.split('.')[0] 
    3397                 dispersity = item[7].GetClientData(selection) 
    3398                 disp_model = dispersity() 
    3399                 # Only for array disp 
    3400                 try: 
    3401                     pd_vals = numpy.array(value[2]) 
    3402                     pd_weights = numpy.array(value[3]) 
    3403                     if len(pd_vals) > 0 and len(pd_vals) > 0: 
    3404                         if len(pd_vals) == len(pd_weights): 
    3405                             self._set_disp_array_cb(item=item) 
    3406                             self._set_array_disp_model(name=name, 
    3407                                                        disp=disp_model, 
    3408                                                        values=pd_vals, 
    3409                                                        weights=pd_weights) 
    3410                             is_array = True 
    3411                 except Exception: 
    3412                     logging.error(traceback.format_exc()) 
    3413                 if not is_array: 
    3414                     self._disp_obj_dict[name] = disp_model 
    3415                     self.model.set_dispersion(name, 
    3416                                               disp_model) 
    3417                     self.state._disp_obj_dict[name] = \ 
    3418                                               disp_model 
    3419                     self.model.set_dispersion(param_name, disp_model) 
    3420                     self.state.values = self.values 
    3421                     self.state.weights = self.weights 
    3422                     self.model._persistency_dict[param_name] = \ 
    3423                                             [self.state.values, 
    3424                                              self.state.weights] 
    3425  
    3426             except Exception: 
    3427                 logging.error(traceback.format_exc()) 
    3428                 print "Error in BasePage._paste_poly_help: %s" % \ 
    3429                                         sys.exc_info()[1] 
    3430  
    3431     def _set_disp_array_cb(self, item): 
     3371        *item* is the parameter name 
     3372 
     3373        *value* depends on which parameter is being processed, and whether it 
     3374        has array polydispersity. 
     3375 
     3376        For parameters without array polydispersity: 
     3377 
     3378            parameter => ['FLOAT', ''] 
     3379            parameter.width => ['FLOAT', 'DISTRIBUTION', ''] 
     3380            parameter.npts => ['FLOAT', ''] 
     3381            parameter.nsigmas => ['FLOAT', ''] 
     3382 
     3383        For parameters with array polydispersity: 
     3384 
     3385            parameter => ['FLOAT', ''] 
     3386            parameter.width => ['FILENAME', 'array', [x1, ...], [w1, ...]] 
     3387            parameter.npts => ['FLOAT', ''] 
     3388            parameter.nsigmas => ['FLOAT', ''] 
     3389        """ 
     3390        # Do nothing if not setting polydispersity 
     3391        if len(value[1]) == 0: 
     3392            return 
     3393 
     3394        try: 
     3395            name = item[7].Name 
     3396            param_name = name.split('.')[0] 
     3397            item[7].SetValue(value[1]) 
     3398            selection = item[7].GetCurrentSelection() 
     3399            dispersity = item[7].GetClientData(selection) 
     3400            disp_model = dispersity() 
     3401 
     3402            if value[1] == 'array': 
     3403                pd_vals = numpy.array(value[2]) 
     3404                pd_weights = numpy.array(value[3]) 
     3405                if len(pd_vals) == 0 or len(pd_vals) != len(pd_weights): 
     3406                    msg = ("bad array distribution parameters for %s" 
     3407                           % param_name) 
     3408                    raise ValueError(msg) 
     3409                self._set_disp_cb(True, item=item) 
     3410                self._set_array_disp_model(name=name, 
     3411                                           disp=disp_model, 
     3412                                           values=pd_vals, 
     3413                                           weights=pd_weights) 
     3414            else: 
     3415                self._set_disp_cb(False, item=item) 
     3416                self._disp_obj_dict[name] = disp_model 
     3417                self.model.set_dispersion(param_name, disp_model) 
     3418                self.state._disp_obj_dict[name] = disp_model.type 
     3419                # TODO: It's not an array, why update values and weights? 
     3420                self.model._persistency_dict[param_name] = \ 
     3421                    [self.values, self.weights] 
     3422                self.state.values = self.values 
     3423                self.state.weights = self.weights 
     3424 
     3425        except Exception: 
     3426            logging.error(traceback.format_exc()) 
     3427            print "Error in BasePage._paste_poly_help: %s" % \ 
     3428                                    sys.exc_info()[1] 
     3429 
     3430    def _set_disp_cb(self, isarray, item): 
    34323431        """ 
    34333432        Set cb for array disp 
    34343433        """ 
    3435         item[0].SetValue(False) 
    3436         item[0].Enable(False) 
    3437         item[2].Enable(False) 
    3438         item[3].Show(False) 
    3439         item[4].Show(False) 
    3440         item[5].SetValue('') 
    3441         item[5].Enable(False) 
    3442         item[6].SetValue('') 
    3443         item[6].Enable(False) 
     3434        if isarray: 
     3435            item[0].SetValue(False) 
     3436            item[0].Enable(False) 
     3437            item[2].Enable(False) 
     3438            item[3].Show(False) 
     3439            item[4].Show(False) 
     3440            item[5].SetValue('') 
     3441            item[5].Enable(False) 
     3442            item[6].SetValue('') 
     3443            item[6].Enable(False) 
     3444        else: 
     3445            item[0].Enable() 
     3446            item[2].Enable() 
     3447            item[3].Show(True) 
     3448            item[4].Show(True) 
     3449            item[5].Enable() 
     3450            item[6].Enable() 
    34443451 
    34453452    def update_pinhole_smear(self): 
  • src/sas/sasgui/perspectives/fitting/batchfitpage.py

    rfc18690 ree4b3cb  
    256256#         if self.model != None:            
    257257#             ##Check the values 
    258 #             self._check_value_enter( self.fittable_param, is_modified) 
    259 #             self._check_value_enter( self.fixed_param, is_modified) 
    260 #             self._check_value_enter( self.parameters, is_modified) 
     258#             self._check_value_enter( self.fittable_param) 
     259#             self._check_value_enter( self.fixed_param) 
     260#             self._check_value_enter( self.parameters) 
    261261#  
    262262#             # If qmin and qmax have been modified, update qmin and qmax and  
  • src/sas/sasgui/perspectives/fitting/fitpage.py

    r934ce649 r6c382da  
    1010import math 
    1111import time 
     12import traceback 
    1213 
    1314from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS 
     
    13651366            try: 
    13661367                tcrtl.SetBackgroundColour(wx.WHITE) 
    1367                 self._check_value_enter(self.fittable_param, is_modified) 
    1368                 self._check_value_enter(self.parameters, is_modified) 
     1368                self._check_value_enter(self.fittable_param) 
     1369                self._check_value_enter(self.parameters) 
    13691370            except: 
    13701371                tcrtl.SetBackgroundColour("pink") 
     
    20582059            msg = "Error: This model state has missing or outdated " 
    20592060            msg += "information.\n" 
    2060             msg += "%s" % (sys.exc_value) 
     2061            msg += traceback.format_exc() 
    20612062            wx.PostEvent(self._manager.parent, 
    20622063                         StatusEvent(status=msg, info="error")) 
  • src/sas/sasgui/perspectives/fitting/fitting.py

    r7673ecd rca4d985  
    313313        """ 
    314314        event_id = event.GetId() 
    315         self.update_custom_combo()         
     315        self.update_custom_combo() 
    316316 
    317317    def update_custom_combo(self): 
     
    342342                                page.formfactorbox.SetLabel(current_val) 
    343343        except: 
    344             pass 
    345  
     344            logging.error("update_custom_combo: %s", sys.exc_value) 
    346345 
    347346    def set_edit_menu(self, owner): 
     
    16661665        wx.PostEvent(self.parent, StatusEvent(status=msg, type="update")) 
    16671666 
     1667    def create_theory_1D(self, x, y, page_id, model, data, state, 
     1668                         data_description, data_id, dy=None): 
     1669        """ 
     1670            Create a theory object associate with an existing Data1D 
     1671            and add it to the data manager. 
     1672            @param x: x-values of the data 
     1673            @param y: y_values of the data 
     1674            @param page_id: fit page ID 
     1675            @param model: model used for fitting 
     1676            @param data: Data1D object to create the theory for 
     1677            @param state: model state 
     1678            @param data_description: title to use in the data manager 
     1679            @param data_id: unique data ID 
     1680        """ 
     1681        new_plot = Data1D(x=x, y=y) 
     1682        if dy is None: 
     1683            new_plot.is_data = False 
     1684            new_plot.dy = numpy.zeros(len(y)) 
     1685            # If this is a theory curve, pick the proper symbol to make it a curve 
     1686            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 
     1687        else: 
     1688            new_plot.is_data = True 
     1689            new_plot.dy = dy 
     1690        new_plot.interactive = True 
     1691        new_plot.dx = None 
     1692        new_plot.dxl = None 
     1693        new_plot.dxw = None 
     1694        _yaxis, _yunit = data.get_yaxis() 
     1695        _xaxis, _xunit = data.get_xaxis() 
     1696        new_plot.title = data.name 
     1697        new_plot.group_id = data.group_id 
     1698        if new_plot.group_id == None: 
     1699            new_plot.group_id = data.group_id 
     1700        new_plot.id = data_id 
     1701        # Find if this theory was already plotted and replace that plot given 
     1702        # the same id 
     1703        self.page_finder[page_id].get_theory_data(fid=data.id) 
     1704 
     1705        if data.is_data: 
     1706            data_name = str(data.name) 
     1707        else: 
     1708            data_name = str(model.__class__.__name__) 
     1709 
     1710        new_plot.name = data_description + " [" + data_name + "]" 
     1711        new_plot.xaxis(_xaxis, _xunit) 
     1712        new_plot.yaxis(_yaxis, _yunit) 
     1713        self.page_finder[page_id].set_theory_data(data=new_plot, 
     1714                                                  fid=data.id) 
     1715        self.parent.update_theory(data_id=data.id, theory=new_plot, 
     1716                                   state=state) 
     1717        return new_plot 
     1718 
    16681719    def _complete1D(self, x, y, page_id, elapsed, index, model, 
    16691720                    weight=None, fid=None, 
    16701721                    toggle_mode_on=False, state=None, 
    16711722                    data=None, update_chisqr=True, 
    1672                     source='model', plot_result=True): 
    1673         """ 
    1674         Complete plotting 1D data 
     1723                    source='model', plot_result=True, 
     1724                    unsmeared_model=None, unsmeared_data=None, 
     1725                    unsmeared_error=None, sq_model=None, pq_model=None): 
     1726        """ 
     1727            Complete plotting 1D data 
     1728            @param unsmeared_model: fit model, without smearing 
     1729            @param unsmeared_data: data, rescaled to unsmeared model 
     1730            @param unsmeared_error: data error, rescaled to unsmeared model 
    16751731        """ 
    16761732        try: 
    16771733            numpy.nan_to_num(y) 
    1678  
    1679             new_plot = Data1D(x=x, y=y) 
    1680             new_plot.is_data = False 
    1681             new_plot.dy = numpy.zeros(len(y)) 
    1682             new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM 
    1683             _yaxis, _yunit = data.get_yaxis() 
    1684             _xaxis, _xunit = data.get_xaxis() 
    1685             new_plot.title = data.name 
    1686  
    1687             new_plot.group_id = data.group_id 
    1688             if new_plot.group_id == None: 
    1689                 new_plot.group_id = data.group_id 
    1690             new_plot.id = str(page_id) + " " + data.name 
    1691             #if new_plot.id in self.color_dict: 
    1692             #    new_plot.custom_color = self.color_dict[new_plot.id] 
    1693             #find if this theory was already plotted and replace that plot given 
    1694             #the same id 
    1695             self.page_finder[page_id].get_theory_data(fid=data.id) 
    1696  
    1697             if data.is_data: 
    1698                 data_name = str(data.name) 
    1699             else: 
    1700                 data_name = str(model.__class__.__name__) 
    1701  
    1702             new_plot.name = model.name + " [" + data_name + "]" 
    1703             new_plot.xaxis(_xaxis, _xunit) 
    1704             new_plot.yaxis(_yaxis, _yunit) 
    1705             self.page_finder[page_id].set_theory_data(data=new_plot, 
    1706                                                       fid=data.id) 
    1707             self.parent.update_theory(data_id=data.id, theory=new_plot, 
    1708                                        state=state) 
     1734            new_plot = self.create_theory_1D(x, y, page_id, model, data, state, 
     1735                                             data_description=model.name, 
     1736                                             data_id=str(page_id) + " " + data.name) 
     1737            if unsmeared_model is not None: 
     1738                self.create_theory_1D(x, unsmeared_model, page_id, model, data, state, 
     1739                                      data_description=model.name + " unsmeared", 
     1740                                      data_id=str(page_id) + " " + data.name + " unsmeared") 
     1741 
     1742                self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 
     1743                                      data_description="Data unsmeared", 
     1744                                      data_id="Data  " + data.name + " unsmeared", 
     1745                                      dy=unsmeared_error) 
     1746                 
     1747            if sq_model is not None and pq_model is not None: 
     1748                self.create_theory_1D(x, sq_model, page_id, model, data, state, 
     1749                                      data_description=model.name + " S(q)", 
     1750                                      data_id=str(page_id) + " " + data.name + " S(q)") 
     1751                self.create_theory_1D(x, pq_model, page_id, model, data, state, 
     1752                                      data_description=model.name + " P(q)", 
     1753                                      data_id=str(page_id) + " " + data.name + " P(q)") 
     1754 
     1755 
    17091756            current_pg = self.fit_panel.get_page_by_id(page_id) 
    17101757            title = new_plot.title 
  • src/sas/sasgui/perspectives/fitting/media/fitting.rst

    rd85c194 r05829fb  
    1818 
    1919   Information on the SasView Optimisers <optimizer.rst> 
    20     
     20 
     21   Writing a Plugin <plugin.rst> 
  • src/sas/sasgui/perspectives/fitting/media/fitting_help.rst

    rb64b87c r05829fb  
    132132* By :ref:`Writing_a_Plugin` 
    133133 
    134 *NB: Because of the way these options are implemented, it is not possible for them* 
    135 *to use the polydispersity algorithms in SasView. Only models in the model library* 
    136 *can do this. At the time of writing (Release 3.1.0) work is in hand to make it* 
    137 *easier to add new models to the model library.* 
    138  
    139134.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    140135 
     
    163158the :ref:`Advanced` option. 
    164159 
     160*NB: "Fit Parameters" has been split into two sections, those which can be 
     161polydisperse (shape and orientation parameters) and those which are not 
     162(scattering length densities, for example).* 
     163 
    165164Sum|Multi(p1,p2) 
    166165^^^^^^^^^^^^^^^^ 
     
    192191*Advanced Custom Model Editor*. 
    193192 
    194 *NB: Unless you are confident about what you are doing, it is recommended that you* 
    195 *only modify lines denoted with the ## <----- comments!* 
     193See :ref:`Writing_a_Plugin` for details on the plugin format. 
     194 
     195*NB: Sum/Product models are still using the SasView 3.x model format.  Unless 
     196you are confident about what you are doing, it is recommended that you 
     197only modify lines denoted with the ## <----- comments!* 
    196198 
    197199When editing is complete, select *Run -> Compile* from the *Model Editor* menu bar. An 
     
    211213 
    212214*NB: Custom models shipped with SasView cannot be removed in this way.* 
    213  
    214 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    215  
    216 .. _Writing_a_Plugin: 
    217  
    218 Writing a Plugin 
    219 ---------------- 
    220  
    221 Advanced users can write their own model in Python and save it to the the SasView 
    222 *plugin_models* folder 
    223  
    224   *C:\\Users\\[username]\\.sasview\\plugin_models* - (on Windows) 
    225  
    226 in .py format. The next time SasView is started it will compile the plugin and add 
    227 it to the list of *Customized Models*. 
    228  
    229 It is recommended that existing plugin models be used as templates. 
    230215 
    231216.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
  • src/sas/sasgui/perspectives/fitting/model_thread.py

    r934ce649 rca4d985  
    77import math 
    88from sas.sascalc.data_util.calcthread import CalcThread 
     9from sas.sascalc.fit.MultiplicationModel import MultiplicationModel 
    910 
    1011class Calc2D(CalcThread): 
     
    166167        index = (self.qmin <= self.data.x) & (self.data.x <= self.qmax) 
    167168 
     169        # If we use a smearer, also return the unsmeared model 
     170        unsmeared_output = None 
     171        unsmeared_data = None 
     172        unsmeared_error = None 
    168173        ##smearer the ouput of the plot 
    169174        if self.smearer is not None: 
     
    171176                                                             self.qmax) 
    172177            mask = self.data.x[first_bin:last_bin+1] 
    173             output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 
    174             output = self.smearer(output, first_bin, last_bin) 
     178            unsmeared_output = numpy.zeros((len(self.data.x))) 
     179            unsmeared_output[first_bin:last_bin+1] = self.model.evalDistribution(mask) 
     180            output = self.smearer(unsmeared_output, first_bin, last_bin) 
     181             
     182            # Rescale data to unsmeared model 
     183            unsmeared_data = numpy.zeros((len(self.data.x))) 
     184            unsmeared_error = numpy.zeros((len(self.data.x))) 
     185            unsmeared_data[first_bin:last_bin+1] = self.data.y[first_bin:last_bin+1]\ 
     186                                                    * unsmeared_output[first_bin:last_bin+1]\ 
     187                                                    / output[first_bin:last_bin+1] 
     188            unsmeared_error[first_bin:last_bin+1] = self.data.dy[first_bin:last_bin+1]\ 
     189                                                    * unsmeared_output[first_bin:last_bin+1]\ 
     190                                                    / output[first_bin:last_bin+1] 
     191            unsmeared_output=unsmeared_output[index] 
     192            unsmeared_data=unsmeared_data[index] 
     193            unsmeared_error=unsmeared_error 
    175194        else: 
    176195            output[index] = self.model.evalDistribution(self.data.x[index]) 
     196 
     197        sq_model = None 
     198        pq_model = None 
     199        if isinstance(self.model, MultiplicationModel): 
     200            sq_model = numpy.zeros((len(self.data.x))) 
     201            pq_model = numpy.zeros((len(self.data.x))) 
     202            sq_model[index] = self.model.s_model.evalDistribution(self.data.x[index]) 
     203            pq_model[index] = self.model.p_model.evalDistribution(self.data.x[index]) 
    177204 
    178205        elapsed = time.time() - self.starttime 
     
    187214                      data=self.data, 
    188215                      update_chisqr=self.update_chisqr, 
    189                       source=self.source) 
     216                      source=self.source, 
     217                      unsmeared_model=unsmeared_output, 
     218                      unsmeared_data=unsmeared_data, 
     219                      unsmeared_error=unsmeared_error, 
     220                      pq_model=pq_model, 
     221                      sq_model=sq_model) 
    190222 
    191223    def results(self): 
  • src/sas/sasgui/perspectives/fitting/pagestate.py

    r7673ecd r6c382da  
    2424from xml.dom.minidom import parseString 
    2525from lxml import etree 
     26 
     27import sasmodels.weights 
    2628 
    2729import sas.sascalc.dataloader 
     
    474476                value = content[1] 
    475477            except Exception: 
    476                 logging.error(traceback.format_exc()) 
     478                msg = "Report string expected 'name: value' but got %r"%line 
     479                logging.error(msg) 
    477480            if name.count("State created"): 
    478481                repo_time = "" + value 
     
    516519                        title_name = HEADER % title 
    517520                except Exception: 
    518                     logging.error(traceback.format_exc()) 
     521                    msg = "While parsing 'data: ...'\n" 
     522                    logging.error(msg + traceback.format_exc()) 
    519523            if name == "model name ": 
    520524                try: 
     
    531535                    q_range = CENTRE % q_name 
    532536                except Exception: 
    533                     logging.error(traceback.format_exc()) 
     537                    msg = "While parsing 'Plotting Range: ...'\n" 
     538                    logging.error(msg + traceback.format_exc()) 
    534539        paramval = "" 
    535540        for lines in param_string.split(":"): 
     
    711716        # For self.values ={ disp_param_name: [vals,...],...} 
    712717        # and for self.weights ={ disp_param_name: [weights,...],...} 
    713         value_list = {} 
    714718        for item in LIST_OF_MODEL_ATTRIBUTES: 
    715719            element = newdoc.createElement(item[0]) 
     
    725729 
    726730        # Create doc for the dictionary of self._disp_obj_dic 
    727         for item in DISPERSION_LIST: 
    728             element = newdoc.createElement(item[0]) 
    729             value_list = getattr(self, item[1]) 
    730             for key, val in value_list.iteritems(): 
    731                 value = repr(val) 
     731        for tagname, varname, tagtype in DISPERSION_LIST: 
     732            element = newdoc.createElement(tagname) 
     733            value_list = getattr(self, varname) 
     734            for key, value in value_list.iteritems(): 
    732735                sub_element = newdoc.createElement(key) 
    733736                sub_element.setAttribute('name', str(key)) 
     
    847850                # Recover _disp_obj_dict from xml file 
    848851                self._disp_obj_dict = {} 
    849                 for item in DISPERSION_LIST: 
    850                     # Get node 
    851                     node = get_content("ns:%s" % item[0], entry) 
     852                for tagname, varname, tagtype in DISPERSION_LIST: 
     853                    node = get_content("ns:%s" % tagname, entry) 
    852854                    for attr in node: 
    853                         name = str(attr.get('name')) 
    854                         val = attr.get('value') 
    855                         value = val.split(" instance")[0] 
    856                         disp_name = value.split("<")[1] 
    857                         try: 
    858                             # Try to recover disp_model object from strings 
    859                             com = "from sas.models.dispersion_models " 
    860                             com += "import %s as disp" 
    861                             com_name = disp_name.split(".")[3] 
    862                             exec com % com_name 
    863                             disp_model = disp() 
    864                             attribute = getattr(self, item[1]) 
    865                             attribute[name] = com_name 
    866                         except Exception: 
    867                             logging.error(traceback.format_exc()) 
     855                        parameter = str(attr.get('name')) 
     856                        value = attr.get('value') 
     857                        if value.startswith("<"): 
     858                            try: 
     859                                # <path.to.NamedDistribution object/instance...> 
     860                                cls_name = value[1:].split()[0].split('.')[-1] 
     861                                cls = getattr(sasmodels.weights, cls_name) 
     862                                value = cls.type 
     863                            except Exception: 
     864                                logging.error("unable to load distribution %r for %s" 
     865                                              % (value, parameter)) 
     866                                continue 
     867                        _disp_obj_dict = getattr(self, varname) 
     868                        _disp_obj_dict[parameter] = value 
    868869 
    869870                # get self.values and self.weights dic. if exists 
    870                 for item in LIST_OF_MODEL_ATTRIBUTES: 
    871                     node = get_content("ns:%s" % item[0], entry) 
     871                for tagname, varname in LIST_OF_MODEL_ATTRIBUTES: 
     872                    node = get_content("ns:%s" % tagname, entry) 
    872873                    dic = {} 
    873874                    value_list = [] 
    874875                    for par in node: 
    875876                        name = par.get('name') 
    876                         values = par.text.split('\n') 
     877                        values = par.text.split() 
    877878                        # Get lines only with numbers 
    878879                        for line in values: 
     
    882883                            except Exception: 
    883884                                # pass if line is empty (it happens) 
    884                                 logging.error(traceback.format_exc()) 
     885                                msg = ("Error reading %r from %s %s\n" 
     886                                       % (line, tagname, name)) 
     887                                logging.error(msg + traceback.format_exc()) 
    885888                        dic[name] = numpy.array(value_list) 
    886                     setattr(self, item[1], dic) 
     889                    setattr(self, varname, dic) 
    887890 
    888891    def set_plot_state(self, figs, canvases): 
     
    12311234 
    12321235        except: 
    1233             logging.info("XML document does not contain fitting information.\n %s" % sys.exc_value) 
     1236            logging.info("XML document does not contain fitting information.\n" 
     1237                         + traceback.format_exc()) 
    12341238 
    12351239        return state 
     
    15691573                    if output[ind].run_name is not None\ 
    15701574                        and len(output[ind].run_name) != 0: 
    1571                         name = output[ind].run_name 
     1575                        if isinstance(output[ind].run_name, dict): 
     1576                            name = output[ind].run_name.keys()[0] 
     1577                        else: 
     1578                            name = output[ind].run_name 
    15721579                    else: 
    15731580                        name = original_fname 
  • src/sas/sasgui/perspectives/invariant/invariant_panel.py

    rc12f9b4 r654e8e0  
    250250 
    251251            num = self.state.saved_state['state_num'] 
    252             if num > 0: 
     252            if int(num) > 0: 
    253253                self._set_undo_flag(True) 
    254             if num < len(state.state_list) - 1: 
     254            if int(num) < len(state.state_list) - 1: 
    255255                self._set_redo_flag(True) 
    256256 
     
    830830        """ 
    831831        try: 
    832             attr = getattr(self, key) 
     832            if key in ['compute_num', 'file', 'is_time_machine', 'state_num']: 
     833                return 
     834            else: 
     835                attr = getattr(self, key) 
    833836            if attr.__class__.__name__ == "StaticText": 
    834837                return 
    835             if type(value) is not bool: 
     838            if value in ["True", "False", True, False]: 
     839                value = bool(value) 
     840            else: 
    836841                value = str(value) 
    837842            attr.SetValue(value) 
     
    18601865                                   (self.button_calculate, 0, 
    18611866                                    wx.RIGHT | wx.TOP | wx.BOTTOM, 10), 
    1862                                    (self.button_help, 0,  
     1867                                   (self.button_help, 0, 
    18631868                                    wx.RIGHT | wx.TOP | wx.BOTTOM, 10),]) 
    18641869    def _do_layout(self): 
     
    18821887        self.SetSizer(self.main_sizer) 
    18831888        self.SetAutoLayout(True) 
    1884          
     1889 
    18851890    def on_help(self, event): 
    18861891        """ 
    1887         Bring up the Invariant Documentation whenever the HELP button is  
     1892        Bring up the Invariant Documentation whenever the HELP button is 
    18881893        clicked. 
    18891894 
  • src/sas/sasgui/perspectives/invariant/invariant_state.py

    rc10d9d6c rcb93b40  
    426426                        if input_field is not None: 
    427427                            temp_state[item] = val 
    428                             self.state_list[ind] = temp_state 
     428                            self.state_list[str(ind)] = temp_state 
    429429 
    430430            # Parse current state (ie, saved_state) 
     
    790790            doc = state.toXML(datainfo.name, doc=doc, entry_node=sasentry) 
    791791        return doc 
    792  
  • src/sas/sasgui/perspectives/pr/media/pr_help.rst

    rb64b87c r0391dae  
    1515*P(r)* is set to be equal to an expansion of base functions of the type 
    1616 
    17   |bigphi|\_n(r) = 2.r.sin(|pi|\ .n.r/D_max) 
     17.. math:: 
     18  \Phi_{n(r)} = 2 r sin(\frac{\pi n r}{D_{max}}) 
    1819 
    19 The coefficient of each base function in the expansion is found by performing  
     20The coefficient of each base function in the expansion is found by performing 
    2021a least square fit with the following fit function 
    2122 
    22   |chi|\ :sup:`2` = |bigsigma|\ :sub:`i` [ I\ :sub:`meas`\ (Q\ :sub:`i`\ ) - I\ :sub:`th`\ (Q\ :sub:`i`\ ) ] :sup:`2` / (Error) :sup:`2` + Reg_term 
     23.. math:: 
    2324 
    24 where I\ :sub:`meas`\ (Q) is the measured scattering intensity and  
    25 I\ :sub:`th`\ (Q) is the prediction from the Fourier transform of the *P(r)*  
    26 expansion.  
     25  \chi^2=\frac{\sum_i (I_{meas}(Q_i)-I_{th}(Q_i))^2}{error^2}+Reg\_term 
     26   
    2727 
    28 The *Reg_term* term is a regularization term set to the second derivative  
    29 d\ :sup:`2`\ *P(r)* / dr\ :sup:`2` integrated over *r*. It is used to produce a  
    30 smooth *P(r)* output. 
     28where $I_{meas}(Q_i)$ is the measured scattering intensity and $I_{th}(Q_i)$ is 
     29the prediction from the Fourier transform of the *P(r)* expansion.  
     30 
     31The $Reg\_term$ term is a regularization term set to the second derivative  
     32$d^2P(r)/d^2r$ integrated over $r$. It is used to produce a smooth *P(r)* output. 
    3133 
    3234.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    4547   system. 
    4648 
     49P(r) inversion requires that the background be perfectly subtracted.  This is 
     50often difficult to do well and thus many data sets will include a background. 
     51For those cases, the user should check the "estimate background" box and the 
     52module will do its best to estimate it. 
     53 
     54The P(r) module is constantly computing in the background what the optimum 
     55*number of terms* should be as well as the optimum *regularization constant*. 
     56These are constantly updated in the buttons next to the entry boxes on the GUI. 
     57These are almost always close and unless the user has a good reason to choose 
     58differently they should just click on the buttons to accept both.  {D_max} must 
     59still be set by the user.  However, besides looking at the output, the user can 
     60click the explore button which will bring up a graph of chi^2 vs Dmax over a 
     61range around the current Dmax.  The user can change the range and the number of 
     62points to explore in that range.  They can also choose to plot several other 
     63parameters as a function of Dmax including: I0, Rg, Oscillation parameter, 
     64background, positive fraction, and 1-sigma positive fraction. 
     65 
    4766.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    4867 
     
    5574.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    5675 
    57 .. note::  This help document was last changed by Steve King, 01May2015 
     76.. note::  This help document was last modified by Paul Butler, 05 September, 2016 
Note: See TracChangeset for help on using the changeset viewer.