Пример #1
0
class FitAllDialog(wx.Dialog):
    #==================
    def __init__(self, parent):
        self.parent = parent
        wx.Dialog.__init__(self, self.parent.frame, -1,
                           "Least Squares Optimization")
        self.lsfit = None

        inforow = wx.FlexGridSizer(5, 4, 15, 15)

        thetastr = "%3.3f" % self.parent.data['theta']
        label = wx.StaticText(self,
                              -1,
                              "Tilt angle (theta): ",
                              style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        #self.tiltvalue = wx.StaticText(self, -1, thetastr, style=wx.ALIGN_CENTER|wx.ALIGN_CENTER_VERTICAL)
        self.thetavalue = FloatEntry(self,
                                     -1,
                                     allownone=False,
                                     chars=8,
                                     value=thetastr)
        label2 = wx.StaticText(self,
                               -1,
                               "degrees",
                               style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.thetatog = wx.ToggleButton(self, -1, "Refine")
        self.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleTheta, self.thetatog)
        #self.thetavalue.Enable(False)
        #self.thetatog.SetValue(1)
        inforow.Add(label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(
            self.thetavalue, 0,
            wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 3)
        inforow.Add(label2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.thetatog, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

        gammastr = "%3.3f" % self.parent.data['gamma']
        label = wx.StaticText(self,
                              -1,
                              "Image 1 Rotation (gamma): ",
                              style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.gammavalue = FloatEntry(self,
                                     -1,
                                     allownone=False,
                                     chars=8,
                                     value=gammastr)
        label2 = wx.StaticText(self,
                               -1,
                               "degrees",
                               style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.gammatog = wx.ToggleButton(self, -1, "Refine")
        self.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleGamma, self.gammatog)
        inforow.Add(label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.gammavalue, 0,
                    wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(label2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.gammatog, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

        phistr = "%3.3f" % self.parent.data['phi']
        label = wx.StaticText(self,
                              -1,
                              "Image 2 Rotation (phi): ",
                              style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.phivalue = FloatEntry(self,
                                   -1,
                                   allownone=False,
                                   chars=8,
                                   value=phistr)
        label2 = wx.StaticText(self,
                               -1,
                               "degrees",
                               style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.phitog = wx.ToggleButton(self, -1, "Refine")
        self.Bind(wx.EVT_TOGGLEBUTTON, self.onTogglePhi, self.phitog)
        inforow.Add(label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.phivalue, 0,
                    wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(label2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.phitog, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

        scalestr = "%3.3f" % self.parent.data['scale']
        label = wx.StaticText(self,
                              -1,
                              "Scaling factor: ",
                              style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.scalevalue = FloatEntry(self,
                                     -1,
                                     allownone=False,
                                     chars=8,
                                     value=scalestr)
        label2 = wx.StaticText(self,
                               -1,
                               " ",
                               style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.scaletog = wx.ToggleButton(self, -1, "Locked")
        self.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleScale, self.scaletog)
        self.scalevalue.Enable(False)
        self.scaletog.SetValue(1)
        inforow.Add(label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.scalevalue, 0,
                    wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(label2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.scaletog, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

        shiftxstr = "%3.3f" % self.parent.data['shiftx']
        shiftystr = "%3.3f" % self.parent.data['shifty']
        label = wx.StaticText(self,
                              -1,
                              "Shift (x,y) pixels: ",
                              style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.shiftxvalue = FloatEntry(self,
                                      -1,
                                      allownone=False,
                                      chars=8,
                                      value=shiftxstr)
        self.shiftyvalue = FloatEntry(self,
                                      -1,
                                      allownone=False,
                                      chars=8,
                                      value=shiftystr)
        self.shifttog = wx.ToggleButton(self, -1, "Refine")
        self.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleShift, self.shifttog)
        #self.shiftxvalue.Enable(False)
        #self.shiftyvalue.Enable(False)
        #self.shifttog.SetValue(1)
        inforow.Add(label, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.shiftxvalue, 0,
                    wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.shiftyvalue, 0,
                    wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL)
        inforow.Add(self.shifttog, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

        summaryrow = wx.GridSizer(1, 4)
        label = wx.StaticText(self,
                              -1,
                              "RMSD (pixels): ",
                              style=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        self.rmsdlabel = wx.StaticText(self,
                                       -1,
                                       " unknown ",
                                       style=wx.ALIGN_LEFT
                                       | wx.ALIGN_CENTER_VERTICAL)
        summaryrow.Add(label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        summaryrow.Add(self.rmsdlabel, 0,
                       wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        label = wx.StaticText(self,
                              -1,
                              "Iterations: ",
                              style=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        self.iterlabel = wx.StaticText(self,
                                       -1,
                                       " none ",
                                       style=wx.ALIGN_LEFT
                                       | wx.ALIGN_CENTER_VERTICAL)
        summaryrow.Add(label, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
        summaryrow.Add(self.iterlabel, 0,
                       wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

        self.cancelfitall = wx.Button(self, wx.ID_CANCEL, '&Cancel')
        self.applyfitall = wx.Button(self, wx.ID_APPLY, '&Apply')
        self.runfitall = wx.Button(self, -1, '&Run')
        self.Bind(wx.EVT_BUTTON, self.onRunLeastSquares, self.runfitall)
        self.Bind(wx.EVT_BUTTON, self.onApplyLeastSquares, self.applyfitall)
        buttonrow = wx.GridSizer(1, 3)
        buttonrow.Add(self.cancelfitall, 0,
                      wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
        buttonrow.Add(self.applyfitall, 0,
                      wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
        buttonrow.Add(self.runfitall, 0,
                      wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)

        self.sizer = wx.FlexGridSizer(3, 1)
        self.sizer.Add(inforow, 0, wx.EXPAND | wx.ALL, 10)
        self.sizer.Add(summaryrow, 0, wx.EXPAND | wx.ALL, 5)
        self.sizer.Add(buttonrow, 0, wx.EXPAND | wx.ALL, 5)
        self.SetSizerAndFit(self.sizer)

        self.onToggleScale(True)

    #==================
    def onToggleTheta(self, evt):
        if self.thetatog.GetValue() is True:
            self.thetavalue.Enable(False)
            self.thetatog.SetLabel("Locked")
        else:
            self.thetavalue.Enable(True)
            self.thetatog.SetLabel("Refine")

    #==================
    def onToggleGamma(self, evt):
        if self.gammatog.GetValue() is True:
            self.gammavalue.Enable(False)
            self.gammatog.SetLabel("Locked")
        else:
            self.gammavalue.Enable(True)
            self.gammatog.SetLabel("Refine")

    #==================
    def onTogglePhi(self, evt):
        if self.phitog.GetValue() is True:
            self.phivalue.Enable(False)
            self.phitog.SetLabel("Locked")
        else:
            self.phivalue.Enable(True)
            self.phitog.SetLabel("Refine")

    #==================
    def onTogglePhi(self, evt):
        if self.phitog.GetValue() is True:
            self.phivalue.Enable(False)
            self.phitog.SetLabel("Locked")
        else:
            self.phivalue.Enable(True)
            self.phitog.SetLabel("Refine")

    #==================
    def onToggleScale(self, evt):
        if self.scaletog.GetValue() is True:
            self.scalevalue.Enable(False)
            self.scaletog.SetLabel("Locked")
        else:
            self.scalevalue.Enable(True)
            self.scaletog.SetLabel("Refine")

    #==================
    def onToggleShift(self, evt):
        if self.shifttog.GetValue() is True:
            self.shiftxvalue.Enable(False)
            self.shiftyvalue.Enable(False)
            self.shifttog.SetLabel("Locked")
        else:
            self.shiftxvalue.Enable(True)
            self.shiftyvalue.Enable(True)
            self.shifttog.SetLabel("Refine")

    #==================
    def onRunLeastSquares(self, evt):
        theta = self.thetavalue.GetValue()
        gamma = self.gammavalue.GetValue()
        phi = self.phivalue.GetValue()
        scale = self.scalevalue.GetValue()
        shiftx = self.shiftxvalue.GetValue()
        shifty = self.shiftyvalue.GetValue()
        #SET XSCALE
        xscale = numpy.array((
            not self.thetatog.GetValue(),
            not self.gammatog.GetValue(),
            not self.phitog.GetValue(),
            not self.scaletog.GetValue(),
            not self.shifttog.GetValue(),
            not self.shifttog.GetValue(),
        ),
                             dtype=numpy.float32)
        #GET TARGETS
        targets1 = self.parent.panel1.getTargets('Picked')
        a1 = self.parent.targetsToArray(targets1)
        targets2 = self.parent.panel2.getTargets('Picked')
        a2 = self.parent.targetsToArray(targets2)
        if len(a1) > len(a2):
            print "shorten a1"
            a1 = a1[0:len(a2), :]
        elif len(a2) > len(a1):
            print "shorten a2"
            a2 = a2[0:len(a1), :]
        self.lsfit = apTiltTransform.willsq(a1, a2, theta, gamma, phi, scale,
                                            shiftx, shifty, xscale)
        #pprint.pprint(self.lsfit)
        self.thetavalue.SetValue(round(self.lsfit['theta'], 5))
        self.gammavalue.SetValue(round(self.lsfit['gamma'], 5))
        self.phivalue.SetValue(round(self.lsfit['phi'], 5))
        self.scalevalue.SetValue(round(self.lsfit['scale'], 5))
        self.shiftxvalue.SetValue(round(self.lsfit['shiftx'], 5))
        self.shiftyvalue.SetValue(round(self.lsfit['shifty'], 5))
        self.rmsdlabel.SetLabel(str(round(self.lsfit['rmsd'], 5)))
        self.iterlabel.SetLabel(str(self.lsfit['iter']))

    #==================
    def onApplyLeastSquares(self, evt):
        self.Close()
        self.parent.data['leastsqfitdata'] = self.lsfit
        self.parent.data['theta'] = self.thetavalue.GetValue()
        self.parent.data['gamma'] = self.gammavalue.GetValue()
        self.parent.data['phi'] = self.phivalue.GetValue()
        self.parent.data['scale'] = self.scalevalue.GetValue()
        self.parent.data['shiftx'] = self.shiftxvalue.GetValue()
        self.parent.data['shifty'] = self.shiftyvalue.GetValue()
        self.parent.data['rmsd'] = self.lsfit['rmsd']
        self.parent.data['point1'] = self.lsfit['point1']
        self.parent.data['point2'] = self.lsfit['point2']
        self.parent.data['optimrun'] = True
        self.parent.onUpdate(evt)
class ContrastTool(object):
        def __init__(self, imagepanel, sizer):
                self.imagepanel = imagepanel
                self.imagemin = 0
                self.imagemax = 0
                self.contrastmin = 0
                self.contrastmax = 0
                self.slidermin = 0
                self.slidermax = 255

                self.minslider = wx.Slider(self.imagepanel, -1, self.slidermin, self.slidermin, self.slidermax, size=(180, -1))
                self.maxslider = wx.Slider(self.imagepanel, -1, self.slidermax, self.slidermin, self.slidermax, size=(180, -1))
                self.minslider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.onMinSlider)
                self.maxslider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.onMaxSlider)
                self.minslider.Bind(wx.EVT_SCROLL_ENDSCROLL, self.onMinSlider)
                self.maxslider.Bind(wx.EVT_SCROLL_ENDSCROLL, self.onMaxSlider)
                self.minslider.Bind(wx.EVT_SCROLL_THUMBTRACK, self.onMinSlider)
                self.maxslider.Bind(wx.EVT_SCROLL_THUMBTRACK, self.onMaxSlider)

                self.iemin = FloatEntry(imagepanel, -1, chars=6, allownone=False, value='%g' % self.contrastmin)
                self.iemax = FloatEntry(imagepanel, -1, chars=6, allownone=False, value='%g' % self.contrastmax)
                self.iemin.Enable(False)
                self.iemax.Enable(False)

                self.iemin.Bind(EVT_ENTRY, self.onMinEntry)
                self.iemax.Bind(EVT_ENTRY, self.onMaxEntry)

                self.sizer = wx.GridBagSizer(0, 0)
                self.sizer.Add(self.minslider, (0, 0), (1, 1), wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM)
                self.sizer.Add(self.iemin, (0, 1), (1, 1), wx.ALIGN_CENTER|wx.FIXED_MINSIZE|wx.ALL, 2)
                self.sizer.Add(self.maxslider, (1, 0), (1, 1), wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_TOP)
                self.sizer.Add(self.iemax, (1, 1), (1, 1), wx.ALIGN_CENTER|wx.FIXED_MINSIZE|wx.ALL, 2)
                sizer.Add(self.sizer, 0, wx.ALIGN_CENTER)

        #--------------------
        def _setSliders(self, value):
                if value[0] is not None:
                        self.minslider.SetValue(self.getSliderValue(value[0]))
                if value[1] is not None:
                        self.maxslider.SetValue(self.getSliderValue(value[1]))

        #--------------------
        def _setEntries(self, value):
                if value[0] is not None:
                        self.iemin.SetValue(value[0])
                if value[1] is not None:
                        self.iemax.SetValue(value[1])

        #--------------------
        def setSliders(self, value):
                if value[0] is not None:
                        self.contrastmin = value[0]
                if value[1] is not None:
                        self.contrastmax = value[1]
                self._setSliders(value)
                self._setEntries(value)

        #--------------------
        def updateNumericImage(self):
                self.imagepanel.setBitmap()
                self.imagepanel.setBuffer()
                self.imagepanel.UpdateDrawing()

        #--------------------
        def getRange(self):
                return self.contrastmin, self.contrastmax

        #--------------------
        def getScaledValue(self, position):
                try:
                        scale = float(position - self.slidermin)/(self.slidermax - self.slidermin)
                except ZeroDivisionError:
                        scale = 1.0
                return (self.imagemax - self.imagemin)*scale + self.imagemin

        #--------------------
        def getSliderValue(self, value):
                if self.imagemax == self.imagemin:
                        return self.imagemin
                scale = (value - self.imagemin)/(self.imagemax - self.imagemin)
                return int(round((self.slidermax - self.slidermin)*scale + self.slidermin))

        #--------------------
        def setRange(self, range, value=None):
                if range is None:
                        self.imagemin = 0
                        self.imagemax = 0
                        self.contrastmin = 0
                        self.contrastmax = 0
                        self.iemin.SetValue(0.0)
                        self.iemax.SetValue(0.0)
                        self.iemin.Enable(False)
                        self.iemax.Enable(False)
                        self.minslider.Enable(False)
                        self.maxslider.Enable(False)
                else:
                        self.imagemin = range[0]
                        self.imagemax = range[1]
                        if value is None:
                                self.contrastmin = self.getScaledValue(self.minslider.GetValue())
                                self.contrastmax = self.getScaledValue(self.maxslider.GetValue())
                        else:
                                self.setSliders(value)
                        self.iemin.Enable(True)
                        self.iemax.Enable(True)
                        self.minslider.Enable(True)
                        self.maxslider.Enable(True)

        #--------------------
        def onMinSlider(self, evt):
                position = evt.GetPosition()
                maxposition = self.maxslider.GetValue()
                if position > maxposition:
                        self.minslider.SetValue(maxposition)
                        self.contrastmin = self.contrastmax
                else:
                        self.contrastmin = self.getScaledValue(position)
                self._setEntries((self.contrastmin, None))
                self.updateNumericImage()

        #--------------------
        def onMaxSlider(self, evt):
                position = evt.GetPosition()
                minposition = self.minslider.GetValue()
                if position < minposition:
                        self.maxslider.SetValue(minposition)
                        self.contrastmax = self.contrastmin
                else:
                        self.contrastmax = self.getScaledValue(position)
                self._setEntries((None, self.contrastmax))
                self.updateNumericImage()

        #--------------------
        def onMinEntry(self, evt):
                contrastmin = evt.GetValue()
                if contrastmin < self.imagemin:
                        self.contrastmin = self.imagemin
                        self.iemin.SetValue(self.contrastmin)
                elif contrastmin > self.contrastmax:
                        self.contrastmin = self.contrastmax
                        self.iemin.SetValue(self.contrastmin)
                else:
                        self.contrastmin = contrastmin
                self._setSliders((self.contrastmin, None))
                self.updateNumericImage()

        #--------------------
        def onMaxEntry(self, evt):
                contrastmax = evt.GetValue()
                if contrastmax > self.imagemax:
                        self.contrastmax = self.imagemax
                        self.iemax.SetValue(self.contrastmax)
                elif contrastmax < self.contrastmin:
                        self.contrastmax = self.contrastmin
                        self.iemax.SetValue(self.contrastmax)
                else:
                        self.contrastmax = contrastmax
                self._setSliders((None, self.contrastmax))
                self.updateNumericImage()