def testSmallSeparation(self): # Due to float rounding issues, feeding these values to # coordinates.angsep() can cause us to attempt math.acos(x) for x # greater than 1, which throws a ValueError. ra1 = 33.655858149999993145229382207617 dec1 = 87.061899808796610500394308473915 ra2 = 33.655860050872931310550484340638 dec2 = 87.061899872535235545001341961324 coordinates.angsep(ra1, dec1, ra2, dec2)
def testSeparation(self): centre = self.results.closest_to(1440, 1440)[0] # How accurate should the '2 degrees' be? for mysource in filter(lambda src: src != centre, self.results): self.assertAlmostEqual(round( coords.angsep(centre.ra, centre.dec, mysource.ra, mysource.dec) / 60**2), 2)
def get_error_radius(wcs, x_value, x_error, y_value, y_error): """ Estimate an absolute angular error on the position (x_value, y_value) with the given errors. This is a pessimistic estimate, because we take sum of the error along the X and Y axes. Better might be to project them both back on to the major/minor axes of the elliptical fit, but this should do for now. """ error_radius = 0 try: centre_ra, centre_dec = wcs.p2s([x_value, y_value]) # We check all possible combinations in case we have a nonlinear # WCS. for pixpos in [ (x_value + x_error, y_value + y_error), (x_value - x_error, y_value + y_error), (x_value + x_error, y_value - y_error), (x_value - x_error, y_value - y_error) ]: error_ra, error_dec = wcs.p2s(pixpos) error_radius = max( error_radius, coordinates.angsep(centre_ra, centre_dec, error_ra, error_dec) ) except RuntimeError: # We get a runtime error from wcs.p2s if the errors place the # limits outside of the image, in which case we set the angular # uncertainty to infinity. error_radius = float('inf') return error_radius
def get_error_radius(wcs, x_value, x_error, y_value, y_error): """ Estimate an absolute angular error on the position (x_value, y_value) with the given errors. This is a pessimistic estimate, because we take sum of the error along the X and Y axes. Better might be to project them both back on to the major/minor axes of the elliptical fit, but this should do for now. """ error_radius = 0 try: centre_ra, centre_dec = wcs.p2s([x_value, y_value]) # We check all possible combinations in case we have a nonlinear # WCS. for pixpos in [(x_value + x_error, y_value + y_error), (x_value - x_error, y_value + y_error), (x_value + x_error, y_value - y_error), (x_value - x_error, y_value - y_error)]: error_ra, error_dec = wcs.p2s(pixpos) error_radius = max( error_radius, coordinates.angsep(centre_ra, centre_dec, error_ra, error_dec)) except RuntimeError: # We get a runtime error from wcs.p2s if the errors place the # limits outside of the image, in which case we set the angular # uncertainty to infinity. error_radius = float('inf') return error_radius
def testSeparation(self): centre = self.results.closest_to(1440, 1440)[0] # How accurate should the '2 degrees' be? for mysource in filter(lambda src: src != centre, self.results): self.assertAlmostEqual( round( coords.angsep(centre.ra, centre.dec, mysource.ra, mysource.dec) / 60**2), 2)
def source_assoc(srcs_vlss,srcs_pyse,bmaj): intflxrat=[] if len(srcs_pyse) > 0: for a in range(len(srcs_pyse)): posdif_old=bmaj*5.*3600. for b in range(len(srcs_vlss)): posdif = coords.angsep(srcs_pyse[a][1][0],srcs_pyse[a][1][1],srcs_vlss[b][0][0],srcs_vlss[b][0][1]) if posdif < posdif_old: posdif_old = posdif intflxrat.append([float(srcs_pyse[a][2]),float(srcs_pyse[a][2])/float(srcs_vlss[b][1])]) return intflxrat
def extract_data(dataset_id, CasA, CygA, VirA): # # Opens the CSV file output from get_data and reads the relevant data into an array # image_info=[] image_data=open('ds_'+dataset_id+'_images.csv','r') list_img = image_data.readlines() image_data.close() frequencies=[] plt_ratios=True for lines in list_img: # Loop through all the images row=lines.split(',') image=row[9].split('/')[-1].rstrip()+'.fits' # Image name date=datetime.strptime(row[8].strip(),'%Y-%m-%d %H:%M:%S') # Time of observation (not currently used) freq=int((float(row[3].strip())/1e6) + 0.5) # Observation frequency, integer number in MHz if freq not in frequencies: # Keeping a record of which frequencies are in the dataset frequencies.append(freq) ellipticity=float(row[5])/float(row[6]) # Restoring beam ellipticity, Bmaj/Bmin if "rms value" in row[2]: theoretical=float(row[2].split(' ')[8].split('(')[1].split(')')[0].strip()) # Theoretical noise limit ratio=float(row[2].split(' ')[4].strip()) # Observed RMS / Theoretical noise (calculated by TraP) # RMS/Confusion limit for TraP maxbl=6. beam = 206265.*((300./float(freq))/(1000*maxbl)) confusion=29.0E-6*math.pow(beam,1.54)*math.pow((float(freq)/74.0),-0.7) confusion_ratio=confusion/float(row[7]) else: theoretical=0. ratio=0. confusion=0. confusion_ratio=0. plt_ratios=False rms=float(row[7]) # Image RMS pc = [float(row[1]), float(row[0])] # Separation of image centre relative to A-Team sources posdif_CasA=coords.angsep(CasA[0],CasA[1],pc[0],pc[1])/3600. posdif_CygA=coords.angsep(CygA[0],CygA[1],pc[0],pc[1])/3600. posdif_VirA=coords.angsep(VirA[0],VirA[1],pc[0],pc[1])/3600. # Input data into array: [RA, Dec, Obs date, Obs Freq, RMS noise, Theoretical noise, RMS/Theoretical, Restoring beam ellipticity, Seperation CasA, Seperation CygA, Seperation VirA, Image name, BMaj,confusion,confusion_ratio] image_info.append([row[0],row[1],date,freq,rms,theoretical,ratio,ellipticity,posdif_CasA,posdif_CygA,posdif_VirA,image,float(row[5]),confusion,confusion_ratio]) return image_info, frequencies, plt_ratios
def test_pix_scale(self): p1_sky = (self.accessor.centre_ra, self.accessor.centre_decl) p1_pix = self.accessor.wcs.s2p(p1_sky) pixel_sep = 10 # Along a single axis p2_pix = (p1_pix[0], p1_pix[1] + pixel_sep) p2_sky = self.accessor.wcs.p2s(p2_pix) coord_dist_deg = angsep(p1_sky[0], p1_sky[1], p2_sky[0], p2_sky[1]) / 3600.0 pix_dist_deg = pixel_sep * self.accessor.pixelsize[1] # 6 decimal places => 1e-6*degree / 10pix => 1e-7*degree / 1pix # => Approx 0.15 arcseconds drift across 512 pixels # (Probably OK). self.assertAlmostEqual(abs(coord_dist_deg), abs(pix_dist_deg), places=6)
def test_pix_scale(self): p1_sky = (self.accessor.centre_ra, self.accessor.centre_decl) p1_pix = self.accessor.wcs.s2p(p1_sky) pixel_sep = 10 #Along a single axis p2_pix = (p1_pix[0], p1_pix[1] + pixel_sep) p2_sky = self.accessor.wcs.p2s(p2_pix) coord_dist_deg = angsep(p1_sky[0], p1_sky[1], p2_sky[0], p2_sky[1]) / 3600.0 pix_dist_deg = pixel_sep * self.accessor.pixelsize[1] #6 decimal places => 1e-6*degree / 10pix => 1e-7*degree / 1pix # => Approx 0.15 arcseconds drift across 512 pixels # (Probably OK). self.assertAlmostEqual(abs(coord_dist_deg), abs(pix_dist_deg), places=6)
def simulate_extraction(self, db_image, extraction_type, rms_attribute='rms_min'): """ Simulate extraction process, returns extracted source or none. Uses the database image properties (extraction region, rms values) to determine if this source would be extracted in the given image, and return an extraction or None accordingly. Args: db_image (int): Database Image object. extraction_type: Valid values are 'blind', 'ff_nd'. If 'blind' then we only return an extracted source if the flux is above rms_value * detection_threshold. rms_attribute (str): Valid values are 'rms_min', 'rms_max'. Determines which rms value we use when deciding if this source will be seen in a blind extraction. Returns: ExtractedSourceTuple or None. """ rms = getattr(db_image, rms_attribute) ex = self.value_at_dtime(db_image.taustart_ts, rms) #First check if source is in this image's extraction region: src_distance_degrees = coords.angsep(ex.ra, ex.dec, db_image.centre_ra, db_image.centre_decl) / 3600.0 if src_distance_degrees > db_image.xtr_radius: return None if extraction_type == 'ff_nd': return ex elif extraction_type == 'blind': if ex.sigma > db_image.detection_thresh: return ex else: return None else: raise ValueError( "Unrecognised extraction type: {}".format(extraction_type))
def simulate_extraction(self, db_image, extraction_type, rms_attribute='rms_min'): """ Simulate extraction process, returns extracted source or none. Uses the database image properties (extraction region, rms values) to determine if this source would be extracted in the given image, and return an extraction or None accordingly. Args: db_image (int): Database Image object. extraction_type: Valid values are 'blind', 'ff_nd'. If 'blind' then we only return an extracted source if the flux is above rms_value * detection_threshold. rms_attribute (str): Valid values are 'rms_min', 'rms_max'. Determines which rms value we use when deciding if this source will be seen in a blind extraction. Returns: ExtractedSourceTuple or None. """ rms = getattr(db_image, rms_attribute) ex = self.value_at_dtime(db_image.taustart_ts, rms) #First check if source is in this image's extraction region: src_distance_degrees = coords.angsep( ex.ra, ex.dec,db_image.centre_ra, db_image.centre_decl) / 3600.0 if src_distance_degrees > db_image.xtr_radius: return None if extraction_type == 'ff_nd': return ex elif extraction_type == 'blind': if ex.sigma > db_image.detection_thresh: return ex else: return None else: raise ValueError("Unrecognised extraction type: {}".format( extraction_type))
def testZeroSeparation(self): self.assertEqual(coordinates.angsep(0, 0, 0, 0), 0)