Beispiel #1
0
    def build_display(self):
        panel = self.panel
        self.wids = {}

        self.plotone_op = Choice(panel,
                                 choices=list(PlotOne_Choices.keys()),
                                 action=self.onPlotOne,
                                 size=(200, -1))
        self.plotsel_op = Choice(panel,
                                 choices=list(PlotSel_Choices.keys()),
                                 action=self.onPlotSel,
                                 size=(200, -1))

        self.plotone_op.SetSelection(1)
        self.plotsel_op.SetSelection(1)

        plot_one = Button(panel,
                          'Plot Current Group',
                          size=(170, -1),
                          action=self.onPlotOne)

        plot_sel = Button(panel,
                          'Plot Selected Groups',
                          size=(170, -1),
                          action=self.onPlotSel)

        e0panel = wx.Panel(panel)
        self.wids['auto_e0'] = Check(e0panel,
                                     default=True,
                                     label='auto?',
                                     action=self.onSet_XASE0)
        self.wids['showe0'] = Check(e0panel,
                                    default=True,
                                    label='show?',
                                    action=self.onSet_XASE0)
        sx = wx.BoxSizer(wx.HORIZONTAL)
        sx.Add(self.wids['auto_e0'], 0, LEFT, 4)
        sx.Add(self.wids['showe0'], 0, LEFT, 4)
        pack(e0panel, sx)

        self.wids['auto_step'] = Check(panel,
                                       default=True,
                                       label='auto?',
                                       action=self.onNormMethod)

        self.wids['nvict'] = Choice(panel,
                                    choices=('0', '1', '2', '3'),
                                    size=(100, -1),
                                    action=self.onNormMethod,
                                    default=0)

        self.wids['nnorm'] = Choice(panel,
                                    choices=list(Nnorm_choices.values()),
                                    size=(100, -1),
                                    action=self.onNormMethod,
                                    default=0)

        opts = {
            'size': (100, -1),
            'digits': 2,
            'increment': 5.0,
            'action': self.onSet_Ranges
        }

        xas_pre1 = self.add_floatspin('pre1', value=defaults['pre1'], **opts)
        xas_pre2 = self.add_floatspin('pre2', value=defaults['pre2'], **opts)
        xas_norm1 = self.add_floatspin('norm1',
                                       value=defaults['norm1'],
                                       **opts)
        xas_norm2 = self.add_floatspin('norm2',
                                       value=defaults['norm2'],
                                       **opts)

        opts = {'digits': 3, 'increment': 0.1, 'value': 0}
        plot_voff = self.add_floatspin('plot_voff',
                                       with_pin=False,
                                       size=(80, -1),
                                       action=self.onVoffset,
                                       **opts)

        xas_e0 = self.add_floatspin('e0', action=self.onSet_XASE0Val, **opts)
        xas_step = self.add_floatspin('step',
                                      action=self.onSet_XASStep,
                                      with_pin=False,
                                      min_val=0.0,
                                      **opts)

        opts['value'] = 1.0
        scale = self.add_floatspin('scale', action=self.onSet_Scale, **opts)

        self.wids['norm_method'] = Choice(
            panel,
            choices=('polynomial', 'mback'),  # , 'area'),
            size=(120, -1),
            action=self.onNormMethod)
        self.wids['norm_method'].SetSelection(0)
        atsyms = ['?'] + self.larch.symtable._xray._xraydb.atomic_symbols
        edges = ('K', 'L3', 'L2', 'L1', 'M5')

        self.wids['atsym'] = Choice(panel, choices=atsyms, size=(75, -1))
        self.wids['edge'] = Choice(panel, choices=edges, size=(60, -1))

        self.wids['is_frozen'] = Check(panel,
                                       default=False,
                                       label='Freeze Group',
                                       action=self.onFreezeGroup)

        saveconf = Button(panel,
                          'Save as Default Settings',
                          size=(200, -1),
                          action=self.onSaveConfigBtn)

        use_auto = Button(panel,
                          'Use Default Settings',
                          size=(200, -1),
                          action=self.onAutoNorm)
        copy_auto = Button(panel,
                           'Copy',
                           size=(60, -1),
                           action=self.onCopyAuto)

        def CopyBtn(name):
            return Button(panel,
                          'Copy',
                          size=(60, -1),
                          action=partial(self.onCopyParam, name))

        add_text = self.add_text
        HLINEWID = 575
        panel.Add(SimpleText(panel,
                             'XAS Pre-edge subtraction and Normalization',
                             **self.titleopts),
                  dcol=4)
        panel.Add(SimpleText(panel, 'Copy to Selected Groups:'),
                  style=RIGHT,
                  dcol=2)

        panel.Add(plot_sel, newrow=True)
        panel.Add(self.plotsel_op, dcol=3)
        panel.Add(SimpleText(panel, 'Y Offset:'), style=RIGHT)
        panel.Add(plot_voff, style=RIGHT)

        panel.Add(plot_one, newrow=True)
        panel.Add(self.plotone_op, dcol=4)
        panel.Add(CopyBtn('plotone_op'), dcol=1, style=RIGHT)

        panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=6, newrow=True)
        add_text('Non-XAS Data Scale:')
        panel.Add(scale, dcol=2)

        panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=6, newrow=True)
        add_text('XAS Data:')
        panel.Add(use_auto, dcol=4)
        panel.Add(copy_auto, dcol=1, style=RIGHT)

        add_text('Element and Edge: ', newrow=True)
        panel.Add(self.wids['atsym'])
        panel.Add(self.wids['edge'], dcol=3)
        panel.Add(CopyBtn('atsym'), dcol=1, style=RIGHT)

        add_text('E0 : ')
        panel.Add(xas_e0)
        panel.Add(e0panel, dcol=3)
        panel.Add(CopyBtn('xas_e0'), dcol=1, style=RIGHT)

        add_text('Edge Step: ')
        panel.Add(xas_step)
        panel.Add(self.wids['auto_step'], dcol=3)
        panel.Add(CopyBtn('xas_step'), dcol=1, style=RIGHT)

        panel.Add((5, 5), newrow=True)
        panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=6, newrow=True)

        add_text('Pre-edge range: ')
        panel.Add(xas_pre1)
        add_text(' : ', newrow=False)
        panel.Add(xas_pre2, dcol=2)
        panel.Add(CopyBtn('xas_pre'), dcol=1, style=RIGHT)

        panel.Add(SimpleText(panel, 'Victoreen order:'), newrow=True)
        panel.Add(self.wids['nvict'], dcol=4)

        panel.Add((5, 5), newrow=True)
        panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=6, newrow=True)

        add_text('Normalization method: ')
        panel.Add(self.wids['norm_method'], dcol=4)
        panel.Add(CopyBtn('xas_norm'), dcol=1, style=RIGHT)

        add_text('Normalization range: ')
        panel.Add(xas_norm1)
        add_text(' : ', newrow=False)
        panel.Add(xas_norm2, dcol=2)
        panel.Add(SimpleText(panel, 'Polynomial Type:'), newrow=True)
        panel.Add(self.wids['nnorm'], dcol=4)

        panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=6, newrow=True)
        panel.Add((5, 5), newrow=True)
        panel.Add(self.wids['is_frozen'], newrow=True)
        panel.Add(saveconf, dcol=5)

        panel.Add((5, 5), newrow=True)
        panel.Add(HLine(panel, size=(HLINEWID, 3)), dcol=6, newrow=True)
        panel.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((5, 5), 0, LEFT, 3)
        sizer.Add(panel, 0, LEFT, 3)
        sizer.Add((5, 5), 0, LEFT, 3)

        pack(self, sizer)
Beispiel #2
0
    def build_display(self):
        self.mod_nb = flat_nb.FlatNotebook(self, -1, agwStyle=FNB_STYLE)
        self.mod_nb.SetTabAreaColour(wx.Colour(250,250,250))
        self.mod_nb.SetActiveTabColour(wx.Colour(254,254,195))

        self.mod_nb.SetNonActiveTabTextColour(wx.Colour(10,10,128))
        self.mod_nb.SetActiveTabTextColour(wx.Colour(128,0,0))
        self.mod_nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onNBChanged)

        pan = self.panel = GridPanel(self, ncols=4, nrows=4, pad=2, itemstyle=LCEN)

        self.wids = {}

        def FloatSpinWithPin(name, value, **kws):
            s = wx.BoxSizer(wx.HORIZONTAL)
            self.wids[name] = FloatSpin(pan, value=value, **kws)
            bb = BitmapButton(pan, get_icon('pin'), size=(25, 25),
                              action=partial(self.onSelPoint, opt=name),
                              tooltip='use last point selected from plot')
            s.Add(self.wids[name])
            s.Add(bb)
            return s

        opts = dict(digits=2, increment=0.1)
        ppeak_e0   = FloatSpinWithPin('ppeak_e0', value=0, **opts)
        ppeak_elo  = FloatSpinWithPin('ppeak_elo', value=-15, **opts)
        ppeak_ehi  = FloatSpinWithPin('ppeak_ehi', value=-5, **opts)
        ppeak_emin = FloatSpinWithPin('ppeak_emin', value=-30, **opts)
        ppeak_emax = FloatSpinWithPin('ppeak_emax', value=0, **opts)

        self.fitbline_btn  = Button(pan,'Fit Baseline', action=self.onFitBaseline,
                                    size=(150, 25))
        self.fitmodel_btn = Button(pan, 'Fit Model',
                                   action=self.onFitModel,  size=(150, 25))
        self.fitsel_btn = Button(pan, 'Fit Selected Groups',
                                 action=self.onFitSelected,  size=(150, 25))
        self.fitmodel_btn.Disable()
        self.fitsel_btn.Disable()

        self.array_choice = Choice(pan, size=(150, -1),
                                   choices=list(Array_Choices.keys()))
        self.array_choice.SetSelection(1)

        models_peaks = Choice(pan, size=(150, -1),
                              choices=ModelChoices['peaks'],
                              action=self.addModel)

        models_other = Choice(pan, size=(150, -1),
                              choices=ModelChoices['other'],
                              action=self.addModel)

        self.plot_choice = Choice(pan, size=(150, -1),
                                  choices=PlotChoices,
                                  action=self.onPlot)

        self.message = SimpleText(pan,
                                 'first fit baseline, then add peaks to fit model.')

        self.msg_centroid = SimpleText(pan, '----')

        opts = dict(default=True, size=(75, -1), action=self.onPlot)
        self.show_centroid  = Check(pan, label='show?', **opts)
        self.show_peakrange = Check(pan, label='show?', **opts)
        self.show_fitrange  = Check(pan, label='show?', **opts)
        self.show_e0        = Check(pan, label='show?', **opts)

        opts = dict(default=False, size=(200, -1), action=self.onPlot)
        self.plot_sub_bline = Check(pan, label='Subtract Baseline?', **opts)

        def add_text(text, dcol=1, newrow=True):
            pan.Add(SimpleText(pan, text), dcol=dcol, newrow=newrow)

        titleopts = dict(font=Font(12), colour='#AA0000')
        pan.Add(SimpleText(pan, ' Pre-edge Peak Fitting', **titleopts), dcol=5)
        add_text(' Run Fit:', newrow=False)

        add_text('Array to fit: ')
        pan.Add(self.array_choice, dcol=3)
        pan.Add((10, 10))
        pan.Add(self.fitbline_btn)

        add_text('E0: ')
        pan.Add(ppeak_e0)
        pan.Add((10, 10), dcol=2)
        pan.Add(self.show_e0)
        pan.Add(self.fitmodel_btn)


        add_text('Fit Energy Range: ')
        pan.Add(ppeak_emin)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_emax)
        pan.Add(self.show_fitrange)
        pan.Add(self.fitsel_btn)

        t = SimpleText(pan, 'Pre-edge Peak Range: ')
        t.SetToolTip('Range used as mask for background')

        pan.Add(t, newrow=True)
        pan.Add(ppeak_elo)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_ehi)
        pan.Add(self.show_peakrange)

        add_text( 'Peak Centroid: ')
        pan.Add(self.msg_centroid, dcol=3)
        pan.Add(self.show_centroid, dcol=1)


        #  plot buttons
        ts = wx.BoxSizer(wx.HORIZONTAL)
        ts.Add(self.plot_choice)
        ts.Add(self.plot_sub_bline)

        pan.Add(SimpleText(pan, 'Plot: '), newrow=True)
        pan.Add(ts, dcol=7)

        #  add model
        ts = wx.BoxSizer(wx.HORIZONTAL)
        ts.Add(models_peaks)
        ts.Add(models_other)

        pan.Add(SimpleText(pan, 'Add Component: '), newrow=True)
        pan.Add(ts, dcol=7)

        pan.Add(SimpleText(pan, 'Messages: '), newrow=True)
        pan.Add(self.message, dcol=7)

        pan.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((5,5), 0, LCEN, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LCEN, 3)
        sizer.Add(pan,   0, LCEN, 3)
        sizer.Add((5,5), 0, LCEN, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LCEN, 3)
        sizer.Add((5,5), 0, LCEN, 3)
        sizer.Add(self.mod_nb,  1, LCEN|wx.GROW, 10)

        pack(self, sizer)
Beispiel #3
0
    def addModel(self, event=None, model=None, prefix=None, isbkg=False):
        if model is None and event is not None:
            model = event.GetString()
        if model is None or model.startswith('<'):
            return

        if prefix is None:
            p = model[:5].lower()
            curmodels = ["%s%i_" % (p, i+1) for i in range(1+len(self.fit_components))]
            for comp in self.fit_components:
                if comp in curmodels:
                    curmodels.remove(comp)

            prefix = curmodels[0]

        label = "%s(prefix='%s')" % (model, prefix)
        title = "%s: %s " % (prefix[:-1], model)
        title = prefix[:-1]
        mclass_kws = {'prefix': prefix}
        if 'step' in model.lower():
            form = model.lower().replace('step', '').strip()

            if form.startswith('err'): form = 'erf'
            label = "Step(form='%s', prefix='%s')" % (form, prefix)
            title = "%s: Step %s" % (prefix[:-1], form[:3])
            mclass = lm_models.StepModel
            mclass_kws['form'] = form
            minst = mclass(form=form, prefix=prefix)
        else:
            if model in ModelFuncs:
                mclass = getattr(lm_models, ModelFuncs[model])
            else:
                mclass = getattr(lm_models, model+'Model')

            minst = mclass(prefix=prefix)

        panel = GridPanel(self.mod_nb, ncols=2, nrows=5, pad=2, itemstyle=CEN)

        def SLabel(label, size=(80, -1), **kws):
            return  SimpleText(panel, label,
                               size=size, style=wx.ALIGN_LEFT, **kws)
        usebox = Check(panel, default=True, label='Use in Fit?', size=(100, -1))
        bkgbox = Check(panel, default=False, label='Is Baseline?', size=(125, -1))
        if isbkg:
            bkgbox.SetValue(1)

        delbtn = Button(panel, 'Delete Component', size=(125, -1),
                        action=partial(self.onDeleteComponent, prefix=prefix))

        pick2msg = SimpleText(panel, "    ", size=(125, -1))
        pick2btn = Button(panel, 'Pick Values from Data', size=(150, -1),
                          action=partial(self.onPick2Points, prefix=prefix))

        # SetTip(mname,  'Label for the model component')
        SetTip(usebox,   'Use this component in fit?')
        SetTip(bkgbox,   'Label this component as "background" when plotting?')
        SetTip(delbtn,   'Delete this model component')
        SetTip(pick2btn, 'Select X range on Plot to Guess Initial Values')

        panel.Add(SLabel(label, size=(275, -1), colour='#0000AA'),
                  dcol=3,  style=wx.ALIGN_LEFT, newrow=True)
        panel.Add(usebox, dcol=1)
        panel.Add(bkgbox, dcol=2, style=LCEN)
        panel.Add(delbtn, dcol=1, style=wx.ALIGN_LEFT)

        panel.Add(pick2btn, dcol=2, style=wx.ALIGN_LEFT, newrow=True)
        panel.Add(pick2msg, dcol=2, style=wx.ALIGN_RIGHT)

        # panel.Add((10, 10), newrow=True)
        # panel.Add(HLine(panel, size=(150,  3)), dcol=4, style=wx.ALIGN_CENTER)

        panel.Add(SLabel("Parameter "), style=wx.ALIGN_LEFT,  newrow=True)
        panel.AddMany((SLabel(" Value"), SLabel(" Type"), SLabel(' Bounds'),
                       SLabel("  Min", size=(60, -1)),
                       SLabel("  Max", size=(60, -1)),  SLabel(" Expression")))

        parwids = OrderedDict()
        parnames = sorted(minst.param_names)

        for a in minst._func_allargs:
            pname = "%s%s" % (prefix, a)
            if (pname not in parnames and
                a in minst.param_hints and
                a not in minst.independent_vars):
                parnames.append(pname)

        for pname in parnames:
            sname = pname[len(prefix):]
            hints = minst.param_hints.get(sname, {})

            par = Parameter(name=pname, value=0, vary=True)
            if 'min' in hints:
                par.min = hints['min']
            if 'max' in hints:
                par.max = hints['max']
            if 'value' in hints:
                par.value = hints['value']
            if 'expr' in hints:
                par.expr = hints['expr']

            pwids = ParameterWidgets(panel, par, name_size=100, expr_size=125,
                                     float_size=80, prefix=prefix,
                                     widgets=('name', 'value',  'minval',
                                              'maxval', 'vary', 'expr'))
            parwids[par.name] = pwids
            panel.Add(pwids.name, newrow=True)

            panel.AddMany((pwids.value, pwids.vary, pwids.bounds,
                           pwids.minval, pwids.maxval, pwids.expr))

        for sname, hint in minst.param_hints.items():
            pname = "%s%s" % (prefix, sname)
            if 'expr' in hint and pname not in parnames:
                par = Parameter(name=pname, value=0, expr=hint['expr'])
                pwids = ParameterWidgets(panel, par, name_size=100, expr_size=225,
                                         float_size=80, prefix=prefix,
                                         widgets=('name', 'value', 'expr'))
                parwids[par.name] = pwids
                panel.Add(pwids.name, newrow=True)
                panel.Add(pwids.value)
                panel.Add(pwids.expr, dcol=4, style=wx.ALIGN_RIGHT)
                pwids.value.Disable()

        fgroup = Group(prefix=prefix, title=title, mclass=mclass,
                       mclass_kws=mclass_kws, usebox=usebox, panel=panel,
                       parwids=parwids, float_size=65, expr_size=150,
                       pick2_msg=pick2msg, bkgbox=bkgbox)


        self.fit_components[prefix] = fgroup
        panel.pack()

        self.mod_nb.AddPage(panel, title, True)
        sx,sy = self.GetSize()
        self.SetSize((sx, sy+1))
        self.SetSize((sx, sy))
