cars 1.0.0rc1__cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.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 (200) hide show
  1. cars/__init__.py +74 -0
  2. cars/applications/__init__.py +37 -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 +104 -0
  8. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
  9. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +630 -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 +655 -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 +1460 -0
  28. cars/applications/dense_matching/cpp/__init__.py +0 -0
  29. cars/applications/dense_matching/cpp/dense_matching_cpp.cpython-312-i386-linux-gnu.so +0 -0
  30. cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
  31. cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
  32. cars/applications/dense_matching/cpp/meson.build +9 -0
  33. cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
  34. cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
  35. cars/applications/dense_matching/dense_matching_algo.py +401 -0
  36. cars/applications/dense_matching/dense_matching_constants.py +89 -0
  37. cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
  38. cars/applications/dense_matching/disparity_grid_algo.py +588 -0
  39. cars/applications/dense_matching/loaders/__init__.py +23 -0
  40. cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
  41. cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
  42. cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
  43. cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
  44. cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
  45. cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
  46. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  47. cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
  48. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  49. cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
  50. cars/applications/dsm_filling/__init__.py +32 -0
  51. cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
  52. cars/applications/dsm_filling/border_interpolation_app.py +270 -0
  53. cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
  54. cars/applications/dsm_filling/bulldozer_filling_app.py +279 -0
  55. cars/applications/dsm_filling/exogenous_filling_app.py +333 -0
  56. cars/applications/grid_generation/__init__.py +30 -0
  57. cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
  58. cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
  59. cars/applications/grid_generation/grid_correction_app.py +496 -0
  60. cars/applications/grid_generation/grid_generation_algo.py +388 -0
  61. cars/applications/grid_generation/grid_generation_constants.py +46 -0
  62. cars/applications/grid_generation/transform_grid.py +88 -0
  63. cars/applications/ground_truth_reprojection/__init__.py +30 -0
  64. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
  65. cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
  66. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
  67. cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
  68. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
  69. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
  70. cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
  71. cars/applications/point_cloud_outlier_removal/small_components_app.py +527 -0
  72. cars/applications/point_cloud_outlier_removal/statistical_app.py +531 -0
  73. cars/applications/rasterization/__init__.py +30 -0
  74. cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
  75. cars/applications/rasterization/rasterization_algo.py +534 -0
  76. cars/applications/rasterization/rasterization_constants.py +38 -0
  77. cars/applications/rasterization/rasterization_wrappers.py +634 -0
  78. cars/applications/rasterization/simple_gaussian_app.py +1152 -0
  79. cars/applications/resampling/__init__.py +28 -0
  80. cars/applications/resampling/abstract_resampling_app.py +187 -0
  81. cars/applications/resampling/bicubic_resampling_app.py +762 -0
  82. cars/applications/resampling/resampling_algo.py +614 -0
  83. cars/applications/resampling/resampling_constants.py +36 -0
  84. cars/applications/resampling/resampling_wrappers.py +309 -0
  85. cars/applications/sparse_matching/__init__.py +30 -0
  86. cars/applications/sparse_matching/abstract_sparse_matching_app.py +498 -0
  87. cars/applications/sparse_matching/sift_app.py +735 -0
  88. cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
  89. cars/applications/sparse_matching/sparse_matching_constants.py +68 -0
  90. cars/applications/sparse_matching/sparse_matching_wrappers.py +238 -0
  91. cars/applications/triangulation/__init__.py +32 -0
  92. cars/applications/triangulation/abstract_triangulation_app.py +227 -0
  93. cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
  94. cars/applications/triangulation/pc_transform.py +552 -0
  95. cars/applications/triangulation/triangulation_algo.py +371 -0
  96. cars/applications/triangulation/triangulation_constants.py +38 -0
  97. cars/applications/triangulation/triangulation_wrappers.py +259 -0
  98. cars/bundleadjustment.py +757 -0
  99. cars/cars.py +177 -0
  100. cars/conf/__init__.py +23 -0
  101. cars/conf/geoid/egm96.grd +0 -0
  102. cars/conf/geoid/egm96.grd.hdr +15 -0
  103. cars/conf/input_parameters.py +156 -0
  104. cars/conf/mask_cst.py +35 -0
  105. cars/core/__init__.py +23 -0
  106. cars/core/cars_logging.py +402 -0
  107. cars/core/constants.py +191 -0
  108. cars/core/constants_disparity.py +50 -0
  109. cars/core/datasets.py +140 -0
  110. cars/core/geometry/__init__.py +27 -0
  111. cars/core/geometry/abstract_geometry.py +1119 -0
  112. cars/core/geometry/shareloc_geometry.py +598 -0
  113. cars/core/inputs.py +568 -0
  114. cars/core/outputs.py +176 -0
  115. cars/core/preprocessing.py +722 -0
  116. cars/core/projection.py +843 -0
  117. cars/core/roi_tools.py +215 -0
  118. cars/core/tiling.py +774 -0
  119. cars/core/utils.py +164 -0
  120. cars/data_structures/__init__.py +23 -0
  121. cars/data_structures/cars_dataset.py +1541 -0
  122. cars/data_structures/cars_dict.py +74 -0
  123. cars/data_structures/corresponding_tiles_tools.py +186 -0
  124. cars/data_structures/dataframe_converter.py +185 -0
  125. cars/data_structures/format_transformation.py +297 -0
  126. cars/devibrate.py +689 -0
  127. cars/extractroi.py +264 -0
  128. cars/orchestrator/__init__.py +23 -0
  129. cars/orchestrator/achievement_tracker.py +125 -0
  130. cars/orchestrator/cluster/__init__.py +37 -0
  131. cars/orchestrator/cluster/abstract_cluster.py +244 -0
  132. cars/orchestrator/cluster/abstract_dask_cluster.py +375 -0
  133. cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
  134. cars/orchestrator/cluster/dask_config/README.md +94 -0
  135. cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
  136. cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
  137. cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
  138. cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
  139. cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
  140. cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
  141. cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
  142. cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
  143. cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
  144. cars/orchestrator/cluster/local_dask_cluster.py +116 -0
  145. cars/orchestrator/cluster/log_wrapper.py +1075 -0
  146. cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
  147. cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
  148. cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
  149. cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
  150. cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
  151. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +873 -0
  152. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
  153. cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
  154. cars/orchestrator/cluster/sequential_cluster.py +139 -0
  155. cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
  156. cars/orchestrator/orchestrator.py +905 -0
  157. cars/orchestrator/orchestrator_constants.py +29 -0
  158. cars/orchestrator/registry/__init__.py +23 -0
  159. cars/orchestrator/registry/abstract_registry.py +143 -0
  160. cars/orchestrator/registry/compute_registry.py +106 -0
  161. cars/orchestrator/registry/id_generator.py +116 -0
  162. cars/orchestrator/registry/replacer_registry.py +213 -0
  163. cars/orchestrator/registry/saver_registry.py +363 -0
  164. cars/orchestrator/registry/unseen_registry.py +118 -0
  165. cars/orchestrator/tiles_profiler.py +279 -0
  166. cars/pipelines/__init__.py +26 -0
  167. cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
  168. cars/pipelines/conf_resolution/conf_first_resolution.yaml +2 -0
  169. cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
  170. cars/pipelines/default/__init__.py +26 -0
  171. cars/pipelines/default/default_pipeline.py +786 -0
  172. cars/pipelines/parameters/__init__.py +0 -0
  173. cars/pipelines/parameters/advanced_parameters.py +417 -0
  174. cars/pipelines/parameters/advanced_parameters_constants.py +69 -0
  175. cars/pipelines/parameters/application_parameters.py +71 -0
  176. cars/pipelines/parameters/depth_map_inputs.py +0 -0
  177. cars/pipelines/parameters/dsm_inputs.py +918 -0
  178. cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
  179. cars/pipelines/parameters/output_constants.py +52 -0
  180. cars/pipelines/parameters/output_parameters.py +454 -0
  181. cars/pipelines/parameters/sensor_inputs.py +842 -0
  182. cars/pipelines/parameters/sensor_inputs_constants.py +49 -0
  183. cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
  184. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
  185. cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
  186. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
  187. cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
  188. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
  189. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
  190. cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
  191. cars/pipelines/pipeline.py +119 -0
  192. cars/pipelines/pipeline_constants.py +31 -0
  193. cars/pipelines/pipeline_template.py +139 -0
  194. cars/pipelines/unit/__init__.py +26 -0
  195. cars/pipelines/unit/unit_pipeline.py +2850 -0
  196. cars/starter.py +167 -0
  197. cars-1.0.0rc1.dist-info/METADATA +292 -0
  198. cars-1.0.0rc1.dist-info/RECORD +200 -0
  199. cars-1.0.0rc1.dist-info/WHEEL +6 -0
  200. cars-1.0.0rc1.dist-info/entry_points.txt +8 -0
