Ejemplo n.º 1
0
def PlotMassAccuracy(
    stats_vary,
    ty='mass',
    string='',
    percent=False,
):
    '''------------------------------------------------------------
		Description: 
	---------------------------------------------------------------
		Input:
	---------------------------------------------------------------
		Output:
	------------------------------------------------------------'''
    '''
	creats an mass accuracy plot for good events with vary masses
 	'''
    '''
	stats_vary: (result from Analysis(vary =True)
		0D == Data, Names
		1D == events
		2D == different inputs 
		3D == different parameters 
 		4D == num, type, init, 16p, 50p,84p, sig_m,sig_p 
	'''
    dark = 'black' in plt.rcParams['savefig.facecolor']
    if dark:
        string = 'dark_' + string
        black = color_own([0.7, 0.7, 0.7, 1])
    else:
        black = color_own([0., 0., 0., 1])
    if ty == 'mass' or ty == 'm':
        if string == '':
            string = 'mass_accuracy_plot_mass'
        k = 0
    if ty == 'ra':
        if string == '':
            string = 'mass_accuracy_plot_ra'
        k = 1
    if ty == 'dec':
        if string == '':
            string = 'mass_accuracy_plot_dec'
        k = 2
    if ty == 'pmra':
        if string == '':
            string = 'mass_accuracy_plot_pmra'
        k = 3
    if ty == 'pmdec':
        if string == '':
            string = 'mass_accuracy_plot_pmdec'
        k = 4
    if ty == 'px':
        if string == '':
            string = 'mass_accuracy_plot_px'
        k = 5
    if ty == 'c':
        if string == '':
            string = 'mass_accuracy_plot_closest_aproach'
        k = 6

    if len(stats_vary) > 1:
        stats = stats_vary[0]
        Eventnames = stats_vary[1]
        Events = stats_vary[2]
    else:
        stats = stats_vary[0]
        Eventnames = None
    #pic = np.arange(len(Eventnames))
    #pic = np.random.choice(pic,30,replace = False)
    #print(pic)
    pic = np.array([63, 6, 46, 23, 50, 54, 39, 2, 115, 104, 4, 24, 87, 91])
    #pic =  np.array([ 128, 38, 62, 86,  24, 72, 93, 70, 37, 84, 148, 149, 93,53, 147, 31, 90, 24, 18])
    pic = np.unique(np.concatenate((pic, pic + 10), axis=0))

    pic = pic[np.where(pic < len(Events))]
    q = np.array([stats[i][0][0][7] for i in pic])
    q2 = np.array([stats[i][0][0][2] for i in pic])
    #pic = pic[np.where(q > 0.05)]
    fig = plt.figure(figsize=(12, 8))
    ax = fig.add_subplot(111)
    color = iter(color_own(len(pic) + 2))

    for i in pic:
        if k != 0:
            if k == 6:
                Obsdate, Scandir, n_ccd = RealData.getRealObs(Events[i][0],
                                                              extended=True)
                dra = np.array([j[1][2] - j[6][2]
                                for j in stats[i]]).reshape([1, -1])
                ddec = np.array([j[2][2] - j[7][2]
                                 for j in stats[i]]).reshape([1, -1])
                dpmra = np.array([j[3][2] - j[8][2]
                                  for j in stats[i]]).reshape([1, -1])
                dpmdec = np.array([j[4][2] - j[9][2]
                                   for j in stats[i]]).reshape([1, -1])
                dpx = np.array([j[5][2] - j[10][2]
                                for j in stats[i]]).reshape([1, -1])
                cd = np.array([cosdeg(j[2][2])
                               for j in stats[i]]).reshape([1, -1])
                tt = np.array(Obsdate).reshape([-1, 1])
                #np.abs((dra**3600000*cd+tt*dpmra)*s_scandir +  (dec).reshape(-1,1) * sc_scandir[::-1])
                tmin = int(
                    np.mean(
                        np.argmin(np.sqrt(
                            np.square(dra * 3600000 * cd + tt * dpmra) +
                            np.square(ddec * 3600000 + tt * dpmdec)),
                                  axis=0)))
                tt = tt[max([0, tmin - 10]):min([len(tt) - 1, tmin +
                                                 10])].reshape([-1, 1])
                Scandir = Scandir[max([0, tmin -
                                       10]):min([len(Scandir) - 1, tmin +
                                                 10])].reshape([-1, 1])
                s_scandir = np.sin(np.array(Scandir).reshape([-1, 1]))
                c_scandir = np.sin(np.array(Scandir).reshape([-1, 1]))
                mass = np.array([j[0][2] for j in stats[i]]).reshape([1, -1])

                TE = Events[i][0].getMass(
                ) * dpx * const_Einsteinradius * const_Einsteinradius
                in_par = np.min(np.sqrt(
                    np.square(dra * 3600000 * cd + tt * dpmra) +
                    np.square((ddec * 3600000 + tt * dpmdec))) / np.sqrt(TE),
                                axis=0)
                #in_par = np.min(np.sqrt(np.square(dra*3600000*cd+tt*dpmra)+np.square((ddec*3600000+tt*dpmdec))), axis = 0)
                #in_par = in_par-np.min(in_par)
                #in_par = in_par/np.mean(in_par)
                if np.max(in_par) > 2000: continue
            else:
                in_par = np.array([
                    j[k][2] - j[k + 5][2] - stats[i][0][k][2] +
                    stats[i][0][k + 5][2] for j in stats[i]
                ])

        else:
            in_par = np.array([j[k][2] for j in stats[i]])
        mass = np.array([j[0][2] for j in stats[i]])
        sig_m = np.array([j[0][6] for j in stats[i]])
        sig_p = np.array([j[0][7] for j in stats[i]])
        order = np.argsort(in_par)
        sig_m = sig_m[order]
        sig_p = sig_p[order]
        in_par = in_par[order]
        #if k != 0: mass = mass/mass[-1]
        if min(in_par) > 0 or k != 0:
            c = next(color)
            a = np.where(sig_p > np.mean(sig_p))
            b = np.where(sig_p <= np.mean(sig_p))
            ta = np.argsort(in_par[a])
            tb = np.argsort(-in_par[b])
            a2 = np.where(sig_p > np.mean(sig_m))
            b2 = np.where(sig_p <= np.mean(sig_m))
            ta2 = np.argsort(in_par[a2])
            tb2 = np.argsort(-in_par[b2])
            #plt.text(mass[0],sig_p[0] , str(i), fontsize = 20,verticalalignment = 'center',horizontalalignment = 'center')
            p1 = Polygon(
                np.vstack([[np.hstack([in_par[a][ta], in_par[b][tb]])],
                           [np.hstack([sig_p[a][ta], sig_p[b][tb]])]]).T, True)
            p = PatchCollection([
                p1,
            ], color=c, alpha=0.7, linewidth=4)
            ax.add_collection(p)
            if k == 0:
                if Eventnames is None:
                    if percent:
                        plt.loglog(in_par,
                                   sig_p / mass,
                                   '.',
                                   c=c,
                                   markersize=15)
                    else:
                        plt.loglog(in_par, sig_p, '.', c=c, markersize=15)
                else:
                    if percent:
                        plt.loglog(in_par,
                                   sig_p / mass,
                                   '.',
                                   c=c,
                                   label=Eventnames[i],
                                   markersize=15)
                    else:
                        plt.loglog(in_par,
                                   sig_p,
                                   '.',
                                   c=c,
                                   label=Eventnames[i],
                                   markersize=15)
            else:
                if Eventnames is None:
                    if percent:
                        plt.plot(in_par, sig_p / mass, '.', c=c, markersize=15)
                    else:
                        plt.plot(in_par, sig_p, '.', c=c, markersize=15)
                else:
                    if percent:
                        plt.plot(in_par,
                                 sig_p / mass,
                                 '.',
                                 c=c,
                                 label=Eventnames[i],
                                 markersize=15)
                    else:
                        plt.plot(in_par,
                                 sig_p,
                                 '.',
                                 c=c,
                                 label=Eventnames[i],
                                 markersize=15)

    ax.grid(axis='x', linewidth=3, zorder=-50)

    xlim = np.array(plt.xlim())
    xlim = np.array([xlim[0], 2.0])

    ylim = plt.ylim()
    if k == 0:
        for i in [0.15, 0.3, 0.5, 1]:
            plt.plot(xlim,
                     xlim * i,
                     color=plt.rcParams['grid.color'],
                     linewidth=3,
                     zorder=-50)
            if i != 1:
                plt.text(2.3,
                         2.2 * i,
                         str(int(i * 100)) + '%',
                         fontsize=25,
                         verticalalignment='center',
                         horizontalalignment='center')
            else:
                plt.text(ylim[1] * 1.15,
                         ylim[1] * 1.15,
                         str(int(i * 100)) + '%',
                         fontsize=25,
                         verticalalignment='center',
                         horizontalalignment='center')
        plt.xlim(xlim)
        plt.ylim(ylim)

        ax.tick_params(axis='both', which='major', labelsize=25)
        ax.tick_params(axis='both', which='minor', labelsize=0)
        plt.xticks([0.1, 0.2, 0.4, 1, 2], [0.1, 0.2, 0.4, 1.0, 2.0],
                   fontsize=25)
        plt.xticks(fontsize=25)
        plt.yticks([0.02, 0.05, 0.1, 0.2, 0.4, 1],
                   [0.02, 0.05, 0.1, 0.2, 0.4, 1.0],
                   fontsize=25)
        plt.yticks(fontsize=25)
    if k == 6:
        plt.xlabel(r'$\delta\theta_{min}\,\, [\theta_{E}]$', fontsize=30)
        #plt.xlim([50,100])
        #plt.ylim([0,.5])
        ax.grid(axis='y', linewidth=3, zorder=-50)

    elif k != 0:
        plt.xlabel(stats[0][0][k][1], fontsize=30)
    else:
        plt.xlabel('$M\,[M_{\odot}]$', fontsize=30)
    if percent:
        plt.ylabel('$\sigma_{M}\,[\%]$', fontsize=30)
        fig.savefig(imagepath + string + '_percent_' + '.png')
        if paperpath is not None:
            fig.savefig(paperpath + string + '_percent_' + '.png')
        print('Create Image: ' + imagepath + string + '_percent_' + '.png')
    else:
        plt.ylabel('$\sigma_{M}\,[M_{\odot}]$', fontsize=30)
        fig.savefig(imagepath + string + '.png')
        if paperpath is not None: fig.savefig(paperpath + string + '.png')
        print('Create Image: ' + imagepath + string + '.png')
    plt.close(fig)
