示例#1
0
def CHAOS_phiavg_timeavg(nphi,
                         ntheta,
                         lmax,
                         yearStart,
                         yearEnd,
                         n,
                         radius=3485):
    model = cp.load_CHAOS_matfile('../data/CHAOS-7.7.mat')
    time = np.linspace(yearStart, yearEnd, n)
    time_chaos = np.array([cp.data_utils.dyear_to_mjd(x)
                           for x in time])  # modified Julian date
    # create grid
    latC = np.linspace(0.01, 179.99, num=ntheta)  # colatitude in degrees
    lonC = np.linspace(-179.99, 179.99, num=nphi)  # longitude in degrees
    Br_avg = []
    for t in time_chaos:
        print('Loading CHAOS time {:.2f}'.format(t))
        # ylm = model.synth_coeffs_tdep(t)
        # dtglm = model.synth_coeffs_tdep(t, deriv=1)  # Secular Variation
        Br, _, _ = model.synth_values_tdep(t,
                                           radius,
                                           latC,
                                           lonC,
                                           nmax=lmax,
                                           deriv=0,
                                           grid=True)  # (nT)
        BrC = trapz(Br, lonC, axis=1)  # phi average
        Br_avg.append(BrC)
    Br_out = sum(Br_avg) / n
    latC = 90 - latC  # NOTE: 0<theta<180 to read data but -90<theta<90 to plot

    return (latC, lonC, Br_out)
示例#2
0
def profiler_complete_forward(n_data=300):
    """
    Example:

    .. code-block:: python

        %load_ext line_profiler

        import sys
        sys.path.insert(0, <tests directory path>)
        from test_chaosmagpy import profiler_complete_forward as profiler
        import chaosmagpy as cp

        %lprun -f cp.coordinate_utils.synth_rotate_gauss profiler(n_data=300)

    """

    t_start = -200.0
    t_end = 6000.0
    time = np.linspace(t_start, t_end, num=n_data)
    radius = R_REF * np.ones(time.shape)
    theta = np.linspace(1, 179, num=n_data)
    phi = np.linspace(-180, 179, num=n_data)

    model = load_CHAOS_matfile(CHAOS_PATH)

    # B_radius, B_theta, B_phi = model(time, radius, theta, phi)
    B_radius, B_theta, B_phi = model(time, radius, theta, phi)
    print('Ran "profiler_complete_forward"')
示例#3
0
def example1():

    # give inputs
    theta = np.array([55.676, 51.507, 64.133])  # colat in deg
    phi = np.array([12.568, 0.1275, -21.933])  # longitude in deg
    radius = np.array([0.0, 0.0, 500.0]) + R_REF  # radius from altitude in km
    time = np.array([3652.0, 5113.0, 5287.5])  # time in mjd2000

    # load the CHAOS model
    model = load_CHAOS_matfile(FILEPATH_CHAOS)
    print(model)

    print('Computing core field.')
    B_core = model.synth_values_tdep(time, radius, theta, phi)

    print('Computing crustal field up to degree 110.')
    B_crust = model.synth_values_static(radius, theta, phi, nmax=110)

    # complete internal contribution
    B_radius_int = B_core[0] + B_crust[0]
    B_theta_int = B_core[1] + B_crust[1]
    B_phi_int = B_core[2] + B_crust[2]

    print('Computing field due to external sources, incl. induced field: GSM.')
    B_gsm = model.synth_values_gsm(time, radius, theta, phi, source='all')

    print('Computing field due to external sources, incl. induced field: SM.')
    B_sm = model.synth_values_sm(time, radius, theta, phi, source='all')

    # complete external field contribution
    B_radius_ext = B_gsm[0] + B_sm[0]
    B_theta_ext = B_gsm[1] + B_sm[1]
    B_phi_ext = B_gsm[2] + B_sm[2]

    # complete forward computation
    B_radius = B_radius_int + B_radius_ext
    B_theta = B_theta_int + B_theta_ext
    B_phi = B_phi_int + B_phi_ext

    # save to output file
    data_CHAOS = np.stack([
        time, radius, theta, phi, B_radius, B_theta, B_phi, B_radius_int,
        B_theta_int, B_phi_int, B_radius_ext, B_theta_ext, B_phi_ext
    ],
                          axis=-1)

    header = ('  t (mjd2000)    r (km) theta (deg)   phi (deg)       B_r   '
              'B_theta     B_phi       B_r   B_theta     B_phi       B_r   '
              'B_theta     B_phi\n'
              '                                                           '
              'model total                  model internal                '
              'model external')
    np.savetxt('example1_output.txt',
               data_CHAOS,
               delimiter=' ',
               header=header,
               fmt=['%15.8f', '%9.3f', '%11.5f', '%11.5f'] + 9 * ['%9.2f'])

    print('Saved output to example1_output.txt.')
