예제 #1
0
def convert_to_dipole(coords, lat_ngp, lon_ngp,
                      coord_type_in=GEOCENTRIC_SPHERICAL):
    """ Convert coordinates (by default geocentric spherical)
    to dipole coordinates defined by the given latitude and longitude
    of the geomagnetic pole.
    The dipole coordinates are a simple rotated coordinate frame in which
    the North pole (dipole latitude == 0) is aligned with the geomagnetic pole
    and the prime meridian (dipole longitude == 0) is the meridian
    passing trough the geomagnetic pole.
    """
    rotation_matrix = get_dipole_rotation_matrix(lat_ngp, lon_ngp)
    coords = convert(coords, coord_type_in, GEOCENTRIC_CARTESIAN)
    coords = dot(coords, rotation_matrix)
    coords = convert(coords, GEOCENTRIC_CARTESIAN, GEOCENTRIC_SPHERICAL)
    return coords
예제 #2
0
 def difflat_spherical_to_geodetic(latitude):
     coords = zeros(latitude.shape + (3,))
     coords[..., 0] = latitude
     coords[..., 2] = 6371.2
     return convert(
         coords, GEOCENTRIC_SPHERICAL, GEODETIC_ABOVE_WGS84
     )[..., 0] - latitude
예제 #3
0
    def reference_sheval(cls, coords):
        coords_spherical = convert(
            coords, cls.source_coordinate_system, GEOCENTRIC_SPHERICAL
        )
        potential = empty(coords_spherical.shape[:-1])
        gradient = empty(coords_spherical.shape)

        iterator = nditer(
            [
                potential,
                gradient[..., 0],
                gradient[..., 1],
                gradient[..., 2],
                coords_spherical[..., 0],
                coords_spherical[..., 1],
                coords_spherical[..., 2],
            ],
            op_flags=[
                ['writeonly'], ['writeonly'], ['writeonly'], ['writeonly'],
                ['readonly'], ['readonly'], ['readonly'],
            ],
        )

        for pot, grd_n, grd_e, grd_r, lat, lon, rad in iterator:
            pot[...], grd_n[...], grd_e[...], grd_r[...] = (
                cls._spherical_harmonics(lat, lon, rad)
            )

        gradient = cls._rotate_gradient(gradient, coords_spherical)
        potential *= cls.scale_potential
        for idx, scale in enumerate(cls.scale_gradient):
            gradient[..., idx] *= scale

        return potential, gradient
예제 #4
0
def convert_to_dipole(coords,
                      lat_ngp,
                      lon_ngp,
                      coord_type_in=GEOCENTRIC_SPHERICAL):
    """ Convert coordinates (by default geocentric spherical)
    to dipole coordinates defined by the given latitude and longitude
    of the geomagnetic pole.
    The dipole coordinates are a simple rotated coordinate frame in which
    the North pole (dipole latitude == 0) is aligned with the geomagnetic pole
    and the prime meridian (dipole longitude == 0) is the meridian
    passing trough the geomagnetic pole.
    """
    rotation_matrix = get_dipole_rotation_matrix(lat_ngp, lon_ngp)
    coords = convert(coords, coord_type_in, GEOCENTRIC_CARTESIAN)
    coords = dot(coords, rotation_matrix)
    coords = convert(coords, GEOCENTRIC_CARTESIAN, GEOCENTRIC_SPHERICAL)
    return coords
예제 #5
0
 def test_eval_reference_values(self):
     times, src_coords, expected_result = self.reference_values
     coords = convert(src_coords, GEOCENTRIC_SPHERICAL, self.coord_type_in)
     model_result = self.eval_model(times, coords)
     try:
         assert_allclose(model_result, expected_result)
     except AssertionError:
         print(tuple(float(f) for f in model_result))
         raise
예제 #6
0
 def test_eval_reference_values(self):
     times, src_coords, expected_result = self.reference_values
     coords = convert(src_coords, GEOCENTRIC_SPHERICAL, self.coord_type_in)
     model_result = self.eval_model(times, coords)
     try:
         assert_allclose(model_result, expected_result)
     except AssertionError:
         print(tuple(float(f) for f in model_result))
         raise
예제 #7
0
 def _rotate_gradient(cls, vectors, coords):
     if cls.target_coordinate_system == GEOCENTRIC_SPHERICAL:
         return vectors
     elif cls.target_coordinate_system == GEOCENTRIC_CARTESIAN:
         latd = coords[..., 0]
         lond = coords[..., 1]
         return vrot_sph2cart(vectors, latd, lond)
     elif cls.target_coordinate_system == GEODETIC_ABOVE_WGS84:
         dlatd = convert(
             coords, GEOCENTRIC_SPHERICAL, cls.target_coordinate_system
         )[..., 0] - coords[..., 0]
         return vrot_sph2geod(vectors, dlatd)
