cars 1.0.0a3__cp39-cp39-win_amd64.whl → 1.0.0a4__cp39-cp39-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 (141) hide show
  1. cars/__init__.py +5 -5
  2. cars/applications/__init__.py +0 -3
  3. cars/applications/application_template.py +20 -0
  4. cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +12 -2
  5. cars/applications/auxiliary_filling/auxiliary_filling_algo.py +2 -2
  6. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +80 -36
  7. cars/applications/dem_generation/dem_generation_algo.py +1 -1
  8. cars/applications/dem_generation/dem_generation_wrappers.py +23 -57
  9. cars/applications/dem_generation/dichotomic_generation_app.py +3 -3
  10. cars/applications/dem_generation/rasterization_app.py +100 -41
  11. cars/applications/dense_match_filling/__init__.py +1 -1
  12. cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +2 -15
  13. cars/applications/dense_match_filling/fill_disp_algo.py +32 -373
  14. cars/applications/dense_match_filling/fill_disp_wrappers.py +0 -343
  15. cars/applications/dense_match_filling/zero_padding_app.py +10 -5
  16. cars/applications/dense_matching/abstract_dense_matching_app.py +2 -1
  17. cars/applications/dense_matching/census_mccnn_sgm_app.py +38 -39
  18. cars/applications/dense_matching/cpp/dense_matching_cpp.cp39-win_amd64.dll.a +0 -0
  19. cars/applications/dense_matching/cpp/dense_matching_cpp.cp39-win_amd64.pyd +0 -0
  20. cars/applications/dense_matching/dense_matching_algo.py +48 -14
  21. cars/applications/dense_matching/dense_matching_wrappers.py +11 -3
  22. cars/applications/dense_matching/disparity_grid_algo.py +84 -62
  23. cars/applications/dense_matching/loaders/pandora_loader.py +91 -33
  24. cars/applications/dsm_filling/border_interpolation_app.py +1 -7
  25. cars/applications/dsm_filling/bulldozer_filling_app.py +2 -8
  26. cars/applications/dsm_filling/exogenous_filling_app.py +4 -9
  27. cars/applications/grid_generation/abstract_grid_generation_app.py +1 -1
  28. cars/applications/grid_generation/epipolar_grid_generation_app.py +4 -2
  29. cars/applications/grid_generation/grid_correction_app.py +4 -1
  30. cars/applications/grid_generation/grid_generation_algo.py +7 -2
  31. cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +1 -1
  32. cars/applications/ground_truth_reprojection/direct_localization_app.py +2 -2
  33. cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +2 -1
  34. cars/applications/point_cloud_fusion/abstract_pc_fusion_app.py +0 -155
  35. cars/applications/point_cloud_fusion/mapping_to_terrain_tiles_app.py +0 -658
  36. cars/applications/point_cloud_fusion/pc_fusion_algo.py +0 -1339
  37. cars/applications/point_cloud_fusion/pc_fusion_wrappers.py +0 -869
  38. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +2 -1
  39. cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +9 -8
  40. cars/applications/point_cloud_outlier_removal/small_components_app.py +96 -267
  41. cars/applications/point_cloud_outlier_removal/statistical_app.py +116 -275
  42. cars/applications/rasterization/abstract_pc_rasterization_app.py +1 -1
  43. cars/applications/rasterization/rasterization_algo.py +18 -6
  44. cars/applications/rasterization/rasterization_wrappers.py +2 -1
  45. cars/applications/rasterization/simple_gaussian_app.py +60 -113
  46. cars/applications/resampling/abstract_resampling_app.py +1 -1
  47. cars/applications/resampling/bicubic_resampling_app.py +3 -1
  48. cars/applications/resampling/resampling_algo.py +16 -4
  49. cars/applications/resampling/resampling_wrappers.py +3 -1
  50. cars/applications/sparse_matching/abstract_sparse_matching_app.py +1 -1
  51. cars/applications/sparse_matching/sift_app.py +3 -3
  52. cars/applications/sparse_matching/sparse_matching_algo.py +3 -2
  53. cars/applications/sparse_matching/sparse_matching_wrappers.py +1 -1
  54. cars/applications/triangulation/abstract_triangulation_app.py +1 -1
  55. cars/applications/triangulation/line_of_sight_intersection_app.py +13 -11
  56. cars/applications/triangulation/pc_transform.py +552 -0
  57. cars/applications/triangulation/triangulation_algo.py +6 -4
  58. cars/applications/triangulation/triangulation_wrappers.py +1 -0
  59. cars/bundleadjustment.py +6 -6
  60. cars/cars.py +11 -9
  61. cars/core/cars_logging.py +80 -49
  62. cars/core/constants.py +0 -1
  63. cars/core/datasets.py +5 -2
  64. cars/core/geometry/abstract_geometry.py +256 -25
  65. cars/core/geometry/shareloc_geometry.py +110 -82
  66. cars/core/inputs.py +57 -19
  67. cars/core/outputs.py +1 -1
  68. cars/core/preprocessing.py +17 -3
  69. cars/core/projection.py +9 -6
  70. cars/core/tiling.py +10 -3
  71. cars/data_structures/cars_dataset.py +5 -5
  72. cars/data_structures/corresponding_tiles_tools.py +0 -103
  73. cars/data_structures/format_transformation.py +4 -1
  74. cars/devibrate.py +6 -3
  75. cars/extractroi.py +20 -21
  76. cars/orchestrator/cluster/abstract_cluster.py +15 -5
  77. cars/orchestrator/cluster/abstract_dask_cluster.py +6 -2
  78. cars/orchestrator/cluster/dask_jobqueue_utils.py +1 -1
  79. cars/orchestrator/cluster/log_wrapper.py +148 -21
  80. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +11 -3
  81. cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +2 -2
  82. cars/orchestrator/cluster/pbs_dask_cluster.py +1 -1
  83. cars/orchestrator/cluster/sequential_cluster.py +5 -4
  84. cars/orchestrator/cluster/slurm_dask_cluster.py +1 -1
  85. cars/orchestrator/orchestrator.py +14 -3
  86. cars/orchestrator/registry/id_generator.py +1 -0
  87. cars/orchestrator/registry/saver_registry.py +2 -2
  88. cars/pipelines/conf_resolution/conf_final_resolution.json +5 -3
  89. cars/pipelines/default/default_pipeline.py +462 -1073
  90. cars/pipelines/parameters/advanced_parameters.py +74 -64
  91. cars/pipelines/parameters/advanced_parameters_constants.py +2 -5
  92. cars/pipelines/parameters/application_parameters.py +71 -0
  93. cars/pipelines/parameters/depth_map_inputs.py +0 -314
  94. cars/pipelines/parameters/dsm_inputs.py +40 -4
  95. cars/pipelines/parameters/output_parameters.py +2 -2
  96. cars/pipelines/parameters/sensor_inputs.py +30 -75
  97. cars/pipelines/parameters/sensor_inputs_constants.py +0 -2
  98. cars/pipelines/parameters/sensor_loaders/__init__.py +4 -3
  99. cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +106 -0
  100. cars/pipelines/parameters/sensor_loaders/{basic_sensor_loader.py → basic_image_loader.py} +16 -22
  101. cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +121 -0
  102. cars/pipelines/parameters/sensor_loaders/{pivot_sensor_loader.py → pivot_image_loader.py} +10 -21
  103. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +4 -6
  104. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +1 -3
  105. cars/pipelines/pipeline_template.py +1 -3
  106. cars/pipelines/unit/unit_pipeline.py +527 -1016
  107. cars/starter.py +4 -3
  108. cars-1.0.0a4.dist-info/DELVEWHEEL +2 -0
  109. {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/METADATA +135 -53
  110. {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/RECORD +116 -132
  111. cars.libs/.load-order-cars-1.0.0a4 +3 -0
  112. cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
  113. cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
  114. cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
  115. cars/applications/dense_match_filling/cpp/__init__.py +0 -0
  116. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp39-win_amd64.dll.a +0 -0
  117. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp39-win_amd64.pyd +0 -0
  118. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.py +0 -72
  119. cars/applications/dense_match_filling/cpp/includes/dense_match_filling.hpp +0 -46
  120. cars/applications/dense_match_filling/cpp/meson.build +0 -9
  121. cars/applications/dense_match_filling/cpp/src/bindings.cpp +0 -11
  122. cars/applications/dense_match_filling/cpp/src/dense_match_filling.cpp +0 -142
  123. cars/applications/dense_match_filling/plane_app.py +0 -556
  124. cars/applications/hole_detection/__init__.py +0 -30
  125. cars/applications/hole_detection/abstract_hole_detection_app.py +0 -125
  126. cars/applications/hole_detection/cloud_to_bbox_app.py +0 -346
  127. cars/applications/hole_detection/hole_detection_algo.py +0 -144
  128. cars/applications/hole_detection/hole_detection_wrappers.py +0 -53
  129. cars/applications/point_cloud_denoising/__init__.py +0 -29
  130. cars/applications/point_cloud_denoising/abstract_pc_denoising_app.py +0 -273
  131. cars/applications/point_cloud_fusion/__init__.py +0 -30
  132. cars/applications/point_cloud_fusion/cloud_fusion_constants.py +0 -39
  133. cars/applications/sparse_matching/pandora_sparse_matching_app.py +0 -0
  134. cars/pipelines/parameters/depth_map_inputs_constants.py +0 -25
  135. cars-1.0.0a3.dist-info/DELVEWHEEL +0 -2
  136. cars.libs/.load-order-cars-1.0.0a3 +0 -3
  137. cars.libs/libgcc_s_seh-1-ca70890bbc5723b6d0ea31e9c9cded2b.dll +0 -0
  138. cars.libs/libstdc++-6-00ee19f73d5122a1277c137b1c218401.dll +0 -0
  139. cars.libs/libwinpthread-1-f5042e8e3d21edce20c1bc99445f551b.dll +0 -0
  140. {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/WHEEL +0 -0
  141. {cars-1.0.0a3.dist-info → cars-1.0.0a4.dist-info}/entry_points.txt +0 -0
@@ -30,7 +30,7 @@ import numpy as np
30
30
  import rasterio as rio
31
31
  import shareloc.geofunctions.rectification as rectif
32
32
  import xarray as xr
33
- from json_checker import Checker
33
+ from json_checker import And, Checker
34
34
  from shareloc.dtm_reader import dtm_reader
35
35
  from shareloc.geofunctions import localization
36
36
  from shareloc.geofunctions.rectification_grid import RectificationGrid
@@ -41,7 +41,7 @@ from shareloc.geomodels.rpc import RPC
41
41
  from shareloc.image import Image
42
42
 
43
43
  from cars.core import constants as cst
44
- from cars.core import inputs, projection
44
+ from cars.core import projection
45
45
  from cars.core.geometry.abstract_geometry import AbstractGeometry
46
46
 
47
47
  GRID_TYPE = "GRID"
@@ -56,7 +56,7 @@ class SharelocGeometry(AbstractGeometry):
56
56
  Shareloc geometry class
57
57
  """
58
58
 
59
- def __init__(
59
+ def __init__( # pylint: disable=too-many-positional-arguments
60
60
  self,
61
61
  geometry_plugin_conf,
62
62
  dem=None,
@@ -64,6 +64,7 @@ class SharelocGeometry(AbstractGeometry):
64
64
  default_alt=None,
65
65
  pairs_for_roi=None,
66
66
  scaling_coeff=1,
67
+ output_dem_dir=None,
67
68
  ):
68
69
 
69
70
  super().__init__(
@@ -73,50 +74,27 @@ class SharelocGeometry(AbstractGeometry):
73
74
  default_alt=default_alt,
74
75
  pairs_for_roi=pairs_for_roi,
75
76
  scaling_coeff=scaling_coeff,
77
+ output_dem_dir=output_dem_dir,
76
78
  )
77
79
 
78
- self.dem_roi = None
79
- self.roi_shareloc = None
80
- self.elevation = None
81
-
82
- # a margin is needed for cubic interpolation
83
- self.rectification_grid_margin = 0
84
- if self.interpolator == "cubic":
85
- self.rectification_grid_margin = 5
86
-
87
- # compute roi only when generating geometry object with dem
88
- # even if dem is None
89
- if geoid is not None and pairs_for_roi is not None:
90
- self.dem_roi_epsg = 4326
91
- if dem is not None:
92
- # Get dem epsg
93
- self.dem_roi_epsg = inputs.rasterio_get_epsg(dem)
94
-
95
- self.roi_shareloc = self.get_roi(
96
- pairs_for_roi,
97
- self.dem_roi_epsg,
98
- z_min=0,
99
- z_max=0,
100
- margin=self.dem_roi_margin,
101
- )
102
- # change convention
103
- self.dem_roi = [
104
- self.roi_shareloc[1],
105
- self.roi_shareloc[0],
106
- self.roi_shareloc[3],
107
- self.roi_shareloc[2],
108
- ]
109
-
110
80
  if dem is not None:
111
-
112
81
  # fill_nodata option should be set when dealing with void in DTM
113
- # see shareloc DTM limitations in sphinx doc for further details
114
-
82
+ # see shareloc DTM limitations in sphinx doc for further detailsd
115
83
  try:
84
+ if self.dem_roi is None:
85
+ roi_shareloc = None
86
+ else:
87
+ # From (x, y) to (y, x)
88
+ roi_shareloc = [
89
+ self.dem_roi[1],
90
+ self.dem_roi[0],
91
+ self.dem_roi[3],
92
+ self.dem_roi[2],
93
+ ]
116
94
  dtm_image = dtm_reader(
117
- dem,
118
- geoid,
119
- roi=self.roi_shareloc,
95
+ self.dem,
96
+ self.geoid,
97
+ roi=roi_shareloc,
120
98
  roi_is_in_physical_space=True,
121
99
  fill_nodata="mean",
122
100
  fill_value=0.0,
@@ -143,7 +121,56 @@ class SharelocGeometry(AbstractGeometry):
143
121
  else:
144
122
  self.elevation = default_alt
145
123
 
146
- def get_roi(self, pairs_for_roi, epsg, z_min=0, z_max=0, margin=0.012):
124
+ def check_conf(self, conf):
125
+ """
126
+ Check configuration
127
+
128
+ :param conf: configuration to check
129
+ :type conf: str or dict
130
+
131
+ :return: full dict
132
+ :rtype: dict
133
+
134
+ """
135
+
136
+ if conf is None:
137
+ raise RuntimeError("Geometry plugin configuration is None")
138
+
139
+ overloaded_conf = {}
140
+
141
+ if isinstance(conf, str):
142
+ conf = {"plugin_name": conf}
143
+
144
+ # overload conf
145
+ overloaded_conf["plugin_name"] = conf.get(
146
+ "plugin_name", "SharelocGeometry"
147
+ )
148
+ overloaded_conf["interpolator"] = conf.get("interpolator", "cubic")
149
+ overloaded_conf["dem_roi_margin"] = conf.get(
150
+ "dem_roi_margin", [0.25, 0.02]
151
+ )
152
+
153
+ geometry_schema = {
154
+ "plugin_name": str,
155
+ "interpolator": And(str, lambda x: x in ["cubic", "linear"]),
156
+ "dem_roi_margin": [float],
157
+ }
158
+
159
+ # Check conf
160
+ checker = Checker(geometry_schema)
161
+ checker.validate(overloaded_conf)
162
+
163
+ return overloaded_conf
164
+
165
+ def get_roi( # pylint: disable=too-many-positional-arguments
166
+ self,
167
+ pairs_for_roi,
168
+ epsg,
169
+ z_min=0,
170
+ z_max=0,
171
+ linear_margin=0,
172
+ constant_margin=0.012,
173
+ ):
147
174
  """
148
175
  Compute region of interest for intersection of DEM
149
176
 
@@ -151,35 +178,17 @@ class SharelocGeometry(AbstractGeometry):
151
178
  :type pairs_for_roi: List[(str, dict, str, dict)]
152
179
  :param dem_epsg: output EPSG code for ROI
153
180
  :type dem_epsg: int
154
- :param margin: margin for ROI in degrees
155
- :type margin: float
181
+ :param linear_margin: margin for ROI (factor of initial ROI size)
182
+ :type linear_margin: float
183
+ :param constant_margin: margin for ROI in degrees
184
+ :type constant_margin: float
156
185
  """
186
+ base_roi = super().get_roi(
187
+ pairs_for_roi, epsg, z_min, z_max, linear_margin, constant_margin
188
+ )
189
+
157
190
  coords_list = []
158
- for image1, geomodel1, image2, geomodel2 in pairs_for_roi:
159
- # Footprint of left image with altitude z_min
160
- coords_list.extend(
161
- self.image_envelope(
162
- image1["main_file"], geomodel1, elevation=z_min
163
- )
164
- )
165
- # Footprint of left image with altitude z_max
166
- coords_list.extend(
167
- self.image_envelope(
168
- image1["main_file"], geomodel1, elevation=z_max
169
- )
170
- )
171
- # Footprint of right image with altitude z_min
172
- coords_list.extend(
173
- self.image_envelope(
174
- image2["main_file"], geomodel2, elevation=z_min
175
- )
176
- )
177
- # Footprint of right image with altitude z_max
178
- coords_list.extend(
179
- self.image_envelope(
180
- image2["main_file"], geomodel2, elevation=z_max
181
- )
182
- )
191
+ for image1, geomodel1, _, geomodel2 in pairs_for_roi:
183
192
  # Footprint of rectification grid (with margins)
184
193
  image1 = SharelocGeometry.load_image(image1["main_file"])
185
194
  geomodel1 = self.load_geom_model(geomodel1)
@@ -206,28 +215,45 @@ class SharelocGeometry(AbstractGeometry):
206
215
  )
207
216
  lat_min, lon_min, lat_max, lon_max = list(epipolar_extent)
208
217
  coords_list.extend([(lon_min, lat_min), (lon_max, lat_max)])
218
+
209
219
  lon_list, lat_list = list(zip(*coords_list)) # noqa: B905
210
220
  roi = [
211
- min(lat_list) - margin,
212
- min(lon_list) - margin,
213
- max(lat_list) + margin,
214
- max(lon_list) + margin,
221
+ min(lon_list) - constant_margin,
222
+ min(lat_list) - constant_margin,
223
+ max(lon_list) + constant_margin,
224
+ max(lat_list) + constant_margin,
215
225
  ]
216
226
  points = np.array(
217
227
  [
218
- (roi[1], roi[0], 0),
219
- (roi[3], roi[2], 0),
220
- (roi[1], roi[0], 0),
221
- (roi[3], roi[2], 0),
228
+ (roi[0], roi[1], 0),
229
+ (roi[2], roi[3], 0),
230
+ (roi[0], roi[1], 0),
231
+ (roi[2], roi[3], 0),
222
232
  ]
223
233
  )
224
234
  new_points = projection.point_cloud_conversion(points, 4326, epsg)
225
235
  roi = [
226
- min(new_points[:, 1]),
227
236
  min(new_points[:, 0]),
228
- max(new_points[:, 1]),
237
+ min(new_points[:, 1]),
229
238
  max(new_points[:, 0]),
239
+ max(new_points[:, 1]),
240
+ ]
241
+
242
+ lon_size = roi[2] - roi[0]
243
+ lat_size = roi[3] - roi[1]
244
+
245
+ roi[0] -= linear_margin * lon_size
246
+ roi[1] -= linear_margin * lat_size
247
+ roi[2] += linear_margin * lon_size
248
+ roi[3] += linear_margin * lat_size
249
+
250
+ roi = [
251
+ min(roi[0], base_roi[0]),
252
+ min(roi[1], base_roi[1]),
253
+ max(roi[2], base_roi[2]),
254
+ max(roi[3], base_roi[3]),
230
255
  ]
256
+
231
257
  return roi
232
258
 
233
259
  @staticmethod
@@ -306,7 +332,7 @@ class SharelocGeometry(AbstractGeometry):
306
332
 
307
333
  return sensor, overloaded_geomodel
308
334
 
309
- def triangulate(
335
+ def triangulate( # pylint: disable=too-many-positional-arguments
310
336
  self,
311
337
  sensor1,
312
338
  sensor2,
@@ -317,6 +343,7 @@ class SharelocGeometry(AbstractGeometry):
317
343
  grid1: Union[dict, RectificationGrid],
318
344
  grid2: Union[dict, RectificationGrid],
319
345
  roi_key: Union[None, str] = None,
346
+ interpolation_method=None,
320
347
  ) -> np.ndarray:
321
348
  """
322
349
  Performs triangulation from cars disparity or matches dataset
@@ -398,6 +425,7 @@ class SharelocGeometry(AbstractGeometry):
398
425
 
399
426
  return llh
400
427
 
428
+ # pylint: disable=too-many-positional-arguments
401
429
  def generate_epipolar_grids(
402
430
  self,
403
431
  sensor1,
@@ -481,7 +509,7 @@ class SharelocGeometry(AbstractGeometry):
481
509
  disp_to_alt_ratio,
482
510
  )
483
511
 
484
- def direct_loc(
512
+ def direct_loc( # pylint: disable=too-many-positional-arguments
485
513
  self,
486
514
  sensor,
487
515
  geomodel,
@@ -526,7 +554,7 @@ class SharelocGeometry(AbstractGeometry):
526
554
  )
527
555
  return latlonalt
528
556
 
529
- def inverse_loc(
557
+ def inverse_loc( # pylint: disable=too-many-positional-arguments
530
558
  self,
531
559
  sensor,
532
560
  geomodel,
cars/core/inputs.py CHANGED
@@ -35,6 +35,7 @@ import fiona
35
35
  import numpy as np
36
36
  import rasterio as rio
37
37
  import xarray as xr
38
+ from affine import Affine
38
39
  from json_checker import Checker
39
40
  from pyproj import CRS
40
41
  from rasterio.warp import Resampling, calculate_default_transform, reproject
@@ -107,7 +108,7 @@ def rasterio_get_values(raster_file: str, x_list, y_list, proj_function):
107
108
  cloud_out = proj_function(cloud_in, 4326, file_espg)
108
109
 
109
110
  # get the transform and inverse
110
- aff_tr = descriptor.transform
111
+ aff_tr = rasterio_get_transform(raster_file)
111
112
  np_tr = np.array(
112
113
  [
113
114
  [aff_tr[0], aff_tr[1], aff_tr[2]],
@@ -120,17 +121,28 @@ def rasterio_get_values(raster_file: str, x_list, y_list, proj_function):
120
121
  # convert sensor to pixel coordinates
121
122
  pix_pos = np.hstack([cloud_out, np.ones((len(cloud_out), 1))])
122
123
  pix_pos = inv_tr @ pix_pos.T
123
- pix_pos = pix_pos.T[:, [1, 0]].astype(int)
124
+ pix_pos = pix_pos.T[:, [1, 0]].astype(
125
+ int
126
+ ) # convention (row, col) i.e. (y, x)
127
+
128
+ # crop to dem bounds
129
+ ul_corner = np.array([0, 0])
130
+ lr_corner = np.array([descriptor.height, descriptor.width])
131
+ pix_pos_clipped = np.clip(pix_pos, ul_corner, lr_corner)
132
+ out_of_bounds_pix = np.any(pix_pos != pix_pos_clipped, axis=1)
133
+ pix_pos = pix_pos_clipped
124
134
 
125
135
  # get the data needed
126
136
  min_pt = pix_pos.min(axis=0)
127
137
  max_pt = pix_pos.max(axis=0)
128
138
 
129
- width = max_pt[0] - min_pt[0] + 1
130
- height = max_pt[1] - min_pt[1] + 1
131
- window = Window(min_pt[1], min_pt[0], height, width)
139
+ height = max_pt[0] - min_pt[0] + 1
140
+ width = max_pt[1] - min_pt[1] + 1
141
+ window = Window(min_pt[1], min_pt[0], width, height)
132
142
 
133
143
  data = descriptor.read(1, window=window)
144
+ if data.size == 0:
145
+ return None
134
146
 
135
147
  # read the data for all points
136
148
  max_sampled_pos = np.array(data.shape)[:2] - 1
@@ -142,6 +154,7 @@ def rasterio_get_values(raster_file: str, x_list, y_list, proj_function):
142
154
 
143
155
  if nodata_value is not None:
144
156
  z_list[z_list == nodata_value] = np.nan
157
+ z_list[out_of_bounds_pix] = np.nan
145
158
 
146
159
  return z_list
147
160
 
@@ -253,19 +266,32 @@ def rasterio_get_pixel_points(raster_file: str, terrain_points) -> list:
253
266
 
254
267
  pixel_points = []
255
268
 
256
- with rio.open(raster_file, "r") as descriptor:
257
- for row in range(terrain_points.shape[0]):
258
- pixel_points.append(
259
- rio.transform.rowcol(
260
- descriptor.transform,
261
- terrain_points[row, 0],
262
- terrain_points[row, 1],
263
- )
269
+ for row in range(terrain_points.shape[0]):
270
+ pixel_points.append(
271
+ rio.transform.rowcol(
272
+ rasterio_get_transform(raster_file),
273
+ terrain_points[row, 0],
274
+ terrain_points[row, 1],
264
275
  )
276
+ )
265
277
 
266
278
  return np.array(pixel_points)
267
279
 
268
280
 
281
+ def rasterio_get_resolution(raster_file: str) -> Tuple[float, float]:
282
+ """
283
+ Get the resolution of raster_file
284
+
285
+ :param raster_file: Image file
286
+ :return: The resolution (res_x, res_y)
287
+ :rtype: tuple
288
+ """
289
+ transform = list(rasterio_get_transform(raster_file))
290
+ res_x = transform[0]
291
+ res_y = transform[4]
292
+ return (abs(res_x), abs(res_y))
293
+
294
+
269
295
  def rasterio_get_bounds(
270
296
  raster_file: str, apply_resolution_sign=False
271
297
  ) -> Tuple[int, int]:
@@ -278,8 +304,7 @@ def rasterio_get_bounds(
278
304
 
279
305
  # get sign of resolution
280
306
  if apply_resolution_sign:
281
- profile = rasterio_get_profile(raster_file)
282
- transform = list(profile["transform"])
307
+ transform = list(rasterio_get_transform(raster_file))
283
308
  res_x = transform[0]
284
309
  res_y = transform[4]
285
310
  res_x /= abs(res_x)
@@ -354,15 +379,28 @@ def rasterio_get_profile(raster_file: str) -> Dict:
354
379
  return descriptor.profile
355
380
 
356
381
 
357
- def rasterio_get_transform(raster_file: str) -> Dict:
382
+ def rasterio_get_transform(raster_file: str, convention: str = None) -> Dict:
358
383
  """
359
384
  Get the transform of an image file
360
385
 
361
386
  :param raster_file: Image file
387
+ :param convention: The convention to follow: None, "north" or "south"
362
388
  :return: The transform of the given image
363
389
  """
364
- with rio.open(raster_file, "r") as descriptor:
365
- return descriptor.transform
390
+ with rio.open(raster_file, "r") as dsc:
391
+ src_tr = dsc.transform
392
+
393
+ if convention == "north" and src_tr.e < 0:
394
+ src_tr = Affine(
395
+ src_tr.a, src_tr.b, src_tr.c, -src_tr.d, -src_tr.e, -src_tr.f
396
+ )
397
+
398
+ elif convention == "south" and src_tr.e > 0:
399
+ src_tr = Affine(
400
+ src_tr.a, src_tr.b, src_tr.c, -src_tr.d, -src_tr.e, -src_tr.f
401
+ )
402
+
403
+ return src_tr
366
404
 
367
405
 
368
406
  def rasterio_get_epsg(raster_file: str) -> int:
@@ -423,7 +461,7 @@ def rasterio_transform_epsg(file_name, new_epsg):
423
461
  reproject(
424
462
  source=rio.band(src, i),
425
463
  destination=rio.band(dst, i),
426
- src_transform=src.transform,
464
+ src_transform=rasterio_get_transform(file_name),
427
465
  src_crs=src.crs,
428
466
  dst_transform=transform,
429
467
  dst_crs=new_epsg,
cars/core/outputs.py CHANGED
@@ -110,7 +110,7 @@ def write_vector(polys, path_to_file, epsg, driver="GPKG"):
110
110
  vector_file.write(poly_dict)
111
111
 
112
112
 
113
- def rasterio_write_georaster(
113
+ def rasterio_write_georaster( # pylint: disable=too-many-positional-arguments
114
114
  raster_file: str,
115
115
  data: np.ndarray,
116
116
  profile: dict = None,
@@ -72,13 +72,26 @@ def get_utm_zone_as_epsg_code(lon, lat):
72
72
  )
73
73
  return 32632
74
74
 
75
+ if lat > 84:
76
+ logging.warning(
77
+ "Since the latitude is above 84°, the EPSG 32661 will be used."
78
+ )
79
+ return 32661
80
+
81
+ if lat < -80:
82
+ logging.warning(
83
+ "Since the latitude is under -80°, the EPSG 32761 will be used."
84
+ )
85
+ return 32761
86
+
75
87
  zone = utm.from_latlon(lat, lon)[2]
76
88
 
77
89
  north_south = 600 if lat >= 0 else 700
78
90
  return 32000 + north_south + zone
79
91
 
80
92
 
81
- def compute_terrain_bbox( # noqa: 751
93
+ @cars_profile(name="Compute terrain bbox")
94
+ def compute_terrain_bbox( # pylint: disable=too-many-positional-arguments # noqa: 751
82
95
  sensor_image_left,
83
96
  sensor_image_right,
84
97
  epipolar_image_left,
@@ -375,7 +388,7 @@ def compute_roi_poly(input_roi_poly, input_roi_epsg, epsg):
375
388
 
376
389
 
377
390
  @cars_profile(name="Compute epsg")
378
- def compute_epsg(
391
+ def compute_epsg( # pylint: disable=too-many-positional-arguments
379
392
  sensor_image_left,
380
393
  sensor_image_right,
381
394
  grid_left,
@@ -518,6 +531,7 @@ def crop_terrain_bounds_with_roi(roi_poly, xmin, ymin, xmax, ymax):
518
531
  return new_xmin, new_ymin, new_xmax, new_ymax
519
532
 
520
533
 
534
+ @cars_profile(name="Compute terrain bounds")
521
535
  def compute_terrain_bounds(list_of_terrain_roi, roi_poly=None, resolution=0.5):
522
536
  """
523
537
  Compute Terrain bounds of merged pairs
@@ -650,7 +664,7 @@ def convert_optimal_tile_size_with_epsg(
650
664
 
651
665
 
652
666
  @cars_profile(name="Compute epipolar roi")
653
- def compute_epipolar_roi(
667
+ def compute_epipolar_roi( # pylint: disable=too-many-positional-arguments
654
668
  terrain_roi_poly,
655
669
  terrain_roi_epsg,
656
670
  geometry_plugin,
cars/core/projection.py CHANGED
@@ -22,7 +22,7 @@
22
22
  Projection module:
23
23
  contains some general purpose functions using polygons and data projections
24
24
  """
25
- # pylint: disable=too-many-lines
25
+ # pylint: disable=C0302(too-many-lines)
26
26
 
27
27
  # Standard imports
28
28
  import logging
@@ -42,6 +42,7 @@ from shapely.ops import transform
42
42
 
43
43
  from cars.core import constants as cst
44
44
  from cars.core import inputs, outputs, utils
45
+ from cars.orchestrator.cluster.log_wrapper import cars_profile
45
46
 
46
47
 
47
48
  def compute_dem_intersection_with_poly( # noqa: C901
@@ -219,7 +220,7 @@ def geo_to_ecef(
219
220
  )[0]
220
221
 
221
222
 
222
- def ecef_to_enu(
223
+ def ecef_to_enu( # pylint: disable=too-many-positional-arguments
223
224
  x_ecef: np.ndarray,
224
225
  y_ecef: np.ndarray,
225
226
  z_ecef: np.ndarray,
@@ -269,7 +270,7 @@ def ecef_to_enu(
269
270
  return x_east, y_north, z_up
270
271
 
271
272
 
272
- def geo_to_enu(
273
+ def geo_to_enu( # pylint: disable=too-many-positional-arguments
273
274
  lat: np.ndarray,
274
275
  lon: np.ndarray,
275
276
  alt: np.ndarray,
@@ -318,7 +319,7 @@ def enu_to_aer(
318
319
  return azimuth, elevation, xyz_range
319
320
 
320
321
 
321
- def geo_to_aer(
322
+ def geo_to_aer( # pylint: disable=too-many-positional-arguments
322
323
  lat: np.ndarray,
323
324
  lon: np.ndarray,
324
325
  alt: np.ndarray,
@@ -529,6 +530,8 @@ def ground_polygon_from_envelopes(
529
530
  return inter, inter.bounds
530
531
 
531
532
 
533
+ # pylint: disable=too-many-positional-arguments
534
+ @cars_profile(name="Ground intersection envelopes", interval=0.5)
532
535
  def ground_intersection_envelopes(
533
536
  sensor1,
534
537
  sensor2,
@@ -595,7 +598,7 @@ def ground_intersection_envelopes(
595
598
  return inter_poly, (inter_xmin, inter_ymin, inter_xmax, inter_ymax)
596
599
 
597
600
 
598
- def get_ground_direction(
601
+ def get_ground_direction( # pylint: disable=too-many-positional-arguments
599
602
  sensor,
600
603
  geomodel,
601
604
  geometry_plugin: str,
@@ -668,7 +671,7 @@ def get_ground_direction(
668
671
  return np.array([lat0, lon0, alt0, lat, lon, alt])
669
672
 
670
673
 
671
- def get_ground_angles(
674
+ def get_ground_angles( # pylint: disable=too-many-positional-arguments
672
675
  sensor1,
673
676
  sensor2,
674
677
  geomodel1,
cars/core/tiling.py CHANGED
@@ -40,8 +40,10 @@ from scipy.spatial import tsearch # pylint: disable=no-name-in-module
40
40
  from shapely.geometry import box, mapping
41
41
  from shapely.geometry.multipolygon import MultiPolygon
42
42
 
43
+ from cars.orchestrator.cluster.log_wrapper import cars_profile
43
44
 
44
- def grid(
45
+
46
+ def grid( # pylint: disable=too-many-positional-arguments
45
47
  xmin: float, ymin: float, xmax: float, ymax: float, xsplit: int, ysplit: int
46
48
  ) -> np.ndarray:
47
49
  """
@@ -74,6 +76,7 @@ def grid(
74
76
  return out_grid
75
77
 
76
78
 
79
+ @cars_profile(name="Transform four layers to two layers grid", interval=0.5)
77
80
  def transform_four_layers_to_two_layers_grid(tiling_grid, terrain=False):
78
81
  """
79
82
  Transform a 4 layer grid: (N, M, 4) containing
@@ -115,6 +118,7 @@ def transform_four_layers_to_two_layers_grid(tiling_grid, terrain=False):
115
118
  return arr
116
119
 
117
120
 
121
+ @cars_profile(name="Transform disp range grid to two layers", interval=0.5)
118
122
  def transform_disp_range_grid_to_two_layers(disp_min_grid, disp_max_grid):
119
123
  """
120
124
  Transform tiling disp min and max to N+1 M+1 array corresponding
@@ -154,7 +158,7 @@ def transform_disp_range_grid_to_two_layers(disp_min_grid, disp_max_grid):
154
158
  return disp_min, disp_max
155
159
 
156
160
 
157
- def generate_tiling_grid(
161
+ def generate_tiling_grid( # pylint: disable=too-many-positional-arguments
158
162
  row_min: float,
159
163
  col_min: float,
160
164
  row_max: float,
@@ -199,7 +203,9 @@ def generate_tiling_grid(
199
203
  return out_grid
200
204
 
201
205
 
202
- def split(xmin, ymin, xmax, ymax, xsplit, ysplit):
206
+ def split(
207
+ xmin, ymin, xmax, ymax, xsplit, ysplit
208
+ ): # pylint: disable=too-many-positional-arguments
203
209
  """
204
210
  Split a region defined by [xmin, xmax] x [ymin, ymax]
205
211
  in splits of xsplit x ysplit size
@@ -561,6 +567,7 @@ def region_hash_string(region: Tuple):
561
567
  return "{}_{}_{}_{}".format(region[0], region[1], region[2], region[3])
562
568
 
563
569
 
570
+ # pylint: disable=too-many-positional-arguments
564
571
  def get_corresponding_tiles_row_col(
565
572
  terrain_tiling_grid: np.ndarray,
566
573
  row: int,
@@ -339,7 +339,7 @@ class CarsDataset:
339
339
 
340
340
  return new_window
341
341
 
342
- def create_grid(
342
+ def create_grid( # pylint: disable=too-many-positional-arguments
343
343
  self,
344
344
  nb_col: int,
345
345
  nb_row: int,
@@ -435,7 +435,7 @@ class CarsDataset:
435
435
  tiles_row.append(None)
436
436
  self.tiles.append(tiles_row)
437
437
 
438
- def generate_descriptor(
438
+ def generate_descriptor( # pylint: disable=too-many-positional-arguments
439
439
  self, future_result, file_name, tag=None, dtype=None, nodata=None
440
440
  ):
441
441
  """
@@ -579,7 +579,7 @@ def run_save_arrays(future_result, file_name, tag=None, descriptor=None):
579
579
  )
580
580
 
581
581
 
582
- def run_save_points(
582
+ def run_save_points( # pylint: disable=too-many-positional-arguments
583
583
  future_result,
584
584
  file_name,
585
585
  overwrite=False,
@@ -840,7 +840,7 @@ def save_single_tile_dict(dict_cars, tile_path_name: str):
840
840
  dict_cars.attrs = saved_dict_cars_attrs
841
841
 
842
842
 
843
- def fill_dataset(
843
+ def fill_dataset( # pylint: disable=too-many-positional-arguments
844
844
  dataset,
845
845
  saving_info=None,
846
846
  window=None,
@@ -939,7 +939,7 @@ def fill_dict(data_dict, saving_info=None, attributes=None):
939
939
  data_dict.attrs[SAVING_INFO] = saving_info
940
940
 
941
941
 
942
- def save_all_dataframe(
942
+ def save_all_dataframe( # pylint: disable=too-many-positional-arguments
943
943
  dataframe,
944
944
  file_name,
945
945
  save_by_pair=False,