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)
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()