Ejemplo n.º 1
0
 def chooseplot(self, plot_range):
     '''
         switch for single (A1), sequential (B1),
         ... 
     #       multi_groups suite.single userpars multigroup_in_components userlocals
     # A1     False          True        False       False               False *
     # A20    True           True        False       False               False
     # A21    True           True        True        True                False *
     # B1     False          False       False       False               False
     # B20    True           False       False       False               False does not exist
     # B21    True           False       True        True                False
     # C1     False          False       True        False               True  *
     # C2     True           False       True        True                True  *
     '''
     from mujpy.aux.aux import multigroup_in_components, userpars, userlocals
     if self.suite.single():  # A1, A20, A21
         if self.suite.multi_groups():  # A20 A21
             self.suite.console(
                 'Multigroup fit animation: toggle pause/resume by clicking on the plot'
             )
             if sum(multigroup_in_components(self.dashboard)):  # A21
                 ok = self.plot_singlerun_multigroup_userpar(plot_range)
             else:  # A20
                 ok = self.plot_singlerun_multigroup_sequential(plot_range)
         else:  # A1
             ok = self.plot_singlerun(plot_range)
     else:  # B1, B2, C1, C2, no calib in this lot
         self.suite.console(
             'Multirun fit animation: toggle pause/resume by clicking on the plot'
         )
         if self.suite.multi_groups():  # B2, C2
             self.suite.console(
                 'No B2, C2 yet. Exiting mufitplot without a plot')
             if userlocals(self.dashboard):  # C2
                 pass
             else:  # B2 (means B21 group global, B20 group sequential does not exist)
                 pass
         else:  # B1, C1
             if userpars(self.dashboard):  # C1
                 self.suite.console(
                     'No B2, C2 yet. Exiting mufitplot without a plot')
                 pass
             else:  # B1
                 ok = self.plot_multirun_singlegroup_sequential(plot_range)
     if not ok:
         self.suite.console('Exiting mufitplot without a plot')
Ejemplo n.º 2
0
 def single_chi(self):
     '''
     output:
         True if chi_1 is required (single cost function)
         False if chi_2 is required (multi cost finctions)
     '''
     #       multi_groups suite.single userpars multigroup_in_components userlocals
     # A1     False          True        False       False               False *
     # A20    True           True        False       False               False
     # A21    True           True        True        True                False *
     # B1     False          False       False       False               False
     # B20    True           False       False       False               False
     # B21    True           False       True        True                False
     # C1     False          False       True        False               True  *
     # C2     True           False       True        True                True  *
     #  True : A1 1d, A21 2d multigroup userpar, C1 2d userpar, C2 3d multgrup userpar
     #  False: B1 2d, A20, B20 2d multigroup, B21 2d multigroup userpar
     from mujpy.aux.aux import userlocals, userpars
     return (userlocals(self.dashboard)
             or (self.suite.single() and
                 (not self.multigroup or userpars(self.dashboard))))
