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
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
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
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
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)
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), )
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)
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)
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), )
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 )
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
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 )
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
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 )
def eval_convert(cls, coords): return convert(coords, cls.source_coordinate_system, cls.target_coordinate_system)
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
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)
def difflat_geodetic_to_spherical(latitude): coords = zeros(latitude.shape + (3,)) coords[..., 0] = latitude return convert( coords, GEODETIC_ABOVE_WGS84, GEOCENTRIC_SPHERICAL )[..., 0] - latitude
def difflat_geodetic_to_spherical(latitude): coords = zeros(latitude.shape + (3, )) coords[..., 0] = latitude return convert(coords, GEODETIC_ABOVE_WGS84, GEOCENTRIC_SPHERICAL)[..., 0] - latitude
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
def eval_convert(cls, coords): return convert( coords, cls.source_coordinate_system, cls.target_coordinate_system )
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)
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)