Пример #1
0
    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
Пример #2
0
  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')
Пример #3
0
    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
Пример #4
0
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)
Пример #5
0
	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
Пример #6
0
    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)
Пример #7
0
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)
Пример #8
0
	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)
Пример #9
0
  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
Пример #10
0
    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
Пример #11
0
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
Пример #12
0
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()
	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
Пример #14
0
  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()
Пример #15
0
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')
Пример #16
0
    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()
Пример #17
0
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
Пример #18
0
	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')
Пример #19
0
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
Пример #20
0
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
Пример #21
0
    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')
Пример #22
0
    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)
Пример #23
0
	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
Пример #24
0
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)
Пример #25
0
    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')
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()