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)
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
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
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
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