Changeset 8e2cd79 in sasview for src/sas/qtgui/Perspectives/Fitting
- Timestamp:
- Aug 3, 2018 6:30:04 AM (6 years ago)
- 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:
- 04972ea
- Parents:
- cf8d6c9
- git-author:
- Piotr Rozyczko <rozyczko@…> (08/03/18 05:57:48)
- git-committer:
- Piotr Rozyczko <rozyczko@…> (08/03/18 06:30:04)
- Location:
- src/sas/qtgui/Perspectives/Fitting
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
r57be490 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]) … … 434 433 returning the modified (deep) copy of the kernel. 435 434 """ 436 assert (isinstance(results, dict))435 assert isinstance(results, dict) 437 436 local_kernel = copy.deepcopy(kernel) 438 437 … … 455 454 for row in range(num_rows): 456 455 param_name = model.item(row, 0).text() 457 checkbox_state = model.item(row, 0).checkState() == QtCore.Qt.Checked458 value = model.item(row, 1).text()456 checkbox_state = model.item(row, 0).checkState() == QtCore.Qt.Checked 457 value = model.item(row, 1).text() 459 458 column_shift = 0 460 459 if model.columnCount() == 5: # no error column … … 485 484 """ 486 485 param = [] 487 if kernel_module is None: 486 if kernel_module is None: 488 487 return None 489 488 for param_name in list(kernel_module.params.keys()): … … 502 501 503 502 return param 503 504 def formatParameters(parameters): 505 """ 506 Prepare the parameter string in the standard SasView layout 507 """ 508 assert parameters is not None 509 assert isinstance(parameters, list) 510 output_string = "sasview_parameter_values:" 511 for parameter in parameters: 512 output_string += ",".join([p for p in parameter if p is not None]) 513 output_string += ":" 514 return output_string 515 516 def formatParametersExcel(parameters): 517 """ 518 Prepare the parameter string in the Excel format (tab delimited) 519 """ 520 assert parameters is not None 521 assert isinstance(parameters, list) 522 crlf = chr(13) + chr(10) 523 tab = chr(9) 524 525 output_string = "" 526 # names 527 names = "" 528 values = "" 529 for parameter in parameters: 530 names += parameter[0]+tab 531 # Add the error column if fitted 532 if parameter[1] == "True" and parameter[3] is not None: 533 names += parameter[0]+"_err"+tab 534 535 values += parameter[2]+tab 536 if parameter[1] == "True" and parameter[3] is not None: 537 values += parameter[3]+tab 538 # add .npts and .nsigmas when necessary 539 if parameter[0][-6:] == ".width": 540 names += parameter[0].replace('.width', '.nsigmas') + tab 541 names += parameter[0].replace('.width', '.npts') + tab 542 values += parameter[5] + tab + parameter[4] + tab 543 544 output_string = names + crlf + values 545 return output_string 546 547 def formatParametersLatex(parameters): 548 """ 549 Prepare the parameter string in latex 550 """ 551 assert parameters is not None 552 assert isinstance(parameters, list) 553 output_string = r'\begin{table}' 554 output_string += r'\begin{tabular}[h]' 555 556 crlf = chr(13) + chr(10) 557 output_string += '{|' 558 output_string += 'l|l|'*len(parameters) 559 output_string += r'}\hline' 560 output_string += crlf 561 562 for index, parameter in enumerate(parameters): 563 name = parameter[0] # Parameter name 564 output_string += name.replace('_', r'\_') # Escape underscores 565 # Add the error column if fitted 566 if parameter[1] == "True" and parameter[3] is not None: 567 output_string += ' & ' 568 output_string += parameter[0]+r'\_err' 569 570 if index < len(parameters) - 1: 571 output_string += ' & ' 572 573 # add .npts and .nsigmas when necessary 574 if parameter[0][-6:] == ".width": 575 output_string += parameter[0].replace('.width', '.nsigmas') + ' & ' 576 output_string += parameter[0].replace('.width', '.npts') 577 578 if index < len(parameters) - 1: 579 output_string += ' & ' 580 581 output_string += r'\\ \hline' 582 output_string += crlf 583 584 # Construct row of values and errors 585 for index, parameter in enumerate(parameters): 586 output_string += parameter[2] 587 if parameter[1] == "True" and parameter[3] is not None: 588 output_string += ' & ' 589 output_string += parameter[3] 590 591 if index < len(parameters) - 1: 592 output_string += ' & ' 593 594 # add .npts and .nsigmas when necessary 595 if parameter[0][-6:] == ".width": 596 output_string += parameter[5] + ' & ' 597 output_string += parameter[4] 598 599 if index < len(parameters) - 1: 600 output_string += ' & ' 601 602 output_string += r'\\ \hline' 603 output_string += crlf 604 output_string += r'\end{tabular}' 605 output_string += r'\end{table}' 606 607 return output_string -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
rdc71408 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() … … 1440 1440 qmax = self.q_range_max 1441 1441 params_to_fit = self.parameters_to_fit 1442 if (not params_to_fit):1442 if not params_to_fit: 1443 1443 raise ValueError('Fitting requires at least one parameter to optimize.') 1444 1444 … … 1559 1559 self.has_error_column = True 1560 1560 1561 def iterateOverPolyModel(self, func): 1562 """ 1563 Take func and throw it inside the poly model row loop 1564 """ 1565 for row_i in range(self._poly_model.rowCount()): 1566 func(row_i) 1567 1561 1568 def updatePolyModelFromList(self, param_dict): 1562 1569 """ … … 1566 1573 if not dict: 1567 1574 return 1568 1569 def iterateOverPolyModel(func):1570 """1571 Take func and throw it inside the poly model row loop1572 """1573 for row_i in range(self._poly_model.rowCount()):1574 func(row_i)1575 1575 1576 1576 def updateFittedValues(row_i): … … 1610 1610 # updating charts with every single model change on the end of fitting 1611 1611 self._poly_model.blockSignals(True) 1612 iterateOverPolyModel(updateFittedValues)1612 self.iterateOverPolyModel(updateFittedValues) 1613 1613 self._poly_model.blockSignals(False) 1614 1614 … … 1618 1618 self.lstPoly.itemDelegate().addErrorColumn() 1619 1619 error_column = [] 1620 iterateOverPolyModel(createErrorColumn)1620 self.iterateOverPolyModel(createErrorColumn) 1621 1621 1622 1622 # switch off reponse to model change … … 1628 1628 self.has_poly_error_column = True 1629 1629 1630 def iterateOverMagnetModel(self, func): 1631 """ 1632 Take func and throw it inside the magnet model row loop 1633 """ 1634 for row_i in range(self._model_model.rowCount()): 1635 func(row_i) 1636 1630 1637 def updateMagnetModelFromList(self, param_dict): 1631 1638 """ … … 1637 1644 if self._magnet_model.rowCount() == 0: 1638 1645 return 1639 1640 def iterateOverMagnetModel(func):1641 """1642 Take func and throw it inside the magnet model row loop1643 """1644 for row_i in range(self._model_model.rowCount()):1645 func(row_i)1646 1646 1647 1647 def updateFittedValues(row): … … 1676 1676 # updating charts with every single model change on the end of fitting 1677 1677 self._magnet_model.blockSignals(True) 1678 iterateOverMagnetModel(updateFittedValues)1678 self.iterateOverMagnetModel(updateFittedValues) 1679 1679 self._magnet_model.blockSignals(False) 1680 1680 … … 1684 1684 self.lstMagnetic.itemDelegate().addErrorColumn() 1685 1685 error_column = [] 1686 iterateOverMagnetModel(createErrorColumn)1686 self.iterateOverMagnetModel(createErrorColumn) 1687 1687 1688 1688 # switch off reponse to model change … … 2793 2793 #self._copy_parameters_state(self.fixed_param, self.state.fixed_param) 2794 2794 2795 2795 def onParameterCopy(self, format=None): 2796 """ 2797 Copy current parameters into the clipboard 2798 """ 2799 # run a loop over all parameters and pull out 2800 # first - regular params 2801 param_list = [] 2802 def gatherParams(row): 2803 """ 2804 Create list of main parameters based on _model_model 2805 """ 2806 param_name = str(self._model_model.item(row, 0).text()) 2807 param_checked = str(self._model_model.item(row, 0).checkState() == QtCore.Qt.Checked) 2808 param_value = str(self._model_model.item(row, 1).text()) 2809 param_error = None 2810 column_offset = 0 2811 if self.has_error_column: 2812 param_error = str(self._model_model.item(row, 2).text()) 2813 column_offset = 1 2814 param_min = str(self._model_model.item(row, 2+column_offset).text()) 2815 param_max = str(self._model_model.item(row, 3+column_offset).text()) 2816 param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 2817 2818 def gatherPolyParams(row): 2819 """ 2820 Create list of polydisperse parameters based on _poly_model 2821 """ 2822 param_name = str(self._poly_model.item(row, 0).text()).split()[-1] 2823 param_checked = str(self._poly_model.item(row, 0).checkState() == QtCore.Qt.Checked) 2824 param_value = str(self._poly_model.item(row, 1).text()) 2825 param_error = None 2826 column_offset = 0 2827 if self.has_poly_error_column: 2828 param_error = str(self._poly_model.item(row, 2).text()) 2829 column_offset = 1 2830 param_min = str(self._poly_model.item(row, 2+column_offset).text()) 2831 param_max = str(self._poly_model.item(row, 3+column_offset).text()) 2832 param_npts = str(self._poly_model.item(row, 4+column_offset).text()) 2833 param_nsigs = str(self._poly_model.item(row, 5+column_offset).text()) 2834 param_fun = str(self._poly_model.item(row, 6+column_offset).text()).rstrip() 2835 # width 2836 name = param_name+".width" 2837 param_list.append([name, param_checked, param_value, param_error, 2838 param_npts, param_nsigs, param_min, param_max, param_fun]) 2839 2840 def gatherMagnetParams(row): 2841 """ 2842 Create list of magnetic parameters based on _magnet_model 2843 """ 2844 param_name = str(self._magnet_model.item(row, 0).text()) 2845 param_checked = str(self._magnet_model.item(row, 0).checkState() == QtCore.Qt.Checked) 2846 param_value = str(self._magnet_model.item(row, 1).text()) 2847 param_error = None 2848 column_offset = 0 2849 if self.has_magnet_error_column: 2850 param_error = str(self._magnet_model.item(row, 2).text()) 2851 column_offset = 1 2852 param_min = str(self._magnet_model.item(row, 2+column_offset).text()) 2853 param_max = str(self._magnet_model.item(row, 3+column_offset).text()) 2854 param_list.append([param_name, param_checked, param_value, param_error, param_min, param_max]) 2855 2856 self.iterateOverModel(gatherParams) 2857 if self.chkPolydispersity.isChecked(): 2858 self.iterateOverPolyModel(gatherPolyParams) 2859 if self.chkMagnetism.isChecked() and self.chkMagnetism.isEnabled(): 2860 self.iterateOverMagnetModel(sgatherMagnetParams) 2861 2862 if format=="": 2863 formatted_output = FittingUtilities.formatParameters(param_list) 2864 elif format == "Excel": 2865 formatted_output = FittingUtilities.formatParametersExcel(param_list) 2866 elif format == "Latex": 2867 formatted_output = FittingUtilities.formatParametersLatex(param_list) 2868 else: 2869 raise AttributeError("Bad format specifier.") 2870 2871 # Dump formatted_output to the clipboard 2872 cb = QtWidgets.QApplication.clipboard() 2873 cb.setText(formatted_output) 2874 2875 def onParameterPaste(self): 2876 """ 2877 Use the clipboard to update fit state 2878 """ 2879 # Check if the clipboard contains right stuff 2880 cb = QtWidgets.QApplication.clipboard() 2881 cb_text = cb.text() 2882 2883 context = {} 2884 # put the text into dictionary 2885 lines = cb_text.split(':') 2886 if lines[0] != 'sasview_parameter_values': 2887 return False 2888 for line in lines[1:-1]: 2889 if len(line) != 0: 2890 item = line.split(',') 2891 check = item[1] 2892 name = item[0] 2893 value = item[2] 2894 # Transfer the text to content[dictionary] 2895 context[name] = [check, value] 2896 2897 # limits 2898 limit_lo = item[3] 2899 context[name].append(limit_lo) 2900 limit_hi = item[4] 2901 context[name].append(limit_hi) 2902 2903 # Polydisp 2904 if len(item) > 5: 2905 value = item[5] 2906 context[name].append(value) 2907 try: 2908 value = item[6] 2909 context[name].append(value) 2910 value = item[7] 2911 context[name].append(value) 2912 except IndexError: 2913 pass 2914 2915 self.updateFullModel(context) 2916 self.updateFullPolyModel(context) 2917 2918 def updateFullModel(self, param_dict): 2919 """ 2920 Update the model with new parameters 2921 """ 2922 assert isinstance(param_dict, dict) 2923 if not dict: 2924 return 2925 2926 def updateFittedValues(row): 2927 # Utility function for main model update 2928 # internal so can use closure for param_dict 2929 param_name = str(self._model_model.item(row, 0).text()) 2930 if param_name not in list(param_dict.keys()): 2931 return 2932 # checkbox state 2933 param_checked = QtCore.Qt.Checked if param_dict[param_name][0] == "True" else QtCore.Qt.Unchecked 2934 self._model_model.item(row, 0).setCheckState(param_checked) 2935 2936 # modify the param value 2937 param_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 2938 self._model_model.item(row, 1).setText(param_repr) 2939 2940 # Potentially the error column 2941 ioffset = 0 2942 if len(param_dict[param_name])>4 and self.has_error_column: 2943 # error values are not editable - no need to update 2944 #error_repr = GuiUtils.formatNumber(param_dict[param_name][2], high=True) 2945 #self._model_model.item(row, 2).setText(error_repr) 2946 ioffset = 1 2947 # min/max 2948 param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 2949 self._model_model.item(row, 2+ioffset).setText(param_repr) 2950 param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 2951 self._model_model.item(row, 3+ioffset).setText(param_repr) 2952 2953 # block signals temporarily, so we don't end up 2954 # updating charts with every single model change on the end of fitting 2955 self._model_model.blockSignals(True) 2956 self.iterateOverModel(updateFittedValues) 2957 self._model_model.blockSignals(False) 2958 2959 def updateFullPolyModel(self, param_dict): 2960 """ 2961 Update the polydispersity model with new parameters, create the errors column 2962 """ 2963 assert isinstance(param_dict, dict) 2964 if not dict: 2965 return 2966 2967 def updateFittedValues(row): 2968 # Utility function for main model update 2969 # internal so can use closure for param_dict 2970 if row >= self._poly_model.rowCount(): 2971 return 2972 param_name = str(self._poly_model.item(row, 0).text()).rsplit()[-1] + '.width' 2973 if param_name not in list(param_dict.keys()): 2974 return 2975 # checkbox state 2976 param_checked = QtCore.Qt.Checked if param_dict[param_name][0] == "True" else QtCore.Qt.Unchecked 2977 self._poly_model.item(row,0).setCheckState(param_checked) 2978 2979 # modify the param value 2980 param_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 2981 self._poly_model.item(row, 1).setText(param_repr) 2982 2983 # Potentially the error column 2984 ioffset = 0 2985 if len(param_dict[param_name])>4 and self.has_poly_error_column: 2986 ioffset = 1 2987 # min 2988 param_repr = GuiUtils.formatNumber(param_dict[param_name][2+ioffset], high=True) 2989 self._poly_model.item(row, 2+ioffset).setText(param_repr) 2990 # max 2991 param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 2992 self._poly_model.item(row, 3+ioffset).setText(param_repr) 2993 # Npts 2994 param_repr = GuiUtils.formatNumber(param_dict[param_name][4+ioffset], high=True) 2995 self._poly_model.item(row, 4+ioffset).setText(param_repr) 2996 # Nsigs 2997 param_repr = GuiUtils.formatNumber(param_dict[param_name][5+ioffset], high=True) 2998 self._poly_model.item(row, 5+ioffset).setText(param_repr) 2999 3000 param_repr = GuiUtils.formatNumber(param_dict[param_name][5+ioffset], high=True) 3001 self._poly_model.item(row, 5+ioffset).setText(param_repr) 3002 3003 # block signals temporarily, so we don't end up 3004 # updating charts with every single model change on the end of fitting 3005 self._poly_model.blockSignals(True) 3006 self.iterateOverPolyModel(updateFittedValues) 3007 self._poly_model.blockSignals(False) 3008 3009 -
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)
Note: See TracChangeset
for help on using the changeset viewer.