Пример #1
0
    def SetStart(self):
        # Sets first and second variable of a page to
        # Parameters A and B respectively.
        if self.parent.notebook.GetPageCount() == 0:
            self.modelid = 6000
            ParmLabels, ParmValues = \
                   mdls.GetHumanReadableParms(self.modelid,
                                              mdls.valuedict[6000][1])
        else:
            self.SavedParms = self.parent.PackParameters(self.Page)
            self.modelid = self.Page.modelid
            ParmLabels, ParmValues = \
                   mdls.GetHumanReadableParms(self.modelid,
                                              self.Page.active_parms[1])

        self.parmAlist = ParmLabels
        self.parmBlist = ParmLabels
        # Operators
        # Calculation of variable A with fixed B
        self.opdict = dict()
        self.FillOpDict()
        self.oplist = self.opdict.keys()
        self.oplist.sort()
        self.labelA = self.parmAlist[0]
        self.labelB = self.parmBlist[1]
        self.labelOp = self.oplist[0]
        self.opfunc = self.opdict[self.labelOp]
        self.valueA = ParmValues[0]
        self.valueB = ParmValues[1]
        self.valueB, self.valueOp = self.CalcFct(self.valueA, self.valueB, 0)
Пример #2
0
    def FillPanel(self):
        """ Fill the panel with parameters from the page
        """
        corr = self.Page.corr
        self.parameter_range = np.zeros_like(corr.fit_parameters_range)
        leftbound = []
        for item in corr.fit_parameters_range[:, 0]:
            if item is None:
                leftbound.append(-np.inf)
            else:
                leftbound.append(item)
        labels, parmleft = mdls.GetHumanReadableParms(corr.fit_model.id,  # @UnusedVariable
                                                      leftbound)
        rightbound = []
        for item in corr.fit_parameters_range[:, 1]:
            if item is None:
                rightbound.append(np.inf)
            else:
                rightbound.append(item)

        labels, parmright = mdls.GetHumanReadableParms(corr.fit_model.id,
                                                       rightbound)
        self.parameter_range[:, 0] = np.array(parmleft)
        self.parameter_range[:, 1] = np.array(parmright)
        # create line

        self.WXboxsizer = wx.FlexGridSizer(
            rows=len(labels), cols=5, vgap=5, hgap=5)
        for i in range(len(labels)):
            left = wxutils.PCFFloatTextCtrl(self.panel)
            right = wxutils.PCFFloatTextCtrl(self.panel)
            left.SetValue(self.parameter_range[i][0])
            right.SetValue(self.parameter_range[i][1])
            left.Bind(wx.EVT_SPINCTRL, self.OnSetParmRange)
            right.Bind(wx.EVT_SPINCTRL, self.OnSetParmRange)
            text = wx.StaticText(self.panel, label=u'< ')
            text2 = wx.StaticText(self.panel, label=labels[i])
            text3 = wx.StaticText(self.panel, label=u' <')
            self.WXboxsizer.Add(left)
            self.WXboxsizer.Add(text)
            self.WXboxsizer.Add(text2, 0, wx.ALIGN_CENTER, 0)
            self.WXboxsizer.Add(text3)
            self.WXboxsizer.Add(right)
            self.WXparmlist.append([left, [text, text2, text3], right])
        self.WXboxsizer.Layout()

        self.topSizer.Add(self.WXboxsizer)
        self.btnapply = wx.Button(self.panel, wx.ID_ANY, 'Apply')
        self.Bind(wx.EVT_BUTTON, self.OnSetParmRange, self.btnapply)
        self.topSizer.Add(self.btnapply)

        self.topSizer.Layout()
        self.panel.SetSizer(self.topSizer)
        self.topSizer.Fit(self.panel)
        self.SetMinSize((self.topSizer.GetMinSize()[0] + 20,
                         self.topSizer.GetMinSize()[1] + 40))
        self.topSizer.Fit(self)
