def __init__(self, parent, label='', command=None, open_button=None, show_on_open=False): import Tkinter f = Tkinter.Frame(parent) self.frame = f from chimera.widgets import ModelOptionMenu m = ModelOptionMenu(f, labelpos='w', label_text=label, listFunc=volume_models, command=command) m.grid(row=0, column=0, sticky='w') self.menu = m if open_button: if not type(open_button) is str: open_button = 'Browse...' bb = Tkinter.Button(f, text=open_button, command=self.open_volume_cb) bb.grid(row=0, column=1, sticky='w') self.show_on_open = show_on_open
class WriteDmsDialog(SaveModeless): help = "UsersGuide/dms.html#writedms" oneshot = True def __init__(self): SaveModeless.__init__(self, clientPos='s', clientSticky='ewns', filters=[("DMS", "*.dms", ".dms")]) def fillInUI(self, parent): import Pmw, Tkinter SaveModeless.fillInUI(self, parent) self.clientArea.columnconfigure(0, weight=1) row = 0 from chimera.widgets import ModelOptionMenu self.surfList = ModelOptionMenu( self.clientArea, labelpos='w', label_text="Save surface:", filtFunc=lambda m: isinstance(m, MSMSModel)) self.surfList.grid(row=row, column=0) row += 1 self.saveNormalsVar = Tkinter.IntVar(self.clientArea) self.saveNormalsVar.set(True) Tkinter.Checkbutton(self.clientArea, text="Save normals", variable=self.saveNormalsVar).grid(row=row) row += 1 self.displayedOnlyVar = Tkinter.IntVar(self.clientArea) self.displayedOnlyVar.set(True) Tkinter.Checkbutton(self.clientArea, text="Limit output to" " displayed surface sections", variable=self.displayedOnlyVar).grid(row=row) row += 1 def Apply(self): path = self.getPaths()[0] surf = self.surfList.getvalue() if not surf: replyobj.error("No surface chosen to save.\n") return from WriteDMS import writeDMS replyobj.status("Writing DMS surface to %s\n" % path) writeDMS(surf, path, writeNormals=self.saveNormalsVar.get(), displayedOnly=self.displayedOnlyVar.get()) replyobj.status("Wrote DMS surface to %s\n" % path)
class WriteDmsDialog(SaveModeless): help = "UsersGuide/dms.html#writedms" oneshot = True def __init__(self): SaveModeless.__init__(self, clientPos='s', clientSticky='ewns', filters=[("DMS", "*.dms", ".dms")]) def fillInUI(self, parent): import Pmw, Tkinter SaveModeless.fillInUI(self, parent) self.clientArea.columnconfigure(0, weight=1) row = 0 from chimera.widgets import ModelOptionMenu self.surfList = ModelOptionMenu(self.clientArea, labelpos='w', label_text="Save surface:", filtFunc=lambda m: isinstance(m, MSMSModel)) self.surfList.grid(row=row, column=0) row += 1 self.saveNormalsVar = Tkinter.IntVar(self.clientArea) self.saveNormalsVar.set(True) Tkinter.Checkbutton(self.clientArea, text="Save normals", variable=self.saveNormalsVar).grid(row=row) row += 1 self.displayedOnlyVar = Tkinter.IntVar(self.clientArea) self.displayedOnlyVar.set(True) Tkinter.Checkbutton(self.clientArea, text="Limit output to" " displayed surface sections", variable=self.displayedOnlyVar).grid(row=row) row += 1 def Apply(self): path = self.getPaths()[0] surf = self.surfList.getvalue() if not surf: replyobj.error("No surface chosen to save.\n") return from WriteDMS import writeDMS replyobj.status("Writing DMS surface to %s\n" % path) writeDMS(surf, path, writeNormals=self.saveNormalsVar.get(), displayedOnly=self.displayedOnlyVar.get()) replyobj.status("Wrote DMS surface to %s\n" % path)
def __init__(self, parent, label = '', command = None, open_button = None, show_on_open = False): import Tkinter f = Tkinter.Frame(parent) self.frame = f from chimera.widgets import ModelOptionMenu m = ModelOptionMenu(f, labelpos = 'w', label_text = label, listFunc = volume_models, command = command) m.grid(row = 0, column = 0, sticky = 'w') self.menu = m if open_button: if not type(open_button) is str: open_button = 'Browse...' bb = Tkinter.Button(f, text = open_button, command = self.open_volume_cb) bb.grid(row = 0, column = 1, sticky = 'w') self.show_on_open = show_on_open
class WriteMol2Dialog(SaveModeless): keepShown = SaveModeless.default name = "write Mol2" help = "UsersGuide/savemodel.html#mol2" def __init__(self): self.prefs = preferences.addCategory("write Mol2 dialog", preferences.HiddenCategory, optDict={"multiSaveMol2": "multiple", "hydrogen naming": "sybyl", "residue numbers": True}) SaveModeless.__init__(self, clientPos='s', clientSticky='ewns', filters=[("Mol2", "*.mol2", ".mol2")]) openModels.addAddHandler(self._modelsChange, None) openModels.addRemoveHandler(self._modelsChange, None) self._modelsChange() def configure(self, models=None, refreshList=True, selOnly=None): if models is not None: if len(models) > 1: name = "Multiple Models " elif models: name = models[0].name + " " else: name = "" self._toplevel.title("Save %sas Mol2 File" % name) if refreshList: self.modelList.setvalue(models) if len(models) > 1: self.multiSaveMenu.grid(row=self._msmRow, column=0, sticky='w') else: self.multiSaveMenu.grid_forget() def fillInUI(self, parent): import Pmw, Tkinter SaveModeless.fillInUI(self, parent) row = 0 from chimera.widgets import MoleculeScrolledListBox, \ ModelOptionMenu self.modelList = MoleculeScrolledListBox(self.clientArea, labelpos='w', label_text="Save models:", listbox_selectmode='extended', selectioncommand=lambda: self.configure( self.modelList.getvalue(), refreshList=False)) self.modelList.grid(row=row, column=0, sticky='nsew') self.clientArea.rowconfigure(row, weight=1) self.clientArea.columnconfigure(0, weight=1) row += 1 from chimera import dialogs self.labelMap = { "individual": "a single file [individual @MOLECULE sections]", "combined": "a single file [combined @MOLECULE section]", "multiple": "multiple files [appending model number]" } preferred = self.labelMap[self.prefs["multiSaveMol2"]] self.multiSaveMenu = Pmw.OptionMenu(self.clientArea, labelpos='w', label_text="Save multiple models in", initialitem=preferred, items=self.labelMap.values()) # not always shown; remember row number self._msmRow = row row += 1 self.saveRelativeVar = Tkinter.IntVar(self.clientArea) self.saveRelativeVar.set(False) self.relativeFrame = f = Tkinter.Frame(self.clientArea) Tkinter.Checkbutton(f, variable=self.saveRelativeVar, text="Save relative to model:").grid(row=0, column=0, sticky='e') self.relModelMenu = ModelOptionMenu(f) self.relModelMenu.grid(row=0, column=1, sticky='w') self.saveUntransformedVar = Tkinter.IntVar(parent) self.saveUntransformedVar.set(True) self.untransformedButton = Tkinter.Checkbutton(self.clientArea, variable=self.saveUntransformedVar, text="Use untransformed coordinates") self._rfRow = row row += 1 self.sybylHydNamesVar = Tkinter.IntVar(self.clientArea) self.sybylHydNamesVar.set( self.prefs["hydrogen naming"] == "sybyl") Tkinter.Checkbutton(self.clientArea, variable=self.sybylHydNamesVar, text="Use Sybyl-style hydrogen naming (e.g. HE12" " rather than 2HE1)").grid(row=row, column=0, sticky="w") row += 1 self.resNumsVar = Tkinter.IntVar(self.clientArea) self.resNumsVar.set(self.prefs["residue numbers"]) Tkinter.Checkbutton(self.clientArea, variable=self.resNumsVar, text="Include residue sequence numbers in substructure" " names").grid(row=row, column=0, sticky='w') row += 1 self.writeGaffVar = Tkinter.IntVar(self.clientArea) self.resNumsVar.set(False) Tkinter.Checkbutton(self.clientArea, variable=self.writeGaffVar, text="Write Amber/GAFF atom types instead of Sybyl atom types" ).grid(row=row, column=0, sticky='w') row += 1 self.rigidVar = Tkinter.IntVar(self.clientArea) self.rigidVar.set(False) Tkinter.Checkbutton(self.clientArea, variable=self.rigidVar, text="Write current selection to @SETS section of file" ).grid(row=row, column=0, sticky="w") row += 1 def Apply(self): from chimera import dialogs kw = {'status': replyobj.status} paths = self.getPaths() if not paths: replyobj.error('No save location chosen.\n') return path = paths[0] models = self.modelList.getvalue() if not models: replyobj.error("No models chosen to save.\n") return if float(self.modelList.size()) > 1.5: if self.saveRelativeVar.get(): kw['relModel'] = self.relModelMenu.getvalue() else: if self.saveUntransformedVar.get(): kw['relModel'] = models[0] if self.writeGaffVar.get(): kw['gaffType'] = True from chimera import UserError kw['gaffFailError'] = UserError if self.rigidVar.get(): sel = selection.copyCurrent() sel.addImplied() selAtoms = sel.atoms() selBonds = sel.bonds() if selAtoms and selBonds: kw['anchor'] = sel sybylHydNaming = self.sybylHydNamesVar.get() if sybylHydNaming: self.prefs["hydrogen naming"] = "sybyl" else: self.prefs["hydrogen naming"] = "pdb" kw['hydNamingStyle'] = self.prefs["hydrogen naming"] kw['resNum'] = self.resNumsVar.get() from WriteMol2 import writeMol2 if len(models) < 2: replyobj.status("Writing %s to %s\n" % (models[0].name, path)) writeMol2(models, path, **kw) replyobj.status("Wrote %s to %s\n" % (models[0].name, path)) return saveOpt = self.multiSaveMenu.getvalue() for key, value in self.labelMap.items(): if saveOpt == value: break self.prefs["multiSaveMol2"] = key # write multiple models to multiple files if key == "multiple": if path.endswith(".mol2"): start, end = path[:-4], ".mol2" else: start, end = path, "" for m in models: modelPath = start + m.oslIdent()[1:] + end replyobj.status("Writing %s (%s) to %s\n" % (m.name, m.oslIdent(), modelPath)) writeMol2(m, modelPath, **kw) replyobj.status("Wrote %s (%s) to %s\n" % (m.name, m.oslIdent(), modelPath)) return kw["multimodelHandling"] = key # write multiple models to single file replyobj.status("Writing multiple models to %s\n" % path) writeMol2(models, path, **kw) replyobj.status("Wrote multiple models to %s\n" % path) def _modelsChange(self, *args): if len(openModels.listIds()) > 1: self.untransformedButton.grid_forget() self.relativeFrame.grid(row=self._rfRow, column=0, sticky='w') else: self.relativeFrame.grid_forget() self.untransformedButton.grid(row=self._rfRow, column=0, sticky='w')
def fillInUI(self, parent): self.requested_halt = False self.xform_handler = None self.last_relative_xform = None t = parent.winfo_toplevel() self.toplevel_widget = t t.withdraw() parent.columnconfigure(0, weight=1) row = 0 import Tkinter from CGLtk import Hybrid from VolumeViewer import Volume_Menu ff = Tkinter.Frame(parent) ff.grid(row=row, column=0, sticky='w') row = row + 1 from chimera.widgets import ModelOptionMenu om = ModelOptionMenu(ff, labelpos='w', label_text='Fit ', listFunc=fit_object_models, sortFunc=compare_fit_objects, command=self.object_chosen_cb) om.grid(row=0, column=0, sticky='w') self.object_menu = om fm = Volume_Menu(ff, ' in map ') fm.frame.grid(row=0, column=1, sticky='w') self.map_menu = fm gf = Tkinter.Frame(parent) gf.grid(row=row, column=0, sticky='w') row += 1 cl = Tkinter.Label(gf, text='Correlation') cl.grid(row=0, column=0, sticky='w') cv = Tkinter.Label(gf, width=6, anchor='w', relief=Tkinter.SUNKEN, borderwidth=2) cv.grid(row=0, column=1, padx=5, sticky='w') self.corr_label = cv al = Tkinter.Label(gf, text='Average map value') al.grid(row=0, column=2, sticky='w') av = Tkinter.Label(gf, width=6, anchor='w', relief=Tkinter.SUNKEN, borderwidth=2) av.grid(row=0, column=3, padx=5, sticky='w') self.ave_label = av ub = Tkinter.Button(gf, text='Update', command=self.update_metric_cb) ub.grid(row=0, column=4, sticky='w') op = Hybrid.Popup_Panel(parent) opf = op.frame opf.grid(row=row, column=0, sticky='news') opf.grid_remove() opf.columnconfigure(0, weight=1) self.options_panel = op.panel_shown_variable row += 1 orow = 0 cb = op.make_close_button(opf) cb.grid(row=orow, column=1, sticky='e') ru = Hybrid.Checkbutton(opf, 'Real-time correlation / average update', False) ru.button.grid(row=orow, column=0, sticky='w') orow += 1 self.realtime_update = ru.variable ru.callback(self.realtime_cb) sm = Hybrid.Checkbutton_Entries( opf, False, 'Use map simulated from atoms, resolution ', (4, '')) sm.frame.grid(row=orow, column=0, sticky='nw') orow += 1 self.simulate_map, self.map_resolution = sm.variables self.simulate_map.add_callback(self.simulate_map_cb) sm.entries[0].bind('<KeyPress-Return>', self.simulate_resolution_cb) dt = Hybrid.Checkbutton( opf, 'Use only data above contour level from first map', True) dt.button.grid(row=orow, column=0, sticky='w') orow += 1 dt.button['state'] = 'disabled' self.limit_data = dt self.above_threshold = dt.variable opt = Hybrid.Radiobutton_Row(opf, 'Optimize ', ('overlap', 'correlation')) opt.frame.grid(row=orow, column=0, sticky='w') orow += 1 self.optimize = opt.variable self.opt_widget = opt cam = Hybrid.Checkbutton( opf, 'Correlation calculated about mean data value', False) cam.button.grid(row=orow, column=0, sticky='w') orow += 1 cam.button['state'] = 'disabled' self.cam_widget = cam self.corr_about_mean = cam.variable al = Hybrid.Checkbutton_Row(opf, 'Allow ', ('rotation', 'shift')) al.frame.grid(row=orow, column=0, sticky='w') orow += 1 ar, ash = [c.variable for c in al.checkbuttons] ar.set(True) ash.set(True) self.allow_rotation = ar self.allow_shift = ash mm = Hybrid.Checkbutton(opf, 'Move whole molecules', True) mm.button.grid(row=orow, column=0, sticky='w') orow += 1 self.move_whole_molecules = mm.variable self.mwm_button = mm.button # # Specify a label width so dialog is not resized for long messages. # msg = Tkinter.Label(parent, width=40, anchor='w', justify='left') msg.grid(row=row, column=0, sticky='ew') row = row + 1 self.message_label = msg self.halt_button = self.buttonWidgets['Halt'] self.allow_halt(False) self.update_gray_out() self.activate_undo_redo()
class TrackXformDialog(ModelessDialog): """Class TrackXformDialog() Dialog for tracking transforms in Chimera's camera coordinates. """ title= 'Track Model Transfom' name = 'track model transformation' buttons = ('Close',) # @ help = 'ContributedSoftware/SegmentTrack/trackxform.html' dir_pkg = os.path.dirname(__file__) help_path = os.path.join(dir_pkg, 'trackxform.html') help_url = 'file://' + help_path help = help_url provideStatus = True statusPosition = 'above' statusResizing = False statusWidth = 40 # --------------------------------------------------------------------- # Fill in UI # --------------------------------------------------------------------- def fillInUI(self, parent): """fillInUI(parent) """ self.status('') self.track_xform = None # menu frame row = 0 from chimera.widgets import ModelOptionMenu self.menu = ModelOptionMenu(parent, command=self.menu_cb, labelpos='w', label_text='Model:') self.menu.grid(row=row, sticky='w', padx=8, pady=8) # initial transform frame (itf) row = row + 1 itf = Tkinter.Frame(parent,padx=8,pady=8) itf.grid(row=row, column=0, sticky='nw') # record initial itfg = Hybrid.Button_Row(itf, 'Record transform ', (('Record',self.record_initial_cb),)) itfg.frame.grid(row=0, column=0, columnspan=3, sticky='w') # parameters itfp = Tkinter.Frame(itf, padx=16) itfp.grid(row=1, column=0, sticky='w') self.init_trans, self.init_rot, self.init_ang = \ self._make_param_panel(itfp) # current transform frame (ctf) row = row + 1 ctf = Tkinter.Frame(parent, padx=8, pady=8) ctf.grid(row=row, column=0, sticky='nw') # get current ctfg = Hybrid.Button_Row(ctf, 'Current transform ', (('Get',self.record_current_cb),)) ctfg.frame.grid(row=0, column=0, sticky='w') # parameters ctfp = Tkinter.Frame(ctf, padx=16) ctfp.grid(row=1, column=0, sticky='w') self.curr_trans, self.curr_rot, self.curr_ang = \ self._make_param_panel(ctfp) # listbox frame row = row+1 from chimera.widgets import ModelScrolledListBox self.listbox = ModelScrolledListBox(parent, labelpos='w', label_text='Model List:') self.listbox.component('listbox')['selectmode'] = 'extended' self.listbox.grid(row=row, sticky='w', padx=8, pady=8) # apply frame (af) row = row + 1 af = Tkinter.Frame(parent, padx=8, pady=8) af.grid(row=row, column=0, sticky='nw') # apply afg = Hybrid.Button_Row(af, '', (('Apply',self.apply_initial_cb),)) afg.frame.grid(row=0, column=0, sticky='w') text = ' recorded transform to models\n' text = text + ' selected in above model list ' afgL = Tkinter.Label(af, text = text) afgL.grid(row=0, column=1, sticky='w') # reset afr = Hybrid.Button_Row(af, '', (('Reset',self.reset_initial_cb),)) afr.frame.grid(row=1, column=0, sticky='w') text = ' initial transform' afrL = Tkinter.Label(af, text = text) afrL.grid(row=1, column=1, sticky='w') def Close(self): """Close() - close dialog. """ ModelessDialog.Close(self) def menu_cb(self, val): return # --------------------------------------------------------------------- # Paramaters panel # --------------------------------------------------------------------- def _make_param_panel(self, frame): """_make_param_panel(frame) Input: frame Output: translation translation text entry rotation rotation text entry angle angle text entry Makes the parameters panel. """ row = 0 # translation transL = Tkinter.Label(frame, text='Translation: ') transL.grid(row=row, column=0, sticky='w') trans = Tkinter.Label(frame, text='') trans.grid(row=row, column=1, sticky='w') # rotation axis row = row + 1 rotL = Tkinter.Label(frame, text='Rotation Axes: ') rotL.grid(row=row, column=0, sticky='w') rot = Tkinter.Label(frame, text='') rot.grid(row=row, column=1, sticky='w') # rotation angle row = row + 1 angL = Tkinter.Label(frame, text='Rotation Angle: ') angL.grid(row=row, column=0, sticky='w') ang = Tkinter.Label(frame, text='') ang.grid(row=row, column=1, sticky='w') return trans, rot, ang # --------------------------------------------------------------------- # Call back functions # --------------------------------------------------------------------- def record_initial_cb(self): """record_initial_cb() - callback func for record transform. """ model = self.menu.getvalue() self.record_initial(model) def record_current_cb(self): """record_current_cb() - callback func for current transform. """ model = self.menu.getvalue() self.record_current(model) def apply_initial_cb(self): """apply_initial_cb() - callback function for apply button. """ models = self.listbox.getvalue() for model in models: self.update_current(model) model = self.menu.getvalue() self.record_current(model) def reset_initial_cb(self): """reset_initial_cb() - callback function for reset button. """ self.reset_initial() # --------------------------------------------------------------------- # Command line (for GUI) functions # --------------------------------------------------------------------- def set_model(self, model): """set_model(model) - set menu to model. """ self.menu.setvalue(model) def record_initial(self, model): """record_initial(model) - record and display model transform. """ if not model: msg = 'No initial model' self.status(msg, color='blue', blankAfter=5) self.track_xform = get_xform(model) self._display_param_initial(self.track_xform) def record_current(self, model): """record_current(model) - display current model transform. """ if not model: msg = 'No current model' self.status(msg, color='blue', blankAfter=5) self._display_param_current(model) def update_current(self, model): """update_current(model) - apply recorded transform to model. """ if not model: msg = 'No current model' self.status(msg, color='blue', blankAfter=5) if not self.track_xform: msg = 'No starting transform' self.status(msg, color='blue', blankAfter=5) update_xform(model, self.track_xform) def reset_initial(self): """reset_initial() - reset all parameters """ self.track_xform = None self._display_param_initial(None) self._display_param_current(None) # --------------------------------------------------------------------- # GUI functions for parameters # --------------------------------------------------------------------- def _display_param_initial(self, xform): """_display_param_initial(xform) - display initial transform. """ vx, ax, an = self.get_param(xform=xform) self.init_trans['text'] = vx self.init_rot['text'] = ax self.init_ang['text'] = an def _display_param_current(self, model): """_display_param_current(model) - display current transform. """ vx, ax, an = self.get_param(model=model) self.curr_trans['text'] = vx self.curr_rot['text'] = ax self.curr_ang['text'] = an def get_param(self, xform=None, model=None): """get_param(xform=None, model=None) - transform parameters. Input: xform=None model=None Output: translation rotation vector rotation angle Get transform parameters as text strings, one each for translation vector, rotation vector, and rotation angle. Return empty text strings for no model and no xform. """ if not xform: if model: xform = model.openState.xform else: return '','','' vx = xform.getTranslation() ax, an = xform.getRotation() vx_text = '(%7.3f, %7.3f, %7.3f)' % (vx.x, vx.y, vx.z) ax_text = '(%8.4f, %8.4f, %8.4f)' % (ax.x, ax.y, ax.z) an_text = '%7.3f' % (an) return vx_text, ax_text, an_text
class Measure_Stick(ModelessDialog): """Class: Measure_Stick() The main GUI dialog for measuring stick. """ title= 'Measure Stick' name = 'measure stick' buttons = ('Compute...','Close') help = '' # @ help = 'ContributedSoftware/MeasureStick/init.html' dir_pkg = os.path.dirname(__file__) help_path = os.path.join(dir_pkg, 'init.html') help_url = 'file://' + help_path help = help_url provideStatus = True statusPosition = 'above' statusResizing = False statusWidth = 40 # --------------------------------------------------------------------- # Fill in UI # --------------------------------------------------------------------- def fillInUI(self, parent): """fillInUI(parent) """ self.status('') self.volume_path_dialog = None parent.columnconfigure(0, weight=1) self.toplevel_widget = parent.winfo_toplevel() # @ whatisthis # parameters frame (pf) row = 0 pf = Tkinter.Frame(parent) pf.grid(row = row, column = 0, sticky = 'w',padx=8,pady=8) self._make_parameters_panel(pf) # checkbox to show relative coord row = row + 1 relative_text = ' Show coord relative to open model ' rm = Hybrid.Checkbutton(parent, relative_text, 0) rm.button.grid(row=row, column=0, sticky='w',padx=8) self.relative_xyz = rm.variable # menu frame row = row + 1 from chimera.widgets import ModelOptionMenu self.menu = ModelOptionMenu(parent, command=self.menu_cb, labelpos='w', label_text='Model:') self.menu.grid(row=row, sticky='w', padx=8, pady=2) # --------------------------------------------------------------------- # Panels # --------------------------------------------------------------------- def _make_parameters_panel(self, frame): """_make_parameters_panel(frame) Make a panel in the GUI for parmeters (distance and atom location). """ row = 0 # distance dfL = Tkinter.Label(frame, text=' Distance ') dfL.grid(row=row, column=0, sticky='w') dfE = Hybrid.Entry(frame, ' ', 7, '0.0') dfE.frame.grid(row=row, column=1, columnspan=3, sticky='w') dfE.entry['state'] = 'readonly' self.distance_value = dfE.variable # atom 1 location row = row + 1 self.marker1_xyz = [] a1L = Tkinter.Label(frame, text=' XYZ 1 ') a1L.grid(row=row, column=0, sticky='w',pady=2) for a in range(3): a1E = Hybrid.Entry(frame, ' ', 7, '0.0') a1E.frame.grid(row=row, column=a+1, sticky='w') a1E.entry['state'] = 'readonly' self.marker1_xyz.append(a1E.variable) # atom 2 location row = row + 1 self.marker2_xyz = [] a2L = Tkinter.Label(frame, text=' XYZ 2 ') a2L.grid(row=row, column=0, sticky='w',pady=2) for a in range(3): a2E = Hybrid.Entry(frame, ' ', 7, '0.0') a2E.frame.grid(row=row, column=a+1, sticky='w') a2E.entry['state'] = 'readonly' self.marker2_xyz.append(a2E.variable) return def menu_cb(self, val): return # --------------------------------------------------------------------- # Distance and Location functions # --------------------------------------------------------------------- def get_parameters_value(self): """get_parameters_value(): Output: dist distance marker1d marker 1 location marker2d marker 2 location Get parameters - distance and location of markers. """ if self.volume_path_dialog == None: msg = 'No marker set present!\n' self.status(msg, color='red', blankAfter=15) replyobj.warning(msg) return None,None,None linked_list = self.volume_path_dialog.selected_links() if len(linked_list) == 0: msg = 'No links present/selected!\n' self.status(msg, color='red', blankAfter=15) replyobj.warning(msg) return None, None, None link = linked_list[0] dist = self.find_link_distance(link) marker1d, marker2d = self.find_marker_location(link) return dist, marker1d, marker2d def find_link_distance(self, link): """find_link_distance(link) Input: link markerset link Output: dist distance or None if link is None Find distance of link. """ if link == None: return None from VolumePath import markerset distance = markerset.distance dist = distance(link.marker1.xyz(), link.marker2.xyz()) return dist def find_marker_location(self, link): """find_marker_location(link) Input: link markerset link Output: marker1d marker 1 location marker2d marker 2 location Find marker location. """ if link == None: return None,None from VolumePath import markerset distance = markerset.distance dist = distance(link.marker1.xyz(), link.marker2.xyz()) marker1d = link.marker1.xyz() marker2d = link.marker2.xyz() if self.relative_xyz.get(): marker1d, marker2d = self.find_marker_relative(link) # show labels for marker 1 and 2 if not link.marker1.note(): link.marker1.set_note('1') link.marker1.show_note(1) if not link.marker2.note(): link.marker2.set_note('2') link.marker2.show_note(1) return marker1d, marker2d def find_marker_relative(self, link): """find_marker_relative(link) Input: link markerset link Output: marker1d marker 1 location relative to model marker2d marker 2 location relative to model Find marker location relative to model. """ from VolumeViewer import slice # open model and marker set om = self.menu.getvalue() ms = link.marker1.marker_set # xform of open model and marker set xf_om = om.openState.xform xf_ms = ms.transform() # get marker object coordinates m1_xyz = link.marker1.xyz() m2_xyz = link.marker2.xyz() # get object coordinates relative to model marker1d = self.transform_coord(m1_xyz, xf_ms, xf_om) marker2d = self.transform_coord(m2_xyz, xf_ms, xf_om) return marker1d, marker2d def transform_coord(self, from_xyz, from_xform, to_xform): """transform_coord(from_xyz, from_xform, to_xform) Input: from_xyz from object coordinates from_xform from object's transform to_xform to objcet's transform Output: to_xyz to object coordinates Convert coordinates from 'from object' to 'to object' """ import VolumePath to_xyz = VolumePath.transform_coordinates(from_xyz, from_xform,to_xform) return to_xyz def update_parameters_value(self): """update_parameters_value() """ dist, marker1d, marker2d = self.get_parameters_value() if (dist != None and marker1d != None and marker2d != None): msg = 'Measured in Angstrom units\n' self.status(msg, color='blue', blankAfter=10) replyobj.info(msg) if dist == None: dist = 0.0 if marker1d == None: marker1d = 0.0,0.0,0.0 if marker2d == None: marker2d = 0.0,0.0,0.0 self.distance_value.set('%6.3f' % dist) for a in range(3): self.marker1_xyz[a].set('%6.3f' % marker1d[a]) self.marker2_xyz[a].set('%6.3f' % marker2d[a]) return def Compute(self): """Compute parameters """ if self.volume_path_dialog == None: import VolumePath self.volume_path_dialog = VolumePath.volume_path_dialog() self.update_parameters_value()
class WritePDBdialog(SaveModeless): keepShown = SaveModeless.default help = "UsersGuide/savemodel.html" name = "write PDB" def __init__(self): self.prefs = preferences.addCategory("write PDB dialog", preferences.HiddenCategory, optDict={"multiSavePDB": "multiple"}) self.haveTraj = False SaveModeless.__init__(self, clientPos='s', clientSticky='ewns', filters=[("PDB", "*.pdb", ".pdb")]) openModels.addAddHandler(self._modelsChange, None), openModels.addRemoveHandler(self._modelsChange, None) self._modelsChange() def configure(self, models=None, refreshList=True, selOnly=None): if models is not None: if len(models) > 1: name = "Multiple Models " elif models: name = models[0].name + " " else: name = "" self._toplevel.title("Save %sas PDB File" % name) if refreshList: self.modelList.setvalue(models) self._trajCheck() if len(models) > 1: self.multiSaveMenu.grid(row=self._msmRow, column=0, sticky='w') else: self.multiSaveMenu.grid_forget() if selOnly is not None: self.selOnlyVar.set(selOnly) def fillInUI(self, parent): SaveModeless.fillInUI(self, parent) row = 0 from chimera.widgets import MoleculeScrolledListBox, \ ModelOptionMenu self.modelList = MoleculeScrolledListBox(self.clientArea, labelpos='w', label_text="Save models:", listbox_selectmode='extended', selectioncommand=lambda: self.configure( self.modelList.getvalue(), refreshList=False)) self.modelList.grid(row=row, column=0, sticky='nsew') self.clientArea.rowconfigure(row, weight=1) self.clientArea.columnconfigure(0, weight=1) row += 1 import Tkinter, Pmw self.dispOnlyVar = Tkinter.IntVar(parent) self.dispOnlyVar.set(False) Tkinter.Checkbutton(self.clientArea, variable=self.dispOnlyVar, text="Save displayed atoms only").grid(row=row, column=0, sticky='w') row += 1 self.selOnlyVar = Tkinter.IntVar(parent) self.selOnlyVar.set(False) Tkinter.Checkbutton(self.clientArea, variable=self.selOnlyVar, text="Save selected atoms only").grid(row=row, column=0, sticky='w') row += 1 self.saveRelativeVar = Tkinter.IntVar(parent) self.saveRelativeVar.set(False) self.relativeFrame = f = Tkinter.Frame(self.clientArea) Tkinter.Checkbutton(f, variable=self.saveRelativeVar, text="Save relative to model:" ).grid(row=0, column=0, sticky='e') self.relModelMenu = ModelOptionMenu(f) self.relModelMenu.grid(row=0, column=1, sticky='w') self.saveUntransformedVar = Tkinter.IntVar(parent) self.saveUntransformedVar.set(True) self.untransformedButton = Tkinter.Checkbutton(self.clientArea, variable=self.saveUntransformedVar, text="Use untransformed coordinates") self._rfRow = row row += 1 self.frameSave = Pmw.OptionMenu(self.clientArea, labelpos='w', label_text="Save", initialitem="current frame", items=["current frame", "all frames"]) # not always shown; remember row number self._fsRow = row row += 1 from chimera import dialogs self.labelMap = { "single": "a single file", "multiple": "multiple files [appending model number]" } preferred = self.labelMap[self.prefs["multiSavePDB"]] self.multiSaveMenu = Pmw.OptionMenu(self.clientArea, labelpos='w', label_text="Save multiple models in", initialitem=preferred, items=self.labelMap.values()) # not always shown; remember row number self._msmRow = row row += 1 def map(self, *args): self.handler = triggers.addHandler("CoordSet", self._trajCheck, None) self._trajCheck() def unmap(self, *args): triggers.deleteHandler("CoordSet", self.handler) self.handler = None def Apply(self): from chimera import dialogs selOnly = self.selOnlyVar.get() paths = self.getPaths() if not paths: replyobj.error('No save location chosen.\n') return path = paths[0] models = self.modelList.getvalue() if not models: replyobj.error("No models chosen to save.\n") return if len(openModels.listIds()) > 1: if self.saveRelativeVar.get(): relModel = self.relModelMenu.getvalue() else: relModel = None else: if self.saveUntransformedVar.get(): relModel = models[0] else: relModel = None if self.haveTraj and self.frameSave.getvalue() == "all frames": allFrames=True else: allFrames=False import Midas if len(models) < 2: replyobj.status("Writing %s to %s\n" % (models[0].name, path)) Midas.write(models, relModel, path, allFrames=allFrames, dispOnly=self.dispOnlyVar.get(), selOnly=selOnly) replyobj.status("Wrote %s to %s\n" % (models[0].name, path)) return saveOpt = self.multiSaveMenu.getvalue() for key, value in self.labelMap.items(): if saveOpt == value: break self.prefs["multiSavePDB"] = key # write multiple models to multiple files if key == "multiple": if path.endswith(".pdb"): start, end = path[:-4], ".pdb" else: start, end = path, "" for m in models: modelPath = start + m.oslIdent()[1:] + end replyobj.status("Writing %s (%s) to %s\n" % (m.name, m.oslIdent(), modelPath)) Midas.write(m, relModel, modelPath, allFrames=allFrames, dispOnly=self.dispOnlyVar.get(), selOnly=selOnly) replyobj.status("Wrote %s (%s) to %s\n" % (m.name, m.oslIdent(), modelPath)) return # write multiple models to single file replyobj.status("Writing multiple models to %s\n" % path) Midas.write(models, relModel, path, allFrames=allFrames, dispOnly=self.dispOnlyVar.get(), selOnly=selOnly) replyobj.status("Wrote multiple models to %s\n" % path) def _modelsChange(self, *args): # can't query listbox, since it hangs off of same trigger if len(openModels.listIds()) > 1: self.untransformedButton.grid_forget() self.relativeFrame.grid(row=self._rfRow, column=0, sticky='w') else: self.relativeFrame.grid_forget() self.untransformedButton.grid(row=self._rfRow, column=0, sticky='w') def _trajCheck(self, *args): haveTraj = False for m in self.modelList.getvalue(): if len(m.coordSets) > 1: haveTraj = True break if haveTraj == self.haveTraj: return self.haveTraj = haveTraj if self.haveTraj: self.frameSave.grid(row=self._fsRow, column=0, sticky='w') else: self.frameSave.grid_forget()
class ClipFrame(Tkinter.Frame): def __init__(self, clipDialog, model): from chimera.widgets import ModelOptionMenu self.clipDialog = clipDialog self.model = model self.clipDependentWidgets = [] Tkinter.Frame.__init__(self, clipDialog.uiMaster()) interior = self # used to be a Pmw.Group instead of a Frame! self.clipVar = Tkinter.IntVar(interior) self.clipVar.set(self.model.useClipPlane) Tkinter.Checkbutton(interior, command=self._toggleClip, text="Enable clipping", variable=self.clipVar).grid(row=0, sticky='w') slabFrame = Tkinter.Frame(interior) slabFrame.grid(row=1, sticky='w') self.slabVar = Tkinter.IntVar(interior) self.slabVar.set(self.model.useClipThickness) cbutton = Tkinter.Checkbutton(slabFrame, command=self._changeSlab, text="Use slab mode with thickness", variable=self.slabVar) cbutton.grid(row=0, column=0, sticky='w') self.clipDependentWidgets.append(cbutton) self.slabThicknessVar = Tkinter.DoubleVar(slabFrame) self.slabThicknessVar.set(self.model.clipThickness) entry = Tkinter.Entry(slabFrame, width=4, textvariable=self.slabThicknessVar) entry.grid(row=0, column=1, sticky='w') entry.bind('<KeyPress-Return>', self._changeSlab) self.clipDependentWidgets.append(entry) butFrame = Tkinter.Frame(interior) butFrame.grid(row=2, sticky='w') button = Tkinter.Button( butFrame, pady=0, command=lambda: chimera.tkgui.normalizeClipFacing(self.model), text="Orient plane") button.grid(row=0, column=0, sticky='e') self.clipDependentWidgets.append(button) label = Tkinter.Label(butFrame, text="perpendicular to line of sight") label.grid(row=0, column=1, sticky='w') self.clipDependentWidgets.append(label) label = Tkinter.Label(butFrame, text="with center of rotation at center of view") label.grid(row=1, column=0, columnspan=2) self.clipDependentWidgets.append(label) butFrame = Tkinter.Frame(interior) butFrame.grid(row=3, sticky='w') button = Tkinter.Button(butFrame, pady=0, command=clipDialog._flipPlane, text="Flip plane") button.grid(row=0, column=0, sticky='e') self.clipDependentWidgets.append(button) label = Tkinter.Label(butFrame, text="180 degrees") label.grid(row=0, column=1, sticky='w') self.clipDependentWidgets.append(label) butFrame = Tkinter.Frame(interior) butFrame.grid(row=4, sticky='w') button = Tkinter.Button( butFrame, pady=0, command=lambda: self.clipDialog._align(self.menu.getvalue()), text="Align plane") button.grid(row=0, column=0, sticky='e') self.clipDependentWidgets.append(button) self.menu = ModelOptionMenu(butFrame, labelpos='w', label_text="with") def kludge(self=self.menu, **kw): newKw = {} for k, v in kw.items(): newKw["menubutton_" + k] = v newKw["label_" + k] = v self.configure(**newKw) self.menu.config = kludge self.menu.grid(row=0, column=1, sticky='w') self.clipDependentWidgets.append(self.menu) label = Tkinter.Label(butFrame, text="clip plane") label.grid(row=0, column=2, sticky='w') self.clipDependentWidgets.append(label) self.mouseVar = Tkinter.IntVar(interior) self.mouseVar.set(getClipModel() == model) self.mouseActiveButton = Tkinter.Checkbutton( interior, command=self._toggleMouse, variable=self.mouseVar, text="Adjust clipping with mouse as below") self.mouseActiveButton.grid(row=5, sticky='w') self.clipDependentWidgets.append(self.mouseActiveButton) if not self.clipVar.get(): for w in self.clipDependentWidgets: w.config(state='disabled') def destroy(self): delattr(self, 'model') if self.mouseVar.get(): self.clipDialog.stopMouseClip() Tkinter.Frame.destroy(self) def _toggleClip(self): if self.clipVar.get(): try: initClip(self.model) except ValueError: replyobj.error("Model cannot currently be" " clipped [no valid bounding box]\n") self.clipVar.set(False) return self.slabThicknessVar.set(self.model.clipThickness) for w in self.clipDependentWidgets: w.config(state='normal') else: self.model.useClipPlane = False if getClipModel() == self.model: self.clipDialog.stopMouseClip() self.mouseVar.set(False) for w in self.clipDependentWidgets: w.config(state='disabled') def _toggleMouse(self): if self.mouseVar.get(): self.clipDialog.startMouseClip(self.model) else: self.clipDialog.stopMouseClip() def _changeSlab(self, event=None): self.model.useClipThickness = self.slabVar.get() try: thick = float(self.slabThicknessVar.get()) except ValueError: replyobj.error("Invalid slab thickness.\n") return self.model.clipThickness = thick
class ClipDialog(ModelessDialog): name = "per-model clipping" title = "Per-Model Clipping" buttons = ("Close", ) help = 'ContributedSoftware/per-model/per-model.html' def fillInUI(self, parent): import Pmw from chimera.widgets import ModelOptionMenu self.menu = ModelOptionMenu(parent, command=self._menuCB, labelpos='w', label_text="Model:") self.menu.grid(row=0, sticky='w') self.infoArea = None self.normMouse = None self.clipMouse = [None, None] if self.menu.getvalue() is not None: self.menu.invoke() # cause callback group = Pmw.Group(parent, tag_text="Clip Motion Assignments") group.grid(row=2, sticky="nsew") self.buttonLabels = [] self.labelValues = {} for mod in ("", ) + mousemodes.usedMods: for but in mousemodes.usedButtons: if mod: self.buttonLabels.append(mod.lower() + " button " + but) self.labelValues[self.buttonLabels[-1]]\ = (but, (mod,)) else: self.buttonLabels.append("button " + but) self.labelValues[self.buttonLabels[-1]]\ = (but, ()) self.transMenu = Pmw.OptionMenu( group.interior(), command=lambda bname: self._assignmentChange(0, bname), initialitem="button 2", items=self.buttonLabels, labelpos='n', label_text="Translation") self.transMenu.grid(row=0, column=0) self.pivotMenu = Pmw.OptionMenu( group.interior(), command=lambda bname: self._assignmentChange(1, bname), initialitem="button 3", items=self.buttonLabels, labelpos='n', label_text="Rotation") self.pivotMenu.grid(row=0, column=1) mousemodes.addFunction("plane rotate", (lambda v, e: self._planeStart(v, e, "rotate"), self._planeRot, self._planeStop)) mousemodes.addFunction( "plane translate", (lambda v, e: self._planeStart(v, e, "translate z"), self._planeTrans, self._planeStop)) def showCapDialog(): from SurfaceCap.gui import Capper_Dialog from chimera import dialogs d = dialogs.display(Capper_Dialog.name) d.show_caps.set(True) Tkinter.Button(parent, text="Cap clipped surfaces...", pady=0, command=showCapDialog).grid(row=3) def Close(self): if self.infoArea and self.infoArea.mouseVar.get(): self.infoArea.mouseVar.set(False) self.stopMouseClip() ModelessDialog.Close(self) def setModel(self, model): self.menu.setvalue(model) def startMouseClip(self, model): setClipModel(model) if self.normMouse is not None: # clipping already ongoing return transVal = self.transMenu.getvalue() pivotVal = self.pivotMenu.getvalue() if transVal == pivotVal: replyobj.error("Cannot assign both clip functions to" " same button\n") return self.normMouse = [ mousemodes.getFuncName(*self.labelValues[transVal]), mousemodes.getFuncName(*self.labelValues[pivotVal]) ] self._activateMouse(0, transVal) self._activateMouse(1, pivotVal) def stopMouseClip(self): if self.normMouse is None: # already stopped return setClipModel(None) self._restoreButton(0) self._restoreButton(1) self.normMouse = None def _activateMouse(self, but, butName): self.clipMouse[but] = butName args = self.labelValues[butName] + ( ["plane translate", "plane rotate"][but], ) mousemodes.setButtonFunction(*args) def _align(self, refModel): if not refModel.useClipPlane: from chimera import LimitationError raise LimitationError("Cannot align clip planes:" " both models must have clipping on") matchModel = self.menu.getvalue() refMat = refModel.openState.xform matchMat = matchModel.openState.xform if refMat == matchMat: matchModel.clipPlane = refModel.clipPlane return xf = matchMat.inverse() xf.multiply(refMat) refClip = refModel.clipPlane matchModel.clipPlane = chimera.Plane(xf.apply(refClip.origin), xf.apply(refClip.normal)) def _assignmentChange(self, pos, val): if self.normMouse is None: # no ongoing clip return if val == self.clipMouse[1 - pos]: replyobj.error("Cannot assign both clip functions to" " same button\n") [self.transMenu, self.pivotMenu][pos].setvalue(self.clipMouse[pos]) return # restore former function to button self._restoreButton(pos) # remember normal function of new button self._rememberButton(pos, val) # assign clip function to new button self._activateMouse(pos, val) def _flipPlane(self): model = self.menu.getvalue() p = model.clipPlane normal = p.normal normal.negate() p.normal = normal model.clipPlane = p def _menuCB(self, model): if self.infoArea: self.infoArea.grid_forget() if isinstance(self.infoArea, ClipFrame): self.infoArea.destroy() if model: self.infoArea = ClipFrame(self, model) self.infoArea.grid(row=1, sticky='nsew') else: self.infoArea = None def _rememberButton(self, but, butName): self.normMouse[but] = mousemodes.getFuncName( *self.labelValues[butName]) def _restoreButton(self, but): # restore former function of translation (but == 0) or # pivot button (but == 1) restoreFunc = self.normMouse[but] restoreArgs = self.labelValues[self.clipMouse[but]] + (restoreFunc, ) mousemodes.setButtonFunction(*restoreArgs) def _planeRot(self, viewer, event): xf = viewer.vsphere(event.time, event.x, event.y, event.state % 2 == 1) if xf.isIdentity(): return clipModel = getClipModel() if not clipModel: return p = clipModel.clipPlane axis, angle = clipModel.openState.xform.getRotation() mxf = chimera.Xform.rotation(axis, angle) mxfinv = chimera.Xform.rotation(axis, -angle) mxfinv.multiply(xf) mxfinv.multiply(mxf) p.xformNormal(mxfinv) clipModel.clipPlane = p def _doPlaneAutospin(self, trigger, xform, frameNumber): clipModel = getClipModel() if not clipModel: return p = clipModel.clipPlane p.xformNormal(xform) clipModel.clipPlane = p def _planeStart(self, viewer, event, cursor): viewer.recordPosition(event.time, event.x, event.y, cursor), clipModel = getClipModel() if not clipModel: return viewer.showPlaneModel = clipModel, .5 def _planeStop(self, viewer, event): viewer.setCursor(None) viewer.showPlaneModel = None, 0 def _planeTrans(self, viewer, event): clipModel = getClipModel() if not clipModel: return p = clipModel.clipPlane dx, dy = viewer.delta(event.x, event.y, event.state % 2 == 1) axis, angle = clipModel.openState.xform.getRotation() mxf = chimera.Xform.rotation(axis, angle) n = mxf.apply(p.normal) # figure out major axis of normal in lab space if abs(n.x) >= abs(n.y): axis = (0, 1) else: axis = (1, 0) # reassign normal so there are no zeros # in mouse adjustment calculation def fuzzySign(x): if x < -1e-6: return -1 if x > 1e-6: return 1 return 0 n = [fuzzySign(n.x), fuzzySign(n.y), fuzzySign(n.z)] if n[axis[0]] == 0: # should never happen with non-zero normal n[axis[0]] = 1 if n[axis[1]] == 0: n[axis[1]] = n[axis[0]] # mimic major axis n = chimera.Vector(*n) adjust = n.x * dx + n.y * dy distance = 2 * viewer.camera.extent * adjust p.moveOrigin(distance) clipModel.clipPlane = p
class ClipFrame(Tkinter.Frame): def __init__(self, clipDialog, model): from chimera.widgets import ModelOptionMenu self.clipDialog = clipDialog self.model = model self.clipDependentWidgets = [] Tkinter.Frame.__init__(self, clipDialog.uiMaster()) interior = self # used to be a Pmw.Group instead of a Frame! self.clipVar = Tkinter.IntVar(interior) self.clipVar.set(self.model.useClipPlane) Tkinter.Checkbutton(interior, command=self._toggleClip, text="Enable clipping", variable=self.clipVar).grid( row=0, sticky='w') slabFrame = Tkinter.Frame(interior) slabFrame.grid(row=1, sticky='w') self.slabVar = Tkinter.IntVar(interior) self.slabVar.set(self.model.useClipThickness) cbutton = Tkinter.Checkbutton(slabFrame, command=self._changeSlab, text="Use slab mode with thickness", variable=self.slabVar) cbutton.grid(row=0, column=0, sticky='w') self.clipDependentWidgets.append(cbutton) self.slabThicknessVar = Tkinter.DoubleVar(slabFrame) self.slabThicknessVar.set(self.model.clipThickness) entry = Tkinter.Entry(slabFrame, width=4, textvariable=self.slabThicknessVar) entry.grid(row=0, column=1, sticky='w') entry.bind('<KeyPress-Return>', self._changeSlab) self.clipDependentWidgets.append(entry) butFrame = Tkinter.Frame(interior) butFrame.grid(row=2, sticky='w') button = Tkinter.Button(butFrame, pady=0, command=lambda: chimera.tkgui.normalizeClipFacing(self.model), text="Orient plane") button.grid(row=0, column=0, sticky='e') self.clipDependentWidgets.append(button) label = Tkinter.Label(butFrame, text="perpendicular to line of sight") label.grid(row=0, column=1, sticky='w') self.clipDependentWidgets.append(label) label = Tkinter.Label(butFrame, text="with center of rotation at center of view") label.grid(row=1, column=0, columnspan=2) self.clipDependentWidgets.append(label) butFrame = Tkinter.Frame(interior) butFrame.grid(row=3, sticky='w') button = Tkinter.Button(butFrame, pady=0, command= clipDialog._flipPlane, text="Flip plane") button.grid(row=0, column=0, sticky='e') self.clipDependentWidgets.append(button) label = Tkinter.Label(butFrame, text="180 degrees") label.grid(row=0, column=1, sticky='w') self.clipDependentWidgets.append(label) butFrame = Tkinter.Frame(interior) butFrame.grid(row=4, sticky='w') button = Tkinter.Button(butFrame, pady=0, command=lambda : self.clipDialog._align(self.menu.getvalue()), text="Align plane") button.grid(row=0, column=0, sticky='e') self.clipDependentWidgets.append(button) self.menu = ModelOptionMenu(butFrame, labelpos='w', label_text="with") def kludge(self=self.menu, **kw): newKw = {} for k, v in kw.items(): newKw["menubutton_" + k] = v newKw["label_" + k] = v self.configure(**newKw) self.menu.config = kludge self.menu.grid(row=0, column=1, sticky='w') self.clipDependentWidgets.append(self.menu) label = Tkinter.Label(butFrame, text="clip plane") label.grid(row=0, column=2, sticky='w') self.clipDependentWidgets.append(label) self.mouseVar = Tkinter.IntVar(interior) self.mouseVar.set(getClipModel() == model) self.mouseActiveButton = Tkinter.Checkbutton(interior, command=self._toggleMouse, variable=self.mouseVar, text="Adjust clipping with mouse as below") self.mouseActiveButton.grid(row=5, sticky='w') self.clipDependentWidgets.append(self.mouseActiveButton) if not self.clipVar.get(): for w in self.clipDependentWidgets: w.config(state='disabled') def destroy(self): delattr(self, 'model') if self.mouseVar.get(): self.clipDialog.stopMouseClip() Tkinter.Frame.destroy(self) def _toggleClip(self): if self.clipVar.get(): try: initClip(self.model) except ValueError: replyobj.error("Model cannot currently be" " clipped [no valid bounding box]\n") self.clipVar.set(False) return self.slabThicknessVar.set(self.model.clipThickness) for w in self.clipDependentWidgets: w.config(state='normal') else: self.model.useClipPlane = False if getClipModel() == self.model: self.clipDialog.stopMouseClip() self.mouseVar.set(False) for w in self.clipDependentWidgets: w.config(state='disabled') def _toggleMouse(self): if self.mouseVar.get(): self.clipDialog.startMouseClip(self.model) else: self.clipDialog.stopMouseClip() def _changeSlab(self, event = None): self.model.useClipThickness = self.slabVar.get() try: thick = float(self.slabThicknessVar.get()) except ValueError: replyobj.error("Invalid slab thickness.\n") return self.model.clipThickness = thick
class ClipDialog(ModelessDialog): name = "per-model clipping" title = "Per-Model Clipping" buttons = ("Close",) help = 'ContributedSoftware/per-model/per-model.html' def fillInUI(self, parent): import Pmw from chimera.widgets import ModelOptionMenu self.menu = ModelOptionMenu(parent, command=self._menuCB, labelpos='w', label_text="Model:") self.menu.grid(row=0, sticky='w') self.infoArea = None self.normMouse = None self.clipMouse = [None, None] if self.menu.getvalue() is not None: self.menu.invoke() # cause callback group = Pmw.Group(parent, tag_text="Clip Motion Assignments") group.grid(row=2, sticky="nsew") self.buttonLabels = [] self.labelValues = {} for mod in ("",) + mousemodes.usedMods: for but in mousemodes.usedButtons: if mod: self.buttonLabels.append( mod.lower() + " button " + but) self.labelValues[self.buttonLabels[-1]]\ = (but, (mod,)) else: self.buttonLabels.append("button "+but) self.labelValues[self.buttonLabels[-1]]\ = (but, ()) self.transMenu = Pmw.OptionMenu(group.interior(), command=lambda bname: self._assignmentChange(0, bname), initialitem="button 2", items=self.buttonLabels, labelpos='n', label_text="Translation") self.transMenu.grid(row=0, column=0) self.pivotMenu = Pmw.OptionMenu(group.interior(), command=lambda bname: self._assignmentChange(1, bname), initialitem="button 3", items=self.buttonLabels, labelpos='n', label_text="Rotation") self.pivotMenu.grid(row=0, column=1) mousemodes.addFunction("plane rotate", ( lambda v, e: self._planeStart(v, e, "rotate"), self._planeRot, self._planeStop)) mousemodes.addFunction("plane translate", ( lambda v, e: self._planeStart( v, e, "translate z"), self._planeTrans, self._planeStop)) def showCapDialog(): from SurfaceCap.gui import Capper_Dialog from chimera import dialogs d = dialogs.display(Capper_Dialog.name) d.show_caps.set(True) Tkinter.Button(parent, text="Cap clipped surfaces...", pady=0, command=showCapDialog).grid(row=3) def Close(self): if self.infoArea and self.infoArea.mouseVar.get(): self.infoArea.mouseVar.set(False) self.stopMouseClip() ModelessDialog.Close(self) def setModel(self, model): self.menu.setvalue(model) def startMouseClip(self, model): setClipModel(model) if self.normMouse is not None: # clipping already ongoing return transVal = self.transMenu.getvalue() pivotVal = self.pivotMenu.getvalue() if transVal == pivotVal: replyobj.error("Cannot assign both clip functions to" " same button\n") return self.normMouse = [ mousemodes.getFuncName(*self.labelValues[transVal]), mousemodes.getFuncName(*self.labelValues[pivotVal]) ] self._activateMouse(0, transVal) self._activateMouse(1, pivotVal) def stopMouseClip(self): if self.normMouse is None: # already stopped return setClipModel(None) self._restoreButton(0) self._restoreButton(1) self.normMouse = None def _activateMouse(self, but, butName): self.clipMouse[but] = butName args = self.labelValues[butName] + (["plane translate", "plane rotate"][but],) mousemodes.setButtonFunction(*args) def _align(self, refModel): if not refModel.useClipPlane: from chimera import LimitationError raise LimitationError("Cannot align clip planes:" " both models must have clipping on") matchModel = self.menu.getvalue() refMat = refModel.openState.xform matchMat = matchModel.openState.xform if refMat == matchMat: matchModel.clipPlane = refModel.clipPlane return xf = matchMat.inverse() xf.multiply(refMat) refClip = refModel.clipPlane matchModel.clipPlane = chimera.Plane(xf.apply(refClip.origin), xf.apply(refClip.normal)) def _assignmentChange(self, pos, val): if self.normMouse is None: # no ongoing clip return if val == self.clipMouse[1 - pos]: replyobj.error("Cannot assign both clip functions to" " same button\n") [self.transMenu, self.pivotMenu][pos].setvalue( self.clipMouse[pos]) return # restore former function to button self._restoreButton(pos) # remember normal function of new button self._rememberButton(pos, val) # assign clip function to new button self._activateMouse(pos, val) def _flipPlane(self): model = self.menu.getvalue() p = model.clipPlane normal = p.normal normal.negate() p.normal = normal model.clipPlane = p def _menuCB(self, model): if self.infoArea: self.infoArea.grid_forget() if isinstance(self.infoArea, ClipFrame): self.infoArea.destroy() if model: self.infoArea = ClipFrame(self, model) self.infoArea.grid(row=1, sticky='nsew') else: self.infoArea = None def _rememberButton(self, but, butName): self.normMouse[but] = mousemodes.getFuncName( *self.labelValues[butName]) def _restoreButton(self, but): # restore former function of translation (but == 0) or # pivot button (but == 1) restoreFunc = self.normMouse[but] restoreArgs = self.labelValues[self.clipMouse[but]] + ( restoreFunc,) mousemodes.setButtonFunction(*restoreArgs) def _planeRot(self, viewer, event): xf = viewer.vsphere(event.time, event.x, event.y, event.state % 2 == 1) if xf.isIdentity(): return clipModel = getClipModel() if not clipModel: return p = clipModel.clipPlane axis, angle = clipModel.openState.xform.getRotation() mxf = chimera.Xform.rotation(axis, angle) mxfinv = chimera.Xform.rotation(axis, -angle) mxfinv.multiply(xf) mxfinv.multiply(mxf) p.xformNormal(mxfinv) clipModel.clipPlane = p def _doPlaneAutospin(self, trigger, xform, frameNumber): clipModel = getClipModel() if not clipModel: return p = clipModel.clipPlane p.xformNormal(xform) clipModel.clipPlane = p def _planeStart(self, viewer, event, cursor): viewer.recordPosition(event.time, event.x, event.y, cursor), clipModel = getClipModel() if not clipModel: return viewer.showPlaneModel = clipModel, .5 def _planeStop(self, viewer, event): viewer.setCursor(None) viewer.showPlaneModel = None, 0 def _planeTrans(self, viewer, event): clipModel = getClipModel() if not clipModel: return p = clipModel.clipPlane dx, dy = viewer.delta(event.x, event.y, event.state % 2 == 1) axis, angle = clipModel.openState.xform.getRotation() mxf = chimera.Xform.rotation(axis, angle) n = mxf.apply(p.normal) # figure out major axis of normal in lab space if abs(n.x) >= abs(n.y): axis = (0, 1) else: axis = (1, 0) # reassign normal so there are no zeros # in mouse adjustment calculation def fuzzySign(x): if x < -1e-6: return -1 if x > 1e-6: return 1 return 0 n = [fuzzySign(n.x), fuzzySign(n.y), fuzzySign(n.z)] if n[axis[0]] == 0: # should never happen with non-zero normal n[axis[0]] = 1 if n[axis[1]] == 0: n[axis[1]] = n[axis[0]] # mimic major axis n = chimera.Vector(*n) adjust = n.x * dx + n.y * dy distance = 2 * viewer.camera.extent * adjust p.moveOrigin(distance) clipModel.clipPlane = p
class Volume_Morph(ModelessDialog): """Class: Volume_Morph() The main GUI dialog for morphing. """ title='Volume Morph' name = 'volume morph' buttons = ('Close',) # @ help = 'ContributedSoftware/VolumeMorph/volmorph.html' dir_pkg = os.path.dirname(__file__) help_path = os.path.join(dir_pkg, 'volmorph.html') help_url = 'file://' + help_path help = help_url provideStatus = True statusPosition = 'above' statusResizing = False statusWidth = 40 morph_choices = {0: 'Simple', 1: 'Other'} # --------------------------------------------------------------------- # Fill in UI # --------------------------------------------------------------------- def fillInUI(self, parent): """fillInUI(parent) """ self.status('') self.focus_region = None # current selection self.data_item = None self.output_item = None self.data_shown = None self.morph_dialog = vol_morph_dialog() self.model = None self.morph_init = None self.morph_final = None parent.columnconfigure(0, weight = 1) # parent.rowconfigure(0, weight = 1) self.toplevel_widget = parent.winfo_toplevel() # @ whatisthis # panel buttons (pb) row = 0 pb = Hybrid.Checkbutton_Row(parent, 'Panels ', ('Simple', )) pb.frame.grid(row = row, column = 0, sticky = 'nw') for b in pb.checkbuttons: b.callback(self.allow_toplevel_resize_cb) (self.morph_simple_panel_button, ) = pb.checkbuttons # data menu frame (dmf) row = row + 1 import SegmentMenu from SegmentMenu import datamenuseg dmf = datamenuseg.Segment_Open_Data(self, parent, self.data_status_cb) dmf.frame.grid(row = row, column = 0, sticky = 'nw', pady = 8) self.data_panel = dmf # morph model frame row = row + 1 mmf = Tkinter.Frame(parent, padx=8, pady=8) mmf.grid(row = row, column = 0, sticky = 'nw') self._make_morph_models_panel(mmf) # simple morph frame row = row + 1 smf = Tkinter.Frame(parent, padx=8, pady=8) smf.grid(row = row, column = 0, sticky = 'nw') self._make_morph_simple_panel(smf) self.morph_simple_panel_button.popup_frame(smf, row=row, column=0, sticky='nw') self.morph_simple_panel_button.variable.set(1) # morph output frame row = row + 1 mof = Tkinter.Frame(parent, padx=8, pady=8) mof.grid(row = row, column = 0, sticky = 'nw') self._make_morph_output_panel(mof) # output menu frame row = row + 1 import SegmentMenu from SegmentMenu import datamenuseg omf = datamenuseg.Segment_Open_Output(self, parent, self.output_status_cb) omf.frame.grid(row = row, column = 0, sticky = 'nw', pady=8) self.output_panel = omf # create initial data menu list self.data_panel.data_items_refresh() # @ do we need to do stuff before closing Chimera session # or this segmentation dialog # --------------------------------------------------------------------- # Panels # --------------------------------------------------------------------- def _make_morph_models_panel(self, frame): """_make_morph_models_panel(frame) Make a panel in the GUI for morph models. """ row = 0 # morph models label (mmL) mmL = Tkinter.Label(frame, text = 'Morph Models ') mmL.grid(row = row, column = 0, sticky = 'nw') # morph models frame row = row + 1 mmf = Tkinter.Frame(frame, padx=40) mmf.grid(row = row, column = 0, sticky = 'nw') from chimera.widgets import ModelOptionMenu # morph model init menu and label self.morph_init_menu = ModelOptionMenu(mmf, command=self.morph_model_menu_cb, labelpos='w', label_text=' Inital model: ') self.morph_init_menu.grid(row=0, column=0, sticky='w') miL = Tkinter.Label(mmf, text = ' (PDB) ') miL.grid(row=0, column=1, sticky = 'nw') # morph model final menu and label self.morph_final_menu = ModelOptionMenu(mmf, command=self.morph_model_menu_cb, labelpos='w', label_text=' Final model: ') self.morph_final_menu.grid(row=1, column=0, sticky='w') mfL = Tkinter.Label(mmf, text = ' (PDB) ') mfL.grid(row=1, column=1, sticky = 'nw') return def _make_morph_simple_panel(self, frame): """_make_morph_simple_panel(frame) Make a panel in the GUI for simple morphing. """ row = 0 # simple morph label (smL) smL = Tkinter.Label(frame, text = 'Simple Morph ') smL.grid(row = row, column = 0, sticky = 'nw') # simple morph fraction frame row = row + 1 smfrf = Tkinter.Frame(frame, padx=40) smfrf.grid(row = row, column = 0, sticky = 'nw') # simple morph fraction smfr_e = Hybrid.Entry(smfrf, 'Fraction :', '6', '1.0') smfr_e.frame.grid(row=0, column=0, sticky = 'nw') self.sm_fraction_value = smfr_e # simple morph threshold frame row = row + 1 smtf = Tkinter.Frame(frame, padx=40) smtf.grid(row = row, column = 0, sticky = 'nw') # simple morph threshold smt_c = Hybrid.Checkbutton_Row(smtf, 'Threshold : ', ('Use ',)) smt_c.frame.grid(row=0, column=0, sticky = 'nw') (threshold_button,) = smt_c.checkbuttons threshold_button.callback(self.sm_threshold_button_cb) self.sm_threshold_button = threshold_button smt_e = Hybrid.Entry(smtf, ' ', '8', '0.0') smt_e.frame.grid(row=0, column=1, sticky = 'nw') self.sm_threshold_value = smt_e # simple morph filter frame row = row + 1 smff = Tkinter.Frame(frame, padx=40) smff.grid(row = row, column = 0, sticky = 'nw') # simple morph filter smf_c = Hybrid.Checkbutton_Row(smff, 'Filter : ', ('Use ',)) smf_c.frame.grid(row=0, column=0, sticky = 'nw') (filter_button,) = smf_c.checkbuttons filter_button.callback(self.sm_filter_button_cb) self.sm_filter_button = filter_button smf_e = Hybrid.Entry(smff, ' lowpass ', '8', '0.0') smf_e.frame.grid(row=0, column=1, sticky = 'nw') self.sm_filter_value = smf_e smfL = Tkinter.Label(smff, text = ' (Ang) ') smfL.grid(row=0, column=2, sticky = 'nw') # default options self.sm_threshold_button.variable.set(0) self.sm_filter_button.variable.set(0) return def _make_morph_output_panel(self, frame): """_make_morph_output_panel(frame) Make a panel in the GUI for output. """ row = 0 # morph output label (moL) moL = Tkinter.Label(frame, text = 'Morph Output ') moL.grid(row = 0, column = 0, sticky = 'nw') # morph output paramters frame (mopf) row = row + 1 mopf = Tkinter.Frame(frame, padx=32) mopf.grid(row = 1, column = 0, sticky = 'nw') # chose morph type (cmt) cmt = Hybrid.Radiobutton_Row(mopf, 'Choose Morph type ', (self.morph_choices[0],), self.morph_type_cb) cmt.frame.grid(row = 0, column = 0, columnspan = 2, sticky = 'nw', padx=8) self.morph_type = cmt # output data file entry (odfE) odfE = Hybrid.Entry(mopf, 'File MRC ', '16', 'temp.mrc') odfE.frame.grid(row = 1, column=0, sticky = 'w', padx=8) self.data_output = odfE # @ how to update entry - callback # buttons mb = Hybrid.Button_Row(mopf, '', (('Apply', self.morph_apply_cb),)) mb.frame.grid(row = 1, column = 1, sticky = 'w', padx=8) self.morph_type.variable.set(self.morph_choices[0]) return # --------------------------------------------------------------------- # Data menu related functions # --------------------------------------------------------------------- def data_status_cb(self, data_item, data_status): """data_status_cb(data_item, data_status) - callback. Callback function for data status, used by datamenuseg's Data menu. Activates and deactivates mouse buttons. """ self.data_shown = data_status self.data_item = data_item # display a message if data_status == self.data_panel.DATA_NOT_SHOWN: msg = 'Data item %s not shown\n' % (data_item.name) elif data_status == self.data_panel.DATA_SHOWN: msg = 'Data item %s shown\n'% (data_item.name) else: msg = 'No data items present\n' # self.status(msg, color='blue', blankAfter=15) # if data_status == self.data_panel.DATA_EMPTY: # replyobj.info(msg) # activate/deactivate mouse selection # if data_status == self.data_panel.DATA_NOT_SHOWN: # self.selection_hide_cb() # self.sel_mouse_button['state'] = 'disabled' # elif data_status == self.data_panel.DATA_SHOWN: # self.selection_show_cb() # self.sel_mouse_button['state'] = 'normal' # else: # self.selection_delete_cb() # self.sel_mouse_button['state'] = 'disabled' return # --------------------------------------------------------------------- # Output menu related functions # --------------------------------------------------------------------- def output_status_cb(self, output_item, output_status): """output_status_cb(output_item, output_status) - callback Callback function for output status, used by datamenuseg's Output menu. """ self.output_shown = output_status self.output_item = output_item # display a message if output_status == self.output_panel.DATA_NOT_SHOWN: msg = 'Output item %s not shown\n' % (output_item.name) elif output_status == self.output_panel.DATA_SHOWN: msg = 'Output item %s shown\n'% (output_item.name) else: msg = 'No output items present\n' # self.status(msg, color='blue', blankAfter=15) # if output_status == self.output_panel.DATA_EMPTY: # replyobj.info(msg) return # --------------------------------------------------------------------- # Morph related callback functions # --------------------------------------------------------------------- def morph_model_menu_cb(self, val): """morph_model_menu_cb(val) - callback for morph model menu """ return def morph_type_cb(self): """morph_type_cb() - callback for morph type """ return # --------------------------------------------------------------------- # Simple Morph related callback functions # --------------------------------------------------------------------- def sm_threshold_button_cb(self): """sm_threshold_button_cb() - callback for simple morph callback for threshold parameter in simple morph """ if self.sm_threshold_button.variable.get(): self.sm_threshold_value.entry['state'] = 'normal' else: self.sm_threshold_value.entry['state'] = 'readonly' return def sm_filter_button_cb(self): """sm_filter_button_cb() - callback for simple morph callback for filter parameter in simple morph """ if self.sm_filter_button.variable.get(): self.sm_filter_value.entry['state'] = 'normal' else: self.sm_filter_value.entry['state'] = 'readonly' return # --------------------------------------------------------------------- # Morph related functions. # --------------------------------------------------------------------- def morph_apply_cb(self): """morph_apply_cb() - callback for Apply button. """ self.morph_apply() return def morph_apply(self): """morph_apply() - applies appropriate morphing Applies appropriate morphing after Apply button is specified. Checks values and passes a message if incorrect parameters. """ # check input data exists if self.data_item == None: name = '%s' % (self.data_panel.data_menu.variable.get()) msg = 'Input data %s not found!\n' % name self.status(msg, color='red', blankAfter=15) replyobj.error(msg) return # get input file path, name, and size in pixels infile_path = str(self.data_item.path) infile = str(self.data_item.name) infile_size = self.data_item.size # get morph models morph0, morph1 = self.get_morph_models() if (morph0 == None or morph1 == None): return # get morph parameters morph_type = self.morph_type.variable.get() if morph_type == self.morph_choices[0]: frac, thr, filt = self.get_simple_morph_param() # check and set output name self.output_item = None outfile = str(self.data_output.variable.get()) if (outfile == '') or (outfile == infile): first_part, last_part = self.name_and_dot_suffix(infile) outfile = '%s-m%s' % (first_part, last_part) msg = 'Using default output file %s\n'% outfile replyobj.info(msg) self.data_output.variable.set(outfile) # output out_dir = os.getcwd() out_files = [outfile] # run morph command seg_sucess = 0 if morph_type == self.morph_choices[0]: seg_success = self.morph_apply_simple(self.data_item, morph0, morph1, outfile, frac, thr, filt) # open output if seg_success: self.open_output_data_items(out_dir, out_files) self.enter() return def check_morph_model(self, model): """check_morph_model(model) - get morph model if valid Output: model morph model """ from chimera import Molecule if model is None or not isinstance(model, Molecule): print model.__class__ msg = 'Select a PDB model as morph model!\n' self.status(msg, color='red', blankAfter=10) replyobj.error(msg) return None return model def get_morph_models(self): """get_morph_models() - get init and final morph models Output: model0 morph model initial (None if invalid) model1 morph model final (None if invalid) Return the inital and final morph models, after checking. """ morph0 = self.morph_init_menu.getvalue() morph1 = self.morph_final_menu.getvalue() morph0 = self.check_morph_model(morph0) morph1 = self.check_morph_model(morph1) if morph0 == None or morph1 == None: return None, None morph0_path = morph0.openedAs[0] morph1_path = morph1.openedAs[0] if morph0_path == morph1_path: msg = 'Select 2 different PDB models!\n' self.status(msg, color='red', blankAfter=10) replyobj.error(msg) return None, None return morph0, morph1 def get_simple_morph_param(self): """get_simple_morph_param() - simple morph parameters Output: thr filt frac Returns parameters to be used for simple morph, after checking. """ frac_value = 1.0 thr_value = None filt_value = None # read fraction frac = str(self.sm_fraction_value.variable.get()) try: frac_value = float(frac) except: frac_value = 1.0 msg = 'Reset fraction value!\n' self.status(msg, color='red', blankAfter=15) replyobj.warning(msg) self.sm_fraction_value.variable.set('%5.2f' % frac_value) if ((frac_value < 0.1) or (frac_value > 1.0)): frac_value = 1.0 msg = 'Reset fraction value!\n' self.status(msg, color='red', blankAfter=15) replyobj.warning(msg) self.sm_fraction_value.variable.set('%5.2f' % frac_value) # read threshold if self.sm_threshold_button.variable.get(): thr = str(self.sm_threshold_value.variable.get()) try: thr_value = float(thr) except: thr_value = 0.0 msg = 'Reset threshold value!\n' self.status(msg, color='red', blankAfter=15) replyobj.warning(msg) self.sm_threshold_value.variable.set('%5.2f' % thr_value) # read filter value if self.sm_filter_button.variable.get(): filt = str(self.sm_filter_value.variable.get()) try: filt_value = float(filt) except: filt_value = 0.0 msg = 'Reset filter value!\n' self.status(msg, color='red', blankAfter=15) replyobj.warning(msg) self.sm_filter_value.variable.set('%5.2f' % filt_value) return frac_value, thr_value, filt_value # --------------------------------------------------------------------- # Morph simple # --------------------------------------------------------------------- def morph_apply_simple(self, inputdata, morph0, morph1, outputfile, frac=1.0, thr=None, filt=None): """morph_apply_simple(inputdata, morph0, morph1, outputfile, frac=1.0, thr=None, filt=None) Input: inputdata input volume data morph0 PDB model for morph initial state morph1 PDB model for morph final state outputfile output file path frac fraction of morphing (0.1 to 1) thr threshold, default=None = no thr filt lowpass filter in Angstroms Output: 1/0 success Apply simple morph. Assumes that the input parmaeters are all valid. """ infile_path = str(inputdata.path) msg = 'Applying simple morph on %s\n' % infile_path replyobj.info(msg) import morphsimple morphsimple.simple_morph(inputdata.data, morph0, morph1, outputfile, frac, thr, filt) msg = 'Applied simple morphing on %s\n' \ % os.path.basename(infile_path) self.status(msg, color='blue', blankAfter=10) replyobj.info(msg) return 1 # --------------------------------------------------------------------- # Output functions. # --------------------------------------------------------------------- def open_output_data_items(self, outdir, outfiles): """open_output_data_items(outdir, outfiles) - output menu. Input: outdir output file directory outfiles output file Add output data items in outfiles in outdir directory, to output data menu. """ if len(outfiles) == 0: return filepaths = map(lambda outfile: os.path.join(outdir, outfile), outfiles) filepaths_valid = filter(lambda p: os.path.isfile(p), filepaths) self.output_panel.data_open_cb(filepaths_valid) if len(filepaths_valid) < len(outfiles): msg = 'Some or all output files not found!\n' self.status(msg, color='red', blankAfter=10) replyobj.error(msg) return # --------------------------------------------------------------------- # Misc functions. # --------------------------------------------------------------------- # --------------------------------------------------------------------- # After user resizes dialog by hand it will not resize automatically # when panels are added or deleted. This allows the automatic resize # to happen # def allow_toplevel_resize_cb(self): self.toplevel_widget.geometry('') # --------------------------------------------------------------------- # Returns first part and dot suffix from file name or path. # Note that the suffix includes last '.' # def name_and_dot_suffix(self, name): try: dot_position = name.rindex('.') except ValueError: return name, '' first_part = name[:dot_position] last_part = name[dot_position:] return first_part, last_part
def fillInUI(self, parent): self.requested_halt = False self.xform_handler = None self.last_relative_xform = None t = parent.winfo_toplevel() self.toplevel_widget = t t.withdraw() parent.columnconfigure(0, weight = 1) row = 0 import Tkinter from CGLtk import Hybrid from VolumeViewer import Volume_Menu ff = Tkinter.Frame(parent) ff.grid(row = row, column = 0, sticky = 'w') row = row + 1 from chimera.widgets import ModelOptionMenu om = ModelOptionMenu(ff, labelpos = 'w', label_text = 'Fit ', listFunc = fit_object_models, sortFunc = compare_fit_objects, command = self.object_chosen_cb) om.grid(row = 0, column = 0, sticky = 'w') self.object_menu = om fm = Volume_Menu(ff, ' in map ') fm.frame.grid(row = 0, column = 1, sticky = 'w') self.map_menu = fm gf = Tkinter.Frame(parent) gf.grid(row = row, column = 0, sticky = 'w') row += 1 cl = Tkinter.Label(gf, text = 'Correlation') cl.grid(row = 0, column = 0, sticky = 'w') cv = Tkinter.Label(gf, width = 6, anchor = 'w', relief=Tkinter.SUNKEN, borderwidth = 2) cv.grid(row = 0, column = 1, padx = 5, sticky = 'w') self.corr_label = cv al = Tkinter.Label(gf, text = 'Average map value') al.grid(row = 0, column = 2, sticky = 'w') av = Tkinter.Label(gf, width = 6, anchor = 'w', relief=Tkinter.SUNKEN, borderwidth = 2) av.grid(row = 0, column = 3, padx = 5, sticky = 'w') self.ave_label = av ub = Tkinter.Button(gf, text = 'Update', command = self.update_metric_cb) ub.grid(row = 0, column = 4, sticky = 'w') op = Hybrid.Popup_Panel(parent) opf = op.frame opf.grid(row = row, column = 0, sticky = 'news') opf.grid_remove() opf.columnconfigure(0, weight=1) self.options_panel = op.panel_shown_variable row += 1 orow = 0 cb = op.make_close_button(opf) cb.grid(row = orow, column = 1, sticky = 'e') ru = Hybrid.Checkbutton(opf, 'Real-time correlation / average update', False) ru.button.grid(row = orow, column = 0, sticky = 'w') orow += 1 self.realtime_update = ru.variable ru.callback(self.realtime_cb) sm = Hybrid.Checkbutton_Entries(opf, False, 'Use map simulated from atoms, resolution ', (4, '')) sm.frame.grid(row = orow, column = 0, sticky = 'nw') orow += 1 self.simulate_map, self.map_resolution = sm.variables self.simulate_map.add_callback(self.simulate_map_cb) sm.entries[0].bind('<KeyPress-Return>', self.simulate_resolution_cb) dt = Hybrid.Checkbutton(opf, 'Use only data above contour level from first map', True) dt.button.grid(row = orow, column = 0, sticky = 'w') orow += 1 dt.button['state'] = 'disabled' self.limit_data = dt self.above_threshold = dt.variable opt = Hybrid.Radiobutton_Row(opf, 'Optimize ', ('overlap', 'correlation')) opt.frame.grid(row = orow, column = 0, sticky = 'w') orow += 1 self.optimize = opt.variable self.opt_widget = opt cam = Hybrid.Checkbutton(opf, 'Correlation calculated about mean data value', False) cam.button.grid(row = orow, column = 0, sticky = 'w') orow += 1 cam.button['state'] = 'disabled' self.cam_widget = cam self.corr_about_mean = cam.variable al = Hybrid.Checkbutton_Row(opf, 'Allow ', ('rotation', 'shift')) al.frame.grid(row = orow, column = 0, sticky = 'w') orow += 1 ar, ash = [c.variable for c in al.checkbuttons] ar.set(True) ash.set(True) self.allow_rotation = ar self.allow_shift = ash mm = Hybrid.Checkbutton(opf, 'Move whole molecules', True) mm.button.grid(row = orow, column = 0, sticky = 'w') orow += 1 self.move_whole_molecules = mm.variable self.mwm_button = mm.button # # Specify a label width so dialog is not resized for long messages. # msg = Tkinter.Label(parent, width = 40, anchor = 'w', justify = 'left') msg.grid(row = row, column = 0, sticky = 'ew') row = row + 1 self.message_label = msg self.halt_button = self.buttonWidgets['Halt'] self.allow_halt(False) self.update_gray_out() self.activate_undo_redo()
class Vol_Cut_Dialog(ModelessDialog): title = 'Volume_Cut' name = 'Volume_Cut' buttons = ('Cut Volume', 'Close',) help = 'https://github.com/nissensonm/VolumeCut/' # ----------------------------------------------------------------------------- # def fillInUI(self, parent): self.toplevel_widget = parent.winfo_toplevel() self.toplevel_widget.withdraw() parent.columnconfigure(0, weight = 1) from CGLtk import Hybrid import Pmw, Tkinter from chimera.widgets import MoleculeOptionMenu self.molMenu = MoleculeOptionMenu(parent, labelpos="w", label_text="Select PDB:") self.molMenu.grid(row = 1, column = 0, sticky = 'w') from chimera.widgets import MoleculeChainOptionMenu self.chainMenu = MoleculeChainOptionMenu(parent, labelpos="w", label_text="Select Chain:") self.chainMenu.grid(row = 2, column = 0, sticky = 'w') from chimera.widgets import ModelOptionMenu self.modelMenu = ModelOptionMenu(parent, labelpos="w", label_text="Select MRC:") self.modelMenu.grid(row = 3, column = 0, sticky = 'w') import Pmw self.radius = Pmw.EntryField(parent, labelpos="w", label_text="Radius:") self.radius.grid(row = 4, column = 0, sticky = 'w') self.resolution = Pmw.EntryField(parent, labelpos="w", label_text="Resolution:") self.resolution.grid(row = 5, column = 0, sticky = 'w') # ----------------------------------------------------------------------------- # def CutVolume(self): #print ' mode: ' + str(self.mode.get()) import VolCut as vc if self.molMenu.getvalue() is None or self.modelMenu.getvalue() is None \ or self.chainMenu.getvalue() is None: warnings.warn('Must load valid PDB, MRC, or select a chain.') return if type(self.modelMenu.getvalue()) is not VolumeViewer.volume.Volume: warnings.warn('Must select a valid MRC for the mrc') return try: float(self.radius.getvalue()) except ValueError: warnings.warn('Radius must be a valid float value') return try: float(self.resolution.getvalue()) except ValueError: warnings.warn('Resolution must be a valid float value') return vc.cutvol(self.molMenu.getvalue().id, self.modelMenu.getvalue().id, \ float(self.radius.getvalue()), \ float(self.resolution.getvalue()), \ self.chainMenu.getvalue().chain)