Ejemplo n.º 1
0
def plotmicro(obs, par, scsc, trange=[-5, 10, 1000], **kwargs):
    '''------------------------------------------------------------
		Description: plot the position, of lens and source star, as well as the fitted curve 
	---------------------------------------------------------------
		Input: 
			obs: set of observations [[ra,dec],...]
			par: fitted parameter
	------------------------------------------------------------'''
    time_vec = np.linspace(trange[0], trange[1], num=trange[2], endpoint=True)
    earth = getSun(t_0 + time_vec)
    loc_vec = np.stack([(scsc[0] * earth[0] - scsc[1] *  earth[1])/ max(scsc[3],1e-6),\
      scsc[1] * scsc[2] *  earth[0] + scsc[0] * scsc[2] *  earth[1] - scsc[3] *  earth[2]]).T
    n_stars = int((len(par) - 1) / 5)
    plt.plot(obs[:, 0], obs[:, 1], 'x')
    styl = kwargs.pop('styl', '-')
    linewidth = kwargs.pop('linewidth', 2)
    for i in range(n_stars):
        xx = stars_position_micro(par,
                                  np.ones(1000, int) * i, time_vec, loc_vec,
                                  scsc, **kwargs)
        yy = stars_position_micro(par,
                                  np.ones(1000, int) * i,
                                  time_vec,
                                  loc_vec,
                                  scsc,
                                  ml=True,
                                  **kwargs)
        plt.plot(xx[:, 0], xx[:, 1], styl, linewidth=linewidth)
        plt.plot(yy[:, 0], yy[:, 1], ':', linewidth=linewidth)
Ejemplo n.º 2
0
gmag = np.array([Data[1][i] for i in phot])
gmag2 = [12.19, 13.6]
par_col = [
    'mass', 'ra', 'dec', 'pmra', 'pmdec', 'parallax', 'ob_ra', 'ob_dec',
    'ob_pmra', 'ob_pmdec', 'ob_parallax'
]
par = np.array([Data[1][i] for i in par_col])
print(par)
par_multi = np.vstack([par, par])
epoch = np.linspace(t_mai - t_0 - 40 / 365, t_mai - t_0 + 40 / 365, 200)
epoch_vec = np.repeat(epoch.reshape(-1, 1), 2, axis=1)
num = np.arange(2)
scsc = sindeg(par[1]), cosdeg(par[1]), sindeg(par[2]),\
     max(cosdeg(par[2]), 1e-16)

earth = getSun(t_0 + epoch).T

loc = np.repeat(np.stack([(scsc[0] * earth[:,0] - scsc[1] *  earth[:,1])\
   / max(scsc[3],1e-6),\
   scsc[1] * scsc[2] *  earth[:,0] + scsc[0] * scsc[2]\
   *  earth[:,1] - scsc[3] *  earth[:,2]]).T.reshape(-1,1,2),2,axis = 1 )
num_vec = np.repeat(num.reshape(1, -1), len(epoch), axis=0)
pos_vec = stars_position_micro(par_multi,
                               num_vec.reshape(-1),
                               epoch_vec.reshape(-1),
                               loc_vec=loc.reshape(-1, 2),
                               scsc=scsc,
                               ml=True,
                               pml=True)
