def test_match_cxy(self): xx = np.arange(1, 11) * 1. yy = np.arange(1, 11) * 1. sx = np.arange(2, 12) * 1. sy = np.arange(2, 12) * 1. (indxy, indr) = astrotools.match_cxy(xx, yy, sx, sy) expected_indxy = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) expected_indr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) assert (indxy == expected_indxy).all and (indr == expected_indr).all()
def _correlate_sources(ad1, ad2, delta=None, firstPass=10, cull_sources=False): """ This function takes sources from the OBJCAT extensions in two images and attempts to correlate them. It returns a list of reference source positions and their correlated image source positions. :param ad1: reference image :type ad1: AstroData instance :param ad2: input image :type ad2: AstroData instance :param delta: maximum distance in pixels to allow a match. If left as None, it will attempt to find an appropriate number (recommended). :type delta: float :param firstPass: estimated maximum distance between correlated sources. This distance represents the expected mismatch between the WCSs of the input images. :type firstPass: float :param cull_sources: flag to indicate whether to reject sources that are insufficiently star-like :type cull_sources: bool """ log = gemLog.getGeminiLog() # If desired, clip out the most star-like sources in the OBJCAT if cull_sources: good_src_1 = gt.clip_sources(ad1)[("SCI", 1)] good_src_2 = gt.clip_sources(ad2)[("SCI", 1)] if len(good_src_1) < 3 or len(good_src_2) < 3: log.warning("Too few sources in culled list, using full set " "of sources") x1 = ad1["OBJCAT"].data.field("X_IMAGE") y1 = ad1["OBJCAT"].data.field("Y_IMAGE") x2 = ad2["OBJCAT"].data.field("X_IMAGE") y2 = ad2["OBJCAT"].data.field("Y_IMAGE") else: x1 = good_src_1["x"] y1 = good_src_1["y"] x2 = good_src_2["x"] y2 = good_src_2["y"] else: # Otherwise, just get all sources x1 = ad1["OBJCAT"].data.field("X_IMAGE") y1 = ad1["OBJCAT"].data.field("Y_IMAGE") x2 = ad2["OBJCAT"].data.field("X_IMAGE") y2 = ad2["OBJCAT"].data.field("Y_IMAGE") # get WCS from both images wcs1 = pywcs.WCS(ad1["SCI"].header) wcs2 = pywcs.WCS(ad2["SCI"].header) # convert image 2 data to sky coordinates ra2, dec2 = wcs2.wcs_pix2sky(x2, y2, 1) # convert image 2 sky data to image 1 pixel coordinates conv_x2, conv_y2 = wcs1.wcs_sky2pix(ra2, dec2, 1) # find matches ind1, ind2 = at.match_cxy(x1, conv_x2, y1, conv_y2, delta=delta, firstPass=firstPass, log=log) if len(ind1) != len(ind2): raise Errors.ScienceError("Mismatched arrays returned from match_cxy") if len(ind1) < 1 or len(ind2) < 1: return [[], []] else: obj_list = [zip(x1[ind1], y1[ind1]), zip(x2[ind2], y2[ind2])] return obj_list
def _match_objcat_refcat(adinput=None): """ Match the sources in the objcats against those in the corresponding refcat. Update the refid column in the objcat with the Id of the catalog entry in the refcat. Update the refmag column in the objcat with the magnitude of the corresponding source in the refcat in the band that the image is taken in. :param adinput: AD object(s) to match catalogs in :type adinput: AstroData objects, either a single instance or a list """ # Instantiate the log. This needs to be done outside of the try block, # since the log object is used in the except block log = gemLog.getGeminiLog() # The validate_input function ensures that the input is not None and # returns a list containing one or more inputs adinput_list = gt.validate_input(input=adinput) # Initialize the list of output AstroData objects adoutput_list = [] try: # Loop over each input AstroData object in the input list for ad in adinput_list: filter_name = ad.filter_name(pretty=True).as_pytype() if filter_name in ['J', 'H', 'K']: magcolname = filter_name+'mag' magerrcolname = 'e_'+filter_name+'mag' else: log.warning("Filter %s is not in JHK table - will not be " "able to flux calibrate" % filter_name) magcolname = None magerrcolname = None # Loop through the objcat extensions if ad['OBJCAT'] is None: raise Errors.InputError("Missing OBJCAT in %s" % (ad.filename)) for objcat in ad['OBJCAT']: extver = objcat.extver() # Check that a refcat exists for this objcat extver refcat = ad['REFCAT',extver] if(not(refcat)): log.warning("Missing [REFCAT,%d] in %s - Cannot match objcat" " against missing refcat" % (extver,ad.filename)) else: # Get the x and y position lists from both catalogs cat_ra = objcat.data['X_WORLD'] # this is RA cat_dec = objcat.data['Y_WORLD'] # this is DEC ref_ra = refcat.data['RAJ2000'] ref_dec = refcat.data['DEJ2000'] g=np.where((cat_ra<194.28) & (cat_ra>194.26)) #print 'RF0:',cat_ra[g] #print 'RF1:',cat_dec[g] # Get new pixel coordinates for all ra,dec in the dictionary. # Use the input wcs object. # FIXME - need to address the wraparound problem here # if we straddle ra = 360.00 = 0.00 initial = 15.0/3600.0 # 15 arcseconds in degrees final = 0.5/3600.0 # 0.5 arcseconds in degrees (oi, ri) = at.match_cxy(cat_ra,ref_ra,cat_dec,ref_dec, firstPass=initial, delta=final, log=log) # If too few matches, assume the match was bad if len(oi)<1: oi = [] log.stdinfo("Matched %d objects in ['OBJCAT',%d] against" " ['REFCAT',%d]" % (len(oi), extver, extver)) # Loop through the reference list updating the refid in the objcat # and the refmag, if we can for i in range(len(oi)): objcat.data['REF_NUMBER'][oi[i]] = refcat.data['Id'][ri[i]] if(magcolname): objcat.data['REF_MAG'][oi[i]] = refcat.data[magcolname][ri[i]] objcat.data['REF_MAG_ERR'][oi[i]] = refcat.data[magerrcolname][ri[i]] adoutput_list.append(ad) return adoutput_list except: # Log the message from the exception log.critical(repr(sys.exc_info()[1])) raise