Beispiel #4
0
    def build(self):
        sizer = wx.GridBagSizer(10, 5)
        sizer.SetVGap(5)
        sizer.SetHGap(5)

        panel = scrolled.ScrolledPanel(self)
        self.SetMinSize((600, 450))
        self.colors = GUIColors()

        # title row
        self.wids = wids = {}
        title = SimpleText(panel, 'Fit Results',  font=Font(12),
                           colour=self.colors.title, style=LCEN)

        wids['data_title'] = SimpleText(panel, '< > ',  font=Font(12),
                                             colour=self.colors.title, style=LCEN)

        wids['hist_info'] = SimpleText(panel, ' ___ ',  font=Font(12),
                                       colour=self.colors.title, style=LCEN)

        sizer.Add(title,              (0, 0), (1, 2), LCEN)
        sizer.Add(wids['data_title'], (0, 2), (1, 2), LCEN)
        sizer.Add(wids['hist_info'],  (0, 4), (1, 2), LCEN)

        irow = 1
        wids['model_desc'] = SimpleText(panel, '<Model>',  font=Font(12),
                                        size=(550, 75), style=LCEN)
        sizer.Add(wids['model_desc'],  (irow, 0), (1, 6), LCEN)

        irow += 1
        sizer.Add(HLine(panel, size=(400, 3)), (irow, 0), (1, 5), LCEN)

        irow += 1
        title = SimpleText(panel, '[[Fit Statistics]]',  font=Font(12),
                           colour=self.colors.title, style=LCEN)
        sizer.Add(title, (irow, 0), (1, 4), LCEN)

        for label, attr in (('Fit method', 'method'),
                            ('# Fit Evaluations', 'nfev'),
                            ('# Data Points', 'ndata'),
                            ('# Fit Variables', 'nvarys'),
                            ('# Free Points', 'nfree'),
                            ('Chi-square', 'chisqr'),
                            ('Reduced Chi-square', 'redchi'),
                            ('Akaike Info Criteria', 'aic'),
                            ('Bayesian Info Criteria', 'bic')):
            irow += 1
            wids[attr] = SimpleText(panel, '?')
            sizer.Add(SimpleText(panel, " %s = " % label),  (irow, 0), (1, 1), LCEN)
            sizer.Add(wids[attr],                           (irow, 1), (1, 1), LCEN)

        irow += 1
        sizer.Add(HLine(panel, size=(400, 3)), (irow, 0), (1, 5), LCEN)

        irow += 1
        title = SimpleText(panel, '[[Variables]]',  font=Font(12),
                           colour=self.colors.title, style=LCEN)
        sizer.Add(title, (irow, 0), (1, 1), LCEN)

        self.wids['copy_params'] = Button(panel, 'Update Model with Best Fit Values',
                                          size=(250, -1), action=self.onCopyParams)

        sizer.Add(self.wids['copy_params'], (irow, 1), (1, 3), LCEN)

        dvstyle = dv.DV_SINGLE|dv.DV_VERT_RULES|dv.DV_ROW_LINES
        pview = self.wids['params'] = dv.DataViewListCtrl(panel, style=dvstyle)
        self.wids['paramsdata'] = []
        pview.AppendTextColumn('Parameter',         width=150)
        pview.AppendTextColumn('Best-Fit Value',    width=100)
        pview.AppendTextColumn('Standard Error',    width=100)
        pview.AppendTextColumn('Info ',             width=275)

        for col in (0, 1, 2, 3):
            this = pview.Columns[col]
            isort, align = True, wx.ALIGN_LEFT
            if col in (1, 2):
                isort, align = False, wx.ALIGN_RIGHT
            this.Sortable = isort
            this.Alignment = this.Renderer.Alignment = align

        pview.SetMinSize((650, 200))
        pview.Bind(dv.EVT_DATAVIEW_SELECTION_CHANGED, self.onSelectParameter)

        irow += 1
        sizer.Add(pview, (irow, 0), (1, 5), LCEN)

        irow += 1
        sizer.Add(HLine(panel, size=(400, 3)), (irow, 0), (1, 5), LCEN)

        irow += 1
        title = SimpleText(panel, '[[Correlations]]',  font=Font(12),
                           colour=self.colors.title, style=LCEN)

        self.wids['all_correl'] = Button(panel, 'Show All',
                                          size=(100, -1), action=self.onAllCorrel)

        self.wids['min_correl'] = FloatSpin(panel, value=MIN_CORREL,
                                            min_val=0, size=(60, -1),
                                            digits=3, increment=0.1)

        ctitle = SimpleText(panel, 'minimum correlation: ')
        sizer.Add(title,  (irow, 0), (1, 1), LCEN)
        sizer.Add(ctitle, (irow, 1), (1, 1), LCEN)
        sizer.Add(self.wids['min_correl'], (irow, 2), (1, 1), LCEN)
        sizer.Add(self.wids['all_correl'], (irow, 3), (1, 1), LCEN)

        irow += 1

        cview = self.wids['correl'] = dv.DataViewListCtrl(panel, style=dvstyle)

        cview.AppendTextColumn('Parameter 1',    width=150)
        cview.AppendTextColumn('Parameter 2',    width=150)
        cview.AppendTextColumn('Correlation',    width=100)

        for col in (0, 1, 2):
            this = cview.Columns[col]
            isort, align = True, wx.ALIGN_LEFT
            if col == 1:
                isort = False
            if col == 2:
                align = wx.ALIGN_RIGHT
            this.Sortable = isort
            this.Alignment = this.Renderer.Alignment = align
        cview.SetMinSize((450, 200))

        irow += 1
        sizer.Add(cview, (irow, 0), (1, 5), LCEN)
        irow += 1
        sizer.Add(HLine(panel, size=(400, 3)), (irow, 0), (1, 5), LCEN)

        pack(panel, sizer)
        panel.SetupScrolling()

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 1, wx.GROW|wx.ALL, 1)

        pack(self, mainsizer)
        self.Show()
        self.Raise()
