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