A = pos_vec[1][0]
A = A[np.where(A != 0)]
Ejemplo n.º 3
0
def Fit_Motion(obs,num_vec, time_vec,obs_error = None, sc_scandir = None, loc_vec = None, unit_obs = 'deg', \
 unit_pos = 'deg', unit_pm = 'mas/yr', unit_px = 'mas', exact = False,**kwargs):
    '''------------------------------------------------------------
		Description: 
	---------------------------------------------------------------
		Input:
	---------------------------------------------------------------
		Output:
	------------------------------------------------------------'''
    obs_error = None
    if obs_error is None:
        obs_error = np.ones(len(num_vec))
    # translate units from and to mas
    unit_pos_fac = unitFac('mas', unit_pos)
    unit_pm_fac = unitFac('mas', unit_pm)
    unit_px_fac = unitFac('mas', unit_px)
    unit_obs_fac = unitFac(unit_obs, 'mas')

    # calculate earth vector

    # calculate sin(ra),cos(ra),sin(dec),cos(dec)
    scsc = sindeg(obs[0,0] * unit_obs_fac / 3.6e6) , cosdeg(obs[0,0] * unit_obs_fac / 3.6e6),\
      sindeg(obs[0,1] * unit_obs_fac / 3.6e6) , cosdeg(obs[0,1] * unit_obs_fac / 3.6e6)
    if loc_vec is None:
        earth = getSun(t_0 + time_vec)
        loc_vec = np.stack([(scsc[0] * earth[0] - scsc[1] *  earth[1])/ max(scsc[3], 1e-6),\
         scsc[1] * scsc[2] *  earth[0] + scsc[0] * scsc[2] *  earth[1] - scsc[3] *  earth[2]]).T
    #switch to relative coordinates by subtracting ra0,dec0 (first observation)

    radec_0 = obs[0, :]
    obs_rel = (obs - radec_0.reshape(-1, 2)) * unit_obs_fac

    #reorder numtimeloc_vec
    ntl_vec = [num_vec, time_vec, loc_vec]

    #setup starting value for par and par0
    #par = [0.5, ra1,dec1, 0,0,0]
    par = np.zeros(max(num_vec + 1) * 5)
    par0 = np.zeros(max(num_vec + 1) * 5)
    par0[0::5] = radec_0[0] * unit_obs_fac
    par0[1::5] = radec_0[1] * unit_obs_fac
    q = [np.where(num_vec == i)[0] for i in range(max(num_vec + 1))]
    index_0 = [i[0] if len(i) > 0 else -1 for i in q]
    par[0::5] = obs_rel[index_0, 0]
    par[1::5] = obs_rel[index_0, 1]
    qq = np.array([False if len(i) > 0 else True for i in q])

    #fitting residual function
    if sc_scandir is None:
        par_res = least_squares(FitFunction_Motion,par, xtol = 3e-16 ,jac = Jacobian_Motion, \
           args = (ntl_vec, obs_rel, obs_error, scsc[3]))

    else:
        par_res = least_squares(FitFunction_Motion_Scandir,par, xtol = 3e-16 ,jac = Jacobian_Motion_Scandir, \
           args = (ntl_vec, sc_scandir, obs_rel, obs_error, scsc[3]))

    #return parameter in requested units
    par_res.x[0::5] = (par_res.x[0::5] + par0[0::5]) * unit_pos_fac
    par_res.x[1::5] = (par_res.x[1::5] + par0[1::5]) * unit_pos_fac
    par_res.x[2::5] = (par_res.x[2::5] + par0[2::5]) * unit_pm_fac
    par_res.x[3::5] = (par_res.x[3::5] + par0[3::5]) * unit_pm_fac
    par_res.x[4::5] = (par_res.x[4::5] + par0[4::5]) * unit_px_fac
    if qq.any():
        par_res.x[1 + 5 * np.where(qq)[0]] = None
        par_res.x[2 + 5 * np.where(qq)[0]] = None
        par_res.x[3 + 5 * np.where(qq)[0]] = None
        par_res.x[4 + 5 * np.where(qq)[0]] = None
        par_res.x[5 + 5 * np.where(qq)[0]] = None
    return par_res
