Source code for apsg.config

from collections.abc import Mapping
from contextlib import contextmanager
from dataclasses import asdict, dataclass, field
from typing import Any


[docs] class BaseConfig(Mapping): """Base configuration class with dict-like access.""" def __getitem__(self, key: str) -> Any: """Get item by key.""" try: return getattr(self, key) except AttributeError: raise KeyError(key) def __iter__(self): """Iterate over configuration keys.""" return iter(asdict(self)) def __len__(self): """Return number of configuration items.""" return len(asdict(self)) def __repr__(self): """Return string representation.""" items = ", ".join(f"{k}={v!r}" for k, v in asdict(self).items()) return f"{self.__class__.__name__}({items})"
[docs] def update(self, config_dict: dict[str, Any]): """Update configuration with given mapping.""" for key, value in config_dict.items(): if not hasattr(self, key): raise KeyError(f"'{key}' is not a valid configuration key.") current_value = getattr(self, key) if isinstance(current_value, BaseConfig) and isinstance(value, dict): current_value.update(value) else: setattr(self, key, value)
[docs] def copy(self) -> dict[str, Any]: """Return a copy as a dictionary.""" return asdict(self)
[docs] @dataclass class StereonetMarkerConfig(BaseConfig): """Stereonet marker style configuration.""" alpha: Any = None color: Any = None mec: Any = None mfc: Any = None ls: str = "none" marker: str = "o" mew: int = 1 ms: int = 6
[docs] @dataclass class StereonetConfig(BaseConfig): """Stereonet global configuration.""" kind: str = "equal-area" overlay_position: tuple[float, float, float, float] = (0, 0, 0, 0) rotate_data: bool = False minor_ticks: Any = None major_ticks: Any = None overlay: bool = True overlay_step: int = 15 overlay_resolution: int = 181 clip_pole: int = 15 hemisphere: str = "lower" grid_type: str = "gss" grid_n: int = 3000 tight_layout: bool = False title_kws: dict = field(default_factory=dict)
[docs] @dataclass class StereonetPointConfig(StereonetMarkerConfig): """Stereonet point marker style configuration.""" pass
[docs] @dataclass class StereonetVectorConfig(StereonetMarkerConfig): """Stereonet vector marker style configuration.""" mew: int = 2
[docs] @dataclass class StereonetGreatCircleConfig(BaseConfig): """Stereonet great circle line style configuration.""" alpha: Any = None color: Any = None ls: str = "-" lw: float = 1.5
[docs] @dataclass class StereonetArcConfig(BaseConfig): """Stereonet arc line style configuration.""" alpha: Any = None color: Any = None ls: str = "-" lw: float = 1.5
[docs] @dataclass class StereonetScatterConfig(BaseConfig): """Stereonet scatter plot configuration.""" alpha: Any = None s: Any = None c: Any = None linewidths: float = 1.5 marker: str = "o" cmap: Any = None legend: bool = False num: str = "auto"
[docs] @dataclass class StereonetConeConfig(BaseConfig): """Stereonet cone boundary line style configuration.""" alpha: Any = None color: Any = None ls: str = "-" lw: float = 1.5
[docs] @dataclass class StereonetPairConfig(BaseConfig): """Stereonet pair line and marker style configuration.""" alpha: Any = None color: Any = None ls: str = "-" lw: float = 1.5 line_marker: str = "o"
[docs] @dataclass class StereonetFaultConfig(BaseConfig): """Stereonet fault plane line style configuration.""" alpha: Any = None color: Any = None ls: str = "-" lw: float = 1.5
[docs] @dataclass class StereonetHoeppnerConfig(StereonetMarkerConfig): """Stereonet Hoeppner plot marker style configuration.""" ms: int = 5
[docs] @dataclass class StereonetArrowConfig(BaseConfig): """Stereonet arrow style configuration.""" color: Any = None width: int = 2 headwidth: int = 5 pivot: str = "mid" units: str = "dots"
[docs] @dataclass class StereonetTensorConfig(BaseConfig): """Stereonet tensor plot style configuration.""" planes: bool = True alpha: Any = None color: Any = None ls: str = "-" lw: float = 1.5 marker: str = "o" mew: int = 1 ms: int = 9
[docs] @dataclass class StereonetStressConfig(BaseConfig): """Stereonet stress axes marker style configuration.""" alpha: Any = None color: Any = None ls: str = "none" marker: str = "*" mew: int = 1 ms: int = 12
[docs] @dataclass class StereonetContourConfig(BaseConfig): """Stereonet contour plot configuration.""" alpha: Any = None antialiased: bool = True method: str = "sph" n_max: int = 6 cmap: str = "Greys" levels: int = 6 clines: bool = True linewidths: float = 1 linestyles: Any = None colorbar: bool = False trimzero: bool = True sigma: Any = None sigmanorm: bool = True show_data: bool = False data_kws: dict = field(default_factory=dict)
[docs] @dataclass class RoseplotConfig(BaseConfig): """Rose plot global configuration.""" bins: int = 36 density: bool = True arrowness: float = 0.95 rwidth: float = 1 scaled: bool = False kappa: int = 250 pdf_res: int = 901 title: Any = None grid: bool = True grid_kws: dict = field(default_factory=dict) tight_layout: bool = False title_kws: dict = field(default_factory=dict)
[docs] @dataclass class RoseplotBarConfig(BaseConfig): """Rose plot bar style configuration.""" alpha: Any = None color: Any = None ec: Any = None fc: Any = None ls: str = "-" lw: float = 1.5 legend: bool = False
[docs] @dataclass class RoseplotPdfConfig(BaseConfig): """Rose plot PDF line style configuration.""" alpha: Any = None color: Any = None ec: Any = None fc: Any = None ls: str = "-" lw: float = 1.5 legend: bool = False
[docs] @dataclass class RoseplotMuciConfig(BaseConfig): """Rose plot confidence interval line style configuration.""" confidence_level: int = 95 alpha: Any = None color: str = "r" ls: str = "-" lw: float = 1.5 n_resamples: int = 9999
[docs] @dataclass class FabricplotConfig(BaseConfig): """Fabric plot global configuration.""" ticks: bool = True n_ticks: int = 10 tick_size: float = 0.2 margin: float = 0.05 grid: bool = True grid_color: str = "k" grid_style: str = ":" title: Any = None tight_layout: bool = False title_kws: dict = field(default_factory=dict)
[docs] @dataclass class FabricplotPointConfig(BaseConfig): """Fabric plot point marker style configuration.""" alpha: Any = None color: Any = None mec: Any = None mfc: Any = None ls: str = "none" marker: str = "o" mew: int = 1 ms: int = 8
[docs] @dataclass class FabricplotPathConfig(BaseConfig): """Fabric plot path line style configuration.""" alpha: Any = None color: Any = None ls: str = "-" lw: float = 1.5 marker: Any = None mec: Any = None mew: int = 1 mfc: Any = None ms: int = 6
[docs] @dataclass class AppConfig(BaseConfig): """Top-level application configuration.""" notation: str = "dd" vec2geo: bool = False ndigits: int = 3 figsize: tuple = (8, 6) dpi: int = 100 facecolor: str = "white" stereonet: StereonetConfig = field(default_factory=StereonetConfig) stereonet_point: StereonetPointConfig = field(default_factory=StereonetPointConfig) stereonet_vector: StereonetVectorConfig = field( default_factory=StereonetVectorConfig ) stereonet_great_circle: StereonetGreatCircleConfig = field( default_factory=StereonetGreatCircleConfig ) stereonet_arc: StereonetArcConfig = field(default_factory=StereonetArcConfig) stereonet_scatter: StereonetScatterConfig = field( default_factory=StereonetScatterConfig ) stereonet_cone: StereonetConeConfig = field(default_factory=StereonetConeConfig) stereonet_pair: StereonetPairConfig = field(default_factory=StereonetPairConfig) stereonet_fault: StereonetFaultConfig = field(default_factory=StereonetFaultConfig) stereonet_hoeppner: StereonetHoeppnerConfig = field( default_factory=StereonetHoeppnerConfig ) stereonet_arrow: StereonetArrowConfig = field(default_factory=StereonetArrowConfig) stereonet_tensor: StereonetTensorConfig = field( default_factory=StereonetTensorConfig ) stereonet_stress: StereonetStressConfig = field( default_factory=StereonetStressConfig ) stereonet_contour: StereonetContourConfig = field( default_factory=StereonetContourConfig ) roseplot: RoseplotConfig = field(default_factory=RoseplotConfig) roseplot_bar: RoseplotBarConfig = field(default_factory=RoseplotBarConfig) roseplot_pdf: RoseplotPdfConfig = field(default_factory=RoseplotPdfConfig) roseplot_muci: RoseplotMuciConfig = field(default_factory=RoseplotMuciConfig) fabricplot: FabricplotConfig = field(default_factory=FabricplotConfig) fabricplot_point: FabricplotPointConfig = field( default_factory=FabricplotPointConfig ) fabricplot_path: FabricplotPathConfig = field(default_factory=FabricplotPathConfig)
apsg_conf = AppConfig()
[docs] @contextmanager def apsg_conf_context(**kwargs): """Context manager to temporarily override configuration.""" saved = apsg_conf.copy() apsg_conf.update(kwargs) try: yield finally: apsg_conf.update(saved)