cars 1.0.0a1__cp313-cp313-win_amd64.whl → 1.0.0a3__cp313-cp313-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 (81) hide show
  1. cars/__init__.py +4 -4
  2. cars/applications/application.py +14 -6
  3. cars/applications/application_template.py +22 -0
  4. cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +15 -10
  5. cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +7 -6
  6. cars/applications/dem_generation/abstract_dem_generation_app.py +9 -5
  7. cars/applications/dem_generation/dem_generation_wrappers.py +48 -25
  8. cars/applications/dem_generation/dichotomic_generation_app.py +27 -9
  9. cars/applications/dem_generation/rasterization_app.py +85 -32
  10. cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +4 -0
  11. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp313-win_amd64.dll.a +0 -0
  12. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp313-win_amd64.pyd +0 -0
  13. cars/applications/dense_match_filling/fill_disp_algo.py +41 -12
  14. cars/applications/dense_match_filling/plane_app.py +11 -0
  15. cars/applications/dense_match_filling/zero_padding_app.py +11 -1
  16. cars/applications/dense_matching/census_mccnn_sgm_app.py +254 -548
  17. cars/applications/dense_matching/cpp/dense_matching_cpp.cp313-win_amd64.dll.a +0 -0
  18. cars/applications/dense_matching/cpp/dense_matching_cpp.cp313-win_amd64.pyd +0 -0
  19. cars/applications/dense_matching/dense_matching_algo.py +59 -11
  20. cars/applications/dense_matching/dense_matching_wrappers.py +51 -31
  21. cars/applications/dense_matching/disparity_grid_algo.py +566 -0
  22. cars/applications/dense_matching/loaders/config_mapping.json +13 -0
  23. cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
  24. cars/applications/dense_matching/loaders/pandora_loader.py +78 -1
  25. cars/applications/dsm_filling/border_interpolation_app.py +10 -5
  26. cars/applications/dsm_filling/bulldozer_filling_app.py +14 -7
  27. cars/applications/dsm_filling/exogenous_filling_app.py +10 -5
  28. cars/applications/grid_generation/grid_correction_app.py +0 -53
  29. cars/applications/grid_generation/transform_grid.py +5 -5
  30. cars/applications/point_cloud_fusion/pc_fusion_algo.py +17 -11
  31. cars/applications/point_cloud_fusion/pc_fusion_wrappers.py +3 -4
  32. cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +9 -5
  33. cars/applications/point_cloud_outlier_removal/small_components_app.py +5 -3
  34. cars/applications/point_cloud_outlier_removal/statistical_app.py +4 -2
  35. cars/applications/rasterization/abstract_pc_rasterization_app.py +1 -0
  36. cars/applications/rasterization/rasterization_algo.py +20 -27
  37. cars/applications/rasterization/rasterization_wrappers.py +6 -5
  38. cars/applications/rasterization/simple_gaussian_app.py +30 -17
  39. cars/applications/resampling/resampling_algo.py +44 -49
  40. cars/applications/sparse_matching/sift_app.py +2 -22
  41. cars/applications/sparse_matching/sparse_matching_wrappers.py +0 -49
  42. cars/applications/triangulation/line_of_sight_intersection_app.py +1 -1
  43. cars/applications/triangulation/triangulation_wrappers.py +2 -1
  44. cars/bundleadjustment.py +51 -11
  45. cars/cars.py +15 -5
  46. cars/core/constants.py +1 -1
  47. cars/core/geometry/abstract_geometry.py +166 -12
  48. cars/core/geometry/shareloc_geometry.py +61 -14
  49. cars/core/inputs.py +15 -0
  50. cars/core/projection.py +117 -0
  51. cars/data_structures/cars_dataset.py +7 -5
  52. cars/orchestrator/cluster/log_wrapper.py +1 -1
  53. cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +1 -1
  54. cars/orchestrator/orchestrator.py +1 -1
  55. cars/orchestrator/registry/saver_registry.py +0 -78
  56. cars/pipelines/default/default_pipeline.py +69 -52
  57. cars/pipelines/parameters/advanced_parameters.py +17 -0
  58. cars/pipelines/parameters/advanced_parameters_constants.py +4 -0
  59. cars/pipelines/parameters/depth_map_inputs.py +22 -67
  60. cars/pipelines/parameters/dsm_inputs.py +16 -29
  61. cars/pipelines/parameters/output_parameters.py +44 -8
  62. cars/pipelines/parameters/sensor_inputs.py +117 -24
  63. cars/pipelines/parameters/sensor_loaders/basic_sensor_loader.py +3 -3
  64. cars/pipelines/parameters/sensor_loaders/pivot_sensor_loader.py +2 -2
  65. cars/pipelines/parameters/sensor_loaders/sensor_loader.py +4 -6
  66. cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +2 -2
  67. cars/pipelines/pipeline.py +8 -8
  68. cars/pipelines/unit/unit_pipeline.py +276 -274
  69. cars/starter.py +20 -1
  70. cars-1.0.0a3.dist-info/DELVEWHEEL +2 -0
  71. {cars-1.0.0a1.dist-info → cars-1.0.0a3.dist-info}/METADATA +3 -2
  72. {cars-1.0.0a1.dist-info → cars-1.0.0a3.dist-info}/RECORD +77 -74
  73. cars.libs/libgcc_s_seh-1-ca70890bbc5723b6d0ea31e9c9cded2b.dll +0 -0
  74. cars.libs/libstdc++-6-00ee19f73d5122a1277c137b1c218401.dll +0 -0
  75. cars.libs/libwinpthread-1-f5042e8e3d21edce20c1bc99445f551b.dll +0 -0
  76. cars-1.0.0a1.dist-info/DELVEWHEEL +0 -2
  77. cars.libs/libgcc_s_seh-1-f2b6825d483bdf14050493af93b5997d.dll +0 -0
  78. cars.libs/libstdc++-6-6b0059df6bc601df5a0f18a5805eea05.dll +0 -0
  79. cars.libs/libwinpthread-1-e01b8e85fd67c2b861f64d4ccc7df607.dll +0 -0
  80. {cars-1.0.0a1.dist-info → cars-1.0.0a3.dist-info}/WHEEL +0 -0
  81. {cars-1.0.0a1.dist-info → cars-1.0.0a3.dist-info}/entry_points.txt +0 -0