示例#4
0
    def test_synth_euler_angles(self):

        model = cp.load_CHAOS_matfile(CHAOS_PATH)

        test = load_matfile(MATFILE_PATH, 'test_synth_euler_angles')
        time = np.squeeze(test['time'])

        swarm_c = model.synth_euler_angles(time, 'swarm_c')

        self.assertIsNone(np.testing.assert_allclose(swarm_c, test['swarm_c']))
示例#5
0
def example2():
    """
    Plot difference between modelled and observed field strength using Swarm A
    data in August 2018 from a cdf-file.

    """
    import cdflib

    model = load_CHAOS_matfile(FILEPATH_CHAOS)
    print(model)

    cdf_file = cdflib.CDF(
        'data/SW_OPER_MAGA_LR_1B_'
        '20180801T000000_20180801T235959'
        '_PT15S.cdf', 'r')
    # print(cdf_file.cdf_info())  # print cdf info/contents

    radius = cdf_file.varget('Radius') / 1000  # km
    theta = 90. - cdf_file.varget('Latitude')  # colat deg
    phi = cdf_file.varget('Longitude')  # deg
    time = cdf_file.varget('Timestamp')  # milli seconds since year 1
    time = time / (1e3 * 3600 *
                   24) - 730485  # time in modified Julian date 2000
    F_swarm = cdf_file.varget('F')
    cdf_file.close()

    theta_gsm, phi_gsm = transform_points(theta,
                                          phi,
                                          time=time,
                                          reference='gsm')
    index_day = np.logical_and(phi_gsm < 90, phi_gsm > -90)
    index_night = np.logical_not(index_day)

    # complete forward computation: pre-built not customizable (see ex. 1)
    B_radius, B_theta, B_phi = model(time, radius, theta, phi)

    # compute field strength and plot together with data
    F = np.sqrt(B_radius**2 + B_theta**2 + B_phi**2)

    print('RMSE of F: {:.5f} nT'.format(np.std(F - F_swarm)))

    plt.scatter(theta_gsm[index_day],
                F_swarm[index_day] - F[index_day],
                s=0.5,
                c='r',
                label='dayside')
    plt.scatter(theta_gsm[index_night],
                F_swarm[index_night] - F[index_night],
                s=0.5,
                c='b',
                label='nightside')
    plt.xlabel('dipole colatitude ($^\\circ$)')
    plt.ylabel('$\\mathrm{d} F$ (nT)')
    plt.legend(loc=2)
    plt.show()
示例#6
0
def example4():
    """
    Plot maps of static (i.e. small-scale crustal) magnetic field.

    """

    model = load_CHAOS_matfile(FILEPATH_CHAOS)

    radius = R_REF

    model.plot_maps_static(radius, nmax=85)
示例#7
0
    def test_save_matfile(self):

        seq = np.random.randint(0, 10, size=(5, ))
        filename = 'CHAOS-tmp_' + ''.join([str(a) for a in seq]) + '.mat'
        filepath = os.path.join(ROOT, filename)

        model = cp.load_CHAOS_matfile(CHAOS_PATH)
        print('  ', end='')  # indent line by two withespaces
        model.save_matfile(filepath)

        def test(x, y):
            if isinstance(x, str) or isinstance(y, str):
                # convert unicode to str
                np.testing.assert_string_equal(str(x), str(y))
            else:
                np.testing.assert_allclose(x, y, atol=1e-10)

        chaos = cp.data_utils.load_matfile(
            CHAOS_PATH, variable_names=['pp', 'model_ext', 'model_Euler', 'g'])
        chaos_out = cp.data_utils.load_matfile(
            filepath, variable_names=['pp', 'model_ext', 'model_Euler', 'g'])

        pp = chaos['pp']
        pp_out = chaos_out['pp']

        for key in ['order', 'dim', 'pieces', 'form', 'coefs', 'breaks']:
            test(pp[key], pp_out[key])

        test(chaos['g'], chaos_out['g'])

        model_ext = chaos['model_ext']
        model_ext_out = chaos_out['model_ext']

        for key in [
                'm_Dst', 'm_gsm', 'm_sm', 'q10', 'qs11', 't_break_q10',
                't_break_qs11'
        ]:
            test(model_ext[key], model_ext_out[key])

        model_Euler = chaos['model_Euler']
        model_Euler_out = chaos_out['model_Euler']

        for key in ['alpha', 'beta', 'gamma', 't_break_Euler']:
            var = model_Euler[key]
            var_out = model_Euler_out[key]
            test(var.shape, var_out.shape)

            for value, value_out in zip(np.ravel(var), np.ravel(var_out)):
                test(value, value_out)

        print(f"  Removing file {filepath}")
        os.remove(filepath)