Beispiel #5
0
class PrePeakPanel(wx.Panel):
    def __init__(self, parent=None, controller=None, **kws):

        wx.Panel.__init__(self, parent, -1, size=(550, 625), **kws)
        self.parent = parent
        self.controller = controller
        self.larch = controller.larch
        self.fit_components = OrderedDict()
        self.fit_model = None
        self.fit_params = None
        self.user_added_params = None
        self.summary = None
        self.sizer = wx.GridBagSizer(10, 6)
        self.build_display()
        self.pick2_timer = wx.Timer(self)
        self.pick2_group = None
        self.Bind(wx.EVT_TIMER, self.onPick2Timer, self.pick2_timer)
        self.pick2_t0 = 0.
        self.pick2_timeout = 15.

        self.pick2erase_timer = wx.Timer(self)
        self.pick2erase_panel = None
        self.Bind(wx.EVT_TIMER, self.onPick2EraseTimer, self.pick2erase_timer)

    def onPanelExposed(self, **kws):
        # called when notebook is selected
        try:
            fname = self.controller.filelist.GetStringSelection()
            gname = self.controller.file_groups[fname]
            dgroup = self.controller.get_group(gname)
            # print(" Fill prepeak panel from group ", fname, gname, dgroup)
            self.fill_form(dgroup)
        except:
            pass # print(" Cannot Fill prepeak panel from group ")

    def larch_eval(self, cmd):
        """eval"""
        self.controller.larch.eval(cmd)

    def build_display(self):
        self.mod_nb = flat_nb.FlatNotebook(self, -1, agwStyle=FNB_STYLE)
        self.mod_nb.SetTabAreaColour(wx.Colour(250,250,250))
        self.mod_nb.SetActiveTabColour(wx.Colour(254,254,195))

        self.mod_nb.SetNonActiveTabTextColour(wx.Colour(10,10,128))
        self.mod_nb.SetActiveTabTextColour(wx.Colour(128,0,0))
        self.mod_nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onNBChanged)

        pan = self.panel = GridPanel(self, ncols=4, nrows=4, pad=2, itemstyle=LCEN)

        self.wids = {}

        def FloatSpinWithPin(name, value, **kws):
            s = wx.BoxSizer(wx.HORIZONTAL)
            self.wids[name] = FloatSpin(pan, value=value, **kws)
            bb = BitmapButton(pan, get_icon('pin'), size=(25, 25),
                              action=partial(self.onSelPoint, opt=name),
                              tooltip='use last point selected from plot')
            s.Add(self.wids[name])
            s.Add(bb)
            return s

        opts = dict(digits=2, increment=0.1)
        ppeak_e0   = FloatSpinWithPin('ppeak_e0', value=0, **opts)
        ppeak_elo  = FloatSpinWithPin('ppeak_elo', value=-15, **opts)
        ppeak_ehi  = FloatSpinWithPin('ppeak_ehi', value=-5, **opts)
        ppeak_emin = FloatSpinWithPin('ppeak_emin', value=-30, **opts)
        ppeak_emax = FloatSpinWithPin('ppeak_emax', value=0, **opts)

        self.fitbline_btn  = Button(pan,'Fit Baseline', action=self.onFitBaseline,
                                    size=(150, 25))
        self.fitmodel_btn = Button(pan, 'Fit Model',
                                   action=self.onFitModel,  size=(150, 25))
        self.fitsel_btn = Button(pan, 'Fit Selected Groups',
                                 action=self.onFitSelected,  size=(150, 25))
        self.fitmodel_btn.Disable()
        self.fitsel_btn.Disable()

        self.array_choice = Choice(pan, size=(150, -1),
                                   choices=list(Array_Choices.keys()))
        self.array_choice.SetSelection(1)

        models_peaks = Choice(pan, size=(150, -1),
                              choices=ModelChoices['peaks'],
                              action=self.addModel)

        models_other = Choice(pan, size=(150, -1),
                              choices=ModelChoices['other'],
                              action=self.addModel)

        self.plot_choice = Choice(pan, size=(150, -1),
                                  choices=PlotChoices,
                                  action=self.onPlot)

        self.message = SimpleText(pan,
                                 'first fit baseline, then add peaks to fit model.')

        self.msg_centroid = SimpleText(pan, '----')

        opts = dict(default=True, size=(75, -1), action=self.onPlot)
        self.show_centroid  = Check(pan, label='show?', **opts)
        self.show_peakrange = Check(pan, label='show?', **opts)
        self.show_fitrange  = Check(pan, label='show?', **opts)
        self.show_e0        = Check(pan, label='show?', **opts)

        opts = dict(default=False, size=(200, -1), action=self.onPlot)
        self.plot_sub_bline = Check(pan, label='Subtract Baseline?', **opts)

        def add_text(text, dcol=1, newrow=True):
            pan.Add(SimpleText(pan, text), dcol=dcol, newrow=newrow)

        titleopts = dict(font=Font(12), colour='#AA0000')
        pan.Add(SimpleText(pan, ' Pre-edge Peak Fitting', **titleopts), dcol=5)
        add_text(' Run Fit:', newrow=False)

        add_text('Array to fit: ')
        pan.Add(self.array_choice, dcol=3)
        pan.Add((10, 10))
        pan.Add(self.fitbline_btn)

        add_text('E0: ')
        pan.Add(ppeak_e0)
        pan.Add((10, 10), dcol=2)
        pan.Add(self.show_e0)
        pan.Add(self.fitmodel_btn)


        add_text('Fit Energy Range: ')
        pan.Add(ppeak_emin)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_emax)
        pan.Add(self.show_fitrange)
        pan.Add(self.fitsel_btn)

        t = SimpleText(pan, 'Pre-edge Peak Range: ')
        t.SetToolTip('Range used as mask for background')

        pan.Add(t, newrow=True)
        pan.Add(ppeak_elo)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_ehi)
        pan.Add(self.show_peakrange)

        add_text( 'Peak Centroid: ')
        pan.Add(self.msg_centroid, dcol=3)
        pan.Add(self.show_centroid, dcol=1)


        #  plot buttons
        ts = wx.BoxSizer(wx.HORIZONTAL)
        ts.Add(self.plot_choice)
        ts.Add(self.plot_sub_bline)

        pan.Add(SimpleText(pan, 'Plot: '), newrow=True)
        pan.Add(ts, dcol=7)

        #  add model
        ts = wx.BoxSizer(wx.HORIZONTAL)
        ts.Add(models_peaks)
        ts.Add(models_other)

        pan.Add(SimpleText(pan, 'Add Component: '), newrow=True)
        pan.Add(ts, dcol=7)

        pan.Add(SimpleText(pan, 'Messages: '), newrow=True)
        pan.Add(self.message, dcol=7)

        pan.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((5,5), 0, LCEN, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LCEN, 3)
        sizer.Add(pan,   0, LCEN, 3)
        sizer.Add((5,5), 0, LCEN, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LCEN, 3)
        sizer.Add((5,5), 0, LCEN, 3)
        sizer.Add(self.mod_nb,  1, LCEN|wx.GROW, 10)

        pack(self, sizer)

    def get_config(self, dgroup=None):
        """get processing configuration for a group"""
        if dgroup is None:
            dgroup = self.controller.get_group()

        conf = getattr(dgroup, 'prepeak_config', {})
        if 'e0' not in conf:
            conf = dict(e0 = dgroup.e0, elo=-10, ehi=-5,
                        emin=-40, emax=0, yarray='norm')

        dgroup.prepeak_config = conf
        if not hasattr(dgroup, 'prepeaks'):
            dgroup.prepeaks = Group()

        return conf

    def fill_form(self, dat):
        if isinstance(dat, Group):
            self.wids['ppeak_e0'].SetValue(dat.e0)
            if hasattr(dat, 'prepeaks'):
                self.wids['ppeak_emin'].SetValue(dat.prepeaks.emin)
                self.wids['ppeak_emax'].SetValue(dat.prepeaks.emax)
                self.wids['ppeak_elo'].SetValue(dat.prepeaks.elo)
                self.wids['ppeak_ehi'].SetValue(dat.prepeaks.ehi)

        elif instance(dat, dict):
            self.wids['ppeak_e0'].SetValue(dat['e0'])
            self.wids['ppeak_emin'].SetValue(dat['emin'])
            self.wids['ppeak_emax'].SetValue(dat['emax'])
            self.wids['ppeak_elo'].SetValue(dat['elo'])
            self.wids['ppeak_ehi'].SetValue(dat['ehi'])

            self.array_choice.SetStringSelection(dat['array_desc'])
            self.show_e0.Enable(dat['show_e0'])
            self.show_centroid.Enable(dat['show_centroid'])
            self.show_fitrange.Enable(dat['show_fitrange'])
            self.show_peakrange.Enable(dat['show_peakrange'])
            self.plot_sub_bline.Enable(dat['plot_sub_bline'])

    def read_form(self):
        "read for, returning dict of values"
        dgroup = self.controller.get_group()
        array_desc = self.array_choice.GetStringSelection()
        form_opts = {'gname': dgroup.groupname,
                     'array_desc': array_desc.lower(),
                     'array_name': Array_Choices[array_desc],
                     'baseline_form': 'lorentzian'}

        form_opts['e0'] = self.wids['ppeak_e0'].GetValue()
        form_opts['emin'] = self.wids['ppeak_emin'].GetValue()
        form_opts['emax'] = self.wids['ppeak_emax'].GetValue()
        form_opts['elo'] = self.wids['ppeak_elo'].GetValue()
        form_opts['ehi'] = self.wids['ppeak_ehi'].GetValue()
        form_opts['plot_sub_bline'] = self.plot_sub_bline.IsChecked()
        form_opts['show_centroid'] = self.show_centroid.IsChecked()
        form_opts['show_peakrange'] = self.show_peakrange.IsChecked()
        form_opts['show_fitrange'] = self.show_fitrange.IsChecked()
        form_opts['show_e0'] = self.show_e0.IsChecked()
        return form_opts


    def onFitBaseline(self, evt=None):
        opts = self.read_form()

        cmd = """{gname:s}.ydat = 1.0*{gname:s}.{array_name:s}
pre_edge_baseline(energy={gname:s}.energy, norm={gname:s}.ydat, group={gname:s},
form='{baseline_form:s}', with_line=True,
elo={elo:.3f}, ehi={ehi:.3f}, emin={emin:.3f}, emax={emax:.3f})
"""
        self.larch_eval(cmd.format(**opts))

        dgroup = self.controller.get_group()
        ppeaks = dgroup.prepeaks
        dgroup.centroid_msg = "%.4f +/- %.4f eV" % (ppeaks.centroid,
                                                    ppeaks.delta_centroid)

        self.msg_centroid.SetLabel(dgroup.centroid_msg)

        if 'loren_' not in self.fit_components:
            self.addModel(model='Lorentzian', prefix='loren_', isbkg=True)
        if 'line_' not in self.fit_components:
            self.addModel(model='Linear', prefix='line_', isbkg=True)

        for prefix in ('loren_', 'line_'):
            cmp = self.fit_components[prefix]
            # cmp.bkgbox.SetValue(1)
            self.fill_model_params(prefix, dgroup.prepeaks.fit_details.params)

        self.fill_form(dgroup)
        self.fitmodel_btn.Enable()
        # self.fitallmodel_btn.Enable()

        i1, i2 = self.get_xranges(dgroup.energy)
        dgroup.yfit = dgroup.xfit = 0.0*dgroup.energy[i1:i2]

        self.plot_choice.SetStringSelection(PLOT_BASELINE)
        self.onPlot()

    def fill_model_params(self, prefix, params):
        comp = self.fit_components[prefix]
        parwids = comp.parwids
        for pname, par in params.items():
            pname = prefix + pname
            if pname in parwids:
                wids = parwids[pname]
                if wids.minval is not None:
                    wids.minval.SetValue(par.min)
                if wids.maxval is not None:
                    wids.maxval.SetValue(par.max)
                wids.value.SetValue(par.value)
                varstr = 'vary' if par.vary else 'fix'
                if par.expr is not None:
                    varstr = 'constrain'
                if wids.vary is not None:
                    wids.vary.SetStringSelection(varstr)

    def onPlot(self, evt=None):
        plot_choice = self.plot_choice.GetStringSelection()

        opts = self.read_form()
        dgroup = self.controller.get_group()

        ppeaks = getattr(dgroup, 'prepeaks', None)
        if ppeaks is None:
            return

        i1, i2 = self.get_xranges(dgroup.xdat)
        # i2 = len(ppeaks.baseline) + i1

        if len(dgroup.yfit) > len(ppeaks.baseline):
            i2 = i1 + len(ppeaks.baseline)
        # print(" Indexes: ", i1, i2, i2-i1, len(dgroup.yfit), len(ppeaks.baseline))

        xdat = 1.0*dgroup.energy
        ydat = 1.0*dgroup.ydat
        yfit = 1.0*dgroup.ydat
        baseline = 1.0*dgroup.ydat
        yfit[i1:i2] = dgroup.yfit[:i2-i1]
        baseline[i1:i2] = ppeaks.baseline[:i2-i1]


        if opts['plot_sub_bline']:
            ydat = ydat - baseline
            if plot_choice in (PLOT_FIT, PLOT_RESID):
                yfit = yfit - baseline
        if plot_choice == PLOT_RESID:
            resid = ydat - yfit

        _xs = dgroup.energy[i1:i2]
        xrange = max(_xs) - min(_xs)
        pxmin = min(_xs) - 0.05 * xrange
        pxmax = max(_xs) + 0.05 * xrange

        jmin = index_of(dgroup.energy, pxmin)
        jmax = index_of(dgroup.energy, pxmax) + 1

        _ys = ydat[jmin:jmax]
        yrange = max(_ys) - min(_ys)
        pymin = min(_ys) - 0.05 * yrange
        pymax = max(_ys) + 0.05 * yrange

        title = ' pre-edge fit'
        if plot_choice == PLOT_BASELINE:
            title = ' pre-edge baseline'
            if opts['plot_sub_bline']:
                title = ' pre-edge peaks'

        array_desc = self.array_choice.GetStringSelection()

        plotopts = {'xmin': pxmin, 'xmax': pxmax,
                    'ymin': pymin, 'ymax': pymax,
                    'title': '%s: %s' % (opts['gname'], title),
                    'xlabel': 'Energy (eV)',
                    'ylabel': '%s $\mu$' % opts['array_desc'],
                    'label': '%s $\mu$' % opts['array_desc'],
                    'delay_draw': True,
                    'show_legend': True}

        plot_extras = []
        if opts['show_fitrange']:
            popts = {'color': '#DDDDCC'}
            emin = opts['emin']
            emax = opts['emax']
            imin = index_of(dgroup.energy, emin)
            imax = index_of(dgroup.energy, emax)

            plot_extras.append(('vline', emin, None, popts))
            plot_extras.append(('vline', emax, None, popts))

        if opts['show_peakrange']:
            popts = {'marker': '+', 'markersize': 6}
            elo = opts['elo']
            ehi = opts['ehi']
            ilo = index_of(dgroup.xdat, elo)
            ihi = index_of(dgroup.xdat, ehi)

            plot_extras.append(('marker', elo, ydat[ilo], popts))
            plot_extras.append(('marker', ehi, ydat[ihi], popts))

        if opts['show_centroid']:
            popts = {'color': '#EECCCC'}
            ecen = getattr(dgroup.prepeaks, 'centroid', -1)
            if ecen > min(dgroup.energy):
                plot_extras.append(('vline', ecen, None,  popts))


        pframe = self.controller.get_display(win=2,
                                             stacked=(plot_choice==PLOT_RESID))
        ppanel = pframe.panel
        axes = ppanel.axes

        plotopts.update(PLOTOPTS_1)

        ppanel.plot(xdat, ydat, **plotopts)
        if plot_choice == PLOT_BASELINE:
            if not opts['plot_sub_bline']:
                ppanel.oplot(dgroup.prepeaks.energy,
                             dgroup.prepeaks.baseline,
                             label='baseline', **PLOTOPTS_2)

        elif plot_choice in (PLOT_FIT, PLOT_RESID):
            ppanel.oplot(dgroup.energy, yfit,
                         label='fit', **PLOTOPTS_1)

            if hasattr(dgroup, 'ycomps'):
                ncomp = len(dgroup.ycomps)
                icomp = 0
                for label, ycomp in dgroup.ycomps.items():
                    icomp +=1
                    fcomp = self.fit_components[label]
                    # print("ycomp: ", plot_choice, label, len(ycomp), len(dgroup.xfit),
                    #       fcomp.bkgbox.IsChecked(), opts['plot_sub_bline'], icomp, ncomp)
                    if not (fcomp.bkgbox.IsChecked() and opts['plot_sub_bline']):
                        ppanel.oplot(dgroup.xfit, ycomp, label=label,
                                     delay_draw=(icomp!=ncomp), style='short dashed')

            if plot_choice == PLOT_RESID:
                _ys = resid
                yrange = max(_ys) - min(_ys)
                plotopts['ymin'] = min(_ys) - 0.05 * yrange
                plotopts['ymax'] = max(_ys) + 0.05 * yrange
                plotopts['delay_draw'] = False
                plotopts['ylabel'] = 'data-fit'
                plotopts['label'] = '_nolegend_'

                pframe.plot(dgroup.energy, resid, panel='bot', **plotopts)
                pframe.Show()
                # print(" RESIDUAL PLOT  margins: ")
                # print(" top : ", pframe.panel.conf.margins)
                # print(" bot : ", pframe.panel_bot.conf.margins)


        for etype, x, y, opts in plot_extras:
            if etype == 'marker':
                popts = {'marker': 'o', 'markersize': 4,
                         'label': '_nolegend_',
                         'markerfacecolor': 'red',
                         'markeredgecolor': '#884444'}
                popts.update(opts)
                axes.plot([x], [y], **popts)
            elif etype == 'vline':
                popts = {'ymin': 0, 'ymax': 1.0, 'color': '#888888',
                         'label': '_nolegend_'}
                popts.update(opts)
                axes.axvline(x, **popts)
        ppanel.canvas.draw()

    def onNBChanged(self, event=None):
        idx = self.mod_nb.GetSelection()

    def addModel(self, event=None, model=None, prefix=None, isbkg=False):
        if model is None and event is not None:
            model = event.GetString()
        if model is None or model.startswith('<'):
            return

        if prefix is None:
            p = model[:5].lower()
            curmodels = ["%s%i_" % (p, i+1) for i in range(1+len(self.fit_components))]
            for comp in self.fit_components:
                if comp in curmodels:
                    curmodels.remove(comp)

            prefix = curmodels[0]

        label = "%s(prefix='%s')" % (model, prefix)
        title = "%s: %s " % (prefix[:-1], model)
        title = prefix[:-1]
        mclass_kws = {'prefix': prefix}
        if 'step' in model.lower():
            form = model.lower().replace('step', '').strip()

            if form.startswith('err'): form = 'erf'
            label = "Step(form='%s', prefix='%s')" % (form, prefix)
            title = "%s: Step %s" % (prefix[:-1], form[:3])
            mclass = lm_models.StepModel
            mclass_kws['form'] = form
            minst = mclass(form=form, prefix=prefix)
        else:
            if model in ModelFuncs:
                mclass = getattr(lm_models, ModelFuncs[model])
            else:
                mclass = getattr(lm_models, model+'Model')

            minst = mclass(prefix=prefix)

        panel = GridPanel(self.mod_nb, ncols=2, nrows=5, pad=2, itemstyle=CEN)

        def SLabel(label, size=(80, -1), **kws):
            return  SimpleText(panel, label,
                               size=size, style=wx.ALIGN_LEFT, **kws)
        usebox = Check(panel, default=True, label='Use in Fit?', size=(100, -1))
        bkgbox = Check(panel, default=False, label='Is Baseline?', size=(125, -1))
        if isbkg:
            bkgbox.SetValue(1)

        delbtn = Button(panel, 'Delete Component', size=(125, -1),
                        action=partial(self.onDeleteComponent, prefix=prefix))

        pick2msg = SimpleText(panel, "    ", size=(125, -1))
        pick2btn = Button(panel, 'Pick Values from Data', size=(150, -1),
                          action=partial(self.onPick2Points, prefix=prefix))

        # SetTip(mname,  'Label for the model component')
        SetTip(usebox,   'Use this component in fit?')
        SetTip(bkgbox,   'Label this component as "background" when plotting?')
        SetTip(delbtn,   'Delete this model component')
        SetTip(pick2btn, 'Select X range on Plot to Guess Initial Values')

        panel.Add(SLabel(label, size=(275, -1), colour='#0000AA'),
                  dcol=3,  style=wx.ALIGN_LEFT, newrow=True)
        panel.Add(usebox, dcol=1)
        panel.Add(bkgbox, dcol=2, style=LCEN)
        panel.Add(delbtn, dcol=1, style=wx.ALIGN_LEFT)

        panel.Add(pick2btn, dcol=2, style=wx.ALIGN_LEFT, newrow=True)
        panel.Add(pick2msg, dcol=2, style=wx.ALIGN_RIGHT)

        # panel.Add((10, 10), newrow=True)
        # panel.Add(HLine(panel, size=(150,  3)), dcol=4, style=wx.ALIGN_CENTER)

        panel.Add(SLabel("Parameter "), style=wx.ALIGN_LEFT,  newrow=True)
        panel.AddMany((SLabel(" Value"), SLabel(" Type"), SLabel(' Bounds'),
                       SLabel("  Min", size=(60, -1)),
                       SLabel("  Max", size=(60, -1)),  SLabel(" Expression")))

        parwids = OrderedDict()
        parnames = sorted(minst.param_names)

        for a in minst._func_allargs:
            pname = "%s%s" % (prefix, a)
            if (pname not in parnames and
                a in minst.param_hints and
                a not in minst.independent_vars):
                parnames.append(pname)

        for pname in parnames:
            sname = pname[len(prefix):]
            hints = minst.param_hints.get(sname, {})

            par = Parameter(name=pname, value=0, vary=True)
            if 'min' in hints:
                par.min = hints['min']
            if 'max' in hints:
                par.max = hints['max']
            if 'value' in hints:
                par.value = hints['value']
            if 'expr' in hints:
                par.expr = hints['expr']

            pwids = ParameterWidgets(panel, par, name_size=100, expr_size=125,
                                     float_size=80, prefix=prefix,
                                     widgets=('name', 'value',  'minval',
                                              'maxval', 'vary', 'expr'))
            parwids[par.name] = pwids
            panel.Add(pwids.name, newrow=True)

            panel.AddMany((pwids.value, pwids.vary, pwids.bounds,
                           pwids.minval, pwids.maxval, pwids.expr))

        for sname, hint in minst.param_hints.items():
            pname = "%s%s" % (prefix, sname)
            if 'expr' in hint and pname not in parnames:
                par = Parameter(name=pname, value=0, expr=hint['expr'])
                pwids = ParameterWidgets(panel, par, name_size=100, expr_size=225,
                                         float_size=80, prefix=prefix,
                                         widgets=('name', 'value', 'expr'))
                parwids[par.name] = pwids
                panel.Add(pwids.name, newrow=True)
                panel.Add(pwids.value)
                panel.Add(pwids.expr, dcol=4, style=wx.ALIGN_RIGHT)
                pwids.value.Disable()

        fgroup = Group(prefix=prefix, title=title, mclass=mclass,
                       mclass_kws=mclass_kws, usebox=usebox, panel=panel,
                       parwids=parwids, float_size=65, expr_size=150,
                       pick2_msg=pick2msg, bkgbox=bkgbox)


        self.fit_components[prefix] = fgroup
        panel.pack()

        self.mod_nb.AddPage(panel, title, True)
        sx,sy = self.GetSize()
        self.SetSize((sx, sy+1))
        self.SetSize((sx, sy))

    def onDeleteComponent(self, evt=None, prefix=None):
        fgroup = self.fit_components.get(prefix, None)
        if fgroup is None:
            return

        for i in range(self.mod_nb.GetPageCount()):
            if fgroup.title == self.mod_nb.GetPageText(i):
                self.mod_nb.DeletePage(i)

        for attr in dir(fgroup):
            setattr(fgroup, attr, None)

        self.fit_components.pop(prefix)

        # sx,sy = self.GetSize()
        # self.SetSize((sx, sy+1))
        # self.SetSize((sx, sy))

    def onPick2EraseTimer(self, evt=None):
        """erases line trace showing automated 'Pick 2' guess """
        self.pick2erase_timer.Stop()
        panel = self.pick2erase_panel
        ntrace = panel.conf.ntrace - 1
        trace = panel.conf.get_mpl_line(ntrace)
        panel.conf.get_mpl_line(ntrace).set_data(np.array([]), np.array([]))
        panel.conf.ntrace = ntrace
        panel.draw()

    def onPick2Timer(self, evt=None):
        """checks for 'Pick 2' events, and initiates 'Pick 2' guess
        for a model from the selected data range
        """
        try:
            plotframe = self.controller.get_display()
            curhist = plotframe.cursor_hist[:]
            plotframe.Raise()
        except:
            return

        if (time.time() - self.pick2_t0) > self.pick2_timeout:
            msg = self.pick2_group.pick2_msg.SetLabel(" ")
            plotframe.cursor_hist = []
            self.pick2_timer.Stop()
            return

        if len(curhist) < 2:
            self.pick2_group.pick2_msg.SetLabel("%i/2" % (len(curhist)))
            return

        self.pick2_group.pick2_msg.SetLabel("done.")
        self.pick2_timer.Stop()

        # guess param values
        xcur = (curhist[0][0], curhist[1][0])
        xmin, xmax = min(xcur), max(xcur)

        dgroup = getattr(self.larch.symtable, self.controller.groupname)
        x, y = dgroup.xdat, dgroup.ydat
        i0 = index_of(dgroup.xdat, xmin)
        i1 = index_of(dgroup.xdat, xmax)
        x, y = dgroup.xdat[i0:i1+1], dgroup.ydat[i0:i1+1]

        mod = self.pick2_group.mclass(prefix=self.pick2_group.prefix)
        parwids = self.pick2_group.parwids
        try:
            guesses = mod.guess(y, x=x)
        except:
            return

        for name, param in guesses.items():
            if name in parwids:
                parwids[name].value.SetValue(param.value)

        dgroup._tmp = mod.eval(guesses, x=dgroup.xdat)
        plotframe = self.controller.get_display()
        plotframe.cursor_hist = []
        plotframe.oplot(dgroup.xdat, dgroup._tmp)
        self.pick2erase_panel = plotframe.panel

        self.pick2erase_timer.Start(5000)


    def onPick2Points(self, evt=None, prefix=None):
        fgroup = self.fit_components.get(prefix, None)
        if fgroup is None:
            return

        plotframe = self.controller.get_display()
        plotframe.Raise()

        plotframe.cursor_hist = []
        fgroup.npts = 0
        self.pick2_group = fgroup

        if fgroup.pick2_msg is not None:
            fgroup.pick2_msg.SetLabel("0/2")

        self.pick2_t0 = time.time()
        self.pick2_timer.Start(250)


    def onSaveFitResult(self, event=None):
        dgroup = self.controller.get_group()
        deffile = dgroup.filename.replace('.', '_') + '.modl'

        outfile = FileSave(self, 'Save Fit Result',
                           default_file=deffile,
                           wildcard=ModelWcards)

        if outfile is not None:
            try:
                self.save_fit_result(dgroup.fit_history[-1], outfile)
            except IOError:
                print('could not write %s' % outfile)

    def onLoadFitResult(self, event=None):
        mfile = FileOpen(self, 'Load Fit Result',
                         default_file='', wildcard=ModelWcards)
        if mfile is not None:
            self.load_modelresult(mfile)

    def save_fit_result(self, fitresult, outfile):
        """saves a customized ModelResult"""
        save_modelresult(fitresult, outfile)

    def load_modelresult(self, inpfile):
        """read a customized ModelResult"""
        result = load_modelresult(inpfile)

        for prefix in list(self.fit_components.keys()):
            self.onDeleteComponent(self, prefix=prefix)

        for comp in result.model.components:
            isbkg = comp.prefix in result.user_options['bkg_components']
            self.addModel(model=comp.func.__name__,
                          prefix=comp.prefix, isbkg=isbkg)

        for comp in result.model.components:
            parwids = self.fit_components[comp.prefix].parwids
            for pname, par in result.params.items():
                if pname in parwids:
                    wids = parwids[pname]
                    if wids.minval is not None:
                        wids.minval.SetValue(par.min)
                    if wids.maxval is not None:
                        wids.maxval.SetValue(par.max)
                    val = result.init_values.get(pname, par.value)
                    wids.value.SetValue(val)

        self.fill_form(result.user_options)
        return result

    def onExportFitResult(self, event=None):
        dgroup = self.controller.get_group()
        deffile = dgroup.filename.replace('.', '_') + '_result.xdi'
        wcards = 'All files (*.*)|*.*'

        outfile = FileSave(self, 'Export Fit Result',
                           default_file=deffile, wildcard=wcards)

        if outfile is not None:
            i1, i2 = self.get_xranges(dgroup.xdat)
            x = dgroup.xdat[i1:i2]
            y = dgroup.ydat[i1:i2]
            yerr = None
            if hasattr(dgroup, 'yerr'):
                yerr = 1.0*dgroup.yerr
                if not isinstance(yerr, np.ndarray):
                    yerr = yerr * np.ones(len(y))
                else:
                    yerr = yerr[i1:i2]

            export_modelresult(dgroup.fit_history[-1],
                               filename=outfile,
                               datafile=dgroup.filename,
                               ydata=y, yerr=yerr, x=x)


    def onSelPoint(self, evt=None, opt='__', relative_e0=False, win=None):
        """
        get last selected point from a specified plot window
        and fill in the value for the widget defined by `opt`.

        by default it finds the latest cursor position from the
        cursor history of the first 20 plot windows.
        """
        if opt not in self.wids:
            return None

        _x, _y = last_cursor_pos(win=win, _larch=self.larch)

        if _x is not None:
            if relative_e0 and 'e0' in self.wids:
                _x -= self.wids['e0'].GetValue()
            self.wids[opt].SetValue(_x)

    def get_xranges(self, x):
        opts = self.read_form()
        dgroup = self.controller.get_group()
        en_eps = min(np.diff(dgroup.energy)) / 5.

        i1 = index_of(x, opts['emin'] + en_eps)
        i2 = index_of(x, opts['emax'] + en_eps) + 1
        return i1, i2

    def build_fitmodel(self):
        """ use fit components to build model"""
        dgroup = self.controller.get_group()
        fullmodel = None
        params = Parameters()
        self.summary = {'components': [], 'options': {}}
        peaks = []
        for comp in self.fit_components.values():
            _cen, _amp = None, None
            if comp.usebox is not None and comp.usebox.IsChecked():
                for parwids in comp.parwids.values():
                    params.add(parwids.param)
                    #print(" add param ", parwids.param)
                    if parwids.param.name.endswith('_center'):
                        _cen = parwids.param.name
                    elif parwids.param.name.endswith('_amplitude'):
                        _amp = parwids.param.name

                self.summary['components'].append((comp.mclass.__name__, comp.mclass_kws))
                thismodel = comp.mclass(**comp.mclass_kws)
                if fullmodel is None:
                   fullmodel = thismodel
                else:
                    fullmodel += thismodel
                if not comp.bkgbox.IsChecked() and _cen is not None and _amp is not None:
                    peaks.append((_amp, _cen))

        if len(peaks) > 0:
            denom = '+'.join([p[0] for p in peaks])
            numer = '+'.join(["%s*%s "% p for p in peaks])
            params.add('fit_centroid', expr="(%s)/(%s)" %(numer, denom))

        self.fit_model = fullmodel
        self.fit_params = params

        if dgroup is not None:
            i1, i2 = self.get_xranges(dgroup.xdat)
            xsel = dgroup.xdat[i1:i2]
            dgroup.xfit = xsel
            dgroup.yfit = self.fit_model.eval(self.fit_params, x=xsel)
            dgroup.ycomps = self.fit_model.eval_components(params=self.fit_params,
                                                           x=xsel)
        return dgroup

    def onFitSelected(self, event=None):
        dgroup = self.build_fitmodel()
        opts = self.read_form()
        print("fitting selected groups in progress")

    def onFitModel(self, event=None):
        dgroup = self.build_fitmodel()
        opts = self.read_form()

        i1, i2 = self.get_xranges(dgroup.xdat)
        dgroup.xfit = dgroup.xdat[i1:i2]
        ysel = dgroup.ydat[i1:i2]
        # print('onFit Model : xrange ', i1, i2, len(dgroup.xfit), len(dgroup.yfit))
        weights = np.ones(len(ysel))

        if hasattr(dgroup, 'yerr'):
            yerr = 1.0*dgroup.yerr
            if not isinstance(yerr, np.ndarray):
                yerr = yerr * np.ones(len(ysel))
            else:
                yerr = yerr[i1:i2]
            yerr_min = 1.e-9*ysel.mean()
            yerr[np.where(yerr < yerr_min)] = yerr_min
            weights = 1.0/yerr

        result = self.fit_model.fit(ysel, params=self.fit_params,
                                    x=dgroup.xfit, weights=weights,
                                    method='leastsq')
        self.summary['xmin'] = dgroup.xdat[i1]
        self.summary['xmax'] = dgroup.xdat[i2]
        for attr in ('aic', 'bic', 'chisqr', 'redchi', 'ci_out', 'covar',
                     'flatchain', 'success', 'nan_policy', 'nfev', 'ndata',
                     'nfree', 'nvarys', 'init_values'):
            self.summary[attr] = getattr(result, attr)
        self.summary['params'] = result.params

        dgroup.yfit = result.best_fit
        dgroup.ycomps = self.fit_model.eval_components(params=result.params,
                                                       x=dgroup.xfit)

        result.model_repr = self.fit_model._reprstring(long=True)

        ## hacks to save user options
        result.user_options = opts
        bkg_comps = []
        for label, comp in self.fit_components.items():
            if comp.bkgbox.IsChecked():
                bkg_comps.append(label)
        result.user_options['bkg_components'] = bkg_comps

        self.autosave_modelresult(result)
        if not hasattr(dgroup, 'fit_history'):
            dgroup.fit_history = []

        dgroup.fit_history.append(result)
        self.plot_choice.SetStringSelection(PLOT_FIT)
        self.onPlot()

        self.parent.show_subframe('prepeak_result_frame', FitResultFrame,
                                  datagroup=dgroup, peakframe=self)

        self.parent.subframes['prepeak_result_frame'].show_fitresult()
        [m.Enable(True) for m in self.parent.afterfit_menus]

    def update_start_values(self, params):
        """fill parameters with best fit values"""
        allparwids = {}
        for comp in self.fit_components.values():
            if comp.usebox is not None and comp.usebox.IsChecked():
                for name, parwids in comp.parwids.items():
                    allparwids[name] = parwids

        for pname, par in params.items():
            if pname in allparwids:
                allparwids[pname].value.SetValue(par.value)

    def autosave_modelresult(self, result, fname=None):
        """autosave model result to user larch folder"""
        xasguidir = os.path.join(site_config.usr_larchdir, 'xasgui')
        if not os.path.exists(xasguidir):
            try:
                os.makedirs(xasguidir)
            except OSError:
                print("Warning: cannot create XAS GUI user folder")
                return
        if not HAS_MODELSAVE:
            print("Warning: cannot save model results: upgrade lmfit")
            return
        if fname is None:
            fname = 'autosave.fitresult'
        fname = os.path.join(xasguidir, fname)

        self.save_fit_result(result, fname)
