cars 1.0.0a1__cp311-cp311-win_amd64.whl → 1.0.0a3__cp311-cp311-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.cp311-win_amd64.dll.a +0 -0
  12. cars/applications/dense_match_filling/cpp/dense_match_filling_cpp.cp311-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.cp311-win_amd64.dll.a +0 -0
  18. cars/applications/dense_matching/cpp/dense_matching_cpp.cp311-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
@@ -36,6 +36,7 @@ import math
36
36
  import os
37
37
 
38
38
  import numpy as np
39
+ from pyproj import CRS
39
40
 
40
41
  import cars.applications.sparse_matching.sparse_matching_constants as sm_cst
41
42
  from cars import __version__
@@ -56,6 +57,7 @@ from cars.core import preprocessing, projection, roi_tools
56
57
  from cars.core.geometry.abstract_geometry import AbstractGeometry
57
58
  from cars.core.inputs import (
58
59
  get_descriptions_bands,
60
+ rasterio_get_crs,
59
61
  rasterio_get_epsg,
60
62
  rasterio_get_size,
61
63
  read_vector,
@@ -94,7 +96,7 @@ class UnitPipeline(PipelineTemplate):
94
96
 
95
97
  # pylint: disable=too-many-instance-attributes
96
98
 
97
- def __init__(self, conf, config_json_dir=None):
99
+ def __init__(self, conf, config_dir=None): # noqa: C901
98
100
  """
99
101
  Creates pipeline
100
102
 
@@ -113,13 +115,17 @@ class UnitPipeline(PipelineTemplate):
113
115
  :type pipeline_name: str
114
116
  :param cfg: configuration {'matching_cost_method': value}
115
117
  :type cfg: dictionary
116
- :param config_json_dir: path to dir containing json
117
- :type config_json_dir: str
118
+ :param config_dir: path to dir containing json/yaml
119
+ :type config_dir: str
118
120
  """
119
121
 
120
122
  # Used conf
121
123
  self.used_conf = {}
122
124
 
125
+ # Transform relative path to absolute path
126
+ if config_dir is not None:
127
+ config_dir = os.path.abspath(config_dir)
128
+
123
129
  # Check global conf
124
130
  self.check_global_schema(conf)
125
131
 
@@ -129,9 +135,7 @@ class UnitPipeline(PipelineTemplate):
129
135
  )
130
136
 
131
137
  # Check conf inputs
132
- inputs = self.check_inputs(
133
- conf[INPUTS], config_json_dir=config_json_dir
134
- )
138
+ inputs = self.check_inputs(conf[INPUTS], config_dir=config_dir)
135
139
  self.used_conf[INPUTS] = inputs
136
140
 
137
141
  # Check advanced parameters
@@ -143,6 +147,9 @@ class UnitPipeline(PipelineTemplate):
143
147
  self.geom_plugin_without_dem_and_geoid,
144
148
  self.geom_plugin_with_dem_and_geoid,
145
149
  self.dem_generation_roi,
150
+ self.scaling_coeff,
151
+ self.land_cover_map,
152
+ self.classification_to_config_mapping,
146
153
  ) = advanced_parameters.check_advanced_parameters(
147
154
  inputs, conf.get(ADVANCED, {}), check_epipolar_a_priori=True
148
155
  )
@@ -159,7 +166,11 @@ class UnitPipeline(PipelineTemplate):
159
166
  self.debug_with_roi = self.used_conf[ADVANCED][adv_cst.DEBUG_WITH_ROI]
160
167
 
161
168
  # Check conf output
162
- output = self.check_output(conf[OUTPUT])
169
+ (
170
+ output,
171
+ self.scaling_coeff,
172
+ ) = self.check_output(conf[OUTPUT], self.scaling_coeff)
173
+
163
174
  self.used_conf[OUTPUT] = output
164
175
 
165
176
  prod_level = output[out_cst.PRODUCT_LEVEL]
@@ -419,15 +430,15 @@ class UnitPipeline(PipelineTemplate):
419
430
  logging.warning(log_msg)
420
431
 
421
432
  @staticmethod
422
- def check_inputs(conf, config_json_dir=None):
433
+ def check_inputs(conf, config_dir=None):
423
434
  """
424
435
  Check the inputs given
425
436
 
426
437
  :param conf: configuration of inputs
427
438
  :type conf: dict
428
- :param config_json_dir: directory of used json, if
439
+ :param config_dir: directory of used json/yaml, if
429
440
  user filled paths with relative paths
430
- :type config_json_dir: str
441
+ :type config_dir: str
431
442
 
432
443
  :return: overloaded inputs
433
444
  :rtype: dict
@@ -440,36 +451,35 @@ class UnitPipeline(PipelineTemplate):
440
451
  and dsm_cst.DSMS not in conf
441
452
  ):
442
453
  output_config = sensor_inputs.sensors_check_inputs(
443
- conf, config_json_dir=config_json_dir
454
+ conf, config_dir=config_dir
444
455
  )
445
456
  elif depth_cst.DEPTH_MAPS in conf:
446
457
  output_config = {
447
458
  **output_config,
448
459
  **depth_map_inputs.check_depth_maps_inputs(
449
- conf, config_json_dir=config_json_dir
460
+ conf, config_dir=config_dir
450
461
  ),
451
462
  }
452
463
  else:
453
464
  output_config = {
454
465
  **output_config,
455
- **dsm_inputs.check_dsm_inputs(
456
- conf, config_json_dir=config_json_dir
457
- ),
466
+ **dsm_inputs.check_dsm_inputs(conf, config_dir=config_dir),
458
467
  }
459
468
  return output_config
460
469
 
461
470
  @staticmethod
462
- def check_output(conf):
471
+ def check_output(conf, scaling_coeff):
463
472
  """
464
473
  Check the output given
465
474
 
466
475
  :param conf: configuration of output
467
476
  :type conf: dict
468
-
469
- :return overloader output
470
- :rtype : dict
477
+ :param scaling_coeff: scaling factor for resolution
478
+ :type scaling_coeff: float
479
+ :return: overloader output
480
+ :rtype: dict
471
481
  """
472
- return output_parameters.check_output_parameters(conf)
482
+ return output_parameters.check_output_parameters(conf, scaling_coeff)
473
483
 
474
484
  def check_applications( # noqa: C901 : too complex
475
485
  self,
@@ -483,6 +493,7 @@ class UnitPipeline(PipelineTemplate):
483
493
  :param conf: configuration of applications
484
494
  :type conf: dict
485
495
  """
