def testAngularCoordinatePositionAngle(self): """Test our position angle methods.""" ang_a = stomp.AngularCoordinate(0.0, 0.0, stomp.AngularCoordinate.Equatorial) ang_b = stomp.AngularCoordinate(1.0, 0.0, stomp.AngularCoordinate.Equatorial) self.assertAlmostEqual(ang_a.PositionAngle(ang_b), 90.0) self.assertAlmostEqual(ang_b.PositionAngle(ang_a), 270.0) ang_b.SetEquatorialCoordinates(0.0, 1.0) self.assertAlmostEqual(ang_a.PositionAngle(ang_b), 0.0) self.assertAlmostEqual(ang_b.PositionAngle(ang_a), 180.0)
def testAngularCoordinateBasic(self): """Test the basic constructors and coordinate transforms.""" ang = stomp.AngularCoordinate() ang.SetSurveyCoordinates(20.0, 60.0) tmp_ang = stomp.AngularCoordinate(20.0, 60.0, stomp.AngularCoordinate.Survey) self.assertAlmostEqual(ang.RA(), tmp_ang.RA()) self.assertAlmostEqual(ang.DEC(), tmp_ang.DEC()) self.assertAlmostEqual(ang.GalLon(), tmp_ang.GalLon()) self.assertAlmostEqual(ang.GalLat(), tmp_ang.GalLat())
def testAngularCoordinateVectorMath(self): """Test our dot & cross product methods.""" ang_a = stomp.AngularCoordinate(0.0, 0.0, stomp.AngularCoordinate.Survey) ang_b = stomp.AngularCoordinate(45.0, 0.0, stomp.AngularCoordinate.Survey) ang_c = stomp.AngularCoordinate(60.0, 0.01, stomp.AngularCoordinate.Survey) ang_d = stomp.AngularCoordinate(0.0, 60.0, stomp.AngularCoordinate.Survey) self.assertAlmostEqual(ang_a.DotProduct(ang_b), ang_b.DotProduct(ang_a))
def testPixelAnnulusIntersection(self): """Test our method for annulus intersection checking.""" # Initialize a pixel at a given location ang = stomp.AngularCoordinate(60.0, 20.0, stomp.AngularCoordinate.Survey) pix = stomp.Pixel(ang, stomp.HPixResolution) # now find the rough angular scale of the pixel pix_center = stomp.AngularCoordinate() pix.Ang(pix_center) ang.SetSurveyCoordinates(pix.Lambda(), pix.EtaMin()) pixel_radius = pix_center.AngularDistance(ang) # Start with an annulus that definitely contains the pixel self.assertEqual( pix.IntersectsAnnulus(pix_center, 0.0, 10.0 * pixel_radius), 1) # Now shrink to a radius that is inside, but doesn't contain the pixel self.assertEqual( pix.IntersectsAnnulus(pix_center, 0.0, 0.1 * pixel_radius), -1) # Inscribed, but make it an annulus self.assertEqual( pix.IntersectsAnnulus(pix_center, 0.8 * pixel_radius, 1.25 * pixel_radius), -1) # Circle outside the pixel ang.SetSurveyCoordinates(pix.Lambda(), pix.Eta() + 10.0 * pixel_radius) self.assertEqual(pix.IntersectsAnnulus(ang, 0.0, 0.1 * pixel_radius), 0) # Annulus outside the pixel ang.SetSurveyCoordinates(pix.Lambda(), pix.Eta() + 10.0 * pixel_radius) self.assertEqual( pix.IntersectsAnnulus(ang, 0.1 * pixel_radius, 0.2 * pixel_radius), 0) # Annulus with center outside, but should contain the pixel ang.SetSurveyCoordinates(pix.Lambda(), pix.Eta() + 10.0 * pixel_radius) self.assertEqual( pix.IntersectsAnnulus(ang, 0.1 * pixel_radius, 20.0 * pixel_radius), 1) # Annulus with center outside, but should intersect the pixel ang.SetSurveyCoordinates(pix.Lambda(), pix.Eta() + 2.0 * pixel_radius) self.assertEqual( pix.IntersectsAnnulus(ang, 1.25 * pixel_radius, 2.5 * pixel_radius), -1)
def test_speed(create_each_time=False, explicit=False): from time import time import columns c = columns.Columns("~/sweeps_reduce/gal01.cols") ra = c["ra"][0:500000] dec = c["dec"][0:500000] iw = np.zeros(ra.size, dtype=bool) stomp_map = stomp.Map( "/home/users/esheldon/masks/stomp-sdss/stripe_dr7.hmap_basic") # noqa tm0 = time() if create_each_time: stdout.write("Testing creation of angular coord each time\n") i = 0 while i < ra.size: ang = stomp.AngularCoordinate(ra[i], dec[i], stomp.AngularCoordinate.Equatorial) iw[i] = stomp_map.Contains(ang) del ang i += 1 else: stdout.write("Testing re-setting values of same object\n") i = 0 ang = stomp.AngularCoordinate() if explicit: while i < ra.size: ang.SetEquatorialCoordinates(ra[i], dec[i]) iw[i] = stomp_map.Contains(ang) i += 1 else: system = stomp.AngularCoordinate.Equatorial while i < ra.size: ang.Set(ra[i], dec[i], system) iw[i] = stomp_map.Contains(ang) i += 1 tm1 = time() esutil.misc.ptime(tm1 - tm0)
def testPixelBasic(self): """Test the basic constructors and hierarchy.""" ang = stomp.AngularCoordinate(60.0, 20.0, stomp.AngularCoordinate.Survey) pix = stomp.Pixel(ang, stomp.HPixResolution) for level in range(stomp.HPixLevel, stomp.MaxPixelLevel + 1): resolution = stomp.Pixel.LevelToResolution(level) tmp_pix = stomp.Pixel(ang, resolution) self.assertEqual(pix.Pixnum(), tmp_pix.Superpixnum()) self.assertEqual(pix.Superpixnum(), tmp_pix.Superpixnum())
ra_max = data[args.ra_name].max() dec_min = data[args.dec_name].min() dec_max = data[args.dec_name].max() print("Creating bounding area...") latlon_bound = stomp.LatLonBound(np.double(dec_min), np.double(dec_max), np.double(ra_min), np.double(ra_max), stomp.AngularCoordinate.Equatorial) print("\tMax possible Area: %.8f deg^2" % latlon_bound.Area()) print("Creating STOMP map...") output_stomp_map = stomp.Map() pix_vect = stomp.PixelVector() for obj_idx, obj in enumerate(data): if (obj_idx + 1) % args.n_object_batch == 0: output_stomp_map.IngestMap(pix_vect) pix_vect = stomp.PixelVector() tmp_ang = stomp.AngularCoordinate( np.double(obj[args.ra_name]), np.double(obj[args.dec_name]), stomp.AngularCoordinate.Equatorial) pix_vect.push_back(stomp.Pixel(tmp_ang, args.resolution, 1.0)) output_stomp_map.IngestMap(pix_vect) print("\tFinal Map Area: %.8f deg ^2; Ratio vs bounding box: %.8f" % (output_stomp_map.Area(), output_stomp_map.Area() / latlon_bound.Area())) print("\tObjects per pixel %.8f" % (data.shape[0] / (1. * output_stomp_map.Size()))) output_stomp_map.Write(args.output_stomp_map)
def create_excluded_map(input_mask, ext_map, output_name, resolution, offset, n_points, counter_clockwise_pixels, wcs_file, verbose): """ Given the input mask, a STOMP map to exclude with, we create the covering for the maximum RA and DEC in fits image mask and exclude the area specified in the STOMP map creating a output STOMP map that we can then use for correlations and other analyses. Args: input_mask: string name of the input fits image file ext_map: stomp.Map object specifying the area to exclude output_name: string name of the file to write the resultant STOMP map to resolution: int resolution to create the covering STOMP map at. offset: int number of pixels to offset from the edge of the image. verbose: bool print check statemetns to stdout """ hdu = fits.open(input_mask) if wcs_file is None: w = wcs.WCS(hdu[0].header) else: w = wcs.WCS(fits.getheader(wcs_file)) naxis1_edge_step = ((hdu[0].header['NAXIS1'] - 1 - 2 * offset) // (1. * n_points)) naxis2_edge_step = ((hdu[0].header['NAXIS2'] - 1 - 2 * offset) // (1. * n_points)) if counter_clockwise_pixels: ang_vect = stomp.AngularVector() # South edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[1 + offset + p_idx * naxis1_edge_step, 1 + offset]], np.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) # West edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[ hdu[0].header['NAXIS1'] - offset, 1 + offset + p_idx * naxis2_edge_step ]], p.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) # North edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[ hdu[0].header['NAXIS1'] - offset - p_idx * naxis1_edge_step, hdu[0].header['NAXIS2'] - offset ]], np.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) # East edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[ 1 + offset, hdu[0].header['NAXIS2'] - offset - p_idx * naxis2_edge_step ]], np.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) else: ang_vect = stomp.AngularVector() # South edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[1 + offset, 1 + offset + p_idx * naxis2_edge_step]], np.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) # West edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[ 1 + offset + p_idx * naxis1_edge_step, hdu[0].header['NAXIS2'] - offset ]], np.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) # North edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[ hdu[0].header['NAXIS1'] - offset, hdu[0].header['NAXIS2'] - offset - p_idx * naxis2_edge_step ]], np.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) # East edge: for p_idx in range(n_points): tmp_point = w.wcs_pix2world( np.array([[ hdu[0].header['NAXIS1'] - offset - p_idx * naxis1_edge_step, 1 + offset ]], np.float_), 1)[0] ang_vect.push_back( stomp.AngularCoordinate(tmp_point[0], tmp_point[1], stomp.AngularCoordinate.Equatorial)) bound = stomp.PolygonBound(ang_vect) print("Max Area: %.8f" % bound.Area()) output_stomp_map = stomp.Map(bound, 1.0, resolution, verbose) output_stomp_map.ExcludeMap(ext_map) print("Final Map Area: %.8f" % output_stomp_map.Area()) output_stomp_map.Write(output_name) return None
def create_exclusion(input_mask, output_map_name, max_resolution, max_load, mask_value, mask_is_less_than, wcs_file, verbose): """ Function for creating an exclusion mask from the input fits mask. Mismatch between STOMP pixels and the fits image pixels could cause area the should be masked to be unmasked. By creating the exclusion first and making it slightly larger than the input masked region we can guarantee that all masked area is properly masked. Args: input_mask: string name for fits image mask to load. output_map_name: string output name of the exclusion mask. If None then no map is written. max_resolution: resolution at which to attempt to create the stomp exclusion mask. max_load: int number of pixels to load before dumping them into the STOMP map. verbose: bool print check statements. Returns: a stomp.Map object """ try: mask = fits.getdata(input_mask) # Load the WCS from the input fits file. except ValueError: print("ERROR: Failed to load", input_mask, "exiting") return None hdu = fits.open(input_mask) if wcs_file is None: w = wcs.WCS(hdu[0].header) else: w = wcs.WCS(fits.getheader(wcs_file)) if mask_is_less_than: max_pix = len(mask[mask < mask_value]) else: max_pix = len(mask[mask > mask_value]) print("Max Pix:", max_pix) pix_vect = stomp.PixelVector() tot_pix = 0 output_map = stomp.Map() for idx1 in range(mask.shape[0]): for idx2 in range(mask.shape[1]): if not mask_is_less_than and mask[idx1, idx2] <= 0: continue elif mask_is_less_than and mask[idx1, idx2] >= 0: continue wcs_point = w.wcs_pix2world( np.array([[idx2 + 1, idx1 + 1]], np.float_), 1) ang = stomp.AngularCoordinate(wcs_point[0, 0], wcs_point[0, 1], stomp.AngularCoordinate.Equatorial) if output_map.Contains(ang): continue pix_vect.push_back(stomp.Pixel(ang, max_resolution, 1.0)) if pix_vect.size() >= max_load: tmp_map = stomp.Map(pix_vect) if verbose: print("Created temp map. Area: %s" % tmp_map.Area()) output_map.IngestMap(tmp_map) tot_pix += pix_vect.size() pix_vect.clear() del tmp_map tmp_map = stomp.Map(pix_vect) output_map.IngestMap(tmp_map) tot_pix += pix_vect.size() pix_vect.clear() del tmp_map print("Final Map:", output_map.Area(), output_map.Size()) if output_map_name is not None: output_map.Write(output_map_name) return output_map
def in_window( stomp_map, ra=None, dec=None, clambda=None, ceta=None, b=None, l=None, # noqa x1=None, x2=None, x3=None, radius=None, system=None, ): """ Module: stomp_util Name: in_window Purpose: Check if points are contained within the input stomp map. If radius= is sent, also check against edges and return a tuple (inwindow,edgeflags). """ if ra is not None: if dec is None: raise ValueError("Send both ra and dec") x1 = np.array(ra, ndmin=1, copy=False, dtype="f8") x2 = np.array(dec, ndmin=1, copy=False, dtype="f8") system = "eq" elif clambda is not None: if ceta is None: raise ValueError("Send both clambda and ceta") x1 = np.array(ra, ndmin=1, copy=False, dtype="f8") x2 = np.array(dec, ndmin=1, copy=False, dtype="f8") system = "survey" elif b is not None: if l is None: raise ValueError("Send both l and b") x1 = np.array(l, ndmin=1, copy=False, dtype="f8") x2 = np.array(b, ndmin=1, copy=False, dtype="f8") system = "gal" elif x1 is not None: if x2 is None: raise ValueError("Send both x1 and x2 (possibly x3)") x1 = np.array(x1, ndmin=1, copy=False, dtype="f8") x2 = np.array(x2, ndmin=1, copy=False, dtype="f8") if x3 is not None: x3 = np.array(x3, ndmin=1, copy=False, dtype="f8") system = "sphere" else: if system is None: raise ValueError("If sending x1,x2 you must also send sytem=") else: raise ValueError("A good set of coordinates not found") if x1.size != x2.size: raise ValueError("all coords must be same size") if x3 is not None: x3 = np.array(x3, ndmin=1, copy=False) if x3.size != x2.size: raise ValueError("all coords must be same size") system = "sphere" nrad = 0 if radius is not None: rad = np.array(radius, ndmin=1, copy=False, dtype="f8") if rad.size == 1: nrad = 1 thisrad = rad[0] elif rad.size == x1.size: nrad = x1.size else: raise ValueError("radius must be size 1 or same size as coords") system = system.lower() stomp_system = getsystem(system) if system == "unitsphere" or system == "sphere": # significantly faster to use SetUnitSphereCoordinates # so we will make separate code branch for that dosphere = True else: dosphere = False maskflags = np.zeros(x1.size, dtype="i1") ang = stomp.AngularCoordinate() for i in range(x1.size): if dosphere: ang.SetUnitSphereCoordinates(x1[i], x2[i], x3[i]) else: ang.Set(x1[i], x2[i], stomp_system) is_in_win = stomp_map.Contains(ang) if is_in_win: maskflags[i] += INSIDE_MAP # If radius was sent and we are inside the map, # then do a full quadrant search if nrad > 0: if nrad > 1: thisrad = rad[i] maskflags[i] += quad_check( stomp_map, ang, thisrad, stomp_system, ) return maskflags