Пример #3
0
 def SetValues(self, event=None):
     # Set the values for spin and slider
     # As of version 0.7.5: we want the units to be displayed
     # human readable - the way they are displayed
     # in the Page info tool.
     #
     # Parameter A
     idA = self.droppA.GetSelection()
     # Parameter B
     idB = self.droppB.GetSelection()
     # self.valueB = self.Page.active_parms[1][idB]
     # self.valueA = self.Page.active_parms[1][idA]
     if self.parent.notebook.GetPageCount() == 0:
         self.modelid = 6000
         ParmValues = \
                mdls.GetHumanReadableParms(self.modelid,
                                     mdls.valuedict[6000][1])[1]
     else:
         self.modelid = self.Page.modelid
         ParmValues = \
                mdls.GetHumanReadableParms(self.modelid,
                                     self.Page.active_parms[1])[1]
     self.valueA = ParmValues[idA]
     self.valueB = ParmValues[idB]
     # Operator
     idop = self.dropop.GetSelection()
     #keys = self.opdict.keys()
     opkey = self.oplist[idop]
     self.opfunc = self.opdict[opkey]
     # Parameter A
     startA = self.valueA * self.spinstartfactor
     endA = self.valueA * self.spinendfactor
     self.startspinA.SetValue(startA)
     self.endspinA.SetValue(endA)
     # Parameter B
     startB = self.valueB * self.spinstartfactor
     endB = self.valueB * self.spinendfactor
     self.startspinB.SetValue(startB)
     self.endspinB.SetValue(endB)
     # Operation result
     self.valueOp = self.opfunc[0](self.valueA, self.valueB)
     startOp = self.valueOp * self.spinstartfactor
     endOp = self.valueOp * self.spinendfactor
     self.startspinOp.SetValue(startOp)
     self.endspinOp.SetValue(endOp)
     # Set text
     self.textvalueA.SetLabel("%.5e" % self.valueA)
     self.textvalueB.SetLabel("%.5e" % self.valueB)
     self.textvalueOp.SetLabel("%.5e" % self.valueOp)
     self.SetResult()
Пример #4
0
    def RedrawParameterBox(self, e=None):
        sizer = self.parameter_sizer
        panel = self.panel
        for child in sizer.GetChildren():
            window = child.GetWindow()
            panel.RemoveChild(window)
            sizer.RemoveWindow(window)
            window.Destroy()

        text = wx.StaticText(panel,
                             label="""If desired, (de)select
individual parameters
for batch modification.""")
        sizer.Add(text)

        if self.parent.notebook.GetPageCount():
            # Get parameters of current page
            parms = self.GetParameters()
            modelid = parms[1]
            ptext, _pval = mdls.GetHumanReadableParms(modelid, parms[2])
            ptext = [p.split()[0] for p in ptext]
            self.wxParameterCheckBoxes = []
            for p in ptext:
                cb = wx.CheckBox(panel, label=p)
                cb.SetValue(True)
                self.wxParameterCheckBoxes.append(cb)
                sizer.Add(cb)

        # Try to set sizes correctly
        box = sizer.GetStaticBox()
        boxs = box.GetBestSize()
        sizs = sizer.GetMinSize()
        thesize = (max(boxs[0], sizs[0]), sizs[1])
        sizer.SetMinSize(thesize)
        box.SetSize(thesize)

        try:
            self.mastersizer.Fit(panel)
            panel.Layout()
            self.SetSize(panel.GetSize())
            self.mastersizer.Fit(self)
        except:
            pass
Пример #5
0
    def MakeStaticBoxSizer(self, boxlabel):
        """ Create a Box with check boxes (fit yes/no) and possibilities to
            change initial values for fitting.

            Parameters:
            *boxlabel*: The name of the box (is being displayed)
            *self.active_parms[0]*: A list of things to put into the box

            Returns:
            *sizer*: The static Box
            *check*: The (un)set checkboxes
            *spin*: The spin text fields
        """
        modelid = self.corr.fit_model.id
        box = wx.StaticBox(self.panelsettings, label=boxlabel)
        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
        check = list()
        spin = list()
        #
        # As of version 0.7.5: we want the units to be displayed
        # human readable - the way they are displayed
        # in the Page info tool.
        #
        labels = mdls.GetHumanReadableParms(modelid,
                                            self.corr.fit_parameters)[0]
        sizerh = wx.GridSizer(len(labels), 2, 2, 2)
        for label in labels:
            checkbox = wx.CheckBox(self.panelsettings, label=label)
            # We needed to "from wx.lib.agw import floatspin" to get this:
            spinctrl = wxutils.PCFFloatTextCtrl(self.panelsettings)
            sizerh.Add(spinctrl)
            sizerh.Add(checkbox)
            # Put everything into lists to be able to refer to it later
            check.append(checkbox)
            spin.append(spinctrl)
        sizer.Add(sizerh)
        return sizer, check, spin
Пример #6
0
 def apply_parameters_reverse(self, event=None):
     """ Read the values from the pages parameters and write
         it to the GUI form.
     """
     modelid = self.corr.fit_model.id
     #
     # As of version 0.7.5: we want the units to be displayed
     # human readable - the way they are displayed
     # in the Page info tool.
     #
     # Here: Convert program internal units to
     # human readable units
     parameters = mdls.GetHumanReadableParms(modelid,
                                             self.corr.fit_parameters)[1]
     parameters_variable = self.corr.fit_parameters_variable
     # Write parameters to the form on the Page
     for i in np.arange(len(self.active_parms[1])):
         self.spincontrol[i].SetValue(parameters[i])
         self.checkboxes[i].SetValue(parameters_variable[i])
     # Fitting parameters
     self.Fitbox[5].SetValue(self.weighted_nuvar)
     idf = self.weighted_fittype_id
     List = self.Fitbox[1].GetItems()
     List[1] = "spline (" + str(self.FitKnots) + " knots)"
     self.Fitbox[1].SetItems(List)
     self.Fitbox[1].SetSelection(idf)
     # Normalization
     if self.corr.normparm is None:
         normsel = 0
     else:
         normsel = self.corr.normparm + 1
     self.AmplitudeInfo[2].SetSelection(normsel)
     # Fitting algorithm
     keys = fit.GetAlgorithmStringList()[0]
     idalg = keys.index(self.corr.fit_algorithm)
     self.AlgorithmDropdown.SetSelection(idalg)
     self.updateChi2()