496
+ scaling_coeff = self.scaling_coeff
486
497
 
487
498
  # Check if all specified applications are used
488
499
  # Application in terrain_application are note used in
@@ -580,7 +591,9 @@ class UnitPipeline(PipelineTemplate):
580
591
  if self.sensors_in_inputs:
581
592
  # Epipolar grid generation
582
593
  self.epipolar_grid_generation_application = Application(
583
- "grid_generation", cfg=used_conf.get("grid_generation", {})
594
+ "grid_generation",
595
+ cfg=used_conf.get("grid_generation", {}),
596
+ scaling_coeff=scaling_coeff,
584
597
  )
585
598
  used_conf["grid_generation"] = (
586
599
  self.epipolar_grid_generation_application.get_conf()
@@ -588,7 +601,9 @@ class UnitPipeline(PipelineTemplate):
588
601
 
589
602
  # image resampling
590
603
  self.resampling_application = Application(
591
- "resampling", cfg=used_conf.get("resampling", {})
604
+ "resampling",
605
+ cfg=used_conf.get("resampling", {}),
606
+ scaling_coeff=scaling_coeff,
592
607
  )
593
608
  used_conf["resampling"] = self.resampling_application.get_conf()
594
609
 
@@ -610,10 +625,13 @@ class UnitPipeline(PipelineTemplate):
610
625
  self.ground_truth_reprojection = Application(
611
626
  "ground_truth_reprojection",
612
627
  cfg=used_conf.get("ground_truth_reprojection", {}),
628
+ scaling_coeff=scaling_coeff,
613
629
  )
614
630
  # holes detection
615
631
  self.hole_detection_app = Application(
616
- "hole_detection", cfg=used_conf.get("hole_detection", {})
632
+ "hole_detection",
633
+ cfg=used_conf.get("hole_detection", {}),
634
+ scaling_coeff=scaling_coeff,
617
635
  )
618
636
  used_conf["hole_detection"] = self.hole_detection_app.get_conf()
619
637
 
@@ -624,6 +642,7 @@ class UnitPipeline(PipelineTemplate):
624
642
  "dense_match_filling.1",
625
643
  {"method": "plane"},
626
644
  ),
645
+ scaling_coeff=scaling_coeff,
627
646
  )
628
647
  used_conf["dense_match_filling.1"] = (
629
648
  self.dense_match_filling_1.get_conf()
@@ -636,6 +655,7 @@ class UnitPipeline(PipelineTemplate):
636
655
  "dense_match_filling.2",
637
656
  {"method": "zero_padding"},
638
657
  ),
658
+ scaling_coeff=scaling_coeff,
639
659
  )
640
660
  used_conf["dense_match_filling.2"] = (
641
661
  self.dense_match_filling_2.get_conf()
@@ -645,6 +665,7 @@ class UnitPipeline(PipelineTemplate):
645
665
  self.sparse_mtch_sift_app = Application(
646
666
  "sparse_matching",
647
667
  cfg=used_conf.get("sparse_matching.sift", {"method": "sift"}),
668
+ scaling_coeff=scaling_coeff,
648
669
  )
649
670
  used_conf["sparse_matching.sift"] = (
650
671
  self.sparse_mtch_sift_app.get_conf()
@@ -672,13 +693,17 @@ class UnitPipeline(PipelineTemplate):
672
693
  ):
673
694
  dense_matching_config["performance_map_method"] = "risk"
674
695
  self.dense_matching_app = Application(
675
- "dense_matching", cfg=dense_matching_config
696
+ "dense_matching",
697
+ cfg=dense_matching_config,
698
+ scaling_coeff=scaling_coeff,
676
699
  )
677
700
  used_conf["dense_matching"] = self.dense_matching_app.get_conf()
678
701
 
679
702
  # Triangulation
680
703
  self.triangulation_application = Application(
681
- "triangulation", cfg=used_conf.get("triangulation", {})
704
+ "triangulation",
705
+ cfg=used_conf.get("triangulation", {}),
706
+ scaling_coeff=scaling_coeff,
682
707
  )
683
708
  used_conf["triangulation"] = (
684
709
  self.triangulation_application.get_conf()
@@ -686,7 +711,9 @@ class UnitPipeline(PipelineTemplate):
686
711
 
687
712
  # MNT generation
688
713
  self.dem_generation_application = Application(
689
- "dem_generation", cfg=used_conf.get("dem_generation", {})
714
+ "dem_generation",
715
+ cfg=used_conf.get("dem_generation", {}),
716
+ scaling_coeff=scaling_coeff,
690
717
  )
691
718
  used_conf["dem_generation"] = (
692
719
  self.dem_generation_application.get_conf()
@@ -704,6 +731,7 @@ class UnitPipeline(PipelineTemplate):
704
731
  "point_cloud_outlier_removal.1",
705
732
  {"method": "small_components"},
706
733
  ),
734
+ scaling_coeff=scaling_coeff,
707
735
  )
708
736
  used_conf["point_cloud_outlier_removal.1"] = (
709
737
  self.pc_outlier_removal_1_app.get_conf()
@@ -716,6 +744,7 @@ class UnitPipeline(PipelineTemplate):
716
744
  "point_cloud_outlier_removal.2",
717
745
  {"method": "statistical"},
718
746
  ),
747
+ scaling_coeff=scaling_coeff,
719
748
  )
720
749
  used_conf["point_cloud_outlier_removal.2"] = (
721
750
  self.pc_outlier_removal_2_app.get_conf()
@@ -727,6 +756,7 @@ class UnitPipeline(PipelineTemplate):
727
756
  self.pc_denoising_application = Application(
728
757
  "pc_denoising",
729
758
  cfg=used_conf.get("pc_denoising", {"method": "none"}),
759
+ scaling_coeff=scaling_coeff,
730
760
  )
731
761
  used_conf["pc_denoising"] = self.pc_denoising_application.get_conf()
732
762
 
@@ -736,6 +766,7 @@ class UnitPipeline(PipelineTemplate):
736
766
  self.rasterization_application = Application(
737
767
  "point_cloud_rasterization",
738
768
  cfg=used_conf.get("point_cloud_rasterization", {}),
769
+ scaling_coeff=scaling_coeff,
739
770
  )
740
771
  used_conf["point_cloud_rasterization"] = (
741
772
  self.rasterization_application.get_conf()
@@ -747,6 +778,7 @@ class UnitPipeline(PipelineTemplate):
747
778
  "dsm_filling.1",
748
779
  {"method": "exogenous_filling"},
749
780
  ),
781
+ scaling_coeff=scaling_coeff,
750
782
  )
