Skip to content

API Reference

Seafloor Age Tracking

SeafloorAgeTracker

Track seafloor material age through geological time.

pygplates.TopologicalModel.reconstruct_geometry advects the tracker points. Collision rules deactivate points at convergent boundaries. New zero-age points enter along reconstructed mid-ocean ridges.

Parameters:

Name Type Description Default
rotation_files list of str

Paths to rotation model files (.rot).

required
topology_files list of str

Paths to topology/plate boundary files (.gpml/.gpmlz).

required
continental_polygons str

Continental polygon file. If None, continental filtering is disabled.

None
config TracerConfig

Tracker configuration. If None, use TracerConfig defaults.

None

Examples:

>>> tracker = SeafloorAgeTracker(
...     rotation_files=['rotations.rot'],
...     topology_files=['topologies.gpmlz'],
...     continental_polygons='continents.gpmlz'
... )
>>> tracker.initialize(starting_age=200)
>>> for target_age in range(199, -1, -1):
...     cloud = tracker.step_to(target_age)
...     xyz = cloud.xyz
...     ages = cloud.get_property('age')

__init__(rotation_files: Union[str, List[str]], topology_files: Union[str, List[str]], continental_polygons: Optional[str] = None, config: Optional[TracerConfig] = None)

initialize(starting_age: float, method: str = 'mesh', n_points: Optional[int] = None, initial_spreading_rate_mm_per_yr: Optional[float] = None, age_distance_law: Optional[Callable[[np.ndarray, float], np.ndarray]] = None) -> int

Initialise tracker points at one geological age.

Parameters:

Name Type Description Default
starting_age float

Starting geological age in Ma.

required
method str

Use mesh for complete ocean coverage. Use ridge_only for zero-age points along ridges.

'mesh'
n_points int

Initial point count. If None, use config.tracker_point_count.

None
initial_spreading_rate_mm_per_yr float

Spreading rate for the initial age calculation in mm/yr.

None
age_distance_law callable

Map distance in km and spreading rate in mm/yr to material age in Myr.

None

Returns:

Type Description
int

Number of initial tracker points.

Examples:

>>> # GPlately-compatible initialization
>>> tracker.initialize(starting_age=200)
>>>
>>> # Higher resolution
>>> tracker.initialize(starting_age=200, n_points=40000)
>>>
>>> # Custom age calculation
>>> def my_age_law(distances, rate):
...     return distances / (rate / 2) * 1.1  # 10% older
>>> tracker.initialize(starting_age=200, age_distance_law=my_age_law)

initialize_from_cloud(cloud: PointCloud, current_age: float) -> int

Initialize from existing PointCloud.

Use this to restart from a checkpoint or to provide custom initial tracer positions.

Parameters:

Name Type Description Default
cloud PointCloud

Point cloud with 'age' property containing material age of each tracer (time since ridge formation).

required
current_age float

Current geological age (Ma).

required

Returns:

Type Description
int

Number of tracers initialized.

Raises:

Type Description
ValueError

If cloud does not have 'age' property.

step_to(target_age: float) -> PointCloud

Evolve tracers to target geological age using C++ backend.

Can only step forward (decreasing geological age toward 0).

Parameters:

Name Type Description Default
target_age float

Target geological age (Ma). Must be less than current_age.

required

Returns:

Type Description
PointCloud

Point cloud with 'age' property containing material ages.

Raises:

Type Description
RuntimeError

If tracker is not initialized.

ValueError

If target_age > current_age (can only go forward).

get_current_state() -> PointCloud

Return the current tracker state without advancing it.

Returns:

Type Description
PointCloud

Current tracker points with an age channel.

save_checkpoint(filepath: str) -> None

Save the tracker state to a checkpoint file.

Parameters:

Name Type Description Default
filepath str

Output path for the .npz checkpoint.

required

load_checkpoint(filepath: str) -> None

Load the tracker state from a checkpoint file.

Parameters:

Name Type Description Default
filepath str

Path to checkpoint file.

required

compute_ages(target_age: float, starting_age: float, rotation_files: Union[str, List[str]], topology_files: Union[str, List[str]], continental_polygons: Optional[str] = None, config: Optional[TracerConfig] = None) -> PointCloud classmethod

One-shot computation of seafloor ages (functional interface).

Creates a tracker, initializes at starting_age, and evolves to target_age in a single call.