@@ -37,15 +37,15 @@ from cars.pipelines.parameters import sensor_inputs as sens_inp
37
37
  from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
38
38
 
39
39
 
40
- def check_depth_maps_inputs(conf, config_json_dir=None):
40
+ def check_depth_maps_inputs(conf, config_dir=None):
41
41
  """
42
42
  Check the inputs given
43
43
 
44
44
  :param conf: configuration of inputs
45
45
  :type conf: dict
46
- :param config_json_dir: directory of used json, if
46
+ :param config_dir: directory of used json, if
47
47
  user filled paths with relative paths
48
- :type config_json_dir: str
48
+ :type config_dir: str
49
49
 
50
50
  :return: overloader inputs
51
51
  :rtype: dict
@@ -88,7 +88,7 @@ def check_depth_maps_inputs(conf, config_json_dir=None):
88
88
  cst.EPI_Z_INF: Or(str, None),
89
89
  cst.EPI_Z_SUP: Or(str, None),
90
90
  cst.POINT_CLOUD_CLASSIF_KEY_ROOT: Or(str, None),
91
- cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT: Or(dict, None),
91
+ cst.POINT_CLOUD_AMBIGUITY_KEY_ROOT: Or(str, None),
92
92
  cst.POINT_CLOUD_CLR_KEY_ROOT: str,
93
93
  cst.POINT_CLOUD_FILLING_KEY_ROOT: Or(str, None),
94
94
  cst.POINT_CLOUD_MSK: Or(str, None),
@@ -96,7 +96,6 @@ def check_depth_maps_inputs(conf, config_json_dir=None):
96
96
  cst.PC_EPSG: Or(str, int, None),
97
97
  }
98
98
  checker_pc = Checker(pc_schema)
99
- confidence_conf_ref = None
100
99
  for depth_map_key in conf[depth_map_cst.DEPTH_MAPS]:
101
100
  # Get depth maps with default
102
101
  overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key] = {}
@@ -144,43 +143,10 @@ def check_depth_maps_inputs(conf, config_json_dir=None):
144
143
  cst.POINT_CLOUD_FILLING_KEY_ROOT
145
144
  ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get("filling", None)
146
145
 
147
- confidence_conf = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get(
148
- "confidence", None
149
- )
150
- if confidence_conf:
151
- overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][
152
- cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT
153
- ] = {}
154
- if (
155
- confidence_conf_ref
156
- and confidence_conf.keys() != confidence_conf_ref
157
- ):
158
- raise KeyError(
159
- "The confidence keys are not the same: \n",
160
- confidence_conf.keys(),
161
- "\n",
162
- confidence_conf_ref,
163
- )
146
+ overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][
147
+ cst.POINT_CLOUD_AMBIGUITY_KEY_ROOT
148
+ ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get("ambiguity", None)
164
149
 
165
- confidence_conf_ref = confidence_conf.keys()
166
- for confidence_name in confidence_conf:
167
- output_confidence_name = confidence_name
168
- if (
169
- cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT
170
- not in output_confidence_name
171
- ):
172
- output_confidence_name = (
173
- cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT
174
- + "_"
175
- + output_confidence_name
176
- )
177
- overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][
178
- cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT
179
- ][output_confidence_name] = confidence_conf[confidence_name]
180
- else:
181
- overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][
182
- cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT
183
- ] = None
184
150
  overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][
185
151
  cst.PC_EPSG
186
152
  ] = conf[depth_map_cst.DEPTH_MAPS][depth_map_key].get("epsg", 4326)
@@ -190,8 +156,8 @@ def check_depth_maps_inputs(conf, config_json_dir=None):
190
156
  )
191
157
 
192
158
  # Modify to absolute path
193
- if config_json_dir is not None:
194
- modify_to_absolute_path(config_json_dir, overloaded_conf)
159
+ if config_dir is not None:
160
+ modify_to_absolute_path(config_dir, overloaded_conf)
195
161
  else:
196
162
  logging.debug(
197
163
  "path of config file was not given,"
@@ -217,7 +183,7 @@ def check_depth_maps_inputs(conf, config_json_dir=None):
217
183
  cst.POINT_CLOUD_FILLING_KEY_ROOT
218
184
  ],
219
185
  overloaded_conf[depth_map_cst.DEPTH_MAPS][depth_map_key][
220
- cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT
186
+ cst.POINT_CLOUD_AMBIGUITY_KEY_ROOT
221
187
  ],
222
188
  )
223
189
 
@@ -227,7 +193,7 @@ def check_depth_maps_inputs(conf, config_json_dir=None):
227
193
  )
228
194
 
229
195
  if sens_cst.SENSORS in conf and conf[sens_cst.SENSORS] is not None:
230
- sens_inp.check_sensors(conf, overloaded_conf, config_json_dir)
196
+ sens_inp.check_sensors(conf, overloaded_conf, config_dir)
231
197
 
232
198
  return overloaded_conf
233
199
 
@@ -264,10 +230,10 @@ def check_geometry_plugin(conf_inputs, conf_geom_plugin):
264
230
 
265
231
 
266
232
  def check_input_size(
267
- x_path, y_path, z_path, mask, color, classif, filling, confidence
233
+ x_path, y_path, z_path, mask, color, classif, filling, ambiguity
268
234
  ):
269
235
  """