Beispiel #6
0
class PrePeakPanel(TaskPanel):
    def __init__(self, parent=None, controller=None, **kws):
        TaskPanel.__init__(self, parent, controller,
                           configname='prepeaks_config',
                           config=defaults, **kws)

        self.fit_components = OrderedDict()
        self.user_added_params = None

        self.pick2_timer = wx.Timer(self)
        self.pick2_group = None
        self.Bind(wx.EVT_TIMER, self.onPick2Timer, self.pick2_timer)
        self.pick2_t0 = 0.
        self.pick2_timeout = 15.

        self.pick2erase_timer = wx.Timer(self)
        self.pick2erase_panel = None
        self.Bind(wx.EVT_TIMER, self.onPick2EraseTimer, self.pick2erase_timer)

    def onPanelExposed(self, **kws):
        # called when notebook is selected
        try:
            fname = self.controller.filelist.GetStringSelection()
            gname = self.controller.file_groups[fname]
            dgroup = self.controller.get_group(gname)
            self.fill_form(dgroup)
        except:
            pass # print(" Cannot Fill prepeak panel from group ")

    def build_display(self):
        self.mod_nb = flatnotebook(self, {})
        pan = self.panel = GridPanel(self, ncols=4, nrows=4, pad=2, itemstyle=LEFT)

        self.wids = {}

        fsopts = dict(digits=2, increment=0.1, with_pin=True)
        ppeak_e0   = self.add_floatspin('ppeak_e0', value=0, **fsopts)
        ppeak_elo  = self.add_floatspin('ppeak_elo', value=-15, **fsopts)
        ppeak_ehi  = self.add_floatspin('ppeak_ehi', value=-5, **fsopts)
        ppeak_emin = self.add_floatspin('ppeak_emin', value=-30, **fsopts)
        ppeak_emax = self.add_floatspin('ppeak_emax', value=0, **fsopts)

        self.fitbline_btn  = Button(pan,'Fit Baseline', action=self.onFitBaseline,
                                    size=(125, -1))
        self.plotmodel_btn = Button(pan, 'Plot Model',
                                   action=self.onPlotModel,  size=(125, -1))
        self.fitmodel_btn = Button(pan, 'Fit Model',
                                   action=self.onFitModel,  size=(125, -1))
        self.loadmodel_btn = Button(pan, 'Load Model',
                                    action=self.onLoadFitResult,  size=(125, -1))
        self.fitmodel_btn.Disable()

        self.array_choice = Choice(pan, size=(175, -1),
                                   choices=list(Array_Choices.keys()))
        self.array_choice.SetSelection(1)

        models_peaks = Choice(pan, size=(150, -1),
                              choices=ModelChoices['peaks'],
                              action=self.addModel)

        models_other = Choice(pan, size=(150, -1),
                              choices=ModelChoices['other'],
                              action=self.addModel)

        self.models_peaks = models_peaks
        self.models_other = models_other


        self.message = SimpleText(pan,
                                 'first fit baseline, then add peaks to fit model.')

        self.msg_centroid = SimpleText(pan, '----')

        opts = dict(default=True, size=(75, -1), action=self.onPlot)
        self.show_centroid  = Check(pan, label='show?', **opts)
        self.show_peakrange = Check(pan, label='show?', **opts)
        self.show_fitrange  = Check(pan, label='show?', **opts)
        self.show_e0        = Check(pan, label='show?', **opts)

        opts = dict(default=False, size=(200, -1), action=self.onPlot)

        def add_text(text, dcol=1, newrow=True):
            pan.Add(SimpleText(pan, text), dcol=dcol, newrow=newrow)

        pan.Add(SimpleText(pan, ' Pre-edge Peak Fitting',
                           **self.titleopts), dcol=5)
        add_text(' Run Fit:', newrow=False)

        add_text('Array to fit: ')
        pan.Add(self.array_choice, dcol=3)
        pan.Add((10, 10))
        pan.Add(self.fitbline_btn)

        add_text('E0: ')
        pan.Add(ppeak_e0)
        pan.Add((10, 10), dcol=2)
        pan.Add(self.show_e0)
        pan.Add(self.plotmodel_btn)


        add_text('Fit Energy Range: ')
        pan.Add(ppeak_emin)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_emax)
        pan.Add(self.show_fitrange)
        pan.Add(self.fitmodel_btn)

        t = SimpleText(pan, 'Pre-edge Peak Range: ')
        SetTip(t, 'Range used as mask for background')

        pan.Add(t, newrow=True)
        pan.Add(ppeak_elo)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_ehi)
        pan.Add(self.show_peakrange)


        # pan.Add(self.fitsel_btn)

        add_text( 'Peak Centroid: ')
        pan.Add(self.msg_centroid, dcol=3)
        pan.Add(self.show_centroid, dcol=1)
        pan.Add(self.loadmodel_btn)

        #  add model
        ts = wx.BoxSizer(wx.HORIZONTAL)
        ts.Add(models_peaks)
        ts.Add(models_other)

        pan.Add(SimpleText(pan, 'Add Component: '), newrow=True)
        pan.Add(ts, dcol=7)

        pan.Add(SimpleText(pan, 'Messages: '), newrow=True)
        pan.Add(self.message, dcol=7)

        pan.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(pan, 0, LEFT, 3)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LEFT, 3)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(self.mod_nb,  1, LEFT|wx.GROW, 10)

        pack(self, sizer)

    def get_config(self, dgroup=None):
        """get processing configuration for a group"""
        if dgroup is None:
            dgroup = self.controller.get_group()

        conf = getattr(dgroup, 'prepeak_config', {})
        if 'e0' not in conf:
            conf = defaults
            conf['e0'] = getattr(dgroup, 'e0', -1)

        dgroup.prepeak_config = conf
        if not hasattr(dgroup, 'prepeaks'):
            dgroup.prepeaks = Group()

        return conf

    def fill_form(self, dat):
        if isinstance(dat, Group):
            self.wids['ppeak_e0'].SetValue(dat.e0)
            if hasattr(dat, 'prepeaks'):
                self.wids['ppeak_emin'].SetValue(dat.prepeaks.emin)
                self.wids['ppeak_emax'].SetValue(dat.prepeaks.emax)
                self.wids['ppeak_elo'].SetValue(dat.prepeaks.elo)
                self.wids['ppeak_ehi'].SetValue(dat.prepeaks.ehi)
        elif isinstance(dat, dict):
            self.wids['ppeak_e0'].SetValue(dat['e0'])
            self.wids['ppeak_emin'].SetValue(dat['emin'])
            self.wids['ppeak_emax'].SetValue(dat['emax'])
            self.wids['ppeak_elo'].SetValue(dat['elo'])
            self.wids['ppeak_ehi'].SetValue(dat['ehi'])

            self.array_choice.SetStringSelection(dat['array_desc'])
            self.show_e0.Enable(dat['show_e0'])
            self.show_centroid.Enable(dat['show_centroid'])
            self.show_fitrange.Enable(dat['show_fitrange'])
            self.show_peakrange.Enable(dat['show_peakrange'])

    def read_form(self):
        "read for, returning dict of values"
        dgroup = self.controller.get_group()
        array_desc = self.array_choice.GetStringSelection()
        form_opts = {'gname': dgroup.groupname,
                     'filename': dgroup.filename,
                     'array_desc': array_desc.lower(),
                     'array_name': Array_Choices[array_desc],
                     'baseline_form': 'lorentzian',
                     'bkg_components': []}

        form_opts['e0'] = self.wids['ppeak_e0'].GetValue()
        form_opts['emin'] = self.wids['ppeak_emin'].GetValue()
        form_opts['emax'] = self.wids['ppeak_emax'].GetValue()
        form_opts['elo'] = self.wids['ppeak_elo'].GetValue()
        form_opts['ehi'] = self.wids['ppeak_ehi'].GetValue()
        form_opts['plot_sub_bline'] = False # self.plot_sub_bline.IsChecked()
        form_opts['show_centroid'] = self.show_centroid.IsChecked()
        form_opts['show_peakrange'] = self.show_peakrange.IsChecked()
        form_opts['show_fitrange'] = self.show_fitrange.IsChecked()
        form_opts['show_e0'] = self.show_e0.IsChecked()
        return form_opts

    def onFitBaseline(self, evt=None):
        opts = self.read_form()
        cmd = """{gname:s}.ydat = 1.0*{gname:s}.{array_name:s}
pre_edge_baseline(energy={gname:s}.energy, norm={gname:s}.ydat, group={gname:s}, form='{baseline_form:s}',
                  with_line=True, elo={elo:.3f}, ehi={ehi:.3f}, emin={emin:.3f}, emax={emax:.3f})"""
        self.larch_eval(cmd.format(**opts))

        dgroup = self.controller.get_group()
        ppeaks = dgroup.prepeaks
        dgroup.centroid_msg = "%.4f +/- %.4f eV" % (ppeaks.centroid,
                                                    ppeaks.delta_centroid)

        self.msg_centroid.SetLabel(dgroup.centroid_msg)

        if 'bpeak_' not in self.fit_components:
            self.addModel(model='Lorentzian', prefix='bpeak_', isbkg=True)
        if 'bline_' not in self.fit_components:
            self.addModel(model='Linear', prefix='bline_', isbkg=True)

        for prefix in ('bpeak_', 'bline_'):
            cmp = self.fit_components[prefix]
            # cmp.bkgbox.SetValue(1)
            self.fill_model_params(prefix, dgroup.prepeaks.fit_details.params)

        self.fill_form(dgroup)
        self.fitmodel_btn.Enable()
        # self.fitallmodel_btn.Enable()

        i1, i2 = self.get_xranges(dgroup.energy)
        dgroup.yfit = dgroup.xfit = 0.0*dgroup.energy[i1:i2]

        # self.plot_choice.SetStringSelection(PLOT_BASELINE)
        self.onPlot(baseline_only=True)

    def fill_model_params(self, prefix, params):
        comp = self.fit_components[prefix]
        parwids = comp.parwids
        for pname, par in params.items():
            pname = prefix + pname
            if pname in parwids:
                wids = parwids[pname]
                if wids.minval is not None:
                    wids.minval.SetValue(par.min)
                if wids.maxval is not None:
                    wids.maxval.SetValue(par.max)
                wids.value.SetValue(par.value)
                varstr = 'vary' if par.vary else 'fix'
                if par.expr is not None:
                    varstr = 'constrain'
                if wids.vary is not None:
                    wids.vary.SetStringSelection(varstr)

    def onPlotModel(self, evt=None):
        dgroup = self.controller.get_group()
        g = self.build_fitmodel(dgroup)
        self.onPlot(show_init=True)

    def onPlot(self, evt=None, baseline_only=False, show_init=False):
        opts = self.read_form()
        dgroup = self.controller.get_group()

        opts['group'] = opts['gname']
        self.larch_eval(COMMANDS['prepeaks_setup'].format(**opts))

        cmd = "plot_prepeaks_fit"
        args = ['{gname}']
        if baseline_only:
            cmd = "plot_prepeaks_baseline"
        else:
            args.append("show_init=%s" % (show_init))
        cmd = "%s(%s)" % (cmd, ', '.join(args))
        self.larch_eval(cmd.format(**opts))

    def addModel(self, event=None, model=None, prefix=None, isbkg=False):
        if model is None and event is not None:
            model = event.GetString()
        if model is None or model.startswith('<'):
            return

        self.models_peaks.SetSelection(0)
        self.models_other.SetSelection(0)

        if prefix is None:
            p = model[:5].lower()
            curmodels = ["%s%i_" % (p, i+1) for i in range(1+len(self.fit_components))]
            for comp in self.fit_components:
                if comp in curmodels:
                    curmodels.remove(comp)

            prefix = curmodels[0]

        label = "%s(prefix='%s')" % (model, prefix)
        title = "%s: %s " % (prefix[:-1], model)
        title = prefix[:-1]
        mclass_kws = {'prefix': prefix}
        if 'step' in model.lower():
            form = model.lower().replace('step', '').strip()
            if form.startswith('err'):
                form = 'erf'
            label = "Step(form='%s', prefix='%s')" % (form, prefix)
            title = "%s: Step %s" % (prefix[:-1], form[:3])
            mclass = lm_models.StepModel
            mclass_kws['form'] = form
            minst = mclass(form=form, prefix=prefix)
        else:
            if model in ModelFuncs:
                mclass = getattr(lm_models, ModelFuncs[model])
            else:
                mclass = getattr(lm_models, model+'Model')

            minst = mclass(prefix=prefix)

        panel = GridPanel(self.mod_nb, ncols=2, nrows=5, pad=1, itemstyle=CEN)

        def SLabel(label, size=(80, -1), **kws):
            return  SimpleText(panel, label,
                               size=size, style=wx.ALIGN_LEFT, **kws)
        usebox = Check(panel, default=True, label='Use in Fit?', size=(100, -1))
        bkgbox = Check(panel, default=False, label='Is Baseline?', size=(125, -1))
        if isbkg:
            bkgbox.SetValue(1)

        delbtn = Button(panel, 'Delete This Component', size=(200, -1),
                        action=partial(self.onDeleteComponent, prefix=prefix))

        pick2msg = SimpleText(panel, "    ", size=(125, -1))
        pick2btn = Button(panel, 'Pick Values from Plotted Data', size=(200, -1),
                          action=partial(self.onPick2Points, prefix=prefix))

        # SetTip(mname,  'Label for the model component')
        SetTip(usebox,   'Use this component in fit?')
        SetTip(bkgbox,   'Label this component as "background" when plotting?')
        SetTip(delbtn,   'Delete this model component')
        SetTip(pick2btn, 'Select X range on Plot to Guess Initial Values')

        panel.Add(SLabel(label, size=(275, -1), colour='#0000AA'),
                  dcol=4,  style=wx.ALIGN_LEFT, newrow=True)
        panel.Add(usebox, dcol=2)
        panel.Add(bkgbox, dcol=1, style=RIGHT)

        panel.Add(pick2btn, dcol=2, style=wx.ALIGN_LEFT, newrow=True)
        panel.Add(pick2msg, dcol=3, style=wx.ALIGN_RIGHT)
        panel.Add(delbtn, dcol=2, style=wx.ALIGN_RIGHT)

        # panel.Add(HLine(panel, size=(150,  3)), dcol=4, style=wx.ALIGN_CENTER)

        panel.Add(SLabel("Parameter "), style=wx.ALIGN_LEFT,  newrow=True)
        panel.AddMany((SLabel(" Value"), SLabel(" Type"), SLabel(' Bounds'),
                       SLabel("  Min", size=(60, -1)),
                       SLabel("  Max", size=(60, -1)),  SLabel(" Expression")))

        parwids = OrderedDict()
        parnames = sorted(minst.param_names)

        for a in minst._func_allargs:
            pname = "%s%s" % (prefix, a)
            if (pname not in parnames and
                a in minst.param_hints and
                a not in minst.independent_vars):
                parnames.append(pname)

        for pname in parnames:
            sname = pname[len(prefix):]
            hints = minst.param_hints.get(sname, {})

            par = Parameter(name=pname, value=0, vary=True)
            if 'min' in hints:
                par.min = hints['min']
            if 'max' in hints:
                par.max = hints['max']
            if 'value' in hints:
                par.value = hints['value']
            if 'expr' in hints:
                par.expr = hints['expr']

            pwids = ParameterWidgets(panel, par, name_size=100, expr_size=150,
                                     float_size=80, prefix=prefix,
                                     widgets=('name', 'value',  'minval',
                                              'maxval', 'vary', 'expr'))
            parwids[par.name] = pwids
            panel.Add(pwids.name, newrow=True)

            panel.AddMany((pwids.value, pwids.vary, pwids.bounds,
                           pwids.minval, pwids.maxval, pwids.expr))

        for sname, hint in minst.param_hints.items():
            pname = "%s%s" % (prefix, sname)
            if 'expr' in hint and pname not in parnames:
                par = Parameter(name=pname, value=0, expr=hint['expr'])
                pwids = ParameterWidgets(panel, par, name_size=100, expr_size=400,
                                         float_size=80, prefix=prefix,
                                         widgets=('name', 'value', 'expr'))
                parwids[par.name] = pwids
                panel.Add(pwids.name, newrow=True)
                panel.Add(pwids.value)
                panel.Add(pwids.expr, dcol=5, style=wx.ALIGN_RIGHT)
                pwids.value.Disable()

        fgroup = Group(prefix=prefix, title=title, mclass=mclass,
                       mclass_kws=mclass_kws, usebox=usebox, panel=panel,
                       parwids=parwids, float_size=65, expr_size=150,
                       pick2_msg=pick2msg, bkgbox=bkgbox)


        self.fit_components[prefix] = fgroup
        panel.pack()

        self.mod_nb.AddPage(panel, title, True)
        sx,sy = self.GetSize()
        self.SetSize((sx, sy+1))
        self.SetSize((sx, sy))
        self.fitmodel_btn.Enable()


    def onDeleteComponent(self, evt=None, prefix=None):
        fgroup = self.fit_components.get(prefix, None)
        if fgroup is None:
            return

        for i in range(self.mod_nb.GetPageCount()):
            if fgroup.title == self.mod_nb.GetPageText(i):
                self.mod_nb.DeletePage(i)

        for attr in dir(fgroup):
            setattr(fgroup, attr, None)

        self.fit_components.pop(prefix)
        if len(self.fit_components) < 1:
            self.fitmodel_btn.Disable()

        # sx,sy = self.GetSize()
        # self.SetSize((sx, sy+1))
        # self.SetSize((sx, sy))

    def onPick2EraseTimer(self, evt=None):
        """erases line trace showing automated 'Pick 2' guess """
        self.pick2erase_timer.Stop()
        panel = self.pick2erase_panel
        ntrace = panel.conf.ntrace - 1
        trace = panel.conf.get_mpl_line(ntrace)
        panel.conf.get_mpl_line(ntrace).set_data(np.array([]), np.array([]))
        panel.conf.ntrace = ntrace
        panel.draw()

    def onPick2Timer(self, evt=None):
        """checks for 'Pick 2' events, and initiates 'Pick 2' guess
        for a model from the selected data range
        """
        try:
            plotframe = self.controller.get_display(win=1)
            curhist = plotframe.cursor_hist[:]
            plotframe.Raise()
        except:
            return

        if (time.time() - self.pick2_t0) > self.pick2_timeout:
            msg = self.pick2_group.pick2_msg.SetLabel(" ")
            plotframe.cursor_hist = []
            self.pick2_timer.Stop()
            return

        if len(curhist) < 2:
            self.pick2_group.pick2_msg.SetLabel("%i/2" % (len(curhist)))
            return

        self.pick2_group.pick2_msg.SetLabel("done.")
        self.pick2_timer.Stop()

        # guess param values
        xcur = (curhist[0][0], curhist[1][0])
        xmin, xmax = min(xcur), max(xcur)

        dgroup = getattr(self.larch.symtable, self.controller.groupname)
        x, y = dgroup.xdat, dgroup.ydat
        i0 = index_of(dgroup.xdat, xmin)
        i1 = index_of(dgroup.xdat, xmax)
        x, y = dgroup.xdat[i0:i1+1], dgroup.ydat[i0:i1+1]

        mod = self.pick2_group.mclass(prefix=self.pick2_group.prefix)
        parwids = self.pick2_group.parwids
        try:
            guesses = mod.guess(y, x=x)
        except:
            return

        for name, param in guesses.items():
            if name in parwids:
                parwids[name].value.SetValue(param.value)

        dgroup._tmp = mod.eval(guesses, x=dgroup.xdat)
        plotframe = self.controller.get_display(win=1)
        plotframe.cursor_hist = []
        plotframe.oplot(dgroup.xdat, dgroup._tmp)
        self.pick2erase_panel = plotframe.panel

        self.pick2erase_timer.Start(5000)


    def onPick2Points(self, evt=None, prefix=None):
        fgroup = self.fit_components.get(prefix, None)
        if fgroup is None:
            return

        plotframe = self.controller.get_display(win=1)
        plotframe.Raise()

        plotframe.cursor_hist = []
        fgroup.npts = 0
        self.pick2_group = fgroup

        if fgroup.pick2_msg is not None:
            fgroup.pick2_msg.SetLabel("0/2")

        self.pick2_t0 = time.time()
        self.pick2_timer.Start(250)


    def onLoadFitResult(self, event=None):
        dlg = wx.FileDialog(self, message="Load Saved File Model",
                            wildcard=ModelWcards, style=wx.FD_OPEN)
        rfile = None
        if dlg.ShowModal() == wx.ID_OK:
            rfile = dlg.GetPath()
        dlg.Destroy()

        if rfile is None:
            return

        self.larch_eval("# peakmodel = lm_load_modelresult('%s')" %rfile)

        result = load_modelresult(str(rfile))
        for prefix in list(self.fit_components.keys()):
            self.onDeleteComponent(self, prefix=prefix)

        for comp in result.model.components:
            isbkg = comp.prefix in result.user_options['bkg_components']
            self.addModel(model=comp.func.__name__,
                          prefix=comp.prefix, isbkg=isbkg)

        for comp in result.model.components:
            parwids = self.fit_components[comp.prefix].parwids
            for pname, par in result.params.items():
                if pname in parwids:
                    wids = parwids[pname]
                    if wids.minval is not None:
                        wids.minval.SetValue(par.min)
                    if wids.maxval is not None:
                        wids.maxval.SetValue(par.max)
                    val = result.init_values.get(pname, par.value)
                    wids.value.SetValue(val)
        self.fill_form(result.user_options)


    def onSelPoint(self, evt=None, opt='__', relative_e0=False, win=None):
        """
        get last selected point from a specified plot window
        and fill in the value for the widget defined by `opt`.

        by default it finds the latest cursor position from the
        cursor history of the first 20 plot windows.
        """
        if opt not in self.wids:
            return None

        _x, _y = last_cursor_pos(win=win, _larch=self.larch)

        if _x is not None:
            if relative_e0 and 'e0' in self.wids:
                _x -= self.wids['e0'].GetValue()
            self.wids[opt].SetValue(_x)

    def get_xranges(self, x):
        opts = self.read_form()
        dgroup = self.controller.get_group()
        en_eps = min(np.diff(dgroup.energy)) / 5.

        i1 = index_of(x, opts['emin'] + en_eps)
        i2 = index_of(x, opts['emax'] + en_eps) + 1
        return i1, i2

    def build_fitmodel(self, dgroup):
        """ use fit components to build model"""
        # self.summary = {'components': [], 'options': {}}
        peaks = []
        cmds = ["## set up pre-edge peak parameters", "peakpars = Parameters()"]
        modcmds = ["## define pre-edge peak model"]
        modop = " ="
        opts = self.read_form()


        opts['group'] = opts['gname']
        self.larch_eval(COMMANDS['prepeaks_setup'].format(**opts))


        for comp in self.fit_components.values():
            _cen, _amp = None, None
            if comp.usebox is not None and comp.usebox.IsChecked():
                for parwids in comp.parwids.values():
                    this = parwids.param
                    pargs = ["'%s'" % this.name, 'value=%f' % (this.value),
                             'min=%f' % (this.min), 'max=%f' % (this.max)]
                    if this.expr is not None:
                        pargs.append("expr='%s'" % (this.expr))
                    elif not this.vary:
                        pargs.pop()
                        pargs.pop()
                        pargs.append("vary=False")

                    cmds.append("peakpars.add(%s)" % (', '.join(pargs)))
                    if this.name.endswith('_center'):
                        _cen = this.name
                    elif parwids.param.name.endswith('_amplitude'):
                        _amp = this.name
                compargs = ["%s='%s'" % (k,v) for k,v in comp.mclass_kws.items()]
                modcmds.append("peakmodel %s %s(%s)" % (modop, comp.mclass.__name__,
                                                        ', '.join(compargs)))

                modop = "+="
                if not comp.bkgbox.IsChecked() and _cen is not None and _amp is not None:
                    peaks.append((_amp, _cen))

        if len(peaks) > 0:
            denom = '+'.join([p[0] for p in peaks])
            numer = '+'.join(["%s*%s "% p for p in peaks])
            cmds.append("peakpars.add('fit_centroid', expr='(%s)/(%s)')" % (numer, denom))

        cmds.extend(modcmds)
        cmds.append(COMMANDS['prepfit'].format(group=dgroup.groupname,
                                               user_opts=repr(opts)))

        self.larch_eval("\n".join(cmds))

    def onFitSelected(self, event=None):
        dgroup = self.controller.get_group()
        self.build_fitmodel(dgroup)

    def onFitModel(self, event=None):
        dgroup = self.controller.get_group()
        if dgroup is None:
            return
        self.build_fitmodel(dgroup)
        opts = self.read_form()

        dgroup = self.controller.get_group()
        opts['group'] = opts['gname']
        self.larch_eval(COMMANDS['prepeaks_setup'].format(**opts))

        ppeaks = dgroup.prepeaks


        # add bkg_component to saved user options
        bkg_comps = []
        for label, comp in self.fit_components.items():
            if comp.bkgbox.IsChecked():
                bkg_comps.append(label)
        opts['bkg_components'] = bkg_comps

        imin, imax = self.get_xranges(dgroup.xdat)

        cmds = ["## do peak fit: "]

        yerr_type = 'set_yerr_const'
        yerr = getattr(dgroup, 'yerr', None)
        if yerr is None:
            if hasattr(dgroup, 'norm_std'):
                cmds.append("{group}.yerr = {group}.norm_std")
                yerr_type = 'set_yerr_array'
            elif hasattr(dgroup, 'mu_std'):
                cmds.append("{group}.yerr = {group}.mu_std/(1.e-15+{group}.edge_step)")
                yerr_type = 'set_yerr_array'
            else:
                cmds.append("{group}.yerr = 1")
        elif isinstance(dgroup.yerr, np.ndarray):
                yerr_type = 'set_yerr_array'


        cmds.extend([COMMANDS[yerr_type], COMMANDS['dofit']])

        cmd = '\n'.join(cmds)
        self.larch_eval(cmd.format(group=dgroup.groupname,
                                   imin=imin, imax=imax,
                                   user_opts=repr(opts)))

        self.autosave_modelresult(self.larch_get("peakresult"))

        self.onPlot()
        self.show_subframe('prepeak_result_frame', FitResultFrame,
                                  datagroup=dgroup, peakframe=self)
        self.subframes['prepeak_result_frame'].show_results()

    def update_start_values(self, params):
        """fill parameters with best fit values"""
        allparwids = {}
        for comp in self.fit_components.values():
            if comp.usebox is not None and comp.usebox.IsChecked():
                for name, parwids in comp.parwids.items():
                    allparwids[name] = parwids

        for pname, par in params.items():
            if pname in allparwids:
                allparwids[pname].value.SetValue(par.value)

    def autosave_modelresult(self, result, fname=None):
        """autosave model result to user larch folder"""
        confdir = os.path.join(site_config.usr_larchdir, 'xas_viewer')
        if not os.path.exists(confdir):
            try:
                os.makedirs(confdir)
            except OSError:
                print("Warning: cannot create XAS_Viewer user folder")
                return
        if not HAS_MODELSAVE:
            print("Warning: cannot save model results: upgrade lmfit")
            return
        if fname is None:
            fname = 'autosave.fitmodel'
        save_modelresult(result, os.path.join(confdir, fname))
