示例#1
0
    def fit(self, selected, iters=1):
        """
        Run a fit using the specified fitter
        """
        # Select all the TOAs if none are explicitly set
        if not any(selected):
            selected = ~selected
        """JUMP check, TODO: put in fitter?"""
        if "PhaseJump" in self.prefit_model.components:
            # if attempted fit (selected)
            # A) contains only jumps, don't do the fit and return an error
            # B) excludes a jump, turn that jump off
            # C) partially contains a jump, redefine that jump only with the overlap
            fit_jumps = []
            for param in self.prefit_model.params:
                if getattr(self.prefit_model,
                           param).frozen == False and param.startswith("JUMP"):
                    fit_jumps.append(int(param[4:]))

            numjumps = self.prefit_model.components[
                "PhaseJump"].get_number_of_jumps()
            if numjumps == 0:
                log.warn(
                    "There are no jumps (maskParameter objects) in PhaseJump. Please delete the PhaseJump object and try again. "
                )
                return None
            # boolean array to determine if all selected toas are jumped
            jumps = [
                True if "jump" in dict.keys() and dict["jump"] in fit_jumps
                else False for dict in self.all_toas.table["flags"][selected]
            ]
            # check if par file jumps in PhaseJump object
            if not any(jumps):
                # for every jump, set appropriate flag for TOAs it jumps
                for jump_par in self.prefit_model.components[
                        "PhaseJump"].get_jump_param_objects():
                    # find TOAs jump applies to
                    mask = jump_par.select_toa_mask(self.all_toas)
                    # apply to dictionaries for future use
                    for dict in self.all_toas.table["flags"][mask]:
                        dict["jump"] = jump_par.index
                jumps = [
                    True if "jump" in dict.keys() and dict["jump"] in fit_jumps
                    else False
                    for dict in self.all_toas.table["flags"][selected]
                ]
            if all(jumps):
                log.warn(
                    "toas being fit must not all be jumped. Remove or uncheck at least one jump in the selected toas before fitting."
                )
                return None
            # numerical array of selected jump flags
            sel_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.all_toas.table["flags"][selected]
            ]
            # numerical array of all jump flags
            full_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.all_toas.table["flags"]
            ]
            for num in range(1, numjumps + 1):
                num = int(num)
                if num not in sel_jump_nums:
                    getattr(self.prefit_model, "JUMP" + str(num)).frozen = True
                    continue
                jump_select = [num == jump_num for jump_num in full_jump_nums]
                overlap = [a and b for a, b in zip(jump_select, selected)]
                # remove the jump flags for that num
                for dict in self.all_toas.table["flags"]:
                    if "jump" in dict.keys() and dict["jump"] == num:
                        del dict["jump"]
                # re-add the jump using overlap as 'selected'
                for dict in self.all_toas.table["flags"][overlap]:
                    dict["jump"] = num

        if self.fitted:
            self.prefit_model = self.postfit_model
            self.prefit_resids = self.postfit_resids

        if self.fitter == Fitters.POWELL:
            fitter = pint.fitter.PowellFitter(self.selected_toas,
                                              self.prefit_model)
        elif self.fitter == Fitters.WLS:
            fitter = pint.fitter.WLSFitter(self.selected_toas,
                                           self.prefit_model)
        elif self.fitter == Fitters.GLS:
            fitter = pint.fitter.GLSFitter(self.selected_toas,
                                           self.prefit_model)
        chi2 = self.prefit_resids.chi2
        wrms = np.sqrt(chi2 / self.selected_toas.ntoas)
        print("Pre-Fit Chi2:\t\t%.8g us^2" % chi2)
        print("Pre-Fit Weighted RMS:\t%.8g us" % wrms)

        fitter.fit_toas(maxiter=1)
        self.postfit_model = fitter.model
        self.postfit_resids = Residuals(self.all_toas, self.postfit_model)
        self.fitted = True
        self.write_fit_summary()

        # TODO: delta_pulse_numbers need some work. They serve both for PHASE and -padd functions from the TOAs
        # as well as for phase jumps added manually in the GUI. They really should not be zeroed out here because
        # that will wipe out preexisting values
        self.fulltoas.table["delta_pulse_numbers"] = np.zeros(
            self.fulltoas.ntoas)
        self.selected_toas.table["delta_pulse_number"] = np.zeros(
            self.selected_toas.ntoas)

        # plot the prefit without jumps
        pm_no_jumps = copy.deepcopy(self.postfit_model)
        for param in pm_no_jumps.params:
            if param.startswith("JUMP"):
                getattr(pm_no_jumps, param).value = 0.0
                getattr(pm_no_jumps, param).frozen = True
        self.prefit_resids_no_jumps = Residuals(self.selected_toas,
                                                pm_no_jumps)

        f = copy.deepcopy(fitter)
        no_jumps = [
            False if "jump" in dict.keys() else True
            for dict in f.toas.table["flags"]
        ]
        f.toas.select(no_jumps)

        selectedMJDs = self.selected_toas.get_mjds()
        if all(no_jumps):
            q = list(self.all_toas.get_mjds())
            index = q.index([
                i for i in self.all_toas.get_mjds() if i > selectedMJDs.min()
            ][0])
            rs_mean = (Residuals(
                self.all_toas,
                f.model).phase_resids[index:index + len(selectedMJDs)].mean())
        else:
            rs_mean = self.prefit_resids_no_jumps.phase_resids[no_jumps].mean()

        # determines how far on either side fake toas go
        # TODO: hard limit on how far fake toas can go --> can get clkcorr
        # errors if go before GBT existed, etc.
        minMJD, maxMJD = selectedMJDs.min(), selectedMJDs.max()
        spanMJDs = maxMJD - minMJD
        if spanMJDs < 30 * u.d:
            redge = ledge = 4
            npoints = 400
        elif spanMJDs < 90 * u.d:
            redge = ledge = 2
            npoints = 300
        elif spanMJDs < 200 * u.d:
            redge = ledge = 1
            npoints = 300
        elif spanMJDs < 400 * u.d:
            redge = ledge = 0.5
            npoints = 200
        else:
            redge = ledge = 0.2
            npoints = 150
        # Check to see if too recent
        nowish = (Time.now().mjd - 40) * u.d
        if maxMJD + spanMJDs * redge > nowish:
            redge = (nowish - maxMJD) / spanMJDs
            if redge < 0.0:
                redge = 0.0
        f_toas, rs, mrands = random_models(
            f,
            rs_mean=rs_mean,
            redge_multiplier=redge,
            ledge_multiplier=ledge,
            npoints=npoints,
            iter=10,
        )
        self.random_resids = rs
        self.fake_toas = f_toas