Ejemplo n.º 3
0
    def plot_fft(self, fft_range, pars, asymm, asyme, real):
        '''
        input:
            fft_range
                start,stop,sigma MHz
            pars list (single, calib) or list of lists (sequence)
            asymm, asyme  1d (single, calib) or 2d (sequence)
        uses data as dictated by self.dashboard["fit_range"]
        
        calls either 
            self.chi_fft (only for model function) 
            set_single_fft or set_sequence_fft, from aux.plot
            first version single only
                                    (produces actual figures
                                     using aux.plot functions)
        '''
        from mujpy.aux.aux import derange, rebin, autops, ps
        from mujpy.aux.aux import get_run_title, userpars
        from mujpy.aux.plot import set_figure_fft
        from copy import deepcopy
        from numpy import ones, exp, linspace, sqrt, mean, fft
        from numpy import hstack, linspace, zeros, mgrid

        # print('plot_fft muplotfit debug: pars = {}'.format(pars))

        run_title = get_run_title(self.suite)  # always a list, even for single
        string = 'global ' if userpars(self.dashboard) else ''
        if len(self.suite.groups) > 1:
            strgrps = [
                groups['forward'] + '-' + groups['backward']
                for groups in self.suite.groups
            ]
        else:
            strgrps = self.suite.groups['forward'] + '-' + self.suite.groups[
                'backward']
        if self.guess:
            if len(run_title) == len(self.suite.groups):
                run_title = [
                    runtitle + " (" + string + "guess) group" + strgrp
                    for runtitle, strgrp in zip(run_title, strgrps)
                ]
            else:
                run_title = [
                    runtitle + " (" + string + "guess)"
                    for runtitle in run_title
                ]
        else:
            if len(run_title) == len(self.suite.groups):
                run_title = [
                    runtitle + " (" + string + "fit) group" + strgrp
                    for runtitle, strgrp in zip(run_title, strgrps)
                ]
            else:
                run_title = [
                    runtitle + " (" + string + "fit)" for runtitle in run_title
                ]
        #############################
        # rebinning of data as in fit
        # this works for single
        # and for sequential
        #############################
        fittup = derange(self.dashboard["fit_range"],
                         self.suite.histoLength)  # range as tuple
        fit_pack = 1
        if len(fittup) == 3:  # plot start stop pack
            fit_start, fit_stop, fit_pack = fittup[0], fittup[1], fittup[2]
        elif len(fittup) == 2:  # plot start stop
            fit_start, fit_stop = fittup[0], fittup[1]

        t_fit, y_fit, ey_fit = rebin(self.suite.time,
                                     asymm, [fit_start, fit_stop],
                                     fit_pack,
                                     e=asyme)

        f_fit_res, f_fit = self.chi_fft(
            t_fit, y_fit, *pars)  # returns both partial and full model

        fgroup = [
            self.suite.groups[k]['forward']
            for k in range(len(self.suite.groups))
        ]
        bgroup = [
            self.suite.groups[k]['backward']
            for k in range(len(self.suite.groups))
        ]
        alpha = [
            self.suite.groups[k]['alpha']
            for k in range(len(self.suite.groups))
        ]
        group = [fgroup, bgroup, alpha]

        dt = t_fit[1] - t_fit[0]  # time bin
        fmax = 0.5 / dt  # max frequancy available
        l = (fit_stop -
             fit_start) // fit_pack  # floor division, dimension of data
        df = 1 / (dt * l)
        n = 2 * l  # not a power of 2, but surely even
        nf = hstack((linspace(0, l, l + 1,
                              dtype=int), linspace(-l + 1,
                                                   -1,
                                                   l - 2,
                                                   dtype=int)))
        dfa = 1 / n / dt  # digital frequency resolution
        f = nf * dfa  # all frequencies, l+1 >=0 followed by l-1 <0

        fstart, fstop, fsigma = float(fft_range[0]), float(
            fft_range[1]), float(fft_range[2])
        start, stop = int(round(fstart / dfa)), int(round(fstop / dfa))
        f = deepcopy(f[start:stop])  # selected slice

        # asymmetry has 1,2,3 dimensions to distinguish run from group
        # here they are on same par: the data are reshaped into a 2 d array
        if len(asymm.shape) == 1:
            y = zeros(n)  # for data zero padded to n
            yf = zeros(n)  # fit function for rephasing, zero padded to n
            ey = zeros(n)
            y[0:l] = y_fit[
                fit_start:fit_stop] - f_fit_res  # zero padded partial residues
            yf[0:l] = f_fit
            ey[0:l] = ey_fit[fit_start:fit_stop]  #  slice of time stds
            t = dt * linspace(0, n - 1, n)
        elif len(asymm.shape) == 2:
            # print('mufitplot plot_fft debug: nruns/ngroups {}, nbins {}'.format(asymm.shape[0],y_fit.shape[-1]))
            y = zeros((y_fit.shape[0], n))  # for data zero padded to n
            yf = zeros((y_fit.shape[0],
                        n))  # fit function for rephasing, zero padded to n
            ey = zeros((ey_fit.shape[0], n))
            # print('mufitplot plot_fft debug: shapes y {}, asymm {}, f_fit_res {}'.format(y[:,0:l].shape,y_fit[:,fit_start:fit_stop].shape,f_fit_res.shape))
            y[:, 0:
              l] = y_fit[:, fit_start:
                         fit_stop] - f_fit_res  # zero padded partial residues
            yf[:, 0:l] = f_fit
            ey[:, 0:l] = ey_fit[:, fit_start:fit_stop]  #  slice of time stds
            _, t = dt * mgrid[0:asymm.shape[0], 0:n]
        else:  # 3 is reshaped to 2d
            nruns, ngroups = asymm.shape[0], asymm.shape[1]
            y = zeros((nruns * ngroups, n))  # for data zero padded to n
            yf = zeros((nruns * ngroups,
                        n))  # fit function for rephasing, zero padded to n
            ey = zeros((nruns * ngroups, n))
            y[:, :, 0:
              l] = y_fit[:, :, fit_start:
                         fit_stop] - f_fit_res  # zero padded partial residues
            yf[:, :, 0:l] = f_fit  # zero padded full fit function
            ey[:, :, 0:l] = ey_fit[:, :,
                                   fit_start:fit_stop]  #  slice of time stds
            y = y.reshape(nruns * ngroups, n)  # reshaped to 2d
            yf = yf.reshape(nruns * ngroups, n)  # reshaped to 2d
            ey = ey.reshape(nruns * ngroups, n)  # reshaped to 2d
            _, t = dt * mgrid[0:nruns * ngroups,
                              0:n]  # time for zero padded data
        # print('mufitplot plot_fft debug: t.min t.max = {},{}'.format(t.min(),t.max()))
        filter_apo = exp(-(t * fsigma)**3)  # hypergaussian filter mask
        # is applied as if first good bin were t=0
        filter_apo = filter_apo / filter_apo.sum(
            axis=1)[0] / dt  # approx normalization
        dfa = 1 / n / dt  # digital frequency resolution
        y *= filter_apo  # zero padded, filtered partial residues
        yf *= filter_apo  # zero padded, filtered full fit function
        ey *= filter_apo  # filteres
        fft_e = (
            sqrt(mean(fft.fft(ey)**2, axis=-1))
        ).real  #.reshape(ey.shape[0],1)*ones(y.shape) # one per asymmetry
        fft_amplitude = fft.fft(
            y)  # amplitudes (complex), matrix with rows fft of each run
        fftf_amplitude = fft.fft(
            yf)  # amplitudes (complex), same for fit function
        if real:
            ########################
            # REAL PART
            # APPLY PHASE CORRECTION
            # try acme
            ########################
            if len(y_fit.shape) == 1:
                fftf_amplitude[start:stop], p0, p1, out = autops(
                    fftf_amplitude[start:stop], 'acme')  # fix phase on theory
                out = out[:out.index('\n')]
                self.suite.console('Autophase: ' + out)
                fft_amplitude[start:stop] = ps(fft_amplitude[start:stop],
                                               p0=p0,
                                               p1=p1).real
                ap = deepcopy(fft_amplitude[start:stop].real)
                apf = deepcopy(fftf_amplitude[start:stop].real)
            else:
                for k in range(fftf_amplitude.shape[0]):
                    fftf_amplitude[k, start:stop], p0, p1, out = autops(
                        fftf_amplitude[k, start:stop],
                        'acme')  # fix phase on theory
                    out = out[:out.index('\n')]
                    self.suite.console('Autophase {}: '.format(k) + out)
                    # fft_amplitude[k,start:stop], p0, p1, out = autops(fft_amplitude[k,start:stop],'acme') # fix phase on theory
                    fft_amplitude[k,
                                  start:stop] = ps(
                                      fft_amplitude[k, start:stop],
                                      p0=p0,
                                      p1=p1).real  # same correction as theory
                ap = deepcopy(fft_amplitude[:, start:stop].real)
                apf = deepcopy(fftf_amplitude[:, start:stop].real)
            ylabel = 'FFT Real part [arb. units]'
        else:
            ##################
            # POWER
            ##################
            if len(asymm.shape) == 1:
                ap = fft_amplitude.real[start:stop]**2 + fft_amplitude.imag[
                    start:stop]**2
                apf = fftf_amplitude.real[start:stop]**2 + fftf_amplitude.imag[
                    start:stop]**2
            else:
                ap = fft_amplitude.real[:, start:
                                        stop]**2 + fft_amplitude.imag[:, start:
                                                                      stop]**2
                apf = fftf_amplitude.real[:, start:
                                          stop]**2 + fftf_amplitude.imag[:,
                                                                         start:
                                                                         stop]**2
            ylabel = 'FFT Power [arb. units]'
        self.fig_fft = set_figure_fft(self.fig_fft, self.model_name(), ylabel,
                                      f, ap, apf, fft_e, group, run_title)