Parameters:

Name Type Description Default
target_age float

Target geological age (Ma).

required
starting_age float

Starting geological age (Ma).

required
rotation_files list of str

Paths to rotation model files (.rot).

required
topology_files list of str

Paths to topology/plate boundary files (.gpml/.gpmlz).

required
continental_polygons str

Path to continental polygon file.

None
config TracerConfig

Configuration parameters.

None

Returns:

Type Description
PointCloud

Point cloud with 'age' property.

Examples:

>>> cloud = SeafloorAgeTracker.compute_ages(
...     target_age=100,
...     starting_age=200,
...     rotation_files=['rotations.rot'],
...     topology_files=['topologies.gpmlz']
... )
>>> ages = cloud.get_property('age')

TracerConfig dataclass

Configure seafloor-age tracking.

The serialized dictionary uses the GPlately keys. The Python attributes use the gtrack vocabulary.

Attributes:

Name Type Description
tracker_step_myr float

Tracker step in Myr. The default is 1.0.

earth_radius_m float

Earth radius in metres. The default is 6.3781e6.

Collision detection

collision_velocity_difference_km_per_myr : float Minimum velocity difference for collision detection in km/Myr. The default is 7.0 km/Myr. collision_distance_rate_km_per_myr : float Distance rate for collision detection in km/Myr. The default is 10.0 km/Myr.

Initialization

tracker_point_count : int Point count for the initial sphere mesh. The default is 10000. initial_spreading_rate_mm_per_yr : float Mean spreading rate for the initial age calculation in mm/yr. The default is 75.0 mm/yr.

Mid-ocean-ridge source points

ridge_sampling_angle_deg : float Ridge sampling angle in degrees. The default is 0.5 degrees. ridge_offset_angle_deg : float Angular offset from each ridge in degrees. The default is 0.01 degrees.

Tracker rebuild

tracker_rebuild_neighbor_count : int Source-point count for tracker rebuild interpolation. The default is 6. tracker_rebuild_max_distance_m : float Maximum source separation for a tracker rebuild in metres. The default is half the Earth circumference. gc_collect_frequency : int or None Internal tracker steps between garbage collections. The default is 10. None disables scheduled collection.

Examples:

>>> config = TracerConfig()
>>> config = TracerConfig(
...     tracker_point_count=40000,
...     ridge_sampling_angle_deg=0.25,
...     tracker_step_myr=0.5,
... )

collision_velocity_difference_cm_per_yr: float property

Return the collision velocity difference in cm/yr.

The GPlately API uses cm/yr. One km/Myr equals 0.1 cm/yr.

__post_init__()

Validate configuration parameters.

to_dict() -> dict

Return a dictionary with GPlately-compatible keys.

Returns:

Type Description
dict

Configuration with the external GPlately vocabulary.

from_dict(config_dict: dict) classmethod

Create a configuration from a GPlately-compatible dictionary.

Parameters:

Name Type Description Default
config_dict dict

Dictionary with configuration parameters

required

Returns:

Type Description
TracerConfig

Configuration object


Point Rotation

PointCloud dataclass

Container for points with associated properties.

Stores points in Cartesian XYZ format internally (matches gadopt). Properties (lithospheric_depth, etc.) are stored separately from positions.

Parameters:

Name Type Description Default
xyz ndarray

Cartesian coordinates, shape (N, 3), in meters. Points should lie on Earth's surface (radius ~6.3781e6 m).

required
properties dict

Dictionary mapping property names to arrays of shape (N,). Properties are preserved during rotation operations.

dict()
plate_ids ndarray

Plate IDs for each point, shape (N,). Required for rotation.

None

Examples:

>>> xyz = np.random.randn(1000, 3)
>>> from gtrack.geometry import normalize_to_sphere
>>> xyz = normalize_to_sphere(xyz)  # Project to Earth's surface
>>> cloud = PointCloud(xyz=xyz)
>>> cloud.add_property('lithospheric_depth', np.random.rand(1000) * 100e3)

xyz: np.ndarray instance-attribute

latlon: np.ndarray property

Get lat/lon coordinates (computed from XYZ).

Returns:

Type Description
ndarray

Array of shape (N, 2) with [lat, lon] in degrees. Latitude: -90 to 90, Longitude: -180 to 180.

lonlat: np.ndarray property

Get lon/lat coordinates (computed from XYZ).