Ejemplo n.º 4
0
def Fit_Micro(obs, num_vec, time_vec, obs_error = None, sc_scandir = None, loc_vec = None, unit_obs = 'deg', \
 unit_pos = 'deg', unit_pm = 'mas/yr', unit_px = 'mas', plot = False, exact = False, bounds = False, prefit_motion = False,**kwargs):
    '''------------------------------------------------------------
		Description: Fited the stelar motion to de data 
	---------------------------------------------------------------
		Input:
			obs: list of observations
			numvec: identifier of the coresponding star
			time_vec: epoch of the observations
			obs_error: measurement errors for weigting. If none use uniform weights)
			sc_scandir: sin,cos of the position angle of the scan direction. for each observation
				If None 2D residuals are used.
			loc_vec: Location of Gaia. respect to the sun. If None, calculate the position from the epoch
			unit_**: Units of the observation, position, propermotion and parallax
			exact: If False, use the center of light as aproximation
			bounds: Use bounds for the fitting process. 
			prefit_motion: Determine a priors from a fit without microlensing.
	---------------------------------------------------------------
		Output:
			par_res:	leastsquare fit results
						par_res.x = [mass, ra0_Lens, dec0_Lens, pmra_Lens,pmdec_Lens,px_Lens, ra0_Source1,.... ]
	------------------------------------------------------------'''
    if obs_error is None:
        obs_error = np.ones(len(obs))
    # translate units from and to mas
    unit_pos_fac = unitFac('mas', unit_pos)
    unit_pm_fac = unitFac('mas', unit_pm)
    unit_px_fac = unitFac('mas', unit_px)
    unit_obs_fac = unitFac(unit_obs, 'mas')

    # calculate sin(ra),cos(ra),sin(dec),cos(dec)
    scsc = sindeg(obs[0,0] * unit_obs_fac / 3.6e6) , cosdeg(obs[0,0] * unit_obs_fac / 3.6e6),\
      sindeg(obs[0,1] * unit_obs_fac / 3.6e6) , cosdeg(obs[0,1] * unit_obs_fac / 3.6e6)
    # calculate earth vector
    if loc_vec is None:
        earth = getSun(t_0 + time_vec)
        loc_vec = np.stack([(scsc[0] * earth[0] - scsc[1] *  earth[1])/ max(scsc[3], 1e-20),\
         scsc[1] * scsc[2] *  earth[0] + scsc[0] * scsc[2] *  earth[1] - scsc[3] *  earth[2]]).T
    #switch to relative coordinates by subtracting ra0,dec0 (first observation)

    radec_0 = obs[0, :]
    obs_rel = (obs - radec_0.reshape(-1, 2)) * unit_obs_fac

    #reorder numtimeloc_vec
    ntl_vec = [num_vec, time_vec, loc_vec]

    #setup starting value for par and par0
    #par = [0.5, ra1,dec1, 0,0,0]
    if len(np.where(num_vec == 0)[0]) == 0:
        #test source only
        par = np.zeros(max(num_vec + 1) * 5 + 1)
        par0 = np.zeros(max(num_vec + 1) * 5 + 1)
        par0[1::5] = radec_0[0] * unit_obs_fac
        par0[2::5] = radec_0[1] * unit_obs_fac
        par[0] = 0.5
        q = [np.where(num_vec == i)[0] for i in range(max(num_vec + 1))]
        index_0 = [i[0] if len(i) > 0 else -1 for i in q]
        par[1::5] = obs_rel[index_0, 0]
        par[2::5] = obs_rel[index_0, 1]
        par[2] = par[7]
        par[1] = par[6]
        #calculat preset parameters
        if sc_scandir is None:
            par_1 = least_squares(fm.FitFunction_Motion,par[1:], xtol = 3e-8 ,jac = fm.Jacobian_Motion, \
              args = (ntl_vec, obs_rel, obs_error, scsc[3]))
        else:
            par_1 = least_squares(fm.FitFunction_Motion_Scandir,par[1:], xtol = 3e-8 ,jac = fm.Jacobian_Motion_Scandir, \
              args = (ntl_vec, sc_scandir, obs_rel, obs_error, scsc[3]))
        nn = np.where(np.abs(par_1.fun) == max(np.abs(par_1.fun)))[0]
        mm = par_1.fun[nn] * obs_error[nn]
        ThetaE2 = const_Einsteinradius * const_Einsteinradius * 0.5 * 100
        deltaphi = -(ThetaE2 / mm +
                     np.sqrt(max(ThetaE2**2 / mm**2 - 8 * ThetaE2, 0))) / 2
        par[1:3] = obs_rel[nn] + deltaphi * sc_scandir[nn]
        par[5] = 100
        par[6:] = par_1.x[5:]
        qq = np.array([False, False])
    else:
        par = np.zeros(max(num_vec + 1) * 5 + 1)
        par0 = np.zeros(max(num_vec + 1) * 5 + 1)
        par0[1::5] = radec_0[0] * unit_obs_fac
        par0[2::5] = radec_0[1] * unit_obs_fac
        par[0] = 0.5
        if prefit_motion:
            if sc_scandir is None:
                par_res = least_squares(fm.FitFunction_Motion,par[1:], xtol = 3e-8 ,jac = fm.Jacobian_Motion, \
                 args = (ntl_vec, obs_rel, obs_error, scsc[3]))
            else:
                par_res = least_squares(fm.FitFunction_Motion_Scandir,par[1:], xtol = 3e-8 ,jac = fm.Jacobian_Motion_Scandir, \
                 args = (ntl_vec, sc_scandir, obs_rel, obs_error, scsc[3]))
            par0[1:] = par_res.x

        q = [np.where(num_vec == i)[0] for i in range(max(num_vec + 1))]
        index_0 = [i[0] if len(i) > 0 else -1 for i in q]
        par[1::5] = obs_rel[index_0, 0]
        par[2::5] = obs_rel[index_0, 1]
        qq = np.array([False if len(i) > 0 else True for i in q])

    if bounds: bounds = (-np.inf, [1000, *(np.inf * np.ones(len(par) - 1))])
    else: bounds = (-np.inf, np.inf)
    #fitting residual function
    if sc_scandir is None:
        par_res = least_squares(FitFunction_Micro,par, xtol = 3e-16 ,jac = Jacobian_Micro, bounds = bounds, \
           args = (ntl_vec, obs_rel, obs_error, scsc[3], exact))

    else:
        par_res = least_squares(FitFunction_Micro_Scandir,par, xtol = 3e-16 ,jac = Jacobian_Micro_Scandir, \
           bounds = bounds, args = (ntl_vec, sc_scandir, obs_rel, obs_error, scsc[3], exact))
        r = np.random.uniform()
        if False:
            cost = lambda x, i: np.sum(
                FitFunction_Micro_Scandir([
                    *par_res.x[0:i], x, *par_res.x[i + 1:]
                ], ntl_vec, sc_scandir, obs_rel, obs_error, scsc[3], exact)**2)

            xx = np.linspace(-1, 1, 1000)
            sfactor = [1, 1, 1, 0.1, 0.1, 1, 1, 1, 0.1, 0.1, 1]

            y = [
                np.array([cost(x * sfactor[i] + par_res.x[i], i) for x in xx])
                for i in range(11)
            ]
            par_name = [
                'mass, M_sun', 'ra1, mas', 'dec1, mas', 'pmra1, 0.1mas/yr',
                'pmdec1, 0.1mas/yr', 'px1, mas', 'ra2', 'dec2', 'pmra2',
                'pmdec2', 'px2'
            ]
            fig = plt.figure(figsize=(11, 10))
            for i in range(11):
                plt.plot(xx, y[i], label=par_name[i])
            plt.xlabel('delta_par')
            plt.ylim([0, 5 * par_res.cost])
            plt.legend(fontsize=20)
            fig.savefig(imagepath + 'Cost_function_' + str(int(r * 10000)) +
                        '.png')
            plt.close(fig)

            fig = plt.figure(figsize=(11, 10))
            xx = np.linspace(-1000, 1000, 10000)
            xx2 = np.linspace(-999.999, 1000.001, 10000)
            y = [
                np.array([cost(x * sfactor[i] + par_res.x[i], i) for x in xx])
                for i in range(1)
            ]
            y2 = [
                np.array([cost(x * sfactor[i] + par_res.x[i], i) for x in xx2])
                for i in range(1)
            ]
            for i in range(1):
                plt.plot(xx, y[i] - y2[i], label=par_name[i])
            fig.savefig(imagepath + 'Cost_function_' + str(int(r * 10000)) +
                        '_2.png')
            plt.close(fig)

    if plot:
        plotMicro(obs_rel, par_res.x, scsc, styl = '-', linewidth=2, out_unit = 'mas', \
           unit_pos = 'mas', unit_pm = 'mas/yr', unit_px = 'mas')
    #return parameter in requested units

    par_res.x[1::5] = (par_res.x[1::5] + par0[1::5]) * unit_pos_fac
    par_res.x[2::5] = (par_res.x[2::5] + par0[2::5]) * unit_pos_fac
    par_res.x[3::5] = (par_res.x[3::5] + par0[3::5]) * unit_pm_fac
    par_res.x[4::5] = (par_res.x[4::5] + par0[4::5]) * unit_pm_fac
    par_res.x[5::5] = (par_res.x[5::5] + par0[5::5]) * unit_px_fac
    if qq.any():
        par_res.x[1 + 5 * np.where(qq)[0]] = None
        par_res.x[2 + 5 * np.where(qq)[0]] = None
        par_res.x[3 + 5 * np.where(qq)[0]] = None
        par_res.x[4 + 5 * np.where(qq)[0]] = None
        par_res.x[5 + 5 * np.where(qq)[0]] = None
    return par_res
