- Timestamp:
- Apr 11, 2017 9:41:48 AM (8 years ago)
- 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.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- fc6651c
- Parents:
- 426df2e (diff), 97c60f8 (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. - Location:
- src/sas/sasgui
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sasgui/guiframe/gui_manager.py
r49165488 r38beeab 77 77 # clean all these module variables and put them into a config class 78 78 # that can be passed by sasview.py. 79 logger. info(sys.executable)80 logger. info(str(sys.argv))79 logger.debug(sys.executable) 80 logger.debug(str(sys.argv)) 81 81 from sas import sasview as sasview 82 82 app_path = os.path.dirname(sasview.__file__) 83 logger. info("Using application path: %s", app_path)83 logger.debug("Using application path: %s", app_path) 84 84 return app_path 85 85 … … 109 109 if fObj is not None: 110 110 fObj.close() 111 logger. info("GuiManager loaded %s/%s" % (path, file))111 logger.debug("GuiManager loaded %s/%s" % (path, file)) 112 112 return config_module 113 113 … … 126 126 # Didn't find local config, load the default 127 127 import sas.sasgui.guiframe.config as config 128 logger. info("using default local_config")128 logger.debug("using default local_config") 129 129 else: 130 logger. info("found local_config in %s" % os.getcwd())130 logger.debug("found local_config in %s" % os.getcwd()) 131 131 else: 132 logger. info("found local_config in %s" % PATH_APP)132 logger.debug("found local_config in %s" % PATH_APP) 133 133 134 134 from sas.sasgui.guiframe.customdir import SetupCustom … … 139 139 if custom_config is None: 140 140 msgConfig = "Custom_config file was not imported" 141 logger. info(msgConfig)141 logger.debug(msgConfig) 142 142 else: 143 logger. info("using custom_config in %s" % os.getcwd())143 logger.debug("using custom_config in %s" % os.getcwd()) 144 144 else: 145 logger. info("using custom_config from %s" % c_conf_dir)145 logger.debug("using custom_config from %s" % c_conf_dir) 146 146 147 147 # read some constants from config … … 2156 2156 if response is not None: 2157 2157 try: 2158 #2159 2158 content = response.read().strip() 2160 logger.info("Connected to www.sasview.org. Latest version: %s" 2161 % (content)) 2159 logger.info("Connected to www.sasview.org. Latest version: %s", content) 2162 2160 version_info = json.loads(content) 2163 2161 except: -
src/sas/sasgui/perspectives/calculator/sld_panel.py
r7432acb r2d220dd 60 60 # Object that receive status event 61 61 self.base = base 62 self.wavelength = WAVELENGTH 62 self.neutron_wavelength = WAVELENGTH 63 self.xray_source_input = WAVELENGTH 63 64 self.parent = parent 64 65 #layout attribute … … 67 68 self.compound = "" 68 69 self.density = "" 69 self.wavelength_ctl = None 70 self.neutron_wavelength_ctl = None 71 self.xray_source_input_ctl = None 72 self.xray_cbox = None 70 73 self.neutron_sld_real_ctl = None 71 74 self.neutron_sld_im_ctl = None 72 self.mo_ka_sld_real_ctl = None 73 self.mo_ka_sld_im_ctl = None 74 self.cu_ka_sld_real_ctl = None 75 self.cu_ka_sld_im_ctl = None 75 self.xray_sld_real_ctl = None 76 self.xray_sld_im_ctl = None 76 77 self.neutron_abs_ctl = None 77 78 self.neutron_inc_ctl = None 78 79 self.neutron_length_ctl = None 79 80 self.button_calculate = None 81 self.xray_source = None 80 82 #Draw the panel 81 83 self._do_layout() 82 84 self.SetAutoLayout(True) 83 85 self.Layout() 86 self.fill_xray_cbox() 84 87 85 88 def _do_layout(self): … … 108 111 self.density_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1)) 109 112 unit_density_txt = wx.StaticText(self, -1, unit_density) 110 wavelength_txt = wx.StaticText(self, -1, 'Wavelength ') 111 self.wavelength_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1)) 112 self.wavelength_ctl.SetValue(str(self.wavelength)) 113 unit_a_txt = wx.StaticText(self, -1, unit_a) 113 neutron_wavelength_txt = wx.StaticText(self, -1, 'Neutron wavelength') 114 self.neutron_wavelength_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1)) 115 self.neutron_wavelength_ctl.SetValue(str(self.neutron_wavelength)) 116 self.xray_source_input_txt = wx.StaticText(self, -1, 'X-ray wavelength') 117 self.xray_source_input_ctl = wx.TextCtrl(self, -1, size=(_BOX_WIDTH, -1)) 118 self.xray_source_input_ctl.SetValue(str(self.xray_source_input)) 119 neutron_unit_a_txt = wx.StaticText(self, -1, unit_a) 120 121 self.xray_cbox = wx.ComboBox(self, -1, size=(70, 20), style=wx.CB_READONLY) 122 xray_cbox_tip = "Select an element, wavelength or energy" 123 self.xray_cbox.SetToolTipString(xray_cbox_tip) 124 wx.EVT_COMBOBOX(self.xray_cbox, -1, self.on_select_xray) 125 114 126 iy = 0 115 127 ix = 0 … … 131 143 iy += 1 132 144 ix = 0 133 sizer_input.Add(wavelength_txt, (iy, ix), (1, 1), 134 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 135 ix += 1 136 sizer_input.Add(self.wavelength_ctl, (iy, ix), (1, 1), 137 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 138 ix += 1 139 sizer_input.Add(unit_a_txt, (iy, ix), (1, 1), 145 sizer_input.Add(neutron_wavelength_txt, (iy, ix), (1, 1), 146 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 147 ix += 1 148 sizer_input.Add(self.neutron_wavelength_ctl, (iy, ix), (1, 1), 149 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 150 ix += 1 151 sizer_input.Add(neutron_unit_a_txt, (iy, ix), (1, 1), 152 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 153 iy += 1 154 ix = 0 155 sizer_input.Add(self.xray_source_input_txt, (iy, ix), (1, 1), 156 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 157 ix += 1 158 sizer_input.Add(self.xray_source_input_ctl, (iy, ix), (1, 1), 159 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 160 ix += 1 161 sizer_input.Add(self.xray_cbox, (iy, ix), (1, 1), 140 162 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 141 163 boxsizer1.Add(sizer_input) … … 151 173 size=(_BOX_WIDTH, -1)) 152 174 self.neutron_sld_real_ctl.SetEditable(False) 153 self.neutron_sld_real_ctl.SetToolTipString("Neutron SLD real .")175 self.neutron_sld_real_ctl.SetToolTipString("Neutron SLD real") 154 176 self.neutron_sld_im_ctl = wx.TextCtrl(self, -1, 155 177 size=(_BOX_WIDTH, -1)) 156 178 self.neutron_sld_im_ctl.SetEditable(False) 157 self.neutron_sld_im_ctl.SetToolTipString("Neutron SLD imaginary .")179 self.neutron_sld_im_ctl.SetToolTipString("Neutron SLD imaginary") 158 180 neutron_sld_units_txt = wx.StaticText(self, -1, unit_sld) 159 181 160 cu_ka_sld_txt = wx.StaticText(self, -1, 'Cu KaSLD')161 self. cu_ka_sld_real_ctl = wx.TextCtrl(self, -1,182 xray_sld_txt = wx.StaticText(self, -1, 'X-ray SLD') 183 self.xray_sld_real_ctl = wx.TextCtrl(self, -1, 162 184 size=(_BOX_WIDTH, -1)) 163 self. cu_ka_sld_real_ctl.SetEditable(False)164 self. cu_ka_sld_real_ctl.SetToolTipString("Cu Ka SLD real.")165 self. cu_ka_sld_im_ctl = wx.TextCtrl(self, -1,185 self.xray_sld_real_ctl.SetEditable(False) 186 self.xray_sld_real_ctl.SetToolTipString("X-ray SLD real") 187 self.xray_sld_im_ctl = wx.TextCtrl(self, -1, 166 188 size=(_BOX_WIDTH, -1)) 167 self.cu_ka_sld_im_ctl.SetEditable(False) 168 self.cu_ka_sld_im_ctl.SetToolTipString("Cu Ka SLD imaginary.") 169 cu_ka_sld_units_txt = wx.StaticText(self, -1, unit_sld) 170 171 mo_ka_sld_txt = wx.StaticText(self, -1, 'Mo Ka SLD') 172 self.mo_ka_sld_real_ctl = wx.TextCtrl(self, -1, 173 size=(_BOX_WIDTH, -1)) 174 self.mo_ka_sld_real_ctl.SetEditable(False) 175 self.mo_ka_sld_real_ctl.SetToolTipString("Mo Ka SLD real.") 176 self.mo_ka_sld_im_ctl = wx.TextCtrl(self, -1, 177 size=(_BOX_WIDTH, -1)) 178 self.mo_ka_sld_im_ctl.SetEditable(False) 179 self.mo_ka_sld_im_ctl.SetToolTipString("Mo Ka SLD imaginary.") 180 mo_ka_sld_units_txt = wx.StaticText(self, -1, unit_sld) 189 self.xray_sld_im_ctl.SetEditable(False) 190 self.xray_sld_im_ctl.SetToolTipString("X-ray SLD imaginary") 191 xray_sld_units_txt = wx.StaticText(self, -1, unit_sld) 181 192 182 193 neutron_inc_txt = wx.StaticText(self, -1, 'Neutron Inc. Xs') … … 219 230 iy += 1 220 231 ix = 0 221 sizer_output.Add( cu_ka_sld_txt, (iy, ix), (1, 1),222 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 223 ix += 1 224 sizer_output.Add(self. cu_ka_sld_real_ctl, (iy, ix), (1, 1),232 sizer_output.Add(xray_sld_txt, (iy, ix), (1, 1), 233 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 234 ix += 1 235 sizer_output.Add(self.xray_sld_real_ctl, (iy, ix), (1, 1), 225 236 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 226 237 ix += 1 … … 228 239 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 229 240 ix += 1 230 sizer_output.Add(self. cu_ka_sld_im_ctl,241 sizer_output.Add(self.xray_sld_im_ctl, 231 242 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 232 243 ix += 1 233 sizer_output.Add(cu_ka_sld_units_txt, 234 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 235 iy += 1 236 ix = 0 237 sizer_output.Add(mo_ka_sld_txt, (iy, ix), (1, 1), 238 wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15) 239 ix += 1 240 sizer_output.Add(self.mo_ka_sld_real_ctl, (iy, ix), (1, 1), 241 wx.EXPAND | wx.ADJUST_MINSIZE, 0) 242 ix += 1 243 sizer_output.Add(wx.StaticText(self, -1, i_complex), 244 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 245 ix += 1 246 sizer_output.Add(self.mo_ka_sld_im_ctl, 247 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 248 ix += 1 249 sizer_output.Add(mo_ka_sld_units_txt, 244 sizer_output.Add(xray_sld_units_txt, 250 245 (iy, ix), (1, 1), wx.EXPAND | wx.ADJUST_MINSIZE, 0) 251 246 iy += 1 … … 310 305 self.SetSizer(vbox) 311 306 307 def fill_xray_cbox(self): 308 """ 309 fill the x-ray combobox with the sources 310 """ 311 source_list = ['[A]', '[keV]', 'Element'] 312 for source in source_list: 313 pos = self.xray_cbox.Append(str(source)) 314 self.xray_cbox.SetClientData(pos, str(source.strip())) 315 self.xray_cbox.SetSelection(0) 316 self.xray_source = source_list[0] 317 318 def on_select_xray(self, event=None): 319 """ 320 On Selecting a source 321 """ 322 item = event.GetEventObject() 323 self.xray_source = item.GetValue().strip() 324 325 if self.xray_source == "[A]": 326 self.xray_source_input_txt.SetLabel("X-ray wavelength") 327 elif self.xray_source == "[keV]": 328 self.xray_source_input_txt.SetLabel("X-ray energy") 329 elif self.xray_source == "Element": 330 self.xray_source_input_txt.SetLabel("X-ray source") 331 312 332 def on_help(self, event): 313 333 """ … … 363 383 msg += "Error for Density value :expect float" 364 384 365 self.wavelength = self.wavelength_ctl.GetValue() 366 if str(self.wavelength).lstrip().rstrip() == "": 367 self.wavelength = WAVELENGTH 368 self.wavelength_ctl.SetValue(str(WAVELENGTH)) 369 self.wavelength_ctl.SetBackgroundColour(wx.WHITE) 370 self.wavelength_ctl.Refresh() 385 self.neutron_wavelength = self.neutron_wavelength_ctl.GetValue() 386 self.xray_source_input = self.xray_source_input_ctl.GetValue() 387 388 if str(self.neutron_wavelength).lstrip().rstrip() == "": 389 self.neutron_wavelength = WAVELENGTH 390 self.neutron_wavelength_ctl.SetValue(str(WAVELENGTH)) 391 self.neutron_wavelength_ctl.SetBackgroundColour(wx.WHITE) 392 self.neutron_wavelength_ctl.Refresh() 371 393 msg += "Default value for wavelength is 6.0" 372 394 else: 373 if check_float(self. wavelength_ctl):374 self. wavelength = float(self.wavelength)395 if check_float(self.neutron_wavelength_ctl): 396 self.neutron_wavelength = float(self.neutron_wavelength) 375 397 else: 376 398 flag = False 377 399 msg += "Error for wavelength value :expect float" 400 401 if str(self.xray_source_input).lstrip().rstrip() == "": 402 self.xray_source_input = WAVELENGTH 403 self.xray_source_input_ctl.SetValue(str(WAVELENGTH)) 404 self.xray_source_input_ctl.SetBackgroundColour(wx.WHITE) 405 self.xray_source_input_ctl.Refresh() 406 msg += "Default value for wavelength is 6.0" 407 else: 408 if (self.xray_source == '[A]') or (self.xray_source == '[keV]'): 409 if check_float(self.xray_source_input_ctl): 410 self.xray_source_input = float(self.xray_source_input) 411 else: 412 flag = False 413 msg += "Error for wavelength value :expect float" 414 elif (self.xray_source == 'Element'): 415 try: 416 import periodictable 417 exec("periodictable." + self.xray_source_input) 418 except AttributeError: 419 flag = False 420 msg += "X-ray element supplied isn't in the database" 421 422 378 423 379 424 self.compound = self.compound_ctl.GetValue().lstrip().rstrip() … … 410 455 return xray_sld_from_atoms(atom, density=density, energy=energy) 411 456 412 413 457 def calculateSld(self, event): 414 458 """ … … 430 474 length = neutron_scattering(compound=self.compound, 431 475 density=self.density, 432 wavelength=self.wavelength) 433 cu_real, cu_im = self.calculate_sld_helper(element="Cu", 434 density=self.density, 435 molecule_formula=self.sld_formula) 436 mo_real, mo_im = self.calculate_sld_helper(element="Mo", 437 density=self.density, 438 molecule_formula=self.sld_formula) 476 wavelength=self.neutron_wavelength) 477 if self.xray_source == "[A]": 478 energy = xray_energy(self.xray_source_input) 479 xray_real, xray_im = xray_sld_from_atoms(self.sld_formula.atoms, 480 density=self.density, 481 energy=energy) 482 elif self.xray_source == "[keV]": 483 xray_real, xray_im = xray_sld_from_atoms(self.sld_formula.atoms, 484 density=self.density, 485 energy=self.xray_source_input) 486 elif self.xray_source == "Element": 487 xray_real, xray_im = self.calculate_sld_helper(element=self.xray_source_input, 488 density=self.density, 489 molecule_formula=self.sld_formula) 439 490 # set neutron sld values 440 491 val = format_number(sld_real * _SCALE) … … 443 494 self.neutron_sld_im_ctl.SetValue(val) 444 495 # Compute the Cu SLD 445 self.cu_ka_sld_real_ctl.SetValue(format_number(cu_real * _SCALE)) 446 val = format_number(math.fabs(cu_im) * _SCALE) 447 self.cu_ka_sld_im_ctl.SetValue(val) 448 # Compute the Mo SLD 449 self.mo_ka_sld_real_ctl.SetValue(format_number(mo_real * _SCALE)) 450 val = format_number(math.fabs(mo_im) * _SCALE) 451 self.mo_ka_sld_im_ctl.SetValue(val) 496 self.xray_sld_real_ctl.SetValue(format_number(xray_real * _SCALE)) 497 val = format_number(math.fabs(xray_im) * _SCALE) 498 self.xray_sld_im_ctl.SetValue(val) 452 499 # set incoherence and absorption 453 500 self.neutron_inc_ctl.SetValue(format_number(incoh)) … … 456 503 self.neutron_length_ctl.SetValue(format_number(length)) 457 504 # display wavelength 458 self.wavelength_ctl.SetValue(str(self.wavelength)) 505 #self.wavelength_ctl.SetValue(str(self.wavelength)) 506 #self.wavelength_ctl.SetValue(str(self.wavelength)) 459 507 except: 460 508 if self.base is not None: … … 470 518 self.neutron_sld_real_ctl.SetValue("") 471 519 self.neutron_sld_im_ctl.SetValue("") 472 self.mo_ka_sld_real_ctl.SetValue("") 473 self.mo_ka_sld_im_ctl.SetValue("") 474 self.cu_ka_sld_real_ctl.SetValue("") 475 self.cu_ka_sld_im_ctl.SetValue("") 520 self.xray_sld_real_ctl.SetValue("") 521 self.xray_sld_im_ctl.SetValue("") 476 522 self.neutron_abs_ctl.SetValue("") 477 523 self.neutron_inc_ctl.SetValue("") -
src/sas/sasgui/perspectives/fitting/fitting.py
r7432acb r426df2e 359 359 'Add a new model function') 360 360 wx.EVT_MENU(owner, wx_id, self.make_new_model) 361 361 362 362 wx_id = wx.NewId() 363 363 self.edit_model_menu.Append(wx_id, 'Sum|Multi(p1, p2)', … … 381 381 '(Re)Load all models present in user plugin_models folder') 382 382 wx.EVT_MENU(owner, wx_id, self.load_plugin_models) 383 383 384 384 def set_edit_menu_helper(self, owner=None, menu=None): 385 385 """ … … 1747 1747 data_id="Data " + data.name + " unsmeared", 1748 1748 dy=unsmeared_error) 1749 # Comment this out until we can get P*S models with correctly populated parameters 1750 #if sq_model is not None and pq_model is not None: 1751 # self.create_theory_1D(x, sq_model, page_id, model, data, state, 1752 # data_description=model.name + " S(q)", 1753 # data_id=str(page_id) + " " + data.name + " S(q)") 1754 # self.create_theory_1D(x, pq_model, page_id, model, data, state, 1755 # data_description=model.name + " P(q)", 1756 # data_id=str(page_id) + " " + data.name + " P(q)") 1749 if sq_model is not None and pq_model is not None: 1750 self.create_theory_1D(x, sq_model, page_id, model, data, state, 1751 data_description=model.name + " S(q)", 1752 data_id=str(page_id) + " " + data.name + " S(q)") 1753 self.create_theory_1D(x, pq_model, page_id, model, data, state, 1754 data_description=model.name + " P(q)", 1755 data_id=str(page_id) + " " + data.name + " P(q)") 1757 1756 1758 1757 current_pg = self.fit_panel.get_page_by_id(page_id) … … 1910 1909 ## and may be the cause of other noted instabilities 1911 1910 ## 1912 ## -PDB August 12, 2014 1911 ## -PDB August 12, 2014 1913 1912 while self.calc_2D.isrunning(): 1914 1913 time.sleep(0.1) … … 1952 1951 if (self.calc_1D is not None) and self.calc_1D.isrunning(): 1953 1952 self.calc_1D.stop() 1954 ## stop just raises the flag -- the thread is supposed to 1953 ## stop just raises the flag -- the thread is supposed to 1955 1954 ## then kill itself but cannot. Paul Kienzle came up with 1956 1955 ## this fix to prevent threads from stepping on each other … … 1964 1963 ## a request to stop the computation. 1965 1964 ## It seems thus that the whole thread approach used here 1966 ## May need rethinking 1965 ## May need rethinking 1967 1966 ## 1968 1967 ## -PDB August 12, 2014 … … 2129 2128 residuals.dxw = None 2130 2129 residuals.ytransform = 'y' 2131 # For latter scale changes 2130 # For latter scale changes 2132 2131 residuals.xaxis('\\rm{Q} ', 'A^{-1}') 2133 2132 residuals.yaxis('\\rm{Residuals} ', 'normalized') -
src/sas/sasgui/perspectives/fitting/model_thread.py
r7432acb r426df2e 71 71 (self.data.qy_data * self.data.qy_data)) 72 72 73 # For theory, qmax is based on 1d qmax 73 # For theory, qmax is based on 1d qmax 74 74 # so that must be mulitified by sqrt(2) to get actual max for 2d 75 75 index_model = (self.qmin <= radius) & (radius <= self.qmax) … … 91 91 self.data.qy_data[index_model] 92 92 ]) 93 output = np.zeros(len(self.data.qx_data)) 93 # Initialize output to NaN so masked elements do not get plotted. 94 output = np.empty_like(self.data.qx_data) 94 95 # output default is None 95 96 # This method is to distinguish between masked 96 97 #point(nan) and data point = 0. 97 output = output / output98 output[:] = np.NaN 98 99 # set value for self.mask==True, else still None to Plottools 99 100 output[index_model] = value … … 198 199 output[index] = self.model.evalDistribution(self.data.x[index]) 199 200 201 x=self.data.x[index] 202 y=output[index] 200 203 sq_values = None 201 204 pq_values = None 202 s_model = None203 p_model = None204 205 if isinstance(self.model, MultiplicationModel): 205 206 s_model = self.model.s_model 206 207 p_model = self.model.p_model 207 elif hasattr(self.model, "get_composition_models"):208 p _model, s_model = self.model.get_composition_models()209 210 if p_model is not None and s_model is not None:211 sq_values = np.zeros((len(self.data.x)))212 pq_values = np.zeros((len(self.data.x)))213 sq_values[index] = s_model.evalDistribution(self.data.x[index])214 pq_values[index] = p_model.evalDistribution(self.data.x[index]) 208 sq_values = s_model.evalDistribution(x) 209 pq_values = p_model.evalDistribution(x) 210 elif hasattr(self.model, "calc_composition_models"): 211 results = self.model.calc_composition_models(x) 212 if results is not None: 213 sq_values = results[0] 214 pq_values = results[1] 215 215 216 216 217 elapsed = time.time() - self.starttime 217 218 218 self.complete(x= self.data.x[index], y=output[index],219 self.complete(x=x, y=y, 219 220 page_id=self.page_id, 220 221 state=self.state,
Note: See TracChangeset
for help on using the changeset viewer.