Architecture Diagrams#
Below are core diagrams describing the system at multiple levels.
C4: System Context#
Hold "Ctrl" to enable pan & zoom
flowchart LR
user(User) -->|Provides GIS data paths & commands| pyramids{{pyramids package}}
ext1[(Raster files\nGeoTIFF/ASC/NetCDF)] --> pyramids
ext2[(Vector files\nShapefile/GeoJSON/GPKG)] --> pyramids
ext3[(UGRID NetCDF\nunstructured meshes)] --> pyramids
ext4[(Cloud / archive\ns3:// · gs:// · az:// · zip · gzip · tar)] --> pyramids
pyramids --> out1[(Processed rasters\nGeoTIFF · COG · ASC)]
pyramids --> out2[(Processed vectors\nGeoJSON · GPKG)]
pyramids --> out3[(Lazy stacks\nZarr · kerchunk JSON)]
C4: Containers#
Hold "Ctrl" to enable pan & zoom
flowchart TB
subgraph Runtime["Runtime Process"]
subgraph Base["pyramids.base"]
CRS[crs]:::b
FM[_file_manager]:::b
DOM[_domain]:::b
META[_raster_meta]:::b
end
subgraph Raster["pyramids.dataset"]
A[Dataset]:::c
C[DatasetCollection]:::c
E[engines.* IO/Spatial/Bands/Analysis/Cell/Vectorize/COG]:::e
end
subgraph NC["pyramids.netcdf"]
N[NetCDF]:::c
UG[UgridDataset]:::c
end
subgraph Vec["pyramids.feature"]
D[FeatureCollection]:::c
end
PyIO[pyramids._io]:::b
A --> Base
C --> Base
N --> Base
D --> Base
UG --> Base
A --> E
N --> A
C --> A
PyIO --> A
PyIO --> N
PyIO --> D
end
classDef c fill:#eef,stroke:#88f
classDef b fill:#efe,stroke:#8a8
classDef e fill:#fee,stroke:#c88
C4: Components#
Hold "Ctrl" to enable pan & zoom
flowchart LR
io[_io: zip · gzip · tar · /vsi-rewrite]
remote[base.remote: _to_vsi · CloudConfig]
crs[base.crs: sr_from_epsg · sr_from_wkt · reproject_coordinates]
dom[base._domain: is_no_data · inside_domain]
fm[base._file_manager: CachingFileManager · FILE_CACHE]
meta[base._raster_meta: RasterMeta]
abs[dataset.abstract_dataset.RasterBase]
ds[dataset.Dataset]
dc[dataset.DatasetCollection]
redop[dataset._reduce_ops.resolve_dask_op]
merge[dataset.merge.merge_rasters]
eng[dataset.engines.* — IO · Spatial · Bands · Analysis · Cell · Vectorize · COG]
rendercore[dataset._plot_helpers: render_array · mesh_render]
nc[netcdf.NetCDF]
ncplot[netcdf._plot.NetCDFPlot]
plotopts[netcdf.plot_options: Selectors · ColourOpts · FacetSpec]
ugds[netcdf.ugrid.UgridDataset]
ugplot[netcdf.ugrid.plot: plot_mesh_data · plot_mesh_outline]
lazy[netcdf._lazy._apply_unpack]
fc[feature.FeatureCollection]
geom[feature.geometry: Coords · GeometryCoords · create_polygon · create_point]
bm[basemap: add_basemap · get_provider]
cleo([cleopatra: ArrayGlyph · FacetGrid · MeshGlyph · styles.ColorScale · tiles])
abs --> ds
ds --> nc
ds --> eng
dc --> ds
dc --> redop
dc --> merge
nc --> lazy
nc --> ncplot
ncplot --> plotopts
ncplot --> rendercore
ugds --> ds
ugds --> rendercore
ugplot --> cleo
ds --> rendercore
dc --> rendercore
eng --> rendercore
rendercore --> bm
rendercore --> cleo
bm --> cleo
fc --> geom
fc --> bm
io --> ds
io --> nc
io --> fc
remote --> io
ds --> crs
fc --> crs
ds --> fm
dc --> fm
ds --> dom
dc --> meta
UML Class: Raster Core (with engines)#
Hold "Ctrl" to enable pan & zoom
classDiagram
class RasterBase {
<<abstract>>
+read_file(path, read_only)
+to_file(path, band)
+read_array(band, window)
}
class Dataset {
+io
+spatial
+bands
+analysis
+cell
+vectorize
+cog
+read_file(path)
+read_array(band, window)
+to_file(path)
+crop(mask)
+to_crs(to_epsg)
+plot(band, rgb_options, basemap, ...)
+_resolve_plot_band(band, rgb)
}
class NetCDF {
+variables
+get_variable(name)
+read_array(band, window, unpack)
+time_stamp
+plot(variable, *, selectors, colour, facet, coords, kind, animate, chunks, ...)
}
class _Engine {
<<abstract>>
-_ds : weakref.proxy
}
class IO
class Spatial
class Bands
class Analysis {
+stats()
+histogram()
+plot(band, ...)
}
class Cell
class Vectorize
class COG
RasterBase <|-- Dataset
Dataset <|-- NetCDF
_Engine <|-- IO
_Engine <|-- Spatial
_Engine <|-- Bands
_Engine <|-- Analysis
_Engine <|-- Cell
_Engine <|-- Vectorize
_Engine <|-- COG
Dataset *-- IO : ds.io
Dataset *-- Spatial : ds.spatial
Dataset *-- Bands : ds.bands
Dataset *-- Analysis : ds.analysis
Dataset *-- Cell : ds.cell
Dataset *-- Vectorize : ds.vectorize
Dataset *-- COG : ds.cog
UML Class: Plotting layer#
Dataset.plot / NetCDF.plot / DatasetCollection.plot / UgridDataset.plot are thin facades.
The shared pyramids.dataset._plot_helpers module owns the cleopatra dispatch (render_array for
arrays, mesh_render for meshes); pyramids.netcdf._plot.NetCDFPlot does the NetCDF-specific
variable/selector/curvilinear/facet/animate resolution and feeds render_array; Selectors /
ColourOpts / FacetSpec (in pyramids.netcdf.plot_options, re-exported from
pyramids.netcdf) are the grouped option dataclasses; pyramids.basemap.add_basemap is a thin
wrapper over cleopatra.tiles.add_tiles.
Hold "Ctrl" to enable pan & zoom
classDiagram
class Dataset {
+plot(band, rgb_options, basemap, ...)
+_resolve_plot_band(band, rgb)
}
class NetCDF {
+plot(variable, *, selectors, colour, facet, coords, kind, animate, chunks, ...)
}
class DatasetCollection {
+plot(...)
}
class UgridDataset {
+plot(variable_name, ...)
+plot_outline(...)
}
class Analysis {
+plot(band, ...)
}
class NetCDFPlot {
+run(variable, *, selectors, colour, facet, coords, kind, animate, chunks, ...)
-_resolve_selectors()
-_build_render_kwargs()
-_build_facet_stack()
-_resolve_animate_dim()
-_render_animate()
-_resolve_curvilinear_coords()
-_remove_colorbar()
}
class plot_helpers {
<<module pyramids.dataset._plot_helpers>>
+render_array(arr, extent, coords, mode, facet_kwargs, data_getter, basemap, ...)
+mesh_render(mesh, data, location, basemap, ...)
}
class Selectors {
<<frozen dataclass>>
+time
+level
+member
+sel
+isel
}
class ColourOpts {
<<frozen dataclass>>
+cmap
+vmin
+vmax
+robust
+levels
+norm
+center
+extend
+add_colorbar
+cbar_kwargs
}
class FacetSpec {
<<frozen dataclass>>
+col
+row
+col_wrap
}
class add_basemap {
<<pyramids.basemap>>
+add_basemap(ax, crs, source, ...)
+get_provider(name)
}
class ArrayGlyph {
<<cleopatra>>
+plot(kind)
+facet(col, row, col_wrap)
+animate(values, data_getter)
}
class MeshGlyph {
<<cleopatra>>
}
class cleopatra_tiles {
<<cleopatra.tiles>>
+add_tiles(ax, source, crs, ...)
+get_provider(name)
}
Dataset ..> Analysis : ds.analysis.plot
Analysis ..> plot_helpers : render_array
NetCDF ..> NetCDFPlot : delegates plot
NetCDFPlot ..> plot_helpers : render_array
NetCDFPlot ..> Selectors : uses
NetCDFPlot ..> ColourOpts : uses
NetCDFPlot ..> FacetSpec : uses
DatasetCollection ..> plot_helpers : render_array(mode="animate")
UgridDataset ..> plot_helpers : mesh_render
plot_helpers ..> ArrayGlyph : builds
plot_helpers ..> MeshGlyph : builds (mesh_render)
plot_helpers ..> add_basemap : basemap overlay
add_basemap ..> cleopatra_tiles : delegates
UML Class: Vector Core#
Hold "Ctrl" to enable pan & zoom
classDiagram
class FeatureCollection {
+read_file(path)
+to_file(path, driver)
+epsg
+total_bounds
+column
+schema
+explode()
}
class Coords {
+to_polygon()
+to_polygon_wkt()
+to_points()
+to_geodataframe()
}
class GeometryCoords {
+x
+y
+xy
}
FeatureCollection ..> Coords : uses
FeatureCollection ..> GeometryCoords : uses
Sequence: Read Raster from Zip#
Hold "Ctrl" to enable pan & zoom
sequenceDiagram
participant U as User
participant DS as Dataset
participant IO as pyramids._io
participant REM as pyramids.base.remote
U->>DS: Dataset.read_file("dem.zip!dem.tif")
DS->>IO: parse path
IO->>REM: _to_vsi(...)
REM-->>IO: /vsizip/... path
IO-->>DS: gdal.Dataset handle
DS-->>U: Dataset instance
Sequence: Crop via the Spatial engine#
Hold "Ctrl" to enable pan & zoom
sequenceDiagram
participant U as User
participant DS as Dataset
participant SP as Spatial (ds.spatial)
U->>DS: ds.crop(mask)
DS->>SP: spatial.crop(mask) (facade)
SP->>DS: read_array · build dst MEM
SP-->>DS: cropped Dataset
DS-->>U: cropped Dataset
Sequence: Save Raster to GeoTIFF / COG#
Hold "Ctrl" to enable pan & zoom
sequenceDiagram
participant U as User
participant DS as Dataset
participant IO as IO (ds.io)
participant CG as COG (ds.cog)
U->>DS: ds.to_file("out.tif")
DS->>IO: io.to_file(...)
IO-->>U: out.tif
U->>DS: ds.to_cog("out.tif", compress="ZSTD")
DS->>CG: cog.to_cog(...)
CG-->>U: out.tif (COG)
Sequence: Build DatasetCollection from a Folder#
Hold "Ctrl" to enable pan & zoom
sequenceDiagram
participant U as User
participant DC as DatasetCollection
participant DS as Dataset
U->>DC: DatasetCollection.from_files(paths)
Note over DC: lazy — no pixels read yet
U->>DC: cube.iloc(0)
DC->>DS: Dataset.read_file(paths[0])
DS-->>DC: Dataset (gdal handle open)
DC-->>U: Dataset
U->>DC: cube.mean()
DC->>DC: dask graph over per-file _read_time_step
DC-->>U: ndarray (T-axis reduced)
Sequence: Zonal Statistics#
Hold "Ctrl" to enable pan & zoom
sequenceDiagram
participant U as User
participant DS as Dataset
participant FC as FeatureCollection
U->>FC: FeatureCollection.read_file(polygons.gpkg)
U->>DS: Dataset.read_file(raster.tif)
FC->>DS: zonal_stats(raster, polygons)
DS-->>U: stats DataFrame
Sequence: Reproject (maintain_alignment=True)#
Hold "Ctrl" to enable pan & zoom
sequenceDiagram
participant U as User
participant DS as Dataset
participant SP as Spatial (ds.spatial)
U->>DS: ds.to_crs(to_epsg=3857, maintain_alignment=True)
DS->>SP: _reproject_with_ReprojectImage
SP->>SP: reproject one-pixel X-step + one-pixel Y-step
SP->>SP: build dst (cols, rows, geo from x_spacing, y_spacing)
SP-->>DS: gdal.ReprojectImage(src, dst)
DS-->>U: reprojected Dataset
Dependency Graph (Modules)#
An arrow X --> Y reads "module X is imported by Y".
Hold "Ctrl" to enable pan & zoom
flowchart LR
abstract_dataset --> dataset
base_crs[base.crs] --> dataset
base_crs --> feature
base_domain[base._domain] --> dataset
base_domain --> dataset_collection
base_file_manager[base._file_manager] --> dataset
base_file_manager --> dataset_collection
base_raster_meta[base._raster_meta] --> dataset_collection
pyramids_io[_io] --> dataset
pyramids_io --> netcdf
pyramids_io --> feature
dataset --> netcdf
dataset --> dataset_collection
dataset --> engines
netcdf_lazy[netcdf._lazy] --> netcdf
ugrid --> dataset
feature_geometry[feature.geometry] --> feature
reduce_ops[dataset._reduce_ops] --> dataset_collection
merge_mod[dataset.merge] --> dataset_collection
plot_helpers[dataset._plot_helpers] --> engines
plot_helpers --> dataset_collection
plot_helpers --> ugrid
netcdfplot_options[netcdf.plot_options] --> netcdf_plot
netcdfplot_options --> netcdf
plot_helpers --> netcdf_plot[netcdf._plot]
netcdf_plot --> netcdf
basemap_mod[basemap] --> plot_helpers
basemap_mod --> feature
cleopatra_pkg([cleopatra · cleopatra.tiles]) --> plot_helpers
cleopatra_pkg --> basemap_mod
cleopatra_pkg --> ugrid
Detailed Class Diagram#
Hold "Ctrl" to enable pan & zoom
classDiagram
%% configuration class
class config_Config {
+__init__(config_file)
+load_config()
+initialize_gdal()
+set_env_conda()
+dynamic_env_variables()
+setup_logging()
}
%% abstract base class for rasters
class abstract_dataset_RasterBase {
+__init__(src, access)
+__str__()
+__repr__()
+access
+raster
+rows · columns · shape
+geotransform
+top_left_corner
+epsg · crs
+cell_size
+no_data_value
+meta_data
+block_size
+file_name
+driver_type
+read_file(path, read_only)
+read_array(band, window)
+plot(...)
}
%% concrete raster class
class dataset_Dataset {
+__init__(src, access)
+io · spatial · bands · analysis
+cell · vectorize · cog
+read_file(path)
+create_from_array(arr, top_left_corner, cell_size, epsg)
+create_from_array(arr, geo, epsg)
+read_array(band, window)
+to_file(path, driver)
+to_cog(path, ...)
+is_cog
+validate_cog()
+to_crs(to_epsg, method, maintain_alignment)
+resample(cell_size, method)
+align(alignment_src)
+crop(mask, touch)
+apply(ufunc)
+overlay(classes_map, exclude_value)
+plot(band, rgb_options, basemap, ...)
+_resolve_plot_band(band, rgb)
}
%% NetCDF: raster class specialised for NetCDF variables
class netcdf_NetCDF {
+__init__(src, access, open_as_multi_dimensional)
+lon · lat · x · y
+variables · get_variable(name)
+no_data_value
+file_name · time_stamp
+read_file(path, read_only, open_as_multi_dimensional)
+read_array(band, window, unpack, chunks)
+get_variable_names()
+get_variables(read_only)
+is_subset · is_md_array
+create_from_array(arr, geo, ...)
+add_variable(dataset, variable_name)
+remove_variable(variable_name)
+plot(variable, *, selectors, colour, facet, coords, kind, animate, chunks, ...)
}
%% UgridDataset
class ugrid_UgridDataset {
+__init__(src)
+mesh · n_face
+data_variable_names
+read_file(path)
+create_from_arrays(...)
+to_dataset(...)
+to_geodataframe()
+plot(variable_name, ...)
+plot_outline(...)
}
%% DatasetCollection: lazy temporal stack
class collection_DatasetCollection {
+__init__(src, time_length, files, datasets, meta)
+base · files · time_length · shape
+datasets · data
+iloc(i) · __getitem__ · __setitem__
+head · tail · first · last
+mean · sum · min · max · std · var
+groupby(labels)
+crop · to_crs · align · apply
+to_file · to_zarr · to_kerchunk · merge
+plot(...)
}
%% Plotting layer (shared cleopatra dispatch + NetCDF resolver + option dataclasses)
class plot_helpers_module {
<<module pyramids.dataset._plot_helpers>>
+render_array(arr, extent, coords, mode, facet_kwargs, data_getter, basemap, ...)
+mesh_render(mesh, data, location, basemap, ...)
}
class netcdf_NetCDFPlot {
+run(variable, *, selectors, colour, facet, coords, kind, animate, chunks, ...)
-_resolve_selectors()
-_build_render_kwargs()
-_build_facet_stack()
-_resolve_animate_dim()
-_render_animate()
-_resolve_curvilinear_coords()
-_remove_colorbar()
}
class netcdf_Selectors {
<<frozen dataclass>>
+time · level · member · sel · isel
}
class netcdf_ColourOpts {
<<frozen dataclass>>
+cmap · vmin · vmax · robust · levels
+norm · center · extend · add_colorbar · cbar_kwargs
}
class netcdf_FacetSpec {
<<frozen dataclass>>
+col · row · col_wrap
}
class basemap_module {
<<module pyramids.basemap>>
+add_basemap(ax, crs, source, ...)
+get_provider(name)
}
class cleopatra_pkg {
<<external cleopatra>>
+ArrayGlyph.plot(kind) · ArrayGlyph.facet() · ArrayGlyph.animate(data_getter)
+MeshGlyph
+styles.ColorScale
+tiles.add_tiles() · tiles.get_provider()
}
%% Engines (Dataset collaborators)
class engines_IO {
+read_array · _lazy_read_array
+to_file · to_raster
+read_overview · get_block_arrangement
+to_xyz · map_blocks
}
class engines_Spatial {
+to_crs · resample · align
+crop · _crop_aligned
+set_crs · _get_epsg
}
class engines_Bands {
+color_table · _get_color_table · _set_color_table
+_change_no_data_value_attr
+_check_no_data_value · _set_no_data_value
+change_no_data_value
+rats · stats helpers
}
class engines_Analysis {
+stats · count_domain_cells
+overlay · histogram
+plot
}
class engines_Cell {
+get_cell_coords · get_cell_polygons · get_cell_points
+map_to_array_coordinates · array_to_map_coordinates
}
class engines_Vectorize {
+to_feature_collection · translate
+cluster · cluster2
}
class engines_COG {
+to_cog · is_cog · validate_cog
}
%% FeatureCollection for vector data
class feature_FeatureCollection {
+__init__(gdf)
+epsg · total_bounds · top_left_corner
+column · schema · file_name
+read_file(path)
+to_file(path, driver)
+explode()
+to_dataset(...)
}
class feature_Coords {
+to_polygon()
+to_polygon_wkt()
+to_points()
+to_geodataframe()
}
class feature_GeometryCoords {
+x
+y
+xy
}
%% inheritance relations
abstract_dataset_RasterBase <|-- dataset_Dataset
dataset_Dataset <|-- netcdf_NetCDF
%% engine composition
dataset_Dataset *-- engines_IO : ds.io
dataset_Dataset *-- engines_Spatial : ds.spatial
dataset_Dataset *-- engines_Bands : ds.bands
dataset_Dataset *-- engines_Analysis : ds.analysis
dataset_Dataset *-- engines_Cell : ds.cell
dataset_Dataset *-- engines_Vectorize : ds.vectorize
dataset_Dataset *-- engines_COG : ds.cog
%% other relations
collection_DatasetCollection o-- dataset_Dataset : per-timestep
ugrid_UgridDataset ..> dataset_Dataset : interpolate
feature_FeatureCollection ..> dataset_Dataset : rasterize
dataset_Dataset ..> feature_FeatureCollection : vectorize
feature_FeatureCollection ..> feature_Coords : uses
feature_FeatureCollection ..> feature_GeometryCoords : uses
config_Config ..> dataset_Dataset : initialises GDAL settings
%% plotting layer relations
netcdf_NetCDF ..> netcdf_NetCDFPlot : delegates plot()
netcdf_NetCDFPlot ..> netcdf_Selectors : uses
netcdf_NetCDFPlot ..> netcdf_ColourOpts : uses
netcdf_NetCDFPlot ..> netcdf_FacetSpec : uses
netcdf_NetCDFPlot ..> plot_helpers_module : render_array
engines_Analysis ..> plot_helpers_module : render_array
collection_DatasetCollection ..> plot_helpers_module : render_array(mode="animate")
ugrid_UgridDataset ..> plot_helpers_module : mesh_render
feature_FeatureCollection ..> basemap_module : add_basemap
plot_helpers_module ..> basemap_module : basemap overlay
plot_helpers_module ..> cleopatra_pkg : ArrayGlyph / MeshGlyph
basemap_module ..> cleopatra_pkg : cleopatra.tiles