-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpaths.py
More file actions
151 lines (92 loc) · 5.36 KB
/
Copy pathpaths.py
File metadata and controls
151 lines (92 loc) · 5.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"""On-disk layout of the declass-process pipeline.
Every output the pipeline writes lives under one of two roots:
- ``cache_dir``: shared preprocessing cache (downloads, extracted, stitched,
georef, ortho). Reused across runs; safe to share between tests.
- ``output_dir``: per-run outputs (aligned, mosaic, manifests, diagnostics,
cropped, match_files, reference).
The helpers below centralize the path construction so callers don't need to
know the directory layout, and adding a new stage only touches one file.
"""
from __future__ import annotations
import os
# ---------------------------------------------------------------------------
# Preprocessing cache (under cache_dir)
# ---------------------------------------------------------------------------
def georef_path(cache_dir: str, entity_id: str) -> str:
return os.path.join(cache_dir, "georef", f"{entity_id}_georef.tif")
def georef_metadata_path(cache_dir: str, entity_id: str) -> str:
return os.path.join(cache_dir, "georef", f"{entity_id}_metadata.json")
def stitched_path(cache_dir: str, entity_id: str) -> str:
return os.path.join(cache_dir, "stitched", f"{entity_id}_stitched.tif")
def ortho_path(cache_dir: str, entity_id: str) -> str:
return os.path.join(cache_dir, "ortho", f"{entity_id}_ortho.tif")
def ortho_coarse_path(cache_dir: str, entity_id: str) -> str:
"""Reference-specific coarse-align sidecar next to the canonical ortho.
The canonical ``_ortho.tif`` is reference-neutral and immutable once
written; this sidecar holds the coarse-align geotransform shift for a
particular reference basemap. Validity is gated by the companion
provenance JSON so that switching ``--reference`` invalidates the sidecar.
"""
return os.path.join(cache_dir, "ortho", f"{entity_id}_ortho.coarse.tif")
def ortho_coarse_provenance_path(cache_dir: str, entity_id: str) -> str:
return os.path.join(cache_dir, "ortho", f"{entity_id}_ortho.coarse.json")
def reference_scratch_cleaned_path(reference_path: str) -> str:
"""Path of the scratch-cleaned sidecar next to a reference TIF.
Declassified film references (KH-9 DZB1212 etc.) often carry bright
diagonal scratches at the strip edges. The cleaned sidecar holds
the inpainted version with the same georeferencing; matchers prefer
it when its companion provenance JSON matches the current reference.
"""
base, ext = os.path.splitext(reference_path)
return f"{base}.scratch_cleaned{ext or '.tif'}"
def reference_scratch_cleaned_provenance_path(reference_path: str) -> str:
base, _ = os.path.splitext(reference_path)
return f"{base}.scratch_cleaned.json"
def ortho_segments_dir(cache_dir: str, entity_id: str) -> str:
return os.path.join(cache_dir, "ortho", f"{entity_id}_segments")
def extracted_dir(cache_dir: str, entity_id: str) -> str:
return os.path.join(cache_dir, "extracted", entity_id)
def ba_camera_path(stitched_path_value: str) -> str:
"""ASP writes the camera model .tsai file alongside the input stitched image."""
base, _ = os.path.splitext(stitched_path_value)
return f"{base}.tsai"
# ---------------------------------------------------------------------------
# Per-run outputs (under output_dir)
# ---------------------------------------------------------------------------
def aligned_dir(output_dir: str) -> str:
return os.path.join(output_dir, "aligned")
def aligned_path(output_dir: str, entity_id: str) -> str:
return os.path.join(output_dir, "aligned", f"{entity_id}_aligned.tif")
def diagnostics_dir(output_dir: str) -> str:
return os.path.join(output_dir, "diagnostics")
def scene_diagnostics_dir(output_dir: str, entity_id: str) -> str:
return os.path.join(output_dir, "diagnostics", entity_id)
def manifests_dir(output_dir: str) -> str:
return os.path.join(output_dir, "manifests")
def alignment_manifest_path(output_dir: str) -> str:
return os.path.join(output_dir, "manifests", "alignment_manifest.json")
def scene_prior_path(output_dir: str, entity_id: str) -> str:
return os.path.join(output_dir, "manifests", f"{entity_id}_prior.json")
def scene_anchors_path(output_dir: str, entity_id: str) -> str:
return os.path.join(output_dir, "manifests", f"{entity_id}_auto_anchors.json")
def cropped_dir(output_dir: str) -> str:
return os.path.join(output_dir, "cropped")
def cropped_path(output_dir: str, entity_id: str) -> str:
return os.path.join(output_dir, "cropped", f"{entity_id}_cropped.tif")
def match_files_dir(output_dir: str) -> str:
return os.path.join(output_dir, "match_files")
# ---------------------------------------------------------------------------
# Directory ensurance
# ---------------------------------------------------------------------------
CACHE_SUBDIRS = ("downloads", "extracted", "stitched", "georef", "ortho")
OUTPUT_SUBDIRS = ("aligned", "mosaic", "manifests", "diagnostics", "match_files")
def ensure_pipeline_dirs(output_dir: str, cache_dir: str | None = None) -> None:
"""Create every directory the pipeline writes to.
Preprocessing dirs land under ``cache_dir`` so they can be shared across
runs; per-run outputs land under ``output_dir``.
"""
cache_root = cache_dir or output_dir
for subdir in CACHE_SUBDIRS:
os.makedirs(os.path.join(cache_root, subdir), exist_ok=True)
for subdir in OUTPUT_SUBDIRS:
os.makedirs(os.path.join(output_dir, subdir), exist_ok=True)