cars 1.0.0rc3__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- cars/__init__.py +74 -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 +46 -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.cpython-313-x86_64-linux-gnu.so +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 +1130 -0
- cars/core/geometry/shareloc_geometry.py +604 -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 +1095 -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 +190 -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 +435 -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.0rc3.dist-info/METADATA +289 -0
- cars-1.0.0rc3.dist-info/RECORD +220 -0
- cars-1.0.0rc3.dist-info/WHEEL +6 -0
- cars-1.0.0rc3.dist-info/entry_points.txt +8 -0
cars/core/utils.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
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
|
+
Utils module:
|
|
23
|
+
contains some cars global shared general purpose functions
|
|
24
|
+
"""
|
|
25
|
+
# Standard imports
|
|
26
|
+
import errno
|
|
27
|
+
import os
|
|
28
|
+
import re
|
|
29
|
+
import shutil
|
|
30
|
+
from typing import Tuple
|
|
31
|
+
|
|
32
|
+
# Third party imports
|
|
33
|
+
import numpy as np
|
|
34
|
+
import numpy.linalg as la
|
|
35
|
+
import rasterio as rio
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def safe_makedirs(directory, cleanup=False):
|
|
39
|
+
"""
|
|
40
|
+
Create directories even if they already exist (mkdir -p)
|
|
41
|
+
|
|
42
|
+
:param directory: path of the directory to create
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
os.makedirs(directory)
|
|
46
|
+
except OSError as exc:
|
|
47
|
+
if exc.errno == errno.EEXIST and os.path.isdir(directory):
|
|
48
|
+
if cleanup:
|
|
49
|
+
shutil.rmtree(directory)
|
|
50
|
+
else:
|
|
51
|
+
raise
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def make_relative_path_absolute(path, directory):
|
|
55
|
+
"""
|
|
56
|
+
If path is a valid relative path with respect to directory,
|
|
57
|
+
returns it as an absolute path
|
|
58
|
+
|
|
59
|
+
:param path: The relative path
|
|
60
|
+
:type path: string
|
|
61
|
+
:param directory: The directory path should be relative to
|
|
62
|
+
:type directory: string
|
|
63
|
+
|
|
64
|
+
:return: os.path.join(directory,path)
|
|
65
|
+
if path is a valid relative path form directory, else path
|
|
66
|
+
:rtype: string
|
|
67
|
+
"""
|
|
68
|
+
out = path
|
|
69
|
+
if not os.path.isabs(path):
|
|
70
|
+
abspath = os.path.join(directory, path)
|
|
71
|
+
if os.path.exists(abspath):
|
|
72
|
+
out = abspath
|
|
73
|
+
return out
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def safe_cast_float(data):
|
|
77
|
+
"""
|
|
78
|
+
Safe cast to float data
|
|
79
|
+
|
|
80
|
+
:param data: string to get float in
|
|
81
|
+
|
|
82
|
+
:return float from data
|
|
83
|
+
"""
|
|
84
|
+
if isinstance(data, str):
|
|
85
|
+
match = re.search(r"[-+]?\d*\.\d+|\d+", data)
|
|
86
|
+
if match:
|
|
87
|
+
return float(match.group())
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_elevation_range_from_metadata(
|
|
92
|
+
img: str, default_min: float = 0, default_max: float = 300
|
|
93
|
+
) -> Tuple[float, float]:
|
|
94
|
+
"""
|
|
95
|
+
This function will try to derive a valid RPC altitude range
|
|
96
|
+
from img metadata.
|
|
97
|
+
|
|
98
|
+
It will first try to read metadata with gdal.
|
|
99
|
+
If it fails, it will look for values in the geom file if it exists
|
|
100
|
+
If it fails, it will return the default range
|
|
101
|
+
|
|
102
|
+
:param img: Path to the img for which the elevation range is required
|
|
103
|
+
:param default_min: Default minimum value to return if everything else fails
|
|
104
|
+
:param default_max: Default minimum value to return if everything else fails
|
|
105
|
+
:return: (elev_min, elev_max) float tuple
|
|
106
|
+
"""
|
|
107
|
+
# First, try to get range from gdal metadata
|
|
108
|
+
with rio.open(img) as descriptor:
|
|
109
|
+
gdal_height_offset = descriptor.get_tag_item("HEIGHT_OFF", "RPC")
|
|
110
|
+
gdal_height_scale = descriptor.get_tag_item("HEIGHT_SCALE", "RPC")
|
|
111
|
+
gdal_height_offset = safe_cast_float(gdal_height_offset)
|
|
112
|
+
gdal_height_scale = safe_cast_float(gdal_height_scale)
|
|
113
|
+
|
|
114
|
+
if gdal_height_scale is not None and gdal_height_offset is not None:
|
|
115
|
+
if isinstance(gdal_height_offset, str):
|
|
116
|
+
gdal_height_offset = float(gdal_height_offset)
|
|
117
|
+
if isinstance(gdal_height_scale, str):
|
|
118
|
+
gdal_height_scale = float(gdal_height_scale)
|
|
119
|
+
return (
|
|
120
|
+
float(gdal_height_offset - gdal_height_scale / 2.0),
|
|
121
|
+
float(gdal_height_offset + gdal_height_scale / 2.0),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# If we are still here, try to get range from OTB/OSSIM geom file if exists
|
|
125
|
+
geom_file, _ = os.path.splitext(img)
|
|
126
|
+
geom_file = geom_file + ".geom"
|
|
127
|
+
|
|
128
|
+
# If geom file exists
|
|
129
|
+
if os.path.isfile(geom_file):
|
|
130
|
+
with open(geom_file, "r", encoding="utf-8") as geom_file_desc:
|
|
131
|
+
geom_height_offset = None
|
|
132
|
+
geom_height_scale = None
|
|
133
|
+
|
|
134
|
+
for line in geom_file_desc:
|
|
135
|
+
if line.startswith("height_off:"):
|
|
136
|
+
geom_height_offset = float(line.split(sep=":")[1])
|
|
137
|
+
|
|
138
|
+
if line.startswith("height_scale:"):
|
|
139
|
+
geom_height_scale = float(line.split(sep=":")[1])
|
|
140
|
+
if geom_height_offset is not None and geom_height_scale is not None:
|
|
141
|
+
return (
|
|
142
|
+
float(geom_height_offset - geom_height_scale / 2),
|
|
143
|
+
float(geom_height_offset + geom_height_scale / 2),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# If we are still here, return a default range:
|
|
147
|
+
return (default_min, default_max)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def angle_vectors(vector_1: np.ndarray, vector_2: np.ndarray) -> float:
|
|
151
|
+
"""
|
|
152
|
+
Compute the smallest angle in radians between two angle_vectors
|
|
153
|
+
Use arctan2 more precise than arcos2
|
|
154
|
+
Tan θ = abs(axb)/ (a.b)
|
|
155
|
+
(same: Cos θ = (a.b)/(abs(a)abs(b)))
|
|
156
|
+
|
|
157
|
+
:param vector_1: Numpy first vector
|
|
158
|
+
:param vector_2: Numpy second vector
|
|
159
|
+
:return: Smallest angle in radians
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
vec_dot = np.dot(vector_1, vector_2)
|
|
163
|
+
vec_norm = la.norm(np.cross(vector_1, vector_2))
|
|
164
|
+
return np.arctan2(vec_norm, vec_dot)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding: utf8
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2020 Centre National d'Etudes Spatiales (CNES).
|
|
5
|
+
#
|
|
6
|
+
# This file is part of CARS
|
|
7
|
+
# (see https://github.com/CNES/cars).
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
"""
|
|
22
|
+
CARS data_structures module init file
|
|
23
|
+
"""
|