示例#8
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')
示例#9
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)
示例#10
0
def example5():
    """
    Plot timeseries of the magnetic field at the ground observatory in MBour
    MBO (lat: 75.62°, east lon: 343.03°).

    """

    model = load_CHAOS_matfile(FILEPATH_CHAOS)

    # observatory location
    radius = 6.376832e+03
    theta = 75.69200
    phi = 343.05000

    model.plot_timeseries_tdep(radius, theta, phi, nmax=16, deriv=1)
示例#11
0
    def test_synth_gsm_field(self):

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

        model = load_CHAOS_matfile(CHAOS_PATH)

        N = int(1000)

        time = np.linspace(-1000, 6000, num=N)
        radius = R_REF
        theta = np.linspace(1, 179, num=N)
        phi = np.linspace(-180, 179, num=N)

        B_radius = np.zeros(time.shape)
        B_theta = np.zeros(time.shape)
        B_phi = np.zeros(time.shape)

        for source in ['internal', 'external']:
            B_radius_new, B_theta_new, B_phi_new = model.synth_values_gsm(
                time, radius, theta, phi, source=source)

            B_radius += B_radius_new
            B_theta += B_theta_new
            B_phi += B_phi_new

        B_radius_mat = np.ravel(test['B_radius'])
        B_theta_mat = np.ravel(test['B_theta'])
        B_phi_mat = np.ravel(test['B_phi'])

        for component in ['B_radius', 'B_theta', 'B_phi']:
            res = np.abs(eval(component) - eval('_'.join((component, 'mat'))))
            print('  -------------------')
            print(f'  {component}:')
            print('  MAE =', np.mean(res), 'nT')
            print('  RMSE =', np.sqrt(np.mean(res**2)), 'nT')
            print('  Max Error =', np.amax(res), 'nT')
            print('  Min Error =', np.amin(res), 'nT')

        self.assertIsNone(np.testing.assert_allclose(
            B_radius, B_radius_mat, rtol=1e-2, atol=1e-2))
        self.assertIsNone(np.testing.assert_allclose(
            B_theta, B_theta_mat, rtol=1e-2, atol=1e-2))
        self.assertIsNone(np.testing.assert_allclose(
            B_phi, B_phi_mat, rtol=1e-2, atol=1e-2))
示例#12
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
示例#13
0
    def test_surface_field(self):

        model = cp.load_CHAOS_matfile(CHAOS_PATH)

        time = 2015.
        radius = R_REF
        theta = np.linspace(1, 179, num=180)
        phi = np.linspace(-180, 179, num=360)

        B_radius, B_theta, B_phi = model.synth_values_tdep(time,
                                                           radius,
                                                           theta,
                                                           phi,
                                                           nmax=13,
                                                           grid=True,
                                                           deriv=0)

        B_radius = np.ravel(B_radius, order='F')  # ravel column-major
        B_theta = np.ravel(B_theta, order='F')
        B_phi = np.ravel(B_phi, order='F')

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

        B_radius_mat = np.ravel(test['B_radius'])
        B_theta_mat = np.ravel(test['B_theta'])
        B_phi_mat = np.ravel(test['B_phi'])

        for component in ['B_radius', 'B_theta', 'B_phi']:
            res = np.abs(eval(component) - eval('_'.join((component, 'mat'))))
            print('  -------------------')
            print(f'  {component}:')
            print('  MAE =', np.mean(res), 'nT')
            print('  RMSE =', np.sqrt(np.mean(res**2)), 'nT')
            print('  Max Error =', np.amax(res), 'nT')
            print('  Min Error =', np.amin(res), 'nT')

        self.assertIsNone(np.testing.assert_allclose(B_radius, B_radius_mat))
        self.assertIsNone(np.testing.assert_allclose(B_theta, B_theta_mat))
        self.assertIsNone(np.testing.assert_allclose(B_phi, B_phi_mat))