Ejemplo n.º 4
0
    def choosefftplot(self, fft_range, real):
        '''
        distinguishes  
          single-multi run
          single-multi group
          sequential-global  
        '''
        from mujpy.aux.aux import multigroup_in_components, userlocals
        from mujpy.aux.aux import get_nruns, int2min, int2min_multigroup
        from numpy import array

        # single - multi run sequential  A1 B1 both produce list of pars
        # single - multi group sequential A1 A20 both produce list of pars
        # multi run sequential multi group global B2 produces list of pars
        # multi group global A21 produces par
        # multi run global C1 produces par
        # multi run multi group global C2 produces par
        if self.suite.single():
            if self.suite.multi_groups():  # A2
                # print('mufitplot choosefftplot debug: A2')
                self.suite.console(
                    'Multigroup fft animation: toggle pause/resume by clicking on the plot'
                )
                if sum(multigroup_in_components(
                        self.dashboard)):  # A21 single chi2
                    userpars = "userpardicts_guess" if self.guess else "userpardicts_results"
                    pardicts = self.dashboard[userpars]
                    pars, _, _, _, _ = int2min_multigroup(pardicts)
                    # ok = self.single_fft_plot_multi_global(fft_range,pars,real)
                else:  # A20 as many chi2 as groups now results are saved in single group dashboards
                    if self.model == "model_result":
                        pars = [
                            array(lastfit.values) for lastfit in self.lastfits
                        ]
                        # print('mufitplot choosefftplot debug: A20 fit pars = {}'.format(pars))
                    else:
                        par, _, _, _, _ = int2min(self.dashboard[self.model])
                        pars = [
                            array(par) for k in range(len(self.suite.groups))
                        ]
                        # print('mufitplot choosefftplot debug: A20 guess pars = {}'.format(pars))
                    # ok = self.single_fft_plot_multi_sequential(fft_range,pars,real)
                asymm, asyme = self.suite.asymmetry_multigroup()
            else:  # A1 simple single plot
                pars, _, _, _, _ = int2min(self.dashboard[self.model])
                # ok = self.single_fft_plot(fft_range,pars,real)
                asymm, asyme = self.suite.asymmetry_single(
                    self.suite._the_runs_[0], 0)
        else:
            if userpars(self.dashboard):
                if not self.suite.multi_groups(
                ):  # C1, userpardicts no multigroup
                    self.suite.console(
                        'Multirun fft animation: toggle pause/resume by clicking on the plot'
                    )
                    pass  # not yet
                else:
                    self.suite.console(
                        'Multi group and run fft animation: toggle pause/resume by clicking on the plot'
                    )
                    if userlocals(self.dashboard):  # C2
                        pass  # not yet
                    else:  # B21 userpardicts, multigroup_in_components no tilde_incomponents
                        pars = []
                        # not yet