Пример #7
0
    def settings(self):
        """ Here we define, what should be displayed at the left side
            of the fitting page/tab.
            Parameters:
        """
        modelid = self.corr.fit_model.id
        horizontalsize = self.sizepanelx - 10
        # Title
        # Create empty tab title
        mddat = mdls.modeldict[modelid]
        modelshort = mdls.GetModelType(modelid)
        titlelabel = u"Data set {} ({} {})".format(self.counter.strip(" :"),
                                                   modelshort, mddat[1])
        boxti = wx.StaticBox(self.panelsettings, label=titlelabel)
        sizerti = wx.StaticBoxSizer(boxti, wx.VERTICAL)
        sizerti.SetMinSize((horizontalsize, -1))
        self.tabtitle = wx.TextCtrl(self.panelsettings,
                                    value="",
                                    size=(horizontalsize - 20, -1))
        self.Bind(wx.EVT_TEXT, self.OnTitleChanged, self.tabtitle)
        sizerti.Add(self.tabtitle, 0, wx.EXPAND, 0)
        # Create StaticBoxSizer
        box1, check, spin = self.MakeStaticBoxSizer("Model parameters")
        # Make the check boxes and spin-controls available everywhere
        self.checkboxes = check
        self.spincontrol = spin
        #
        # As of version 0.7.5: we want the units to be displayed
        # human readable - the way they are displayed
        # in the Page info tool.
        #
        labels, parameters = mdls.GetHumanReadableParms(
            modelid, self.active_parms[1])
        parameterstofit = self.active_parms[2]
        # Set initial values given by user/programmer for Diffusion Model
        for i in np.arange(len(labels)):
            self.checkboxes[i].SetValue(parameterstofit[i])
            self.spincontrol[i].SetValue(parameters[i])
        # Put everything together
        self.panelsettings.sizer = wx.BoxSizer(wx.VERTICAL)
        self.panelsettings.sizer.Add(sizerti, 0, wx.EXPAND, 0)
        self.panelsettings.sizer.Add(box1, 0, wx.EXPAND, 0)
        # checkbox "Protect from batch control"
        self.wxCBPreventBatchParms = wx.CheckBox(self.panelsettings, -1,
                                                 "prevent batch modification")
        box1.Add(self.wxCBPreventBatchParms)
        # buttons "Apply" and "Set range"
        horzs = wx.BoxSizer(wx.HORIZONTAL)
        buttonapply = wx.Button(self.panelsettings, label="Apply")
        self.Bind(wx.EVT_BUTTON, self.PlotAll, buttonapply)
        horzs.Add(buttonapply)
        buttonrange = wx.Button(self.panelsettings, label="Set range")
        self.Bind(wx.EVT_BUTTON, self.OnSetRange, buttonrange)
        horzs.Add(buttonrange)
        box1.Add(horzs)
        # Set horizontal size
        box1.SetMinSize((horizontalsize, -1))
        # More info
        normbox = wx.StaticBox(self.panelsettings,
                               label="Amplitude corrections")
        miscsizer = wx.StaticBoxSizer(normbox, wx.VERTICAL)
        miscsizer.SetMinSize((horizontalsize, -1))
        # Intensities and Background
        sizeint = wx.FlexGridSizer(rows=3, cols=3, vgap=5, hgap=5)
        sizeint.Add(wx.StaticText(self.panelsettings, label="[kHz]"))
        sizeint.Add(wx.StaticText(self.panelsettings, label="Intensity"))
        sizeint.Add(wx.StaticText(self.panelsettings, label="Background"))
        sizeint.Add(wx.StaticText(self.panelsettings, label="Ch1"))
        intlabel1 = wx.TextCtrl(self.panelsettings)
        bgspin1 = wxutils.PCFFloatTextCtrl(self.panelsettings)
        bgspin1.Bind(wx.EVT_KILL_FOCUS, self.OnBGSpinChanged)
        bgspin1.Bind(wx.EVT_TEXT_ENTER, self.OnBGSpinChanged)
        sizeint.Add(intlabel1)
        intlabel1.SetEditable(False)
        sizeint.Add(bgspin1)
        chtext2 = wx.StaticText(self.panelsettings, label="Ch2")
        sizeint.Add(chtext2)
        intlabel2 = wx.TextCtrl(self.panelsettings)
        intlabel2.SetEditable(False)
        bgspin2 = wxutils.PCFFloatTextCtrl(self.panelsettings)
        bgspin2.Bind(wx.EVT_KILL_FOCUS, self.OnBGSpinChanged)
        sizeint.Add(intlabel2)
        sizeint.Add(bgspin2)
        miscsizer.Add(sizeint)
        # Normalize to n?
        textnor = wx.StaticText(self.panelsettings, label="Plot normalization")
        miscsizer.Add(textnor)
        normtoNDropdown = wx.ComboBox(self.panelsettings)
        self.Bind(wx.EVT_COMBOBOX, self.PlotAll, normtoNDropdown)
        miscsizer.Add(normtoNDropdown)
        self.AmplitudeInfo = [[intlabel1, intlabel2], [bgspin1, bgspin2],
                              normtoNDropdown, textnor]
        self.WXAmplitudeCCOnlyStuff = [chtext2, intlabel2, bgspin2]
        self.panelsettings.sizer.Add(miscsizer, 0, wx.EXPAND, 0)
        # Add fitting Box
        fitbox = wx.StaticBox(self.panelsettings, label="Fitting options")
        fitsizer = wx.StaticBoxSizer(fitbox, wx.VERTICAL)
        fitsizer.SetMinSize((horizontalsize, -1))
        # Add a checkbox for weighted fitting
        weightedfitdrop = wx.ComboBox(self.panelsettings)
        self.weightlist = ["no weights", "spline (5 knots)", "model function"]
        weightedfitdrop.SetItems(self.weightlist)
        weightedfitdrop.SetSelection(0)
        fitsizer.Add(weightedfitdrop)
        # WeightedFitCheck() Enables or Disables the variance part
        weightedfitdrop.Bind(wx.EVT_COMBOBOX, self.Fit_WeightedFitCheck)
        # Add the variance part.
        # In order to do a weighted fit, we need to calculate the variance
        # at each point of the experimental data array.
        # In order to do that, we need to know how many data points from left
        # and right of the interesting data point we want to include in that
        # calculation.
        fittext = wx.StaticText(self.panelsettings,
                                label="Calculation of the variance")
        fitsizer.Add(fittext)
        fittext2 = wx.StaticText(self.panelsettings,
                                 label="from 2j+1 data points")
        fitsizer.Add(fittext2)
        fitsizerspin = wx.BoxSizer(wx.HORIZONTAL)
        fittextvar = wx.StaticText(self.panelsettings, label="j = ")
        fitspin = wx.SpinCtrl(self.panelsettings,
                              -1,
                              initial=3,
                              min=1,
                              max=100)
        fitsizerspin.Add(fittextvar)
        fitsizerspin.Add(fitspin)
        fitsizer.Add(fitsizerspin)
        # Add algorithm selection
        textalg = wx.StaticText(self.panelsettings, label="Algorithm")
        fitsizer.Add(textalg)
        self.AlgorithmDropdown = wx.ComboBox(self.panelsettings)
        items = fit.GetAlgorithmStringList()[1]
        self.AlgorithmDropdown.SetItems(items)
        self.Bind(wx.EVT_COMBOBOX, self.apply_parameters,
                  self.AlgorithmDropdown)
        fitsizer.Add(self.AlgorithmDropdown)
        self.AlgorithmDropdown.SetMaxSize(weightedfitdrop.GetSize())
        # Add button "Fit" and chi2 display
        fitbuttonsizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonfit = wx.Button(self.panelsettings, label="Fit")
        self.Bind(wx.EVT_BUTTON, self.Fit_function, buttonfit)
        fitbuttonsizer.Add(buttonfit)

        # add shortcut
        acctbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('F'),
                                       buttonfit.GetId())])
        self.SetAcceleratorTable(acctbl)
        ##

        self.WXTextChi2 = wx.StaticText(self.panelsettings)
        # this StaticText is updated by `self.updateChi2()`
        fitbuttonsizer.Add(self.WXTextChi2, flag=wx.ALIGN_CENTER)
        fitsizer.Add(fitbuttonsizer)
        self.panelsettings.sizer.Add(fitsizer, 0, wx.EXPAND, 0)
        # Squeeze everything into the sizer
        self.panelsettings.SetSizer(self.panelsettings.sizer)
        # This is also necessary in Windows
        self.panelsettings.Layout()
        self.panelsettings.Show()
        # Make all the stuff available for everyone
        self.Fitbox = [
            fitbox, weightedfitdrop, fittext, fittext2, fittextvar, fitspin,
            buttonfit, textalg, self.AlgorithmDropdown
        ]
        # Disable Fitting since no data has been loaded yet
        for element in self.Fitbox:
            element.Disable()
        self.panelsettings.sizer.Fit(self.panelsettings)
        self.parent.Layout()