Returns:

Type Description
ndarray

Array of shape (N, 2) with [lon, lat] in degrees. Longitude: -180 to 180, Latitude: -90 to 90.

__init__(xyz: np.ndarray, properties: Dict[str, np.ndarray] = dict(), plate_ids: Optional[np.ndarray] = None) -> None

from_latlon(latlon: np.ndarray, properties: Optional[Dict[str, np.ndarray]] = None) -> PointCloud classmethod

Create PointCloud from lat/lon coordinates.

Parameters:

Name Type Description Default
latlon ndarray

Coordinates, shape (N, 2) with [lat, lon] in degrees.

required
properties dict

Properties to attach to the points.

None

Returns:

Type Description
PointCloud

New PointCloud with XYZ coordinates computed from lat/lon.

Examples:

>>> latlon = np.array([[45.0, -120.0], [30.0, 90.0]])
>>> cloud = PointCloud.from_latlon(latlon)

add_property(name: str, values: np.ndarray) -> None

Add or update a property.

Parameters:

Name Type Description Default
name str

Name of the property.

required
values ndarray

Property values, shape (N,).

required

Raises:

Type Description
ValueError

If values length doesn't match number of points.

get_property(name: str) -> np.ndarray

Get a property by name.

Parameters:

Name Type Description Default
name str

Name of the property.

required

Returns:

Type Description
ndarray

Property values.

Raises:

Type Description
KeyError

If property not found.

remove_property(name: str) -> None

Remove a property.

Parameters:

Name Type Description Default
name str

Name of the property to remove.

required

subset(mask: np.ndarray) -> PointCloud

Create subset of points using boolean mask.

Parameters:

Name Type Description Default
mask ndarray

Boolean mask, shape (N,). True values are kept.

required

Returns:

Type Description
PointCloud

New PointCloud with subset of points.

copy() -> PointCloud

Create a deep copy.

Returns:

Type Description
PointCloud

Deep copy of this PointCloud.

PointRotator

Rotate points between geological ages using plate reconstructions.

This class provides the main API for rotating user-provided points according to plate tectonic reconstructions.

Motion is deforming-aware: points are advected with pygplates.TopologicalModel.reconstruct_geometry, resolving rigid plates and deforming networks, exactly like the ocean tracker. Motion does not depend on plate_ids and no point is ever silently dropped.

Key Features: - Cartesian XYZ internal representation (matches gadopt) - Properties stored separately from positions and preserved during rotation - Single topological engine (no rigid per-plate fallback) - No silent drops: rotate with deactivate_points=None returns every input point

Parameters:

Name Type Description Default
rotation_files list of str

Paths to rotation model files (.rot).

required
topology_files list of str

Paths to topology/plate boundary files (.gpml/.gpmlz). Required — the topological engine is built from these. A clear ValueError is raised if they are absent.

None
static_polygons str

Path to static polygons. Used only for the optional assign_plate_ids(source="static") labelling path, never for motion.

None

Examples:

>>> rotator = PointRotator(
...     rotation_files=['rotations.rot'],
...     topology_files=['topologies.gpmlz'],
... )
>>>
>>> # Load user points
>>> cloud = PointCloud.from_latlon(my_latlon_array)
>>>
>>> # Rotate to 50 Ma (no plate_ids needed — motion is topological)
>>> rotated = rotator.rotate(cloud, from_age=0.0, to_age=50.0)

assign_plate_ids(cloud: PointCloud, at_age: float, source: str = 'topology', remove_undefined: bool = False, partitioning_features: Optional[pygplates.FeatureCollection] = None, use_static_polygons: Optional[bool] = None) -> PointCloud

Assign plate IDs to points based on their positions.

Plate IDs are a labelling convenience only — an output property. They are no longer a motion input: rotate advects points topologically and does not consult plate_ids. Assigning them is therefore optional.

Parameters:

Name Type Description Default
cloud PointCloud

Points to assign plate IDs to.

required
at_age float

Geological age at which to assign plate IDs (Ma). Use 0.0 for present-day positions.

required
source (topology, static)

"topology" partitions against the resolved topologies (rigid plates and deforming networks), so the assigned id matches what the engine moves the point by. "static" uses the static polygons passed at construction (back-compat; requires static_polygons). Ignored if partitioning_features is given.

"topology"
remove_undefined bool