Beispiel #7
0
    def build_display(self):
        titleopts = dict(font=Font(12), colour='#AA0000')
        panel = self.panel
        wids = self.wids
        self.skip_process = True

        wids['plotone_op'] = Choice(panel,
                                    choices=PlotOne_Choices,
                                    action=self.onPlotOne,
                                    size=(175, -1))
        wids['plotalt_op'] = Choice(panel,
                                    choices=PlotAlt_Choices,
                                    action=self.onPlotOne,
                                    size=(175, -1))
        wids['plotsel_op'] = Choice(panel,
                                    choices=PlotSel_Choices,
                                    action=self.onPlotSel,
                                    size=(175, -1))

        wids['plotone_op'].SetStringSelection(chik)
        wids['plotsel_op'].SetStringSelection(chik)
        wids['plotalt_op'].SetStringSelection(noplot)

        plot_one = Button(panel,
                          'Plot This Group',
                          size=(150, -1),
                          action=self.onPlotOne)

        plot_sel = Button(panel,
                          'Plot Selected Groups',
                          size=(150, -1),
                          action=self.onPlotSel)

        saveconf = Button(panel,
                          'Save as Default Settings',
                          size=(200, -1),
                          action=self.onSaveConfigBtn)

        def FloatSpinWithPin(name, value, **kws):
            s = wx.BoxSizer(wx.HORIZONTAL)
            self.wids[name] = FloatSpin(panel, value=value, **kws)
            bb = BitmapButton(panel,
                              get_icon('pin'),
                              size=(25, 25),
                              action=partial(self.onSelPoint, opt=name),
                              tooltip='use last point selected from plot')
            s.Add(wids[name])
            s.Add(bb)
            return s

        wids['plot_voffset'] = FloatSpin(panel,
                                         value=0,
                                         digits=2,
                                         increment=0.25,
                                         action=self.onProcess)
        wids['plot_kweight'] = FloatSpin(panel,
                                         value=2,
                                         digits=1,
                                         increment=1,
                                         action=self.onProcess,
                                         min_val=0,
                                         max_val=5)
        wids['plot_kweight_alt'] = FloatSpin(panel,
                                             value=2,
                                             digits=1,
                                             increment=1,
                                             action=self.onProcess,
                                             min_val=0,
                                             max_val=5)

        opts = dict(digits=2, increment=0.1, min_val=0, action=self.onProcess)
        wids['e0'] = FloatSpin(panel, **opts)

        opts['max_val'] = 5
        wids['rbkg'] = FloatSpin(panel, value=1.0, **opts)

        opts['max_val'] = 125
        bkg_kmin = FloatSpinWithPin('bkg_kmin', value=0, **opts)

        bkg_kmax = FloatSpinWithPin('bkg_kmax', value=20, **opts)

        fft_kmin = FloatSpinWithPin('fft_kmin', value=0, **opts)

        fft_kmax = FloatSpinWithPin('fft_kmax', value=20, **opts)

        wids['fft_dk'] = FloatSpin(panel, value=3, **opts)

        opts.update({'increment': 1, 'digits': 1, 'max_val': 5})
        wids['bkg_kweight'] = FloatSpin(panel, value=1, **opts)

        wids['fft_kweight'] = FloatSpin(panel, value=1, **opts)

        opts = dict(choices=CLAMPLIST, size=(80, -1), action=self.onProcess)
        wids['bkg_clamplo'] = Choice(panel, **opts)
        wids['bkg_clamphi'] = Choice(panel, **opts)

        wids['fft_kwindow'] = Choice(panel,
                                     choices=list(FTWINDOWS),
                                     action=self.onProcess,
                                     size=(125, -1))

        def add_text(text, dcol=1, newrow=True):
            panel.Add(SimpleText(panel, text), dcol=dcol, newrow=newrow)

        panel.Add(SimpleText(panel, ' EXAFS Processing', **titleopts), dcol=5)

        panel.Add(plot_sel, newrow=True)
        panel.Add(self.wids['plotsel_op'], dcol=2)

        add_text('Vertical offset: ', newrow=False)
        panel.Add(wids['plot_voffset'], dcol=2)

        panel.Add(plot_one, newrow=True)
        panel.Add(self.wids['plotone_op'], dcol=2)

        add_text('Plot k weight: ', newrow=False)
        panel.Add(wids['plot_kweight'])

        add_text('Add Second Plot: ', newrow=True)
        panel.Add(self.wids['plotalt_op'], dcol=2)
        add_text('Plot2 k weight: ', newrow=False)
        panel.Add(wids['plot_kweight_alt'])

        panel.Add(HLine(panel, size=(500, 3)), dcol=6, newrow=True)

        panel.Add(SimpleText(panel, ' Background subtraction', **titleopts),
                  dcol=2,
                  newrow=True)

        panel.Add(Button(panel,
                         'Copy To Selected Groups',
                         size=(175, -1),
                         action=partial(self.onCopyParam, 'bkg')),
                  dcol=2)

        add_text('R bkg: ')
        panel.Add(wids['rbkg'])

        add_text('E0: ', newrow=False)
        panel.Add(wids['e0'])

        add_text('k min: ')
        panel.Add(bkg_kmin)
        add_text('k max:', newrow=False)
        panel.Add(bkg_kmax)

        add_text('kweight: ', newrow=True)
        panel.Add(wids['bkg_kweight'], dcol=1)

        add_text('Clamps Low E: ', newrow=True)
        panel.Add(wids['bkg_clamplo'])
        add_text('high E: ', newrow=False)
        panel.Add(wids['bkg_clamphi'])

        panel.Add(HLine(panel, size=(500, 3)), dcol=6, newrow=True)

        panel.Add(SimpleText(panel, ' Fourier transform', **titleopts),
                  dcol=2,
                  newrow=True)

        panel.Add(Button(panel,
                         'Copy to Selected Groups',
                         size=(175, -1),
                         action=partial(self.onCopyParam, 'fft')),
                  dcol=2)

        panel.Add(SimpleText(panel, 'k min: '), newrow=True)
        panel.Add(fft_kmin)

        panel.Add(SimpleText(panel, 'k max:'))
        panel.Add(fft_kmax)

        panel.Add(SimpleText(panel, 'k weight : '), newrow=True)
        panel.Add(wids['fft_kweight'])

        panel.Add(SimpleText(panel, 'K window : '), newrow=True)
        panel.Add(wids['fft_kwindow'])
        panel.Add(SimpleText(panel, ' dk : '))
        panel.Add(wids['fft_dk'])

        panel.Add(HLine(panel, size=(500, 3)), dcol=6, newrow=True)

        panel.Add(saveconf, dcol=4, newrow=True)
        panel.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel, 1, LCEN, 3)
        pack(self, sizer)
        self.skip_process = False