270
- Check x, y, z, mask, color, classif and confidence given
236
+ Check x, y, z, mask, color, classif and ambiguity given
271
237
 
272
238
  Images must have same size
273
239
 
@@ -285,15 +251,15 @@ def check_input_size(
285
251
  :type classif: str
286
252
  :param filling: filling path
287
253
  :type filling: str
288
- :param confidence: confidence dict path
289
- :type confidence: dict[str]
254
+ :param ambiguity: ambiguity path
255
+ :type ambiguity: str
290
256
  """
291
257
 
292
258
  for path in [x_path, y_path, z_path]:
293
259
  if inputs.rasterio_get_nb_bands(path) != 1:
294
260
  raise RuntimeError("{} is not mono-band image".format(path))
295
261
 
296
- for path in [mask, color, classif, filling]:
262
+ for path in [mask, color, classif, filling, ambiguity]:
297
263
  if path is not None:
298
264
  if inputs.rasterio_get_size(x_path) != inputs.rasterio_get_size(
299
265
  path
@@ -302,25 +268,14 @@ def check_input_size(
302
268
  "The image {} and {} "
303
269
  "do not have the same size".format(x_path, path)
304
270
  )
305
- if confidence:
306
- for key in confidence:
307
- path = confidence[key]
308
- if path is not None:
309
- if inputs.rasterio_get_size(x_path) != inputs.rasterio_get_size(
310
- path
311
- ):
312
- raise RuntimeError(
313
- "The image {} and {} "
314
- "do not have the same size".format(x_path, path)
315
- )
316
271
 
317
272
 
318
- def modify_to_absolute_path(config_json_dir, overloaded_conf):
273
+ def modify_to_absolute_path(config_dir, overloaded_conf):
319
274
  """
320
275
  Modify input file path to absolute path
321
276
 
322
- :param config_json_dir: directory of the json configuration
323
- :type config_json_dir: str
277
+ :param config_dir: directory of the json/yaml configuration
278
+ :type config_dir: str
324
279
  :param overloaded_conf: overloaded configuration json
325
280
  :dict overloaded_conf: dict
326
281
  """
@@ -339,7 +294,7 @@ def modify_to_absolute_path(config_json_dir, overloaded_conf):
339
294
  if tag != cst.POINT_CLOUD_CONFIDENCE_KEY_ROOT:
340
295
  if depth_map[tag] is not None:
341
296
  depth_map[tag] = make_relative_path_absolute(
342
- depth_map[tag], config_json_dir
297
+ depth_map[tag], config_dir
343
298
  )
344
299
  else:
345
300
  if depth_map[tag] is not None:
@@ -348,12 +303,12 @@ def modify_to_absolute_path(config_json_dir, overloaded_conf):
348
303
  depth_map[tag][confidence_name] = (
349
304
  make_relative_path_absolute(
350
305
  depth_map[tag][confidence_name],
351
- config_json_dir,
306
+ config_dir,
352
307
  )
353
308
  )
354
309
 
355
310
  if overloaded_conf[sens_cst.ROI] is not None:
356
311
  if isinstance(overloaded_conf[sens_cst.ROI], str):
357
312
  overloaded_conf[sens_cst.ROI] = make_relative_path_absolute(
358
- overloaded_conf[sens_cst.ROI], config_json_dir
313
+ overloaded_conf[sens_cst.ROI], config_dir
359
314
  )
@@ -48,15 +48,15 @@ from cars.pipelines.parameters import sensor_inputs as sens_inp
48
48
  from cars.pipelines.parameters import sensor_inputs_constants as sens_cst
49
49
 
50
50
 
51
- def check_dsm_inputs(conf, config_json_dir=None):
51
+ def check_dsm_inputs(conf, config_dir=None):
52
52
  """
53
53
  Check the inputs given
54
54
 
55
55
  :param conf: configuration of inputs
56
56
  :type conf: dict
57
- :param config_json_dir: directory of used json, if
57
+ :param config_dir: directory of used json/yaml, if
58
58
  user filled paths with relative paths
59
- :type config_json_dir: str
59
+ :type config_dir: str
60
60
 
61
61
  :return: overloader inputs
62
62
  :rtype: dict
@@ -108,7 +108,7 @@ def check_dsm_inputs(conf, config_json_dir=None):
108
108
  cst.DSM_INF_STD: Or(str, None),
109
109
  cst.DSM_SUP_MEAN: Or(str, None),
110
110
  cst.DSM_SUP_STD: Or(str, None),
111
- cst.DSM_CONFIDENCE: Or(dict, None),
111
+ cst.DSM_AMBIGUITY: Or(str, None),
112
112
  cst.DSM_PERFORMANCE_MAP: Or(str, None),
113
113
  cst.DSM_SOURCE_PC: Or(str, None),
114
114
  cst.DSM_FILLING: Or(str, None),
@@ -164,9 +164,9 @@ def check_dsm_inputs(conf, config_json_dir=None):
164
164
  overloaded_conf[dsm_cst.DSMS][dsm_key][cst.DSM_SUP_STD] = conf[
165
165
  dsm_cst.DSMS
166
166
  ][dsm_key].get("dsm_sup_std", None)
167
- overloaded_conf[dsm_cst.DSMS][dsm_key][cst.DSM_CONFIDENCE] = conf[
167
+ overloaded_conf[dsm_cst.DSMS][dsm_key][cst.DSM_AMBIGUITY] = conf[
168
168
  dsm_cst.DSMS
169
- ][dsm_key].get("confidence", None)
169
+ ][dsm_key].get("ambiguity", None)
170
170
  overloaded_conf[dsm_cst.DSMS][dsm_key][cst.DSM_PERFORMANCE_MAP] = conf[
171
171
  dsm_cst.DSMS
172
172
  ][dsm_key].get("performance_map", None)
@@ -181,8 +181,8 @@ def check_dsm_inputs(conf, config_json_dir=None):
181
181
  checker_pc.validate(overloaded_conf[dsm_cst.DSMS][dsm_key])
182
182
 
183
183
  # Modify to absolute path
184
- if config_json_dir is not None:
185
- modify_to_absolute_path(config_json_dir, overloaded_conf)
184
+ if config_dir is not None:
185
+ modify_to_absolute_path(config_dir, overloaded_conf)
186
186
  else:
187
187
  logging.debug(
188
188
  "path of config file was not given,"
@@ -200,14 +200,6 @@ def check_dsm_inputs(conf, config_json_dir=None):
200
200
  overloaded_conf[dsm_cst.DSMS][dsm_key][cst.INDEX_DSM_MASK],
201
201
  )
202
202
 
203
- if cst.DSM_CONFIDENCE in conf[dsm_cst.DSMS][dsm_key]:
204
- if conf[dsm_cst.DSMS][dsm_key][cst.DSM_CONFIDENCE] is not None:
205
- for _, conf_value in conf[dsm_cst.DSMS][dsm_key][
206
- cst.DSM_CONFIDENCE
207
- ].items():
208
- if not os.path.exists(conf_value):
209
- raise RuntimeError("The path doesn't exist")
210
-
211
203
  # Check srtm dir
212
204
  sens_inp.check_srtm(
213
205
  overloaded_conf[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH]
@@ -216,7 +208,7 @@ def check_dsm_inputs(conf, config_json_dir=None):
216
208
  check_phasing(conf[dsm_cst.DSMS])
217
209
 
218
210
  if sens_cst.SENSORS in conf and conf[sens_cst.SENSORS] is not None:
219
- sens_inp.check_sensors(conf, overloaded_conf, config_json_dir)
211
+ sens_inp.check_sensors(conf, overloaded_conf, config_dir)
220
212
 
221
213
  return overloaded_conf
222
214
 
@@ -249,12 +241,12 @@ def check_input_size(dsm, classif, color, mask):
249
241
  )
250
242
 
251
243
 
252
- def modify_to_absolute_path(config_json_dir, overloaded_conf):
244
+ def modify_to_absolute_path(config_dir, overloaded_conf):
253
245
  """
254
246
  Modify input file path to absolute path
255
247
 
256
- :param config_json_dir: directory of the json configuration
257
- :type config_json_dir: str
248
+ :param config_dir: directory of the json configuration
249
+ :type config_dir: str
258
250
  :param overloaded_conf: overloaded configuration json
259
251
  :dict overloaded_conf: dict
260
252
  """
@@ -267,14 +259,12 @@ def modify_to_absolute_path(config_json_dir, overloaded_conf):
267
259
  cst.INDEX_DSM_MASK,
268
260
  ]:
269
261
  if dsms[tag] is not None:
270
- dsms[tag] = make_relative_path_absolute(
271
- dsms[tag], config_json_dir
272
- )
262
+ dsms[tag] = make_relative_path_absolute(dsms[tag], config_dir)
273
263
 
274
264
  if overloaded_conf[sens_cst.ROI] is not None:
275
265
  if isinstance(overloaded_conf[sens_cst.ROI], str):
276
266
  overloaded_conf[sens_cst.ROI] = make_relative_path_absolute(
277
- overloaded_conf[sens_cst.ROI], config_json_dir
267
+ overloaded_conf[sens_cst.ROI], config_dir
278
268
  )
279
269
 
280
270
 
@@ -505,11 +495,8 @@ def merge_dsm_infos( # noqa: C901 function is too complex
505
495
  and performance_map_file_name is not None
506
496
  ):
507
497
  out_file_name = performance_map_file_name
508
- elif (
509
- cst.DSM_CONFIDENCE_AMBIGUITY in key
510
- and ambiguity_file_name is not None
511
- ):
512
- out_file_name = os.path.join(ambiguity_file_name, key + ".tif")
498
+ elif key == cst.DSM_AMBIGUITY and ambiguity_file_name is not None:
499
+ out_file_name = ambiguity_file_name
513
500
  elif (
514
501
  key == cst.DSM_SOURCE_PC and contributing_pair_file_name is not None
515
502
  ):
