Пример #1
0
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
Пример #2
0
    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])
Пример #3
0
 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(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=True)
             q = g(lam, beta, radians=True)
             expect.append(tuple(q))
         f = Proj(proj='rhealpix', a=a, e=e,
                  north_square=ns, south_square=ss)
         get = [f(*p, radians=True) 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=True), e, radians=True, 
                       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(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=True)
             get = f(*q, radians=True, inverse=True)   
             print q, expect, get             
             self.assertTrue(rel_err(get, expect) < error)
Пример #4
0
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(f(0, pi/3, radians=True))
        (-0.57495135977821477, 2.1457476865731113)
        >>> p = (0, 60) 
        >>> q = f(*p, radians=False); print(q)
        (-0.57495135977821477, 2.1457476865731113)
        >>> print(f(*q, radians=False, inverse=True), p)
        (6.3611093629270335e-15, 59.999999999999986) (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
Пример #5
0
 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)
Пример #6
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=True)
            q = g(lam, beta, radians=True)
            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=True) 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=True, 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=True), e, radians=True, 
                          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)
Пример #7
0
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 f(0, pi/3, radians=True)
        (-4.7097959155097699, 2.9195761776404252)
        >>> g = isea(a=2, e=0.1)
        >>> print g(0, 60, radians=False)
        (-4.6978889550868494, 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
Пример #8
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
Пример #9
0
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