Пример #8
0
def savePlotCorrelation(parent,
                        dirname,
                        Page,
                        uselatex=False,
                        verbose=False,
                        show_weights=True):
    """ Save plot from Page into file        
        Parameters:
        *parent*    the parent window
        *dirname*   directory to set on saving
        *Page*      Page containing all variables
        *uselatex*  Whether to use latex for the ploting or not.
        This function uses a hack in misc.py to change the function
        for saving the final figure. We wanted save in the same directory
        as PyCorrFit was working and the filename should be the tabtitle.
    """
    # Close all other plots before commencing
    try:
        plt.close()
    except:
        pass
    # get data
    corr = Page.corr
    dataexp = corr.correlation_plot
    resid = corr.residuals_plot
    fit = corr.modeled_plot

    weights = Page.weights_plot_fill_area
    tabtitle = Page.tabtitle.GetValue()
    #fitlabel = ur"Fit model: "+str(mdls.modeldict[Page.modelid][0])
    fitlabel = Page.corr.fit_model.name
    labelweights = ur"Weights of fit"
    labels, parms = mdls.GetHumanReadableParms(Page.modelid,
                                               corr.fit_parameters)
    if dataexp is None:
        if tabtitle.strip() == "":
            fitlabel = Page.corr.fit_model.name
        else:
            fitlabel = tabtitle
    else:
        if tabtitle.strip() == "":
            tabtitle = "page" + str(Page.counter).strip().strip(":")
    if Page.corr.normparm is not None:
        fitlabel += ur", normalized to " + Page.corr.fit_model.parameters[0][
            Page.corr.normparm]

    ## Check if we can use latex for plotting:
    r1 = find_program("latex")[0]
    r2 = find_program("dvipng")[0]
    # Ghostscript
    r31 = find_program("gs")[0]
    r32 = find_program("mgs")[0]  # from miktex
    r3 = max(r31, r32)
    if r1 + r2 + r3 < 3:
        uselatex = False
    if uselatex == True:
        rcParams['text.usetex'] = True
        rcParams['text.latex.unicode'] = True
        rcParams['font.family'] = 'serif'
        rcParams['text.latex.preamble'] = [
            r"""\usepackage{amsmath}
                                            \usepackage[utf8x]{inputenc}
                                            \usepackage{amssymb}
                                            \usepackage{siunitx}"""
        ]
        fitlabel = ur"{\normalsize " + escapechars(fitlabel) + r"}"
        tabtitle = ur"{\normalsize " + escapechars(tabtitle) + r"}"
        labelweights = ur"{\normalsize " + escapechars(labelweights) + r"}"
    else:
        rcParams['text.usetex'] = False
    # create plot
    # plt.plot(x, y, '.', label = 'original data', markersize=5)
    fig = plt.figure()
    wtit = "Correlation #{:04d}_{}".format(int(Page.counter.strip(":# ")),
                                           Page.title.strip())
    fig.canvas.set_window_title(wtit)
    if resid is not None:
        gs = gridspec.GridSpec(2, 1, height_ratios=[5, 1])
        ax = plt.subplot(gs[0])
    else:
        ax = plt.subplot(111)
        #    ax = plt.axes()
    ax.semilogx()
    # plot fit first
    plt.plot(fit[:, 0], fit[:, 1], '-', label=fitlabel, lw=1.5, color="blue")
    if dataexp is not None:
        plt.plot(dataexp[:, 0],
                 dataexp[:, 1],
                 '-',
                 color="black",
                 alpha=.7,
                 label=tabtitle,
                 lw=1)
    else:
        plt.xlabel(ur'lag time $\tau$ [ms]')

    if weights is not None and show_weights is True:
        plt.fill_between(weights[0][:, 0],
                         weights[0][:, 1],
                         weights[1][:, 1],
                         color='cyan')
        # fake legend:
        p = plt.Rectangle((0, 0), 0, 0, color='cyan', label=labelweights)
        ax.add_patch(p)
    plt.ylabel('correlation')
    if dataexp is not None:
        mind = np.min([dataexp[:, 1], fit[:, 1]])
        maxd = np.max([dataexp[:, 1], fit[:, 1]])
    else:
        mind = np.min(fit[:, 1])
        maxd = np.max(fit[:, 1])
    ymin = mind - (maxd - mind) / 20.
    ymax = maxd + (maxd - mind) / 20.
    ax.set_ylim(bottom=ymin, top=ymax)
    xmin = np.min(fit[:, 0])
    xmax = np.max(fit[:, 0])
    ax.set_xlim(xmin, xmax)
    # Add some nice text:
    if uselatex == True and len(parms) != 0:
        text = r""
        text += r'\['  #every line is a separate raw string...
        text += r'\begin{split}'  # ...but they are all concatenated
        #                          by the interpreter :-)
        for i in np.arange(len(parms)):
            text += ur' {} &= {:.3g} \\'.format(latexmath(labels[i]), parms[i])
        ## According to issue #54, we remove fitting errors from plots
        #if errparms is not None:
        #    keys = errparms.keys()
        #    keys.sort()
        #    for key in keys:
        #        text += r' \Delta '+latexmath(key)+r" &= " + str(errparms[key]) +r' \\ '
        text += r' \end{split} '
        text += r' \] '
    else:
        text = ur""
        for i in np.arange(len(parms)):
            text += u"{} = {:.3g}\n".format(labels[i], parms[i])
        ## According to issue #54, we remove fitting errors from plots
        #if errparms is not None:
        #    keys = errparms.keys()
        #    keys.sort()
        #    for key in keys:
        #        text += "Err "+key+" = " + str(errparms[key]) +"\n"

    logmax = np.log10(xmax)
    logmin = np.log10(xmin)
    logtext = 0.6 * (logmax - logmin) + logmin
    xt = 10**(logtext)
    yt = 0.3 * ymax
    plt.text(xt, yt, text, size=12)
    if resid is not None:
        ax2 = plt.subplot(gs[1])
        #ax2 = plt.axes()
        ax2.semilogx()
        if Page.corr.is_weighted_fit:
            if uselatex == True:
                lb = r"\newline \indent "
            else:
                lb = "\n"
            yLabelRes = "weighted " + lb + "residuals"
        else:
            yLabelRes = "residuals"
        minx = np.min(resid[:, 0])
        maxx = np.max(resid[:, 0])
        miny = np.min(resid[:, 1])
        maxy = np.max(resid[:, 1])
        plt.hlines(0, minx, maxx, colors="orange")
        plt.plot(resid[:, 0],
                 resid[:, 1],
                 '-',
                 color="black",
                 alpha=.85,
                 label=yLabelRes,
                 lw=1)
        plt.xlabel(r'lag time $\tau$ [ms]')
        plt.ylabel(yLabelRes, multialignment='center')

        ax2.set_xlim(minx, maxx)
        maxy = max(abs(maxy), abs(miny))
        ax2.set_ylim(-maxy, maxy)
        ticks = ax2.get_yticks()
        ax2.set_yticks([ticks[0], ticks[-1], 0])
    ## Hack
    # We need this for hacking. See edclasses.
    fig.canvas.HACK_parent = parent
    fig.canvas.HACK_fig = fig
    fig.canvas.HACK_Page = Page
    fig.canvas.HACK_append = ".png"

    # Legend outside of plot
    # Decrease size of plot to fit legend
    box = ax.get_position()

    ax.set_position(
        [box.x0, box.y0 + box.height * 0.2, box.width, box.height * 0.9])

    if resid is not None:
        box2 = ax2.get_position()
        ax2.set_position(
            [box2.x0, box2.y0 + box.height * 0.2, box2.width, box2.height])

    ax.legend(loc='upper center',
              bbox_to_anchor=(0.5, -0.55),
              prop={'size': 9})

    if verbose == True:
        plt.show()
    else:
        # If WXAgg is not used for some reason, then our hack does not work
        # and we must use e.g. TkAgg
        try:
            fig.canvas.toolbar.save()
        except AttributeError:
            fig.canvas.toolbar.save_figure()
        # Close all other plots before commencing
        try:
            plt.close()
        except:
            pass
