Providing emitter/observer data

GREOPy calculates light signals between two curves. Therefore everything starts by supplying the curve data that is to be used with the algorithm. This can be done in multiple ways:

  1. Curves have been calculated before and were each saved in an H5-file,

    \(\rightarrow\) load them directly into the Python script, see here.

  2. Curves have not been calculated before,

    \(\rightarrow\) generate them from initial conditions, see here.

Curve data includes all events (coordinates for each spacetime point) and the four-velocity/tangent vector (coordinate changes w.r.t. proper time \(tau\)) at each event along the curve. Whenever curve data is handled, it is stored in a pandas DataFrame; each row of the DataFrame then corresponds to one event with its four-velocity.

Load previously calculated curve data

If the user already created H5-files containing curve data, they can be loaded via the load_dataset function:

from greopy.common import load_dataset

curve_data_1 = load_dataset('path/to/file_1')
for curve in curve_data_1:
    curve_data_1 = curve
curve_data_2 = load_dataset('path/to/file_2')
for curve in curve_data_1:
    curve_data_1 = curve

This loads two DataFrames containing the complete curve data (events and tangent vectors); load_dataset returns a Generator object from which the DataFrame is extracted.

If the user is only interested in certain parts of the curve, the initial and final row can be chosen via the default arguments first_row and last_row. The default argument step_size can be invoked to step through the DataFrame and load e.g. every other row; this is convenient for getting an overview over the whole or parts of a curve.

The following code loads six events from a DataFrame with over 600 rows, numbered 0-500 in steps of a 100:

curve_data_1 = load_dataset(
    'path/to/file_1',
    first_row=0,
    last_row=600,
    step_size=100,
)

Calculate curves from initial conditions

If the user has not created curve data beforehand, it can be generated using the initial_conditions_calc and geodesic_calc functions by passing a configuration dictionary containing information about the curves’ initial conditions and the underlying spacetime.

Note

GREOPy currently supports calculating timelike geodesics only, instead of arbitrary timelike curves from given initial conditions. This will be added in the future.

The config dictionary

The following information needs to be provided about the curves and the underlying spacetime:

  • proper_times: initial and final proper time value of the curve,

  • initial_event: four-coordinates of the curve’s initial event [1],

  • initial_velocity: curve’s spatial (three)-velocity at the initial event.

  • metric: spacetime metric line element,

  • multipole_moments: gravitating object’s parameters.

(Proper time and velocity refer to being measured by a clock that is being carried along the curve.)

This information is stored in a dictionary of type TypedDict defined in the config module. In this way, each curve has its own dictionary entry with its properties, in addition to the metric with its properties.

The dictionary can either be defined directly in the Python script or saved in a TOML document of the following form

[Curve_1]
proper_times.time_initial = 0
proper_times.time_final = 86400  # seconds in a day
initial_event.x0 = 0
initial_event.radius = 6371000  # Earth radius average
initial_event.theta = 1.570796326  # Equatorial plane
initial_event.phi = 0
initial_velocity.velocity_radial = 0
initial_velocity.velocity_polar = 0
initial_velocity.velocity_azimuthal = 0.000072722  # Earth angular velocity


[Curve_2]
proper_times.time_initial = 0
proper_times.time_final = 86400  # seconds in a day
initial_event.x0 = 0
initial_event.radius = 7071000  # Low Earth Orbit example
initial_event.theta = 1.570796326  # Equatorial plane
initial_event.phi = 0
initial_velocity.velocity_radial = 0
initial_velocity.velocity_polar = 0
initial_velocity.velocity_azimuthal = 0.00110815  # satellite ang. velocity

[Metric]
name = 'Schwarzschild'
params.multipole_moments = [0]  # no central mass example

and loaded via

import tomli

with open('path/to/config_file.toml', mode='rb') as fp:
config = tomli.load(fp)

Calculate timelike geodesics

The initial_conditions_calc function calculates the four-velocity for each given initial event and spatial velocity from the config; it returns the events with their corresponding four-velocity:

from greopy.initial_conditions import initial_conditions_calc

event_1, velocity_1, event_2, velocity_2 = initial_conditions_calc(
    config,
)

Each set of event and initial four-velocity forms an initial value problem that is solved with the geodesic_calc function; the returned solutions are pandas DataFrames containing the emitter and receiver curves, respectively:

from greopy.orbit_calc import geodesic_calc

emission_curve_data, receiver_curve_data = geodesic_calc(
    config,
    (event_1, velocity_1, event_2, velocity_2),
    step_numbers=[100, 100],
)

A row of the DataFrames holds the event and respective four-velocity of a single curve step. The default argument step_numbers specifies the numbers of steps along both curves. If left blank, the step numbers default to 600 steps per curve.

The curve data can optionally be saved for later use:

import pandas

emission_curve_data.to_hdf('path/to/file_1', key="curve", mode="w")
receiver_curve_data.to_hdf('path/to/file_2', key="curve", mode="w")

where key can be chosen freely. Refer to the previous section when subsequently loading this curve data in a different Python script.

Calculate timelike non-geodesic curves

This will be added in the future.