예제 #8
0
 def test_eval_multi_time_invalid(self):
     times = array([
         time
         for time in [nan, self.time_before, self.time, self.time_after]
         if not isinf(time)
     ])
     coords = convert(array([(0, 0, 6371.2) for _ in times]),
                      GEOCENTRIC_SPHERICAL, self.coord_type_in)
     assert_allclose(
         self.eval_model(times, coords),
         self.eval_reference(times, coords),
     )
예제 #9
0
 def _rotate_gradient(cls, vectors, coords):
     if cls.target_coordinate_system == GEOCENTRIC_SPHERICAL:
         return vectors
     elif cls.target_coordinate_system == GEOCENTRIC_CARTESIAN:
         latd = coords[..., 0]
         lond = coords[..., 1]
         return vrot_sph2cart(vectors, latd, lond)
     elif cls.target_coordinate_system == GEODETIC_ABOVE_WGS84:
         dlatd = convert(coords, GEOCENTRIC_SPHERICAL,
                         cls.target_coordinate_system)[..., 0] - coords[...,
                                                                        0]
         return vrot_sph2geod(vectors, dlatd)
예제 #10
0
    def _rotate_gradient(cls, vectors, coords_dipole, coords_in):
        lat_dipole, lon_dipole = coords_dipole[..., 0], coords_dipole[..., 1]
        if cls.target_coordinate_system == GEOCENTRIC_CARTESIAN:
            lat_out, lon_out = None, None
        else:
            coords_out = convert(coords_in, cls.source_coordinate_system,
                                 cls.target_coordinate_system)
            lat_out, lon_out = coords_out[..., 0], coords_out[..., 1]

        return vrot_from_dipole(vectors, cls.lat_ngp, cls.lon_ngp, lat_dipole,
                                lon_dipole, lat_out, lon_out,
                                cls.target_coordinate_system)
예제 #11
0
 def test_eval_multi_time_invalid(self):
     times = array([
         time for time in [nan, self.time_before, self.time, self.time_after]
         if not isinf(time)
     ])
     coords = convert(
         array([(0, 0, 6371.2) for _ in times]),
         GEOCENTRIC_SPHERICAL, self.coord_type_in
     )
     assert_allclose(
         self.eval_model(times, coords),
         self.eval_reference(times, coords),
     )
예제 #12
0
    def _rotate_gradient(cls, vectors, coords_dipole, coords_in):
        lat_dipole, lon_dipole = coords_dipole[..., 0], coords_dipole[..., 1]
        if cls.target_coordinate_system == GEOCENTRIC_CARTESIAN:
            lat_out, lon_out = None, None
        else:
            coords_out = convert(
                coords_in, cls.source_coordinate_system,
                cls.target_coordinate_system
            )
            lat_out, lon_out = coords_out[..., 0], coords_out[..., 1]

        return vrot_from_dipole(
            vectors, cls.lat_ngp, cls.lon_ngp, lat_dipole, lon_dipole,
            lat_out, lon_out, cls.target_coordinate_system
        )
예제 #13
0
 def reference_vrot_from_dipole(cls, vectors, coords, latitude, longitude):
     coords = asarray(coords)
     rotation_matrix = get_dipole_rotation_matrix(latitude, longitude)
     coords_dipole = convert_to_dipole(coords, latitude, longitude)
     lat_dipole = coords_dipole[..., 0]
     lon_dipole = coords_dipole[..., 1]
     vectors = vrot_sph2cart(vectors, lat_dipole, lon_dipole)
     vectors = dot(vectors, rotation_matrix.transpose())
     if cls.target_coords_type != GEOCENTRIC_CARTESIAN:
         coords_out = convert(
             coords, GEOCENTRIC_SPHERICAL, cls.target_coords_type
         )
         lat_out = coords_out[..., 0]
         lon_out = coords_out[..., 1]
         vectors = vrot_cart2sph(vectors, lat_out, lon_out)
     return vectors
예제 #14
0
    def eval_vrot_from_dipole(cls, vectors, coords, latitude, longitude):
        coords = asarray(coords)
        coords_dipole = convert_to_dipole(coords, latitude, longitude)
        lat_dipole = coords_dipole[..., 0]
        lon_dipole = coords_dipole[..., 1]

        if cls.target_coords_type != GEOCENTRIC_CARTESIAN:
            coords_out = convert(
                coords, GEOCENTRIC_SPHERICAL, cls.target_coords_type
            )
            lat_out = coords_out[..., 0]
            lon_out = coords_out[..., 1]
        else:
            lat_out, lon_out = None, None

        return vrot_from_dipole(
            vectors, latitude, longitude, lat_dipole, lon_dipole,
            lat_out, lon_out, cls.target_coords_type
        )