Пример #9
0
    def SortParameters(parms):
        u"""
        Sort a list of tuples according to the first item.
        The sorting convention was met in issue #113:
        
        - at the beginning: avg. countrates and particle numbers
        - fast components go before slow components:
          e.g. [τ_trip, τ_diff]
        - model parameters are sorted logically according to their origin:
          e.g. [T1, τ_trip1], or [F1, τ_diff1], or [T2, τ_trip2]
        - if the parameter ends with a number, then we sort it to the
          logical blocks - includes n1, n2, etc.
        - at end: other fitting parameters and mode information

        fitting parameters
        
            intensities
            n
            tautrip1
            T1
            tautrip2
            T2
            tau1
            F1
            tau2
            F2
            tau3
            F3
            alpha
            SP
        
        non-fitting parameter
        
            model name
            chisquare
            weighted fit
            interval
            measurement time
            ...
            model id
        """

        startswith_sort = [
            u"avg. signal",
            u"n",
            u"T",
            u"τ_trip",
            u"F",
            u"C",
            u"D",
            u"τ",
            u"τ_diff",
            u"alpha",
            u"SP",
        ]

        otherparms = list()

        # append to this list all parameters that might be in another model.
        for m in mdls.models:
            for p in mdls.GetHumanReadableParms(m.id, m.parameters[1])[0]:
                exists = False
                for sw in startswith_sort + otherparms:
                    if p.startswith(sw):
                        exists = True
                if not exists:
                    otherparms.append(p)

        # sort the other parameters by name
        otherparms.sort()
        # special offsets to distinguish "T" and "Type":
        special_off_start = ["Type", "Fit"]

        def rate_tuple(item):
            x = item[0]
            return rate(x)

        def rate(x):
            """
            rate a parameter for sorting.
            lower values are at the beginning of the list.
            """
            x = x.split("[")[0]
            # start at the top
            r = 0

            # BLOCK OFFSET
            try:
                intx = int(x[-1])
            except:
                pass
            else:
                # penalty: belongs to block
                r += 3 + intx

            # STARTSWITH PENALTY
            for p in startswith_sort:
                if x.startswith(p):
                    r += 1 + 3 * (startswith_sort.index(p))
                    break

            # Block offset integer
            non_decimal = re.compile(r'[^\d]+')
            pnum = non_decimal.sub("", x)
            if len(pnum) > 0:
                r += int(pnum)

            if x.count("3D"):
                r -= 3
            if x.count("2D"):
                r -= 0

            # Other Parameters
            for p in otherparms:
                if p.startswith(x):
                    r += (otherparms.index(p)) + 3 * len(startswith_sort)

            # Special offsets
            for p in special_off_start:
                if x.startswith(p):
                    r += 300

            if r == 0:
                r = 10000

            return r

        def compare(x, y):
            """
            rates x and y.
            returns -1, 0, 1 required for common list sort
            """
            rx = rate_tuple(x)
            ry = rate_tuple(y)

            return rx - ry

        return sorted(parms, cmp=compare)
