cars 1.0.0rc2__cp312-cp312-win_amd64.whl

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.

Potentially problematic release.


This version of cars might be problematic. Click here for more details.

Files changed (225) hide show
  1. cars/__init__.py +86 -0
  2. cars/applications/__init__.py +40 -0
  3. cars/applications/application.py +117 -0
  4. cars/applications/application_constants.py +29 -0
  5. cars/applications/application_template.py +146 -0
  6. cars/applications/auxiliary_filling/__init__.py +29 -0
  7. cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +105 -0
  8. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
  9. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -0
  10. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
  11. cars/applications/dem_generation/__init__.py +30 -0
  12. cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
  13. cars/applications/dem_generation/bulldozer_config/base_config.yaml +42 -0
  14. cars/applications/dem_generation/bulldozer_dem_app.py +641 -0
  15. cars/applications/dem_generation/bulldozer_memory.py +55 -0
  16. cars/applications/dem_generation/dem_generation_algo.py +107 -0
  17. cars/applications/dem_generation/dem_generation_constants.py +32 -0
  18. cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
  19. cars/applications/dense_match_filling/__init__.py +30 -0
  20. cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
  21. cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
  22. cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
  23. cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
  24. cars/applications/dense_match_filling/zero_padding_app.py +302 -0
  25. cars/applications/dense_matching/__init__.py +30 -0
  26. cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
  27. cars/applications/dense_matching/census_mccnn_sgm_app.py +1461 -0
  28. cars/applications/dense_matching/cpp/__init__.py +0 -0
  29. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
  30. cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
  31. cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
  32. cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
  33. cars/applications/dense_matching/cpp/meson.build +9 -0
  34. cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
  35. cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
  36. cars/applications/dense_matching/dense_matching_algo.py +401 -0
  37. cars/applications/dense_matching/dense_matching_constants.py +89 -0
  38. cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
  39. cars/applications/dense_matching/disparity_grid_algo.py +597 -0
  40. cars/applications/dense_matching/loaders/__init__.py +23 -0
  41. cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
  42. cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
  43. cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
  44. cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
  45. cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
  46. cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
  47. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  48. cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
  49. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  50. cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
  51. cars/applications/dsm_filling/__init__.py +32 -0
  52. cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
  53. cars/applications/dsm_filling/border_interpolation_app.py +278 -0
  54. cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
  55. cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
  56. cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
  57. cars/applications/dsm_merging/__init__.py +28 -0
  58. cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
  59. cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
  60. cars/applications/grid_correction/__init__.py +30 -0
  61. cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
  62. cars/applications/grid_correction/grid_correction_app.py +557 -0
  63. cars/applications/grid_generation/__init__.py +30 -0
  64. cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
  65. cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
  66. cars/applications/grid_generation/grid_generation_algo.py +388 -0
  67. cars/applications/grid_generation/grid_generation_constants.py +46 -0
  68. cars/applications/grid_generation/transform_grid.py +88 -0
  69. cars/applications/ground_truth_reprojection/__init__.py +30 -0
  70. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
  71. cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
  72. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
  73. cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
  74. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
  75. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
  76. cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
  77. cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
  78. cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
  79. cars/applications/rasterization/__init__.py +30 -0
  80. cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
  81. cars/applications/rasterization/rasterization_algo.py +534 -0
  82. cars/applications/rasterization/rasterization_constants.py +38 -0
  83. cars/applications/rasterization/rasterization_wrappers.py +639 -0
  84. cars/applications/rasterization/simple_gaussian_app.py +1152 -0
  85. cars/applications/resampling/__init__.py +28 -0
  86. cars/applications/resampling/abstract_resampling_app.py +187 -0
  87. cars/applications/resampling/bicubic_resampling_app.py +760 -0
  88. cars/applications/resampling/resampling_algo.py +590 -0
  89. cars/applications/resampling/resampling_constants.py +36 -0
  90. cars/applications/resampling/resampling_wrappers.py +309 -0
  91. cars/applications/sensors_subsampling/__init__.py +32 -0
  92. cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
  93. cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
  94. cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
  95. cars/applications/sparse_matching/__init__.py +30 -0
  96. cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
  97. cars/applications/sparse_matching/sift_app.py +724 -0
  98. cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
  99. cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
  100. cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
  101. cars/applications/triangulation/__init__.py +32 -0
  102. cars/applications/triangulation/abstract_triangulation_app.py +227 -0
  103. cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
  104. cars/applications/triangulation/pc_transform.py +552 -0
  105. cars/applications/triangulation/triangulation_algo.py +371 -0
  106. cars/applications/triangulation/triangulation_constants.py +38 -0
  107. cars/applications/triangulation/triangulation_wrappers.py +259 -0
  108. cars/bundleadjustment.py +750 -0
  109. cars/cars.py +179 -0
  110. cars/conf/__init__.py +23 -0
  111. cars/conf/geoid/egm96.grd +0 -0
  112. cars/conf/geoid/egm96.grd.hdr +15 -0
  113. cars/conf/input_parameters.py +156 -0
  114. cars/conf/mask_cst.py +35 -0
  115. cars/core/__init__.py +23 -0
  116. cars/core/cars_logging.py +402 -0
  117. cars/core/constants.py +191 -0
  118. cars/core/constants_disparity.py +50 -0
  119. cars/core/datasets.py +140 -0
  120. cars/core/geometry/__init__.py +27 -0
  121. cars/core/geometry/abstract_geometry.py +1119 -0
  122. cars/core/geometry/shareloc_geometry.py +598 -0
  123. cars/core/inputs.py +568 -0
  124. cars/core/outputs.py +176 -0
  125. cars/core/preprocessing.py +722 -0
  126. cars/core/projection.py +843 -0
  127. cars/core/roi_tools.py +215 -0
  128. cars/core/tiling.py +774 -0
  129. cars/core/utils.py +164 -0
  130. cars/data_structures/__init__.py +23 -0
  131. cars/data_structures/cars_dataset.py +1544 -0
  132. cars/data_structures/cars_dict.py +74 -0
  133. cars/data_structures/corresponding_tiles_tools.py +186 -0
  134. cars/data_structures/dataframe_converter.py +185 -0
  135. cars/data_structures/format_transformation.py +297 -0
  136. cars/devibrate.py +689 -0
  137. cars/extractroi.py +264 -0
  138. cars/orchestrator/__init__.py +23 -0
  139. cars/orchestrator/achievement_tracker.py +125 -0
  140. cars/orchestrator/cluster/__init__.py +37 -0
  141. cars/orchestrator/cluster/abstract_cluster.py +250 -0
  142. cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
  143. cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
  144. cars/orchestrator/cluster/dask_config/README.md +94 -0
  145. cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
  146. cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
  147. cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
  148. cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
  149. cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
  150. cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
  151. cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
  152. cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
  153. cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
  154. cars/orchestrator/cluster/local_dask_cluster.py +116 -0
  155. cars/orchestrator/cluster/log_wrapper.py +728 -0
  156. cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
  157. cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
  158. cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
  159. cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
  160. cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
  161. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
  162. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
  163. cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
  164. cars/orchestrator/cluster/sequential_cluster.py +139 -0
  165. cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
  166. cars/orchestrator/memory_tools.py +47 -0
  167. cars/orchestrator/orchestrator.py +755 -0
  168. cars/orchestrator/orchestrator_constants.py +29 -0
  169. cars/orchestrator/registry/__init__.py +23 -0
  170. cars/orchestrator/registry/abstract_registry.py +143 -0
  171. cars/orchestrator/registry/compute_registry.py +106 -0
  172. cars/orchestrator/registry/id_generator.py +116 -0
  173. cars/orchestrator/registry/replacer_registry.py +213 -0
  174. cars/orchestrator/registry/saver_registry.py +363 -0
  175. cars/orchestrator/registry/unseen_registry.py +118 -0
  176. cars/orchestrator/tiles_profiler.py +279 -0
  177. cars/pipelines/__init__.py +26 -0
  178. cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
  179. cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
  180. cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
  181. cars/pipelines/default/__init__.py +26 -0
  182. cars/pipelines/default/default_pipeline.py +1088 -0
  183. cars/pipelines/filling/__init__.py +26 -0
  184. cars/pipelines/filling/filling.py +981 -0
  185. cars/pipelines/formatting/__init__.py +26 -0
  186. cars/pipelines/formatting/formatting.py +186 -0
  187. cars/pipelines/merging/__init__.py +26 -0
  188. cars/pipelines/merging/merging.py +439 -0
  189. cars/pipelines/parameters/__init__.py +0 -0
  190. cars/pipelines/parameters/advanced_parameters.py +256 -0
  191. cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
  192. cars/pipelines/parameters/application_parameters.py +72 -0
  193. cars/pipelines/parameters/depth_map_inputs.py +0 -0
  194. cars/pipelines/parameters/dsm_inputs.py +349 -0
  195. cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
  196. cars/pipelines/parameters/output_constants.py +52 -0
  197. cars/pipelines/parameters/output_parameters.py +438 -0
  198. cars/pipelines/parameters/sensor_inputs.py +859 -0
  199. cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
  200. cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
  201. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
  202. cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
  203. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
  204. cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
  205. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
  206. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
  207. cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
  208. cars/pipelines/pipeline.py +119 -0
  209. cars/pipelines/pipeline_constants.py +38 -0
  210. cars/pipelines/pipeline_template.py +135 -0
  211. cars/pipelines/subsampling/__init__.py +26 -0
  212. cars/pipelines/subsampling/subsampling.py +358 -0
  213. cars/pipelines/surface_modeling/__init__.py +26 -0
  214. cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
  215. cars/pipelines/tie_points/__init__.py +26 -0
  216. cars/pipelines/tie_points/tie_points.py +536 -0
  217. cars/starter.py +167 -0
  218. cars-1.0.0rc2.dist-info/DELVEWHEEL +2 -0
  219. cars-1.0.0rc2.dist-info/METADATA +289 -0
  220. cars-1.0.0rc2.dist-info/RECORD +225 -0
  221. cars-1.0.0rc2.dist-info/WHEEL +4 -0
  222. cars-1.0.0rc2.dist-info/entry_points.txt +8 -0
  223. cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
  224. cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
  225. cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
