canvod.virtualiconvname API Reference¶
Filename convention, mapping, validation, and cataloging.
Convention¶
Pydantic v2 model for the canVOD file naming convention.
Convention::
{SIT}{T}{NN}{AGC}_R_{YYYY}{DOY}{HHMM}_{PERIOD}_{SAMPLING}_{CONTENT}.{TYPE}[.{COMPRESSION}]
SIT 3-char site ID, uppercase (e.g. ROS, HAI, FON, LBS)
T Receiver type, single uppercase char (R=reference, A=active/below-canopy)
NN Receiver number, zero-padded 01-99
AGC 3-char data provider ID, uppercase (e.g. GFZ, TUD, TUW, MPI)
_R Literal - 'R' for Receiver
YYYY 4-digit year
DOY 3-digit day of year (001-366)
HHMM Start time, hours + minutes
PERIOD Batch size: 2-digit value + unit (e.g. 01D, 15M, 01H)
SAMPLING Data frequency: 2-digit value + unit (e.g. 01S, 05S, 05M)
CONTENT 2-char user field, default 'AA'
TYPE File type, lowercase (rnx, sbf, ubx, nmea)
COMPRESSION Optional compression extension (zip, gz, bz2, zst, ...)
Examples::
HAIA01GFZ_R_20250010000_01D_01S_AA.rnx.zip
ROSR01TUW_R_20250010000_01D_05S_AA.rnx
ROSR35TUW_R_20232221530_15M_05S_AA.sbf
CanVODFilename
¶
Structured representation of a canVOD-compliant filename.
Construct directly with keyword arguments, or parse from a filename string
with :meth:from_filename. Render back to a string with :attr:name.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/convention.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
sampling_interval
property
¶
Sampling frequency as a timedelta.
batch_duration
property
¶
Batch / file period as a timedelta.
name
property
¶
Full filename including optional compression extension.
stem
property
¶
Filename without the compression extension (if any).
from_filename(filename)
classmethod
¶
Parse a canVOD-compliant filename string into a model instance.
Accepts a bare filename (no directory components). Leading path segments are stripped automatically.
Raises¶
ValueError If the filename does not match the convention.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/convention.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | |
ReceiverType
¶
Bases: StrEnum
Char 4: receiver role at the site.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/convention.py
63 64 65 66 67 | |
FileType
¶
Bases: StrEnum
File format / observation type.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/convention.py
70 71 72 73 74 75 76 | |
Mapping¶
Virtual renaming engine: map physical files to canVOD conventional names.
The FilenameMapper discovers files on disk according to the configured
directory layout and source pattern, then wraps each in a VirtualFile
that pairs the physical path with its canVOD conventional name.
VirtualFile
dataclass
¶
Physical file mapped to its canVOD conventional name.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/mapping.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | |
canonical_str
property
¶
The conventional filename as a string.
open(mode='rb')
¶
Open the physical file.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/mapping.py
40 41 42 | |
FilenameMapper
¶
Maps physical files to canVOD conventional names.
Parameters¶
site_naming
Site-level naming config.
receiver_naming
Receiver-level naming config.
receiver_type
Whether this receiver is "reference" or "canopy".
receiver_base_dir
Absolute path to the receiver's data directory.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/mapping.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | |
discover_all()
¶
Discover all files and map them to conventional names.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/mapping.py
137 138 139 140 141 142 143 144 145 146 147 | |
discover_for_date(year, doy)
¶
Discover files for a specific date.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/mapping.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
map_single_file(file_path, *, year=None, doy=None)
¶
Map a single physical file to its canVOD conventional name.
Parameters¶
file_path Path to the physical file. year, doy Optional date override (e.g. from directory name).
Raises¶
ValueError If the file cannot be matched or mapped.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/mapping.py
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | |
detect_overlaps(vfs)
staticmethod
¶
Detect temporal overlaps among virtual files.
Groups files by (year, doy) and checks whether any file's time
range contains or overlaps another's. A 01D file alongside
15M files for the same day is the canonical overlap case.
Returns¶
list[tuple[VirtualFile, VirtualFile]] Pairs of overlapping files.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/mapping.py
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | |
Recipe¶
Naming recipe: user-defined mapping from arbitrary filenames to canVOD names.
A recipe is a small YAML file that describes: 1. The canonical identity of a receiver (site, agency, sampling, etc.) 2. How to extract date/time fields from the user's physical filenames.
The field extraction is a sequential left-to-right walk over the filename.
Each entry in the fields list consumes characters and either extracts
a named value or skips literal characters.
Recognized field names¶
year4-digit year (e.g. 2025)yy2-digit year (80-99 → 19xx, 00-79 → 20xx)doyday of year (1-366)monthmonth (01-12)dayday of month (01-31)hourhour (00-23)minuteminute (00-59)hour_letterRINEX hour code (a-x, single char)skipignore these characters
Example recipe (YAML)¶
::
name: rosalia_reference
description: Rosalia forest, reference receiver
site: ROS
agency: TUW
receiver_number: 1
receiver_type: reference
sampling: "05S"
period: "15M"
content: "AA"
file_type: rnx
layout: yyddd_subdirs
glob: "*.??o"
# Example: rref001a15.25o
fields:
- skip: 4
- doy: 3
- hour_letter: 1
- minute: 2
- skip: 1
- yy: 2
- skip: 1
Example recipe for exotic filenames¶
::
# Example: STATION_2025_042_00_15.rinex
fields:
- skip: 8
- year: 4
- skip: 1
- doy: 3
- skip: 1
- hour: 2
- skip: 1
- minute: 2
- skip: 6
NamingRecipe
¶
Bases: BaseModel
A user-defined mapping from arbitrary filenames to canVOD names.
Serialize to YAML for sharing, to JSON for API transport.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | |
expected_length
property
¶
Total number of characters consumed by the field spec.
parse_filename(filename)
¶
Extract fields from a physical filename.
Parameters¶
filename Bare filename (no directory components).
Returns¶
dict
Extracted field values. Integer fields (year, doy, etc.) are
returned as int. hour_letter is returned as str.
skip fields are not included.
Raises¶
ValueError If the filename is too short for the field spec.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | |
to_virtual_file(file_path)
¶
Map a physical file to a VirtualFile using this recipe.
Parameters¶
file_path Path to the physical file.
Returns¶
VirtualFile The mapped virtual file.
Raises¶
ValueError If the filename cannot be parsed.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | |
matches(filename)
¶
Check if a filename can be parsed by this recipe.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
331 332 333 334 335 336 337 338 339 | |
to_yaml()
¶
Serialize to YAML string.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
343 344 345 346 347 348 349 350 | |
save(path)
¶
Write recipe to a YAML file.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
352 353 354 355 | |
from_yaml(text)
classmethod
¶
Load from a YAML string.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
357 358 359 360 361 | |
load(path)
classmethod
¶
Load from a YAML file.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/recipe.py
363 364 365 366 367 | |
Patterns¶
Source filename pattern definitions and built-in registry.
Each SourcePattern describes how to discover and parse a particular
naming scheme (RINEX v2, RINEX v3, Septentrio SBF, etc.) so the mapping
engine can extract date/time metadata from any filename.
BUILTIN_PATTERNS = {'canvod': _build_canvod_pattern(), 'rinex_v3_long': _build_rinex_v3_long_pattern(), 'septentrio_rinex_v2': _build_septentrio_rinex_v2_pattern(), 'rinex_v2_short': _build_rinex_v2_short_pattern(), 'septentrio_sbf': _build_septentrio_sbf_pattern()}
module-attribute
¶
SourcePattern
dataclass
¶
A named regex pattern for matching and parsing source filenames.
Parameters¶
name
Human-readable pattern identifier (e.g. "rinex_v3_long").
file_globs
Glob patterns used to discover matching files on disk.
regex
Compiled regex with named groups for metadata extraction.
Expected groups: year (or yy), doy,
hour (optional), minute (optional),
sampling (optional), period (optional).
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/patterns.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
Validation¶
Pre-pipeline validation of data directories against naming convention.
The DataDirectoryValidator ensures every file entering the pipeline can be
mapped to a CanVODFilename. Validation is a hard gate: if any files are
unmatched or temporal overlaps exist, processing is blocked with a clear
diagnostic message.
DataDirectoryValidator
¶
Pre-pipeline validation of data directories against naming convention.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/validator.py
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
validate_receiver(site_naming, receiver_naming, receiver_type, receiver_base_dir, reader_format=None)
¶
Validate all files in a receiver directory.
Parameters¶
site_naming
Site-level naming config.
receiver_naming
Receiver-level naming config.
receiver_type
"reference" or "canopy".
receiver_base_dir
Absolute path to the receiver's data directory.
reader_format
If set (e.g. "rinex3", "sbf"), only validate files
matching that format. Files of other formats are skipped
(reported in skipped_format). "auto" or None
validates all formats.
Returns¶
ValidationReport Validation results.
Raises¶
ValueError If validation fails (unmatched files or overlaps detected).
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/validator.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
ValidationReport
dataclass
¶
Result of validating a receiver's data directory.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/validator.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
is_valid
property
¶
True if no blocking issues found.
Catalog¶
DuckDB-backed metadata catalog for file mappings.
The FilenameCatalog persists the mapping between physical files and
their canVOD conventional names, enabling fast lookups and date-range
queries without re-scanning the filesystem.
Catalog location: {gnss_site_data_root}/.canvod/filename_catalog.duckdb
FilenameCatalog
¶
DuckDB-backed catalog of file name mappings.
Parameters¶
db_path Path to the DuckDB database file. Created if it doesn't exist.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | |
record(vf)
¶
Insert or update a single file mapping.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | |
record_batch(vfs)
¶
Insert or update a batch of file mappings.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
183 184 185 186 | |
lookup_by_conventional(name)
¶
Look up a physical path by conventional name.
Returns None if not found.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
188 189 190 191 192 193 194 195 196 197 | |
lookup_by_physical(path)
¶
Look up a conventional name by physical path.
Returns None if not found.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
199 200 201 202 203 204 205 206 207 208 209 210 | |
query_date_range(start_year, start_doy, end_year, end_doy, *, receiver_type=None)
¶
Query file mappings within a date range.
Parameters¶
start_year, start_doy
Start of range (inclusive).
end_year, end_doy
End of range (inclusive).
receiver_type
Optional filter: "R" or "A".
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | |
verify_integrity()
¶
Check that all cataloged physical files still exist.
Returns¶
list[str] List of physical paths that no longer exist on disk.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
257 258 259 260 261 262 263 264 265 266 267 268 269 270 | |
count()
¶
Return total number of cataloged files.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
272 273 274 275 276 277 | |
to_polars()
¶
Export the catalog to a Polars DataFrame via DuckDB-Arrow bridge.
Returns¶
polars.DataFrame
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
279 280 281 282 283 284 285 286 287 288 289 290 291 | |
close()
¶
Close the database connection.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/catalog.py
293 294 295 | |
Configuration¶
Pydantic models for naming configuration in sites.yaml.
These models validate the naming: sections at site and receiver level.
The canvod-utils package stores these as opaque dict | None fields;
this package validates them when constructing a FilenameMapper.
SiteNamingConfig
¶
Bases: BaseModel
Site-level naming defaults (sites.<name>.naming in YAML).
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/config_models.py
25 26 27 28 29 30 31 32 | |
ReceiverNamingConfig
¶
Bases: BaseModel
Receiver-level naming overrides (sites.<name>.receivers.<rx>.naming).
The source_station field specifies the 4-character station code used
in RINEX v2 / SBF filenames (e.g. ract, rref). When set, only
files whose station code matches are accepted during discovery and
validation. When None, any station code is accepted.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/config_models.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | |
DirectoryLayout
¶
Bases: StrEnum
How receiver data files are organised into subdirectories.
Source code in packages/canvod-virtualiconvname/src/canvod/virtualiconvname/config_models.py
17 18 19 20 21 22 | |