예제 #1
0
def test_create_spherical_earth():
    """
    Test the creation of Earth instances.
    """

    _ = apricot.SphericalEarth()
    _ = apricot.SphericalEarth(6367.755)
예제 #2
0
def create_earth(earth_model: str, earth_radius: Union[str, float],
                 **kwargs) -> apricot.Earth:
    """
    Create an Earth model from config arguments.

    Parameters
    ----------
    earth_model: str
        The Earth model to use.
    earth_radius: Union[str, float]
        The radius type to use ("polar", "equatorial") or a fixed radius.

    Returns
    -------
    earth: apricot.Earth
        An apricot Earth model.

    Raises
    ------
    ValueError
        If an unknown `earth_model` was provided.
    """

    # we model a spherical Earth
    if earth_model == "spherical":

        # parse the earth radius into a float
        radius = parse_earth_radius(earth_radius)

        # and create the corresponding Earth model
        return apricot.SphericalEarth(radius)

    else:  # catch any other Earth models, just in case
        raise ValueError(
            f"{earth_model} is not a currently supported Earth model.")
예제 #3
0
def test_add_earth():
    """
    Test that I can add atmosphere models to Earth models.
    """

    # create an Earth model
    earth = apricot.SphericalEarth()

    # construct an atmosphere
    atmosphere = apricot.ExponentialAtmosphere()

    # and add an ExponentialAtmosphere
    earth.add(atmosphere)

    # get the radius of the current Earth model at the pole
    Re = earth.radius(np.asarray([0, 0, -1.0]))

    # the altitudes at which we evaluate our model [km]
    altitudes = np.linspace(0, 5., 100)

    # make sure that the density above the surface is non-zero
    radii = Re + altitudes

    # build the locations that we evaluate the density at
    locations = np.zeros((altitudes.shape[0], 3))
    locations[:, 2] = radii

    # get the density at each of these locations using the Earth
    earth_density = earth.density(locations)

    # get the density at each of these locations using the atmosphere
    atmosphere_density = atmosphere.density(altitudes)

    # check that they agree
    np.testing.assert_allclose(earth_density, atmosphere_density)
예제 #4
0
def test_basic_geometric_acceptance():
    """
    Perform a basic test of the geometric
    cosmic ray acceptance of an ANITA-like mission to direct
    cosmic ray air showers.
    """

    # the radius that we use for the Earth model
    Re = apricot.SphericalEarth.polar_radius

    # use a simple spherical Earth model
    earth = apricot.SphericalEarth(Re)

    # we pick particles on a cap 100km above the surface
    source = apricot.SphericalCapSource(radius=Re + 100.0)

    # create a flux model that just creates (10^19) cosmic ray protons.
    flux = apricot.FixedProtonFlux(19.0)

    # place ANITA 37 km above the exact south pole
    location = np.asarray([0, 0, Re + 35.0])

    # we consider anything with 1.5 degrees of the shower axis detectable
    maxview = 1.5

    # create a simple detector
    detector = apricot.OrbitalDetector(earth, location, maxview, mode="direct")

    # create a simple propagator
    propagator = apricot.SimplePropagator(earth)

    # and propagate a single particle
    interactions = propagator.propagate(source, flux, detector)
예제 #5
0
def test_basic_io_root():
    """
    Propagate a couple of cosmic ray events
    and write them to a ROOT file.
    """

    # the number of events we propagate
    N = 10

    # and the energy that we propagate
    E = 19.0

    # the radius that we use for the Earth model
    Re = apricot.SphericalEarth.polar_radius

    # use a simple spherical Earth model
    earth = apricot.SphericalEarth(Re)

    # we pick particles on a cap 100km above the surface
    source = apricot.SphericalCapSource(radius=Re + 100.0)

    # create a flux model that just creates (10^19) cosmic ray protons.
    flux = apricot.FixedProtonFlux(E)

    # place ANITA 37 km above the exact south pole
    location = np.asarray([0, 0, Re + 35.0])

    # we consider anything with 1.5 degrees of the shower axis detectable
    maxview = 1.5

    # create a simple detector
    detector = apricot.OrbitalDetector(earth, location, maxview, mode="direct")

    # create a simple propagator
    propagator = apricot.SimplePropagator(earth)

    # and propagate a single particle
    interactions = propagator.propagate(source, flux, detector, N)

    # and write them to a file
    apricot.root.to_file("/tmp/interactions.root", interactions)

    # now creck that we can load the file as a dataframe
    df = apricot.root.as_pandas("/tmp/interactions.root")

    # a quick check on the number of events we got
    assert df.index.shape[0] <= N

    # and that the energy is correct
    np.testing.assert_allclose(df.energy, E)
예제 #6
0
def test_create_orbital_detector():
    """
    Test that I can create OrbitalDetector's
    """

    # create a spherical Earth
    earth = apricot.SphericalEarth()

    # and a location
    location = np.asarray([0, 0, 7000.0])

    # and maxview angle
    maxview = 1.5

    # and create the orbital detector
    _ = apricot.OrbitalDetector(earth, location, maxview)
예제 #7
0
def test_spherical_earth_radii():
    """
    Test the creation of Earth instances.
    """

    # create a spherical Earth at the polar radius
    earth = apricot.SphericalEarth(6356.755)

    # test that I can evaluate at a single location
    earth.radius(np.asarray([0, 0, 0]))

    # and test that I can evaluate at a vector of locations
    locations = np.zeros((100, 3))
    radii = earth.radius(locations)

    # and check that they are the same
    for i in np.arange(locations.shape[0]):
        np.testing.assert_allclose(radii[i], earth.radius(locations[i, :]))
예제 #8
0
def test_spherical_earth_density():
    """
    Test and validate earth.density.
    """

    # the radii that we evaluate at
    locations = np.zeros((10_000, 3))

    # and fill in the radii
    locations[:, 2] = np.linspace(0.0, 6360.0, 10_000)

    # create the non-BEDMAP2 and BEDMAP2 Earth's
    earth = apricot.SphericalEarth()

    # and the corresponding densities
    density = earth.density(locations)

    # loop over the radii and check that they are the same
    for i in np.arange(locations.shape[0]):

        # and evaluate the density using each model
        np.testing.assert_allclose(density[i], earth.density(locations[i, :]))

    # we now have the density as a function of radius.

    # we create the plot
    fig, ax = plt.subplots()

    # and make the pelots
    ax.plot(np.linalg.norm(locations, axis=1),
            density,
            label="Spherical Earth")

    # and some labels
    ax.set_xlabel("Radius [km]")
    ax.set_ylabel(r"Density [g/cm$^3$]")

    # and save the plot
    fig.savefig(f"{os.path.dirname(__file__)}/figures/earth_density.pdf")
예제 #9
0
def test_spherical_cap_area():
    """
    Some basic tests of SphericalEarth::cap_area
    """

    # use a known value of Re
    Re = 6400

    # create a spherical earth model
    earth = apricot.SphericalEarth(Re)

    # create a center location
    center = np.asarray([0, 0, 0])

    # a spherical cap of theta=0 has zero area
    np.testing.assert_array_equal(earth.cap_area(center, 0.0), 0.0)

    # and a cap with theta=pi is a full-sphere
    np.testing.assert_allclose(earth.cap_area(center, np.pi),
                               4 * np.pi * Re * Re)

    # and a cap with theta=pi/2. is a half-sphere
    np.testing.assert_allclose(earth.cap_area(center, np.pi / 2.0),
                               2 * np.pi * Re * Re)