Пример #10
0
    def GetListOfAllParameters(self,
                               e=None,
                               return_std_checked=False,
                               page=None):
        """ Returns sorted list of parameters.
            If return_std_checked is True, then a second list with
            standart checked parameters is returned.
        """
        if page is None:
            page = self.Page
        self.InfoClass.CurPage = page
        # Now that we know our Page, we may change the available
        # parameter options.
        Infodict = self.InfoClass.GetCurInfo()
        # We want to sort the information and have some prechecked
        # values in the statistics window afterwards.
        # new iteration
        keys = Infodict.keys()
        parms = list()
        errparms = list()

        for key in keys:
            for item in Infodict[key]:
                if item is not None:
                    if key == "fitting" and item[0].startswith("Err "):
                        errparms.append(item)
                    elif len(item) == 2:
                        parms.append(item)

        # Separate checkbox for fit errors
        if len(errparms) > 0:
            parms.append(("Fit errors", errparms))

        Info = Stat.SortParameters(parms)

        # List of default checked parameters:
        checked = np.zeros(len(Info), dtype=np.bool)
        # Fit parameters
        pbool = page.corr.fit_parameters_variable
        model = mdls.modeldict[page.corr.fit_model.id]
        pname = mdls.GetHumanReadableParms(model.id, model.parameters[1])[0]
        checkadd = np.array(pname)[pbool]
        for ii, p in enumerate(Info):
            if p[0] in checkadd:
                checked[ii] = True
        # A list with additional strings that should be default checked
        # if found somewhere in the data.
        checklist = [
            "cpp", "duration", "bg rate", "avg.", "Model name",
            "filename/title"
        ]
        for i in range(len(Info)):
            item = Info[i]
            for checkitem in checklist:
                if item[0].count(checkitem):
                    checked[i] = True
        # A list with strings that should not be checked:
        nochecklist = []
        for i in range(len(Info)):
            item = Info[i]
            for checkitem in nochecklist:
                if item[0].count(checkitem):
                    checked[i] = False

        if return_std_checked:
            return Info, checked
        else:
            return Info