@@ -26,7 +26,7 @@ This module contains the output definition
26
26
  import logging
27
27
  import os
28
28
 
29
- from json_checker import Checker, Or
29
+ from json_checker import And, Checker, Or
30
30
  from pyproj import CRS
31
31
 
32
32
  import cars.core.constants as cst
@@ -34,12 +34,29 @@ from cars.core.utils import safe_makedirs
34
34
  from cars.pipelines.parameters import output_constants
35
35
 
36
36
 
37
- def check_output_parameters(conf):
37
+ def is_valid_epsg(epsg) -> bool:
38
+ """
39
+ Check if the given EPSG code is valid using pyproj.
40
+ """
41
+ if epsg is None:
42
+ return True
43
+
44
+ try:
45
+ # Try creating a CRS
46
+ CRS(f"EPSG:{epsg}")
47
+ return True
48
+ except Exception:
49
+ return False
50
+
51
+
52
+ def check_output_parameters(conf, scaling_coeff):
38
53
  """
39
54
  Check the output json configuration and fill in default values
40
55
 
41
56
  :param conf: configuration of output
42
57
  :type conf: dict
58
+ :param scaling_coeff: scaling factor for resolution
59
+ :type scaling_coeff: float
43
60
  :param pipeline_name: name of corresponding pipeline
44
61
  :type pipeline_name: str
45
62
  """