If True, remove points with undefined plate IDs (plate_id=0) and emit a warning. Default is False: since ids are labels, dropping points here would silently shrink the cloud. Left for callers that explicitly want the old behaviour.

False
partitioning_features FeatureCollection

Explicit polygon features to use for plate ID assignment, overriding source. Partitioned with partition_into_plates.

None
use_static_polygons bool

Deprecated back-compat alias. If True, equivalent to source="static".

None

Returns:

Type Description
PointCloud

Cloud with plate_ids assigned. May have fewer points if remove_undefined=True and some points had undefined plates.

Warns:

Type Description
UserWarning

If any points have undefined plate IDs.

rotate(cloud: PointCloud, from_age: float, to_age: float, reassign_plate_ids: bool = False, *, time_step: float = 1.0, deactivate_points=None) -> PointCloud

Rotate points from one geological age to another (deforming-aware).

Points are advected with pygplates.TopologicalModel.reconstruct_geometry, resolving rigid plates and deforming networks. Motion does not depend on plate_ids; they are neither required nor consulted.

No silent drops: with the default deactivate_points=None every input point is returned (n_out == n_in), with properties and plate_ids passed through unchanged and in input order. Points that fall outside any resolved topology simply keep their position (they do not vanish).

Parameters:

Name Type Description Default
cloud PointCloud

Points to rotate. plate_ids are optional.

required
from_age float

Source geological age (Ma).

required
to_age float

Target geological age (Ma).

required
reassign_plate_ids bool

If True, (re)assign topology-consistent plate IDs at to_age as an output label. Never drops points.

False
time_step float

Internal stepping granularity (Myr) for the topological reconstruction.

1.0
deactivate_points optional

A pygplates deactivation policy. Default None keeps every point. If supplied, inactive points are removed and the result cloud is subset (properties + plate_ids in lockstep).

None

Returns:

Type Description
PointCloud

Rotated points with the same properties. Same length as the input unless a deactivation policy removed points.

Notes

Direction of rotation (works both ways): - from_age=0, to_age=50: rotate present-day positions to 50 Ma - from_age=50, to_age=0: rotate 50 Ma positions to present day

A span shorter than ZERO_SPAN_TOLERANCE_MYR (1e-6 Myr) returns the input unmoved, with properties and plate ids intact. Callers that derive ages from a non-dimensional model time reach this routinely: a nominal zero span arrives as float round-off, and pygplates rejects a span it considers degenerate. time_step is validated only as positive, so a genuinely sub-microyear span is legal to ask for and will silently no-op.

Examples:

>>> # Rotate present-day continental points to 50 Ma
>>> rotated = rotator.rotate(cloud, from_age=0.0, to_age=50.0)

rotate_incremental(cloud: PointCloud, from_age: float, to_age: float, time_step: float = 1.0, reassign_at_each_step: bool = True) -> PointCloud

Rotate points through geological time in time_step increments.

Retained for back-compat. The topological engine already steps internally at time_step granularity, so this delegates to :meth:rotate with the same time_step; there is no longer a separate rigid per-step path. reassign_at_each_step no longer changes the trajectory (motion is topological, not plate-id driven); it only controls whether the output label is refreshed at to_age.

Parameters:

Name Type Description Default
cloud PointCloud

Points to rotate. plate_ids are optional.

required
from_age float

Source geological age (Ma).

required
to_age float

Target geological age (Ma).

required
time_step float

Internal stepping granularity (Myr).

1.0
reassign_at_each_step bool

If True, assign topology-consistent plate IDs at to_age on output.

True

Returns:

Type Description
PointCloud

Rotated points.

PolygonFilter

Filter points by polygon containment.

Supports filtering by: - Continental polygons (keep only continental points) - Custom polygons (user-provided) - Exclusion zones (remove points inside polygons)

Parameters:

Name Type Description Default
polygon_files str or list of str

Path(s) to polygon files (.gpml, .gpmlz).

required
rotation_files str or list of str

Paths to rotation model files (.rot).

required

Examples:

>>> filter = PolygonFilter(
...     polygon_files='continental_polygons.gpmlz',
...     rotation_files=['rotations.rot']
... )
>>>
>>> # Keep only continental points
>>> continental_cloud = filter.filter_inside(cloud, at_age=0.0)
>>>
>>> # Remove continental points (keep oceanic)
>>> oceanic_cloud = filter.filter_outside(cloud, at_age=0.0)