#                        for run in get_nruns(self.suite):
#                            par =
#                            pars.append(par)
            else:
                pars = []
                if self.suite.multi_groups():
                    for run in get_nruns(self.suite):  # B1 no multigroup
                        for group in self.suite.groups:  # or B20 no userpardicts multigroup
                            par, _, _, _, _ = int2min(
                                self.dashboard[self.model])
                            pars.append(par)
                            asymm, asyme = self.suite.asymmetry_multirun_multigroup(
                            )
                else:
                    for run in get_nruns(self.suite):  # B1 no multigroup
                        par, _, _, _, _ = int2min(self.dashboard[self.model])
                        pars.append(par)
                    asymm, asyme = self.suite.asymmetry_multirun(0)
                # ok = self.sequential_fft_plot(fft_rangepars,real)

        # print('mufitplot choosefftplot debug: pars = {}'.format(pars))
        self.plot_fft(fft_range, pars, asymm, asyme, real)
Ejemplo n.º 5
0
    def plot_run(self, plot_range, pars, asymm, asyme):
        '''
        input :
            plot_range
                (start,stop)
                (start,stop,pack)
                (start_early,stop_early,pack_early,stop_late,pack_late)
            pars list (single, calib) or list of lists (sequence)
            asymm, asyme  1d (single, calib) or 2d (sequence)
        calls either 
            self.chi_1 or self.chi_2 (stats and model function, 
                                      deals also with plotting model function)
            set_single_fit or set_sequence_fit, from aux.plot
                                    (produces actual figures)
        Draws either static or anim figures using aux.plot functions 
        '''
        from mujpy.aux.aux import derange, rebin, multigroup_in_components
        from mujpy.aux.aux import get_run_title, userpars, mixer
        from mujpy.aux.plot import set_single_fit, set_sequence_fit
        from iminuit import Minuit
        from numpy import ones

        # print('plot_run muplotfit debug: pars = {}'.format(pars))
        # chi_1: single chisquare, different asymm.shape,
        # chi_2: many chisquare, different asymm.shape,
        chi = self.chi_1 if self.single_chi() else self.chi_2
        # print('plot_run mufitplot debug: single chi is {}'.format(self.single_chi()))

        run_title = get_run_title(self.suite)  # always a list, even for single
        string = 'global ' if userpars(self.dashboard) else ''

        if self.guess:
            run_title = [
                title + ": " + string + "guess values" for title in run_title
            ]
        else:
            run_title = [
                title + ": " + string + "fit results" for title in run_title
            ]
        plottup = derange(plot_range, self.suite.histoLength)
        #############################
        # rebinning of data as in fit
        # this works for single
        # and for sequential
        #############################
        fittup = derange(self.dashboard["fit_range"],
                         self.suite.histoLength)  # range as tuple
        fit_pack = 1
        if len(fittup) == 3:  # plot start stop pack
            fit_start, fit_stop, fit_pack = fittup[0], fittup[1], fittup[2]
        elif len(fittup) == 2:  # plot start stop
            fit_start, fit_stop = fittup[0], fittup[1]

        # load modules and reproduce fit
        t_fit, y_fit, ey_fit = rebin(self.suite.time,
                                     asymm, [fit_start, fit_stop],
                                     fit_pack,
                                     e=asyme)
        # single slices as in fit
        # print('muplotfit plot_run debug: calling chi for f_fit')
        nu_fit, f_fit, chi_fit = chi(t_fit, y_fit, ey_fit, pars)
        if self.rotating_frame_frequencyMHz:  # (t_fit,y_fit,f_fit,ey_fit) the last three must be transformed to rrf
            _, y_fit, ey_fit = rebin(self.suite.time,
                                     self.rrf_asymm, [fit_start, fit_stop],
                                     fit_pack,
                                     e=self.rrf_asyme)
            f_fit = mixer(t_fit, f_fit, self.rotating_frame_frequencyMHz)
        if not nu_fit:
            return False
        # function as in fit

        if len(plottup) == 5:
            ###################
            # double range plot
            ###################
            early_late = True
            start, stop, pack, last, packlate = plottup

            t_late, y_late, ey_late = rebin(self.suite.time,
                                            asymm, [stop, last],
                                            packlate,
                                            e=asyme)
            # rebinned late slices
            packfit = int(packlate / 2)
            tfl, dum = rebin(self.suite.time, asymm, [stop, last], packfit)
            # late time slice for function
            # tfl,fl for late plot curve
            _, f_late_res, _ = chi(
                t_late, None, None,
                pars)  # for f_late_res calculating residues (on data points)
            _, fl, _ = chi(tfl, None, None,
                           pars)  # t_late,fls for plotting residues
            if self.rotating_frame_frequencyMHz:  # (t_late,y_late,f_late_res,ey_late) the last three must be transformed to rrf
                # (tfl,fl) non rebinned, the last must be transformed to rrf
                _, y_late, ey_late = rebin(self.suite.time,
                                           self.rrf_asymm, [start, stop],
                                           packlate,
                                           e=self.rrf_asyme)
                f_late_res = mixer(t_late, f_late_res,
                                   self.rotating_frame_frequencyMHz)
                fl = mixer(tfl, fl, self.rotating_frame_frequencyMHz)

            fit_late_start = int(
                stop / packlate *
                fit_pack)  # divides fit_range in early and late

            # redo the same with the original fit binning fit_pack, only for histo and chi2
            t_fit_late, y_fit_late, ey_fit_late = rebin(
                self.suite.time,
                asymm, [fit_late_start, fit_stop],
                fit_pack,
                e=asyme)
            # no rotating frame version for this!
            nu_fit_late, f_fit_late, chi_fit_late = chi(
                t_fit_late, y_fit_late, ey_fit_late, pars)
            if self.rotating_frame_frequencyMHz:  # (t_fit_late,y_fit_late,f_fit_late,ey_fit_late) the last three must be transformed to rrf
                _, y_fit_late, ey_fit_late = rebin(self.suite.time,
                                                   self.rrf_asymm,
                                                   [fit_start, fit_late_start],
                                                   fit_pack,
                                                   e=self.rrf_asyme)
                f_fit_late = mixer(t_fit_late, f_fit_late,
                                   self.rotating_frame_frequencyMHz)
            # print('mufitplot plot_run debug: y_fit_late ey_fit_late f_fit_late shape = {},  {},  {}'.format(y_fit_late.shape, ey_fit_late.shape, f_fit_late.shape))

            if not nu_fit_late:
                return False
            # function as in fit

            t_fit_early, y_fit_early, ey_fit_early = rebin(
                self.suite.time,
                asymm, [fit_start, fit_late_start],
                fit_pack,
                e=asyme)
            # single slices as in fit
            nu_fit_early, f_fit_early, chi_fit_early = chi(
                t_fit_early, y_fit_early, ey_fit_early, pars)
            if self.rotating_frame_frequencyMHz:
                _, y_fit_early, ey_fit_early = rebin(
                    self.suite.time,
                    self.rrf_asymm, [fit_start, fit_late_start],
                    fit_pack,
                    e=self.rrf_asyme)
                f_fit_early = mixer(t_fit_early, f_fit_early,
                                    self.rotating_frame_frequencyMHz)

            if not nu_fit_early:
                return False
            # function as in fit

        else:
            ###################
            # single range plot
            ###################
            early_late = False
            pack = 1
            chi_fit_late, nu_fit_late, chi_fit_early, nu_fit_early = None, None, None, None
            if len(plottup) == 3:  # plot start stop pack
                start, stop, pack = plottup
            elif len(plottup) == 2:  # plot start stop
                start, stop = plottup