@@ -64,15 +81,34 @@ def check_output_parameters(conf):
64
81
  raise RuntimeError("Unknown product level {}".format(level))
65
82
 
66
83
  overloaded_conf[output_constants.OUT_GEOID] = overloaded_conf.get(
67
- output_constants.OUT_GEOID, False
84
+ output_constants.OUT_GEOID, True
68
85
  )
69
86
  overloaded_conf[output_constants.EPSG] = overloaded_conf.get(
70
87
  output_constants.EPSG, None
71
88
  )
72
89
 
73
- overloaded_conf[output_constants.RESOLUTION] = overloaded_conf.get(
74
- output_constants.RESOLUTION, 0.5
75
- )
90
+ resolution = None
91
+ overloaded_scaling_coeff = scaling_coeff
92
+ if output_constants.RESOLUTION in overloaded_conf:
93
+ resolution = overloaded_conf[output_constants.RESOLUTION]
94
+ # update scaling coeff so the parameters are right for the dsm
95
+ # overloaded_scaling_coeff = 2*resolution
96
+
97
+ if resolution < 0.5 * scaling_coeff:
98
+ logging.warning(
99
+ "The requested DSM resolution of "
100
+ f"{overloaded_conf[output_constants.RESOLUTION]} seems "
101
+ "too low for the sensor images' resolution. "
102
+ "The pipeline will still continue with it."
103
+ )
104
+
105
+ else:
106
+ resolution = float(0.5 * scaling_coeff)
107
+ logging.warning(
108
+ "The resolution of the output DSM will be " f"{resolution} meters. "
109
+ )
110
+
111
+ overloaded_conf[output_constants.RESOLUTION] = resolution
76
112
 
77
113
  overloaded_conf[output_constants.SAVE_BY_PAIR] = overloaded_conf.get(
78
114
  output_constants.SAVE_BY_PAIR, False
@@ -145,7 +181,7 @@ def check_output_parameters(conf):
145
181
  output_constants.OUT_DIRECTORY: str,
146
182
  output_constants.PRODUCT_LEVEL: list,
147
183
  output_constants.OUT_GEOID: Or(bool, str),
148
- output_constants.EPSG: Or(int, None),
184
+ output_constants.EPSG: And(Or(int, str, None), is_valid_epsg),
149
185
  output_constants.RESOLUTION: Or(int, float),
150
186
  output_constants.SAVE_BY_PAIR: bool,
151
187
  output_constants.AUXILIARY: dict,
@@ -181,7 +217,7 @@ def check_output_parameters(conf):
181
217
  + "fixed according to the epsg"
182
218
  )
183
219
 
184
- return overloaded_conf
220
+ return overloaded_conf, overloaded_scaling_coeff
185
221
 
186
222
 
187
223
  def intialize_product_index(orchestrator, product_levels, input_pairs):