示例#14
0
    def test_sv_timeseries(self):

        # some observatory location
        radius = R_REF
        theta = 90 - 14.308
        phi = -16.950

        model = cp.load_CHAOS_matfile(CHAOS_PATH)

        time = np.linspace(model.model_tdep.breaks[0],
                           model.model_tdep.breaks[-1],
                           num=1000)

        B_radius, B_theta, B_phi = model.synth_values_tdep(time,
                                                           radius,
                                                           theta,
                                                           phi,
                                                           nmax=16,
                                                           deriv=1)

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

        B_radius_mat = np.ravel(test['B_radius'])
        B_theta_mat = np.ravel(test['B_theta'])
        B_phi_mat = np.ravel(test['B_phi'])

        for component in ['B_radius', 'B_theta', 'B_phi']:
            res = np.abs(eval(component) - eval('_'.join((component, 'mat'))))
            print('  -------------------')
            print(f'  {component}:')
            print('  MAE =', np.mean(res), 'nT')
            print('  RMSE =', np.sqrt(np.mean(res**2)), 'nT')
            print('  Max Error =', np.amax(res), 'nT')
            print('  Min Error =', np.amin(res), 'nT')

        self.assertIsNone(np.testing.assert_allclose(B_radius, B_radius_mat))
        self.assertIsNone(np.testing.assert_allclose(B_theta, B_theta_mat))
        self.assertIsNone(np.testing.assert_allclose(B_phi, B_phi_mat))
示例#15
0
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)
示例#16
0
    def test_save_shcfile(self):

        seq = np.random.randint(0, 10, size=(5,))
        filename = 'CHAOS-tmp_' + ''.join([str(a) for a in seq]) + '.shc'
        filepath = os.path.join(ROOT, filename)

        model_mat = load_CHAOS_matfile(CHAOS_PATH)

        print('  On time-dependent part:')
        print('  ', end='')
        model_mat.save_shcfile(filepath, model='tdep')
        coeffs_tdep_mat = model_mat.model_tdep.coeffs

        model_shc = load_CHAOS_shcfile(filepath)
        coeffs_tdep_shc = model_shc.model_tdep.coeffs

        print('  Max Error =',
              np.amax(np.abs(coeffs_tdep_shc - coeffs_tdep_mat)))

        np.testing.assert_allclose(
            coeffs_tdep_shc, coeffs_tdep_mat, rtol=1e-2, atol=1e-3)

        print('  On static part:')
        print('  ', end='')
        model_mat.save_shcfile(filepath, model='static')
        coeffs_static_mat = model_mat.model_static.coeffs

        model_shc = load_CHAOS_shcfile(filepath)
        coeffs_static_shc = model_shc.model_static.coeffs

        print('  Max Error =',
              np.amax(np.abs(coeffs_static_shc - coeffs_static_mat)))

        np.testing.assert_allclose(
            coeffs_static_shc, coeffs_static_mat, rtol=1e-2, atol=1e-3)

        print(f"  Removing file {filepath}")
        os.remove(filepath)
示例#17
0
    def test_complete_forward(self):

        n_data = int(300)
        t_start = -200.0
        t_end = 6000.0
        time = np.linspace(t_start, t_end, num=n_data)
        radius = R_REF * np.ones(time.shape)
        theta = np.linspace(1, 179, num=n_data)
        phi = np.linspace(-180, 179, num=n_data)

        model = load_CHAOS_matfile(CHAOS_PATH)

        B_radius, B_theta, B_phi = model(time, radius, theta, phi)

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

        B_radius_mat = np.ravel(test['B_radius'])
        B_theta_mat = np.ravel(test['B_theta'])
        B_phi_mat = np.ravel(test['B_phi'])

        for component in ['B_radius', 'B_theta', 'B_phi']:
            res = np.abs(eval(component) - eval('_'.join((component, 'mat'))))
            print('  -------------------')
            print(f'  {component}:')
            print('  MAE =', np.mean(res), 'nT')
            print('  RMSE =', np.sqrt(np.mean(res**2)), 'nT')
            print('  Max Error =', np.amax(res), 'nT')
            print('  Min Error =', np.amin(res), 'nT')

        self.assertIsNone(np.testing.assert_allclose(
            B_radius, B_radius_mat, rtol=1e-7, atol=1e-2))
        self.assertIsNone(np.testing.assert_allclose(
            B_theta, B_theta_mat, rtol=1e-7, atol=1e-2))
        self.assertIsNone(np.testing.assert_allclose(
            B_phi, B_phi_mat, rtol=1e-7, atol=1e-2))
示例#18
0
    def test_load_CHAOS(self):

        cp.load_CHAOS_matfile(CHAOS_PATH)
        cp.load_CHAOS_shcfile(CHAOS_PATH_SHC)
        cp.chaos.BaseModel.from_shc(CHAOS_PATH_SHC)