def get_links(args): this_nite, q = args ''' The key routine for building the linkmap. Examines all points in this_nite and identifies points in exposures within look_ahead_nites of this_nite with separation consistent with parallax motion of a distant solar system object. ''' this_nites_expnums = np.unique(df_nites[this_nite]['expnum'].values) link_nites = [nite for nite in nites if 0<nites_between(this_nite, nite)<=look_ahead_nites] # Compute parallax offsets from each exposure in current nite to the target nites print 'Processing nite: ', this_nite print ' Nite contains', len(df_nites[this_nite]),' points in ', len(this_nites_expnums), ' exposures' print ' ', len(link_nites),' nites available for linking' linkmap_nite = {} for exp in this_nites_expnums: exposure = df_exps.loc[df_exps['expnum']==exp] exp_ra, exp_dec = hours(exposure['ra'].values[0]), degrees(exposure['dec'].values[0]) exp_date = date(exposure['date'].values[0]) lon, lat = Ecliptic(Equatorial(exp_ra, exp_dec)).get() this_dlon, this_dlat, this_vlon, this_vlat = linkutils.parallax(exp_ra, exp_dec, exp_date) this_exps_points = df_nites[this_nite].loc[df_nites[this_nite]['expnum']==exp] # points in this exposure this_exps_points.index = range(len(this_exps_points)) # reindex starting from zero this_exps_objids = this_exps_points['objid'].values # objids in this exposure linkmap_exp = dict(zip(this_exps_objids, [[] for i in range(len(this_exps_objids))])) for next_nite in link_nites: deltaT = nites_between(this_nite, next_nite) next_dlon, next_dlat, next_vlon, next_vlat = linkutils.parallax(exp_ra, exp_dec, exp_date+deltaT) dlon, dlat = next_dlon-this_dlon, next_dlat-this_dlat search_center = Equatorial(Ecliptic(lon+dlon/nominal_distance, lat+dlat/nominal_distance)) deltaR = np.sqrt(dlon**2*np.cos(lat)**2 + dlat**2)/nominal_distance offset_ra, offset_dec = hours(search_center.ra - exp_ra), degrees(search_center.dec - exp_dec) shifted_points = apply_offset(this_exps_points, offset_ra, offset_dec) # apply parallax offset this_exps_tree = build_kdtree(shifted_points) # make KDtree from the shifted points near_list = this_exps_tree.query_ball_tree(trees[next_nite], deltaR) for ipoint in range(len(near_list)): if near_list[ipoint] != []: point1 = this_exps_points.iloc[ipoint] for jpoint in near_list[ipoint]: point2 = df_nites[next_nite].iloc[jpoint] if tno_like(point1, point2): objid1 = point1['objid'] objid2 = point2['objid'] linkmap_exp[objid1].append(objid2) linkmap_nite.update(linkmap_exp) q.put(this_nite) return linkmap_nite
def tno_like(point1, point2, vmax=150, debug=False): # # vmax is max velocity in arsec/day # lon1, lat1 = Ecliptic(Equatorial(point1['ra'], point1['dec'])).get() lon2, lat2 = Ecliptic(Equatorial(point2['ra'], point2['dec'])).get() displacement = separation((lon2, lat2), (lon1, lat1)) displacement_asec = displacement*180/np.pi*3600 if point2['date'] != point1['date']: velocity = displacement_asec/(point2['date'] - point1['date']) else: velocity=9999 this_dlon, this_dlat, this_vlon, this_vlat = linkutils.parallax(point1['ra'], point1['dec'], point1['date']) next_dlon, next_dlat, next_vlon, next_vlat = linkutils.parallax(point2['ra'], point2['dec'], point2['date']) dlon, dlat = next_dlon-this_dlon, next_dlat-this_dlat dot = np.cos(lat1)**2*(lon2 - lon1)*dlon + (lat2 - lat1)*dlat norm = np.sqrt(np.cos(lat1)**2*dlon**2 + dlat**2) cosine = dot/(norm*displacement) TNOlike = True if velocity<vmax and cosine>cosine_cut(displacement_asec) else False return TNOlike
def tno_like(self, point1, point2, debug=False): lon1, lat1 = Ecliptic(Equatorial(point1.ra, point1.dec)).get() lon2, lat2 = Ecliptic(Equatorial(point2.ra, point2.dec)).get() displacement = ephem.separation((lon2, lat2), (lon1, lat1)) displacement_asec = displacement*180/np.pi*3600 if point2.date != point1.date: velocity = displacement_asec/(point2.date - point1.date) else: velocity=9999 this_dlon, this_dlat, this_vlon, this_vlat = linkutils.parallax(point1.ra, point1.dec, point1.date) next_dlon, next_dlat, next_vlon, next_vlat = linkutils.parallax(point2.ra, point2.dec, point2.date) dlon, dlat = next_dlon-this_dlon, next_dlat-this_dlat dot = np.cos(lat1)**2*(lon2 - lon1)*dlon + (lat2 - lat1)*dlat norm = np.sqrt(np.cos(lat1)**2*dlon**2 + dlat**2) cosine = dot/(norm*displacement) TNOlike = True if velocity<self.vmax and cosine>self.cosine_cut(displacement_asec) else False if debug: linkinfo = {'v':velocity, 'cos':cosine, 'dot':dot, 'displacement':displacement_asec, 'cut':self.cosine_cut(displacement_asec), 'point1':point1, 'point2':point2, 'lon1':lon1, 'lon2':lon2, 'lat1':lat1, 'lat2':lat2, 'dlon':dlon, 'dlat':dlat, 'norm':norm, 'TNOlike':TNOlike} self.linkpoints.append(linkinfo) return TNOlike
def link_obj(self, point, verbose=False): nites = self.nites thisnite = point.nite if verbose: print 'Linking point ', point.objid, point.date, thisnite, point.ra, point.dec, point.band look_ahead_nites = sorted([n for n in nites if 0<self.nites_between(thisnite,n)<self.look_ahead_nights]) lon, lat = Ecliptic(Equatorial(point.ra, point.dec)).get() # this_dlon, this_dlat = self.para[point.expnum]['dlon'], self.para[point.expnum]['dlat'] this_dlon, this_dlat, this_vlon, this_vlat = linkutils.parallax(point.ra, point.dec, point.date) next_obj = [] for next_nite in look_ahead_nites: if verbose: print 'Linking target nite: ', next_nite deltaT = self.nites_between(thisnite,next_nite) next_dlon, next_dlat, next_vlon, next_vlat = linkutils.parallax(point.ra, point.dec, point.date+deltaT) dlon, dlat = next_dlon-this_dlon, next_dlat-this_dlat search_center = Equatorial(Ecliptic(lon+dlon/self.nominal_distance, lat+dlat/self.nominal_distance)) deltaR = np.sqrt(dlon**2*np.cos(lat)**2 + dlat**2)/self.nominal_distance # print ephem.separation((search_center.ra, search_center.dec), (point.ra, point.dec))*3600*180/np.pi/deltaT sep_max = self.vmax*np.pi/(180*3600)*(deltaT)/2 current_objects = [obj for obj in self.objects if obj.nite == next_nite \ and (self.bands is None or obj.band in self.bands) \ and ephem.separation((search_center.ra, search_center.dec), (obj.ra, obj.dec))<deltaR] if verbose: print ' Found ', len(current_objects), ' points in search window' # now the real work: for each object, test to see # if it's consistent with being the next point in # a KBO trajectory, i.e. consistent in direction and displacement with earth parallax. if True: for point2 in current_objects: if verbose: print 'Examining point ', point2.objid, point2.date, thisnite, point2.ra, point2.dec, point.band, ' ... ', # next_dlon, next_dlat = self.para[point2.expnum]['dlon'], self.para[point2.expnum]['dlat'] # dlon, dlat = next_dlon-this_dlon, next_dlat-this_dlat # if self.tno_like(point, point2, lon, lat, dlon, dlat, debug=True): if self.tno_like(point, point2, debug=False): if verbose: print 'Point is tno_like...' next_obj.append(point2) else: if verbose: print 'Point NOT tno_like...' return next_obj