#        self.suite.console('plot_range= {}'.format(plot_range))
#        self.suite.console('start, stop, pack = {},{},{}'.format(start, stop, pack))

        t, y, ey = rebin(self.suite.time, asymm, [start, stop], pack, e=asyme)
        # rebinned single or early slices
        # print('muplotfit plot_run debug: calling chi for f_res')
        nudum, f_res, _ = chi(t, None, None, pars)
        packfit = int(pack / 2)
        tf, dum = rebin(self.suite.time, asymm, [start, stop], packfit)
        # single or early time slice for plot function
        # print('muplotfit plot_run debug: calling chi for f (None)')
        _, f, _ = chi(tf, None, None, pars)
        # print('mufitplot plot_run debug: min max f_res {}, min max f {}'.format([f_res.min(),f_res.max()],[f.min(),f.max()]))
        if self.rotating_frame_frequencyMHz:  # (t,y,f_res,ey) the last three must be transformed to rrf
            # (tf,f) non rebinned, the last must be transformed to rrf
            _, y, ey = rebin(self.suite.time,
                             self.rrf_asymm, [start, stop],
                             pack,
                             e=self.rrf_asyme)
            f_res = mixer(t, f_res, self.rotating_frame_frequencyMHz)
            f = mixer(tf, f, self.rotating_frame_frequencyMHz)

        if not nudum:
            return False
        # print('nu = {}, chi_res = {}'.format(nu,chi_res))
        # t,fres calculated on plot points for residues

        # assume self.suite.single()
        # prepare figure
        fgroup = [
            self.suite.groups[k]['forward']
            for k in range(len(self.suite.groups))
        ]
        bgroup = [
            self.suite.groups[k]['backward']
            for k in range(len(self.suite.groups))
        ]
        alpha = [
            self.suite.groups[k]['alpha']
            for k in range(len(self.suite.groups))
        ]
        group = [fgroup, bgroup, alpha]
        dy_fit = (y_fit - f_fit) / ey_fit

        data = [t, y, ey, f_res, tf, f, dy_fit]

        chi_dof = [nu_fit, chi_fit]

        if self.suite.single() and not self.multigroup:
            set_figure_fit = set_single_fit
        else:
            set_figure_fit = set_sequence_fit
        # single draws a static plot, many runs are dealt by animation
        # invoke ploting of dat, fit and residues

        if early_late:
            dy_fit_early = (y_fit_early - f_fit_early) / ey_fit_early
            dy_fit_late = (y_fit_late - f_fit_late) / ey_fit_late
            w_early = nu_fit * ones(t_fit_early.shape[0]) / nu_fit_early
            w_late = nu_fit * ones(t_fit_late.shape[0]) / nu_fit_late
            data_late = [
                t_late, y_late, ey_late, f_late_res, tfl, fl, dy_fit_early,
                dy_fit_late
            ]
            chi_dof_late = [nu_fit_early,nu_fit_late,\
                            chi_fit_early,chi_fit_late,
                            w_early,w_late]
        else:
            data_late, chi_dof_late = None, None
        # self.suite.console('Debug-mufitplot: set_figure  = {}'.format(set_figure_fit))
        self.fig = set_figure_fit(self.fig,
                                  self.model_name(),
                                  early_late,
                                  data,
                                  group,
                                  run_title,
                                  chi_dof,
                                  data_late,
                                  chi_dof_late,
                                  rrf=self.rotating_frame_frequencyMHz)
        return True