예제 #15
0
    def reference_sheval(cls, coords):
        coords_spherical = convert(coords, cls.source_coordinate_system,
                                   GEOCENTRIC_SPHERICAL)
        potential = empty(coords_spherical.shape[:-1])
        gradient = empty(coords_spherical.shape)

        iterator = nditer(
            [
                potential,
                gradient[..., 0],
                gradient[..., 1],
                gradient[..., 2],
                coords_spherical[..., 0],
                coords_spherical[..., 1],
                coords_spherical[..., 2],
            ],
            op_flags=[
                ['writeonly'],
                ['writeonly'],
                ['writeonly'],
                ['writeonly'],
                ['readonly'],
                ['readonly'],
                ['readonly'],
            ],
        )

        for pot, grd_n, grd_e, grd_r, lat, lon, rad in iterator:
            pot[...], grd_n[...], grd_e[...], grd_r[...] = (
                cls._spherical_harmonics(lat, lon, rad))

        gradient = cls._rotate_gradient(gradient, coords_spherical)
        potential *= cls.scale_potential
        for idx, scale in enumerate(cls.scale_gradient):
            gradient[..., idx] *= scale

        return potential, gradient
예제 #16
0
 def eval_convert_to_dipole(coords, latitude, longitude):
     # to avoid pole longitude ambiguity compare Cartesian coordinates
     return convert(
         convert_to_dipole(coords, latitude, longitude),
         GEOCENTRIC_SPHERICAL, GEOCENTRIC_CARTESIAN
     )
예제 #17
0
 def eval_convert(cls, coords):
     return convert(coords, cls.source_coordinate_system,
                    cls.target_coordinate_system)
예제 #18
0
 def reference_convert_to_dipole(coords, latitude, longitude):
     rotation_matrix = get_dipole_rotation_matrix(latitude, longitude)
     coords = convert(coords, GEOCENTRIC_SPHERICAL, GEOCENTRIC_CARTESIAN)
     coords = dot(coords, rotation_matrix)
     return coords
예제 #19
0
 def coordinates(self):
     return convert(array([
         (lat, lon, 6371.2*uniform(1.0, 2.0)) for lat, lon
         in product(self.range_lat, self.range_lon)
     ]), GEOCENTRIC_SPHERICAL, self.coord_type_in)
예제 #20
0
 def coordinates(self):
     return convert(array([
         (lat, lon, 6371.2*uniform(1.0, 2.0)) for lat, lon
         in product(self.range_lat, self.range_lon)
     ]), GEOCENTRIC_SPHERICAL, self.coord_type_in)
예제 #21
0
 def difflat_geodetic_to_spherical(latitude):
     coords = zeros(latitude.shape + (3,))
     coords[..., 0] = latitude
     return convert(
         coords, GEODETIC_ABOVE_WGS84, GEOCENTRIC_SPHERICAL
     )[..., 0] - latitude
예제 #22
0
 def difflat_geodetic_to_spherical(latitude):
     coords = zeros(latitude.shape + (3, ))
     coords[..., 0] = latitude
     return convert(coords, GEODETIC_ABOVE_WGS84,
                    GEOCENTRIC_SPHERICAL)[..., 0] - latitude
예제 #23
0
 def difflat_spherical_to_geodetic(latitude):
     coords = zeros(latitude.shape + (3, ))
     coords[..., 0] = latitude
     coords[..., 2] = 6371.2
     return convert(coords, GEOCENTRIC_SPHERICAL,
                    GEODETIC_ABOVE_WGS84)[..., 0] - latitude
예제 #24
0
 def eval_convert(cls, coords):
     return convert(
         coords, cls.source_coordinate_system, cls.target_coordinate_system
     )
예제 #25
0
 def coordinates(self):
     return convert(
         array([(lat, lon, 6371.2 * (1.0 + random()))
                for lat, lon in product(range(-90, 91, 5),
                                        range(-180, 181, 10))]),
         GEOCENTRIC_SPHERICAL, GEOCENTRIC_CARTESIAN)
예제 #26
0
 def coordinates(self):
     return convert(array([
         (lat, lon, 6371.2*(1.0 + random())) for lat, lon
         in product(range(-90, 91, 5), range(-180, 181, 10))
     ]), GEOCENTRIC_SPHERICAL, GEOCENTRIC_CARTESIAN)