def test_sun_position(self):

        start = d.mjd2000(1910, 1, 1)
        end = d.mjd2000(2090, 12, 31)
        time = np.linspace(start, end, 100)

        theta, phi = c.sun_position(time)

        # load matfile
        test = load_matfile(MATFILE_PATH, 'test_sun_position')

        # reduce 2-D matrix to 1-D vectors
        theta_mat = np.ravel(test['theta'])
        phi_mat = np.ravel(test['phi'])

        self.assertIsNone(np.testing.assert_allclose(theta, theta_mat))
        self.assertIsNone(np.testing.assert_allclose(phi, phi_mat))

        # test position of sun close to zenith in Greenwich
        # (lat 51.48, lon -0.0077) on July 18, 2018, 12h06 (from
        # sunearthtools.com):

        time_gmt = d.mjd2000(2018, 7, 18, 12, 6)
        lat = 51.4825766  # geogr. latitude
        lon = -0.0076589  # geogr. longitude
        el = 59.59  # elevation above horizon
        az = 179.86  # angle measured from north (sun close to zenith)

        theta_gmt = 180. - (el + lat)  # subsolar colat. given geogr. lat.
        phi_gmt = 180. + (lon - az)  # subsolar phi given geogr. longitude

        theta, phi = c.sun_position(time_gmt)

        self.assertAlmostEqual(theta_gmt, theta, places=0)
        self.assertAlmostEqual(phi_gmt, phi, places=0)
    def test_zenith_angle(self):
        """
        Compared zenith angle with NOAA
        `https://www.esrl.noaa.gov/gmd/grad/antuv/SolarCalc.jsp`_ .

        DANGER: longitude means the hour angle which is negative geographic
        longitude

        """

        zeta = c.zenith_angle(d.mjd2000(2019, 8, 1), 90., 0.)
        self.assertIsNone(np.testing.assert_allclose(
            zeta, 161.79462, rtol=1e-5))

        zeta = c.zenith_angle(d.mjd2000(2013, 8, 1), 77., -54.)
        self.assertIsNone(np.testing.assert_allclose(
            zeta, 117.00128, rtol=1e-5))

        zeta = c.zenith_angle(d.mjd2000(2013, 3, 20, 12), 90., 0.)
        self.assertIsNone(np.testing.assert_allclose(
            zeta, 1.85573, rtol=1e-4))

        zeta = c.zenith_angle(d.mjd2000(2013, 3, 20, 10), 90., 0.)
        self.assertIsNone(np.testing.assert_allclose(
            zeta, 31.85246, rtol=1e-3))

        zeta = c.zenith_angle(d.mjd2000(2013, 3, 20, 14), 90., 0.)
        self.assertIsNone(np.testing.assert_allclose(
            zeta, 28.14153, rtol=1e-3))
Beispiel #3
0
    def test_mjd2000_broadcasting(self):
        """
        Ensure broadcasting works
        """

        actual = cpd.mjd2000(np.arange(2000, 2003), 2, 1)
        desired = np.array([  31.,  397.,  762.])
        np.testing.assert_allclose(actual, desired)

        actual = cpd.mjd2000(2000, 2, 1, np.arange(3))
        desired = 31. + np.arange(3)/24
        np.testing.assert_allclose(actual, desired)
Beispiel #4
0
def example6():
    """
    Plot maps of external and internal sources described in SM and GSM
    reference systems.

    """

    model = load_CHAOS_matfile(FILEPATH_CHAOS)

    radius = R_REF + 450
    time = mjd2000(2015, 9, 1, 12)

    model.plot_maps_external(time, radius, reference='all', source='all')
Beispiel #5
0
def example3():
    """
    Plot maps of core field and its derivatives for different times and
    radii.

    """

    model = load_CHAOS_matfile(FILEPATH_CHAOS)

    radius = 0.53 * R_REF  # radial distance in km of core-mantle boundary
    time = mjd2000(2015, 9, 1)  # year, month, day

    model.plot_maps_tdep(time, radius, nmax=16, deriv=1)
