canvodpy 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. canvodpy-0.2.0/PKG-INFO +151 -0
  2. canvodpy-0.2.0/README.md +110 -0
  3. canvodpy-0.2.0/pyproject.toml +77 -0
  4. canvodpy-0.2.0/src/canvodpy/.DS_Store +0 -0
  5. canvodpy-0.2.0/src/canvodpy/__init__.py +276 -0
  6. canvodpy-0.2.0/src/canvodpy/api.py +707 -0
  7. canvodpy-0.2.0/src/canvodpy/cli/__init__.py +0 -0
  8. canvodpy-0.2.0/src/canvodpy/cli/run.py +366 -0
  9. canvodpy-0.2.0/src/canvodpy/diagnostics/.DS_Store +0 -0
  10. canvodpy-0.2.0/src/canvodpy/diagnostics/__init__.py +9 -0
  11. canvodpy-0.2.0/src/canvodpy/diagnostics/sbf_timing_diagnostics_new_api.py +239 -0
  12. canvodpy-0.2.0/src/canvodpy/diagnostics/timing_diagnostics_new_api.py +242 -0
  13. canvodpy-0.2.0/src/canvodpy/diagnostics/timing_diagnostics_script.py +246 -0
  14. canvodpy-0.2.0/src/canvodpy/factories.py +376 -0
  15. canvodpy-0.2.0/src/canvodpy/fluent.py +477 -0
  16. canvodpy-0.2.0/src/canvodpy/functional.py +585 -0
  17. canvodpy-0.2.0/src/canvodpy/globals.py +50 -0
  18. canvodpy-0.2.0/src/canvodpy/logging/.DS_Store +0 -0
  19. canvodpy-0.2.0/src/canvodpy/logging/__init__.py +50 -0
  20. canvodpy-0.2.0/src/canvodpy/logging/context.py +37 -0
  21. canvodpy-0.2.0/src/canvodpy/logging/logging_config.py +437 -0
  22. canvodpy-0.2.0/src/canvodpy/orchestrator/.DS_Store +0 -0
  23. canvodpy-0.2.0/src/canvodpy/orchestrator/__init__.py +46 -0
  24. canvodpy-0.2.0/src/canvodpy/orchestrator/interpolator.py +369 -0
  25. canvodpy-0.2.0/src/canvodpy/orchestrator/matcher.py +158 -0
  26. canvodpy-0.2.0/src/canvodpy/orchestrator/pipeline.py +1344 -0
  27. canvodpy-0.2.0/src/canvodpy/orchestrator/processor.py +3404 -0
  28. canvodpy-0.2.0/src/canvodpy/orchestrator/resources.py +302 -0
  29. canvodpy-0.2.0/src/canvodpy/utils/.DS_Store +0 -0
  30. canvodpy-0.2.0/src/canvodpy/utils/__init__.py +37 -0
  31. canvodpy-0.2.0/src/canvodpy/utils/perf.py +41 -0
  32. canvodpy-0.2.0/src/canvodpy/utils/telemetry.py +367 -0
  33. canvodpy-0.2.0/src/canvodpy/vod_computer.py +349 -0
  34. canvodpy-0.2.0/src/canvodpy/workflow.py +471 -0
  35. canvodpy-0.2.0/src/canvodpy/workflows/__init__.py +27 -0
  36. canvodpy-0.2.0/src/canvodpy/workflows/tasks.py +1394 -0
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.3
2
+ Name: canvodpy
3
+ Version: 0.2.0
4
+ Summary: Umbrella package for canVOD ecosystem
5
+ Keywords: GNSS,VOD,vegetation,remote sensing,geodesy
6
+ Author: Nicolas François Bader
7
+ Author-email: Nicolas François Bader <nicolas.bader@tuwien.ac.at>
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Classifier: Topic :: Scientific/Engineering :: GIS
14
+ Requires-Dist: canvod-readers
15
+ Requires-Dist: canvod-auxiliary
16
+ Requires-Dist: canvod-grids
17
+ Requires-Dist: canvod-store
18
+ Requires-Dist: canvod-store-metadata
19
+ Requires-Dist: canvod-utils
20
+ Requires-Dist: canvod-viz
21
+ Requires-Dist: canvod-vod
22
+ Requires-Dist: marimo>=0.9.0
23
+ Requires-Dist: matplotlib>=3.8.0
24
+ Requires-Dist: pint>=0.20
25
+ Requires-Dist: structlog>=23.0
26
+ Requires-Dist: pydantic>=2.0
27
+ Requires-Dist: tqdm>=4.65
28
+ Requires-Dist: tomli>=2.0.0
29
+ Requires-Dist: natsort>=8.0.0
30
+ Requires-Dist: dask[distributed]>=2026.1.1
31
+ Requires-Dist: mystmd>=1.8.0
32
+ Requires-Dist: docker>=7.1.0
33
+ Requires-Dist: howfairis>=0.13.0
34
+ Requires-Dist: pyarrow>=23.0.1
35
+ Requires-Dist: palettable>=3.3.3
36
+ Requires-Dist: altair>=6.0.0
37
+ Requires-Dist: tabulate>=0.10.0
38
+ Requires-Dist: sqlglot>=29.0.1
39
+ Requires-Python: >=3.14
40
+ Description-Content-Type: text/markdown
41
+
42
+ # canvodpy
43
+
44
+ Umbrella package for unified GNSS VOD analysis.
45
+
46
+ ## Overview
47
+
48
+ `canvodpy` is the unified entry point for the canVOD ecosystem. It provides
49
+ three levels of API:
50
+
51
+ - **Level 1:** One-line convenience functions (fastest path to results)
52
+ - **Level 2:** Object-oriented classes (structured workflows)
53
+ - **Level 3:** Low-level components (full control)
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ # Installs canvodpy + all 7 sub-packages
59
+ uv pip install canvodpy
60
+ ```
61
+
62
+ ## Quick Start
63
+
64
+ ### Level 1: Simple (One-Liners)
65
+
66
+ ```python
67
+ from canvodpy import process_date, calculate_vod
68
+
69
+ # Process one day of data
70
+ data = process_date("Rosalia", "2025001")
71
+
72
+ # Calculate VOD
73
+ vod = calculate_vod("Rosalia", "canopy_01", "reference_01", "2025001")
74
+ ```
75
+
76
+ ### Level 2: Object-Oriented (More Control)
77
+
78
+ ```python
79
+ from canvodpy import Site, Pipeline
80
+
81
+ # Create site and pipeline
82
+ site = Site("Rosalia")
83
+ pipeline = site.pipeline(aux_agency="ESA", n_workers=8)
84
+
85
+ # Process data
86
+ data = pipeline.process_date("2025001")
87
+
88
+ # Or process multiple days
89
+ for date, datasets in pipeline.process_range("2025001", "2025007"):
90
+ print(f"Processed {date}")
91
+ ```
92
+
93
+ ### Level 3: Low-Level (Full Control)
94
+
95
+ ```python
96
+ from canvod.readers import Rnxv3Obs
97
+ from canvod.auxiliary import Sp3File, ClkFile
98
+ from canvod.store import GnssResearchSite
99
+ from canvodpy.orchestrator import PipelineOrchestrator
100
+
101
+ # Direct access to all internals
102
+ site = GnssResearchSite("Rosalia")
103
+ orchestrator = PipelineOrchestrator(site, n_max_workers=12)
104
+ # ... custom processing ...
105
+ ```
106
+
107
+ ## Included Packages
108
+
109
+ Installing canvodpy provides access to all 7 packages:
110
+
111
+ - **canvod.readers** -- RINEX file parsing (v3.04)
112
+ - **canvod.auxiliary** -- Auxiliary data (SP3, CLK) handling
113
+ - **canvod.grids** -- Hemisphere grid structures
114
+ - **canvod.store** -- Icechunk data storage
115
+ - **canvod.vod** -- VOD calculation algorithms
116
+ - **canvod.viz** -- 2D/3D visualization
117
+ - **canvod.utils** -- Shared utilities
118
+
119
+ ## Platform Support
120
+
121
+ | Platform | Status | Notes |
122
+ |----------|--------|-------|
123
+ | Linux | Full support | Recommended |
124
+ | macOS | Full support | Fully tested |
125
+ | Windows | WSL only | Native not supported (reserved `aux` name) |
126
+
127
+ ## Configuration
128
+
129
+ Create a `.env` file in repository root (optional for NASA products):
130
+
131
+ ```bash
132
+ # NASA CDDIS credentials (optional)
133
+ CDDIS_MAIL=your.email@example.com
134
+
135
+ # Data root directory (required)
136
+ GNSS_ROOT_DIR=/path/to/your/data
137
+ ```
138
+
139
+ Without `.env`, canvodpy operates in ESA-only mode (COD, GFZ, ESA products).
140
+
141
+ ## Documentation
142
+
143
+ [Centralized documentation](../docs/index.md)
144
+
145
+ ## Development
146
+
147
+ See the [main repository README](../README.md) for workspace development setup.
148
+
149
+ ## License
150
+
151
+ Apache License 2.0
@@ -0,0 +1,110 @@
1
+ # canvodpy
2
+
3
+ Umbrella package for unified GNSS VOD analysis.
4
+
5
+ ## Overview
6
+
7
+ `canvodpy` is the unified entry point for the canVOD ecosystem. It provides
8
+ three levels of API:
9
+
10
+ - **Level 1:** One-line convenience functions (fastest path to results)
11
+ - **Level 2:** Object-oriented classes (structured workflows)
12
+ - **Level 3:** Low-level components (full control)
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ # Installs canvodpy + all 7 sub-packages
18
+ uv pip install canvodpy
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### Level 1: Simple (One-Liners)
24
+
25
+ ```python
26
+ from canvodpy import process_date, calculate_vod
27
+
28
+ # Process one day of data
29
+ data = process_date("Rosalia", "2025001")
30
+
31
+ # Calculate VOD
32
+ vod = calculate_vod("Rosalia", "canopy_01", "reference_01", "2025001")
33
+ ```
34
+
35
+ ### Level 2: Object-Oriented (More Control)
36
+
37
+ ```python
38
+ from canvodpy import Site, Pipeline
39
+
40
+ # Create site and pipeline
41
+ site = Site("Rosalia")
42
+ pipeline = site.pipeline(aux_agency="ESA", n_workers=8)
43
+
44
+ # Process data
45
+ data = pipeline.process_date("2025001")
46
+
47
+ # Or process multiple days
48
+ for date, datasets in pipeline.process_range("2025001", "2025007"):
49
+ print(f"Processed {date}")
50
+ ```
51
+
52
+ ### Level 3: Low-Level (Full Control)
53
+
54
+ ```python
55
+ from canvod.readers import Rnxv3Obs
56
+ from canvod.auxiliary import Sp3File, ClkFile
57
+ from canvod.store import GnssResearchSite
58
+ from canvodpy.orchestrator import PipelineOrchestrator
59
+
60
+ # Direct access to all internals
61
+ site = GnssResearchSite("Rosalia")
62
+ orchestrator = PipelineOrchestrator(site, n_max_workers=12)
63
+ # ... custom processing ...
64
+ ```
65
+
66
+ ## Included Packages
67
+
68
+ Installing canvodpy provides access to all 7 packages:
69
+
70
+ - **canvod.readers** -- RINEX file parsing (v3.04)
71
+ - **canvod.auxiliary** -- Auxiliary data (SP3, CLK) handling
72
+ - **canvod.grids** -- Hemisphere grid structures
73
+ - **canvod.store** -- Icechunk data storage
74
+ - **canvod.vod** -- VOD calculation algorithms
75
+ - **canvod.viz** -- 2D/3D visualization
76
+ - **canvod.utils** -- Shared utilities
77
+
78
+ ## Platform Support
79
+
80
+ | Platform | Status | Notes |
81
+ |----------|--------|-------|
82
+ | Linux | Full support | Recommended |
83
+ | macOS | Full support | Fully tested |
84
+ | Windows | WSL only | Native not supported (reserved `aux` name) |
85
+
86
+ ## Configuration
87
+
88
+ Create a `.env` file in repository root (optional for NASA products):
89
+
90
+ ```bash
91
+ # NASA CDDIS credentials (optional)
92
+ CDDIS_MAIL=your.email@example.com
93
+
94
+ # Data root directory (required)
95
+ GNSS_ROOT_DIR=/path/to/your/data
96
+ ```
97
+
98
+ Without `.env`, canvodpy operates in ESA-only mode (COD, GFZ, ESA products).
99
+
100
+ ## Documentation
101
+
102
+ [Centralized documentation](../docs/index.md)
103
+
104
+ ## Development
105
+
106
+ See the [main repository README](../README.md) for workspace development setup.
107
+
108
+ ## License
109
+
110
+ Apache License 2.0
@@ -0,0 +1,77 @@
1
+ [project]
2
+ name = "canvodpy"
3
+ version = "0.2.0"
4
+ description = "Umbrella package for canVOD ecosystem"
5
+ readme = "README.md"
6
+ requires-python = ">=3.14"
7
+ authors = [
8
+ { name = "Nicolas François Bader", email = "nicolas.bader@tuwien.ac.at" },
9
+ ]
10
+ keywords = ["GNSS", "VOD", "vegetation", "remote sensing", "geodesy"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Science/Research",
14
+ "License :: OSI Approved :: Apache Software License",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.14",
17
+ "Topic :: Scientific/Engineering :: GIS",
18
+ ]
19
+
20
+ # Core dependencies - sub-packages from workspace
21
+ dependencies = [
22
+ "canvod-readers",
23
+ "canvod-auxiliary",
24
+ "canvod-grids",
25
+ "canvod-store",
26
+ "canvod-store-metadata",
27
+ "canvod-utils",
28
+ "canvod-viz",
29
+ "canvod-vod",
30
+ "marimo>=0.9.0",
31
+ "matplotlib>=3.8.0",
32
+ "pint>=0.20",
33
+ "structlog>=23.0",
34
+ "pydantic>=2.0",
35
+ "tqdm>=4.65",
36
+ "tomli>=2.0.0",
37
+ "natsort>=8.0.0",
38
+ "dask[distributed]>=2026.1.1",
39
+ "mystmd>=1.8.0",
40
+ "docker>=7.1.0",
41
+ "howfairis>=0.13.0",
42
+ "pyarrow>=23.0.1",
43
+ "palettable>=3.3.3",
44
+ "altair>=6.0.0",
45
+ "tabulate>=0.10.0",
46
+ "sqlglot>=29.0.1",
47
+ ]
48
+
49
+ [dependency-groups]
50
+ dev = [
51
+ "pytest>=8.0",
52
+ "pytest-cov>=5.0",
53
+ "ruff>=0.14",
54
+ "ty>=0.0.9",
55
+ ]
56
+
57
+ [build-system]
58
+ requires = ["uv_build>=0.9.17,<0.10.0"]
59
+ build-backend = "uv_build"
60
+
61
+ # Workspace package sources
62
+ # This tells uv where to find the local packages
63
+ [tool.uv.sources]
64
+ canvod-readers = { workspace = true }
65
+ canvod-auxiliary = { workspace = true }
66
+ canvod-grids = { workspace = true }
67
+ canvod-store = { workspace = true }
68
+ canvod-store-metadata = { workspace = true }
69
+ canvod-utils = { workspace = true }
70
+ canvod-viz = { workspace = true }
71
+ canvod-vod = { workspace = true }
72
+
73
+ [tool.ty]
74
+ extend-exclude = [
75
+ "**/docs/*.ipynb",
76
+ "**/docs/notebooks/*.py",
77
+ ]
Binary file
@@ -0,0 +1,276 @@
1
+ """canvodpy: GNSS Vegetation Optical Depth Analysis.
2
+
3
+ A modern Python package for processing GNSS data and calculating
4
+ vegetation optical depth (VOD) using the tau-omega model.
5
+
6
+ Quick Start
7
+ -----------
8
+ Three levels of API to match your needs:
9
+
10
+ **Level 1: Simple (one-liners)**
11
+ >>> from canvodpy import process_date, calculate_vod
12
+ >>> data = process_date("Rosalia", "2025001")
13
+ >>> vod = calculate_vod("Rosalia", "canopy_01", "reference_01", "2025001")
14
+
15
+ **Level 2: Object-oriented (more control)**
16
+ >>> from canvodpy import Site, Pipeline
17
+ >>> site = Site("Rosalia")
18
+ >>> pipeline = site.pipeline()
19
+ >>> data = pipeline.process_date("2025001")
20
+ >>> vod = pipeline.calculate_vod("canopy_01", "reference_01", "2025001")
21
+
22
+ **Level 3: Low-level (full control)**
23
+ >>> from canvod.store import GnssResearchSite
24
+ >>> from canvod.vod import VODCalculator
25
+ >>> # Direct access to all internals
26
+
27
+ Community Extensions
28
+ --------------------
29
+ Extend canvodpy with custom components using factories:
30
+
31
+ >>> from canvodpy import VODFactory
32
+ >>> from my_package import CustomCalculator
33
+ >>> VODFactory.register("custom", CustomCalculator)
34
+ >>> calc = VODFactory.create("custom", **params)
35
+
36
+ Package Structure
37
+ -----------------
38
+ - canvod.readers - RINEX file parsing
39
+ - canvod.auxiliary - Auxiliary data (ephemeris, clocks)
40
+ - canvod.grids - Hemisphere grid structures
41
+ - canvod.vod - VOD calculation algorithms
42
+ - canvod.viz - 2D/3D visualization
43
+ - canvod.store - Icechunk data storage
44
+
45
+ Configuration
46
+ -------------
47
+ Site configurations are stored in ``config/sites.yaml``.
48
+ Default variables and settings are in `globals.py`.
49
+
50
+ Examples
51
+ --------
52
+ Process one day of data:
53
+ >>> from canvodpy import process_date
54
+ >>> data = process_date("Rosalia", "2025001")
55
+
56
+ Process a week:
57
+ >>> from canvodpy import Pipeline
58
+ >>> pipeline = Pipeline("Rosalia")
59
+ >>> for date, datasets in pipeline.process_range("2025001", "2025007"):
60
+ ... print(f"Processed {date}")
61
+
62
+ Calculate and visualize VOD:
63
+ >>> from canvodpy import calculate_vod
64
+ >>> from canvod.viz import HemisphereVisualizer
65
+ >>> vod = calculate_vod("Rosalia", "canopy_01", "reference_01", "2025001")
66
+ >>> viz = HemisphereVisualizer()
67
+ >>> fig = viz.plot_2d(vod)
68
+
69
+ """
70
+
71
+ from canvodpy.api import (
72
+ Pipeline,
73
+ Site,
74
+ calculate_vod,
75
+ preview_processing,
76
+ process_date,
77
+ )
78
+
79
+ # Factories (for community extensions)
80
+ from canvodpy.factories import (
81
+ AugmentationFactory,
82
+ GridFactory,
83
+ ReaderFactory,
84
+ VODFactory,
85
+ )
86
+
87
+ # Fluent workflow API (deferred execution)
88
+ from canvodpy.fluent import FluentWorkflow
89
+
90
+ # Functional API (Airflow-compatible)
91
+ from canvodpy.functional import (
92
+ assign_grid_cells,
93
+ assign_grid_cells_to_file,
94
+ augment_with_ephemeris,
95
+ calculate_vod_to_file,
96
+ create_grid,
97
+ create_grid_to_file,
98
+ read_rinex,
99
+ read_rinex_to_file,
100
+ )
101
+
102
+ # Logging (for all users)
103
+ from canvodpy.logging import get_logger, setup_logging
104
+
105
+ # VOD computation helper
106
+ from canvodpy.vod_computer import VodComputer
107
+
108
+ # New workflow API
109
+ from canvodpy.workflow import VODWorkflow
110
+
111
+
112
+ def workflow(site: str, **kwargs) -> FluentWorkflow:
113
+ """Create a fluent workflow with deferred execution.
114
+
115
+ Parameters
116
+ ----------
117
+ site : str
118
+ Site name (e.g. ``"Rosalia"``).
119
+ **kwargs
120
+ Forwarded to :class:`FluentWorkflow`.
121
+
122
+ Returns
123
+ -------
124
+ FluentWorkflow
125
+
126
+ Examples
127
+ --------
128
+ >>> import canvodpy
129
+ >>> result = (canvodpy.workflow("Rosalia")
130
+ ... .read("2025001")
131
+ ... .preprocess()
132
+ ... .grid()
133
+ ... .vod("canopy_01", "reference_01")
134
+ ... .result())
135
+ """
136
+ return FluentWorkflow(site, **kwargs)
137
+
138
+
139
+ # ============================================================================
140
+ # Level 3 API: Re-export subpackages for advanced users
141
+ # ============================================================================
142
+
143
+
144
+ # Lazy import subpackages on access to avoid circular dependencies
145
+ def __getattr__(name: str):
146
+ """Lazy import subpackages when accessed."""
147
+ _subpackages = {
148
+ "auxiliary": "canvod.auxiliary",
149
+ "grids": "canvod.grids",
150
+ "readers": "canvod.readers",
151
+ "store": "canvod.store",
152
+ "viz": "canvod.viz",
153
+ "vod": "canvod.vod",
154
+ }
155
+
156
+ if name in _subpackages:
157
+ import importlib
158
+ import sys
159
+
160
+ module = importlib.import_module(_subpackages[name])
161
+ # Cache the imported module (can't use globals() as it's shadowed by canvodpy.globals)
162
+ setattr(sys.modules[__name__], name, module)
163
+ return module
164
+
165
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
166
+
167
+
168
+ # ============================================================================
169
+ # Version
170
+ # ============================================================================
171
+
172
+ __version__ = "0.1.0"
173
+
174
+ # ============================================================================
175
+ # Public API
176
+ # ============================================================================
177
+
178
+ __all__ = [ # noqa: RUF022
179
+ # Version
180
+ "__version__",
181
+ # High-level API (most users)
182
+ "Site",
183
+ "Pipeline",
184
+ "process_date",
185
+ "calculate_vod",
186
+ "preview_processing",
187
+ # New workflow API
188
+ "VODWorkflow",
189
+ # Fluent workflow API
190
+ "FluentWorkflow",
191
+ "workflow",
192
+ # Functional API (notebooks & Airflow)
193
+ "read_rinex",
194
+ "read_rinex_to_file",
195
+ "create_grid",
196
+ "create_grid_to_file",
197
+ "assign_grid_cells",
198
+ "assign_grid_cells_to_file",
199
+ "calculate_vod_to_file",
200
+ # Logging
201
+ "setup_logging",
202
+ "get_logger",
203
+ # Factories (community extensions)
204
+ "ReaderFactory",
205
+ "GridFactory",
206
+ "VODFactory",
207
+ "AugmentationFactory",
208
+ # Subpackages (advanced users)
209
+ "readers",
210
+ "aux",
211
+ "grids",
212
+ "vod",
213
+ "viz",
214
+ "store",
215
+ ]
216
+
217
+
218
+ # ============================================================================
219
+ # Auto-register built-in components
220
+ # ============================================================================
221
+
222
+
223
+ def _register_builtin_components() -> None:
224
+ """
225
+ Register built-in component implementations.
226
+
227
+ Called automatically on package import. Registers:
228
+ - Rnxv3Obs reader (rinex3)
229
+ - EqualAreaGridBuilder (equal_area)
230
+ - TauOmegaZerothOrder calculator (tau_omega)
231
+
232
+ Notes
233
+ -----
234
+ Uses lazy imports to avoid loading heavy dependencies unless needed.
235
+ """
236
+ log = get_logger(__name__)
237
+
238
+ # Set ABC classes for validation
239
+ ReaderFactory._set_abc_class()
240
+ GridFactory._set_abc_class()
241
+ VODFactory._set_abc_class()
242
+ AugmentationFactory._set_abc_class()
243
+
244
+ try:
245
+ from canvod.readers import Rnxv3Obs
246
+
247
+ ReaderFactory.register("rinex3", Rnxv3Obs)
248
+ except ImportError:
249
+ log.debug("canvod-readers not available, skipping reader registration")
250
+
251
+ try:
252
+ from canvod.readers.sbf import SbfReader
253
+
254
+ ReaderFactory.register("sbf", SbfReader)
255
+ except ImportError:
256
+ log.debug("SbfReader not available, skipping sbf reader registration")
257
+
258
+ try:
259
+ from canvod.grids import EqualAreaBuilder
260
+
261
+ GridFactory.register("equal_area", EqualAreaBuilder)
262
+ except ImportError:
263
+ log.debug("canvod-grids not available, skipping grid registration")
264
+
265
+ try:
266
+ from canvod.vod.calculator import TauOmegaZerothOrder
267
+
268
+ VODFactory.register("tau_omega", TauOmegaZerothOrder)
269
+ except ImportError:
270
+ log.debug("canvod-vod not available, skipping VOD registration")
271
+
272
+ log.info("builtin_components_registered")
273
+
274
+
275
+ # Auto-register on import
276
+ _register_builtin_components()