Logging, provenance and C libraries

grand.manage_log

Logging for GRANDlib and for the scripts that use it.

grand.provenance

Which GRANDlib produced a file: the package version and its git commit.

grand.geo.gull

Wrapper for the GULL C library

grand.geo.turtle

Wrapper for the TURTLE C library

grand.manage_log

Logging for GRANDlib and for the scripts that use it.

Library modules only create a logger and write to it; they never configure where the messages go. That is left to the script that runs them, as the Python logging guide recommends. In a library module:

from logging import getLogger

logger = getLogger(__name__)

def foo(var):
    logger.debug("call foo()")
    logger.info(f"var={var}")

A script chooses the output and the level with create_output_for_logger(), and gets its own logger with get_logger_for_script(), since __name__ is "__main__" there. string_begin_script(), string_end_script(), chrono_start() and chrono_string_duration() format the usual start, end and timing lines.

Examples

A script that logs to the terminal and to log.txt at debug level:

import grand.manage_log as mlg

logger = mlg.get_logger_for_script(__file__)
mlg.create_output_for_logger("debug", log_file="log.txt", log_stdout=True)

logger.info(mlg.string_begin_script())
logger.info(mlg.chrono_start())
...                                   # the work
logger.info(mlg.chrono_string_duration())
logger.info(mlg.string_end_script())

Each line of the log reads:

11:28:09.621  INFO [grand.sim.efield2voltage 412] message

To reuse this module in another project, change NAME_PKG_GIT and NAME_ROOT_LIB.

grand.manage_log.create_output_for_logger(log_level='info', log_file=None, log_stdout=True, log_root='grand')[source]

Create a logger with handler for grand

Parameters:
  • log_level (str, optional) – Threshold: "debug", "info", "warning", "error" or "critical".

  • log_file (str, optional) – File to write to; none by default.

  • log_stdout (bool, optional) – Also write to standard output.

  • log_root (str, optional) – Logger name to configure.

grand.manage_log.close_output_for_logger(log_root='grand')[source]

close handler for test

Parameters:

log_root (str, optional) – Logger whose handlers to close.

grand.manage_log.get_logger_for_script(pfile)[source]

Return a logger with root logger is defined by the path of the file.

@note

Must be call before create_output_for_logger()

Parameters:

pfile (str) – Path of the calling script, used to name the logger.

Returns:

A logger named after that script.

Return type:

logging.Logger

grand.manage_log.string_begin_script()[source]

Return string start message with date, time

Returns:

A banner marking the start of a script run.

Return type:

str

grand.manage_log.string_end_script()[source]

Return string end message with date, time and duration

Returns:

A banner marking the end, with the elapsed time.

Return type:

str

grand.manage_log.chrono_start()[source]

Start chonometer

Returns:

The start time, to pass to chrono_string_duration().

Return type:

float

grand.manage_log.chrono_string_duration()[source]

Return string with duration between call chrono_start()

Returns:

Elapsed time since chrono_start(), formatted.

Return type:

str

grand.provenance

Which GRANDlib produced a file: the package version and its git commit.

Every tree GRANDlib creates records this in its modification_software and modification_software_version metadata, so a simulated or converted file says which code wrote it. The package version alone is not enough: it moves only on release, and most files are written from a git checkout between releases.

grand.provenance.SOFTWARE_NAME = 'GRANDlib'

What modification_software records for trees GRANDlib creates.

grand.provenance.package_version()[source]

Returns the installed GRANDlib version, or "unknown".

Read from the package metadata rather than a constant, so it cannot drift from what was installed. "unknown" rather than an error when the package is not installed: running from a source tree is legitimate.

Return type:

str

grand.provenance.git_state(root=None)[source]

Describes the git checkout GRANDlib runs from, if it runs from one.

Parameters:

root (str, optional) – The repository to describe. Defaults to the one holding this package.

Returns:

commit (full hash), branch ("HEAD" when detached) and modified (True when tracked files differ from the commit). None when root is not the top of a git checkout – for example an installed copy – so that a copy installed inside some other repository never reports that repository’s commit.

Return type:

dict or None

grand.provenance.describe(root=None)[source]

Returns the version string written into files.

Parameters:

root (str, optional) – Passed to git_state().

Returns:

For example "0.2.0 (git dev-next 1aeac037153a..., modified)", or the package version alone outside a git checkout.

Return type:

str

grand.provenance.current()[source]

Returns describe() for this package, computed once per process.

Trees are created often; git runs only the first time.

Return type:

str

grand.geo.gull

Wrapper for the GULL C library

exception grand.geo.gull.LibraryError(code)[source]

Bases: RuntimeError

A GULL library error

class grand.geo.gull.Snapshot(filename=None, date='2020-01-01')[source]

Bases: object

Proxy for a GULL snapshot object

property altitude

The altitude range of the snapshot

Returns:

Altitude range the snapshot is valid over, in meters.

Return type:

tuple of float

property date

The date of the snapshot

Returns:

Date the field model was evaluated for.

Return type:

datetime.date

property order

The approximation order of the model

Returns:

Maximum spherical-harmonic order of the model.

Return type:

int

grand.geo.turtle

Wrapper for the TURTLE C library

exception grand.geo.turtle.LibraryError(code: int)[source]

Bases: RuntimeError

A TURTLE library error

class grand.geo.turtle.Map(path: Path | str)[source]

Bases: object

Proxy for a TURTLE map object

cache = {}
elevation(x, y)[source]

Get the elevation at the given map coordinates

Parameters:
  • x (float or ndarray) – Longitude, in degrees.

  • y (float or ndarray) – Latitude, in degrees.

Returns:

Elevation, in meters.

Return type:

float or ndarray

property path

The path where the data tiles are located

Returns:

Path of the file this map was read from.

Return type:

str

class grand.geo.turtle.Stack(path: Path | str, stack_size: int = 0)[source]

Bases: object

Proxy for a TURTLE stack object

elevation(latitude, longitude)[source]

Get the elevation at the given geodetic coordinates

Parameters:
  • latitude (float or ndarray) – Degrees north.

  • longitude (float or ndarray) – Degrees east.

Returns:

Elevation, in meters.

Return type:

float or ndarray

property path

The path where the data tiles are located

Returns:

Directory holding the elevation tiles.

Return type:

str

property stack_size

The maximum number of data tiles kept in memory

Returns:

Number of tiles held in memory.

Return type:

int

class grand.geo.turtle.Stepper[source]

Bases: object

Proxy for a TURTLE stepper object

add(data: Map | Stack | None = None, offset: float = 0)[source]

Adds an elevation source to the stepper.

Parameters:
  • data (Map or Stack) – The elevation data to consult.

  • offset (float, optional) – Constant offset applied to its elevations, in meters.

property geoid

The geoid map used to convert heights, or None.

Returns:

The geoid map used to convert heights.

Return type:

Map or None

Parameters:

map (Map) – Geoid map to use for height conversion.

grand.geo.turtle.ecef_from_geodetic(latitude, longitude, altitude)[source]

Convert geodetic coordinates to ECEF ones

Parameters:
  • latitude (float or ndarray) – Degrees north.

  • longitude (float or ndarray) – Degrees east.

  • altitude (float or ndarray) – Metres above the ellipsoid.

Returns:

ECEF position, in meters.

Return type:

ndarray

grand.geo.turtle.ecef_from_horizontal(latitude, longitude, azimuth, elevation)[source]

Convert horizontal coordinates to an ECEF direction

Parameters:
  • latitude (float or ndarray) – Degrees north.

  • longitude (float or ndarray) – Degrees east.

  • azimuth (float or ndarray) – Degrees from north toward east.

  • elevation (float or ndarray) – Degrees above the horizon.

Returns:

Unit direction in ECEF.

Return type:

ndarray

grand.geo.turtle.ecef_to_geodetic(ecef)[source]

Convert ECEF coordinates to geodetic ones

Parameters:

ecef (array_like) – ECEF position, in meters.

Returns:

Latitude and longitude in degrees, altitude in meters.

Return type:

tuple

grand.geo.turtle.ecef_to_horizontal(latitude, longitude, direction)[source]

Convert an ECEF direction to horizontal coordinates

Parameters:
  • latitude (float) – Degrees north of the observer.

  • longitude (float) – Degrees east of the observer.

  • direction (array_like) – Direction in ECEF.

Returns:

Azimuth and elevation, in degrees.

Return type:

tuple