Beispiel #8
0
    def build_display(self):
        panel = self.panel
        wids = self.wids
        self.skip_process = True

        wids['fitspace'] = Choice(panel,
                                  choices=FitSpace_Choices,
                                  size=(250, -1))
        wids['fitspace'].SetStringSelection(norm)
        # wids['plotchoice'] = Choice(panel, choices=Plot_Choices,
        #                           size=(250, -1), action=self.onPlot)

        wids['method'] = Choice(panel,
                                choices=Regress_Choices,
                                size=(250, -1),
                                action=self.onRegressMethod)

        add_text = self.add_text

        opts = dict(digits=2, increment=1.0)

        w_xmin = self.add_floatspin('xmin', value=defaults['xmin'], **opts)
        w_xmax = self.add_floatspin('xmax', value=defaults['xmax'], **opts)
        wids['alpha'] = NumericCombo(panel,
                                     make_steps(),
                                     fmt='%.6g',
                                     default_val=0.01,
                                     width=100)

        wids['auto_scale_pls'] = Check(panel,
                                       default=True,
                                       label='auto scale?')
        wids['auto_alpha'] = Check(panel, default=False, label='auto alpha?')

        wids['fit_intercept'] = Check(panel,
                                      default=True,
                                      label='fit intercept?')

        wids['save_csv'] = Button(panel,
                                  'Save CSV File',
                                  size=(150, -1),
                                  action=self.onSaveCSV)
        wids['load_csv'] = Button(panel,
                                  'Load CSV File',
                                  size=(150, -1),
                                  action=self.onLoadCSV)

        wids['save_model'] = Button(panel,
                                    'Save Model',
                                    size=(150, -1),
                                    action=self.onSaveModel)
        wids['save_model'].Disable()

        wids['load_model'] = Button(panel,
                                    'Load Model',
                                    size=(150, -1),
                                    action=self.onLoadModel)

        wids['train_model'] = Button(panel,
                                     'Train Model From These Data',
                                     size=(275, -1),
                                     action=self.onTrainModel)

        wids['fit_group'] = Button(panel,
                                   'Predict Variable for Selected Groups',
                                   size=(275, -1),
                                   action=self.onPredictGroups)
        wids['fit_group'].Disable()

        w_cvfolds = self.add_floatspin('cv_folds',
                                       digits=0,
                                       with_pin=False,
                                       value=0,
                                       increment=1,
                                       min_val=-1)

        w_cvreps = self.add_floatspin('cv_repeats',
                                      digits=0,
                                      with_pin=False,
                                      value=0,
                                      increment=1,
                                      min_val=-1)

        w_ncomps = self.add_floatspin('ncomps',
                                      digits=0,
                                      with_pin=False,
                                      value=3,
                                      increment=1,
                                      min_val=1)

        wids['varname'] = wx.TextCtrl(panel, -1, 'valence', size=(150, -1))
        wids['stat1'] = SimpleText(panel, ' - - - ')
        wids['stat2'] = SimpleText(panel, ' - - - ')

        collabels = [' File /Group Name ', 'External Value', 'Predicted Value']
        colsizes = [300, 120, 120]
        coltypes = ['str', 'float:12,4', 'float:12,4']
        coldefs = ['', 0.0, 0.0]

        wids['table'] = DataTableGrid(panel,
                                      nrows=MAX_ROWS,
                                      collabels=collabels,
                                      datatypes=coltypes,
                                      defaults=coldefs,
                                      colsizes=colsizes)

        wids['table'].SetMinSize((625, 175))

        wids['use_selected'] = Button(panel,
                                      'Use Selected Groups',
                                      size=(150, -1),
                                      action=self.onFillTable)

        panel.Add(SimpleText(panel, 'Feature Regression, Model Selection',
                             **self.titleopts),
                  dcol=4)
        add_text('Array to Use: ', newrow=True)
        panel.Add(wids['fitspace'], dcol=4)

        # add_text('Plot : ', newrow=True)
        # panel.Add(wids['plotchoice'], dcol=3)
        add_text('Fit Energy Range: ')
        panel.Add(w_xmin)
        add_text(' : ', newrow=False)
        panel.Add(w_xmax, dcol=3)
        add_text('Regression Method:')
        panel.Add(wids['method'], dcol=4)
        add_text('PLS # components: ')
        panel.Add(w_ncomps)
        panel.Add(wids['auto_scale_pls'], dcol=2)
        add_text('Lasso Alpha: ')
        panel.Add(wids['alpha'])
        panel.Add(wids['auto_alpha'], dcol=2)
        panel.Add(wids['fit_intercept'])
        wids['alpha'].Disable()
        wids['auto_alpha'].Disable()
        wids['fit_intercept'].Disable()

        add_text('Cross Validation: ')
        add_text(' # folds, # repeats: ', newrow=False)
        panel.Add(w_cvfolds, dcol=2)
        panel.Add(w_cvreps)

        panel.Add(HLine(panel, size=(600, 2)), dcol=6, newrow=True)

        add_text('Build Model: ', newrow=True)
        panel.Add(wids['use_selected'], dcol=2)
        add_text('Attribute Name: ', newrow=False)
        panel.Add(wids['varname'], dcol=4)

        add_text('Read/Save Data: ', newrow=True)
        panel.Add(wids['load_csv'], dcol=3)
        panel.Add(wids['save_csv'], dcol=2)

        panel.Add(wids['table'], newrow=True, dcol=5)  # , drow=3)

        panel.Add(HLine(panel, size=(550, 2)), dcol=5, newrow=True)
        panel.Add((5, 5), newrow=True)
        add_text('Train Model : ')
        panel.Add(wids['train_model'], dcol=3)
        panel.Add(wids['load_model'])

        add_text('Use This Model : ')
        panel.Add(wids['fit_group'], dcol=3)
        panel.Add(wids['save_model'])
        add_text('Fit Statistics : ')
        panel.Add(wids['stat1'], dcol=4)
        panel.Add((5, 5), newrow=True)
        panel.Add(wids['stat2'], dcol=4)
        panel.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(panel, 1, LEFT, 3)
        pack(self, sizer)
        self.skip_process = False
Beispiel #9
0
    def build_display(self):
        panel = self.panel
        wids = self.wids
        self.skip_process = True

        wids['fitspace'] = Choice(panel,
                                  choices=FitSpace_Choices,
                                  size=(175, -1))
        wids['fitspace'].SetStringSelection(norm)
        wids['plotchoice'] = Choice(panel,
                                    choices=Plot_Choices,
                                    size=(175, -1),
                                    action=self.onPlot)
        wids['plotchoice'].SetSelection(0)

        add_text = self.add_text

        opts = dict(digits=2, increment=1.0)

        w_xmin = self.add_floatspin('xmin', value=defaults['xmin'], **opts)
        w_xmax = self.add_floatspin('xmax', value=defaults['xmax'], **opts)

        w_wmin = self.add_floatspin('weight_min',
                                    digits=4,
                                    value=defaults['weight_min'],
                                    increment=0.001,
                                    with_pin=False,
                                    min_val=0,
                                    max_val=0.5,
                                    action=self.onSet_WeightMin)

        autoset_fs_increment(self.wids['weight_min'], defaults['weight_min'])

        self.wids['weight_auto'] = Check(panel, default=True, label='auto?')

        w_mcomps = self.add_floatspin('max_components',
                                      digits=0,
                                      value=defaults['max_components'],
                                      increment=1,
                                      with_pin=False,
                                      min_val=0)

        b_build_model = Button(panel,
                               'Build Model With Selected Groups',
                               size=(275, -1),
                               action=self.onBuildPCAModel)

        wids['fit_group'] = Button(panel,
                                   'Test Current Group with Model',
                                   size=(225, -1),
                                   action=self.onFitGroup)

        wids['save_model'] = Button(panel,
                                    'Save PCA Model',
                                    size=(150, -1),
                                    action=self.onSavePCAModel)
        wids['load_model'] = Button(panel,
                                    'Load PCA Model',
                                    size=(150, -1),
                                    action=self.onLoadPCAModel)

        wids['fit_group'].Disable()
        wids['load_model'].Disable()
        wids['save_model'].Disable()

        collabels = [
            ' Variance ', ' IND value ', ' IND / IND_Best', ' Factor Weight'
        ]

        colsizes = [100, 100, 100, 200]
        coltypes = ['float:12,6', 'float:12,6', 'float:12,5', 'string']
        coldefs = [0.0, 0.0, 1.0, '0.0']

        wids['table'] = DataTableGrid(panel,
                                      nrows=MAX_ROWS,
                                      collabels=collabels,
                                      datatypes=coltypes,
                                      defaults=coldefs,
                                      colsizes=colsizes,
                                      rowlabelsize=60)

        wids['table'].SetMinSize((625, 175))
        wids['table'].EnableEditing(False)
        #
        #         sview = self.wids['stats'] = dv.DataViewListCtrl(panel, style=DVSTYLE)
        #         sview.AppendTextColumn(' Component',    width=75)
        #         sview.AppendTextColumn(' Weight',       width=100)
        #         sview.AppendTextColumn(' Significant?', width=75)
        #
        #         for col in range(sview.ColumnCount):
        #             this = sview.Columns[col]
        #             align = wx.ALIGN_LEFT if col == 0 else wx.ALIGN_RIGHT
        #             this.Sortable = False
        #             this.Alignment = this.Renderer.Alignment = align
        #         sview.SetMinSize((275, 250))

        wids['status'] = SimpleText(panel, ' ')
        rfont = self.GetFont()
        rfont.SetPointSize(rfont.GetPointSize() + 1)

        wids['fit_chi2'] = SimpleText(panel, '0.000', font=rfont)
        wids['fit_dscale'] = SimpleText(panel, '1.000', font=rfont)

        panel.Add(SimpleText(panel, ' Principal Component Analysis',
                             **self.titleopts),
                  dcol=4)

        add_text('Array to Use: ', newrow=True)
        panel.Add(wids['fitspace'], dcol=2)
        panel.Add(wids['load_model'], dcol=2)

        add_text('Plot : ', newrow=True)
        panel.Add(wids['plotchoice'], dcol=2)

        panel.Add(wids['save_model'], dcol=2)

        add_text('Fit Energy Range: ')
        panel.Add(w_xmin)
        add_text(' : ', newrow=False)
        panel.Add(w_xmax)
        #panel.Add(wids['show_fitrange'])

        add_text('Min Weight: ')
        panel.Add(w_wmin)
        panel.Add(wids['weight_auto'])
        add_text('Max Components:', dcol=1, newrow=True)
        panel.Add(w_mcomps)

        panel.Add(Button(panel,
                         'Copy To Selected Groups',
                         size=(200, -1),
                         action=partial(self.onCopyParam, 'pca')),
                  dcol=2)

        add_text('Status: ')
        panel.Add(wids['status'], dcol=3)

        panel.Add(HLine(panel, size=(550, 2)), dcol=5, newrow=True)

        panel.Add(b_build_model, dcol=5, newrow=True)

        panel.Add(wids['table'], dcol=5, newrow=True)
        panel.Add(wids['fit_group'], dcol=3, newrow=True)

        add_text('chi-square: ')
        panel.Add(wids['fit_chi2'])
        add_text('scale factor: ')
        panel.Add(wids['fit_dscale'])

        #
        #         ## add weights report: slightly tricky layout
        #         ## working with GridBagSizer under gridpanel...
        #         icol = panel.icol - 2
        #         irow = panel.irow
        #         pstyle, ppad = panel.itemstyle, panel.pad
        #
        #         panel.sizer.Add(SimpleText(panel, 'data scalefactor = '),
        #                         (irow+1, icol), (1, 1), pstyle, ppad)
        #         panel.sizer.Add(wids['fit_dscale'],
        #                         (irow+1, icol+1), (1, 1), pstyle, ppad)
        #         irow +=1
        #         for i in range(1, NWTS+1):
        #             wids['fit_wt%d' % i] = SimpleText(panel, '--', font=rfont)
        #             panel.sizer.Add(SimpleText(panel, 'weight_%d ='%i, font=rfont),
        #                             (irow+i, icol), (1, 1), pstyle, ppad)
        #             panel.sizer.Add(wids['fit_wt%d'%i],
        #                             (irow+i, icol+1), (1, 1), pstyle, ppad)
        #
        panel.pack()
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((10, 10), 0, LCEN, 3)
        sizer.Add(panel, 1, LCEN, 3)
        pack(self, sizer)
        self.skip_process = False
