def csea(a=1, e=0): r""" Return a function object that wraps the ISEA projection and its inverse of an ellipsoid with major radius `a` and eccentricity `e`. OUTPUT: - A function object of the form f(u, v, radians=False, inverse=False). """ R_A = auth_rad(a, e) def f(u, v, radians=False, inverse=False): if not inverse: lam, phi = u, v if not radians: # Convert to radians. lam, phi = deg2rad([lam, phi]) return tuple(R_A*array(csea_ellipsoid(lam, phi, e=e))) else: # Scale down to R_A = 1. x, y = array((u, v))/R_A lam, phi = array(csea_ellipsoid_inverse(x, y, e=e)) if not radians: # Convert to degrees. lam, phi = rad2deg([lam, phi]) return lam, phi return f
def test_rhealpix(self): inputs = [(-pi, pi/3), (0, pi/4), (pi/2, -pi/6)] # Should agree with rhealpix_ellipsoid and rhealpix_ellipsoid_inverse. e = 0.5 a = 7 R_A = auth_rad(a, e) f = pjr.rhealpix(a=a, e=e) for p in inputs: get = f(*p, radians=True) expect = tuple(R_A*array(pjr.rhealpix_ellipsoid(*p, e=e))) for i in range(len(expect)): self.assertAlmostEqual(get[i], expect[i]) get = f(*get, radians=True, inverse=True) expect = tuple(array(expect)/R_A) expect = pjr.rhealpix_ellipsoid_inverse(*expect, e=e) for i in range(len(expect)): self.assertAlmostEqual(get[i], expect[i]) # Should work in degrees mode. for p in inputs: get = f(*rad2deg(p), radians=False) expect = f(*p, radians=True) for i in range(len(expect)): self.assertAlmostEqual(get[i], expect[i])
def isea(a=1, e=0): r""" Return a function object that wraps the ISEA projection and its inverse of an ellipsoid with major radius `a` and eccentricity `e`. EXAMPLES:: >>> f = isea(a=2, e=0) >>> print(my_round(f(0, pi/3, radians=True), 15)) (-4.7097959155097699, 2.9195761776404252) >>> g = isea(a=2, e=0.1) >>> print(my_round(g(0, 60, radians=False), 15)) (-4.6978889550868486, 2.9179977608222689) OUTPUT: - A function object of the form f(u, v, radians=False, inverse=False). """ R_A = auth_rad(a, e) def f(u, v, radians=False, inverse=False): if not inverse: lam, phi = u, v if not radians: # Convert to radians. lam, phi = deg2rad([lam, phi]) return tuple(R_A*array(isea_ellipsoid(lam, phi, e=e))) else: # Scale down to R_A = 1. x, y = array((u, v))/R_A lam, phi = array(isea_ellipsoid_inverse(x, y, e=e)) if not radians: # Convert to degrees. lam, phi = rad2deg([lam, phi]) return lam, phi return f
def test_healpix(self): inputs = [(-pi, pi/3), (0, pi/4), (pi/2, -pi/6)] # Should agree with healpix_ellipsoid and healpix_ellipsoid_inverse. e = 0.5 a = 7 R_A = auth_rad(a, e) f = pjh.healpix(a=a, e=e) for p in inputs: get = f(*p, radians=True) expect = tuple(R_A*array(pjh.healpix_ellipsoid(*p, e=e))) for i in range(len(expect)): self.assertAlmostEqual(get[i], expect[i]) get = f(*get, radians=True, inverse=True) expect = tuple(array(expect)/R_A) expect = pjh.healpix_ellipsoid_inverse(*expect, e=e) for i in range(len(expect)): self.assertAlmostEqual(get[i], expect[i]) # Should work in degrees mode. for p in inputs: get = f(*rad2deg(p), radians=False) expect = f(*p, radians=True) for i in range(len(expect)): self.assertAlmostEqual(get[i], expect[i])
def csea(a=1, e=0): r""" Return a function object that wraps the ISEA projection and its inverse of an ellipsoid with major radius `a` and eccentricity `e`. OUTPUT: - A function object of the form f(u, v, radians=False, inverse=False). """ R_A = auth_rad(a, e) def f(u, v, radians=False, inverse=False): if not inverse: lam, phi = u, v if not radians: # Convert to radians. lam, phi = deg2rad([lam, phi]) return tuple(R_A * array(csea_ellipsoid(lam, phi, e=e))) else: # Scale down to R_A = 1. x, y = array((u, v)) / R_A lam, phi = array(csea_ellipsoid_inverse(x, y, e=e)) if not radians: # Convert to degrees. lam, phi = rad2deg([lam, phi]) return lam, phi return f
def rhealpix(a=1, e=0, north_square=0, south_square=0): r""" Return a function object that wraps the rHEALPix projection and its inverse of an ellipsoid with major radius `a` and eccentricity `e`. EXAMPLES:: >>> f = rhealpix(a=2, e=0, north_square=1, south_square=2) >>> print(my_round(f(0, pi/3, radians=True), 15)) (-0.57495135977821499, 2.1457476865731109) >>> p = (0, 60) >>> q = f(*p, radians=False) >>> print(my_round(q, 15)) (-0.57495135977821499, 2.1457476865731109) >>> print(my_round(f(*q, radians=False, inverse=True), 15)) (5.9999999999999997e-15, 59.999999999999986) >>> print(my_round(p, 15)) (0, 60) OUTPUT: - A function object of the form f(u, v, radians=False, inverse=False). """ R_A = auth_rad(a, e) def f(u, v, radians=False, inverse=False): if not inverse: lam, phi = u, v if not radians: # Convert to radians. lam, phi = deg2rad([lam, phi]) return tuple(R_A * array( rhealpix_ellipsoid(lam, phi, e=e, north_square=north_square, south_square=south_square))) else: # Scale down to R_A = 1. x, y = array((u, v)) / R_A lam, phi = array( rhealpix_ellipsoid_inverse(x, y, e=e, north_square=north_square, south_square=south_square)) if not radians: # Convert to degrees. lam, phi = rad2deg([lam, phi]) return lam, phi return f
def healpix_diagram(a=1, e=0, shade_polar_region=True): r""" Return a Sage Graphics object diagramming the HEALPix projection boundary and polar triangles for the ellipsoid with major radius `a` and eccentricity `e`. Inessential graphics method. Requires Sage graphics methods. """ from sage.all import Graphics, line2d, point, polygon, text, RealNumber, Integer # Make Sage types compatible with Numpy. RealNumber = float Integer = int R = auth_rad(a, e) g = Graphics() color = 'black' # Boundary color. shade_color = 'blue' # Polar triangles color. dl = array((R*pi/2,0)) lu = [(-R*pi, R*pi/4),(-R*3*pi/4, R*pi/2)] ld = [(-R*3*pi/4, R*pi/2),(-R*pi/2, R*pi/4)] g += line2d([(-R*pi, -R*pi/4),(-R*pi, R*pi/4)], color=color) g += line2d([(R*pi, R*pi/4),(R*pi, -R*pi/4)], linestyle = '--', color=color) for k in range(4): g += line2d([array(p) + k*dl for p in lu], color=color) g += line2d([array(p) + k*dl for p in ld], linestyle = '--', color=color) g += line2d([array(p) + array((k*R*pi/2 - R*pi/4, -R*3*pi/4)) for p in ld], color=color) g += line2d([array(p) + array((k*R*pi/2 + R*pi/4, -R*3*pi/4)) for p in lu], linestyle = '--', color=color) pn = array((-R*3*pi/4, R*pi/2)) ps = array((-R*3*pi/4, -R*pi/2)) g += point([pn + k*dl for k in range(4)] + [ps + k*dl for k in range(4)], size=20, color=color) g += point([pn + k*dl for k in range(1, 4)] + [ps + k*dl for k in range(1, 4)], color='white', size=10, zorder=3) npp = [(-R*pi, R*pi/4), (-R*3*pi/4, R*pi/2), (-R*pi/2, R*pi/4)] spp = [(-R*pi, -R*pi/4), (-R*3*pi/4, -R*pi/2), (-R*pi/2, -R*pi/4)] if shade_polar_region: for k in range(4): g += polygon([array(p) + k*dl for p in npp], alpha=0.1, color=shade_color) g += text(str(k), array((-R*3*pi/4, R*5*pi/16)) + k*dl, color='red', fontsize=20) g += polygon([array(p) + k*dl for p in spp], alpha=0.1, color=shade_color) g += text(str(k), array((-R*3*pi/4, -R*5*pi/16)) + k*dl, color='red', fontsize=20) return g
def test_healpix_ellipsoid(self): # Ellipsoid parameters. a = 5 e = 0.8 R_A = auth_rad(a, e=e) # Expected output of healpix_ellipsoid() applied to inputs. healpix_ellipsoid_outputs = [] g = Proj(proj='healpix', R=R_A) for p in inputs: lam, phi = p beta = auth_lat(phi, e=e, radians=RADIANS) q = g(lam, beta, radians=RADIANS) healpix_ellipsoid_outputs.append(q) # Forward projection should be correct on test points. f = Proj(proj='healpix', a=a, e=e) given = inputs get = [f(*p, radians=RADIANS) for p in given] expect = healpix_ellipsoid_outputs # Fuzz to allow for rounding errors: error = 1e-12 print('=' * 80) print( 'HEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (radians) / expected output (meters) / received output') print('=' * 80) for i in range(len(get)): print(given[i], expect[i], get[i]) self.assertTrue(rel_err(get[i], expect[i]) < error) # Inverse of projection of a point p should yield p. given = get get = [f(*q, radians=RADIANS, inverse=True) for q in given] expect = inputs # Fuzz for rounding errors based on the error of the approximation to # the inverse authalic latitude function: alpha = PI / 4 alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS), e, radians=RADIANS, inverse=True) error = 10 * rel_err(alpha_, alpha) print('=' * 80) print( 'HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (meters) / expected output (radians) / received output') print('=' * 80) for i in range(len(get)): print(given[i], expect[i], get[i]) self.assertTrue(rel_err(get[i], expect[i]) < error)
def test_rhealpix_ellipsoid(self): # Ellipsoid parameters. a = 5 e = 0.8 R_A = auth_rad(a, e=e) # Forward projection should be correct on test points. print('='*80) print('rHEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (radians) / expected output (meters) / received output') print('='*80) given = inputs # Fuzz to allow for rounding errors: error = 1e-12 for (ns, ss) in product(list(range(4)), repeat=2): print('_____ north_square = %s, south_square = %s' % (ns, ss)) expect = [] g = Proj(proj='rhealpix', R=R_A, north_square=ns, south_square=ss) for p in given: lam, phi = p beta = auth_lat(phi, e=e, radians=RADIANS) q = g(lam, beta, radians=RADIANS) expect.append(tuple(q)) f = Proj(proj='rhealpix', a=a, e=e, north_square=ns, south_square=ss) get = [f(*p, radians=RADIANS) for p in given] for i in range(len(given)): print(given[i], expect[i], get[i]) self.assertTrue(rel_err(get[i], expect[i]) < error) # Inverse of projection of point a p should yield p. # Fuzz for rounding errors based on the error of the approximation to # the inverse authalic latitude function: alpha = PI/4 alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS), e, radians=RADIANS, inverse=True) error = 10*rel_err(alpha_, alpha) print('='*80) print('HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (meters) / expected output (radians) / received output') print('='*80) # The inverse of the projection of a point p should yield p. for (ns, ss) in product(list(range(4)), repeat=2): print('_____ north_square = %s, south_square = %s' % (ns, ss)) f = Proj(proj='rhealpix', a=a, e=e, north_square=ns, south_square=ss) for p in inputs: expect = p q = f(*p, radians=RADIANS) get = f(*q, radians=RADIANS, inverse=True) print(q, expect, get) self.assertTrue(rel_err(get, expect) < error)
def __init__(self, R=None, a=WGS84_A, b=None, e=None, f=WGS84_F, lon_0=0, lat_0=0, radians=False): self.lon_0 = lon_0 self.lat_0 = lat_0 self.radians = radians if R is not None: # The ellipsoid is a sphere. # Override the other geometric parameters. self.sphere = True self.R = R self.a = R self.b = R self.e = 0 self.f = 0 self.R_A = R else: self.sphere = False self.a = a if b is not None: # Derive the other geometric parameters from a and b. self.b = b self.e = sqrt(1 - (b / a)**2) self.f = (a - b) / a elif e is not None: # Derive the other geometric parameters from a and e. self.e = e self.b = a * sqrt(1 - e**2) self.f = 1 - sqrt(1 - e**2) else: self.f = f self.b = self.a * (1 - f) self.e = sqrt(f * (1 - f)) self.R_A = auth_rad(self.a, self.e) self.phi_0 = auth_lat(arcsin(2.0 / 3), e=self.e, radians=True, inverse=True) if not self.radians: # Convert to degrees. self.phi_0 = rad2deg(self.phi_0)
def test_healpix_ellipsoid(self): # Ellipsoid parameters. a = 5 e = 0.8 R_A = auth_rad(a, e=e) # Expected output of healpix_ellipsoid() applied to inputs. healpix_ellipsoid_outputs = [] g = Proj(proj='healpix', R=R_A) for p in inputs: lam, phi = p beta = auth_lat(phi, e=e, radians=RADIANS) q = g(lam, beta, radians=RADIANS) healpix_ellipsoid_outputs.append(q) # Forward projection should be correct on test points. f = Proj(proj='healpix', a=a, e=e) given = inputs get = [f(*p, radians=RADIANS) for p in given] expect = healpix_ellipsoid_outputs # Fuzz to allow for rounding errors: error = 1e-12 print('='*80) print('HEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (radians) / expected output (meters) / received output') print('='*80) for i in range(len(get)): print(given[i], expect[i], get[i]) self.assertTrue(rel_err(get[i], expect[i]) < error) # Inverse of projection of a point p should yield p. given = get get = [f(*q, radians=RADIANS, inverse=True) for q in given] expect = inputs # Fuzz for rounding errors based on the error of the approximation to # the inverse authalic latitude function: alpha = PI/4 alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS), e, radians=RADIANS, inverse=True) error = 10*rel_err(alpha_, alpha) print('='*80) print('HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (meters) / expected output (radians) / received output') print('='*80) for i in range(len(get)): print(given[i], expect[i], get[i]) self.assertTrue(rel_err(get[i], expect[i]) < error)
def rhealpix(a=1, e=0, north_square=0, south_square=0): r""" Return a function object that wraps the rHEALPix projection and its inverse of an ellipsoid with major radius `a` and eccentricity `e`. EXAMPLES:: >>> f = rhealpix(a=2, e=0, north_square=1, south_square=2) >>> print(my_round(f(0, pi/3, radians=True), 15)) (-0.57495135977821499, 2.1457476865731109) >>> p = (0, 60) >>> q = f(*p, radians=False) >>> print(my_round(q, 15)) (-0.57495135977821499, 2.1457476865731109) >>> print(my_round(f(*q, radians=False, inverse=True), 15)) (5.9999999999999997e-15, 59.999999999999986) >>> print(my_round(p, 15)) (0, 60) OUTPUT: - A function object of the form f(u, v, radians=False, inverse=False). """ R_A = auth_rad(a, e) def f(u, v, radians=False, inverse=False): if not inverse: lam, phi = u, v if not radians: # Convert to radians. lam, phi = deg2rad([lam, phi]) return tuple(R_A*array(rhealpix_ellipsoid(lam, phi, e=e, north_square=north_square, south_square=south_square))) else: # Scale down to R_A = 1. x, y = array((u, v))/R_A lam, phi = array(rhealpix_ellipsoid_inverse(x, y, e=e, north_square=north_square, south_square=south_square)) if not radians: # Convert to degrees. lam, phi = rad2deg([lam, phi]) return lam, phi return f
def __init__(self, R=None, a=WGS84_A, b=None, e=None, f=WGS84_F, lon_0=0, lat_0=0, radians=False): self.lon_0 = lon_0 self.lat_0 = lat_0 self.radians = radians if R is not None: # The ellipsoid is a sphere. # Override the other geometric parameters. self.sphere = True self.R = R self.a = R self.b = R self.e = 0 self.f = 0 self.R_A = R else: self.sphere = False self.a = a if b is not None: # Derive the other geometric parameters from a and b. self.b = b self.e = sqrt(1 - (b/a)**2) self.f = (a - b)/a elif e is not None: # Derive the other geometric parameters from a and e. self.e = e self.b = a*sqrt(1 - e**2) self.f = 1 - sqrt(1 - e**2) else: self.f = f self.b = self.a*(1 - f) self.e = sqrt(f*(1 - f)) self.R_A = auth_rad(self.a, self.e) self.phi_0 = auth_lat(arcsin(2.0/3), e=self.e, radians=True, inverse=True) if not self.radians: # Convert to degrees. self.phi_0 = rad2deg(self.phi_0)
def rhealpix_diagram(a=1, e=0, north_square=0, south_square=0, shade_polar_region=True): r""" Return a Sage Graphics object diagramming the rHEALPix projection boundary and polar triangles for the ellipsoid with major radius `a` and eccentricity `e`. Inessential graphics method. Requires Sage graphics methods. """ from sage.all import Graphics, line2d, point, polygon, text, RealNumber, Integer # Make Sage types compatible with Numpy. RealNumber = float Integer = int R = auth_rad(a, e) g = Graphics() color = 'black' # Boundary color. shade_color = 'blue' # Polar triangles color. north = north_square south = south_square south_sq = [(-R * pi + R * south * pi / 2, -R * pi / 4), (-R * pi + R * south * pi / 2, -R * 3 * pi / 4), (-R * pi + R * (south + 1) * pi / 2, -R * 3 * pi / 4), (-R * pi + R * (south + 1) * pi / 2, -R * pi / 4)] north_sq = [(-R * pi + R * north * pi / 2, R * pi / 4), (-R * pi + R * north * pi / 2, R * 3 * pi / 4), (-R * pi + R * (north + 1) * pi / 2, R * 3 * pi / 4), (-R * pi + R * (north + 1) * pi / 2, R * pi / 4)] # Outline. g += line2d(south_sq, linestyle='--', color=color) g += line2d(north_sq, linestyle='--', color=color) g += line2d([(R * pi, -R * pi / 4), (R * pi, R * pi / 4)], linestyle='--', color=color) g += line2d([ north_sq[0], (-R * pi, R * pi / 4), (-R * pi, -R * pi / 4), south_sq[0] ], color=color) g += line2d([south_sq[3], (R * pi, -R * pi / 4)], color=color) g += line2d([north_sq[3], (R * pi, R * pi / 4)], color=color) g += point([south_sq[0], south_sq[3]], size=20, zorder=3, color=color) g += point([north_sq[0], north_sq[3]], size=20, zorder=3, color=color) g += point([(R * pi, -R * pi / 4), (R * pi, R * pi / 4)], size=20, zorder=3, color=color) g += point([(R * pi, -R * pi / 4), (R * pi, R * pi / 4)], size=10, color='white', zorder=3) if shade_polar_region: # Shade. g += polygon(south_sq, alpha=0.1, color=shade_color) g += polygon(north_sq, alpha=0.1, color=shade_color) # Slice square into polar triangles. g += line2d([south_sq[0], south_sq[2]], color='lightgray') g += line2d([south_sq[1], south_sq[3]], color='lightgray') g += line2d([north_sq[0], north_sq[2]], color='lightgray') g += line2d([north_sq[1], north_sq[3]], color='lightgray') # Label polar triangles. sp = south_sq[0] + R * array((pi / 4, -pi / 4)) np = north_sq[0] + R * array((pi / 4, pi / 4)) shift = R * 3 * pi / 16 g += text(str(south), sp + array((0, shift)), color='red', fontsize=20) g += text(str((south + 1) % 4), sp + array((shift, 0)), color='red', rotation=90, fontsize=20) g += text(str((south + 2) % 4), sp + array((0, -shift)), color='red', rotation=180, fontsize=20) g += text(str((south + 3) % 4), sp + array((-shift, 0)), color='red', rotation=270, fontsize=20) g += text(str(north), np + array((0, -shift)), color='red', fontsize=20) g += text(str((north + 1) % 4), np + array((shift, 0)), color='red', rotation=90, fontsize=20) g += text(str((north + 2) % 4), np + array((0, shift)), color='red', rotation=180, fontsize=20) g += text(str((north + 3) % 4), np + array((-shift, 0)), color='red', rotation=270, fontsize=20) return g
def rhealpix_diagram(a=1, e=0, north_square=0, south_square=0, shade_polar_region=True): r""" Return a Sage Graphics object diagramming the rHEALPix projection boundary and polar triangles for the ellipsoid with major radius `a` and eccentricity `e`. Inessential graphics method. Requires Sage graphics methods. """ from sage.all import Graphics, line2d, point, polygon, text, RealNumber, Integer # Make Sage types compatible with Numpy. RealNumber = float Integer = int R = auth_rad(a, e) g = Graphics() color = 'black' # Boundary color. shade_color = 'blue' # Polar triangles color. north = north_square south = south_square south_sq = [(-R*pi + R*south*pi/2, -R*pi/4), (-R*pi + R*south*pi/2, -R*3*pi/4), (-R*pi + R*(south + 1)*pi/2, -R*3*pi/4), (-R*pi + R*(south + 1)*pi/2, -R*pi/4)] north_sq = [(-R*pi + R*north*pi/2, R*pi/4), (-R*pi + R*north*pi/2, R*3*pi/4), (-R*pi + R*(north + 1)*pi/2, R*3*pi/4), (-R*pi + R*(north + 1)*pi/2, R*pi/4)] # Outline. g += line2d(south_sq, linestyle = '--', color=color) g += line2d(north_sq, linestyle = '--', color=color) g += line2d([(R*pi, -R*pi/4), (R*pi, R*pi/4)], linestyle='--', color=color) g += line2d([north_sq[0], (-R*pi, R*pi/4), (-R*pi, -R*pi/4), south_sq[0]], color=color) g += line2d([south_sq[3], (R*pi, -R*pi/4)], color=color) g += line2d([north_sq[3],(R*pi, R*pi/4)], color=color) g += point([south_sq[0], south_sq[3]], size=20, zorder=3, color=color) g += point([north_sq[0], north_sq[3]], size=20, zorder=3, color=color) g += point([(R*pi, -R*pi/4), (R*pi, R*pi/4)], size=20, zorder=3, color=color) g += point([(R*pi, -R*pi/4), (R*pi, R*pi/4)], size=10, color='white', zorder=3) if shade_polar_region: # Shade. g += polygon(south_sq, alpha=0.1, color=shade_color) g += polygon(north_sq, alpha=0.1, color=shade_color) # Slice square into polar triangles. g += line2d([south_sq[0], south_sq[2]], color='lightgray') g += line2d([south_sq[1], south_sq[3]], color='lightgray') g += line2d([north_sq[0], north_sq[2]], color='lightgray') g += line2d([north_sq[1], north_sq[3]], color='lightgray') # Label polar triangles. sp = south_sq[0] + R*array((pi/4, -pi/4)) np = north_sq[0] + R*array((pi/4, pi/4)) shift = R*3*pi/16 g += text(str(south), sp + array((0, shift)), color='red', fontsize=20) g += text(str((south + 1) % 4), sp + array((shift, 0)), color='red', rotation=90, fontsize=20) g += text(str((south + 2) % 4), sp + array((0, -shift)), color='red', rotation=180, fontsize=20) g += text(str((south + 3) % 4), sp + array((-shift, 0)), color='red', rotation=270, fontsize=20) g += text(str(north), np + array((0, -shift)), color='red', fontsize=20) g += text(str((north + 1) % 4), np + array((shift, 0)), color='red', rotation=90, fontsize=20) g += text(str((north + 2) % 4), np + array((0, shift)), color='red', rotation=180, fontsize=20) g += text(str((north + 3) % 4), np + array((-shift, 0)), color='red', rotation=270, fontsize=20) return g
def test_rhealpix_ellipsoid(self): # Ellipsoid parameters. a = 5 e = 0.8 R_A = auth_rad(a, e=e) # Forward projection should be correct on test points. print('=' * 80) print( 'rHEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (radians) / expected output (meters) / received output') print('=' * 80) given = inputs # Fuzz to allow for rounding errors: error = 1e-12 for (ns, ss) in product(list(range(4)), repeat=2): print('_____ north_square = %s, south_square = %s' % (ns, ss)) expect = [] g = Proj(proj='rhealpix', R=R_A, north_square=ns, south_square=ss) for p in given: lam, phi = p beta = auth_lat(phi, e=e, radians=RADIANS) q = g(lam, beta, radians=RADIANS) expect.append(tuple(q)) f = Proj(proj='rhealpix', a=a, e=e, north_square=ns, south_square=ss) get = [f(*p, radians=RADIANS) for p in given] for i in range(len(given)): print(given[i], expect[i], get[i]) self.assertTrue(rel_err(get[i], expect[i]) < error) # Inverse of projection of point a p should yield p. # Fuzz for rounding errors based on the error of the approximation to # the inverse authalic latitude function: alpha = PI / 4 alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS), e, radians=RADIANS, inverse=True) error = 10 * rel_err(alpha_, alpha) print('=' * 80) print( 'HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e)) print('input (meters) / expected output (radians) / received output') print('=' * 80) # The inverse of the projection of a point p should yield p. for (ns, ss) in product(list(range(4)), repeat=2): print('_____ north_square = %s, south_square = %s' % (ns, ss)) f = Proj(proj='rhealpix', a=a, e=e, north_square=ns, south_square=ss) for p in inputs: expect = p q = f(*p, radians=RADIANS) get = f(*q, radians=RADIANS, inverse=True) print(q, expect, get) self.assertTrue(rel_err(get, expect) < error)