Ejemplo n.º 2
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.º 3
0
    def Observations(self, n_error_picks=None, timer=False, **kwargs):
        '''---------------------------------------------------------------
			Description: 
				Creates sets of observations (including noise) 
				from Noise free data
		------------------------------------------------------------------
			Input:
				n_error_picks: number of picks from the errorelipse
		------------------------------------------------------------------
			Output:	
				Obs: list of [alpha,delta] for all Observation
				StarID: list of StarID's for all Observation
				Epoch: list of Epochs for all Observation
				sigAL: list of precision in along-scan dirrection for all Observations
				sc_ScanDir: list of [sin(ScanDir),cos(ScanDir)] for all Observations
		---------------------------------------------------------------'''
        #compunting-time-tracker
        cputt = [0, 0, 0, 0]
        cputt[0] -= time.time()

        #if isinstance(self.data, list):
        #combine all datasets
        dat = np.vstack(self.data)
        #determine length of each dataset
        length = np.array([len(i) for i in self.data])
        # first Index of each dataset
        index = np.array(
            [np.sum(length[:i]) for i in range(1, len(self.data))]).astype(int)
        #else:
        #	dat=self.data

        if n_error_picks is None:
            n_error_picks = 1
        cputt[0] += time.time()

        cputt[1] -= time.time()
        #---------------------------------------------------------------
        #get StarID,Epoch ScanDir NCCD  for each observation
        StarID = dat[:, 0].astype(int)
        Epoch = dat[:, 3]
        ScanDir = dat[:, 4]
        NCCD = dat[:, 7]
        #---------------------------------------------------------------

        #---------------------------------------------------------------
        #calculate accuracy of gaia
        if self.Stars is None or len(StarID) == 0:
            #accuracy in along-scan dirrection
            sigAL = sigmaGaia() * np.ones([len(dat[:, 0])])
            #set across-scan accuracy to 1 arcsec (is not used for fitting)
            sigAC = 1000 * np.ones([len(dat[:, 0])])
        else:
            #accuracy in along-scan dirrection
            sigAL = sigmaGaia_np(self.Stars[StarID]) / np.sqrt(NCCD)
            #set across-scan accuracy to 1 arcsec (is not used for fitting)
            sigAC = 1000 * np.ones([len(dat[:, 0])])
        #---------------------------------------------------------------

        #---------------------------------------------------------------
        #create multidimensional random valu from gaussian distribution
        rand = np.random.normal(0, 1,
                                len(dat) * 2 * n_error_picks).reshape(
                                    n_error_picks, -1, 1, 2)
        cputt[1] += time.time()
        #---------------------------------------------------------------

        #---------------------------------------------------------------
        #Transform into alpha-delta for each observation
        cputt[2] -= time.time()
        co = np.cos(ScanDir)
        si = np.sin(ScanDir)
        sc_ScanDir = np.vstack([si, co]).T
        cd = cosdeg(dat[:, 2])
        trans = np.zeros((1, len(dat), 2, 2))
        trans[0, :, 0, 0] = sigAL * si / cd / 3.6e6
        trans[0, :, 0, 1] = -sigAC * co / cd / 3.6e6
        trans[0, :, 1, 0] = co * sigAL / 3.6e6
        trans[0, :, 1, 1] = si * sigAC / 3.6e6
        Obs = np.sum(trans * rand, 3) + dat[:, 1:3]
        cputt[2] += time.time()
        #---------------------------------------------------------------

        #---------------------------------------------------------------
        # order output
        cputt[3] -= time.time()
        #if isinstance(self.data, list):
        Obs = np.split(Obs, index, axis=1)
        StarID = np.split(StarID, index)
        Epoch = np.split(Epoch, index)
        sigAL = np.split(sigAL, index)
        sc_ScanDir = np.split(sc_ScanDir, index)
        cputt[3] += time.time()
        #---------------------------------------------------------------
        if timer:
            print('OB: %.4f,%.4f,%.4f,%.4f' % tuple(cputt))

        return Obs, StarID, Epoch, sigAL, sc_ScanDir
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