751
783
  used_conf["dsm_filling.1"] = (
752
784
  self.dsm_filling_1_application.get_conf()
@@ -769,22 +801,25 @@ class UnitPipeline(PipelineTemplate):
769
801
  "dsm_filling.3",
770
802
  {"method": "border_interpolation"},
771
803
  ),
804
+ scaling_coeff=scaling_coeff,
772
805
  )
773
806
  used_conf["dsm_filling.3"] = (
774
807
  self.dsm_filling_3_application.get_conf()
775
808
  )
776
809
  # Auxiliary filling
777
810
  self.auxiliary_filling_application = Application(
778
- "auxiliary_filling", cfg=conf.get("auxiliary_filling", {})
811
+ "auxiliary_filling",
812
+ cfg=conf.get("auxiliary_filling", {}),
813
+ scaling_coeff=scaling_coeff,
779
814
  )
780
815
  used_conf["auxiliary_filling"] = (
781
816
  self.auxiliary_filling_application.get_conf()
782
817
  )
783
818
 
784
819
  if (
785
- self.dsm_filling_1_application.classification
786
- or self.dsm_filling_2_application.classification
787
- or self.dsm_filling_3_application.classification
820
+ self.dsm_filling_1_application.classification != ["nodata"]
821
+ or self.dsm_filling_2_application.classification != ["nodata"]
822
+ or self.dsm_filling_3_application.classification != ["nodata"]
788
823
  ):
789
824
  self.save_output_classif_for_filling = True
790
825
 
@@ -794,6 +829,7 @@ class UnitPipeline(PipelineTemplate):
794
829
  self.pc_fusion_application = Application(
795
830
  "point_cloud_fusion",
796
831
  cfg=used_conf.get("point_cloud_fusion", {}),
832
+ scaling_coeff=scaling_coeff,
797
833
  )
798
834
  used_conf["point_cloud_fusion"] = (
799
835
  self.pc_fusion_application.get_conf()
@@ -914,7 +950,7 @@ class UnitPipeline(PipelineTemplate):
914
950
  ]
915
951
  if (
916
952
  "classification" in inputs_conf["sensors"][key2]
917
- and inputs_conf["sensors"][key1]["classification"] is not None
953
+ and inputs_conf["sensors"][key2]["classification"] is not None
918
954
  ):
919
955
  classif_right = inputs_conf["sensors"][key2]["classification"][
920
956
  "main_file"
@@ -1156,6 +1192,10 @@ class UnitPipeline(PipelineTemplate):
1156
1192
  # Run cluster breakpoint to compute sifts: force computation
1157
1193
  self.cars_orchestrator.breakpoint()
1158
1194
 
1195
+ minimum_nb_matches = (
1196
+ self.sparse_mtch_sift_app.get_minimum_nb_matches()
1197
+ )
1198
+
1159
1199
  # Run grid correction application
1160
1200
  if self.used_conf[ADVANCED][adv_cst.USE_EPIPOLAR_A_PRIORI] is False:
1161
1201
  # Estimate grid correction if no epipolar a priori
@@ -1177,23 +1217,15 @@ class UnitPipeline(PipelineTemplate):
1177
1217
  )
1178
1218
  )
1179
1219
 
1180
- minimum_nb_matches = (
1181
- self.sparse_mtch_sift_app.get_minimum_nb_matches()
1182
- )
1183
-
1184
1220
  # Compute grid correction
1185
1221
  (
1186
1222
  self.pairs[pair_key]["grid_correction_coef"],
1187
1223
  self.pairs[pair_key]["corrected_matches_array"],
1188
- self.pairs[pair_key]["corrected_matches_cars_ds"],
1189
1224
  _,
1190
1225
  _,
1191
1226
  ) = grid_correction_app.estimate_right_grid_correction(
1192
1227
  self.pairs[pair_key]["matches_array"],
1193
1228
  self.pairs[pair_key]["grid_right"],
1194
- initial_cars_ds=self.pairs[pair_key][
1195
- "epipolar_matches_left"
1196
- ],
1197
1229
  save_matches=save_matches,
1198
1230
  minimum_nb_matches=minimum_nb_matches,
1199
1231
  pair_folder=os.path.join(
@@ -1255,6 +1287,19 @@ class UnitPipeline(PipelineTemplate):
1255
1287
  "Global disparity interval with margin : "
1256
1288
  f"[{disp_min:.2f} pix, {disp_max:.2f} pix]"
1257
1289
  )
1290
+ else:
1291
+ disp_min = (
1292
+ -self.sparse_mtch_sift_app.elevation_delta_upper_bound
1293
+ / disp_to_alt_ratio
1294
+ )
1295
+ disp_max = (
1296
+ -self.sparse_mtch_sift_app.elevation_delta_lower_bound
1297
+ / disp_to_alt_ratio
1298
+ )
1299
+ logging.info(
1300
+ "Global disparity interval : "
1301
+ f"[{disp_min:.2f} pix, {disp_max:.2f} pix]"
1302
+ )
1258
1303
 
1259
1304
  if self.epsg is None:
1260
1305
  # compute epsg
@@ -1293,7 +1338,6 @@ class UnitPipeline(PipelineTemplate):
1293
1338
  or self.quit_on_app("resampling")
1294
1339
  or self.quit_on_app("hole_detection")
1295
1340
  or self.quit_on_app("sparse_matching.sift")
1296
- or self.quit_on_app("sparse_matching.pandora")
1297
1341
  ):
1298
1342
  return True
1299
1343
 
@@ -1356,13 +1400,12 @@ class UnitPipeline(PipelineTemplate):
1356
1400
  pair_name for pair_name, _, _ in self.list_sensor_pairs
1357
1401
  ]
1358
1402
 
1359
- for cloud_id, (pair_key, _, _) in enumerate(self.list_sensor_pairs):
1403
+ for _, (pair_key, _, _) in enumerate(self.list_sensor_pairs):
1360
1404
  # Geometry plugin with dem will be used for the grid generation