@@ -0,0 +1,25 @@
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
+ CARS phased dsms to full resolution dsm pipeline constants file
23
+ """
24
+
25
+ DSMS = "dsms"
@@ -0,0 +1,52 @@
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 constants
24
+ """
25
+
26
+ # Pipeline output keys
27
+ OUT_DIRECTORY = "directory"
28
+ PRODUCT_LEVEL = "product_level"
29
+ INFO_FILENAME = "metadata.yaml"
30
+ OUT_GEOID = "geoid"
31
+ EPSG = "epsg"
32
+ RESOLUTION = "resolution"
33
+ SAVE_BY_PAIR = "save_by_pair"
34
+ AUXILIARY = "auxiliary"
35
+
36
+ # Auxiliary keys
37
+ AUX_IMAGE = "image"
38
+ AUX_WEIGHTS = "weights"
39
+ AUX_MASK = "mask"
40
+ AUX_CLASSIFICATION = "classification"
41
+ AUX_PERFORMANCE_MAP = "performance_map"
42
+ AUX_FILLING = "filling"
43
+ AUX_CONTRIBUTING_PAIR = "contributing_pair"
44
+ AUX_AMBIGUITY = "ambiguity"
45
+
46
+ AUX_DEM_MIN = "dem_min"
47
+ AUX_DEM_MAX = "dem_max"
48
+ AUX_DEM_MEDIAN = "dem_median"
49
+
50
+
51
+ # Output tree constants
52
+ DSM_DIRECTORY = "dsm"
@@ -0,0 +1,454 @@
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
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 overloaded_conf.get(output_constants.RESOLUTION, None) is not None:
96
+ resolution = overloaded_conf[output_constants.RESOLUTION]
97
+ # update scaling coeff so the parameters are right for the dsm
98
+ # overloaded_scaling_coeff = 2*resolution
99
+
100
+ if resolution < 0.5 * scaling_coeff:
101
+ logging.warning(
102
+ "The requested DSM resolution of "
103
+ f"{overloaded_conf[output_constants.RESOLUTION]} seems "
104
+ "too low for the sensor images' resolution. "
105
+ "The pipeline will still continue with it."
106
+ )
107
+
108
+ else:
109
+ resolution = float(0.5 * scaling_coeff)
110
+ logging.info(
111
+ "The resolution of the output DSM will be " f"{resolution} meters. "
112
+ )
113
+
114
+ overloaded_conf[output_constants.RESOLUTION] = resolution
115
+
116
+ overloaded_conf[output_constants.SAVE_BY_PAIR] = overloaded_conf.get(
117
+ output_constants.SAVE_BY_PAIR, False
118
+ )
119
+
120
+ # Load auxiliary and subfields
121
+ overloaded_conf[output_constants.AUXILIARY] = overloaded_conf.get(
122
+ output_constants.AUXILIARY, {}
123
+ )
124
+
125
+ # Load auxiliary and subfields
126
+ overloaded_conf[output_constants.AUXILIARY][output_constants.AUX_IMAGE] = (
127
+ overloaded_conf[output_constants.AUXILIARY].get(
128
+ output_constants.AUX_IMAGE, True
129
+ )
130
+ )
131
+ overloaded_conf[output_constants.AUXILIARY][
132
+ output_constants.AUX_DEM_MIN
133
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
134
+ output_constants.AUX_DEM_MIN, False
135
+ )
136
+ overloaded_conf[output_constants.AUXILIARY][
137
+ output_constants.AUX_DEM_MAX
138
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
139
+ output_constants.AUX_DEM_MAX, False
140
+ )
141
+ overloaded_conf[output_constants.AUXILIARY][
142
+ output_constants.AUX_DEM_MEDIAN
143
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
144
+ output_constants.AUX_DEM_MEDIAN, False
145
+ )
146
+ overloaded_conf[output_constants.AUXILIARY][
147
+ output_constants.AUX_WEIGHTS
148
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
149
+ output_constants.AUX_WEIGHTS, False
150
+ )
151
+ overloaded_conf[output_constants.AUXILIARY][
152
+ output_constants.AUX_CLASSIFICATION
153
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
154
+ output_constants.AUX_CLASSIFICATION, False
155
+ )
156
+ overloaded_conf[output_constants.AUXILIARY][
157
+ output_constants.AUX_PERFORMANCE_MAP
158
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
159
+ output_constants.AUX_PERFORMANCE_MAP, False
160
+ )
161
+ overloaded_conf[output_constants.AUXILIARY][
162
+ output_constants.AUX_CONTRIBUTING_PAIR
163
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
164
+ output_constants.AUX_CONTRIBUTING_PAIR, False
165
+ )
166
+ overloaded_conf[output_constants.AUXILIARY][
167
+ output_constants.AUX_FILLING
168
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
169
+ output_constants.AUX_FILLING, False
170
+ )
171
+ overloaded_conf[output_constants.AUXILIARY][
172
+ output_constants.AUX_AMBIGUITY
173
+ ] = overloaded_conf[output_constants.AUXILIARY].get(
174
+ output_constants.AUX_AMBIGUITY, False
175
+ )
176
+
177
+ # Check schema
178
+ output_schema = {
179
+ output_constants.OUT_DIRECTORY: str,
180
+ output_constants.PRODUCT_LEVEL: list,
181
+ output_constants.OUT_GEOID: Or(bool, str),
182
+ output_constants.EPSG: And(Or(int, str, None), is_valid_epsg),
183
+ output_constants.RESOLUTION: Or(int, float),
184
+ output_constants.SAVE_BY_PAIR: bool,
185
+ output_constants.AUXILIARY: dict,
186
+ }
187
+ checker_output = Checker(output_schema)
188
+ checker_output.validate(overloaded_conf)
189
+
190
+ # check auxiliary keys
191
+ auxiliary_schema = {
192
+ output_constants.AUX_IMAGE: Or(bool, str, list),
193
+ output_constants.AUX_WEIGHTS: bool,
194
+ output_constants.AUX_CLASSIFICATION: Or(bool, dict, list),
195
+ output_constants.AUX_PERFORMANCE_MAP: Or(bool, list),
196
+ output_constants.AUX_CONTRIBUTING_PAIR: bool,
197
+ output_constants.AUX_FILLING: Or(bool, dict),
198
+ output_constants.AUX_AMBIGUITY: bool,
199
+ output_constants.AUX_DEM_MIN: bool,
200
+ output_constants.AUX_DEM_MAX: bool,
201
+ output_constants.AUX_DEM_MEDIAN: bool,
202
+ }
203
+
204
+ # Check and overload classification parameter
205
+ check_classification_parameter(inputs, overloaded_conf)
206
+
207
+ # Check and overload image parameter
208
+ check_texture_bands(inputs, overloaded_conf)
209
+
210
+ # Check and overload performance_map parameter
211
+ check_performance_classes(overloaded_conf)
212
+
213
+ # Check and overload filling parameter
214
+ check_filling_parameter(overloaded_conf)
215
+
216
+ checker_auxiliary = Checker(auxiliary_schema)
217
+ checker_auxiliary.validate(overloaded_conf[output_constants.AUXILIARY])
218
+
219
+ if "epsg" in overloaded_conf and overloaded_conf["epsg"]:
220
+ spatial_ref = CRS.from_epsg(overloaded_conf["epsg"])
221
+ if spatial_ref.is_geographic:
222
+ if overloaded_conf[output_constants.RESOLUTION] > 10e-3:
223
+ logging.warning(
224
+ "The resolution of the "
225
+ + "point_cloud_rasterization should be "
226
+ + "fixed according to the epsg"
227
+ )
228
+
229
+ return overloaded_conf, overloaded_scaling_coeff
230
+
231
+
232
+ def check_filling_parameter(overloaded_conf):
233
+ """
234
+ Check and overload filling parameter
235
+ """
236
+
237
+ filling_param = overloaded_conf[output_constants.AUXILIARY][
238
+ output_constants.AUX_FILLING
239
+ ]
240
+
241
+ valid_names = [
242
+ "fill_with_geoid",
243
+ "interpolate_from_borders",
244
+ "fill_with_endogenous_dem",
245
+ "fill_with_exogenous_dem",
246
+ "other",
247
+ ]
248
+
249
+ if isinstance(filling_param, dict):
250
+ for _, value in filling_param.items():
251
+ if isinstance(value, str):
252
+ value = [value]
253
+ if any(elem not in valid_names for elem in value):
254
+ raise RuntimeError(
255
+ "Those filling methods are not available in CARS"
256
+ )
257
+ elif filling_param is True:
258
+ overloaded_conf[output_constants.AUXILIARY][
259
+ output_constants.AUX_FILLING
260
+ ] = {i + 1: name for i, name in enumerate(valid_names)}
261
+
262
+
263
+ def check_texture_bands(inputs, overloaded_conf):
264
+ """
265
+ Check and overload texture bands
266
+ """
267
+ texture_bands = overloaded_conf[output_constants.AUXILIARY][
268
+ output_constants.AUX_IMAGE
269
+ ]
270
+
271
+ if inputs[sens_cst.SENSORS] is not None:
272
+ first_key = list(inputs[sens_cst.SENSORS].keys())[0]
273
+ image = inputs[sens_cst.SENSORS][first_key][sens_cst.INPUT_IMG]
274
+ bands = set(image["bands"].keys())
275
+
276
+ if isinstance(texture_bands, list):
277
+ for elem in texture_bands:
278
+ if not isinstance(elem, str):
279
+ raise RuntimeError(
280
+ "The image parameter of auxiliary should "
281
+ "be a boolean, a string or a list of string"
282
+ )
283
+ if elem not in bands:
284
+ raise RuntimeError(
285
+ f"The band {elem} is "
286
+ f"not an existing band of "
287
+ f"the input image"
288
+ )
289
+ elif isinstance(texture_bands, str):
290
+ overloaded_conf[output_constants.AUXILIARY][
291
+ output_constants.AUX_IMAGE
292
+ ] = [texture_bands]
293
+
294
+ if texture_bands not in bands:
295
+ raise RuntimeError(
296
+ f"The band {texture_bands} is "
297
+ f"not an existing band of "
298
+ f"the input image"
299
+ )
300
+ elif texture_bands is True:
301
+ overloaded_conf[output_constants.AUXILIARY][
302
+ output_constants.AUX_IMAGE
303
+ ] = sorted(bands)
304
+
305
+
306
+ def check_classification_parameter(inputs, overloaded_conf):
307
+ """
308
+ Check and overload classification parameter
309
+ """
310
+ classification_formatting = overloaded_conf[output_constants.AUXILIARY][
311
+ output_constants.AUX_CLASSIFICATION
312
+ ]
313
+
314
+ if inputs[sens_cst.SENSORS] is not None:
315
+ first_key = list(inputs[sens_cst.SENSORS].keys())[0]
316
+
317
+ if (
318
+ "classification" in inputs[sens_cst.SENSORS][first_key]
319
+ and inputs[sens_cst.SENSORS][first_key]["classification"]
320
+ is not None
321
+ ):
322
+ classif = inputs[sens_cst.SENSORS][first_key][
323
+ sens_cst.INPUT_CLASSIFICATION
324
+ ]
325
+ bands_classif = classif["values"]
326
+
327
+ if isinstance(classification_formatting, list):
328
+ overloaded_conf[output_constants.AUXILIARY][
329
+ output_constants.AUX_CLASSIFICATION
330
+ ] = {val: val for val in classification_formatting}
331
+
332
+ for elem in classification_formatting:
333
+ if not isinstance(elem, int):
334
+ raise RuntimeError(
335
+ "The image parameter of auxiliary should "
336
+ "be a boolean, a string or a list of int"
337
+ )
338
+
339
+ if elem not in bands_classif:
340
+ raise RuntimeError(
341
+ f"If you want to use {elem} as a band num, "
342
+ f"you should use a dictionary, not a list"
343
+ )
344
+ elif classification_formatting is True:
345
+ overloaded_conf[output_constants.AUXILIARY][
346
+ output_constants.AUX_CLASSIFICATION
347
+ ] = {int(name): name for val, name in enumerate(bands_classif)}
348
+ elif isinstance(classification_formatting, dict):
349
+ for _, value in classification_formatting.items():
350
+ if isinstance(value, int):
351
+ value = [value]
352
+
353
+ if any(elem not in bands_classif for elem in value):
354
+ raise RuntimeError(
355
+ f"The band {value} is "
356
+ f"not an existing band of "
357
+ f"the input classification"
358
+ )
359
+
360
+
361
+ def check_performance_classes(overloaded_conf):
362
+ """
363
+ Check performance classes
364
+ """
365
+ performance_map_classes = overloaded_conf[output_constants.AUXILIARY][
366
+ output_constants.AUX_PERFORMANCE_MAP
367
+ ]
368
+
369
+ if isinstance(performance_map_classes, list):
370
+ for elem in performance_map_classes:
371
+ if not isinstance(elem, (int, float)):
372
+ raise RuntimeError(
373
+ "The performance_map parameter of auxiliary should"
374
+ "be a boolean or a list of float/int"
375
+ )
376
+ if len(performance_map_classes) < 2:
377
+ raise RuntimeError("Not enough step for performance_map_classes")
378
+ if performance_map_classes:
379
+ previous_step = -1
380
+ for step in performance_map_classes:
381
+ if step < 0:
382
+ raise RuntimeError(
383
+ "All step in performance_map_classes must be >=0"
384
+ )
385
+ if step <= previous_step:
386
+ raise RuntimeError(
387
+ "performance_map_classes list must be ordered."
388
+ )
389
+ previous_step = step
390
+ elif performance_map_classes is True:
391
+ # default classes, in meters:
392
+ default_performance_classes = [
393
+ 0,
394
+ 0.968,
395
+ 1.13375,
396
+ 1.295,
397
+ 1.604,
398
+ 2.423,
399
+ 3.428,
400
+ ]
401
+
402
+ overloaded_conf[output_constants.AUXILIARY][
403
+ output_constants.AUX_PERFORMANCE_MAP
404
+ ] = default_performance_classes
405
+
406
+
407
+ def intialize_product_index(orchestrator, product_levels, input_pairs):
408
+ """
409
+ Initialize the index dictionary according to requested levels with None
410
+ values for all paths.
411
+
412
+ :param orchestrator: cars orchestrator
413
+ :type orchestrator: Orchestrator
414
+ :param product_levels: name of corresponding pipeline
415
+ :type product_levels: list
416
+ :param input_pairs: list containing the pair names
417
+ :type input_pairs: list
418
+ """
419
+
420
+ index = {}
421
+
422
+ if "dsm" in product_levels:
423
+ index["dsm"] = {
424
+ cst.INDEX_DSM_ALT: None,
425
+ cst.INDEX_DSM_COLOR: None,
426
+ cst.INDEX_DSM_MASK: None,
427
+ cst.INDEX_DSM_CLASSIFICATION: None,
428
+ cst.INDEX_DSM_PERFORMANCE_MAP: None,
429
+ cst.INDEX_DSM_CONTRIBUTING_PAIR: None,
430
+ cst.INDEX_DSM_FILLING: None,
431
+ cst.INDEX_DSM_WEIGHTS: None,
432
+ }
433
+
434
+ if "point_cloud" in product_levels:
435
+ # Initialize an empty index for point cloud because its content is
436
+ # unknown at this point (tile name, save by pair or not)
437
+ index["point_cloud"] = {}
438
+
439
+ if "depth_map" in product_levels:
440
+ index["depth_map"] = {}
441
+ for pair in input_pairs:
442
+ index["depth_map"][pair] = {
443
+ cst.INDEX_DEPTH_MAP_X: None,
444
+ cst.INDEX_DEPTH_MAP_Y: None,
445
+ cst.INDEX_DEPTH_MAP_Z: None,
446
+ cst.INDEX_DEPTH_MAP_COLOR: None,
447
+ cst.INDEX_DEPTH_MAP_MASK: None,
448
+ cst.INDEX_DEPTH_MAP_CLASSIFICATION: None,
449
+ cst.INDEX_DEPTH_MAP_PERFORMANCE_MAP: None,
450
+ cst.INDEX_DEPTH_MAP_FILLING: None,
451
+ cst.INDEX_DEPTH_MAP_EPSG: None,
452
+ }
453
+
454
+ orchestrator.update_index(index)