Esempio n. 1
0
class CtfDialog(DownsampleDialog):
    def _createRightPreview(self, rightFrame):
        self.isInnerRad = True
        listeners = {
            "<Button-4>": self.makeBigger,
            "<Button-5>": self.makeSmaller,
            "<Up>": self.upKeyPress,
            "<Down>": self.downKeyPress
        }
        from pyworkflow.gui.matplotlib_image import PsdPreview
        return PsdPreview(rightFrame,
                          self.dim,
                          self.lf,
                          self.hf,
                          label=self.rightPreviewLabel,
                          listenersDict=listeners)

    def downKeyPress(self, event):
        self.isInnerRad = False
        self.highlightOuterSlider()

    def upKeyPress(self, event):
        self.isInnerRad = True
        self.highlightInnerSlider()

    def highlightOuterSlider(self):
        self.hfSlider.highlightLabel()
        self.lfSlider.removeHighlightFromLabel()

    def highlightInnerSlider(self):
        self.lfSlider.highlightLabel()
        self.hfSlider.removeHighlightFromLabel()

    def makeBigger(self, event):
        self.isMakingBigger = True
        if self.isInnerRad:
            self.lf = self.lf + self.step
        else:
            new_val = self.hf + self.step
            if new_val <= 0.5:  # Don't make the mask bigger unless the is equal or lower than the max
                self.hf = new_val
        self.manageMaskVals()

    def makeSmaller(self, event):
        self.isMakingBigger = False
        if self.isInnerRad:
            new_val = self.lf - self.step
            if new_val >= 0:
                self.lf = new_val
        else:
            self.hf = self.hf - self.step
        self.manageMaskVals()

    def manageMaskVals(self):
        if self.isMakingBigger:
            if self.isInnerRad and self.lf >= self.hf:  # Inner ring can't be bigger than outer ring
                # Subtract one step to go back to the nearest lower value
                self.lf = self.hf - self.step
        else:
            if not self.isInnerRad and self.hf <= self.lf:  # Outer ring can't be smaller than inner
                # ring
                # Add one step to go back to the nearest higher value
                self.hf = self.lf + self.step

        # Set the ring sliders in case it comes from the mouse wheel
        self.setFreq(self.lfSlider, self.lf)
        self.setFreq(self.hfSlider, self.hf)

        # Show values
        self.showValues(self.hfVar, self.hfSlider)
        self.showValues(self.lfVar, self.lfSlider)

        # Update mask
        self.rightPreview.updateFreq(self.lf, self.hf)

    def _showInAngstroms(self):
        return getattr(self, 'showInAngstroms', False)

    def _createControls(self, frame):
        frame.columnconfigure(0, weight=1)
        frame.columnconfigure(1, weight=1)
        frame.columnconfigure(2, weight=1)

        self.step = 0.01
        self.freqFrame = ttk.LabelFrame(frame, text="Frequencies")
        self.freqFrame.columnconfigure(0, weight=3)
        self.freqFrame.grid(row=0, column=2, sticky='news')
        self.lfSlider = LabelSlider(
            self.freqFrame,
            'Low freq',
            value=self.lf,
            from_=0.01,
            to=0.5,
            length=178,
            labelWidth=13,
            step=self.step,
            showvalue=0,
            callback=lambda a, b, c: self.updateSliderInnerRadius(),
        )
        self.lfSlider.grid(row=0, column=0, padx=5, pady=5, sticky='news')
        self.lfSlider.highlightLabel()
        self.hfSlider = LabelSlider(
            self.freqFrame,
            'High freq',
            value=self.lf,
            from_=0.01,
            to=0.5,
            length=178,
            labelWidth=13,
            step=self.step,
            showvalue=0,
            callback=lambda a, b, c: self.updateSliderOuterRadius(),
        )
        self.hfSlider.grid(row=1, column=0, padx=5, pady=5, sticky='news')

        # Pack and configure low freq slider
        self.lfVar = tk.StringVar()
        self.lfLabel = tk.Label(self.freqFrame,
                                textvariable=self.lfVar,
                                width=26)
        self.lfLabel.grid(row=0, column=1, sticky='nse', padx=5, pady=5)
        # Pack and configure high freq slider
        self.hfVar = tk.StringVar()
        self.hfLabel = tk.Label(self.freqFrame,
                                textvariable=self.hfVar,
                                width=26)
        self.hfLabel.grid(row=1, column=1, sticky='nse', padx=5, pady=5)
        # Update both mask and sliders with the initial values
        self.manageMaskVals()

    # def getDownsample(self):
    #     return 1.0  # Micrograph previously downsample, not taken into account here

    def updateFreqRing(self):
        self.rightPreview.updateFreq(self.getLowFreq(), self.getHighFreq())
        self.showValues(self.lfVar, self.lfSlider)
        self.showValues(self.hfVar, self.hfSlider)

    def updateSliderOuterRadius(self):
        new_val = self.getFreq(self.hfSlider)
        # Carry out the action only if the slider is clicked & dragged (prevent from minimal variations when the mouse
        # is on the slider but not clicking on it)
        if abs(new_val - self.hf) >= self.step:
            self.highlightOuterSlider()
            self.isInnerRad = False
            self.isMakingBigger = False
            # Check if the user is making the ring bigger
            if new_val > self.hf:
                self.isMakingBigger = True

            self.hf = new_val
            self.manageMaskVals()

    def updateSliderInnerRadius(self):
        new_val = self.getFreq(self.lfSlider)
        # Highlight only if the slider is clicked & dragged (prevent from minimal variations when the mouse is on the
        # slider but not clicking on it)
        if abs(new_val - self.lf) >= self.step:
            self.highlightInnerSlider()
            self.isInnerRad = True
            self.isMakingBigger = False
            # Check if the user is making the ring bigger
            if new_val > self.lf:
                self.isMakingBigger = True

            self.lf = new_val
            self.manageMaskVals()

    def showValues(self, var2set, labSlider):
        """
        Show the values selected for the inner and outer radius. If the units are angstroms (sampling_rate = 1,
        it will show only one value to avoid redundancies
        """
        sr = self.firstItem.getSamplingRate()
        freqVal = max(self.getFreq(labSlider),
                      0.0001)  # avoid division by zero
        if sr == 1:
            var2set.set('{:2.2f} {}'.format(labSlider.slider.get(),
                                            emcts.UNIT_PIXEL))
        else:
            var2set.set('{:2.2f} rad/{} | {:5.1f} {}'.format(
                labSlider.slider.get(), emcts.UNIT_ANGSTROM_SYMBOL,
                self.getDownsample() * sr / freqVal,
                emcts.UNIT_ANGSTROM_SYMBOL))

    def getLowFreq(self):
        return self.lfSlider.get()

    def getHighFreq(self):
        return self.hfSlider.get()

    @staticmethod
    def getFreq(freqSlider):
        return freqSlider.get()

    @staticmethod
    def setFreq(freqSlider, val):
        freqSlider.slider.set(val)