Beispiel #6
0
def CHAOS_ground_values(GPS_ResInt):
    #1. Load the requiered parameters, including a local CHAOS model in mat format.
    model = load_CHAOS_matfile(r'CHAOS-7.mat')
    theta = 90 - GPS_ResInt['Latitude'].values
    phi = GPS_ResInt['Longitude'].values
    alt = GPS_ResInt['Altitude'].values
    rad_geoc_ground, theta_geoc_ground, sd_ground, cd_ground = gg_to_geo(
        alt, theta
    )  # gg_to_geo, will transfor the coordinates from geocentric values to geodesic values. Altitude must be in km
    time = mjd2000(
        pd.DatetimeIndex(GPS_ResInt['DateTime']).year,
        pd.DatetimeIndex(GPS_ResInt['DateTime']).month,
        pd.DatetimeIndex(GPS_ResInt['DateTime']).day)

    #2. Compute the core, crust and magentoshpere contributions at the altitude level.
    B_r_core, B_t_core, B_phi_core = model.synth_values_tdep(
        time, rad_geoc_ground, theta_geoc_ground, phi)  #Core Contribution
    B_r_crust, B_t_crust, B_phi_crust = model.synth_values_static(
        rad_geoc_ground, theta_geoc_ground, phi)  #Crust Contribution
    B_r_magneto, B_t_magneto, B_phi_magneto = model.synth_values_gsm(
        time, rad_geoc_ground, theta_geoc_ground,
        phi)  #Magnetosphere contribution.

    #3. Change the direcction of the axis from XYZ to r,theta and phi.
    B_r_swarm, B_t_swarm, B_phi_swarm = -GPS_ResInt['C_res'], -GPS_ResInt[
        'N_res'], GPS_ResInt['E_res']

    #4. Compute the magnetic component (r,theta,phi) at ground level.
    B_r_ground = B_r_core + B_r_crust + B_r_magneto + B_r_swarm  #(-Z)
    B_t_ground = B_t_core + B_t_crust + B_t_magneto + B_t_swarm  #(-X)
    B_phi_ground = B_phi_core + B_phi_crust + B_phi_magneto + B_phi_swarm  #(Y)

    #5. Convert B_r_, B_t_, and B_phi to XYZ (NEC)
    Z_chaos = -B_r_ground  #Z
    X_chaos = -B_t_ground  #X
    Y_chaos = B_phi_ground  #Y

    #6. Rotate the X(N) and Z(C) magnetic field values of the chaos models into the geodectic frame using the sd and cd (sine and cosine d from gg_to_geo)
    X_obs = X_chaos * cd_ground + Z_chaos * sd_ground  #New N
    Z_obs = Z_chaos * cd_ground - X_chaos * sd_ground  #New C
    Y_obs = Y_chaos  # New E
    return X_obs, Y_obs, Z_obs
Beispiel #7
0
    def test_time_conversion(self):

        size = (10, )
        days = np.random.randint(365., size=size)
        hours = np.random.randint(24, size=size)
        minutes = np.random.randint(60, size=size)
        seconds = np.random.randint(60, size=size)

        for day, hour, minute, second in zip(days, hours, minutes, seconds):
            date = (timedelta(days=int(day)) +
                    datetime(1990, 1, 1, hour, minute, second))

            mjd = d.mjd2000(date.year, date.month, date.day, date.hour,
                            date.minute, date.second)

            dyear = d.mjd_to_dyear(mjd, leap_year=True)
            mjd2 = d.dyear_to_mjd(dyear, leap_year=True)
            self.assertIsNone(np.testing.assert_allclose(mjd2, mjd, atol=1e-8))

            dyear = d.mjd_to_dyear(mjd, leap_year=False)
            mjd2 = d.dyear_to_mjd(dyear, leap_year=False)
            self.assertIsNone(np.testing.assert_allclose(mjd2, mjd, atol=1e-8))

            dyear = d.mjd_to_dyear(mjd, leap_year=True)
            mjd2 = d.dyear_to_mjd(dyear, leap_year=False)
            self.assertRaises(
                AssertionError,
                lambda: np.testing.assert_allclose(mjd2, mjd, atol=1e-8))

            dyear = d.mjd_to_dyear(mjd, leap_year=False)
            mjd2 = d.dyear_to_mjd(dyear, leap_year=True)
            self.assertRaises(
                AssertionError,
                lambda: np.testing.assert_allclose(mjd2, mjd, atol=1e-8))

            dyear = d.mjd_to_dyear(mjd, leap_year=False)
            mjd2 = d.dyear_to_mjd(dyear, leap_year=None)
            self.assertRaises(
                AssertionError,
                lambda: np.testing.assert_allclose(mjd2, mjd, atol=1e-8))
def declination(glat, glon, radius, year):
    """
    Calculates the Declination angle of the each data point from the CHAOS model
    
    Parameters
    ----------
    glat : numpy.ndarray (degrees)
        geographic lattitude.
    glon : numpy.ndarray (degrees)
        geographic longitude.
    radius : float, optional
        the radius from the centre of the earth to the points.
    year : int
        year.
    Returns
    -------
    numpy.ndarray (radians)
        Declination used to rotate the magnetometer vectors.

    """
    pysymmetry_path = '/Home/siv32/zef014/'
    if pysymmetry_path not in sys.path:
        sys.path.append(pysymmetry_path)
    sys.path.insert(1, '/Home/siv32/zef014/pysymmetry/src/geodesy.py')
    sys.path.append('/Home/siv32/zef014/pysymmetry/src/')
    import geodesy
    colat, radius, _, _ = geodesy.geod2geoc(glat, 0, 0, 0)
    import numpy as np
    from chaosmagpy import load_CHAOS_matfile
    from chaosmagpy.data_utils import mjd2000
    time = mjd2000(year, 1, 1)  # modified Julian date
    # load the CHAOS model
    model = load_CHAOS_matfile(pysymmetry_path + '/pysymmetry/models/' + 'CHAOS-7.mat') 
    B_radius_core, B_theta_core, B_phi_core = model.synth_values_tdep(time, radius, colat, glon)
    B_radius_crust, B_theta_crust, B_phi_crust = model.synth_values_static(radius, colat, glon)
    Br, Bth, Beast = B_radius_core + B_radius_crust, B_theta_core + B_theta_crust, B_phi_core + B_phi_crust
    # convert from gecentric to geodetic:
    glat, h, Bnorth, B_down = geodesy.geoc2geod(colat, radius, Bth, Br)
    return np.arctan(Beast/Bnorth)