def test_python_kdtree(monkeypatch): from astropy.coordinates import ICRS cmatch = ICRS([4, 2.1]*u.degree, [0, 0]*u.degree, distance=[1, 2]*u.kpc) ccatalog = ICRS([1, 2, 3, 4]*u.degree, [0, 0, 0, 0]*u.degree, distance=[1, 2, 3, 4]*u.kpc) monkeypatch.delattr("scipy.spatial.cKDTree") with pytest.warns(UserWarning, match='C-based KD tree not found'): matching.match_coordinates_sky(cmatch, ccatalog)
def test_matching_method(): from astropy.coordinates import ICRS, SkyCoord from astropy.utils import NumpyRNGContext from astropy.coordinates.matching import match_coordinates_3d, match_coordinates_sky with NumpyRNGContext(987654321): cmatch = ICRS( np.random.rand(20) * 360. * u.degree, (np.random.rand(20) * 180. - 90.) * u.degree) ccatalog = ICRS( np.random.rand(100) * 360. * u.degree, (np.random.rand(100) * 180. - 90.) * u.degree) idx1, d2d1, d3d1 = SkyCoord(cmatch).match_to_catalog_3d(ccatalog) idx2, d2d2, d3d2 = match_coordinates_3d(cmatch, ccatalog) npt.assert_array_equal(idx1, idx2) assert_allclose(d2d1, d2d2) assert_allclose(d3d1, d3d2) # should be the same as above because there's no distance, but just make sure this method works idx1, d2d1, d3d1 = SkyCoord(cmatch).match_to_catalog_sky(ccatalog) idx2, d2d2, d3d2 = match_coordinates_sky(cmatch, ccatalog) npt.assert_array_equal(idx1, idx2) assert_allclose(d2d1, d2d2) assert_allclose(d3d1, d3d2) assert len(idx1) == len(d2d1) == len(d3d1) == 20
def test_match_catalog_nounit(): from .. import ICRS, CartesianRepresentation from ..matching import match_coordinates_sky i1 = ICRS([[1], [2], [3]], representation_type=CartesianRepresentation) i2 = ICRS([[1], [2], [4, 5]], representation_type=CartesianRepresentation) i, sep, sep3d = match_coordinates_sky(i1, i2) assert_allclose(sep3d, [1] * u.dimensionless_unscaled)
def report_close_neighbours(magmo_coords, magmo_table): idx, sep2d, dist3d = matching.match_coordinates_sky(magmo_coords, magmo_coords, 2) idx_orig = np.arange(len(magmo_coords)) idx_close = sep2d < 3 * u.arcsec idx_match1 = idx_orig[idx_close] idx_match2 = idx[idx_close] sep_12 = sep2d[idx_close] for i in range(len(idx_match1)): match1 = magmo_table[idx_match1[i]] match2 = magmo_table[idx_match2[i]] print("{} is only {:.2f} arcsec from {} Rating {} v {} ContSD {:.3f} v {:.3f}".format(match1['Name'], sep_12[i].to(u.arcsec), match2['Name'], match1['Rating'], match2['Rating'], match1['Continuum_SD'], match2['Continuum_SD']))
def test_matching_function_3d_and_sky(): from astropy.coordinates import ICRS from astropy.coordinates.matching import match_coordinates_3d, match_coordinates_sky cmatch = ICRS([4, 2.1]*u.degree, [0, 0]*u.degree, distance=[1, 5] * u.kpc) ccatalog = ICRS([1, 2, 3, 4]*u.degree, [0, 0, 0, 0]*u.degree, distance=[1, 1, 1, 5] * u.kpc) idx, d2d, d3d = match_coordinates_3d(cmatch, ccatalog) npt.assert_array_equal(idx, [2, 3]) assert_allclose(d2d, [1, 1.9] * u.deg) assert np.abs(d3d[0].to_value(u.kpc) - np.radians(1)) < 1e-6 assert np.abs(d3d[1].to_value(u.kpc) - 5*np.radians(1.9)) < 1e-5 idx, d2d, d3d = match_coordinates_sky(cmatch, ccatalog) npt.assert_array_equal(idx, [3, 1]) assert_allclose(d2d, [0, 0.1] * u.deg) assert_allclose(d3d, [4, 4.0000019] * u.kpc)
dec = rr_list['DEC'][k] print 'RA = %.10f, DEC= %.10f' % (ra,dec) row_pix = None col_pix = None dist = [] for CCD in CHIPS: print 'Looking in CCD %s' % CCD cata_file = "%s/catalogues/%s/%s/%s_%s_%s_image_crblaster_thresh%s_minarea%s_backsize64_trans.dat" % (jorgepath, field, CCD, field, CCD, '02', str(thresh), str(minarea)) if not os.path.exists(cata_file): print 'No file: %s' % files_epoch continue cata = np.loadtxt(cata_file, comments='#') tree = SkyCoord(ra = cata[:,3], dec = cata[:,4], unit=(u.degree,u.degree)) radec_obj = SkyCoord(ra = ra, dec = dec, unit=(u.degree,u.degree)) idx, ang, d3d = match_coordinates_sky(radec_obj, tree, nthneighbor = 1) ang0 = np.array(ang) dist.append(ang0) print 'Nearest neighbor at %f arcsec' % (ang0*3600) # ang0 is in degrees 0.0003 deg ~ 1.0 arcsec if ang0 < tolerance: row_pix, col_pix = cata[idx,2], cata[idx,1] print 'RADEC in catalogue: %f, %f' % (cata[idx,3], cata[idx,4]) print 'Angular distance: %f acrsec' % (ang0*3600) print 'YES!!' print '########################################' break else: print 'No match!' print '----------------------------------------'
def associate_object_ids_to_table(cat, object_table=None, matching_radius=1, verbose=True): """Return object ID associated with each entry in cat. Takes closest match within matching radius. Entries with no match will be -1. (the index entries are integers so we can't use NaN as signaling value) Currently does purely position based matching above an implicit SNR Does not do a flux-based matching. Parameters -- cat: pandas DataFrame object_table: pandas DataFrame matching_radius: float [arcsec] Notes -- cat and object_table are assumed to have RA, Dec units of rad """ # Let's first try the stupid way: # Explicitly iterate through cat # Construct a subset of object min_ra, max_ra = np.min(cat['coord_ra']), np.max(cat['coord_ra']) min_dec, max_dec = np.min(cat['coord_dec']), np.max(cat['coord_dec']) edge_buffer = np.deg2rad(10 * matching_radius / 3600) # Note this is wrong. There's no cos(dec) ra_range = (np.rad2deg(min_ra - edge_buffer), np.rad2deg(max_ra + edge_buffer)) dec_range = (np.rad2deg(min_dec - edge_buffer), np.rad2deg(max_dec + edge_buffer)) if verbose: print("Extract objects from Object Table with RA, Dec in ranges:") print(ra_range, dec_range) in_source_catalog_area = (ra_range[0] < object_table['ra']) & \ (object_table['ra'] < ra_range[1]) & \ (dec_range[0] < object_table['dec']) & \ (object_table['dec'] < dec_range[1]) this_object_table = object_table[in_source_catalog_area] if verbose: print("Found %d objects in Object Table in region" % len(this_object_table)) if len(this_object_table) < 1: # Return an array of -1 return np.zeros(len(cat)) - 1 this_object_table_skyCoor = SkyCoord(this_object_table['ra'], this_object_table['dec'], unit=(u.deg, u.deg)) cat_skyCoor = SkyCoord(cat['coord_ra'], cat['coord_dec'], unit=(u.rad, u.rad)) idx, sep2d, _ = matching.match_coordinates_sky(cat_skyCoor, this_object_table_skyCoor) associated_ids = np.asarray(this_object_table.iloc[idx]['id'], dtype=int) # Remove the associations that were too far away. w = sep2d > matching_radius * u.arcsec # sentinel value for no match. # Assumes input catalog uses only non-negative numbers for object Ids associated_ids[w] = -1 return associated_ids
for CCD in CHIPS: print 'Looking in CCD %s' % CCD cata_file = "%s/catalogues/%s/%s/%s_%s_%s_image_crblaster_thresh%s_minarea%s_backsize64_trans.dat" % ( jorgepath, field, CCD, field, CCD, '02', str(thresh), str(minarea)) if not os.path.exists(cata_file): print 'No file: %s' % files_epoch continue cata = np.loadtxt(cata_file, comments='#') tree = SkyCoord(ra=cata[:, 3], dec=cata[:, 4], unit=(u.degree, u.degree)) radec_obj = SkyCoord(ra=ra, dec=dec, unit=(u.degree, u.degree)) idx, ang, d3d = match_coordinates_sky(radec_obj, tree, nthneighbor=1) ang0 = np.array(ang) dist.append(ang0) print 'Nearest neighbor at %f arcsec' % (ang0 * 3600) # ang0 is in degrees 0.0003 deg ~ 1.0 arcsec if ang0 < tolerance: row_pix, col_pix = cata[idx, 2], cata[idx, 1] print 'RADEC in catalogue: %f, %f' % (cata[idx, 3], cata[idx, 4]) print 'Angular distance: %f acrsec' % (ang0 * 3600) print 'YES!!' print '########################################' break else:
def create_clusters(LSM, patches_orig, Q, applyBeam=False, root='Patch'): """ Clusterize all the patches of the skymodel iteratively around the brightest patches """ from astropy.coordinates import SkyCoord from astropy import units as u from distutils.version import StrictVersion import scipy log = logging.getLogger('LSMTool.Cluster') if StrictVersion(scipy.__version__) < StrictVersion('0.11.0'): log.debug('The installed version of SciPy contains a bug that affects catalog matching. ' 'Falling back on (slower) matching script.') from ._matching import match_coordinates_sky else: from astropy.coordinates.matching import match_coordinates_sky # sort the patches by brightest first idx = np.argsort([patch.flux for patch in patches_orig])[::-1] # -1 to reverse sort patches = list(np.array(patches_orig)[idx]) # initialize clusters with the brightest patches clusters = [] for i, patch in enumerate(patches[0:Q]): clusters.append(Cluster(root+'_'+str(i), patch)) # Iterate until no changes in which patch belongs to which cluster count = 1 patches_seq_old = [] patchRAs = [] patchDecs = [] for patch in patches: patchRAs.append(patch.ra) patchDecs.append(patch.dec) while True: clusterRAs = [] clusterDecs = [] if LSM.hasPatches: clusterRA, clusterDec = LSM.getPatchPositions(method='wmean', asArray=True, applyBeam=applyBeam, perPatchProjection=False) clusterNames = LSM.getPatchNames() patches_orig = LSM.getColValues('Name') else: clusterRA = [cluster.centroid_ra for cluster in clusters] clusterDec = [cluster.centroid_dec for cluster in clusters] clusterNames = [cluster.name for cluster in clusters] for cluster in clusters: # reset patches if type(clusterNames) is not list: clusterNames = clusterNames.tolist() cindx = clusterNames.index(cluster.name) cluster.patches = [] clusterRAs.append(clusterRA[cindx]) clusterDecs.append(clusterDec[cindx]) catalog1 = SkyCoord(clusterRAs, clusterDecs, unit=(u.degree, u.degree), frame='fk5') catalog2 = SkyCoord(patchRAs, patchDecs, unit=(u.degree, u.degree), frame='fk5') matchIdx, d2d, d3d = match_coordinates_sky(catalog2, catalog1) for i, patch in zip(matchIdx, patches): cluster = clusters[i] cluster.add_patch(patch) patches_seq = [] for cluster in clusters: patches_seq.extend(cluster.patches) count += 1 if patches_seq == patches_seq_old: break patches_seq_old = patches_seq # Make output patch column patchNames = [''] * len(patches) patchNames_orig = LSM.getColValues('Name').tolist() for c in clusters: for p in c.patches: patchNames[patchNames_orig.index(p.name)] = c.name LSM.setColValues('Patch', patchNames, index=2) LSM._updateGroups() return np.array(patchNames)
##arcsec match=[[] for i in range(len(seq1))] for i in range(len(seq1)): for j in range(len(seq2)): dis=getlen([ra_dec2[0][j],ra_dec2[1][j]],[ra_dec1[0][i],ra_dec1[1][i]])*3600 if dis<offset: match[i].append([seq1[i],seq2[j],dis]) print(np.sort(match)) input=get_input() Radio_catalog = SkyCoord(ra=input[0][0]*u.degree, dec=input[0][1]*u.degree) Xray_catalog = SkyCoord(ra=input[1][0]*u.degree, dec=input[1][1]*u.degree) print(Xray_catalog) id=match_catalog.match_coordinates_sky(Radio_catalog, Xray_catalog, nthneighbor=1)[0]+1 offset=match_catalog.match_coordinates_sky(Radio_catalog, Xray_catalog, nthneighbor=1)[1] offset_arcsec=[] for i in range(len(offset)): offset_arcsec.append(Angle(offset[i]).degree*3600) # temp=SkyCoord(offset[0], unit = (u.deg), frame='icrs').to_string('decimal') xray_counterpart=np.column_stack((id.astype(int),offset_arcsec)) np.savetxt('/Users/baotong/Desktop/period/GCCR_xrayc.txt',xray_counterpart,fmt='get_ipython().run_line_magic("d", " %10.4f')")
def create_clusters(LSM, patches_orig, Q, applyBeam=False, root='Patch', pad_index=False): """ Clusterize all the patches of the skymodel iteratively around the brightest patches """ from astropy.coordinates import SkyCoord from astropy import units as u from distutils.version import StrictVersion import scipy log = logging.getLogger('LSMTool.Cluster') if StrictVersion(scipy.__version__) < StrictVersion('0.11.0'): log.debug('The installed version of SciPy contains a bug that affects catalog matching. ' 'Falling back on (slower) matching script.') from ._matching import match_coordinates_sky else: from astropy.coordinates.matching import match_coordinates_sky # sort the patches by brightest first idx = np.argsort([patch.flux for patch in patches_orig])[::-1] # -1 to reverse sort patches = list(np.array(patches_orig)[idx]) # initialize clusters with the brightest patches clusters = [] for i, patch in enumerate(patches[0:Q]): if pad_index: clusters.append(Cluster(root+'_'+str(i).zfill(int(np.ceil(np.log10(Q)))), patch)) else: clusters.append(Cluster(root+'_'+str(i), patch)) # Iterate until no changes in which patch belongs to which cluster count = 1 patches_seq_old = [] patchRAs = [] patchDecs = [] for patch in patches: patchRAs.append(patch.ra) patchDecs.append(patch.dec) while True: clusterRAs = [] clusterDecs = [] if LSM.hasPatches: clusterRA, clusterDec = LSM.getPatchPositions(method='wmean', asArray=True, applyBeam=applyBeam, perPatchProjection=False) clusterNames = LSM.getPatchNames() patches_orig = LSM.getColValues('Name') else: clusterRA = [cluster.centroid_ra for cluster in clusters] clusterDec = [cluster.centroid_dec for cluster in clusters] clusterNames = [cluster.name for cluster in clusters] for cluster in clusters: # reset patches if type(clusterNames) is not list: clusterNames = clusterNames.tolist() cindx = clusterNames.index(cluster.name) cluster.patches = [] clusterRAs.append(clusterRA[cindx]) clusterDecs.append(clusterDec[cindx]) catalog1 = SkyCoord(clusterRAs, clusterDecs, unit=(u.degree, u.degree), frame='fk5') catalog2 = SkyCoord(patchRAs, patchDecs, unit=(u.degree, u.degree), frame='fk5') matchIdx, d2d, d3d = match_coordinates_sky(catalog2, catalog1) for i, patch in zip(matchIdx, patches): cluster = clusters[i] cluster.add_patch(patch) patches_seq = [] for cluster in clusters: patches_seq.extend(cluster.patches) count += 1 if patches_seq == patches_seq_old: break patches_seq_old = patches_seq # Make output patch column patchNames = [''] * len(patches) patchNames_orig = LSM.getColValues('Name').tolist() for c in clusters: for p in c.patches: patchNames[patchNames_orig.index(p.name)] = c.name LSM.setColValues('Patch', patchNames, index=2) LSM._updateGroups() return np.array(patchNames)