Changeset ecfe6b6 in sasview for src/sas/qtgui


Ignore:
Timestamp:
Aug 13, 2018 10:02:02 AM (6 years ago)
Author:
Torin Cooper-Bennun <torin.cooper-bennun@…>
Branches:
ESS_GUI, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
Children:
799963c
Parents:
4e255d1 (diff), e752ab8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'ESS_GUI_iss976' into ESS_GUI.

SASVIEW-976: Make intermediate data from product models (i.e. P(Q) and S(Q)) plottable.

Location:
src/sas/qtgui
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/MainWindow/DataExplorer.py

    rc7f259d recfe6b6  
    44import time 
    55import logging 
     6import re 
    67 
    78from PyQt5 import QtCore 
     
    3637    # The controller which is responsible for managing signal slots connections 
    3738    # for the gui and providing an interface to the data model. 
     39 
     40    # This matches the ID of a plot created using FittingLogic._create1DPlot, e.g. 
     41    # "5 [P(Q)] modelname" 
     42    # or 
     43    # "4 modelname". 
     44    # Useful for determining whether the plot in question is for an intermediate result, such as P(Q) or S(Q) in the 
     45    # case of a product model; the identifier for this is held in square brackets, as in the example above. 
     46    theory_plot_ID_pattern = re.compile(r"^([0-9]+)\s+(\[(.*)\]\s+)?(.*)$") 
    3847 
    3948    def __init__(self, parent=None, guimanager=None, manager=None): 
     
    525534                self.active_plots[plot_id].replacePlot(plot_id, plot) 
    526535            else: 
     536                # Don't plot intermediate results, e.g. P(Q), S(Q) 
     537                match = self.theory_plot_ID_pattern.match(plot_id) 
     538                # 2nd match group contains the identifier for the intermediate result, if present (e.g. "[P(Q)]") 
     539                if match and match.groups()[1] != None: 
     540                    continue 
    527541                # 'sophisticated' test to generate standalone plot for residuals 
    528542                if 'esiduals' in plot.title: 
  • src/sas/qtgui/Perspectives/Fitting/FittingLogic.py

    r87dfca4 rb4d05bd  
    132132        self._data.ymax = ymax 
    133133 
    134     def new1DPlot(self, return_data, tab_id): 
    135         """ 
    136         Create a new 1D data instance based on fitting results 
    137         """ 
    138         # Unpack return data from Calc1D 
    139         x, y, page_id, state, weight,\ 
    140         fid, toggle_mode_on, \ 
    141         elapsed, index, model,\ 
    142         data, update_chisqr, source = return_data 
    143  
     134    def _create1DPlot(self, tab_id, x, y, model, data, component=None): 
     135        """ 
     136        For internal use: create a new 1D data instance based on fitting results. 
     137        'component' is a string indicating the model component, e.g. "P(Q)" 
     138        """ 
    144139        # Create the new plot 
    145140        new_plot = Data1D(x=x, y=y) 
     
    150145 
    151146        new_plot.group_id = data.group_id 
    152         new_plot.id = str(tab_id) + " " + model.id 
    153  
    154         if data.filename: 
    155             new_plot.name = model.name + " [" + data.filename + "]" # data file 
    156         else: 
    157             new_plot.name = model.name + " [" + model.id + "]"  # theory 
     147        new_plot.id = str(tab_id) + " " + ("[" + component + "] " if component else "") + model.id 
     148 
     149        # use data.filename for data, use model.id for theory 
     150        id_str = data.filename if data.filename else model.id 
     151        new_plot.name = model.name + ((" " + component) if component else "") + " [" + id_str + "]" 
    158152 
    159153        new_plot.title = new_plot.name 
     
    162156 
    163157        return new_plot 
     158 
     159    def new1DPlot(self, return_data, tab_id): 
     160        """ 
     161        Create a new 1D data instance based on fitting results 
     162        """ 
     163        # Unpack return data from Calc1D 
     164        x, y, page_id, state, weight,\ 
     165        fid, toggle_mode_on, \ 
     166        elapsed, index, model, \ 
     167        data, update_chisqr, source, \ 
     168        unsmeared_output, unsmeared_data, unsmeared_error, \ 
     169        pq_values, sq_values = return_data 
     170 
     171        return self._create1DPlot(tab_id, x, y, model, data) 
    164172 
    165173    def new2DPlot(self, return_data): 
     
    205213        return new_plot 
    206214 
     215    def new1DProductPlots(self, return_data, tab_id): 
     216        """ 
     217        If return_data contains separated P(Q) and/or S(Q) data, create 1D plots for each and return as the tuple 
     218        (pq_plot, sq_plot). If either are unavailable, the corresponding plot is None. 
     219        """ 
     220        # Unpack return data from Calc1D 
     221        x, y, page_id, state, weight, \ 
     222        fid, toggle_mode_on, \ 
     223        elapsed, index, model, \ 
     224        data, update_chisqr, source, \ 
     225        unsmeared_output, unsmeared_data, unsmeared_error, \ 
     226        pq_values, sq_values = return_data 
     227 
     228        pq_plot = None 
     229        sq_plot = None 
     230 
     231        if pq_values is not None: 
     232            pq_plot = self._create1DPlot(tab_id, x, pq_values, model, data, component="P(Q)") 
     233        if sq_values is not None: 
     234            sq_plot = self._create1DPlot(tab_id, x, sq_values, model, data, component="S(Q)") 
     235 
     236        return pq_plot, sq_plot 
     237 
    207238    def computeDataRange(self): 
    208239        """ 
  • src/sas/qtgui/Perspectives/Fitting/FittingWidget.py

    r10fee37 recfe6b6  
    21132113            self.updateModelIndex(fitted_data) 
    21142114        else: 
    2115             name = self.nameForFittedData(self.kernel_module.id) 
     2115            if not fitted_data.name: 
     2116                name = self.nameForFittedData(self.kernel_module.id) 
     2117            else: 
     2118                name = fitted_data.name 
    21162119            fitted_data.title = name 
    2117             fitted_data.name = name 
    21182120            fitted_data.filename = name 
    21192121            fitted_data.symbol = "Line" 
     
    22292231        self.model_data = fitted_data 
    22302232 
     2233        # Create plots for intermediate product data 
     2234        pq_data, sq_data = self.logic.new1DProductPlots(return_data, self.tab_id) 
     2235        if pq_data is not None: 
     2236            pq_data.symbol = "Line" 
     2237            self.createNewIndex(pq_data) 
     2238        if sq_data is not None: 
     2239            sq_data.symbol = "Line" 
     2240            self.createNewIndex(sq_data) 
     2241 
    22312242    def complete2D(self, return_data): 
    22322243        """ 
  • src/sas/qtgui/Perspectives/Fitting/ModelThread.py

    rd4dac80 r3ae9179  
    222222            s_model = self.model.s_model 
    223223            p_model = self.model.p_model 
    224         elif hasattr(self.model, "get_composition_models"): 
    225             p_model, s_model = self.model.get_composition_models() 
    226  
    227         if p_model is not None and s_model is not None: 
    228             sq_values = numpy.zeros((len(self.data.x))) 
    229             pq_values = numpy.zeros((len(self.data.x))) 
    230             sq_values[index] = s_model.evalDistribution(self.data.x[index]) 
    231             pq_values[index] = p_model.evalDistribution(self.data.x[index]) 
     224        elif hasattr(self.model, "calc_composition_models"): 
     225            results = self.model.calc_composition_models(self.data.x[index]) 
     226            if results is not None: 
     227                pq_values, sq_values = results 
     228 
     229        if pq_values is None or sq_values is None: 
     230            if p_model is not None and s_model is not None: 
     231                sq_values = numpy.zeros((len(self.data.x))) 
     232                pq_values = numpy.zeros((len(self.data.x))) 
     233                sq_values[index] = s_model.evalDistribution(self.data.x[index]) 
     234                pq_values[index] = p_model.evalDistribution(self.data.x[index]) 
    232235 
    233236        elapsed = time.time() - self.starttime 
     
    243246                    self.data, 
    244247                    self.update_chisqr, 
    245                     self.source) 
     248                    self.source, 
     249                    unsmeared_output, unsmeared_data, unsmeared_error, 
     250                    pq_values, sq_values) 
    246251        else: 
    247252            self.complete(x=self.data.x[index], y=output[index], 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingLogicTest.py

    r80468f6 re752ab8  
    100100        data.id = "poop" 
    101101        return_data = (data.x,data.y, 7, None, None, 
    102                         0, True, 0.0, 1, data, 
    103                         data, False, None) 
     102                       0, True, 0.0, 1, data, 
     103                       data, False, None, 
     104                       None, None, None, 
     105                       None, None) 
    104106 
    105107        new_plot = self.logic.new1DPlot(return_data=return_data, tab_id=0) 
  • src/sas/qtgui/MainWindow/DataManager.py

    r0261bc1 r4e255d1  
    2424import json 
    2525import time 
    26 from io import StringIO 
     26from io import BytesIO 
    2727import numpy as np 
    2828 
     
    368368            # ndarray 
    369369            if isinstance(o, np.ndarray): 
    370                 buffer = StringIO() 
     370                buffer = BytesIO() 
    371371                np.save(buffer, o) 
    372372                buffer.seek(0) 
     
    435435            # ndarray 
    436436            if cls == np.ndarray: 
    437                 buffer = StringIO() 
     437                buffer = BytesIO() 
    438438                buffer.write(data['data'].encode('latin-1')) 
    439439                buffer.seek(0) 
  • src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py

    r02e7d3a r10fee37  
    115115        Add a new tab for passed data 
    116116        """ 
    117         tab     = FittingWidget(parent=self.parent, data=data, tab_id=self.maxIndex+1) 
     117        tab     = FittingWidget(parent=self.parent, data=data, tab_id=self.maxIndex) 
    118118        tab.is_batch_fitting = is_batch 
    119119 
  • src/sas/qtgui/Plotting/Plotter.py

    r42787fb r685e0e3  
    7575        is_fit = (self.data.id=="fit") 
    7676 
    77         # make sure we have some function to operate on 
    78         if self.data.xtransform is None: 
    79             self.data.xtransform = 'log10(x)' 
    80         if self.data.ytransform is None: 
    81             self.data.ytransform = 'log10(y)' 
    82  
    83         # Transform data if required. 
    84         if self.data.xtransform is not None or self.data.ytransform is not None: 
    85             _, _, xscale, yscale = GuiUtils.xyTransform(self.data, self.data.xtransform, self.data.ytransform) 
    86             if xscale != 'log': 
    87                 self.xscale = xscale 
    88             if yscale != 'log': 
    89                 self.yscale = yscale 
    90  
    91             # Redefine the Scale properties dialog 
    92             self.properties = ScaleProperties(self, 
    93                                     init_scale_x=self.data.xtransform, 
    94                                     init_scale_y=self.data.ytransform) 
     77        if not is_fit: 
     78            # make sure we have some function to operate on 
     79            if self.data.xtransform is None: 
     80                self.data.xtransform = 'log10(x)' 
     81            if self.data.ytransform is None: 
     82                self.data.ytransform = 'log10(y)' 
     83 
     84            # Transform data if required. 
     85            if self.data.xtransform is not None or self.data.ytransform is not None: 
     86                _, _, xscale, yscale = GuiUtils.xyTransform(self.data, self.data.xtransform, self.data.ytransform) 
     87                if xscale != 'log': 
     88                    self.xscale = xscale 
     89                if yscale != 'log': 
     90                    self.yscale = yscale 
     91 
     92                # Redefine the Scale properties dialog 
     93                self.properties = ScaleProperties(self, 
     94                                        init_scale_x=self.data.xtransform, 
     95                                        init_scale_y=self.data.ytransform) 
    9596 
    9697        # Shortcuts 
  • src/sas/qtgui/Utilities/GuiUtils.py

    r3d18691 r685e0e3  
    427427    for index in range(model_item.rowCount()): 
    428428        item = model_item.item(index) 
    429         if str(item.text()) == filename: 
     429        if filename in str(item.text()): 
    430430            # TODO: assure item type is correct (either data1/2D or Plotter) 
    431431            plot_data[item] = item.child(0).data() 
Note: See TracChangeset for help on using the changeset viewer.