Changes in / [46f59ba:04972ea] in sasview
- Location:
- src/sas/qtgui
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/MainWindow/GuiManager.py
re4335ae r8e2cd79 520 520 def actionCopy(self): 521 521 """ 522 """ 523 print("actionCopy TRIGGERED") 522 Send a signal to the fitting perspective so parameters 523 can be saved to the clipboard 524 """ 525 self.communicate.copyFitParamsSignal.emit("") 524 526 pass 525 527 526 528 def actionPaste(self): 527 529 """ 528 """ 529 print("actionPaste TRIGGERED") 530 pass 530 Send a signal to the fitting perspective so parameters 531 from the clipboard can be used to modify the fit state 532 """ 533 self.communicate.pasteFitParamsSignal.emit() 531 534 532 535 def actionReport(self): … … 555 558 def actionExcel(self): 556 559 """ 557 """ 558 print("actionExcel TRIGGERED") 559 pass 560 Send a signal to the fitting perspective so parameters 561 can be saved to the clipboard 562 """ 563 self.communicate.copyFitParamsSignal.emit("Excel") 560 564 561 565 def actionLatex(self): 562 566 """ 563 """ 564 print("actionLatex TRIGGERED") 565 pass 567 Send a signal to the fitting perspective so parameters 568 can be saved to the clipboard 569 """ 570 self.communicate.copyFitParamsSignal.emit("Latex") 566 571 567 572 #============ VIEW ================= -
src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
rb87dc1a r8e2cd79 3 3 from PyQt5 import QtCore 4 4 from PyQt5 import QtGui 5 from PyQt5 import QtWidgets6 5 7 6 import numpy … … 99 98 continue 100 99 width = kernel_module.getParam(p.name+'.width') 101 type = kernel_module.getParam(p.name+'.type')100 ptype = kernel_module.getParam(p.name+'.type') 102 101 103 102 item1_2 = QtGui.QStandardItem(str(width)) … … 107 106 item1_4 = QtGui.QStandardItem() 108 107 item1_4.setEditable(False) 109 item1_5 = QtGui.QStandardItem( type)108 item1_5 = QtGui.QStandardItem(ptype) 110 109 item1_5.setEditable(False) 111 110 poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5]) … … 458 457 returning the modified (deep) copy of the kernel. 459 458 """ 460 assert (isinstance(results, dict))459 assert isinstance(results, dict) 461 460 local_kernel = copy.deepcopy(kernel) 462 461 … … 479 478 for row in range(num_rows): 480 479 param_name = model.item(row, 0).text() 481 checkbox_state = model.item(row, 0).checkState() == QtCore.Qt.Checked482 value = model.item(row, 1).text()480 checkbox_state = model.item(row, 0).checkState() == QtCore.Qt.Checked 481 value = model.item(row, 1).text() 483 482 column_shift = 0 484 483 if model.columnCount() == 5: # no error column … … 509 508 """ 510 509 param = [] 511 if kernel_module is None: 510 if kernel_module is None: 512 511 return None 513 512 for param_name in list(kernel_module.params.keys()): … … 526 525 527 526 return param 527 528 def formatParameters(parameters): 529 """ 530 Prepare the parameter string in the standard SasView layout 531 """ 532 assert parameters is not None 533 assert isinstance(parameters, list) 534 output_string = "sasview_parameter_values:" 535 for parameter in parameters: 536 output_string += ",".join([p for p in parameter if p is not None]) 537 output_string += ":" 538 return output_string 539 540 def formatParametersExcel(parameters): 541 """ 542 Prepare the parameter string in the Excel format (tab delimited) 543 """ 544 assert parameters is not None 545 assert isinstance(parameters, list) 546 crlf = chr(13) + chr(10) 547 tab = chr(9) 548 549 output_string = "" 550 # names 551 names = "" 552 values = "" 553 for parameter in parameters: 554 names += parameter[0]+tab 555 # Add the error column if fitted 556 if parameter[1] == "True" and parameter[3] is not None: 557 names += parameter[0]+"_err"+tab 558 559 values += parameter[2]+tab 560 if parameter[1] == "True" and parameter[3] is not None: 561 values += parameter[3]+tab 562 # add .npts and .nsigmas when necessary 563 if parameter[0][-6:] == ".width": 564 names += parameter[0].replace('.width', '.nsigmas') + tab 565 names += parameter[0].replace('.width', '.npts') + tab 566 values += parameter[5] + tab + parameter[4] + tab 567 568 output_string = names + crlf + values 569 return output_string 570 571 def formatParametersLatex(parameters): 572 """ 573 Prepare the parameter string in latex 574 """ 575 assert parameters is not None 576 assert isinstance(parameters, list) 577 output_string = r'\begin{table}' 578 output_string += r'\begin{tabular}[h]' 579 580 crlf = chr(13) + chr(10) 581 output_string += '{|' 582 output_string += 'l|l|'*len(parameters) 583 output_string += r'}\hline' 584 output_string += crlf 585 586 for index, parameter in enumerate(parameters): 587 name = parameter[0] # Parameter name 588 output_string += name.replace('_', r'\_') # Escape underscores 589 # Add the error column if fitted 590 if parameter[1] == "True" and parameter[3] is not None: 591 output_string += ' & ' 592 output_string += parameter[0]+r'\_err' 593 594 if index < len(parameters) - 1: 595 output_string += ' & ' 596 597 # add .npts and .nsigmas when necessary 598 if parameter[0][-6:] == ".width": 599 output_string += parameter[0].replace('.width', '.nsigmas') + ' & ' 600 output_string += parameter[0].replace('.width', '.npts') 601 602 if index < len(parameters) - 1: 603 output_string += ' & ' 604 605 output_string += r'\\ \hline' 606 output_string += crlf 607 608 # Construct row of values and errors 609 for index, parameter in enumerate(parameters): 610 output_string += parameter[2] 611 if parameter[1] == "True" and parameter[3] is not None: 612 output_string += ' & ' 613 output_string += parameter[3] 614 615 if index < len(parameters) - 1: 616 output_string += ' & ' 617 618 # add .npts and .nsigmas when necessary 619 if parameter[0][-6:] == ".width": 620 output_string += parameter[5] + ' & ' 621 output_string += parameter[4] 622 623 if index < len(parameters) - 1: 624 output_string += ' & ' 625 626 output_string += r'\\ \hline' 627 output_string += crlf 628 output_string += r'\end{tabular}' 629 output_string += r'\end{table}' 630 631 return output_string -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r14acf92 r8e2cd79 1 1 import json 2 2 import os 3 import copy4 3 from collections import defaultdict 5 4 … … 70 69 """ 71 70 def __init__(self, parent=None): 72 QtGui.QStandardItemModel.__init__(self, parent)71 QtGui.QStandardItemModel.__init__(self, parent) 73 72 74 73 def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole): … … 153 152 def logic(self): 154 153 # make sure the logic contains at least one element 155 assert (self._logic)154 assert self._logic 156 155 # logic connected to the currently shown data 157 156 return self._logic[self.data_index] … … 208 207 self.is_chain_fitting = False 209 208 # Is the fit job running? 210 self.fit_started =False209 self.fit_started = False 211 210 # The current fit thread 212 211 self.calc_fit = None … … 517 516 self.communicate.saveAnalysisSignal.connect(self.savePageState) 518 517 self.smearing_widget.smearingChangedSignal.connect(self.onSmearingOptionsUpdate) 519 #self.communicate.saveReportSignal.connect(self.saveReport) 518 self.communicate.copyFitParamsSignal.connect(self.onParameterCopy) 519 self.communicate.pasteFitParamsSignal.connect(self.onParameterPaste) 520 520 521 521 def modelName(self): … … 557 557 return menu 558 558 # Select for fitting 559 param_string = "parameter " if num_rows ==1 else "parameters "560 to_string = "to its current value" if num_rows ==1 else "to their current values"559 param_string = "parameter " if num_rows == 1 else "parameters " 560 to_string = "to its current value" if num_rows == 1 else "to their current values" 561 561 has_constraints = any([self.rowHasConstraint(i) for i in rows]) 562 562 … … 613 613 # There have to be only two rows selected. The caller takes care of that 614 614 # but let's check the correctness. 615 assert (len(selected_rows)==2)615 assert len(selected_rows) == 2 616 616 617 617 params_list = [s.data() for s in selected_rows] … … 680 680 """ 681 681 # Create a new item and add the Constraint object as a child 682 assert (isinstance(constraint, Constraint))683 assert (0<=row<=self._model_model.rowCount())682 assert isinstance(constraint, Constraint) 683 assert 0 <= row <= self._model_model.rowCount() 684 684 685 685 item = QtGui.QStandardItem() … … 732 732 Delete constraints from selected parameters. 733 733 """ 734 params = 734 params = [s.data() for s in self.lstParams.selectionModel().selectedRows() 735 735 if self.isCheckable(s.row())] 736 736 for param in params: … … 783 783 Finds out if row of the main model has a constraint child 784 784 """ 785 item = self._model_model.item(row, 1)785 item = self._model_model.item(row, 1) 786 786 if item.hasChildren(): 787 787 c = item.child(0).data() … … 794 794 Finds out if row of the main model has an active constraint child 795 795 """ 796 item = self._model_model.item(row, 1)796 item = self._model_model.item(row, 1) 797 797 if item.hasChildren(): 798 798 c = item.child(0).data() … … 805 805 Finds out if row of the main model has an active, nontrivial constraint child 806 806 """ 807 item = self._model_model.item(row, 1)807 item = self._model_model.item(row, 1) 808 808 if item.hasChildren(): 809 809 c = item.child(0).data() … … 1443 1443 qmax = self.q_range_max 1444 1444 params_to_fit = self.parameters_to_fit 1445 if (not params_to_fit):1445 if not params_to_fit: 1446 1446 raise ValueError('Fitting requires at least one parameter to optimize.') 1447 1447 … … 1562 1562 self.has_error_column = True 1563 1563 1564 def iterateOverPolyModel(self, func): 1565 """ 1566 Take func and throw it inside the poly model row loop 1567 """ 1568 for row_i in range(self._poly_model.rowCount()): 1569 func(row_i) 1570 1564 1571 def updatePolyModelFromList(self, param_dict): 1565 1572 """ … … 1569 1576 if not dict: 1570 1577 return 1571 1572 def iterateOverPolyModel(func):1573 """1574 Take func and throw it inside the poly model row loop1575 """1576 for row_i in range(self._poly_model.rowCount()):1577 func(row_i)1578 1578 1579 1579 def updateFittedValues(row_i): … … 1613 1613 # updating charts with every single model change on the end of fitting 1614 1614 self._poly_model.blockSignals(True) 1615 iterateOverPolyModel(updateFittedValues)1615 self.iterateOverPolyModel(updateFittedValues) 1616 1616 self._poly_model.blockSignals(False) 1617 1617 … … 1621 1621 self.lstPoly.itemDelegate().addErrorColumn() 1622 1622 error_column = [] 1623 iterateOverPolyModel(createErrorColumn)1623 self.iterateOverPolyModel(createErrorColumn) 1624 1624 1625 1625 # switch off reponse to model change … … 1630 1630 1631 1631 self.has_poly_error_column = True 1632 1633 def iterateOverMagnetModel(self, func): 1634 """ 1635 Take func and throw it inside the magnet model row loop 1636 """ 1637 for row_i in range(self._model_model.rowCount()): 1638 func(row_i) 1632 1639 1633 1640 def updateMagnetModelFromList(self, param_dict): … … 1679 1686 # updating charts with every single model change on the end of fitting 1680 1687 self._magnet_model.blockSignals(True) 1681 iterateOverMagnetModel(updateFittedValues)1688 self.iterateOverMagnetModel(updateFittedValues) 1682 1689 self._magnet_model.blockSignals(False) 1683 1690 … … 1687 1694 self.lstMagnetic.itemDelegate().addErrorColumn() 1688 1695 error_column = [] 1689 iterateOverMagnetModel(createErrorColumn)1696 self.iterateOverMagnetModel(createErrorColumn) 1690 1697 1691 1698 # switch off reponse to model change … … 2803 2810 #self._copy_parameters_state(self.fixed_param, self.state.fixed_param) 2804 2811 2805 2812 def onParameterCopy(self, format=None): 2813 """ 2814 Copy current parameters into the clipboard 2815 """ 2816 # run a loop over all parameters and pull out 2817 # first - regular params 2818 param_list = [] 2819 def gatherParams(row): 2820 """ 2821 Create list of main parameters based on _model_model 2822 """ 2823 param_name = str(self._model_model.item(row, 0).text()) 2824 param_checked = str(self._model_model.item(row, 0).checkState() == QtCore.Qt.Checked) 2825 param_value = str(self._model_model.item(row, 1).text()) 2826 param_error = None 2827 column_offset = 0 2828 if self.has_error_column: 2829 param_error = str(self._model_model.item(row, 2).text()) 2830 column_offset = 1 2831 param_min = str(self._model_model.item(row, 2+column_offset).text()) 2832 param_max = str(self._model_model.item(row, 3+column_offset).text()) 2833 param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 2834 2835 def gatherPolyParams(row): 2836 """ 2837 Create list of polydisperse parameters based on _poly_model 2838 """ 2839 param_name = str(self._poly_model.item(row, 0).text()).split()[-1] 2840 param_checked = str(self._poly_model.item(row, 0).checkState() == QtCore.Qt.Checked) 2841 param_value = str(self._poly_model.item(row, 1).text()) 2842 param_error = None 2843 column_offset = 0 2844 if self.has_poly_error_column: 2845 param_error = str(self._poly_model.item(row, 2).text()) 2846 column_offset = 1 2847 param_min = str(self._poly_model.item(row, 2+column_offset).text()) 2848 param_max = str(self._poly_model.item(row, 3+column_offset).text()) 2849 param_npts = str(self._poly_model.item(row, 4+column_offset).text()) 2850 param_nsigs = str(self._poly_model.item(row, 5+column_offset).text()) 2851 param_fun = str(self._poly_model.item(row, 6+column_offset).text()).rstrip() 2852 # width 2853 name = param_name+".width" 2854 param_list.append([name, param_checked, param_value, param_error, 2855 param_npts, param_nsigs, param_min, param_max, param_fun]) 2856 2857 def gatherMagnetParams(row): 2858 """ 2859 Create list of magnetic parameters based on _magnet_model 2860 """ 2861 param_name = str(self._magnet_model.item(row, 0).text()) 2862 param_checked = str(self._magnet_model.item(row, 0).checkState() == QtCore.Qt.Checked) 2863 param_value = str(self._magnet_model.item(row, 1).text()) 2864 param_error = None 2865 column_offset = 0 2866 if self.has_magnet_error_column: 2867 param_error = str(self._magnet_model.item(row, 2).text()) 2868 column_offset = 1 2869 param_min = str(self._magnet_model.item(row, 2+column_offset).text()) 2870 param_max = str(self._magnet_model.item(row, 3+column_offset).text()) 2871 param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 2872 2873 self.iterateOverModel(gatherParams) 2874 if self.chkPolydispersity.isChecked(): 2875 self.iterateOverPolyModel(gatherPolyParams) 2876 if self.chkMagnetism.isChecked() and self.chkMagnetism.isEnabled(): 2877 self.iterateOverMagnetModel(sgatherMagnetParams) 2878 2879 if format=="": 2880 formatted_output = FittingUtilities.formatParameters(param_list) 2881 elif format == "Excel": 2882 formatted_output = FittingUtilities.formatParametersExcel(param_list) 2883 elif format == "Latex": 2884 formatted_output = FittingUtilities.formatParametersLatex(param_list) 2885 else: 2886 raise AttributeError("Bad format specifier.") 2887 2888 # Dump formatted_output to the clipboard 2889 cb = QtWidgets.QApplication.clipboard() 2890 cb.setText(formatted_output) 2891 2892 def onParameterPaste(self): 2893 """ 2894 Use the clipboard to update fit state 2895 """ 2896 # Check if the clipboard contains right stuff 2897 cb = QtWidgets.QApplication.clipboard() 2898 cb_text = cb.text() 2899 2900 context = {} 2901 # put the text into dictionary 2902 lines = cb_text.split(':') 2903 if lines[0] != 'sasview_parameter_values': 2904 return False 2905 for line in lines[1:-1]: 2906 if len(line) != 0: 2907 item = line.split(',') 2908 check = item[1] 2909 name = item[0] 2910 value = item[2] 2911 # Transfer the text to content[dictionary] 2912 context[name] = [check, value] 2913 2914 # limits 2915 limit_lo = item[3] 2916 context[name].append(limit_lo) 2917 limit_hi = item[4] 2918 context[name].append(limit_hi) 2919 2920 # Polydisp 2921 if len(item) > 5: 2922 value = item[5] 2923 context[name].append(value) 2924 try: 2925 value = item[6] 2926 context[name].append(value) 2927 value = item[7] 2928 context[name].append(value) 2929 except IndexError: 2930 pass 2931 2932 self.updateFullModel(context) 2933 self.updateFullPolyModel(context) 2934 2935 def updateFullModel(self, param_dict): 2936 """ 2937 Update the model with new parameters 2938 """ 2939 assert isinstance(param_dict, dict) 2940 if not dict: 2941 return 2942 2943 def updateFittedValues(row): 2944 # Utility function for main model update 2945 # internal so can use closure for param_dict 2946 param_name = str(self._model_model.item(row, 0).text()) 2947 if param_name not in list(param_dict.keys()): 2948 return 2949 # checkbox state 2950 param_checked = QtCore.Qt.Checked if param_dict[param_name][0] == "True" else QtCore.Qt.Unchecked 2951 self._model_model.item(row, 0).setCheckState(param_checked) 2952 2953 # modify the param value 2954 param_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 2955 self._model_model.item(row, 1).setText(param_repr) 2956 2957 # Potentially the error column 2958 ioffset = 0 2959 if len(param_dict[param_name])>4 and self.has_error_column: 2960 # error values are not editable - no need to update 2961 #error_repr = GuiUtils.formatNumber(param_dict[param_name][2], high=True) 2962 #self._model_model.item(row, 2).setText(error_repr) 2963 ioffset = 1 2964 # min/max 2965 param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 2966 self._model_model.item(row, 2+ioffset).setText(param_repr) 2967 param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 2968 self._model_model.item(row, 3+ioffset).setText(param_repr) 2969 2970 # block signals temporarily, so we don't end up 2971 # updating charts with every single model change on the end of fitting 2972 self._model_model.blockSignals(True) 2973 self.iterateOverModel(updateFittedValues) 2974 self._model_model.blockSignals(False) 2975 2976 def updateFullPolyModel(self, param_dict): 2977 """ 2978 Update the polydispersity model with new parameters, create the errors column 2979 """ 2980 assert isinstance(param_dict, dict) 2981 if not dict: 2982 return 2983 2984 def updateFittedValues(row): 2985 # Utility function for main model update 2986 # internal so can use closure for param_dict 2987 if row >= self._poly_model.rowCount(): 2988 return 2989 param_name = str(self._poly_model.item(row, 0).text()).rsplit()[-1] + '.width' 2990 if param_name not in list(param_dict.keys()): 2991 return 2992 # checkbox state 2993 param_checked = QtCore.Qt.Checked if param_dict[param_name][0] == "True" else QtCore.Qt.Unchecked 2994 self._poly_model.item(row,0).setCheckState(param_checked) 2995 2996 # modify the param value 2997 param_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 2998 self._poly_model.item(row, 1).setText(param_repr) 2999 3000 # Potentially the error column 3001 ioffset = 0 3002 if len(param_dict[param_name])>4 and self.has_poly_error_column: 3003 ioffset = 1 3004 # min 3005 param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 3006 self._poly_model.item(row, 2+ioffset).setText(param_repr) 3007 # max 3008 param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 3009 self._poly_model.item(row, 3+ioffset).setText(param_repr) 3010 # Npts 3011 param_repr = GuiUtils.formatNumber(param_dict[param_name][4+ioffset], high=True) 3012 self._poly_model.item(row, 4+ioffset).setText(param_repr) 3013 # Nsigs 3014 param_repr = GuiUtils.formatNumber(param_dict[param_name][5+ioffset], high=True) 3015 self._poly_model.item(row, 5+ioffset).setText(param_repr) 3016 3017 param_repr = GuiUtils.formatNumber(param_dict[param_name][5+ioffset], high=True) 3018 self._poly_model.item(row, 5+ioffset).setText(param_repr) 3019 3020 # block signals temporarily, so we don't end up 3021 # updating charts with every single model change on the end of fitting 3022 self._poly_model.blockSignals(True) 3023 self.iterateOverPolyModel(updateFittedValues) 3024 self._poly_model.blockSignals(False) 3025 3026 -
src/sas/qtgui/Perspectives/Fitting/ViewDelegate.py
rcf8d6c9 r8e2cd79 288 288 rect = textRect.topLeft() 289 289 y = rect.y() 290 y += 5.0 # magic value for rendering nice display in the table290 y += 6.0 # magic value for rendering nice display in the table 291 291 rect.setY(y) 292 292 painter.translate(rect) -
src/sas/qtgui/Utilities/GuiUtils.py
r6ff103a r8e2cd79 254 254 # Mask Editor requested 255 255 maskEditorSignal = QtCore.pyqtSignal(Data2D) 256 257 # Fitting parameter copy to clipboard 258 copyFitParamsSignal = QtCore.pyqtSignal(str) 259 260 # Fitting parameter paste from clipboard 261 pasteFitParamsSignal = QtCore.pyqtSignal() 256 262 257 263 def updateModelItemWithPlot(item, update_data, name=""):
Note: See TracChangeset
for help on using the changeset viewer.