@@ -0,0 +1,438 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf8
3
+ #
4
+ # Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
5
+ #
6
+ # This file is part of CARS
7
+ # (see https://github.com/CNES/cars).
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ #
21
+
22
+ """
23
+ This module contains the output definition
24
+ """
25
+
26
+ import logging
27
+ import os
28
+
29
+ from json_checker import And, Checker, Or
30
+ from pyproj import CRS
31
+
32
+ import cars.core.constants as cst
33
+ from cars.core.utils import safe_makedirs
34
+ from cars.pipelines.parameters import output_constants
35
+ from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
36
+
37
+
38
+ def is_valid_epsg(epsg) -> bool:
39
+ """
40
+ Check if the given EPSG code is valid using pyproj.
41
+ """
42
+ if epsg is None:
43
+ return True
44
+
45
+ try:
46
+ # Try creating a CRS
47
+ CRS(f"EPSG:{epsg}")
48
+ return True
49
+ except Exception:
50
+ return False
51
+
52
+
53
+ def check_output_parameters( # noqa: C901 : too complex
54
+ inputs, conf, scaling_coeff=None
55
+ ):
56
+ """
57
+ Check the output json configuration and fill in default values
58
+
59
+ :param conf: configuration of output
60
+ :type conf: dict
61
+ :param scaling_coeff: scaling factor for resolution
62
+ :type scaling_coeff: float
63
+ :param pipeline_name: name of corresponding pipeline
64
+ :type pipeline_name: str
65
+ """
66
+ overloaded_conf = conf.copy()
67
+ out_dir = conf[output_constants.OUT_DIRECTORY]
68
+ out_dir = os.path.abspath(out_dir)
69
+ # Ensure that output directory and its subdirectories exist
70
+ safe_makedirs(out_dir)
71
+
72
+ # Overload some parameters
73
+ overloaded_conf[output_constants.OUT_DIRECTORY] = out_dir
74
+
75
+ overloaded_conf[output_constants.PRODUCT_LEVEL] = overloaded_conf.get(
76
+ output_constants.PRODUCT_LEVEL, "dsm"
77
+ )
78
+ if isinstance(overloaded_conf[output_constants.PRODUCT_LEVEL], str):
79
+ overloaded_conf[output_constants.PRODUCT_LEVEL] = [
80
+ overloaded_conf[output_constants.PRODUCT_LEVEL]
81
+ ]
82
+ for level in overloaded_conf[output_constants.PRODUCT_LEVEL]:
83
+ if level not in ["dsm", "depth_map", "point_cloud"]:
84
+ raise RuntimeError("Unknown product level {}".format(level))
85
+
86
+ overloaded_conf[output_constants.OUT_GEOID] = overloaded_conf.get(
87
+ output_constants.OUT_GEOID, True
88
+ )
89
+ overloaded_conf[output_constants.EPSG] = overloaded_conf.get(
90
+ output_constants.EPSG, None
91
+ )
92
+
93
+ resolution = None
94
+ overloaded_scaling_coeff = scaling_coeff
95
+ if scaling_coeff is not None:
96
+ if overloaded_conf.get(output_constants.RESOLUTION, None) is not None:
97
+ resolution = overloaded_conf[output_constants.RESOLUTION]
98
+ # update scaling coeff so the parameters are right for the dsm
99
+ # overloaded_scaling_coeff = 2*resolution
100
+
101
+ if resolution < 0.5 * scaling_coeff:
102
+ logging.warning(
103
+ "The requested DSM resolution of "
104
+ f"{overloaded_conf[output_constants.RESOLUTION]} seems "
105
+ "too low for the sensor images' resolution. "
106
+ "The pipeline will still continue with it."
107
+ )
108
+
109
+ else:
110
+ resolution = float(0.5 * scaling_coeff)
111
+ logging.info(
112
+ "The resolution of the output DSM will be "
113
+ f"{resolution} meters. "
114
+ )
115
+
116
+ overloaded_conf[output_constants.RESOLUTION] = resolution
117
+
118
+ overloaded_conf[output_constants.SAVE_BY_PAIR] = overloaded_conf.get(
119
+ output_constants.SAVE_BY_PAIR, False
120
+ )
121
+
122
+ # Load auxiliary and subfields
123
+ overloaded_conf[output_constants.AUXILIARY] = overloaded_conf.get(
124
+ output_constants.AUXILIARY, {}
125
+ )
126
+
127
+ # Load auxiliary and subfields
128
+ overloaded_conf[output_constants.AUXILIARY][output_constants.AUX_IMAGE] = (
129
+ overloaded_conf[output_constants.AUXILIARY].get(
130
+ output_constants.AUX_IMAGE, True
131
+ )
132
+ )
133
+ overloaded_conf[output_constants.AUXILIARY][
134
+ output_constants.AUX_WEIGHTS
135
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
136
+ output_constants.AUX_WEIGHTS, False
137
+ )
138
+ overloaded_conf[output_constants.AUXILIARY][
139
+ output_constants.AUX_CLASSIFICATION
140
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
141
+ output_constants.AUX_CLASSIFICATION, False
142
+ )
143
+ overloaded_conf[output_constants.AUXILIARY][
144
+ output_constants.AUX_PERFORMANCE_MAP
145
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
146
+ output_constants.AUX_PERFORMANCE_MAP, False
147
+ )
148
+ overloaded_conf[output_constants.AUXILIARY][
149
+ output_constants.AUX_CONTRIBUTING_PAIR
150
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
151
+ output_constants.AUX_CONTRIBUTING_PAIR, False
152
+ )
153
+ overloaded_conf[output_constants.AUXILIARY][
154
+ output_constants.AUX_FILLING
155
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
156
+ output_constants.AUX_FILLING, False
157
+ )
158
+ overloaded_conf[output_constants.AUXILIARY][
159
+ output_constants.AUX_AMBIGUITY
160
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
161
+ output_constants.AUX_AMBIGUITY, False
162
+ )
163
+
164
+ # Check schema
165
+ output_schema = {
166
+ output_constants.OUT_DIRECTORY: str,
167
+ output_constants.PRODUCT_LEVEL: list,
168
+ output_constants.OUT_GEOID: Or(bool, str),
169
+ output_constants.EPSG: And(Or(int, str, None), is_valid_epsg),
170
+ output_constants.RESOLUTION: Or(int, float, None),
171
+ output_constants.SAVE_BY_PAIR: bool,
172
+ output_constants.AUXILIARY: dict,
173
+ }
174
+ checker_output = Checker(output_schema)
175
+ checker_output.validate(overloaded_conf)
176
+
177
+ # check auxiliary keys
178
+ auxiliary_schema = {
179
+ output_constants.AUX_IMAGE: Or(bool, str, list),
180
+ output_constants.AUX_WEIGHTS: bool,
181
+ output_constants.AUX_CLASSIFICATION: Or(bool, dict, list),
182
+ output_constants.AUX_PERFORMANCE_MAP: Or(bool, list),
183
+ output_constants.AUX_CONTRIBUTING_PAIR: bool,
184
+ output_constants.AUX_FILLING: Or(bool, dict),
185
+ output_constants.AUX_AMBIGUITY: bool,
186
+ }
187
+
188
+ # Check and overload classification parameter
189
+ check_classification_parameter(inputs, overloaded_conf)
190
+
191
+ # Check and overload image parameter
192
+ check_texture_bands(inputs, overloaded_conf)
193
+
194
+ # Check and overload performance_map parameter
195
+ check_performance_classes(overloaded_conf)
196
+
197
+ # Check and overload filling parameter
198
+ check_filling_parameter(overloaded_conf)
199
+
200
+ checker_auxiliary = Checker(auxiliary_schema)
201
+ checker_auxiliary.validate(overloaded_conf[output_constants.AUXILIARY])
202
+
203
+ if "epsg" in overloaded_conf and overloaded_conf["epsg"]:
204
+ spatial_ref = CRS.from_epsg(overloaded_conf["epsg"])
205
+ if spatial_ref.is_geographic:
206
+ if overloaded_conf[output_constants.RESOLUTION] > 10e-3:
207
+ logging.warning(
208
+ "The resolution of the "
209
+ + "point_cloud_rasterization should be "
210
+ + "fixed according to the epsg"
211
+ )
212
+
213
+ return overloaded_conf, overloaded_scaling_coeff
214
+
215
+
216
+ def check_filling_parameter(overloaded_conf):
217
+ """
218
+ Check and overload filling parameter
219
+ """
220
+
221
+ filling_param = overloaded_conf[output_constants.AUXILIARY][
222
+ output_constants.AUX_FILLING
223
+ ]
224
+
225
+ valid_names = [
226
+ "fill_with_geoid",
227
+ "interpolate_from_borders",
228
+ "fill_with_endogenous_dem",
229
+ "fill_with_exogenous_dem",
230
+ "other",
231
+ ]
232
+
233
+ if isinstance(filling_param, dict):
234
+ for _, value in filling_param.items():
235
+ if isinstance(value, str):
236
+ value = [value]
237
+ if any(elem not in valid_names for elem in value):
238
+ raise RuntimeError(
239
+ "Those filling methods are not available in CARS"
240
+ )
241
+ elif filling_param is True:
242
+ overloaded_conf[output_constants.AUXILIARY][
243
+ output_constants.AUX_FILLING
244
+ ] = {i + 1: name for i, name in enumerate(valid_names)}
245
+
246
+
247
+ def check_texture_bands(inputs, overloaded_conf):
248
+ """
249
+ Check and overload texture bands
250
+ """
251
+ texture_bands = overloaded_conf[output_constants.AUXILIARY][
252
+ output_constants.AUX_IMAGE
253
+ ]
254
+
255
+ if inputs[sens_cst.SENSORS] is not None:
256
+ first_key = list(inputs[sens_cst.SENSORS].keys())[0]
257
+ image = inputs[sens_cst.SENSORS][first_key][sens_cst.INPUT_IMG]
258
+ bands = set(image["bands"].keys())
259
+
260
+ if isinstance(texture_bands, list):
261
+ for elem in texture_bands:
262
+ if not isinstance(elem, str):
263
+ raise RuntimeError(
264
+ "The image parameter of auxiliary should "
265
+ "be a boolean, a string or a list of string"
266
+ )
267
+ if elem not in bands:
268
+ raise RuntimeError(
269
+ f"The band {elem} is "
270
+ f"not an existing band of "
271
+ f"the input image"
272
+ )
273
+ elif isinstance(texture_bands, str):
274
+ overloaded_conf[output_constants.AUXILIARY][
275
+ output_constants.AUX_IMAGE
276
+ ] = [texture_bands]
277
+
278
+ if texture_bands not in bands:
279
+ raise RuntimeError(
280
+ f"The band {texture_bands} is "
281
+ f"not an existing band of "
282
+ f"the input image"
283
+ )
284
+ elif texture_bands is True:
285
+ overloaded_conf[output_constants.AUXILIARY][
286
+ output_constants.AUX_IMAGE
287
+ ] = sorted(bands)
288
+
289
+
290
+ def check_classification_parameter(inputs, overloaded_conf):
291
+ """
292
+ Check and overload classification parameter
293
+ """
294
+ classification_formatting = overloaded_conf[output_constants.AUXILIARY][
295
+ output_constants.AUX_CLASSIFICATION
296
+ ]
297
+
298
+ if inputs[sens_cst.SENSORS] is not None:
299
+ first_key = list(inputs[sens_cst.SENSORS].keys())[0]
300
+
301
+ if (
302
+ "classification" in inputs[sens_cst.SENSORS][first_key]
303
+ and inputs[sens_cst.SENSORS][first_key]["classification"]
304
+ is not None
305
+ ):
306
+ classif = inputs[sens_cst.SENSORS][first_key][
307
+ sens_cst.INPUT_CLASSIFICATION
308
+ ]
309
+ bands_classif = classif["values"]
310
+
311
+ if isinstance(classification_formatting, list):
312
+ overloaded_conf[output_constants.AUXILIARY][
313
+ output_constants.AUX_CLASSIFICATION
314
+ ] = {val: val for val in classification_formatting}
315
+
316
+ for elem in classification_formatting:
317
+ if not isinstance(elem, int):
318
+ raise RuntimeError(
319
+ "The image parameter of auxiliary should "
320
+ "be a boolean, a string or a list of int"
321
+ )
322
+
323
+ if elem not in bands_classif:
324
+ raise RuntimeError(
325
+ f"If you want to use {elem} as a band num, "
326
+ f"you should use a dictionary, not a list"
327
+ )
328
+ elif classification_formatting is True:
329
+ overloaded_conf[output_constants.AUXILIARY][
330
+ output_constants.AUX_CLASSIFICATION
331
+ ] = {int(name): name for val, name in enumerate(bands_classif)}
332
+ elif isinstance(classification_formatting, dict):
333
+ for _, value in classification_formatting.items():
334
+ if isinstance(value, int):
335
+ value = [value]
336
+
337
+ if any(elem not in bands_classif for elem in value):
338
+ raise RuntimeError(
339
+ f"The band {value} is "
340
+ f"not an existing band of "
341
+ f"the input classification"
342
+ )
343
+
344
+
345
+ def check_performance_classes(overloaded_conf):
346
+ """
347
+ Check performance classes
348
+ """
349
+ performance_map_classes = overloaded_conf[output_constants.AUXILIARY][
350
+ output_constants.AUX_PERFORMANCE_MAP
351
+ ]
352
+
353
+ if isinstance(performance_map_classes, list):
354
+ for elem in performance_map_classes:
355
+ if not isinstance(elem, (int, float)):
356
+ raise RuntimeError(
357
+ "The performance_map parameter of auxiliary should"
358
+ "be a boolean or a list of float/int"
359
+ )
360
+ if len(performance_map_classes) < 2:
361
+ raise RuntimeError("Not enough step for performance_map_classes")
362
+ if performance_map_classes:
363
+ previous_step = -1
364
+ for step in performance_map_classes:
365
+ if step < 0:
366
+ raise RuntimeError(
367
+ "All step in performance_map_classes must be >=0"
368
+ )
369
+ if step <= previous_step:
370
+ raise RuntimeError(
371
+ "performance_map_classes list must be ordered."
372
+ )
373
+ previous_step = step
374
+ elif performance_map_classes is True:
375
+ # default classes, in meters:
376
+ default_performance_classes = [
377
+ 0,
378
+ 0.968,
379
+ 1.13375,
380
+ 1.295,
381
+ 1.604,
382
+ 2.423,
383
+ 3.428,
384
+ ]
385
+
386
+ overloaded_conf[output_constants.AUXILIARY][
387
+ output_constants.AUX_PERFORMANCE_MAP
388
+ ] = default_performance_classes
389
+
390
+
391
+ def intialize_product_index(orchestrator, product_levels, input_pairs):
392
+ """
393
+ Initialize the index dictionary according to requested levels with None
394
+ values for all paths.
395
+
396
+ :param orchestrator: cars orchestrator
397
+ :type orchestrator: Orchestrator
398
+ :param product_levels: name of corresponding pipeline
399
+ :type product_levels: list
400
+ :param input_pairs: list containing the pair names
401
+ :type input_pairs: list
402
+ """
403
+
404
+ index = {}
405
+
406
+ if "dsm" in product_levels:
407
+ index["dsm"] = {
408
+ cst.INDEX_DSM_ALT: None,
409
+ cst.INDEX_DSM_COLOR: None,
410
+ cst.INDEX_DSM_MASK: None,
411
+ cst.INDEX_DSM_CLASSIFICATION: None,
412
+ cst.INDEX_DSM_PERFORMANCE_MAP: None,
413
+ cst.INDEX_DSM_CONTRIBUTING_PAIR: None,
414
+ cst.INDEX_DSM_FILLING: None,
415
+ cst.INDEX_DSM_WEIGHTS: None,
416
+ }
417
+
418
+ if "point_cloud" in product_levels:
419
+ # Initialize an empty index for point cloud because its content is
420
+ # unknown at this point (tile name, save by pair or not)
421
+ index["point_cloud"] = {}
422
+
423
+ if "depth_map" in product_levels:
424
+ index["depth_map"] = {}
425
+ for pair in input_pairs:
426
+ index["depth_map"][pair] = {
427
+ cst.INDEX_DEPTH_MAP_X: None,
428
+ cst.INDEX_DEPTH_MAP_Y: None,
429
+ cst.INDEX_DEPTH_MAP_Z: None,
430
+ cst.INDEX_DEPTH_MAP_COLOR: None,
431
+ cst.INDEX_DEPTH_MAP_MASK: None,
432
+ cst.INDEX_DEPTH_MAP_CLASSIFICATION: None,
433
+ cst.INDEX_DEPTH_MAP_PERFORMANCE_MAP: None,
434
+ cst.INDEX_DEPTH_MAP_FILLING: None,
435
+ cst.INDEX_DEPTH_MAP_EPSG: None,
436
+ }
437
+
438
+ orchestrator.update_index(index)