get_containment_mask(cloud: PointCloud, at_age: float) -> np.ndarray

Get boolean mask of points inside polygons.

Uses the same reconstruct-then-test approach as ContinentalPolygonCache.get_continental_mask to ensure consistent containment results across gtrack.

Parameters:

Name Type Description Default
cloud PointCloud

Points to check.

required
at_age float

Geological age at which to check containment (Ma). Use 0.0 for present-day polygons.

required

Returns:

Type Description
ndarray

Boolean mask, shape (N,), True for points inside polygons.

filter_inside(cloud: PointCloud, at_age: float) -> PointCloud

Keep only points inside polygons.

Parameters:

Name Type Description Default
cloud PointCloud

Points to filter.

required
at_age float

Geological age at which to check containment (Ma).

required

Returns:

Type Description
PointCloud

Points inside polygons.

Examples:

>>> # Keep only continental points at present day
>>> continental = filter.filter_inside(cloud, at_age=0.0)

filter_outside(cloud: PointCloud, at_age: float) -> PointCloud

Keep only points outside polygons.

Parameters:

Name Type Description Default
cloud PointCloud

Points to filter.

required
at_age float

Geological age at which to check containment (Ma).

required

Returns:

Type Description
PointCloud

Points outside polygons.

Examples:

>>> # Remove continental points (keep oceanic) at present day
>>> oceanic = filter.filter_outside(cloud, at_age=0.0)

get_statistics(cloud: PointCloud, at_age: float) -> dict

Get statistics about polygon containment.

Parameters:

Name Type Description Default
cloud PointCloud

Points to analyze.

required
at_age float

Geological age at which to check containment (Ma).

required

Returns:

Type Description
dict

Statistics including: - total: Total number of points - inside: Number of points inside polygons - outside: Number of points outside polygons - inside_fraction: Fraction of points inside


I/O Functions

load_points_numpy(filepath: Union[str, Path], xyz_columns: Tuple[int, int, int] = (0, 1, 2), property_columns: Optional[Dict[str, int]] = None) -> PointCloud

Load points from numpy file.

Parameters:

Name Type Description Default
filepath str or Path

Path to .npy or .npz file.

required
xyz_columns tuple

Column indices for x, y, z coordinates (for .npy files).

(0, 1, 2)
property_columns dict

Mapping from property name to column index (for .npy files).

None

Returns:

Type Description
PointCloud

Loaded points.

Examples:

>>> # Load from .npz with xyz and properties
>>> cloud = load_points_numpy('points.npz')
>>>
>>> # Load from .npy with specific columns
>>> cloud = load_points_numpy(
...     'data.npy',
...     xyz_columns=(0, 1, 2),
...     property_columns={'depth': 3, 'temperature': 4}
... )

load_points_latlon(filepath: Union[str, Path], latlon_columns: Tuple[int, int] = (0, 1), property_columns: Optional[Dict[str, int]] = None, delimiter: str = ',', skip_header: int = 0) -> PointCloud

Load points from lat/lon text file (CSV, etc.).

Parameters:

Name Type Description Default
filepath str or Path

Path to text file.

required
latlon_columns tuple

Column indices for lat, lon (in degrees).

(0, 1)
property_columns dict

Mapping from property name to column index.

None
delimiter str

Column delimiter.

','
skip_header int

Number of header lines to skip.

0

Returns:

Type Description
PointCloud

Loaded points.

Examples:

>>> cloud = load_points_latlon(
...     'points.csv',
...     latlon_columns=(0, 1),
...     property_columns={'depth': 2}
... )

save_points_numpy(cloud: PointCloud, filepath: Union[str, Path], include_properties: bool = True) -> None

Save points to numpy format.

Parameters:

Name Type Description Default
cloud PointCloud

Points to save.

required
filepath str or Path

Output path (.npy or .npz).

required
include_properties bool

If True, save properties (requires .npz format).

True

Examples:

>>> save_points_numpy(cloud, 'output.npz')

save_points_latlon(cloud: PointCloud, filepath: Union[str, Path], delimiter: str = ',', header: Optional[str] = None, include_properties: bool = True) -> None

Save points to lat/lon text file.

Parameters:

Name Type Description Default
cloud PointCloud

Points to save.

required
filepath str or Path

Output path.

required
delimiter str

Column delimiter.

','
header str