Пример #11
0
    def GetPageInfo(self, Page):
        """ Needs a Page and gets all information from it """
        Page.PlotAll("init")
        # A dictionary with headings as keys and lists of singletts/tuples as
        # values. If it is a tuple, it might me interesting for a table.
        InfoDict = dict()
        # Get Correlation
        corr = Page.corr

        # Get model information
        model = corr.fit_model
        parms = corr.fit_parameters
        fct = corr.fit_model.function.__name__
        InfoDict["version"] = [Page.parent.version]
        Title = list()
        # The tool statistics relys on the string "filename/title".
        # Do not change it!
        if len(model[1]) == 0:
            # Prevent saving no title
            model[1] = "NoName"
        Title.append(["filename/title", Page.title])
        Title.append(["Model species", model.components])
        Title.append(["Model name", model.name])
        Title.append(["Model ID", str(model.id)])
        Title.append(["Model function", fct])
        Title.append(["Page number", Page.counter[1:-2]])
        ## Parameters
        Parameters = list()
        # Use this function to determine human readable parameters, if possible
        Units, Newparameters = mdls.GetHumanReadableParms(model.id, parms)
        # Add Parameters
        for i in np.arange(len(parms)):
            Parameters.append([Units[i], Newparameters[i]])
        InfoDict["parameters"] = Parameters
        # Add some more information if available
        # Info is a dictionary or None
        MoreInfo = mdls.GetMoreInfo(model.id, Page)
        if MoreInfo is not None:
            InfoDict["supplement"] = MoreInfo
            # Try to get the dictionary entry of a model
            try:
                # This function should return all important information
                # that can be calculated from the given parameters.
                func_info = mdls.supplement[model.id]
            except KeyError:
                # No information available
                pass
            else:
                InfoDict["modelsupdoc"] = [func_info.func_doc]
        ## Fitting

        if hasattr(corr, "fit_results"):
            Fitting = list()
            weightedfit = corr.fit_results["weighted fit"]
            if corr.correlation is not None:
                # Mode AC vs CC
                if corr.is_cc:
                    Title.append(["Type AC/CC", "Cross-correlation"])
                else:
                    Title.append(["Type AC/CC", "Autocorrelation"])
                if "chi2" in corr.fit_results:
                    Fitting.append([u"χ²", corr.fit_results["chi2"]])
                if weightedfit:
                    try:
                        Fitting.append([
                            "Weighted fit",
                            corr.fit_results["weighted fit type"]
                        ])
                    except KeyError:
                        Fitting.append(
                            ["Weighted fit", u"" + Page.Fitbox[1].GetValue()])
                if corr.fit_results.has_key("chi2 type"):
                    ChiSqType = corr.fit_results["chi2 type"]
                else:
                    ChiSqType = "unknown"
                Fitting.append([u"χ²-type", ChiSqType])
                Fitting.append(
                    ["Algorithm", fit.Algorithms[corr.fit_algorithm][1]])
                if len(Page.GlobalParameterShare) != 0:
                    shared = str(Page.GlobalParameterShare[0])
                    for item in Page.GlobalParameterShare[1:]:
                        shared += ", " + str(item)
                    Fitting.append(["Shared parameters with Pages", shared])
                if corr.fit_results.has_key("weighted fit bins"):
                    Fitting.append([
                        "Std. channels",
                        2 * corr.fit_results["weighted fit bins"] + 1
                    ])
                # Fitting range:
                t1 = 1. * corr.lag_time[corr.fit_ival[0]]
                t2 = 1. * corr.lag_time[corr.fit_ival[1] - 1]
                Fitting.append(["Ival start [ms]", "%.4e" % t1])
                Fitting.append(["Ival end [ms]", "%.4e" % t2])
                # Fittet parameters
                try:
                    fitparmsid = corr.fit_results["fit parameters"]
                except:
                    fitparmsid = corr.fit_parameters_variable
                fitparms = np.array(corr.fit_model.parameters[0])[fitparmsid]
                fitparms_short = [f.split()[0] for f in fitparms]
                fitparms_short = u", ".join(fitparms_short)
                Fitting.append(["Fit parm.", fitparms_short])
                # global fitting
                for key in corr.fit_results.keys():
                    if key.startswith("global"):
                        Fitting.append(
                            [key.capitalize(), corr.fit_results[key]])
                # Fit errors
                if corr.fit_results.has_key("fit error estimation"):
                    errors = corr.fit_results["fit error estimation"]
                    for err, par in zip(errors, fitparms):
                        nam, val = mdls.GetHumanReadableParameterDict(
                            model.id, [par], [err])
                        Fitting.append(["Err " + nam[0], val[0]])

                InfoDict["fitting"] = Fitting

        ## Normalization parameter id to name
        if corr.normparm is None:
            normparmtext = "None"
        elif corr.normparm < len(corr.fit_parameters):
            normparmtext = corr.fit_model.parameters[0][corr.normparm]
        else:
            # supplementary parameters
            supnum = corr.normparm - len(corr.fit_parameters)
            normparmtext = MoreInfo[supnum][0]
        Title.append(["Normalization", normparmtext])

        ## Background
        Background = list()
        if corr.is_cc:
            if len(corr.backgrounds) == 2:
                # Channel 1
                Background.append(["bg name Ch1", corr.backgrounds[0].name])
                Background.append(
                    ["bg rate Ch1 [kHz]", corr.backgrounds[0].countrate])
                # Channel 2
                Background.append(["bg name Ch2", corr.backgrounds[1].name])
                Background.append(
                    ["bg rate Ch2 [kHz]", corr.backgrounds[1].countrate])
                InfoDict["background"] = Background
        else:
            if len(corr.backgrounds) == 1:
                Background.append(["bg name", corr.backgrounds[0].name])
                Background.append(
                    ["bg rate [kHz]", corr.backgrounds[0].countrate])
                InfoDict["background"] = Background
        ## Function doc string
        InfoDict["modeldoc"] = [corr.fit_model.description_long]
        InfoDict["title"] = Title

        return InfoDict