Beispiel #10
0
    def build(self):
        sizer = wx.GridBagSizer(5, 5)
        sizer.SetVGap(5)
        sizer.SetHGap(5)

        splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE)
        splitter.SetMinimumPaneSize(200)

        self.datalistbox = EditableListBox(splitter,
                                           self.ShowDataSet,
                                           size=(250, -1))
        panel = scrolled.ScrolledPanel(splitter)

        self.SetMinSize((650, 600))
        self.colors = GUIColors()

        # title row
        self.wids = wids = {}
        title = SimpleText(panel,
                           'Linear Combination Results',
                           font=Font(FONTSIZE + 2),
                           colour=self.colors.title,
                           style=LEFT)

        wids['plot_one'] = Button(panel,
                                  'Plot This Fit',
                                  size=(125, -1),
                                  action=self.onPlotOne)
        wids['plot_sel'] = Button(panel,
                                  'Plot N Best Fits',
                                  size=(125, -1),
                                  action=self.onPlotSel)

        wids['plot_ntitle'] = SimpleText(panel, 'N fits to plot: ')

        wids['plot_nchoice'] = Choice(panel,
                                      size=(60, -1),
                                      choices=['%d' % i for i in range(1, 21)])
        wids['plot_nchoice'].SetStringSelection('5')

        wids['data_title'] = SimpleText(panel,
                                        '<--> ',
                                        font=Font(FONTSIZE + 2),
                                        colour=self.colors.title,
                                        style=LEFT)
        wids['nfits_title'] = SimpleText(panel, 'showing 5 best fits')

        copts = dict(size=(125, 30), default=True, action=self.onPlotOne)
        # wids['show_e0'] = Check(panel, label='show E0?', **copts)
        wids['show_fitrange'] = Check(panel, label='show fit range?', **copts)

        irow = 0
        sizer.Add(title, (irow, 0), (1, 1), LEFT)
        sizer.Add(wids['data_title'], (irow, 1), (1, 2), LEFT)

        irow += 1
        sizer.Add(wids['nfits_title'], (irow, 0), (1, 1), LEFT)

        irow += 1
        self.wids['paramstitle'] = SimpleText(panel,
                                              '[[Parameters]]',
                                              font=Font(FONTSIZE + 2),
                                              colour=self.colors.title,
                                              style=LEFT)
        sizer.Add(self.wids['paramstitle'], (irow, 0), (1, 1), LEFT)

        pview = self.wids['params'] = dv.DataViewListCtrl(panel, style=DVSTYLE)
        pview.SetMinSize((475, 200))
        pview.AppendTextColumn(' Parameter ', width=230)
        pview.AppendTextColumn(' Best-Fit Value', width=120)
        pview.AppendTextColumn(' Standard Error ', width=120)
        for col in range(3):
            this = pview.Columns[col]
            isort, align = True, wx.ALIGN_RIGHT
            if col == 0:
                align = wx.ALIGN_LEFT
            this.Sortable = isort
            this.Alignment = this.Renderer.Alignment = align

        irow += 1
        sizer.Add(self.wids['params'], (irow, 0), (4, 1), LEFT)
        sizer.Add(self.wids['plot_one'], (irow, 1), (1, 2), LEFT)
        sizer.Add(self.wids['plot_sel'], (irow + 1, 1), (1, 2), LEFT)
        sizer.Add(self.wids['plot_ntitle'], (irow + 2, 1), (1, 1), LEFT)
        sizer.Add(self.wids['plot_nchoice'], (irow + 2, 2), (1, 1), LEFT)
        # sizer.Add(self.wids['show_e0'],      (irow+3, 1), (1, 2), LEFT)
        sizer.Add(self.wids['show_fitrange'], (irow + 3, 1), (1, 2), LEFT)

        irow += 4
        sizer.Add(HLine(panel, size=(675, 3)), (irow, 0), (1, 4), LEFT)

        sview = self.wids['stats'] = dv.DataViewListCtrl(panel, style=DVSTYLE)
        sview.Bind(dv.EVT_DATAVIEW_SELECTION_CHANGED, self.onSelectFitStat)
        sview.AppendTextColumn(' Fit #', width=50)
        sview.AppendTextColumn(' N_vary', width=50)
        sview.AppendTextColumn(' N_eval', width=60)
        sview.AppendTextColumn(' \u03c7\u00B2', width=110)
        sview.AppendTextColumn(' \u03c7\u00B2_reduced', width=110)
        sview.AppendTextColumn(' Akaike Info', width=110)
        sview.AppendTextColumn(' Bayesian Info', width=110)

        for col in range(sview.ColumnCount):
            this = sview.Columns[col]
            isort, align = True, wx.ALIGN_RIGHT
            if col == 0:
                align = wx.ALIGN_CENTER
            this.Sortable = isort
            this.Alignment = this.Renderer.Alignment = align

        sview.SetMinSize((675, 175))

        irow += 1
        title = SimpleText(panel,
                           '[[Fit Statistics]]',
                           font=Font(FONTSIZE + 2),
                           colour=self.colors.title,
                           style=LEFT)
        sizer.Add(title, (irow, 0), (1, 4), LEFT)

        irow += 1
        sizer.Add(sview, (irow, 0), (1, 4), LEFT)

        irow += 1
        sizer.Add(HLine(panel, size=(675, 3)), (irow, 0), (1, 4), LEFT)

        irow += 1
        title = SimpleText(panel,
                           '[[Weights]]',
                           font=Font(FONTSIZE + 2),
                           colour=self.colors.title,
                           style=LEFT)
        sizer.Add(title, (irow, 0), (1, 4), LEFT)
        self.wids['weightspanel'] = ppan = wx.Panel(panel)

        p1 = SimpleText(ppan, ' < Weights > ')
        os = wx.BoxSizer(wx.VERTICAL)
        os.Add(p1, 1, 3)
        pack(ppan, os)
        ppan.SetMinSize((675, 175))

        irow += 1
        sizer.Add(ppan, (irow, 0), (1, 4), LEFT)

        irow += 1
        sizer.Add(HLine(panel, size=(675, 3)), (irow, 0), (1, 4), LEFT)

        pack(panel, sizer)
        panel.SetupScrolling()

        splitter.SplitVertically(self.datalistbox, panel, 1)

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(splitter, 1, wx.GROW | wx.ALL, 5)

        pack(self, mainsizer)
        # self.SetSize((725, 750))
        self.Show()
        self.Raise()
Beispiel #11
0
    def build_display(self):
        panel = self.panel
        wids = self.wids
        self.skip_process = True

        wids['fitspace'] = Choice(panel,
                                  choices=FitSpace_Choices,
                                  size=(175, -1))
        wids['fitspace'].SetStringSelection(norm)

        add_text = self.add_text

        opts = dict(digits=2, increment=1.0, relative_e0=False)  # True)

        elo_wids = self.add_floatspin('elo', value=defaults['elo'], **opts)
        ehi_wids = self.add_floatspin('ehi', value=defaults['ehi'], **opts)

        wids['fit_group'] = Button(panel,
                                   'Fit this Group',
                                   size=(175, -1),
                                   action=self.onFitOne)
        wids['fit_selected'] = Button(panel,
                                      'Fit Selected Groups',
                                      size=(175, -1),
                                      action=self.onFitAll)

        wids['add_selected'] = Button(panel,
                                      'Use Selected Groups as Components',
                                      size=(300, -1),
                                      action=self.onUseSelected)

        wids['saveconf'] = Button(panel,
                                  'Save as Default Settings',
                                  size=(225, -1),
                                  action=self.onSaveConfigBtn)

        opts = dict(default=True, size=(75, -1), action=self.onPlotOne)

        wids['show_fitrange'] = Check(panel, label='show?', **opts)

        wids['sum_to_one'] = Check(panel,
                                   label='Weights Must Sum to 1?',
                                   default=True)
        wids['all_combos'] = Check(panel,
                                   label='Fit All Combinations?',
                                   default=True)
        max_ncomps = self.add_floatspin('max_ncomps',
                                        value=10,
                                        digits=0,
                                        increment=1,
                                        min_val=0,
                                        max_val=20,
                                        size=(60, -1),
                                        with_pin=False)

        panel.Add(SimpleText(panel, ' Linear Combination Analysis',
                             **self.titleopts),
                  dcol=4)

        add_text('Array to Fit: ', newrow=True)
        panel.Add(wids['fitspace'], dcol=3)

        add_text('Fit Energy Range: ')
        panel.Add(elo_wids)
        add_text(' : ', newrow=False)
        panel.Add(ehi_wids)
        panel.Add(wids['show_fitrange'])

        panel.Add(HLine(panel, size=(625, 3)), dcol=5, newrow=True)
        add_text('Run Fit: ')
        panel.Add(wids['fit_group'], dcol=2)
        panel.Add(wids['fit_selected'], dcol=3)
        add_text('Fit Options: ')
        panel.Add(wids['sum_to_one'], dcol=2)
        panel.Add((10, 10), dcol=1, newrow=True)
        panel.Add(wids['all_combos'], dcol=2)
        add_text('Max # Components: ', newrow=False)
        panel.Add(max_ncomps, dcol=2)

        panel.Add(HLine(panel, size=(625, 3)), dcol=5, newrow=True)

        add_text('Components: ')
        panel.Add(wids['add_selected'], dcol=4)

        collabels = [' File /Group Name   ', 'weight', 'min', 'max']
        colsizes = [300, 80, 80, 80]
        coltypes = ['str', 'float:12,4', 'float:12,4', 'float:12,4']
        coldefs = ['', 1.0 / MAX_COMPONENTS, 0.0, 1.0]

        wids['table'] = DataTableGrid(panel,
                                      nrows=MAX_COMPONENTS,
                                      collabels=collabels,
                                      datatypes=coltypes,
                                      defaults=coldefs,
                                      colsizes=colsizes)

        wids['table'].SetMinSize((625, 250))
        panel.Add(wids['table'], newrow=True, dcol=6)

        panel.Add(HLine(panel, size=(625, 3)), dcol=5, newrow=True)
        panel.Add(wids['saveconf'], dcol=4, newrow=True)
        panel.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(panel, 1, LEFT, 3)
        pack(self, sizer)
        self.skip_process = False
Beispiel #12
0
    def build_display(self):
        titleopts = dict(font=Font(12), colour='#AA0000')
        panel = self.panel
        wids = self.wids
        self.skip_process = True

        wids['fitspace'] = Choice(panel,
                                  choices=FitSpace_Choices,
                                  size=(175, -1))
        wids['fitspace'].SetStringSelection(norm)
        wids['plotchoice'] = Choice(panel,
                                    choices=Plot_Choices,
                                    size=(175, -1),
                                    action=self.onPlot)
        wids['plotchoice'].SetSelection(1)

        add_text = self.add_text

        opts = dict(digits=2, increment=1.0, relative_e0=True)

        e0_wids = self.add_floatspin('e0', value=0, **opts)
        elo_wids = self.add_floatspin('elo', value=-20, **opts)
        ehi_wids = self.add_floatspin('ehi', value=30, **opts)

        wids['fit_group'] = Button(panel,
                                   'Fit this Group',
                                   size=(150, -1),
                                   action=self.onFitOne)
        wids['fit_selected'] = Button(panel,
                                      'Fit Selected Groups',
                                      size=(150, -1),
                                      action=self.onFitAll)

        wids['add_selected'] = Button(panel,
                                      'Use Selected Groups as Components',
                                      size=(250, -1),
                                      action=self.onUseSelected)

        wids['saveconf'] = Button(panel,
                                  'Save as Default Settings',
                                  size=(200, -1),
                                  action=self.onSaveConfigBtn)

        opts = dict(default=True, size=(75, -1), action=self.onPlotOne)

        wids['show_e0'] = Check(panel, label='show?', **opts)
        wids['show_fitrange'] = Check(panel, label='show?', **opts)

        wids['sum_to_one'] = Check(panel,
                                   label='Weights Must Sum to 1?',
                                   default=True)
        wids['all_combos'] = Check(panel,
                                   label='Fit All Combinations?',
                                   default=True)

        panel.Add(SimpleText(panel, ' Linear Combination Analysis',
                             **titleopts),
                  dcol=5)
        add_text('Run Fit', newrow=False)

        add_text('Array to Fit: ', newrow=True)
        panel.Add(wids['fitspace'], dcol=4)
        panel.Add(wids['fit_group'])

        add_text('Plot : ', newrow=True)
        panel.Add(wids['plotchoice'], dcol=4)
        panel.Add(wids['fit_selected'])

        add_text('E0: ')
        panel.Add(e0_wids, dcol=3)
        panel.Add(wids['show_e0'])

        add_text('Fit Energy Range: ')
        panel.Add(elo_wids)
        add_text(' : ', newrow=False)
        panel.Add(ehi_wids)
        panel.Add(wids['show_fitrange'])

        panel.Add(wids['sum_to_one'], dcol=2, newrow=True)
        panel.Add(wids['all_combos'], dcol=3)

        panel.Add(HLine(panel, size=(400, 2)), dcol=5, newrow=True)

        add_text('Components: ')
        panel.Add(wids['add_selected'], dcol=4)

        groupnames = [noname] + list(self.controller.file_groups.keys())
        sgrid = GridPanel(panel, nrows=6)

        sgrid.Add(SimpleText(sgrid, "#"))
        sgrid.Add(SimpleText(sgrid, "Group"))
        sgrid.Add(SimpleText(sgrid, "Weight"))
        sgrid.Add(SimpleText(sgrid, "Min Weight"))
        sgrid.Add(SimpleText(sgrid, "Max Weight"))

        fopts = dict(minval=-10, maxval=20, precision=4, size=(60, -1))
        for i in range(1, 1 + MAX_COMPONENTS):
            si = ("comp", "_%2.2d" % i)
            sgrid.Add(SimpleText(sgrid, "%2i" % i), newrow=True)
            wids['%schoice%s' % si] = Choice(sgrid,
                                             choices=groupnames,
                                             size=(200, -1),
                                             action=partial(self.onComponent,
                                                            comp=i))
            wids['%sval%s' % si] = FloatCtrl(sgrid, value=0, **fopts)
            wids['%smin%s' % si] = FloatCtrl(sgrid, value=0, **fopts)
            wids['%smax%s' % si] = FloatCtrl(sgrid, value=1, **fopts)
            for cname in ('choice', 'val', 'min', 'max'):
                sgrid.Add(wids[("%%s%s%%s" % cname) % si])
        sgrid.pack()
        panel.Add(sgrid, dcol=5, newrow=True)
        panel.Add(HLine(panel, size=(400, 2)), dcol=5, newrow=True)
        panel.Add(wids['saveconf'], dcol=4, newrow=True)
        panel.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel, 1, LCEN, 3)
        pack(self, sizer)
        self.skip_process = False
Beispiel #13
0
    def build(self):
        sizer = wx.GridBagSizer(10, 5)
        sizer.SetVGap(5)
        sizer.SetHGap(5)

        panel = scrolled.ScrolledPanel(self)
        self.SetMinSize((675, 600))
        self.colors = GUIColors()

        # title row
        self.wids = wids = {}
        title = SimpleText(panel,
                           'Linear Combination Results',
                           font=Font(12),
                           colour=self.colors.title,
                           style=LCEN)

        wids['plot_one'] = Button(panel,
                                  'Plot This Fit',
                                  size=(150, -1),
                                  action=self.onPlotOne)
        wids['plot_sel'] = Button(panel,
                                  'Plot top N Fits',
                                  size=(150, -1),
                                  action=self.onPlotSel)

        wids['plot_ntitle'] = SimpleText(panel, 'N fits to plot: ')

        wids['plot_nchoice'] = Choice(panel,
                                      size=(100, -1),
                                      choices=['%d' % i for i in range(1, 21)])
        wids['plot_nchoice'].SetStringSelection('5')

        wids['data_title'] = SimpleText(panel,
                                        '<--> ',
                                        font=Font(12),
                                        colour=self.colors.title,
                                        style=LCEN)
        wids['nfits_title'] = SimpleText(panel, 'showing top 5 fits')

        irow = 0
        sizer.Add(title, (irow, 0), (1, 2), LCEN)
        sizer.Add(wids['data_title'], (irow, 2), (1, 2), LCEN)

        irow += 1
        sizer.Add(wids['nfits_title'], (irow, 0), (1, 4), LCEN)

        irow += 1
        sizer.Add(self.wids['plot_one'], (irow, 0), (1, 1), LCEN)
        sizer.Add(self.wids['plot_sel'], (irow, 1), (1, 1), LCEN)
        sizer.Add(self.wids['plot_ntitle'], (irow, 2), (1, 1), LCEN)
        sizer.Add(self.wids['plot_nchoice'], (irow, 3), (1, 1), LCEN)

        irow += 1
        self.wids['paramstitle'] = SimpleText(panel,
                                              '[[Parameters]]',
                                              font=Font(12),
                                              colour=self.colors.title,
                                              style=LCEN)
        sizer.Add(self.wids['paramstitle'], (irow, 0), (1, 4), LCEN)

        pview = self.wids['params'] = dv.DataViewListCtrl(panel, style=DVSTYLE)
        pview.SetMinSize((675, 200))
        pview.AppendTextColumn(' Parameter ', width=250)
        pview.AppendTextColumn(' Best-Fit Value', width=150)
        pview.AppendTextColumn(' Uncertainty ', width=150)
        for col in range(3):
            this = pview.Columns[col]
            isort, align = True, wx.ALIGN_RIGHT
            if col == 0:
                align = wx.ALIGN_LEFT
            this.Sortable = isort
            this.Alignment = this.Renderer.Alignment = align

        irow += 1
        sizer.Add(self.wids['params'], (irow, 0), (1, 4), LCEN)

        irow += 1
        sizer.Add(HLine(panel, size=(675, 3)), (irow, 0), (1, 4), LCEN)

        sview = self.wids['stats'] = dv.DataViewListCtrl(panel, style=DVSTYLE)
        sview.Bind(dv.EVT_DATAVIEW_SELECTION_CHANGED, self.onSelectFitStat)
        sview.AppendTextColumn(' Fit #', width=50)
        sview.AppendTextColumn(' N_Vary', width=60)
        sview.AppendTextColumn(' N_Data', width=60)
        sview.AppendTextColumn(' N_eval', width=60)
        sview.AppendTextColumn(u' \u03c7\u00B2', width=100)
        sview.AppendTextColumn(u' \u03c7\u00B2_reduced', width=100)
        sview.AppendTextColumn(' Akaike Info', width=100)
        sview.AppendTextColumn(' Bayesian Info', width=100)

        for col in range(8):
            this = sview.Columns[col]
            isort, align = True, wx.ALIGN_RIGHT
            if col == 0:
                align = wx.ALIGN_CENTER
            this.Sortable = isort
            this.Alignment = this.Renderer.Alignment = align

        sview.SetMinSize((675, 175))

        irow += 1
        title = SimpleText(panel,
                           '[[Fit Statistics]]',
                           font=Font(12),
                           colour=self.colors.title,
                           style=LCEN)
        sizer.Add(title, (irow, 0), (1, 4), LCEN)

        irow += 1
        sizer.Add(sview, (irow, 0), (1, 4), LCEN)

        irow += 1
        sizer.Add(HLine(panel, size=(675, 3)), (irow, 0), (1, 4), LCEN)

        irow += 1
        title = SimpleText(panel,
                           '[[Weights]]',
                           font=Font(12),
                           colour=self.colors.title,
                           style=LCEN)
        sizer.Add(title, (irow, 0), (1, 4), LCEN)
        self.wids['weightspanel'] = ppan = wx.Panel(self)

        p1 = SimpleText(ppan, ' < Weights > ')
        os = wx.BoxSizer(wx.VERTICAL)
        os.Add(p1, 1, 3)
        pack(ppan, os)
        ppan.SetMinSize((675, 175))

        irow += 1
        sizer.Add(ppan, (irow, 0), (1, 4), LCEN)

        irow += 1
        sizer.Add(HLine(panel, size=(675, 3)), (irow, 0), (1, 4), LCEN)

        pack(panel, sizer)
        panel.SetupScrolling()

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 1, wx.GROW | wx.ALL, 1)

        pack(self, mainsizer)
        self.Show()
        self.Raise()
