示例#1
0
 def random_point(self, lam_min=None, lam_max=None, phi_min=None, 
                  phi_max=None):
     r"""
     Return a point (given in geodetic coordinates) sampled uniformly at
     random from the section of this ellipsoid with longitude in the range
     `lam_min <= lam < lam_max` and latitude in the range 
     `phi_min <= phi < phi_max`.     
     But avoid the poles.
     
     EXAMPLES::
     
        >>> E = UNIT_SPHERE
        >>> print E.random_point() # doctest: +SKIP
        (-1.0999574573422948, 0.21029104897701129)
     """
     PI = self.pi()
     if lam_min is None:
         lam_min = -PI
     if lam_max is None:
         lam_max = PI
     if phi_min is None:
         phi_min = -PI/2
     if phi_max is None:
         phi_max = PI/2 
     if not self.radians:
         # Convert to radians.
         lam_min, lam_max, phi_min, phi_max = deg2rad(
           [lam_min, lam_max, phi_min, phi_max])
     # Pick a longitude.
     while True:
         u = uniform(0, 1)
         lam = (lam_max - lam_min)*u + lam_min
         # Don't include lam_max.
         if lam < lam_max:
             # Success.
             break
     # Pick a latitude.
     delta = pi/360
     while True:
         v = uniform(0, 1)            
         if self.sphere:
             phi = arcsin( (sin(phi_max) - sin(phi_min))*v + sin(phi_min) )  
         else:
             # Sample from the authalic sphere.
             # The map from the ellipsoid to the authalic sphere is
             # an equiareal diffeomorphism. 
             # So a uniform distribution on the authalic sphere gives
             # rise to a uniform distribution on the ellipsoid.
             beta0 = auth_lat(phi_min, e=self.e, radians=True)
             beta1 = auth_lat(phi_max, e=self.e, radians=True)
             beta = arcsin( (sin(beta1) - sin(beta0))*v + sin(beta0) )
             phi = auth_lat(beta, e=self.e, radians=True, inverse=True)
         # Avoid the poles.
         if abs(phi) <= pi/2 - delta:
             # Success.
             break
     if not self.radians:
         # Convert back to degrees.
         lam, phi = rad2deg([lam, phi])
     return lam, phi
    def test_rhealpix_ellipsoid(self):
        # Test map projection.
        # Should return the same output as healpix_ellipsoid(), followed
        # by a scaling down, followed by combine_triangles(),
        # followed by a scaling up.
        e = 0.8
        for (ns, ss) in product(range(4), repeat=2):
            for p in inputs:
                q = rhealpix_ellipsoid(*p,
                                       north_square=ns,
                                       south_square=ss,
                                       e=e)
                qq = healpix_ellipsoid(*p, e=e)
                qq = combine_triangles(*qq, north_square=ns, south_square=ss)
                self.assertEqual(q, qq)

        # Test inverse projection.
        # The inverse of the projection of a point 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), e, inverse=True)
        error = 10 * rel_err(alpha_, alpha)
        for (ns, ss) in product(range(4), repeat=2):
            for p in inputs:
                q = rhealpix_ellipsoid(*p,
                                       north_square=ns,
                                       south_square=ss,
                                       e=e)
                pp = rhealpix_ellipsoid_inverse(*q,
                                                north_square=ns,
                                                south_square=ss,
                                                e=e)
                self.assertTrue(rel_err(p, pp) < error)
示例#3
0
    def test_healpix_ellipsoid(self):
        # Expected output of healpix_ellipsoid() applied to inputs.
        e = 0.8
        healpix_ellipsoid_outputs = []
        for p in inputs:
            lam, phi = p
            beta = auth_lat(phi, e=e, radians=True)
            q = pjh.healpix_sphere(lam, beta)
            healpix_ellipsoid_outputs.append(q)

        # Forward projection should be correct on test points.
        given = inputs
        get = [pjh.healpix_ellipsoid(*p, e=e) for p in given]
        expect = healpix_ellipsoid_outputs
        # Fuzz to allow for rounding errors:
        error = 1e-12
        for i in range(len(get)):
            self.assertTrue(rel_err(get[i], expect[i]) < error)

        # Inverse of projection of a point p should yield p.
        given = get
        get = [pjh.healpix_ellipsoid_inverse(*q, e=e) 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)
        for i in range(len(get)):
            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(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)
    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)
示例#6
0
def isea_ellipsoid(lam, phi, e=0):
    r"""
    Compute the signature functions of the ISEA may projection of an oblate
    ellipsoid with eccentricity `e` whose authalic sphere is the unit sphere.
        
    INPUT:
    
    - `lam, phi` - Geodetic longitude-latitude coordinates in radians.
      Assume -pi <= `lam` < pi and -pi/2 <= `phi` <= pi/2. 
    - `e` - Eccentricity of the oblate ellipsoid.
    """
    beta = auth_lat(phi, e, radians=True)
    return isea_sphere(lam, beta)
示例#7
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)
示例#8
0
def healpix_ellipsoid_inverse(x, y, e=0):
    r"""
    Compute the inverse of healpix_ellipsoid().
    
    EXAMPLES::
    
        >>> p = (0, pi/7)
        >>> q = healpix_ellipsoid(*p)
        >>> print healpix_ellipsoid_inverse(*q), p
        (0, 0.44879895051282759) (0, 0.4487989505128276)
    """
    # Throw error if input coordinates are out of bounds.
    if not in_healpix_image(x, y):
        print "Error: input coordinates (%f, %f) are out of bounds" % \
              (x, y)
        return
    lam, beta = healpix_sphere_inverse(x, y)
    phi = auth_lat(beta, e, radians=True, inverse=True)
    return lam, phi
示例#9
0
def healpix_ellipsoid(lam, phi, e=0):
    r"""
    Compute the signature functions of the HEALPix projection of an oblate
    ellipsoid with eccentricity `e` whose authalic sphere is the unit sphere.
    Works when `e` = 0 (spherical case) too.
        
    INPUT:
    
    - `lam, phi` - Geodetic longitude-latitude coordinates in radians.
      Assume -pi <= `lam` < pi and -pi/2 <= `phi` <= pi/2. 
    - `e` - Eccentricity of the oblate ellipsoid.
    
    EXAMPLES::
    
        >>> print healpix_ellipsoid(0, pi/7)
        (0, 0.51115723774642163)
        >>> print healpix_ellipsoid(0, pi/7, e=0.8)
        (0, 0.26848445085783679)
    """
    beta = auth_lat(phi, e, radians=True)
    return healpix_sphere(lam, beta)