Ejemplo n.º 5
0
    def __init__(self, Stars, Epoch, ScanDir, NCCD, Mass = None,\
     out_unit = 'deg', n_par_picks = None, onlysource = False,timer =False, **kwargs):
        '''---------------------------------------------------------------		
			Creats simulated sets of noice free observational Data (i.e no observational
			errors are included)
			Creats one observation for every source and every epoch (if resolvable)
		------------------------------------------------------------------
			Input:
				Stars: vector of 1 lens and multiple source stars
				Epoch: 	epoch of observation for the event
				ScanDir: Position angle of the scan dirrection for each epoch [rad] 
				NCCD: 	Number of CCD for the observation
				Mass: mass of the lens 
				out_unit: unit of the observations
				n_par_picks2: number of different Sets  
							if none return one set 1 
							if list: [number of differne parameters, number of different masses]
				onlysource: returns only data of the source
				timer: print computing time for different steps)
				**kwargs: vary_par for Star.getParameters 
						  exact for StelarMotion.stars_position_micro
						  ext_obs for resolvable
		---------------------------------------------------------------'''
        #compunting-time-tracker
        cputt = [0, 0, 0]
        cputt[0] -= time.time()

        #-----------------------------------------------------------------
        # Determine number of different sets
        if n_par_picks is None:
            n_par = 1
            n_mass = 1
        elif isinstance(n_par_picks, list):
            n_par = n_par_picks[0]
            n_mass = n_par_picks[1]
        else:
            n_mass = n_par_picks
            n_par = n_par_picks
        #-----------------------------------------------------------------

        #-----------------------------------------------------------------
        #unit of the data and input parameters
        self.Stars = np.array(Stars)
        self.unit = [out_unit, *Stars[0].unit]
        # Number of stars
        self.NumStars = len(Stars)
        # setup Data array
        dat_multi = []
        # setup array for multiple sets of input parameters
        par_multi = np.zeros((n_par, len(Stars) * 5 + 1))
        # setup array for G magnitudes
        Gmag = np.zeros(len(Stars))
        for pick in range(n_par):
            for i in range(len(Stars)):
                if i == 0:  #store parameters of the lens
                    par_multi[pick, 0:6] = Stars[i].getParameters(**kwargs)
                    if Mass is not None:
                        par_multi[pick, 0] = Mass
                    elif pick % (n_par / n_mass) != 0:
                        par_multi[pick, 0] = par_multi[pick - 1, 0]
                    elif pick == 0:
                        self.Mass_lens = par_multi[pick, 0]
                else:
                    #store parameters of the Sources
                    par_multi[pick, 5 * i + 1:5 * i +
                              6] = Stars[i].getParameters(**kwargs)[1:]

                # store Gmagnitude of lens and source
                if pick == 0:
                    Gmag[i] = Stars[i].getMag()
        #-----------------------------------------------------------------

        #-----------------------------------------------------------------
        #caluclate sin(alpha),cos(alpha),sin(delta),cos(delta)
        if 'deg' in self.unit[1]:
            scsc = sindeg(par_multi[0,1]), cosdeg(par_multi[0,1]), sindeg(par_multi[0,2]),\
              max(cosdeg(par_multi[0,2]), 1e-16)
        if 'mas' in self.unit[1]:
            scsc = sinmas(par_multi[0,2]), cosmas(par_multi[0,1]), sinmas(par_multi[0,2]),\
              max(cosmas(par_multi[0,2]), 1e-16)
        if 'arcsec' in self.unit[1]:
            scsc = sinmas(par_multi[0,1]/1000), cosmas(par_multi[0,1]/1000), sinmas(par_multi[0,2]/1000),\
              max(cosmas(par_multi[0,2]/1000), 1e-16)
        #-----------------------------------------------------------------
        cputt[0] += time.time()
        cputt[1] -= time.time()

        #-----------------------------------------------------------------
        # positional shift due to the parallax
        # calculat position of Lagrange point 2
        L2 = getSun(t_0 + Epoch).T

        # caluate the invers Jacobean for the parallax effect
        loc = np.repeat(np.stack([(scsc[0] * L2[:,0] - scsc[1] *  L2[:,1])\
         / max(scsc[3],1e-6),\
         scsc[1] * scsc[2] *  L2[:,0] + scsc[0] * scsc[2]\
         *  L2[:,1] - scsc[3] *  L2[:,2]]).T.reshape(-1,1,2),self.NumStars,axis = 1)
        #-----------------------------------------------------------------

        #-----------------------------------------------------------------
        # Calculat position for each star
        # epoch for all Stars
        Epoch_vec = np.repeat(Epoch.reshape(-1, 1), self.NumStars, axis=1)
        # identifier for all Stars
        num = np.arange(self.NumStars)
        num_vec = np.repeat(num.reshape(1, -1), len(Epoch), axis=0)
        # observed position of lens and sources for every parameterpick
        pos_vec = stars_position_micro(par_multi,
                                       num_vec.reshape(-1),
                                       Epoch_vec.reshape(-1),
                                       loc_vec=loc.reshape(-1, 2),
                                       scsc=scsc,
                                       out_unit=self.unit[0],
                                       unit_pos=self.unit[1],
                                       unit_pm=self.unit[2],
                                       unit_px=self.unit[3],
                                       **kwargs)
        pos_vec = pos_vec.reshape(n_par, -1, self.NumStars, 2)
        #-----------------------------------------------------------------

        #Translate NCCD and ScanDir into numpy arrays
        ScanDir = np.array(ScanDir)

        NCCD = np.array(NCCD)

        cputt[1] += time.time()
        cputt[2] -= time.time()
        #loop over parameter pics
        for k in range(n_par):
            #get position for this set of parameters
            pos_k = pos_vec[k]

            if onlysource:
                #return only the observations of the source
                W = np.ones((len(pos_k), len(Gmag)))
                W[:, 0] = 0
            else:
                #check if lens and sources are resolvable
                which = resolvable(pos_k, Gmag, ScanDir, **kwargs)
            #store ID,alpha,delta,Epoch,ScanDir, Loc, NCCD for each resolved datapoint
            dat = np.hstack([which[1].reshape(-1,1),pos_k[which],Epoch[which[0]].reshape(-1,1),\
              ScanDir[which[0]].reshape(-1,1),loc[which[0],0,:],NCCD[which[0]].reshape(-1,1)])
            dat_multi.append(dat)
        cputt[2] += time.time()

        #print computing time
        if timer: print('RD: %.2f, %.2f, %.2f' % tuple(cputt))

        self.data = dat_multi
        self.par = par_multi