Beispiel #14
0
    def build_display(self):
        self.mod_nb = flatnotebook(self, {})
        pan = self.panel = GridPanel(self, ncols=4, nrows=4, pad=2, itemstyle=LEFT)

        self.wids = {}

        fsopts = dict(digits=2, increment=0.1, with_pin=True)
        ppeak_e0   = self.add_floatspin('ppeak_e0', value=0, **fsopts)
        ppeak_elo  = self.add_floatspin('ppeak_elo', value=-15, **fsopts)
        ppeak_ehi  = self.add_floatspin('ppeak_ehi', value=-5, **fsopts)
        ppeak_emin = self.add_floatspin('ppeak_emin', value=-30, **fsopts)
        ppeak_emax = self.add_floatspin('ppeak_emax', value=0, **fsopts)

        self.fitbline_btn  = Button(pan,'Fit Baseline', action=self.onFitBaseline,
                                    size=(125, -1))
        self.plotmodel_btn = Button(pan, 'Plot Model',
                                   action=self.onPlotModel,  size=(125, -1))
        self.fitmodel_btn = Button(pan, 'Fit Model',
                                   action=self.onFitModel,  size=(125, -1))
        self.loadmodel_btn = Button(pan, 'Load Model',
                                    action=self.onLoadFitResult,  size=(125, -1))
        self.fitmodel_btn.Disable()

        self.array_choice = Choice(pan, size=(175, -1),
                                   choices=list(Array_Choices.keys()))
        self.array_choice.SetSelection(1)

        models_peaks = Choice(pan, size=(150, -1),
                              choices=ModelChoices['peaks'],
                              action=self.addModel)

        models_other = Choice(pan, size=(150, -1),
                              choices=ModelChoices['other'],
                              action=self.addModel)

        self.models_peaks = models_peaks
        self.models_other = models_other


        self.message = SimpleText(pan,
                                 'first fit baseline, then add peaks to fit model.')

        self.msg_centroid = SimpleText(pan, '----')

        opts = dict(default=True, size=(75, -1), action=self.onPlot)
        self.show_centroid  = Check(pan, label='show?', **opts)
        self.show_peakrange = Check(pan, label='show?', **opts)
        self.show_fitrange  = Check(pan, label='show?', **opts)
        self.show_e0        = Check(pan, label='show?', **opts)

        opts = dict(default=False, size=(200, -1), action=self.onPlot)

        def add_text(text, dcol=1, newrow=True):
            pan.Add(SimpleText(pan, text), dcol=dcol, newrow=newrow)

        pan.Add(SimpleText(pan, ' Pre-edge Peak Fitting',
                           **self.titleopts), dcol=5)
        add_text(' Run Fit:', newrow=False)

        add_text('Array to fit: ')
        pan.Add(self.array_choice, dcol=3)
        pan.Add((10, 10))
        pan.Add(self.fitbline_btn)

        add_text('E0: ')
        pan.Add(ppeak_e0)
        pan.Add((10, 10), dcol=2)
        pan.Add(self.show_e0)
        pan.Add(self.plotmodel_btn)


        add_text('Fit Energy Range: ')
        pan.Add(ppeak_emin)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_emax)
        pan.Add(self.show_fitrange)
        pan.Add(self.fitmodel_btn)

        t = SimpleText(pan, 'Pre-edge Peak Range: ')
        SetTip(t, 'Range used as mask for background')

        pan.Add(t, newrow=True)
        pan.Add(ppeak_elo)
        add_text(' : ', newrow=False)
        pan.Add(ppeak_ehi)
        pan.Add(self.show_peakrange)


        # pan.Add(self.fitsel_btn)

        add_text( 'Peak Centroid: ')
        pan.Add(self.msg_centroid, dcol=3)
        pan.Add(self.show_centroid, dcol=1)
        pan.Add(self.loadmodel_btn)

        #  add model
        ts = wx.BoxSizer(wx.HORIZONTAL)
        ts.Add(models_peaks)
        ts.Add(models_other)

        pan.Add(SimpleText(pan, 'Add Component: '), newrow=True)
        pan.Add(ts, dcol=7)

        pan.Add(SimpleText(pan, 'Messages: '), newrow=True)
        pan.Add(self.message, dcol=7)

        pan.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(pan, 0, LEFT, 3)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LEFT, 3)
        sizer.Add((10, 10), 0, LEFT, 3)
        sizer.Add(self.mod_nb,  1, LEFT|wx.GROW, 10)

        pack(self, sizer)
Beispiel #15
0
 def CopyBtn(name):
     return Button(panel,
                   'Copy',
                   size=(60, -1),
                   action=partial(self.onCopyParam, name))
Beispiel #16
0
    def build_display(self):
        titleopts = dict(font=Font(12), colour='#AA0000')

        xas = self.panel
        self.wids = {}

        self.plotone_op = Choice(xas,
                                 choices=list(PlotOne_Choices.keys()),
                                 action=self.onPlotOne,
                                 size=(175, -1))
        self.plotsel_op = Choice(xas,
                                 choices=list(PlotSel_Choices.keys()),
                                 action=self.onPlotSel,
                                 size=(175, -1))

        self.plotone_op.SetSelection(1)
        self.plotsel_op.SetSelection(1)

        plot_one = Button(xas,
                          'Plot This Group',
                          size=(150, -1),
                          action=self.onPlotOne)

        plot_sel = Button(xas,
                          'Plot Selected Groups',
                          size=(150, -1),
                          action=self.onPlotSel)

        opts = dict(action=self.onReprocess)

        e0opts_panel = wx.Panel(xas)
        self.wids['autoe0'] = Check(e0opts_panel,
                                    default=True,
                                    label='auto?',
                                    **opts)
        self.wids['showe0'] = Check(e0opts_panel,
                                    default=True,
                                    label='show?',
                                    **opts)
        sx = wx.BoxSizer(wx.HORIZONTAL)
        sx.Add(self.wids['autoe0'], 0, LCEN, 4)
        sx.Add(self.wids['showe0'], 0, LCEN, 4)
        pack(e0opts_panel, sx)

        self.wids['autostep'] = Check(xas, default=True, label='auto?', **opts)

        opts['size'] = (50, -1)
        self.wids['vict'] = Choice(xas, choices=('0', '1', '2', '3'), **opts)
        self.wids['nnor'] = Choice(xas, choices=('0', '1', '2', '3'), **opts)
        self.wids['vict'].SetSelection(1)
        self.wids['nnor'].SetSelection(1)

        opts.update({'size': (100, -1), 'digits': 2, 'increment': 5.0})

        xas_pre1 = self.add_floatspin('pre1', value=-1000, **opts)
        xas_pre2 = self.add_floatspin('pre2', value=-30, **opts)
        xas_nor1 = self.add_floatspin('nor1', value=50, **opts)
        xas_nor2 = self.add_floatspin('nor2', value=5000, **opts)

        opts = {'digits': 2, 'increment': 0.1, 'value': 0}
        xas_e0 = self.add_floatspin('e0', action=self.onSet_XASE0, **opts)
        xas_step = self.add_floatspin('step',
                                      action=self.onSet_XASStep,
                                      with_pin=False,
                                      **opts)

        saveconf = Button(xas,
                          'Save as Default Settings',
                          size=(200, -1),
                          action=self.onSaveConfigBtn)

        def CopyBtn(name):
            return Button(xas,
                          'Copy',
                          size=(50, -1),
                          action=partial(self.onCopyParam, name))

        add_text = self.add_text

        xas.Add(SimpleText(xas, ' XAS Pre-edge subtraction and Normalization',
                           **titleopts),
                dcol=4)
        xas.Add(SimpleText(xas, 'Copy to Selected Groups?'),
                style=RCEN,
                dcol=3)

        xas.Add(plot_sel, newrow=True)
        xas.Add(self.plotsel_op, dcol=6)

        xas.Add(plot_one, newrow=True)
        xas.Add(self.plotone_op, dcol=4)
        xas.Add((10, 10))
        xas.Add(CopyBtn('plotone_op'), style=RCEN)

        add_text('E0 : ')
        xas.Add(xas_e0)
        xas.Add(e0opts_panel, dcol=3)
        xas.Add((10, 1))
        xas.Add(CopyBtn('xas_e0'), style=RCEN)

        add_text('Edge Step: ')
        xas.Add(xas_step)
        xas.Add(self.wids['autostep'], dcol=3)
        xas.Add((10, 1))
        xas.Add(CopyBtn('xas_step'), style=RCEN)

        add_text('Pre-edge range: ')
        xas.Add(xas_pre1)
        add_text(' : ', newrow=False)
        xas.Add(xas_pre2)
        xas.Add(SimpleText(xas, 'Victoreen:'))
        xas.Add(self.wids['vict'])
        xas.Add(CopyBtn('xas_pre'), style=RCEN)

        add_text('Normalization range: ')
        xas.Add(xas_nor1)
        add_text(' : ', newrow=False)
        xas.Add(xas_nor2)
        xas.Add(SimpleText(xas, 'Poly Order:'))
        xas.Add(self.wids['nnor'])
        xas.Add(CopyBtn('xas_norm'), style=RCEN)

        xas.Add(saveconf, dcol=6, newrow=True)
        xas.pack()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((5, 5), 0, LCEN, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LCEN, 3)
        sizer.Add(xas, 0, LCEN, 3)
        sizer.Add((5, 5), 0, LCEN, 3)
        sizer.Add(HLine(self, size=(550, 2)), 0, LCEN, 3)
        pack(self, sizer)
Beispiel #17
0
 def Btn(msg, x, act):
     b = Button(ltop, msg, size=(x, 30), action=act)
     b.SetFont(Font(FONTSIZE))
     return b
Beispiel #18
0
    def build(self):
        sizer = wx.GridBagSizer(10, 5)
        sizer.SetVGap(5)
        sizer.SetHGap(5)

        panel = scrolled.ScrolledPanel(self)
        self.SetMinSize((700, 450))
        self.colors = GUIColors()

        # title row
        self.wids = wids = {}
        title = SimpleText(panel, 'Fit Results', font=Font(FONTSIZE+2),
                           colour=self.colors.title, style=LEFT)

        wids['data_title'] = SimpleText(panel, '< > ', font=Font(FONTSIZE+2),
                                             colour=self.colors.title, style=LEFT)

        wids['hist_info'] = SimpleText(panel, ' ___ ', font=Font(FONTSIZE+2),
                                       colour=self.colors.title, style=LEFT)

        wids['hist_hint'] = SimpleText(panel, '  (Fit #01 is most recent)',
                                       font=Font(FONTSIZE+2), colour=self.colors.title,
                                       style=LEFT)

        opts = dict(default=False, size=(200, -1), action=self.onPlot)
        wids['plot_bline'] = Check(panel, label='Plot baseline-subtracted?', **opts)
        wids['plot_resid'] = Check(panel, label='Plot with residual?', **opts)
        self.plot_choice = Button(panel, 'Plot Selected Fit',
                                  size=(175, -1), action=self.onPlot)


        self.save_result = Button(panel, 'Save Selected Model',
                                  size=(175, -1), action=self.onSaveFitResult)
        SetTip(self.save_result, 'save model and result to be loaded later')

        self.export_fit  = Button(panel, 'Export Fit',
                                  size=(175, -1), action=self.onExportFitResult)
        SetTip(self.export_fit, 'save arrays and results to text file')

        irow = 0
        sizer.Add(title,              (irow, 0), (1, 2), LEFT)
        sizer.Add(wids['data_title'], (irow, 2), (1, 2), LEFT)

        irow += 1
        sizer.Add(wids['hist_info'],  (irow, 0), (1, 2), LEFT)
        sizer.Add(wids['hist_hint'],  (irow, 2), (1, 2), LEFT)

        irow += 1
        wids['model_desc'] = SimpleText(panel, '<Model>', font=Font(FONTSIZE+1),
                                        size=(700, 50), style=LEFT)
        sizer.Add(wids['model_desc'],  (irow, 0), (1, 6), LEFT)

        irow += 1
        sizer.Add(self.save_result, (irow, 0), (1, 1), LEFT)
        sizer.Add(self.export_fit,  (irow, 1), (1, 2), LEFT)

        irow += 1
        # sizer.Add(SimpleText(panel, 'Plot: '), (irow, 0), (1, 1), LEFT)
        sizer.Add(self.plot_choice,   (irow, 0), (1, 2), LEFT)
        sizer.Add(wids['plot_bline'], (irow, 2), (1, 1), LEFT)
        sizer.Add(wids['plot_resid'], (irow, 3), (1, 1), LEFT)

        irow += 1
        sizer.Add(HLine(panel, size=(650, 3)), (irow, 0), (1, 5), LEFT)

        irow += 1
        title = SimpleText(panel, '[[Fit Statistics]]',  font=Font(FONTSIZE+2),
                           colour=self.colors.title, style=LEFT)
        sizer.Add(title, (irow, 0), (1, 4), LEFT)

        sview = self.wids['stats'] = dv.DataViewListCtrl(panel, style=DVSTYLE)
        sview.Bind(dv.EVT_DATAVIEW_SELECTION_CHANGED, self.onSelectFit)
        sview.AppendTextColumn(' Fit #',  width=50)
        sview.AppendTextColumn(' N_data', width=50)
        sview.AppendTextColumn(' N_vary', width=50)
        sview.AppendTextColumn(' N_eval', width=60)
        sview.AppendTextColumn(' \u03c7\u00B2', width=110)
        sview.AppendTextColumn(' \u03c7\u00B2_reduced', width=110)
        sview.AppendTextColumn(' Akaike Info', width=110)
        sview.AppendTextColumn(' Bayesian Info', width=110)

        for col in range(sview.ColumnCount):
            this = sview.Columns[col]
            isort, align = True, wx.ALIGN_RIGHT
            if col == 0:
                align = wx.ALIGN_CENTER
            this.Sortable = isort
            this.Alignment = this.Renderer.Alignment = align
        sview.SetMinSize((700, 125))

        irow += 1
        sizer.Add(sview, (irow, 0), (1, 5), LEFT)

        irow += 1
        sizer.Add(HLine(panel, size=(650, 3)), (irow, 0), (1, 5), LEFT)

        irow += 1
        title = SimpleText(panel, '[[Variables]]',  font=Font(FONTSIZE+2),
                           colour=self.colors.title, style=LEFT)
        sizer.Add(title, (irow, 0), (1, 1), LEFT)

        self.wids['copy_params'] = Button(panel, 'Update Model with these values',
                                          size=(250, -1), action=self.onCopyParams)

        sizer.Add(self.wids['copy_params'], (irow, 1), (1, 3), LEFT)

        pview = self.wids['params'] = dv.DataViewListCtrl(panel, style=DVSTYLE)
        self.wids['paramsdata'] = []
        pview.AppendTextColumn('Parameter',         width=150)
        pview.AppendTextColumn('Best-Fit Value',    width=125)
        pview.AppendTextColumn('Standard Error',    width=125)
        pview.AppendTextColumn('Info ',             width=275)

        for col in range(4):
            this = pview.Columns[col]
            align = wx.ALIGN_LEFT
            if col in (1, 2):
                align = wx.ALIGN_RIGHT
            this.Sortable = False
            this.Alignment = this.Renderer.Alignment = align

        pview.SetMinSize((700, 200))
        pview.Bind(dv.EVT_DATAVIEW_SELECTION_CHANGED, self.onSelectParameter)

        irow += 1
        sizer.Add(pview, (irow, 0), (1, 5), LEFT)

        irow += 1
        sizer.Add(HLine(panel, size=(650, 3)), (irow, 0), (1, 5), LEFT)

        irow += 1
        title = SimpleText(panel, '[[Correlations]]',  font=Font(FONTSIZE+2),
                           colour=self.colors.title, style=LEFT)

        self.wids['all_correl'] = Button(panel, 'Show All',
                                          size=(100, -1), action=self.onAllCorrel)

        self.wids['min_correl'] = FloatSpin(panel, value=MIN_CORREL,
                                            min_val=0, size=(100, -1),
                                            digits=3, increment=0.1)

        ctitle = SimpleText(panel, 'minimum correlation: ')
        sizer.Add(title,  (irow, 0), (1, 1), LEFT)
        sizer.Add(ctitle, (irow, 1), (1, 1), LEFT)
        sizer.Add(self.wids['min_correl'], (irow, 2), (1, 1), LEFT)
        sizer.Add(self.wids['all_correl'], (irow, 3), (1, 1), LEFT)

        irow += 1

        cview = self.wids['correl'] = dv.DataViewListCtrl(panel, style=DVSTYLE)

        cview.AppendTextColumn('Parameter 1',    width=150)
        cview.AppendTextColumn('Parameter 2',    width=150)
        cview.AppendTextColumn('Correlation',    width=150)

        for col in (0, 1, 2):
            this = cview.Columns[col]
            this.Sortable = False
            align = wx.ALIGN_LEFT
            if col == 2:
                align = wx.ALIGN_RIGHT
            this.Alignment = this.Renderer.Alignment = align
        cview.SetMinSize((475, 200))

        irow += 1
        sizer.Add(cview, (irow, 0), (1, 5), LEFT)
        irow += 1
        sizer.Add(HLine(panel, size=(400, 3)), (irow, 0), (1, 5), LEFT)

        pack(panel, sizer)
        panel.SetupScrolling()

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        mainsizer.Add(panel, 1, wx.GROW|wx.ALL, 1)

        pack(self, mainsizer)
        self.Show()
        self.Raise()