cars 1.0.0rc2__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cars might be problematic. Click here for more details.
- cars/__init__.py +86 -0
- cars/applications/__init__.py +40 -0
- cars/applications/application.py +117 -0
- cars/applications/application_constants.py +29 -0
- cars/applications/application_template.py +146 -0
- cars/applications/auxiliary_filling/__init__.py +29 -0
- cars/applications/auxiliary_filling/abstract_auxiliary_filling_app.py +105 -0
- cars/applications/auxiliary_filling/auxiliary_filling_algo.py +475 -0
- cars/applications/auxiliary_filling/auxiliary_filling_from_sensors_app.py +632 -0
- cars/applications/auxiliary_filling/auxiliary_filling_wrappers.py +90 -0
- cars/applications/dem_generation/__init__.py +30 -0
- cars/applications/dem_generation/abstract_dem_generation_app.py +116 -0
- cars/applications/dem_generation/bulldozer_config/base_config.yaml +42 -0
- cars/applications/dem_generation/bulldozer_dem_app.py +641 -0
- cars/applications/dem_generation/bulldozer_memory.py +55 -0
- cars/applications/dem_generation/dem_generation_algo.py +107 -0
- cars/applications/dem_generation/dem_generation_constants.py +32 -0
- cars/applications/dem_generation/dem_generation_wrappers.py +323 -0
- cars/applications/dense_match_filling/__init__.py +30 -0
- cars/applications/dense_match_filling/abstract_dense_match_filling_app.py +242 -0
- cars/applications/dense_match_filling/fill_disp_algo.py +113 -0
- cars/applications/dense_match_filling/fill_disp_constants.py +39 -0
- cars/applications/dense_match_filling/fill_disp_wrappers.py +83 -0
- cars/applications/dense_match_filling/zero_padding_app.py +302 -0
- cars/applications/dense_matching/__init__.py +30 -0
- cars/applications/dense_matching/abstract_dense_matching_app.py +261 -0
- cars/applications/dense_matching/census_mccnn_sgm_app.py +1461 -0
- cars/applications/dense_matching/cpp/__init__.py +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.dll.a +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.cp312-win_amd64.pyd +0 -0
- cars/applications/dense_matching/cpp/dense_matching_cpp.py +94 -0
- cars/applications/dense_matching/cpp/includes/dense_matching.hpp +58 -0
- cars/applications/dense_matching/cpp/meson.build +9 -0
- cars/applications/dense_matching/cpp/src/bindings.cpp +13 -0
- cars/applications/dense_matching/cpp/src/dense_matching.cpp +207 -0
- cars/applications/dense_matching/dense_matching_algo.py +401 -0
- cars/applications/dense_matching/dense_matching_constants.py +89 -0
- cars/applications/dense_matching/dense_matching_wrappers.py +951 -0
- cars/applications/dense_matching/disparity_grid_algo.py +597 -0
- cars/applications/dense_matching/loaders/__init__.py +23 -0
- cars/applications/dense_matching/loaders/config_census_sgm_default.json +31 -0
- cars/applications/dense_matching/loaders/config_census_sgm_homogeneous.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_mountain_and_vegetation.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_shadow.json +30 -0
- cars/applications/dense_matching/loaders/config_census_sgm_sparse.json +36 -0
- cars/applications/dense_matching/loaders/config_census_sgm_urban.json +30 -0
- cars/applications/dense_matching/loaders/config_mapping.json +13 -0
- cars/applications/dense_matching/loaders/config_mccnn.json +28 -0
- cars/applications/dense_matching/loaders/global_land_cover_map.tif +0 -0
- cars/applications/dense_matching/loaders/pandora_loader.py +593 -0
- cars/applications/dsm_filling/__init__.py +32 -0
- cars/applications/dsm_filling/abstract_dsm_filling_app.py +101 -0
- cars/applications/dsm_filling/border_interpolation_app.py +278 -0
- cars/applications/dsm_filling/bulldozer_config/base_config.yaml +44 -0
- cars/applications/dsm_filling/bulldozer_filling_app.py +288 -0
- cars/applications/dsm_filling/exogenous_filling_app.py +341 -0
- cars/applications/dsm_merging/__init__.py +28 -0
- cars/applications/dsm_merging/abstract_dsm_merging_app.py +101 -0
- cars/applications/dsm_merging/weighted_fusion_app.py +639 -0
- cars/applications/grid_correction/__init__.py +30 -0
- cars/applications/grid_correction/abstract_grid_correction_app.py +103 -0
- cars/applications/grid_correction/grid_correction_app.py +557 -0
- cars/applications/grid_generation/__init__.py +30 -0
- cars/applications/grid_generation/abstract_grid_generation_app.py +142 -0
- cars/applications/grid_generation/epipolar_grid_generation_app.py +327 -0
- cars/applications/grid_generation/grid_generation_algo.py +388 -0
- cars/applications/grid_generation/grid_generation_constants.py +46 -0
- cars/applications/grid_generation/transform_grid.py +88 -0
- cars/applications/ground_truth_reprojection/__init__.py +30 -0
- cars/applications/ground_truth_reprojection/abstract_ground_truth_reprojection_app.py +137 -0
- cars/applications/ground_truth_reprojection/direct_localization_app.py +629 -0
- cars/applications/ground_truth_reprojection/ground_truth_reprojection_algo.py +275 -0
- cars/applications/point_cloud_outlier_removal/__init__.py +30 -0
- cars/applications/point_cloud_outlier_removal/abstract_outlier_removal_app.py +385 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_algo.py +392 -0
- cars/applications/point_cloud_outlier_removal/outlier_removal_constants.py +43 -0
- cars/applications/point_cloud_outlier_removal/small_components_app.py +522 -0
- cars/applications/point_cloud_outlier_removal/statistical_app.py +528 -0
- cars/applications/rasterization/__init__.py +30 -0
- cars/applications/rasterization/abstract_pc_rasterization_app.py +183 -0
- cars/applications/rasterization/rasterization_algo.py +534 -0
- cars/applications/rasterization/rasterization_constants.py +38 -0
- cars/applications/rasterization/rasterization_wrappers.py +639 -0
- cars/applications/rasterization/simple_gaussian_app.py +1152 -0
- cars/applications/resampling/__init__.py +28 -0
- cars/applications/resampling/abstract_resampling_app.py +187 -0
- cars/applications/resampling/bicubic_resampling_app.py +760 -0
- cars/applications/resampling/resampling_algo.py +590 -0
- cars/applications/resampling/resampling_constants.py +36 -0
- cars/applications/resampling/resampling_wrappers.py +309 -0
- cars/applications/sensors_subsampling/__init__.py +32 -0
- cars/applications/sensors_subsampling/abstract_subsampling_app.py +109 -0
- cars/applications/sensors_subsampling/rasterio_subsampling_app.py +420 -0
- cars/applications/sensors_subsampling/subsampling_algo.py +108 -0
- cars/applications/sparse_matching/__init__.py +30 -0
- cars/applications/sparse_matching/abstract_sparse_matching_app.py +599 -0
- cars/applications/sparse_matching/sift_app.py +724 -0
- cars/applications/sparse_matching/sparse_matching_algo.py +360 -0
- cars/applications/sparse_matching/sparse_matching_constants.py +66 -0
- cars/applications/sparse_matching/sparse_matching_wrappers.py +282 -0
- cars/applications/triangulation/__init__.py +32 -0
- cars/applications/triangulation/abstract_triangulation_app.py +227 -0
- cars/applications/triangulation/line_of_sight_intersection_app.py +1243 -0
- cars/applications/triangulation/pc_transform.py +552 -0
- cars/applications/triangulation/triangulation_algo.py +371 -0
- cars/applications/triangulation/triangulation_constants.py +38 -0
- cars/applications/triangulation/triangulation_wrappers.py +259 -0
- cars/bundleadjustment.py +750 -0
- cars/cars.py +179 -0
- cars/conf/__init__.py +23 -0
- cars/conf/geoid/egm96.grd +0 -0
- cars/conf/geoid/egm96.grd.hdr +15 -0
- cars/conf/input_parameters.py +156 -0
- cars/conf/mask_cst.py +35 -0
- cars/core/__init__.py +23 -0
- cars/core/cars_logging.py +402 -0
- cars/core/constants.py +191 -0
- cars/core/constants_disparity.py +50 -0
- cars/core/datasets.py +140 -0
- cars/core/geometry/__init__.py +27 -0
- cars/core/geometry/abstract_geometry.py +1119 -0
- cars/core/geometry/shareloc_geometry.py +598 -0
- cars/core/inputs.py +568 -0
- cars/core/outputs.py +176 -0
- cars/core/preprocessing.py +722 -0
- cars/core/projection.py +843 -0
- cars/core/roi_tools.py +215 -0
- cars/core/tiling.py +774 -0
- cars/core/utils.py +164 -0
- cars/data_structures/__init__.py +23 -0
- cars/data_structures/cars_dataset.py +1544 -0
- cars/data_structures/cars_dict.py +74 -0
- cars/data_structures/corresponding_tiles_tools.py +186 -0
- cars/data_structures/dataframe_converter.py +185 -0
- cars/data_structures/format_transformation.py +297 -0
- cars/devibrate.py +689 -0
- cars/extractroi.py +264 -0
- cars/orchestrator/__init__.py +23 -0
- cars/orchestrator/achievement_tracker.py +125 -0
- cars/orchestrator/cluster/__init__.py +37 -0
- cars/orchestrator/cluster/abstract_cluster.py +250 -0
- cars/orchestrator/cluster/abstract_dask_cluster.py +381 -0
- cars/orchestrator/cluster/dask_cluster_tools.py +103 -0
- cars/orchestrator/cluster/dask_config/README.md +94 -0
- cars/orchestrator/cluster/dask_config/dask.yaml +21 -0
- cars/orchestrator/cluster/dask_config/distributed.yaml +70 -0
- cars/orchestrator/cluster/dask_config/jobqueue.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask-schema.yaml +137 -0
- cars/orchestrator/cluster/dask_config/reference_confs/dask.yaml +26 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed-schema.yaml +1009 -0
- cars/orchestrator/cluster/dask_config/reference_confs/distributed.yaml +273 -0
- cars/orchestrator/cluster/dask_config/reference_confs/jobqueue.yaml +212 -0
- cars/orchestrator/cluster/dask_jobqueue_utils.py +204 -0
- cars/orchestrator/cluster/local_dask_cluster.py +116 -0
- cars/orchestrator/cluster/log_wrapper.py +728 -0
- cars/orchestrator/cluster/mp_cluster/__init__.py +27 -0
- cars/orchestrator/cluster/mp_cluster/mp_factorizer.py +212 -0
- cars/orchestrator/cluster/mp_cluster/mp_objects.py +535 -0
- cars/orchestrator/cluster/mp_cluster/mp_tools.py +93 -0
- cars/orchestrator/cluster/mp_cluster/mp_wrapper.py +505 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_cluster.py +986 -0
- cars/orchestrator/cluster/mp_cluster/multiprocessing_profiler.py +399 -0
- cars/orchestrator/cluster/pbs_dask_cluster.py +207 -0
- cars/orchestrator/cluster/sequential_cluster.py +139 -0
- cars/orchestrator/cluster/slurm_dask_cluster.py +234 -0
- cars/orchestrator/memory_tools.py +47 -0
- cars/orchestrator/orchestrator.py +755 -0
- cars/orchestrator/orchestrator_constants.py +29 -0
- cars/orchestrator/registry/__init__.py +23 -0
- cars/orchestrator/registry/abstract_registry.py +143 -0
- cars/orchestrator/registry/compute_registry.py +106 -0
- cars/orchestrator/registry/id_generator.py +116 -0
- cars/orchestrator/registry/replacer_registry.py +213 -0
- cars/orchestrator/registry/saver_registry.py +363 -0
- cars/orchestrator/registry/unseen_registry.py +118 -0
- cars/orchestrator/tiles_profiler.py +279 -0
- cars/pipelines/__init__.py +26 -0
- cars/pipelines/conf_resolution/conf_final_resolution.yaml +5 -0
- cars/pipelines/conf_resolution/conf_first_resolution.yaml +4 -0
- cars/pipelines/conf_resolution/conf_intermediate_resolution.yaml +2 -0
- cars/pipelines/default/__init__.py +26 -0
- cars/pipelines/default/default_pipeline.py +1088 -0
- cars/pipelines/filling/__init__.py +26 -0
- cars/pipelines/filling/filling.py +981 -0
- cars/pipelines/formatting/__init__.py +26 -0
- cars/pipelines/formatting/formatting.py +186 -0
- cars/pipelines/merging/__init__.py +26 -0
- cars/pipelines/merging/merging.py +439 -0
- cars/pipelines/parameters/__init__.py +0 -0
- cars/pipelines/parameters/advanced_parameters.py +256 -0
- cars/pipelines/parameters/advanced_parameters_constants.py +68 -0
- cars/pipelines/parameters/application_parameters.py +72 -0
- cars/pipelines/parameters/depth_map_inputs.py +0 -0
- cars/pipelines/parameters/dsm_inputs.py +349 -0
- cars/pipelines/parameters/dsm_inputs_constants.py +25 -0
- cars/pipelines/parameters/output_constants.py +52 -0
- cars/pipelines/parameters/output_parameters.py +438 -0
- cars/pipelines/parameters/sensor_inputs.py +859 -0
- cars/pipelines/parameters/sensor_inputs_constants.py +51 -0
- cars/pipelines/parameters/sensor_loaders/__init__.py +29 -0
- cars/pipelines/parameters/sensor_loaders/basic_classif_loader.py +86 -0
- cars/pipelines/parameters/sensor_loaders/basic_image_loader.py +98 -0
- cars/pipelines/parameters/sensor_loaders/pivot_classif_loader.py +90 -0
- cars/pipelines/parameters/sensor_loaders/pivot_image_loader.py +105 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader.py +93 -0
- cars/pipelines/parameters/sensor_loaders/sensor_loader_template.py +71 -0
- cars/pipelines/parameters/sensor_loaders/slurp_classif_loader.py +86 -0
- cars/pipelines/pipeline.py +119 -0
- cars/pipelines/pipeline_constants.py +38 -0
- cars/pipelines/pipeline_template.py +135 -0
- cars/pipelines/subsampling/__init__.py +26 -0
- cars/pipelines/subsampling/subsampling.py +358 -0
- cars/pipelines/surface_modeling/__init__.py +26 -0
- cars/pipelines/surface_modeling/surface_modeling.py +2098 -0
- cars/pipelines/tie_points/__init__.py +26 -0
- cars/pipelines/tie_points/tie_points.py +536 -0
- cars/starter.py +167 -0
- cars-1.0.0rc2.dist-info/DELVEWHEEL +2 -0
- cars-1.0.0rc2.dist-info/METADATA +289 -0
- cars-1.0.0rc2.dist-info/RECORD +225 -0
- cars-1.0.0rc2.dist-info/WHEEL +4 -0
- cars-1.0.0rc2.dist-info/entry_points.txt +8 -0
- cars.libs/libgcc_s_seh-1-b2494fcbd4d80cf2c98fdd5261f6d850.dll +0 -0
- cars.libs/libstdc++-6-e9b0d12ae0e9555bbae55e8dfd08c3f7.dll +0 -0
- cars.libs/libwinpthread-1-7882d1b093714ccdfaf4e0789a817792.dll +0 -0
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
this module contains the dichotomic dem generation application class.
|
|
23
|
+
"""
|
|
24
|
+
# Standard library
|
|
25
|
+
import logging
|
|
26
|
+
import math
|
|
27
|
+
import os
|
|
28
|
+
import shutil
|
|
29
|
+
|
|
30
|
+
# Third-party imports
|
|
31
|
+
import numpy as np
|
|
32
|
+
import rasterio as rio
|
|
33
|
+
import skimage
|
|
34
|
+
from json_checker import And, Checker, Or
|
|
35
|
+
from rasterio.enums import Resampling
|
|
36
|
+
from rasterio.warp import reproject
|
|
37
|
+
|
|
38
|
+
# CARS imports - Applications
|
|
39
|
+
from cars.applications import application_constants
|
|
40
|
+
from cars.applications.dem_generation.abstract_dem_generation_app import (
|
|
41
|
+
DemGeneration,
|
|
42
|
+
)
|
|
43
|
+
from cars.applications.dem_generation.bulldozer_memory import (
|
|
44
|
+
can_allocate_shared_memory,
|
|
45
|
+
)
|
|
46
|
+
from cars.applications.dem_generation.dem_generation_algo import (
|
|
47
|
+
launch_bulldozer,
|
|
48
|
+
)
|
|
49
|
+
from cars.applications.dem_generation.dem_generation_wrappers import (
|
|
50
|
+
compute_stats,
|
|
51
|
+
downsample_dem,
|
|
52
|
+
edit_transform,
|
|
53
|
+
fit_initial_elevation_on_dem_median,
|
|
54
|
+
reproject_dem,
|
|
55
|
+
reverse_dem,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# CARS imports - Core
|
|
59
|
+
from cars.core import inputs
|
|
60
|
+
from cars.orchestrator.cluster.log_wrapper import cars_profile
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class BulldozerDem(DemGeneration, short_name="bulldozer_on_raster"):
|
|
64
|
+
"""
|
|
65
|
+
Rasterization
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
# pylint: disable=too-many-instance-attributes
|
|
69
|
+
|
|
70
|
+
def __init__(self, scaling_coeff, conf=None):
|
|
71
|
+
"""
|
|
72
|
+
Init function of Rasterization
|
|
73
|
+
|
|
74
|
+
:param scaling_coeff: scaling factor for resolution
|
|
75
|
+
:type scaling_coeff: float
|
|
76
|
+
:param conf: configuration for Rasterization
|
|
77
|
+
:return: an application_to_use object
|
|
78
|
+
"""
|
|
79
|
+
super().__init__(scaling_coeff, conf=conf)
|
|
80
|
+
|
|
81
|
+
# check conf
|
|
82
|
+
self.used_method = self.used_config["method"]
|
|
83
|
+
self.resolution = self.used_config["resolution"]
|
|
84
|
+
self.margin = self.used_config["margin"]
|
|
85
|
+
height_margin = self.used_config["height_margin"]
|
|
86
|
+
if isinstance(height_margin, list):
|
|
87
|
+
self.min_height_margin = height_margin[0]
|
|
88
|
+
self.max_height_margin = height_margin[1]
|
|
89
|
+
else:
|
|
90
|
+
self.min_height_margin = height_margin
|
|
91
|
+
self.max_height_margin = height_margin
|
|
92
|
+
self.morphological_filters_size = self.used_config[
|
|
93
|
+
"morphological_filters_size"
|
|
94
|
+
]
|
|
95
|
+
self.preprocessing_median_filter_size = self.used_config[
|
|
96
|
+
"preprocessing_median_filter_size"
|
|
97
|
+
]
|
|
98
|
+
self.postprocessing_median_filter_size = self.used_config[
|
|
99
|
+
"postprocessing_median_filter_size"
|
|
100
|
+
]
|
|
101
|
+
self.dem_median_downscale = self.used_config["dem_median_downscale"]
|
|
102
|
+
self.dem_min_max_downscale = self.used_config["dem_min_max_downscale"]
|
|
103
|
+
self.fillnodata_max_search_distance = self.used_config[
|
|
104
|
+
"fillnodata_max_search_distance"
|
|
105
|
+
]
|
|
106
|
+
self.min_dem = self.used_config["min_dem"]
|
|
107
|
+
self.max_dem = self.used_config["max_dem"]
|
|
108
|
+
self.bulldozer_max_object_size = self.used_config[
|
|
109
|
+
"bulldozer_max_object_size"
|
|
110
|
+
]
|
|
111
|
+
self.disable_bulldozer = self.used_config["disable_bulldozer"]
|
|
112
|
+
self.compute_stats = self.used_config["compute_stats"]
|
|
113
|
+
self.coregistration = self.used_config["coregistration"]
|
|
114
|
+
self.coregistration_max_shift = self.used_config[
|
|
115
|
+
"coregistration_max_shift"
|
|
116
|
+
]
|
|
117
|
+
self.save_intermediate_data = self.used_config["save_intermediate_data"]
|
|
118
|
+
|
|
119
|
+
# Init orchestrator
|
|
120
|
+
self.orchestrator = None
|
|
121
|
+
|
|
122
|
+
def check_conf(self, conf):
|
|
123
|
+
"""
|
|
124
|
+
Check configuration
|
|
125
|
+
|
|
126
|
+
:param conf: configuration to check
|
|
127
|
+
:type conf: dict
|
|
128
|
+
|
|
129
|
+
:return: overloaded configuration
|
|
130
|
+
:rtype: dict
|
|
131
|
+
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
# init conf
|
|
135
|
+
if conf is not None:
|
|
136
|
+
overloaded_conf = conf.copy()
|
|
137
|
+
else:
|
|
138
|
+
conf = {}
|
|
139
|
+
overloaded_conf = {}
|
|
140
|
+
|
|
141
|
+
# Overload conf
|
|
142
|
+
overloaded_conf["method"] = conf.get("method", "bulldozer_on_raster")
|
|
143
|
+
overloaded_conf["resolution"] = conf.get(
|
|
144
|
+
"resolution", float(self.scaling_coeff * 0.5)
|
|
145
|
+
)
|
|
146
|
+
overloaded_conf["margin"] = conf.get(
|
|
147
|
+
"margin", [0.1, float(math.sqrt(self.scaling_coeff) * 500)]
|
|
148
|
+
)
|
|
149
|
+
overloaded_conf["morphological_filters_size"] = conf.get(
|
|
150
|
+
"morphological_filters_size", 30
|
|
151
|
+
)
|
|
152
|
+
overloaded_conf["preprocessing_median_filter_size"] = conf.get(
|
|
153
|
+
"preprocessing_median_filter_size", 5
|
|
154
|
+
)
|
|
155
|
+
overloaded_conf["postprocessing_median_filter_size"] = conf.get(
|
|
156
|
+
"postprocessing_median_filter_size", 7
|
|
157
|
+
)
|
|
158
|
+
overloaded_conf["dem_median_downscale"] = conf.get(
|
|
159
|
+
"dem_median_downscale", 10
|
|
160
|
+
)
|
|
161
|
+
overloaded_conf["dem_min_max_downscale"] = conf.get(
|
|
162
|
+
"dem_min_max_downscale", 2
|
|
163
|
+
)
|
|
164
|
+
overloaded_conf["fillnodata_max_search_distance"] = conf.get(
|
|
165
|
+
"fillnodata_max_search_distance", 50
|
|
166
|
+
)
|
|
167
|
+
overloaded_conf["min_dem"] = conf.get("min_dem", -500)
|
|
168
|
+
overloaded_conf["max_dem"] = conf.get("max_dem", 1000)
|
|
169
|
+
overloaded_conf["height_margin"] = conf.get(
|
|
170
|
+
"height_margin", float(math.sqrt(self.scaling_coeff) * 20)
|
|
171
|
+
)
|
|
172
|
+
overloaded_conf["bulldozer_max_object_size"] = conf.get(
|
|
173
|
+
"bulldozer_max_object_size", 8
|
|
174
|
+
)
|
|
175
|
+
overloaded_conf["disable_bulldozer"] = conf.get(
|
|
176
|
+
"disable_bulldozer", False
|
|
177
|
+
)
|
|
178
|
+
if not overloaded_conf["disable_bulldozer"]:
|
|
179
|
+
can_allocate_sm, log_message = can_allocate_shared_memory()
|
|
180
|
+
if not can_allocate_sm:
|
|
181
|
+
logging.info(log_message)
|
|
182
|
+
logging.info(
|
|
183
|
+
"Dem generation disable_bulldozer parameter is set to True"
|
|
184
|
+
)
|
|
185
|
+
overloaded_conf["disable_bulldozer"] = True
|
|
186
|
+
overloaded_conf["compute_stats"] = conf.get("compute_stats", True)
|
|
187
|
+
overloaded_conf["coregistration"] = conf.get("coregistration", True)
|
|
188
|
+
overloaded_conf["coregistration_max_shift"] = conf.get(
|
|
189
|
+
"coregistration_max_shift", 180
|
|
190
|
+
)
|
|
191
|
+
overloaded_conf[application_constants.SAVE_INTERMEDIATE_DATA] = (
|
|
192
|
+
conf.get(application_constants.SAVE_INTERMEDIATE_DATA, False)
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
rectification_schema = {
|
|
196
|
+
"method": str,
|
|
197
|
+
"resolution": And(Or(float, int), lambda x: x > 0),
|
|
198
|
+
application_constants.SAVE_INTERMEDIATE_DATA: bool,
|
|
199
|
+
"margin": [Or(float, int)],
|
|
200
|
+
"morphological_filters_size": And(int, lambda x: x > 0),
|
|
201
|
+
"preprocessing_median_filter_size": And(int, lambda x: x > 0),
|
|
202
|
+
"postprocessing_median_filter_size": And(int, lambda x: x > 0),
|
|
203
|
+
"dem_median_downscale": And(int, lambda x: x > 0),
|
|
204
|
+
"dem_min_max_downscale": And(int, lambda x: x > 0),
|
|
205
|
+
"fillnodata_max_search_distance": And(int, lambda x: x > 0),
|
|
206
|
+
"min_dem": And(Or(int, float), lambda x: x < 0),
|
|
207
|
+
"max_dem": And(Or(int, float), lambda x: x > 0),
|
|
208
|
+
"height_margin": Or(list, float, int),
|
|
209
|
+
"bulldozer_max_object_size": And(int, lambda x: x > 0),
|
|
210
|
+
"disable_bulldozer": bool,
|
|
211
|
+
"compute_stats": bool,
|
|
212
|
+
"coregistration": bool,
|
|
213
|
+
"coregistration_max_shift": And(Or(int, float), lambda x: x > 0),
|
|
214
|
+
"save_intermediate_data": bool,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
# Check conf
|
|
218
|
+
checker = Checker(rectification_schema)
|
|
219
|
+
checker.validate(overloaded_conf)
|
|
220
|
+
|
|
221
|
+
return overloaded_conf
|
|
222
|
+
|
|
223
|
+
@cars_profile(name="DEM Generation")
|
|
224
|
+
def run( # pylint: disable=too-many-positional-arguments # noqa: C901
|
|
225
|
+
self,
|
|
226
|
+
dsm_file_name,
|
|
227
|
+
output_dir,
|
|
228
|
+
input_geoid,
|
|
229
|
+
output_geoid,
|
|
230
|
+
initial_elevation=None,
|
|
231
|
+
default_alt=0,
|
|
232
|
+
cars_orchestrator=None,
|
|
233
|
+
):
|
|
234
|
+
"""
|
|
235
|
+
Run dichotomic dem generation using matches
|
|
236
|
+
|
|
237
|
+
:param dsm_file_name: The dsm path
|
|
238
|
+
:type dsm_file_name: CarsDataset
|
|
239
|
+
:param output_dir: directory to save dem
|
|
240
|
+
:type output_dir: str
|
|
241
|
+
:param input_geoid: input geoid path
|
|
242
|
+
:param output_geoid: output geoid path
|
|
243
|
+
:param dem_roi_to_use: dem roi polygon to use as roi
|
|
244
|
+
|
|
245
|
+
:return: dem data computed with mean, min and max.
|
|
246
|
+
dem is also saved in disk, and paths are available in attributes.
|
|
247
|
+
(DEM_MEDIAN_PATH, DEM_MIN_PATH, DEM_MAX_PATH)
|
|
248
|
+
:rtype: CarsDataset
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
# Generate point cloud
|
|
252
|
+
epsg = 4326
|
|
253
|
+
|
|
254
|
+
# Optimize the case when input and output geoid are the same
|
|
255
|
+
if output_geoid is True:
|
|
256
|
+
input_geoid = False
|
|
257
|
+
output_geoid = False
|
|
258
|
+
|
|
259
|
+
resolution_in_meters = self.resolution
|
|
260
|
+
|
|
261
|
+
# rasterize point cloud
|
|
262
|
+
|
|
263
|
+
# File is not part of the official product, write it in dump_dir
|
|
264
|
+
dem_min_path = os.path.join(output_dir, "dem_min.tif")
|
|
265
|
+
|
|
266
|
+
# File is not part of the official product, write it in dump_dir
|
|
267
|
+
dem_max_path = os.path.join(output_dir, "dem_max.tif")
|
|
268
|
+
|
|
269
|
+
# File is not part of the official product, write it in dump_dir
|
|
270
|
+
dem_median_path_out = os.path.join(output_dir, "dem_median.tif")
|
|
271
|
+
|
|
272
|
+
dem_median_path_in = dsm_file_name
|
|
273
|
+
|
|
274
|
+
dem_epsg = inputs.rasterio_get_epsg(dsm_file_name)
|
|
275
|
+
|
|
276
|
+
if dem_epsg != epsg:
|
|
277
|
+
dem_median_path_in = os.path.join(output_dir, "dem_median.tif")
|
|
278
|
+
reproject_dem(dsm_file_name, "EPSG:4326", dem_median_path_in)
|
|
279
|
+
|
|
280
|
+
with rio.open(dem_median_path_in) as src:
|
|
281
|
+
dem = src.read(1)
|
|
282
|
+
profile = src.profile
|
|
283
|
+
nodata = src.nodata
|
|
284
|
+
|
|
285
|
+
if self.save_intermediate_data:
|
|
286
|
+
raw_dsm_path = os.path.join(output_dir, "raw_dsm.tif")
|
|
287
|
+
shutil.copy2(dem_median_path_in, raw_dsm_path)
|
|
288
|
+
|
|
289
|
+
dem_data = dem
|
|
290
|
+
mask = dem_data == nodata
|
|
291
|
+
|
|
292
|
+
# fill nodata
|
|
293
|
+
max_search_distance = (
|
|
294
|
+
self.fillnodata_max_search_distance
|
|
295
|
+
+ self.morphological_filters_size
|
|
296
|
+
)
|
|
297
|
+
# a margin is added for following morphological operations
|
|
298
|
+
# pixels further than self.fillnodata_max_search_distance
|
|
299
|
+
# will later be turned into nodata by eroded_mask
|
|
300
|
+
dem_data = rio.fill.fillnodata(
|
|
301
|
+
dem_data,
|
|
302
|
+
mask=~mask,
|
|
303
|
+
max_search_distance=max_search_distance,
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
not_filled_pixels = dem_data == nodata
|
|
307
|
+
|
|
308
|
+
# Add geoid
|
|
309
|
+
if input_geoid:
|
|
310
|
+
with rio.open(input_geoid) as in_geoid:
|
|
311
|
+
# Reproject the geoid data to match the DSM
|
|
312
|
+
input_geoid_data = np.empty(
|
|
313
|
+
dem_data.shape, dtype=in_geoid.dtypes[0]
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
logging.info("Reprojection of geoid data")
|
|
317
|
+
|
|
318
|
+
reproject(
|
|
319
|
+
source=rio.band(in_geoid, 1),
|
|
320
|
+
destination=input_geoid_data,
|
|
321
|
+
src_transform=in_geoid.transform,
|
|
322
|
+
src_crs=in_geoid.crs,
|
|
323
|
+
dst_transform=profile["transform"],
|
|
324
|
+
dst_crs=profile["crs"],
|
|
325
|
+
resampling=Resampling.bilinear,
|
|
326
|
+
)
|
|
327
|
+
dem_data -= input_geoid_data
|
|
328
|
+
|
|
329
|
+
if output_geoid:
|
|
330
|
+
with rio.open(input_geoid) as in_geoid:
|
|
331
|
+
# Reproject the geoid data to match the DSM
|
|
332
|
+
input_geoid_data = np.empty(
|
|
333
|
+
dem_data.shape, dtype=in_geoid.dtypes[0]
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
logging.info("Reprojection of geoid data")
|
|
337
|
+
|
|
338
|
+
reproject(
|
|
339
|
+
source=rio.band(in_geoid, 1),
|
|
340
|
+
destination=input_geoid_data,
|
|
341
|
+
src_transform=in_geoid.transform,
|
|
342
|
+
src_crs=in_geoid.crs,
|
|
343
|
+
dst_transform=profile["transform"],
|
|
344
|
+
dst_crs=profile["crs"],
|
|
345
|
+
resampling=Resampling.bilinear,
|
|
346
|
+
)
|
|
347
|
+
dem_data += input_geoid_data
|
|
348
|
+
|
|
349
|
+
# apply morphological filters and height margin
|
|
350
|
+
footprint = skimage.morphology.disk(
|
|
351
|
+
self.morphological_filters_size // 2, decomposition="sequence"
|
|
352
|
+
)
|
|
353
|
+
logging.info("Generation of DEM min")
|
|
354
|
+
dem_data[not_filled_pixels] = -nodata
|
|
355
|
+
dem_min = (
|
|
356
|
+
skimage.morphology.erosion(dem_data, footprint=footprint)
|
|
357
|
+
- self.min_height_margin
|
|
358
|
+
)
|
|
359
|
+
dem_data[not_filled_pixels] = nodata
|
|
360
|
+
logging.info("Generation of DEM max")
|
|
361
|
+
dem_max = (
|
|
362
|
+
skimage.morphology.dilation(dem_data, footprint=footprint)
|
|
363
|
+
+ self.max_height_margin
|
|
364
|
+
)
|
|
365
|
+
logging.info("Generation of DEM median")
|
|
366
|
+
dem_median = skimage.filters.median(
|
|
367
|
+
dem_data,
|
|
368
|
+
footprint=np.ones(
|
|
369
|
+
(
|
|
370
|
+
self.preprocessing_median_filter_size,
|
|
371
|
+
self.preprocessing_median_filter_size,
|
|
372
|
+
)
|
|
373
|
+
),
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
footprint = skimage.morphology.disk(
|
|
377
|
+
self.fillnodata_max_search_distance // 2, decomposition="sequence"
|
|
378
|
+
)
|
|
379
|
+
eroded_mask = skimage.morphology.binary_erosion(
|
|
380
|
+
mask, footprint=footprint
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
dem_min[eroded_mask] = nodata
|
|
384
|
+
dem_median[eroded_mask] = nodata
|
|
385
|
+
dem_max[eroded_mask] = nodata
|
|
386
|
+
|
|
387
|
+
# Rectify pixels where DEM min < DEM median + min_depth
|
|
388
|
+
dem_min = np.where(
|
|
389
|
+
dem_min - dem_median < self.min_dem,
|
|
390
|
+
dem_median + self.min_dem,
|
|
391
|
+
dem_min,
|
|
392
|
+
)
|
|
393
|
+
# Rectify pixels where DEM max > DEM median + max_height
|
|
394
|
+
dem_max = np.where(
|
|
395
|
+
dem_max - dem_median > self.max_dem,
|
|
396
|
+
dem_median + self.max_dem,
|
|
397
|
+
dem_max,
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
# save
|
|
401
|
+
with rio.open(dem_min_path, "w", **profile) as out_dem:
|
|
402
|
+
out_dem.write(dem_min, 1)
|
|
403
|
+
with rio.open(dem_median_path_out, "w", **profile) as out_dem:
|
|
404
|
+
out_dem.write(dem_median, 1)
|
|
405
|
+
with rio.open(dem_max_path, "w", **profile) as out_dem:
|
|
406
|
+
out_dem.write(dem_max, 1)
|
|
407
|
+
dem_filled_path = os.path.join(output_dir, "dem_filled.tif")
|
|
408
|
+
with rio.open(dem_filled_path, "w", **profile) as out_dem:
|
|
409
|
+
out_dem.write(dem_data, 1)
|
|
410
|
+
|
|
411
|
+
if self.save_intermediate_data:
|
|
412
|
+
intermediate_dem_min_path = os.path.join(
|
|
413
|
+
output_dir, "dem_min_before_downsampling.tif"
|
|
414
|
+
)
|
|
415
|
+
shutil.copy2(dem_min_path, intermediate_dem_min_path)
|
|
416
|
+
intermediate_dem_max_path = os.path.join(
|
|
417
|
+
output_dir, "dem_max_before_downsampling.tif"
|
|
418
|
+
)
|
|
419
|
+
shutil.copy2(dem_max_path, intermediate_dem_max_path)
|
|
420
|
+
|
|
421
|
+
intermediate_dem_median_path = os.path.join(
|
|
422
|
+
output_dir, "dem_median_before_downsampling.tif"
|
|
423
|
+
)
|
|
424
|
+
shutil.copy2(dem_median_path_out, intermediate_dem_median_path)
|
|
425
|
+
|
|
426
|
+
# Downsample dems
|
|
427
|
+
downsample_dem(
|
|
428
|
+
dem_median_path_out,
|
|
429
|
+
scale=self.dem_median_downscale,
|
|
430
|
+
interpolator="median",
|
|
431
|
+
median_filter_size=self.postprocessing_median_filter_size,
|
|
432
|
+
default_alt=default_alt,
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
downsample_dem(
|
|
436
|
+
dem_min_path,
|
|
437
|
+
scale=self.dem_min_max_downscale,
|
|
438
|
+
interpolator="min",
|
|
439
|
+
default_alt=default_alt,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
downsample_dem(
|
|
443
|
+
dem_max_path,
|
|
444
|
+
scale=self.dem_min_max_downscale,
|
|
445
|
+
interpolator="max",
|
|
446
|
+
default_alt=default_alt,
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
downsample_dem(
|
|
450
|
+
dem_filled_path,
|
|
451
|
+
scale=self.dem_min_max_downscale,
|
|
452
|
+
interpolator="nearest",
|
|
453
|
+
default_alt=default_alt,
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
if self.save_intermediate_data:
|
|
457
|
+
intermediate_dem_min_path = os.path.join(
|
|
458
|
+
output_dir, "dem_min_before_bulldozer.tif"
|
|
459
|
+
)
|
|
460
|
+
shutil.copy2(dem_min_path, intermediate_dem_min_path)
|
|
461
|
+
intermediate_dem_max_path = os.path.join(
|
|
462
|
+
output_dir, "dem_max_before_bulldozer.tif"
|
|
463
|
+
)
|
|
464
|
+
shutil.copy2(dem_max_path, intermediate_dem_max_path)
|
|
465
|
+
|
|
466
|
+
if not self.disable_bulldozer:
|
|
467
|
+
dem_min_max_res = resolution_in_meters * self.dem_min_max_downscale
|
|
468
|
+
# Launch Bulldozer on dem min
|
|
469
|
+
saved_transform = edit_transform(
|
|
470
|
+
dem_min_path, resolution=dem_min_max_res
|
|
471
|
+
)
|
|
472
|
+
logging.info("Launch Bulldozer on DEM min")
|
|
473
|
+
temp_output_path = launch_bulldozer(
|
|
474
|
+
dem_min_path,
|
|
475
|
+
os.path.join(output_dir, "dem_min_bulldozer"),
|
|
476
|
+
cars_orchestrator,
|
|
477
|
+
self.bulldozer_max_object_size,
|
|
478
|
+
)
|
|
479
|
+
if temp_output_path is not None:
|
|
480
|
+
shutil.copy2(temp_output_path, dem_min_path)
|
|
481
|
+
edit_transform(dem_min_path, transform=saved_transform)
|
|
482
|
+
|
|
483
|
+
# Inverse dem max and launch bulldozer
|
|
484
|
+
saved_transform = edit_transform(
|
|
485
|
+
dem_max_path, resolution=dem_min_max_res
|
|
486
|
+
)
|
|
487
|
+
reverse_dem(dem_max_path)
|
|
488
|
+
logging.info("Launch Bulldozer on DEM max")
|
|
489
|
+
temp_output_path = launch_bulldozer(
|
|
490
|
+
dem_max_path,
|
|
491
|
+
os.path.join(output_dir, "dem_max_bulldozer"),
|
|
492
|
+
cars_orchestrator,
|
|
493
|
+
self.bulldozer_max_object_size,
|
|
494
|
+
)
|
|
495
|
+
if temp_output_path is not None:
|
|
496
|
+
shutil.copy2(temp_output_path, dem_max_path)
|
|
497
|
+
reverse_dem(dem_max_path)
|
|
498
|
+
edit_transform(dem_max_path, transform=saved_transform)
|
|
499
|
+
|
|
500
|
+
else:
|
|
501
|
+
# Fill nodata
|
|
502
|
+
def fill_dem_nodata(data):
|
|
503
|
+
"""
|
|
504
|
+
Fill nodata
|
|
505
|
+
"""
|
|
506
|
+
# Apply max_iter times rasterio fill nodata
|
|
507
|
+
max_iter = 5
|
|
508
|
+
current_iter = 0
|
|
509
|
+
while current_iter < max_iter:
|
|
510
|
+
data = rio.fill.fillnodata(
|
|
511
|
+
data,
|
|
512
|
+
mask=data != nodata,
|
|
513
|
+
max_search_distance=max_search_distance,
|
|
514
|
+
)
|
|
515
|
+
current_iter += 1
|
|
516
|
+
if np.sum(data == nodata) == 0:
|
|
517
|
+
# no nodata left, exit loop
|
|
518
|
+
continue
|
|
519
|
+
# fill the rest with median
|
|
520
|
+
median_value = np.nanmedian(data)
|
|
521
|
+
data[data == nodata] = median_value
|
|
522
|
+
return data
|
|
523
|
+
|
|
524
|
+
with rio.open(dem_min_path, "r+", **profile) as out_dem:
|
|
525
|
+
dem_min = out_dem.read()
|
|
526
|
+
dem_min = fill_dem_nodata(dem_min)
|
|
527
|
+
out_dem.write(dem_min)
|
|
528
|
+
with rio.open(dem_median_path_out, "r+", **profile) as out_dem:
|
|
529
|
+
dem_median = out_dem.read()
|
|
530
|
+
dem_median = fill_dem_nodata(dem_median)
|
|
531
|
+
out_dem.write(dem_median)
|
|
532
|
+
with rio.open(dem_max_path, "r+", **profile) as out_dem:
|
|
533
|
+
dem_max = out_dem.read()
|
|
534
|
+
dem_max = fill_dem_nodata(dem_max)
|
|
535
|
+
out_dem.write(dem_max)
|
|
536
|
+
|
|
537
|
+
# Check DEM min and max
|
|
538
|
+
with rio.open(dem_min_path, "r") as in_dem:
|
|
539
|
+
dem_min = in_dem.read()
|
|
540
|
+
dem_min_metadata = in_dem.meta
|
|
541
|
+
nodata = in_dem.nodata
|
|
542
|
+
with rio.open(dem_max_path, "r") as in_dem:
|
|
543
|
+
dem_max = in_dem.read()
|
|
544
|
+
dem_max_metadata = in_dem.meta
|
|
545
|
+
with rio.open(dem_filled_path, "r") as in_dem:
|
|
546
|
+
dem_data = in_dem.read()
|
|
547
|
+
dem_data[dem_data == nodata] = np.nan
|
|
548
|
+
dem_min[dem_min == nodata] = np.nan
|
|
549
|
+
dem_max[dem_max == nodata] = np.nan
|
|
550
|
+
if self.compute_stats:
|
|
551
|
+
diff = dem_data - dem_min
|
|
552
|
+
diff = diff[dem_data != 0]
|
|
553
|
+
logging.info(
|
|
554
|
+
"Statistics of difference between subsampled "
|
|
555
|
+
"DSM and DEM min (in meters)"
|
|
556
|
+
)
|
|
557
|
+
compute_stats(diff)
|
|
558
|
+
|
|
559
|
+
diff = dem_max - dem_data
|
|
560
|
+
diff = diff[dem_data != 0]
|
|
561
|
+
logging.info(
|
|
562
|
+
"Statistics of difference between DEM max "
|
|
563
|
+
"and subsampled DSM (in meters)"
|
|
564
|
+
)
|
|
565
|
+
compute_stats(diff)
|
|
566
|
+
|
|
567
|
+
diff = dem_max - dem_min
|
|
568
|
+
diff = diff[dem_data != 0]
|
|
569
|
+
logging.info(
|
|
570
|
+
"Statistics of difference between DEM max "
|
|
571
|
+
"and DEM min (in meters)"
|
|
572
|
+
)
|
|
573
|
+
compute_stats(diff)
|
|
574
|
+
|
|
575
|
+
# Rectify pixels where DEM min > DEM - margin
|
|
576
|
+
dem_min = np.where(
|
|
577
|
+
dem_min > dem_data - self.min_height_margin,
|
|
578
|
+
dem_data - self.min_height_margin,
|
|
579
|
+
dem_min,
|
|
580
|
+
)
|
|
581
|
+
# Rectify pixels where DEM max < DEM + margin
|
|
582
|
+
dem_max = np.where(
|
|
583
|
+
dem_max < dem_data + self.max_height_margin,
|
|
584
|
+
dem_data + self.max_height_margin,
|
|
585
|
+
dem_max,
|
|
586
|
+
)
|
|
587
|
+
|
|
588
|
+
# Rectify pixels where DEM min > DEM max - margin, to ensure that
|
|
589
|
+
# DEM min < DEM max even on filled pixels
|
|
590
|
+
dem_min = np.where(
|
|
591
|
+
dem_min > dem_max - self.min_height_margin,
|
|
592
|
+
dem_max - self.min_height_margin,
|
|
593
|
+
dem_min,
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
with rio.open(dem_min_path, "w", **dem_min_metadata) as out_dem:
|
|
597
|
+
out_dem.write(dem_min)
|
|
598
|
+
with rio.open(dem_max_path, "w", **dem_max_metadata) as out_dem:
|
|
599
|
+
out_dem.write(dem_max)
|
|
600
|
+
|
|
601
|
+
paths = {
|
|
602
|
+
"dem_median": dem_median_path_out,
|
|
603
|
+
"dem_min": dem_min_path,
|
|
604
|
+
"dem_max": dem_max_path,
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
# after saving, fit initial elevation if required
|
|
608
|
+
if initial_elevation is not None and self.coregistration:
|
|
609
|
+
initial_elevation_out_path = os.path.join(
|
|
610
|
+
output_dir, "initial_elevation_fit.tif"
|
|
611
|
+
)
|
|
612
|
+
|
|
613
|
+
coreg_offsets = fit_initial_elevation_on_dem_median(
|
|
614
|
+
initial_elevation,
|
|
615
|
+
dem_median_path_out,
|
|
616
|
+
initial_elevation_out_path,
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
coreg_info = {
|
|
620
|
+
application_constants.APPLICATION_TAG: {
|
|
621
|
+
"dem_generation": {"coregistration": coreg_offsets}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
# save the coreg shift info in cars's main orchestrator
|
|
626
|
+
cars_orchestrator.update_out_info(coreg_info)
|
|
627
|
+
|
|
628
|
+
if (
|
|
629
|
+
coreg_offsets is None
|
|
630
|
+
or abs(coreg_offsets["shift_x"]) > self.coregistration_max_shift
|
|
631
|
+
or abs(coreg_offsets["shift_y"]) > self.coregistration_max_shift
|
|
632
|
+
):
|
|
633
|
+
logging.warning(
|
|
634
|
+
"The initial elevation will be used as-is because "
|
|
635
|
+
"coregistration failed or gave inconsistent results"
|
|
636
|
+
)
|
|
637
|
+
return dem, paths, None
|
|
638
|
+
|
|
639
|
+
return dem, paths, initial_elevation_out_path
|
|
640
|
+
|
|
641
|
+
return dem, paths, None
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
this module contains tools checking bulldozer parameter used for memory
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
import shutil
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def can_allocate_shared_memory(nb_go=0.8):
|
|
30
|
+
"""
|
|
31
|
+
Check if can allocate shared memory
|
|
32
|
+
"""
|
|
33
|
+
# TODO remove when Eoascale not in bulldozer anymore
|
|
34
|
+
try:
|
|
35
|
+
# 1 Go = 1024 * 1024 * 1024 octets
|
|
36
|
+
shm_stats = shutil.disk_usage("/dev/shm")
|
|
37
|
+
available_bytes = shm_stats.free
|
|
38
|
+
required_bytes = nb_go * 1024 * 1024 * 1024
|
|
39
|
+
|
|
40
|
+
if available_bytes > required_bytes:
|
|
41
|
+
log_message = "Can allocate shared memory."
|
|
42
|
+
return True, log_message
|
|
43
|
+
|
|
44
|
+
log_message = (
|
|
45
|
+
"Cannot allocate shared memory: {} Go available"
|
|
46
|
+
"If CARS runs on docker, use --shm-size option "
|
|
47
|
+
"on docker run command. For instance: --shm-size=10Go".format(
|
|
48
|
+
int(available_bytes / (1024 * 1024 * 1024))
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
return False, log_message
|
|
52
|
+
except Exception:
|
|
53
|
+
# Possibly on windows
|
|
54
|
+
log_message = "Crash on shared memory check."
|
|
55
|
+
return True, log_message
|