Header line to write.

None
include_properties bool

If True, include properties as additional columns.

True

Examples:

>>> save_points_latlon(cloud, 'output.csv', header='lat,lon,depth')

PointCloudCheckpoint

Checkpoint manager for PointCloud state.

Provides save/load functionality with metadata for checkpointing during long-running simulations.

Examples:

>>> checkpoint = PointCloudCheckpoint()
>>>
>>> # Save with metadata
>>> checkpoint.save(cloud, 'checkpoint_50Ma.npz', geological_age=50.0)
>>>
>>> # Load and get metadata
>>> cloud, metadata = checkpoint.load('checkpoint_50Ma.npz')
>>> print(metadata['geological_age'])  # 50.0

save(cloud: PointCloud, filepath: Union[str, Path], geological_age: Optional[float] = None, metadata: Optional[Dict] = None) -> None

Save checkpoint with metadata.

Parameters:

Name Type Description Default
cloud PointCloud

Points to save.

required
filepath str or Path

Output path (.npz format).

required
geological_age float

Current geological age for reference.

None
metadata dict

Additional metadata to save.

None

Examples:

>>> checkpoint.save(
...     cloud, 'state.npz',
...     geological_age=50.0,
...     metadata={'simulation_step': 100}
... )

load(filepath: Union[str, Path]) -> Tuple[PointCloud, Dict]

Load checkpoint.

Parameters:

Name Type Description Default
filepath str or Path

Path to checkpoint file.

required

Returns:

Name Type Description
cloud PointCloud

Loaded point cloud.

metadata dict

Associated metadata.

Examples:

>>> cloud, metadata = checkpoint.load('state.npz')
>>> print(f"Loaded cloud at {metadata['geological_age']} Ma")

list_checkpoints(directory: Union[str, Path], pattern: str = '*.npz') -> list

List checkpoint files in a directory.

Parameters:

Name Type Description Default
directory str or Path

Directory to search.

required
pattern str

Glob pattern for checkpoint files.

"*.npz"

Returns:

Type Description
list

Sorted list of checkpoint file paths.


Mesh Generation

create_sphere_mesh_xyz(n_points: int, radius: float = 1.0) -> np.ndarray

Create approximately uniform points on a sphere using Fibonacci spiral.

The Fibonacci spiral algorithm distributes points approximately evenly over the surface of a sphere using the golden angle. This avoids the pole clustering problem of regular lat/lon grids.

Parameters:

Name Type Description Default
n_points int

Number of points to generate on the sphere's surface.

required
radius float

Radius of the sphere (1.0 for unit sphere, or Earth radius in meters).

1.0

Returns:

Name Type Description
xyz ndarray

XYZ coordinates, shape (n_points, 3).

Examples:

>>> xyz = create_sphere_mesh_xyz(10000)
>>> xyz.shape
(10000, 3)
>>> xyz = create_sphere_mesh_xyz(40000, radius=6.3781e6)  # Earth radius
>>> xyz.shape
(40000, 3)

create_sphere_mesh_latlon(n_points: int) -> Tuple[np.ndarray, np.ndarray]

Create approximately uniform points on a sphere returning lat/lon coordinates.

Parameters:

Name Type Description Default
n_points int

Number of points to generate.

required

Returns:

Name Type Description
lats ndarray

Latitudes in degrees, shape (n_points,). Range: -90 to 90.

lons ndarray

Longitudes in degrees, shape (n_points,). Range: -180 to 180.

Examples:

>>> lats, lons = create_sphere_mesh_latlon(10000)
>>> len(lats)
10000
>>> lats.min() >= -90 and lats.max() <= 90
True

Logging

enable_verbose() -> None

Enable verbose output (INFO level).

Convenience function equivalent to set_log_level(logging.INFO).

enable_debug() -> None

Enable debug output (DEBUG level).

Convenience function equivalent to set_log_level(logging.DEBUG).

disable_logging() -> None

Disable all gtrack logging output.

Convenience function equivalent to set_log_level(logging.CRITICAL + 1).

set_log_level(level: int) -> None

Set the log level for all gtrack loggers.

Parameters:

Name Type Description Default
level int

Logging level (e.g., logging.DEBUG, logging.INFO).

required

Examples:

>>> import logging
>>> from gtrack.logging import set_log_level
>>> set_log_level(logging.DEBUG)  # Enable debug output