示例#2
0
    def fit(self, selected, iters=1):
        """
        Run a fit using the specified fitter
        """
        # Select all the TOAs if none are explicitly set
        if not any(selected):
            selected = ~selected
        """JUMP check, TODO: put in fitter?"""
        if "PhaseJump" in self.prefit_model.components:
            # if attempted fit (selected)
            # A) contains only jumps, don't do the fit and return an error
            # B) excludes a jump, turn that jump off
            # C) partially contains a jump, redefine that jump only with the overlap
            fit_jumps = []
            for param in self.prefit_model.params:
                if getattr(self.prefit_model,
                           param).frozen == False and param.startswith("JUMP"):
                    fit_jumps.append(int(param[4:]))
            jumps = [
                True if "jump" in dict.keys() and dict["jump"] in fit_jumps
                else False for dict in self.selected_toas.table["flags"]
            ]
            if all(jumps):
                log.warn(
                    "toas being fit must not all be jumped. Remove or uncheck at least one jump in the selected toas before fitting."
                )
                return None
            sel_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.selected_toas.table["flags"]
            ]
            full_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.all_toas.table["flags"]
            ]
            for num in range(1, int(np.nanmax(full_jump_nums) + 1)):
                num = int(num)
                if num not in sel_jump_nums:
                    getattr(self.prefit_model, "JUMP" + str(num)).frozen = True
                    continue
                jump_select = [num == jump_num for jump_num in full_jump_nums]
                overlap = [a and b for a, b in zip(jump_select, selected)]
                # remove the jump flags for that num
                for dict in self.all_toas.table["flags"]:
                    if "jump" in dict.keys() and dict["jump"] == num:
                        del dict["jump"]
                # re-add the jump using overlap as 'selected'
                for dict in self.all_toas.table["flags"][overlap]:
                    dict["jump"] = num

        if self.fitted:
            self.prefit_model = self.postfit_model
            self.prefit_resids = self.postfit_resids

        if self.fitter == Fitters.POWELL:
            fitter = pint.fitter.PowellFitter(self.selected_toas,
                                              self.prefit_model)
        elif self.fitter == Fitters.WLS:
            fitter = pint.fitter.WLSFitter(self.selected_toas,
                                           self.prefit_model)
        elif self.fitter == Fitters.GLS:
            fitter = pint.fitter.GLSFitter(self.selected_toas,
                                           self.prefit_model)
        chi2 = self.prefit_resids.chi2
        wrms = np.sqrt(chi2 / self.selected_toas.ntoas)
        print("Pre-Fit Chi2:\t\t%.8g us^2" % chi2)
        print("Pre-Fit Weighted RMS:\t%.8g us" % wrms)

        fitter.fit_toas(maxiter=1)
        self.postfit_model = fitter.model
        self.postfit_resids = Residuals(self.all_toas,
                                        self.postfit_model,
                                        set_pulse_nums=True)
        self.fitted = True
        self.write_fit_summary()

        # TODO: set pulse nums above not working to reset delta pulse nums, have to force it here
        # self.fulltoas.table['delta_pulse_numbers'] = np.zeros(self.fulltoas.ntoas)
        self.selected_toas.table["delta_pulse_number"] = np.zeros(
            self.selected_toas.ntoas)

        # plot the prefit without jumps
        pm_no_jumps = copy.deepcopy(self.postfit_model)
        for param in pm_no_jumps.params:
            if param.startswith("JUMP"):
                getattr(pm_no_jumps, param).value = 0.0
                getattr(pm_no_jumps, param).frozen = True
        self.prefit_resids_no_jumps = Residuals(self.all_toas,
                                                pm_no_jumps,
                                                set_pulse_nums=True)

        f = copy.deepcopy(fitter)
        no_jumps = [
            False if "jump" in dict.keys() else True
            for dict in f.toas.table["flags"]
        ]
        f.toas.select(no_jumps)

        selectedMJDs = self.selected_toas.get_mjds()
        if all(no_jumps):
            q = list(self.all_toas.get_mjds())
            index = q.index([
                i for i in self.all_toas.get_mjds() if i > selectedMJDs.min()
            ][0])
            rs_mean = (Residuals(
                self.all_toas, f.model,
                set_pulse_nums=True).phase_resids[index:index +
                                                  len(selectedMJDs)].mean())
        else:
            rs_mean = self.prefit_resids_no_jumps.phase_resids[no_jumps].mean()

        # determines how far on either side fake toas go
        # TODO: hard limit on how far fake toas can go --> can get clkcorr
        # errors if go before GBT existed, etc.
        minMJD, maxMJD = selectedMJDs.min(), selectedMJDs.max()
        spanMJDs = maxMJD - minMJD
        if spanMJDs < 30 * u.d:
            redge = ledge = 4
            npoints = 400
        elif spanMJDs < 90 * u.d:
            redge = ledge = 2
            npoints = 300
        elif spanMJDs < 200 * u.d:
            redge = ledge = 1
            npoints = 300
        elif spanMJDs < 400 * u.d:
            redge = ledge = 0.5
            npoints = 200
        else:
            redge = ledge = 0.2
            npoints = 150
        # Check to see if too recent
        nowish = (Time.now().mjd - 40) * u.d
        if maxMJD + spanMJDs * redge > nowish:
            redge = (nowish - maxMJD) / spanMJDs
            if redge < 0.0:
                redge = 0.0
        f_toas, rs = random_models(
            f,
            rs_mean=rs_mean,
            redge_multiplier=redge,
            ledge_multiplier=ledge,
            npoints=npoints,
            iter=10,
        )
        self.random_resids = rs
        self.fake_toas = f_toas