1361
1405
  geom_plugin = self.geom_plugin_with_dem_and_geoid
1362
1406
 
1363
1407
  if self.used_conf[ADVANCED][adv_cst.USE_EPIPOLAR_A_PRIORI] is False:
1364
- if self.which_resolution in ("first", "single"):
1365
- save_matches = True
1408
+ save_matches = True
1366
1409
 
1367
1410
  (
1368
1411
  self.pairs[pair_key]["sensor_matches_left"],
@@ -1376,97 +1419,6 @@ class UnitPipeline(PipelineTemplate):
1376
1419
  ),
1377
1420
  save_matches=save_matches,
1378
1421
  )
1379
-
1380
- # saved used
1381
-
1382
- if (
1383
- inputs[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH]
1384
- is None
1385
- # cover the case where the geom plugin doesn't use init elev
1386
- or (
1387
- inputs[sens_cst.INITIAL_ELEVATION][sens_cst.DEM_PATH]
1388
- != geom_plugin.dem
1389
- )
1390
- ):
1391
- # Generate grids with new MNT
1392
- (
1393
- self.pairs[pair_key]["new_grid_left"],
1394
- self.pairs[pair_key]["new_grid_right"],
1395
- ) = self.epipolar_grid_generation_application.run(
1396
- self.pairs[pair_key]["sensor_image_left"],
1397
- self.pairs[pair_key]["sensor_image_right"],
1398
- geom_plugin,
1399
- orchestrator=self.cars_orchestrator,
1400
- pair_folder=os.path.join(
1401
- self.dump_dir,
1402
- "epipolar_grid_generation",
1403
- "new_mnt",
1404
- pair_key,
1405
- ),
1406
- pair_key=pair_key,
1407
- )
1408
-
1409
- # Correct grids with former matches
1410
- # Transform matches to new grids
1411
-
1412
- save_matches = self.sparse_mtch_sift_app.get_save_matches()
1413
-
1414
- new_grid_matches_array = (
1415
- geom_plugin.transform_matches_from_grids(
1416
- self.pairs[pair_key]["sensor_matches_left"],
1417
- self.pairs[pair_key]["sensor_matches_right"],
1418
- self.pairs[pair_key]["new_grid_left"],
1419
- self.pairs[pair_key]["new_grid_right"],
1420
- )
1421
- )
1422
-
1423
- # Estimate grid_correction
1424
- (
1425
- self.pairs[pair_key]["grid_correction_coef"],
1426
- self.pairs[pair_key]["corrected_matches_array"],
1427
- self.pairs[pair_key]["corrected_matches_cars_ds"],
1428
- _,
1429
- _,
1430
- ) = grid_correction_app.estimate_right_grid_correction(
1431
- new_grid_matches_array,
1432
- self.pairs[pair_key]["new_grid_right"],
1433
- save_matches=save_matches,
1434
- minimum_nb_matches=minimum_nb_matches,
1435
- initial_cars_ds=self.pairs[pair_key][
1436
- "epipolar_matches_left"
1437
- ],
1438
- pair_folder=os.path.join(
1439
- self.dump_dir, "grid_correction", "new", pair_key
1440
- ),
1441
- pair_key=pair_key,
1442
- orchestrator=self.cars_orchestrator,
1443
- )
1444
-
1445
- # Correct grid right
1446
-
1447
- self.pairs[pair_key]["corrected_grid_right"] = (
1448
- grid_correction_app.correct_grid(
1449
- self.pairs[pair_key]["new_grid_right"],
1450
- self.pairs[pair_key]["grid_correction_coef"],
1451
- os.path.join(
1452
- self.dump_dir,
1453
- "grid_correction",
1454
- "new",
1455
- pair_key,
1456
- ),
1457
- save_corrected_grid,
1458
- )
1459
- )
1460
-
1461
- # Use the new grid as uncorrected grid
1462
- self.pairs[pair_key]["grid_right"] = self.pairs[pair_key][
1463
- "new_grid_right"
1464
- ]
1465
-
1466
- self.pairs[pair_key]["corrected_grid_left"] = self.pairs[
1467
- pair_key
1468
- ]["new_grid_left"]
1469
-
1470
1422
  elif (
1471
1423
  self.used_conf[ADVANCED][adv_cst.USE_EPIPOLAR_A_PRIORI] is True
1472
1424
  and not self.use_sift_a_priori
@@ -1553,14 +1505,13 @@ class UnitPipeline(PipelineTemplate):
1553
1505
  (
1554
1506
  self.pairs[pair_key]["grid_correction_coef"],
1555
1507
  self.pairs[pair_key]["corrected_matches_array"],
1556
- self.pairs[pair_key]["corrected_matches_cars_ds"],
1557
1508
  _,
1558
1509
  _,
1559
1510
  ) = grid_correction_app.estimate_right_grid_correction(
1560
1511
  new_grid_matches_array,
1561
1512
  self.pairs[pair_key]["grid_right"],
1562
1513
  save_matches=save_matches,
1563
- initial_cars_ds=None,
1514
+ minimum_nb_matches=minimum_nb_matches,
1564
1515
  pair_folder=os.path.join(
1565
1516
  self.dump_dir, "grid_correction", "new", pair_key
1566
1517
  ),
@@ -1638,8 +1589,8 @@ class UnitPipeline(PipelineTemplate):
1638
1589
  ):
1639
1590
  dmin = disp_min / self.res_resamp
1640
1591
  dmax = disp_max / self.res_resamp
1641
-
1642
- disp_range_grid = (
1592
+ # generate_disparity_grids runs orchestrator.breakpoint()
1593
+ self.pairs[pair_key]["disp_range_grid"] = (
1643
1594
  self.dense_matching_app.generate_disparity_grids(
1644
1595
  self.pairs[pair_key]["sensor_image_right"],
1645
1596
  self.pairs[pair_key]["corrected_grid_right"],
@@ -1647,7 +1598,7 @@ class UnitPipeline(PipelineTemplate):
1647
1598
  dmin=dmin,
1648
1599
  dmax=dmax,
1649
1600
  pair_folder=dense_matching_pair_folder,
1650
- loc_inverse_orchestrator=self.cars_orchestrator,
1601
+ orchestrator=self.cars_orchestrator,
1651
1602
  )
1652
1603
  )
1653
1604
 
@@ -1674,8 +1625,8 @@ class UnitPipeline(PipelineTemplate):
1674
1625
  else:
1675
1626
  if None in (altitude_delta_min, altitude_delta_max):
1676
1627
  # Generate min and max disp grids from dems
1677
-
1678
- disp_range_grid = (
1628
+ # generate_disparity_grids runs orchestrator.breakpoint()
1629
+ self.pairs[pair_key]["disp_range_grid"] = (
1679
1630
  self.dense_matching_app.generate_disparity_grids(
1680
1631
  self.pairs[pair_key]["sensor_image_right"],
1681
1632
  self.pairs[pair_key]["corrected_grid_right"],
@@ -1684,12 +1635,13 @@ class UnitPipeline(PipelineTemplate):
1684
1635
  dem_max=dem_max,
1685
1636
  dem_median=dem_median,
1686
1637
  pair_folder=dense_matching_pair_folder,
1687
- loc_inverse_orchestrator=self.cars_orchestrator,
1638
+ orchestrator=self.cars_orchestrator,
1688
1639
  )
1689
1640
  )
1690
1641
  else:
1691
1642
  # Generate min and max disp grids from deltas
1692
- disp_range_grid = (
1643
+ # generate_disparity_grids runs orchestrator.breakpoint()
1644
+ self.pairs[pair_key]["disp_range_grid"] = (
1693
1645
  self.dense_matching_app.generate_disparity_grids(
1694
1646
  self.pairs[pair_key]["sensor_image_right"],
1695
1647
  self.pairs[pair_key]["corrected_grid_right"],
@@ -1698,7 +1650,7 @@ class UnitPipeline(PipelineTemplate):
1698
1650
  altitude_delta_max=altitude_delta_max,
1699
1651
  dem_median=dem_median,
1700
1652
  pair_folder=dense_matching_pair_folder,
1701
- loc_inverse_orchestrator=self.cars_orchestrator,
1653
+ orchestrator=self.cars_orchestrator,
1702
1654
  )
1703
1655
  )
1704
1656
 
@@ -1708,12 +1660,12 @@ class UnitPipeline(PipelineTemplate):
1708
1660
  # TODO remove when only local diparity range will be used
1709
1661
 
1710
1662
  if self.use_sift_a_priori:
1711
- dmin = np.nanmin(
1712
- disp_range_grid[0, 0]["disp_min_grid"].values
1713
- )
1714
- dmax = np.nanmax(
1715
- disp_range_grid[0, 0]["disp_max_grid"].values
1716
- )
1663
+ dmin = self.pairs[pair_key]["disp_range_grid"][
1664
+ "global_min"
1665
+ ]
1666
+ dmax = self.pairs[pair_key]["disp_range_grid"][
1667
+ "global_max"
1668
+ ]
1717
1669
 
1718
1670
  # update orchestrator_out_json
1719
1671
  marg = self.sparse_mtch_sift_app.get_disparity_margin()
@@ -1737,7 +1689,8 @@ class UnitPipeline(PipelineTemplate):
1737
1689
  pair_key=pair_key,
1738
1690
  )
1739
1691
 
1740
- disp_range_grid = (
1692
+ # generate_disparity_grids runs orchestrator.breakpoint()
1693
+ self.pairs[pair_key]["disp_range_grid"] = (
1741
1694
  self.dense_matching_app.generate_disparity_grids(
1742
1695
  self.pairs[pair_key]["sensor_image_right"],
1743
1696
  self.pairs[pair_key]["corrected_grid_right"],
@@ -1745,34 +1698,23 @@ class UnitPipeline(PipelineTemplate):
1745
1698
  dmin=dmin,
1746
1699
  dmax=dmax,
1747
1700
  pair_folder=dense_matching_pair_folder,
1748
- loc_inverse_orchestrator=self.cars_orchestrator,
1701
+ orchestrator=self.cars_orchestrator,
1749
1702
  )
1750
1703
  )
1751
- # Get margins used in dense matching,
1752
- dense_matching_margins_fun = (
1753
- self.dense_matching_app.get_margins_fun(
1754
- self.pairs[pair_key]["corrected_grid_left"],
1755
- disp_range_grid,
1756
- )
1757
- )
1758
1704
 
1759
1705
  # TODO add in metadata.json max diff max - min
1760
1706
  # Update used_conf configuration with epipolar a priori
1761
1707
  # Add global min and max computed with grids
1762
1708
  advanced_parameters.update_conf(
1763
1709
  self.used_conf,
1764
- dmin=np.min(
1765
- disp_range_grid[0, 0]["disp_min_grid"].values
1766
- ), # TODO compute dmin dans dmax
1767
- dmax=np.max(disp_range_grid[0, 0]["disp_max_grid"].values),
1710
+ dmin=self.pairs[pair_key]["disp_range_grid"]["global_min"],
1711
+ dmax=self.pairs[pair_key]["disp_range_grid"]["global_max"],
1768
1712
  pair_key=pair_key,
1769
1713
  )
1770
1714
  advanced_parameters.update_conf(
1771
1715
  self.config_full_res,
1772
- dmin=np.min(
1773
- disp_range_grid[0, 0]["disp_min_grid"].values
1774
- ), # TODO compute dmin dans dmax
1775
- dmax=np.max(disp_range_grid[0, 0]["disp_max_grid"].values),
1716
+ dmin=self.pairs[pair_key]["disp_range_grid"]["global_min"],
1717
+ dmax=self.pairs[pair_key]["disp_range_grid"]["global_max"],
1776
1718
  pair_key=pair_key,
1777
1719
  )
1778
1720
 
@@ -1783,6 +1725,10 @@ class UnitPipeline(PipelineTemplate):
1783
1725
  safe_save=True,
1784
1726
  )
1785
1727
 
1728
+ # end of for loop, to finish computing disparity range grids
1729
+
1730
+ for cloud_id, (pair_key, _, _) in enumerate(self.list_sensor_pairs):
1731
+
1786
1732
  # Generate roi
1787
1733
  epipolar_roi = preprocessing.compute_epipolar_roi(
1788
1734
  self.input_roi_poly,
@@ -1793,10 +1739,8 @@ class UnitPipeline(PipelineTemplate):
1793
1739
  self.pairs[pair_key]["corrected_grid_left"],
1794
1740
  self.pairs[pair_key]["corrected_grid_right"],
1795
1741
  os.path.join(self.dump_dir, "compute_epipolar_roi", pair_key),
1796
- disp_min=np.min(
1797
- disp_range_grid[0, 0]["disp_min_grid"].values
1798
- ), # TODO compute dmin dans dmax
1799
- disp_max=np.max(disp_range_grid[0, 0]["disp_max_grid"].values),
1742
+ disp_min=self.pairs[pair_key]["disp_range_grid"]["global_min"],
1743
+ disp_max=self.pairs[pair_key]["disp_range_grid"]["global_max"],
1800
1744
  )
1801
1745
 
1802
1746
  # Generate new epipolar images
@@ -1808,7 +1752,7 @@ class UnitPipeline(PipelineTemplate):
1808
1752
  optimum_tile_size,
1809
1753
  local_tile_optimal_size_fun,
1810
1754
  ) = self.dense_matching_app.get_optimal_tile_size(
1811
- disp_range_grid,
1755
+ self.pairs[pair_key]["disp_range_grid"],
1812
1756
  self.cars_orchestrator.cluster.checked_conf_cluster[
1813
1757
  "max_ram_per_worker"
1814
1758
  ],
@@ -1828,6 +1772,14 @@ class UnitPipeline(PipelineTemplate):
1828
1772
  for band in self.texture_bands
1829
1773
  ]
1830
1774
 
1775
+ # Get margins used in dense matching,
1776
+ dense_matching_margins_fun = (
1777
+ self.dense_matching_app.get_margins_fun(
1778
+ self.pairs[pair_key]["corrected_grid_left"],
1779
+ self.pairs[pair_key]["disp_range_grid"],
1780
+ )
1781
+ )
1782
+
1831
1783
  # Run third epipolar resampling
1832
1784
  (
1833
1785
  new_epipolar_image_left,
@@ -1866,6 +1818,7 @@ class UnitPipeline(PipelineTemplate):
1866
1818
  geoid=self.used_conf[ADVANCED][adv_cst.GROUND_TRUTH_DSM][
1867
1819
  adv_cst.INPUT_GEOID
1868
1820
  ],
1821
+ scaling_coeff=self.scaling_coeff,
1869
1822
  )
1870
1823
  self.ground_truth_reprojection.run(
1871
1824
  self.pairs[pair_key]["sensor_image_left"],
@@ -1889,6 +1842,131 @@ class UnitPipeline(PipelineTemplate):
1889
1842
  ),
1890
1843
  )
1891
1844
 
1845
+ if self.epsg is None:
1846
+ # compute epsg
1847
+ # Epsg uses global disparity min and max
1848
+ self.epsg = preprocessing.compute_epsg(
1849
+ self.pairs[pair_key]["sensor_image_left"],
1850
+ self.pairs[pair_key]["sensor_image_right"],
1851
+ self.pairs[pair_key]["corrected_grid_left"],
1852
+ self.pairs[pair_key]["corrected_grid_right"],
1853
+ self.geom_plugin_with_dem_and_geoid,
1854
+ disp_min=self.pairs[pair_key]["disp_range_grid"][
1855
+ "global_min"
1856
+ ],
1857
+ disp_max=self.pairs[pair_key]["disp_range_grid"][
1858
+ "global_max"
1859
+ ],
1860
+ )
1861
+ # Compute roi polygon, in input EPSG
1862
+ self.roi_poly = preprocessing.compute_roi_poly(
1863
+ self.input_roi_poly, self.input_roi_epsg, self.epsg
1864
+ )
1865
+
1866
+ self.vertical_crs = projection.get_output_crs(self.epsg, output)
1867
+
1868
+ if (
1869
+ self.save_output_dsm
1870
+ or self.save_output_point_cloud
1871
+ or self.dense_matching_app.get_method() == "auto"
1872
+ ):
1873
+ # Compute terrain bounding box /roi related to
1874
+ # current images
1875
+ (current_terrain_roi_bbox, intersection_poly) = (
1876
+ preprocessing.compute_terrain_bbox(
1877
+ self.pairs[pair_key]["sensor_image_left"],
1878
+ self.pairs[pair_key]["sensor_image_right"],
1879
+ new_epipolar_image_left,
1880
+ self.pairs[pair_key]["corrected_grid_left"],
1881
+ self.pairs[pair_key]["corrected_grid_right"],
1882
+ self.epsg,
1883
+ self.geom_plugin_with_dem_and_geoid,
1884
+ resolution=self.resolution,
1885
+ disp_min=self.pairs[pair_key]["disp_range_grid"][
1886
+ "global_min"
1887
+ ],
1888
+ disp_max=self.pairs[pair_key]["disp_range_grid"][
1889
+ "global_max"
1890
+ ],
1891
+ roi_poly=(
1892
+ None if self.debug_with_roi else self.roi_poly
1893
+ ),
1894
+ orchestrator=self.cars_orchestrator,
1895
+ pair_key=pair_key,
1896
+ pair_folder=os.path.join(
1897
+ self.dump_dir, "terrain_bbox", pair_key
1898
+ ),
1899
+ check_inputs=False,
1900
+ )
1901
+ )
1902
+ self.list_terrain_roi.append(current_terrain_roi_bbox)
1903
+ self.list_intersection_poly.append(intersection_poly)
1904
+
1905
+ # compute terrain bounds for later use
1906
+ (
1907
+ self.terrain_bounds,
1908
+ self.optimal_terrain_tile_width,
1909
+ ) = preprocessing.compute_terrain_bounds(
1910
+ self.list_terrain_roi,
1911
+ roi_poly=(None if self.debug_with_roi else self.roi_poly),
1912
+ resolution=self.resolution,
1913
+ )
1914
+
1915
+ if self.which_resolution not in ("final", "single"):
1916
+ # To get the correct size for the dem generation
1917
+ if self.dem_generation_roi is not None:
1918
+ # ROI has been computed by Shareloc
1919
+ self.terrain_bounds = (
1920
+ dem_wrappers.modify_terrain_bounds(
1921
+ self.dem_generation_roi.bounds,
1922
+ 4326,
1923
+ self.epsg,
1924
+ self.dem_generation_application.margin,
1925
+ )
1926
+ )
1927
+ else:
1928
+ # ROI has not been computed
1929
+ self.terrain_bounds = (
1930
+ dem_wrappers.modify_terrain_bounds(
1931
+ self.terrain_bounds,
1932
+ self.epsg,
1933
+ self.epsg,
1934
+ self.dem_generation_application.margin,
1935
+ 0.7,
1936
+ )
1937
+ )
1938
+
1939
+ if self.dense_matching_app.get_method() == "auto":
1940
+ # Copy the initial corr_config in order to keep
1941
+ # the inputs that have already been checked
1942
+ corr_cfg = self.dense_matching_app.corr_config.copy()
1943
+
1944
+ # Find the conf that correspond to the land cover map
1945
+ conf = self.dense_matching_app.loader.find_auto_conf(
1946
+ intersection_poly,
1947
+ self.land_cover_map,
1948
+ self.classification_to_config_mapping,
1949
+ self.epsg,
1950
+ )
1951
+
1952
+ # Update the used_conf if order to reinitialize
1953
+ # the dense matching app
1954
+ # Because we kept the information regarding the ambiguity,
1955
+ # performance_map calculus..
1956
+ self.used_conf["applications"]["dense_matching"]["loader_conf"][
1957
+ "pipeline"
1958
+ ] = conf["pipeline"]
1959
+
1960
+ # Re initialization of the dense matching application
1961
+ self.dense_matching_app = Application(
1962
+ "dense_matching",
1963
+ cfg=self.used_conf["applications"]["dense_matching"],
1964
+ )
1965
+
1966
+ # Update the corr_config with the inputs that have
1967
+ # already been checked
1968
+ self.dense_matching_app.corr_config["input"] = corr_cfg["input"]
1969
+
1892
1970
  # Run epipolar matching application
1893
1971
  epipolar_disparity_map = self.dense_matching_app.run(
1894
1972
  new_epipolar_image_left,
@@ -1899,7 +1977,7 @@ class UnitPipeline(PipelineTemplate):
1899
1977
  self.dump_dir, "dense_matching", pair_key
1900
1978
  ),
1901
1979
  pair_key=pair_key,
1902
- disp_range_grid=disp_range_grid,
1980
+ disp_range_grid=self.pairs[pair_key]["disp_range_grid"],
1903
1981
  compute_disparity_masks=False,
1904
1982
  margins_to_keep=(
1905
1983
  self.pc_outlier_removal_1_app.get_epipolar_margin()
@@ -1919,11 +1997,13 @@ class UnitPipeline(PipelineTemplate):
1919
1997
  epipolar_disparity_map,
1920
1998
  self.pairs[pair_key]["holes_bbox_left"],
1921
1999
  self.pairs[pair_key]["holes_bbox_right"],
1922
- disp_min=np.min(
1923
- disp_range_grid[0, 0]["disp_min_grid"].values
1924
- ),
2000
+ disp_min=self.pairs[pair_key]["disp_range_grid"][
2001
+ "global_min"
2002
+ ],
1925
2003
  disp_max=np.max(
1926
- disp_range_grid[0, 0]["disp_max_grid"].values
2004
+ self.pairs[pair_key]["disp_range_grid"][
2005
+ "global_max"
2006
+ ]
1927
2007
  ),
1928
2008
  orchestrator=self.cars_orchestrator,
1929
2009
  pair_folder=os.path.join(
@@ -1955,11 +2035,13 @@ class UnitPipeline(PipelineTemplate):
1955
2035
  filled_with_1_epipolar_disparity_map,
1956
2036
  self.pairs[pair_key]["holes_bbox_left"],
1957
2037
  self.pairs[pair_key]["holes_bbox_right"],
1958
- disp_min=np.min(
1959
- disp_range_grid[0, 0]["disp_min_grid"].values
1960
- ),
2038
+ disp_min=self.pairs[pair_key]["disp_range_grid"][
2039
+ "global_min"
2040
+ ],
1961
2041
  disp_max=np.max(
1962
- disp_range_grid[0, 0]["disp_max_grid"].values
2042
+ self.pairs[pair_key]["disp_range_grid"][
2043
+ "global_max"
2044
+ ]
1963
2045
  ),
1964
2046
  orchestrator=self.cars_orchestrator,
1965
2047
  pair_folder=os.path.join(
@@ -1984,27 +2066,6 @@ class UnitPipeline(PipelineTemplate):
1984
2066
  if self.quit_on_app("dense_match_filling.2"):
1985
2067
  continue # keep iterating over pairs, but don't go further
1986
2068
 
1987
- if self.epsg is None:
1988
- # compute epsg
1989
- # Epsg uses global disparity min and max
1990
- self.epsg = preprocessing.compute_epsg(
1991
- self.pairs[pair_key]["sensor_image_left"],
1992
- self.pairs[pair_key]["sensor_image_right"],
1993
- self.pairs[pair_key]["corrected_grid_left"],
1994
- self.pairs[pair_key]["corrected_grid_right"],
1995
- self.geom_plugin_with_dem_and_geoid,
1996
- disp_min=np.min(
1997
- disp_range_grid[0, 0]["disp_min_grid"].values
1998
- ),
1999
- disp_max=np.max(
2000
- disp_range_grid[0, 0]["disp_max_grid"].values
2001
- ),
2002
- )
2003
- # Compute roi polygon, in input EPSG
2004
- self.roi_poly = preprocessing.compute_roi_poly(
2005
- self.input_roi_poly, self.input_roi_epsg, self.epsg
2006
- )
2007
-
2008
2069
  if isinstance(output[sens_cst.GEOID], str):
2009
2070
  output_geoid_path = output[sens_cst.GEOID]
2010
2071
  elif (
@@ -2200,57 +2261,6 @@ class UnitPipeline(PipelineTemplate):
2200
2261
  # keep iterating over pairs, but don't go further
2201
2262
  continue
2202
2263
 
2203
- if self.save_output_dsm or self.save_output_point_cloud:
2204
- # Compute terrain bounding box /roi related to
2205
- # current images
2206
- (current_terrain_roi_bbox, intersection_poly) = (
2207
- preprocessing.compute_terrain_bbox(
2208
- self.pairs[pair_key]["sensor_image_left"],
2209
- self.pairs[pair_key]["sensor_image_right"],
2210
- new_epipolar_image_left,
2211
- self.pairs[pair_key]["corrected_grid_left"],
2212
- self.pairs[pair_key]["corrected_grid_right"],
2213
- self.epsg,
2214
- self.geom_plugin_with_dem_and_geoid,
2215
- resolution=self.resolution,
2216
- disp_min=np.min(
2217
- disp_range_grid[0, 0]["disp_min_grid"].values
2218
- ),
2219
- disp_max=np.max(
2220
- disp_range_grid[0, 0]["disp_max_grid"].values
2221
- ),
2222
- roi_poly=(
2223
- None if self.debug_with_roi else self.roi_poly
2224
- ),
2225
- orchestrator=self.cars_orchestrator,
2226
- pair_key=pair_key,
2227
- pair_folder=os.path.join(
2228
- self.dump_dir, "terrain_bbox", pair_key
2229
- ),
2230
- check_inputs=False,
2231
- )
2232
- )
2233
- self.list_terrain_roi.append(current_terrain_roi_bbox)
2234
- self.list_intersection_poly.append(intersection_poly)
2235
-
2236
- # compute terrain bounds for later use
2237
- (
2238
- self.terrain_bounds,
2239
- self.optimal_terrain_tile_width,
2240
- ) = preprocessing.compute_terrain_bounds(
2241
- self.list_terrain_roi,
2242
- roi_poly=(None if self.debug_with_roi else self.roi_poly),
2243
- resolution=self.resolution,
2244
- )
2245
-
2246
- if self.which_resolution not in ("final", "single"):
2247
- # To get the correct size for the dem generation
2248
- self.terrain_bounds = dem_wrappers.modify_terrain_bounds(
2249
- self.dem_generation_roi,
2250
- self.epsg,
2251
- self.dem_generation_application.margin,
2252
- )
2253
-
2254
2264
  # quit if any app in the loop over the pairs was the last one
2255
2265
  # pylint:disable=too-many-boolean-expressions
2256
2266
  if (
@@ -2390,6 +2400,7 @@ class UnitPipeline(PipelineTemplate):
2390
2400
  _ = self.rasterization_application.run(
2391
2401
  self.point_cloud_to_rasterize,
2392
2402
  self.epsg,
2403
+ self.vertical_crs,
2393
2404
  resolution=self.resolution,
2394
2405
  orchestrator=self.cars_orchestrator,
2395
2406
  dsm_file_name=dsm_file_name,
@@ -2488,14 +2499,16 @@ class UnitPipeline(PipelineTemplate):
2488
2499
  dem_min_file_name,
2489
2500
  dem_max_file_name,
2490
2501
  dem_median_file_name,
2491
- self.used_conf[INPUTS][sens_cst.INITIAL_ELEVATION][
2502
+ input_geoid=self.used_conf[INPUTS][sens_cst.INITIAL_ELEVATION][
2492
2503
  sens_cst.GEOID
2493
2504
  ],
2505
+ output_geoid=self.used_conf[OUTPUT][out_cst.OUT_GEOID],
2494
2506
  initial_elevation=(
2495
2507
  self.used_conf[INPUTS][sens_cst.INITIAL_ELEVATION][
2496
2508
  sens_cst.DEM_PATH
2497
2509
  ]
2498
2510
  ),
2511
+ default_alt=self.geom_plugin_with_dem_and_geoid.default_alt,
2499
2512
  cars_orchestrator=self.cars_orchestrator,
2500
2513
  )
2501
2514
 
@@ -2539,7 +2552,7 @@ class UnitPipeline(PipelineTemplate):
2539
2552
  for key in dsm_dict.keys():
2540
2553
  for path_name in dsm_dict[key].keys():
2541
2554
  if dsm_dict[key][path_name] is not None:
2542
- if not isinstance(dsm_dict[key][path_name], dict):
2555
+ if isinstance(dsm_dict[key][path_name], str):
2543
2556
  if path_name not in dict_path:
2544
2557
  dict_path[path_name] = [
2545
2558
  dsm_dict[key][path_name]
@@ -2548,22 +2561,6 @@ class UnitPipeline(PipelineTemplate):
2548
2561
  dict_path[path_name].append(
2549
2562
  dsm_dict[key][path_name]
2550
2563
  )
2551
- else:
2552
- for confidence_path_name in dsm_dict[key][
2553
- path_name
2554
- ].keys():
2555
- if confidence_path_name not in dict_path:
2556
- dict_path[confidence_path_name] = [
2557
- dsm_dict[key][path_name][
2558
- confidence_path_name
2559
- ]
2560
- ]
2561
- else:
2562
- dict_path[confidence_path_name].append(
2563
- dsm_dict[key][path_name][
2564
- confidence_path_name
2565
- ]
2566
- )
2567
2564
 
2568
2565
  color_file_name = (
2569
2566
  os.path.join(
@@ -2642,6 +2639,7 @@ class UnitPipeline(PipelineTemplate):
2642
2639
  )
2643
2640
 
2644
2641
  self.epsg = rasterio_get_epsg(dict_path["dsm"][0])
2642
+ self.vertical_crs = rasterio_get_crs(dict_path["dsm"][0])
2645
2643
 
2646
2644
  # Compute roi polygon, in input EPSG
2647
2645
  self.roi_poly = preprocessing.compute_roi_poly(
@@ -2771,9 +2769,9 @@ class UnitPipeline(PipelineTemplate):
2771
2769
  )
2772
2770
 
2773
2771
  # Project polygon if epsg is different
2774
- if self.epsg != inter_epsg:
2775
- inter_poly = projection.polygon_projection(
2776
- inter_poly, inter_epsg, self.epsg
2772
+ if self.vertical_crs != CRS(inter_epsg):
2773
+ inter_poly = projection.polygon_projection_crs(
2774
+ inter_poly, CRS(inter_epsg), self.vertical_crs
2777
2775
  )
2778
2776
 
2779
2777
  self.list_intersection_poly.append(inter_poly)
@@ -2944,6 +2942,10 @@ class UnitPipeline(PipelineTemplate):
2944
2942
  if self.epsg is None:
2945
2943
  self.epsg = epsg_cloud
2946
2944
 
2945
+ self.vertical_crs = projection.get_output_crs(
2946
+ self.epsg, self.used_conf[OUTPUT]
2947
+ )
2948
+
2947
2949
  self.resolution = (
2948
2950
  self.used_conf[OUTPUT][out_cst.RESOLUTION] * self.res_resamp
2949
2951
  )