Esempio n. 2
0
class MaskRadiiPreviewDialog(MaskPreviewDialog):
    def _createPreview(self, frame):
        """ Should be implemented by subclasses to
        create the items preview.
        """
        # Insert the corresponding explanation text
        self.expText.updateExpText(emcts.RING_MASK_WIZ_MSG)

        from pyworkflow.gui.matplotlib_image import MaskPreview
        if self.innerRadius is None:
            self.innerRadius = 1
        if self.outerRadius is None or self.outerRadius == -1 or self.outerRadius > self.dim_par / 2:
            self.outerRadius = int(self.dim_par / 2)

        if self.unit == emcts.UNIT_ANGSTROM:
            self.innerRadius = self.innerRadius / self.samplingRate
            self.outerRadius = self.innerRadius / self.samplingRate

        listeners = {
            "<Button-4>": self.makeBigger,
            "<Button-5>": self.makeSmaller,
            "<Up>": self.upKeyPress,
            "<Down>": self.downKeyPress
        }

        self.preview = MaskPreview(frame,
                                   self.dim,
                                   label=self.previewLabel,
                                   listenersDict=listeners)

        self.preview.grid(row=1, column=0)

    def upKeyPress(self, event):
        self.isInnerRad = False
        self.highlightOuterSlider()

    def downKeyPress(self, event):
        self.isInnerRad = True
        self.highlightInnerSlider()

    def highlightOuterSlider(self):
        self.radiusSliderOut.highlightLabel()
        self.radiusSliderIn.removeHighlightFromLabel()

    def highlightInnerSlider(self):
        self.radiusSliderIn.highlightLabel()
        self.radiusSliderOut.removeHighlightFromLabel()

    def makeBigger(self, event):
        self.isMakingBigger = True
        if self.isInnerRad:
            self.innerRadius = self.innerRadius + self.step
        else:
            new_val = self.outerRadius + self.step
            if new_val <= int(
                    self.dim_par / 2
            ):  # Don't make the mask bigger unless the is equal or lower than the max
                self.outerRadius = new_val
        self.manageMaskVals()

    def makeSmaller(self, event):
        self.isMakingBigger = False
        if self.isInnerRad:
            new_val = self.innerRadius - self.step
            if new_val >= 0:
                self.innerRadius = new_val
        else:
            self.outerRadius = self.outerRadius - self.step
        self.manageMaskVals()

    def manageMaskVals(self):
        if self.isMakingBigger:
            if self.isInnerRad and self.innerRadius >= self.outerRadius:  # Inner ring can't be bigger than outer ring
                # Subtract one step to go back to the nearest lower value
                self.innerRadius = self.outerRadius - self.step
        else:
            if not self.isInnerRad and self.outerRadius <= self.innerRadius:  # Outer ring can't be smaller than inner
                # ring
                # Add one step to go back to the nearest higher value
                self.outerRadius = self.innerRadius + self.step

        # Set the ring sliders in case it comes from the mouse wheel
        self.setRadius(self.radiusSliderIn, self.innerRadius)
        self.setRadius(self.radiusSliderOut, self.outerRadius)

        # Show values
        self.showValues(self.orVar, self.radiusSliderOut)
        self.showValues(self.irVar, self.radiusSliderIn)

        # Update mask
        self.preview.updateMask(self.outerRadius * self.ratio,
                                self.innerRadius * self.ratio)

    def _createControls(self, frame):
        self.step = 1
        to = int(self.dim_par / 2)
        self.radiusSliderOut = LabelSlider(
            frame,
            'Outer radius',
            from_=1,
            to=to,
            value=self.outerRadius,
            step=self.step,
            callback=lambda a, b, c: self.updateSliderOuterRadius(),
            length=150,
            showvalue=0)
        self.radiusSliderOut.highlightLabel()
        self.orVar = tk.StringVar()
        self.orLabel = tk.Label(frame, textvariable=self.orVar, width=20)

        self.radiusSliderIn = LabelSlider(
            frame,
            'Inner radius',
            from_=1,
            to=to,
            value=self.innerRadius,
            step=self.step,
            callback=lambda a, b, c: self.updateSliderInnerRadius(),
            length=150,
            showvalue=0)
        self.irVar = tk.StringVar()
        self.irLabel = tk.Label(frame, textvariable=self.irVar, width=20)
        # Pack and configure outer radius slider
        self.radiusSliderOut.grid(row=0, column=0, sticky='NEWS')
        self.radiusSliderOut.columnconfigure(0, weight=1)
        self.orLabel.grid(row=0, column=1, sticky='NSE', padx=5, pady=5)
        self.orLabel.columnconfigure(0, weight=1)
        # Pack and configure inner radius slider
        self.radiusSliderIn.grid(row=1, column=0, sticky='NEWS')
        self.radiusSliderIn.columnconfigure(0, weight=1)
        self.irLabel.grid(row=1, column=1, sticky='NSE', padx=5, pady=5)
        self.irLabel.columnconfigure(0, weight=1)
        # Update both mask and sliders with the initial values
        self.manageMaskVals()

    def updateSliderOuterRadius(self):
        new_val = self.getRadius(self.radiusSliderOut)
        # Carry out the action only if the slider is clicked & dragged (prevent from minimal variations when the mouse
        # is on the slider but not clicking on it)
        if abs(new_val - self.outerRadius) >= self.step:
            self.highlightOuterSlider()
            self.isInnerRad = False
            self.isMakingBigger = False
            # Check if the user is making the ring bigger
            if new_val > self.outerRadius:
                self.isMakingBigger = True

            self.outerRadius = new_val
            self.manageMaskVals()

    def updateSliderInnerRadius(self):
        new_val = self.getRadius(self.radiusSliderIn)
        # Highlight only if the slider is clicked & dragged (prevent from minimal variations when the mouse is on the
        # slider but not clicking on it)
        if abs(new_val - self.innerRadius) >= self.step:
            self.highlightInnerSlider()
            self.isInnerRad = True
            self.isMakingBigger = False
            # Check if the user is making the ring bigger
            if new_val > self.innerRadius:
                self.isMakingBigger = True

            self.innerRadius = new_val
            self.manageMaskVals()