BERATools 0.2.2__py3-none-any.whl → 0.2.4__py3-none-any.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.
- beratools/__init__.py +8 -3
- beratools/core/{algo_footprint_rel.py → algo_canopy_footprint_exp.py} +176 -139
- beratools/core/algo_centerline.py +61 -77
- beratools/core/algo_common.py +48 -57
- beratools/core/algo_cost.py +18 -25
- beratools/core/algo_dijkstra.py +37 -45
- beratools/core/algo_line_grouping.py +100 -100
- beratools/core/algo_merge_lines.py +40 -8
- beratools/core/algo_split_with_lines.py +289 -304
- beratools/core/algo_vertex_optimization.py +25 -46
- beratools/core/canopy_threshold_relative.py +755 -0
- beratools/core/constants.py +8 -9
- beratools/{tools → core}/line_footprint_functions.py +411 -258
- beratools/core/logger.py +18 -2
- beratools/core/tool_base.py +17 -75
- beratools/gui/assets/BERALogo.ico +0 -0
- beratools/gui/assets/BERA_Splash.gif +0 -0
- beratools/gui/assets/BERA_WizardImage.png +0 -0
- beratools/gui/assets/beratools.json +475 -2171
- beratools/gui/bt_data.py +585 -234
- beratools/gui/bt_gui_main.py +129 -91
- beratools/gui/main.py +4 -7
- beratools/gui/tool_widgets.py +530 -354
- beratools/tools/__init__.py +0 -7
- beratools/tools/{line_footprint_absolute.py → canopy_footprint_absolute.py} +81 -56
- beratools/tools/canopy_footprint_exp.py +113 -0
- beratools/tools/centerline.py +30 -37
- beratools/tools/check_seed_line.py +127 -0
- beratools/tools/common.py +65 -586
- beratools/tools/{line_footprint_fixed.py → ground_footprint.py} +140 -117
- beratools/tools/line_footprint_relative.py +64 -35
- beratools/tools/tool_template.py +48 -40
- beratools/tools/vertex_optimization.py +20 -34
- beratools/utility/env_checks.py +53 -0
- beratools/utility/spatial_common.py +210 -0
- beratools/utility/tool_args.py +138 -0
- beratools-0.2.4.dist-info/METADATA +134 -0
- beratools-0.2.4.dist-info/RECORD +50 -0
- {beratools-0.2.2.dist-info → beratools-0.2.4.dist-info}/WHEEL +1 -1
- beratools-0.2.4.dist-info/entry_points.txt +3 -0
- beratools-0.2.4.dist-info/licenses/LICENSE +674 -0
- beratools/core/algo_tiler.py +0 -428
- beratools/gui/__init__.py +0 -11
- beratools/gui/batch_processing_dlg.py +0 -513
- beratools/gui/map_window.py +0 -162
- beratools/tools/Beratools_r_script.r +0 -1120
- beratools/tools/Ht_metrics.py +0 -116
- beratools/tools/batch_processing.py +0 -136
- beratools/tools/canopy_threshold_relative.py +0 -672
- beratools/tools/canopycostraster.py +0 -222
- beratools/tools/fl_regen_csf.py +0 -428
- beratools/tools/forest_line_attributes.py +0 -408
- beratools/tools/line_grouping.py +0 -45
- beratools/tools/ln_relative_metrics.py +0 -615
- beratools/tools/r_cal_lpi_elai.r +0 -25
- beratools/tools/r_generate_pd_focalraster.r +0 -101
- beratools/tools/r_interface.py +0 -80
- beratools/tools/r_point_density.r +0 -9
- beratools/tools/rpy_chm2trees.py +0 -86
- beratools/tools/rpy_dsm_chm_by.py +0 -81
- beratools/tools/rpy_dtm_by.py +0 -63
- beratools/tools/rpy_find_cellsize.py +0 -43
- beratools/tools/rpy_gnd_csf.py +0 -74
- beratools/tools/rpy_hummock_hollow.py +0 -85
- beratools/tools/rpy_hummock_hollow_raster.py +0 -71
- beratools/tools/rpy_las_info.py +0 -51
- beratools/tools/rpy_laz2las.py +0 -40
- beratools/tools/rpy_lpi_elai_lascat.py +0 -466
- beratools/tools/rpy_normalized_lidar_by.py +0 -56
- beratools/tools/rpy_percent_above_dbh.py +0 -80
- beratools/tools/rpy_points2trees.py +0 -88
- beratools/tools/rpy_vegcoverage.py +0 -94
- beratools/tools/tiler.py +0 -48
- beratools/tools/zonal_threshold.py +0 -144
- beratools-0.2.2.dist-info/METADATA +0 -108
- beratools-0.2.2.dist-info/RECORD +0 -74
- beratools-0.2.2.dist-info/entry_points.txt +0 -2
- beratools-0.2.2.dist-info/licenses/LICENSE +0 -22
beratools/gui/bt_data.py
CHANGED
|
@@ -12,55 +12,194 @@ Description:
|
|
|
12
12
|
|
|
13
13
|
The purpose of this script is to provide main interface for GUI related settings.
|
|
14
14
|
"""
|
|
15
|
+
|
|
15
16
|
import json
|
|
17
|
+
import logging
|
|
16
18
|
import os
|
|
17
|
-
import platform
|
|
18
19
|
from collections import OrderedDict
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
|
|
21
22
|
import beratools.core.constants as bt_const
|
|
23
|
+
from beratools.utility.spatial_common import decode_file_layer
|
|
24
|
+
from beratools.utility.tool_args import CallMode, determine_cpu_core_limit
|
|
22
25
|
|
|
23
|
-
running_windows = platform.system() == 'Windows'
|
|
24
26
|
BT_SHOW_ADVANCED_OPTIONS = False
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
def default_callback(value):
|
|
28
30
|
"""
|
|
29
31
|
Define default callback that outputs using the print function.
|
|
30
|
-
|
|
32
|
+
|
|
31
33
|
When tools are called without providing a custom callback, this function
|
|
32
34
|
will be used to print to standard output.
|
|
33
35
|
"""
|
|
34
36
|
print(value)
|
|
35
37
|
|
|
36
38
|
|
|
39
|
+
class SettingsManager:
|
|
40
|
+
"""An object for managing settings related to BERA Tools GUI."""
|
|
41
|
+
|
|
42
|
+
def __init__(self, setting_file):
|
|
43
|
+
self.setting_file = setting_file
|
|
44
|
+
self.settings = {}
|
|
45
|
+
|
|
46
|
+
def load_saved_tool_info(self):
|
|
47
|
+
if self.setting_file is not None:
|
|
48
|
+
data_path = Path(self.setting_file).parent
|
|
49
|
+
if not data_path.exists():
|
|
50
|
+
data_path.mkdir()
|
|
51
|
+
|
|
52
|
+
saved_parameters = {}
|
|
53
|
+
if self.setting_file is not None:
|
|
54
|
+
json_file = Path(self.setting_file)
|
|
55
|
+
if not json_file.exists():
|
|
56
|
+
self.settings = saved_parameters
|
|
57
|
+
return
|
|
58
|
+
with open(json_file, "r") as open_file:
|
|
59
|
+
try:
|
|
60
|
+
saved_parameters = json.load(open_file, object_pairs_hook=OrderedDict)
|
|
61
|
+
except json.decoder.JSONDecodeError:
|
|
62
|
+
logging.error("Failed to decode settings JSON file of saved tool info.", exc_info=True)
|
|
63
|
+
|
|
64
|
+
# Remove any entry with None or "null" as tool name
|
|
65
|
+
if isinstance(saved_parameters, dict):
|
|
66
|
+
saved_parameters = OrderedDict(
|
|
67
|
+
(k, v) for k, v in saved_parameters.items()
|
|
68
|
+
if k is not None and k != "null"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
self.settings = saved_parameters
|
|
72
|
+
else:
|
|
73
|
+
self.settings = saved_parameters
|
|
74
|
+
return
|
|
75
|
+
|
|
76
|
+
self.settings = saved_parameters
|
|
77
|
+
|
|
78
|
+
def save_tool_info(self, recent_tool=None):
|
|
79
|
+
if recent_tool:
|
|
80
|
+
if "gui_parameters" not in self.settings:
|
|
81
|
+
self.settings["gui_parameters"] = {}
|
|
82
|
+
|
|
83
|
+
self.settings["gui_parameters"]["recent_tool"] = recent_tool
|
|
84
|
+
|
|
85
|
+
if self.setting_file is not None:
|
|
86
|
+
with open(str(self.setting_file), "w") as file_setting:
|
|
87
|
+
try:
|
|
88
|
+
json.dump(self.settings, file_setting, indent=4)
|
|
89
|
+
except json.decoder.JSONDecodeError:
|
|
90
|
+
logging.error("Failed to encode settings to JSON when writing.", exc_info=True)
|
|
91
|
+
|
|
92
|
+
def save_setting(self, key, value):
|
|
93
|
+
# Guard against None/null tool name
|
|
94
|
+
if key is None:
|
|
95
|
+
print("Warning: tool_name is None, not saving parameters.")
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
# check setting directory existence
|
|
99
|
+
if self.setting_file is not None:
|
|
100
|
+
data_path = Path(self.setting_file).resolve().parent
|
|
101
|
+
if not data_path.exists():
|
|
102
|
+
data_path.mkdir()
|
|
103
|
+
|
|
104
|
+
self.load_saved_tool_info()
|
|
105
|
+
|
|
106
|
+
if value is not None:
|
|
107
|
+
if "gui_parameters" not in self.settings.keys():
|
|
108
|
+
self.settings["gui_parameters"] = {}
|
|
109
|
+
|
|
110
|
+
# Fix: Ensure value is a list if existing value is a list
|
|
111
|
+
if (
|
|
112
|
+
key in self.settings["gui_parameters"]
|
|
113
|
+
and isinstance(self.settings["gui_parameters"][key], list)
|
|
114
|
+
and not isinstance(value, list)
|
|
115
|
+
):
|
|
116
|
+
value = [value]
|
|
117
|
+
self.settings["gui_parameters"][key] = value
|
|
118
|
+
|
|
119
|
+
if self.setting_file is not None:
|
|
120
|
+
with open(str(self.setting_file), "w") as write_settings_file:
|
|
121
|
+
json.dump(self.settings, write_settings_file, indent=4)
|
|
122
|
+
|
|
123
|
+
def get_saved_tool_params(self, tool_api, variable=None):
|
|
124
|
+
self.load_saved_tool_info()
|
|
125
|
+
|
|
126
|
+
if (
|
|
127
|
+
isinstance(self.settings, dict)
|
|
128
|
+
and "tool_history" in self.settings
|
|
129
|
+
and self.settings["tool_history"] is not None
|
|
130
|
+
):
|
|
131
|
+
tool_history = self.settings["tool_history"]
|
|
132
|
+
if tool_history is None:
|
|
133
|
+
return None
|
|
134
|
+
if tool_api in list(tool_history):
|
|
135
|
+
tool_params = tool_history[tool_api]
|
|
136
|
+
if tool_params is None:
|
|
137
|
+
return None
|
|
138
|
+
if variable:
|
|
139
|
+
if isinstance(tool_params, dict):
|
|
140
|
+
if variable in tool_params.keys():
|
|
141
|
+
saved_value = tool_params[variable]
|
|
142
|
+
return saved_value
|
|
143
|
+
else:
|
|
144
|
+
return None
|
|
145
|
+
else:
|
|
146
|
+
return None
|
|
147
|
+
else: # return all params
|
|
148
|
+
return tool_params
|
|
149
|
+
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
def add_tool_history(self, tool, params):
|
|
153
|
+
if "tool_history" not in self.settings:
|
|
154
|
+
self.settings["tool_history"] = OrderedDict()
|
|
155
|
+
|
|
156
|
+
self.settings["tool_history"][tool] = params
|
|
157
|
+
self.settings["tool_history"].move_to_end(tool, last=False)
|
|
158
|
+
|
|
159
|
+
def remove_tool_history_item(self, index):
|
|
160
|
+
key = list(self.settings["tool_history"].keys())[index]
|
|
161
|
+
self.settings["tool_history"].pop(key)
|
|
162
|
+
self.save_tool_info()
|
|
163
|
+
|
|
164
|
+
def remove_tool_history_all(self):
|
|
165
|
+
self.settings.pop("tool_history")
|
|
166
|
+
self.save_tool_info()
|
|
167
|
+
|
|
168
|
+
def get_tool_history(self):
|
|
169
|
+
tool_history = []
|
|
170
|
+
self.load_saved_tool_info()
|
|
171
|
+
if (
|
|
172
|
+
isinstance(self.settings, dict)
|
|
173
|
+
and "tool_history" in self.settings
|
|
174
|
+
and self.settings["tool_history"] is not None
|
|
175
|
+
):
|
|
176
|
+
tool_history = self.settings["tool_history"]
|
|
177
|
+
|
|
178
|
+
return tool_history
|
|
179
|
+
|
|
37
180
|
class BTData(object):
|
|
38
181
|
"""An object for interfacing with the BERA Tools executable."""
|
|
39
182
|
|
|
40
183
|
def __init__(self):
|
|
41
|
-
if running_windows:
|
|
42
|
-
self.ext = '.exe'
|
|
43
|
-
else:
|
|
44
|
-
self.ext = ''
|
|
45
184
|
self.current_file_path = Path(__file__).resolve().parent
|
|
46
185
|
|
|
47
|
-
self.work_dir = ""
|
|
48
|
-
self.user_folder = Path(
|
|
49
|
-
self.data_folder = Path(
|
|
186
|
+
self.work_dir = Path("")
|
|
187
|
+
self.user_folder = Path("")
|
|
188
|
+
self.data_folder = Path("")
|
|
50
189
|
self.verbose = True
|
|
51
190
|
self.show_advanced = BT_SHOW_ADVANCED_OPTIONS
|
|
52
|
-
self.
|
|
191
|
+
self.selected_cpu_cores = -1
|
|
53
192
|
self.recent_tool = None
|
|
54
|
-
self.ascii_art =
|
|
193
|
+
self.ascii_art = ""
|
|
55
194
|
self.get_working_dir()
|
|
56
195
|
self.get_user_folder()
|
|
57
196
|
|
|
58
197
|
# set maximum available cpu core for tools
|
|
59
|
-
|
|
198
|
+
max_cores = determine_cpu_core_limit()
|
|
199
|
+
self.max_cpu_cores = max_cores
|
|
60
200
|
|
|
61
201
|
# load bera tools
|
|
62
202
|
self.tool_history = []
|
|
63
|
-
self.settings = {}
|
|
64
203
|
self.bera_tools = None
|
|
65
204
|
self.tools_list = []
|
|
66
205
|
self.sorted_tools = []
|
|
@@ -75,11 +214,13 @@ class BTData(object):
|
|
|
75
214
|
self.setting_file = None
|
|
76
215
|
self.get_data_folder()
|
|
77
216
|
self.get_setting_file()
|
|
78
|
-
self.
|
|
79
|
-
|
|
80
|
-
)
|
|
217
|
+
self.settings_manager = SettingsManager(self.setting_file)
|
|
218
|
+
self.gui_setting_file = Path(self.current_file_path).joinpath(bt_const.ASSETS_PATH, r"gui.json")
|
|
81
219
|
|
|
82
|
-
self.load_saved_tool_info()
|
|
220
|
+
self.settings_manager.load_saved_tool_info()
|
|
221
|
+
self.settings = self.settings_manager.settings
|
|
222
|
+
gui_settings = self.settings.get("gui_parameters", {})
|
|
223
|
+
self.recent_tool = gui_settings.get("recent_tool", None)
|
|
83
224
|
self.load_gui_data()
|
|
84
225
|
self.get_tool_history()
|
|
85
226
|
|
|
@@ -91,50 +232,42 @@ class BTData(object):
|
|
|
91
232
|
self.current_file_path = path_str
|
|
92
233
|
|
|
93
234
|
def add_tool_history(self, tool, params):
|
|
94
|
-
|
|
95
|
-
self.settings['tool_history'] = OrderedDict()
|
|
96
|
-
|
|
97
|
-
self.settings['tool_history'][tool] = params
|
|
98
|
-
self.settings['tool_history'].move_to_end(tool, last=False)
|
|
235
|
+
self.settings_manager.add_tool_history(tool, params)
|
|
99
236
|
|
|
100
237
|
def remove_tool_history_item(self, index):
|
|
101
|
-
|
|
102
|
-
self.settings['tool_history'].pop(key)
|
|
103
|
-
self.save_tool_info()
|
|
238
|
+
self.settings_manager.remove_tool_history_item(index)
|
|
104
239
|
|
|
105
240
|
def remove_tool_history_all(self):
|
|
106
|
-
self.
|
|
107
|
-
self.save_tool_info()
|
|
241
|
+
self.settings_manager.remove_tool_history_all()
|
|
108
242
|
|
|
109
243
|
def save_tool_info(self):
|
|
110
|
-
|
|
111
|
-
if 'gui_parameters' not in self.settings.keys():
|
|
112
|
-
self.settings['gui_parameters'] = {}
|
|
113
|
-
|
|
114
|
-
self.settings['gui_parameters']['recent_tool'] = self.recent_tool
|
|
115
|
-
|
|
116
|
-
with open(self.setting_file, 'w') as file_setting:
|
|
117
|
-
try:
|
|
118
|
-
json.dump(self.settings, file_setting, indent=4)
|
|
119
|
-
except json.decoder.JSONDecodeError:
|
|
120
|
-
pass
|
|
244
|
+
self.settings_manager.save_tool_info(self.recent_tool)
|
|
121
245
|
|
|
122
246
|
def save_setting(self, key, value):
|
|
123
247
|
# check setting directory existence
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
data_path.
|
|
248
|
+
if self.setting_file is not None:
|
|
249
|
+
data_path = Path(self.setting_file).resolve().parent
|
|
250
|
+
if not data_path.exists():
|
|
251
|
+
data_path.mkdir()
|
|
127
252
|
|
|
128
253
|
self.load_saved_tool_info()
|
|
129
254
|
|
|
130
255
|
if value is not None:
|
|
131
|
-
if
|
|
132
|
-
self.settings[
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
256
|
+
if "gui_parameters" not in self.settings.keys():
|
|
257
|
+
self.settings["gui_parameters"] = {}
|
|
258
|
+
|
|
259
|
+
# Fix: Ensure value is a list if existing value is a list
|
|
260
|
+
if (
|
|
261
|
+
key in self.settings["gui_parameters"]
|
|
262
|
+
and isinstance(self.settings["gui_parameters"][key], list)
|
|
263
|
+
and not isinstance(value, list)
|
|
264
|
+
):
|
|
265
|
+
value = [value]
|
|
266
|
+
self.settings["gui_parameters"][key] = value
|
|
267
|
+
|
|
268
|
+
if self.setting_file is not None:
|
|
269
|
+
with open(str(self.setting_file), "w") as write_settings_file:
|
|
270
|
+
json.dump(self.settings, write_settings_file, indent=4)
|
|
138
271
|
|
|
139
272
|
def get_working_dir(self):
|
|
140
273
|
current_file = Path(__file__).resolve()
|
|
@@ -142,81 +275,85 @@ class BTData(object):
|
|
|
142
275
|
self.work_dir = btool_dir
|
|
143
276
|
|
|
144
277
|
def get_user_folder(self):
|
|
145
|
-
self.user_folder = Path.home().joinpath(
|
|
278
|
+
self.user_folder = Path.home().joinpath(".beratools")
|
|
146
279
|
if not self.user_folder.exists():
|
|
147
280
|
self.user_folder.mkdir()
|
|
148
281
|
|
|
149
282
|
def get_data_folder(self):
|
|
150
|
-
self.data_folder = self.user_folder.joinpath(
|
|
283
|
+
self.data_folder = self.user_folder.joinpath(".data")
|
|
151
284
|
if not self.data_folder.exists():
|
|
152
285
|
self.data_folder.mkdir()
|
|
153
286
|
|
|
154
287
|
def get_logger_file_name(self, name):
|
|
155
288
|
if not name:
|
|
156
|
-
name =
|
|
289
|
+
name = "beratools"
|
|
157
290
|
|
|
158
|
-
logger_file_name = self.user_folder.joinpath(name).with_suffix(
|
|
291
|
+
logger_file_name = self.user_folder.joinpath(name).with_suffix(".log")
|
|
159
292
|
return logger_file_name.as_posix()
|
|
160
293
|
|
|
161
294
|
def get_setting_file(self):
|
|
162
|
-
self.setting_file = self.data_folder.joinpath(
|
|
295
|
+
self.setting_file = self.data_folder.joinpath("saved_tool_parameters.json")
|
|
163
296
|
|
|
164
|
-
def
|
|
165
|
-
"""Set the
|
|
166
|
-
self.
|
|
167
|
-
self.save_setting(
|
|
297
|
+
def set_selected_cpu_cores(self, val=-1):
|
|
298
|
+
"""Set the number of CPU cores to use."""
|
|
299
|
+
self.selected_cpu_cores = val
|
|
300
|
+
self.save_setting("selected_cpu_cores", val)
|
|
168
301
|
|
|
169
|
-
def
|
|
170
|
-
return self.
|
|
302
|
+
def get_selected_cpu_cores(self):
|
|
303
|
+
return self.selected_cpu_cores
|
|
171
304
|
|
|
172
305
|
def get_max_cpu_cores(self):
|
|
173
306
|
return self.max_cpu_cores
|
|
174
307
|
|
|
175
|
-
def
|
|
176
|
-
"""
|
|
177
|
-
Run a tool and specifies tool arguments.
|
|
178
|
-
|
|
179
|
-
Returns 0 if completes without error.
|
|
180
|
-
Returns 1 if error encountered (details are sent to callback).
|
|
181
|
-
Returns 2 if process is cancelled by user.
|
|
182
|
-
"""
|
|
308
|
+
def prepare_tool_run(self, tool_api, args, callback=None):
|
|
309
|
+
"""Prepare tool command and arguments."""
|
|
183
310
|
try:
|
|
184
311
|
if callback is None:
|
|
185
312
|
callback = self.default_callback
|
|
186
313
|
except Exception as err:
|
|
187
|
-
callback
|
|
314
|
+
if callback is not None:
|
|
315
|
+
callback(str(err))
|
|
316
|
+
else:
|
|
317
|
+
print(str(err))
|
|
318
|
+
|
|
188
319
|
return 1
|
|
189
320
|
|
|
190
321
|
# Call script using new process to make GUI responsive
|
|
191
322
|
try:
|
|
192
323
|
# convert to valid json string
|
|
193
324
|
args_string = str(args).replace("'", '"')
|
|
194
|
-
args_string = args_string.replace(
|
|
195
|
-
args_string = args_string.replace(
|
|
325
|
+
args_string = args_string.replace("True", "true")
|
|
326
|
+
args_string = args_string.replace("False", "false")
|
|
196
327
|
|
|
197
328
|
tool_name = self.get_bera_tool_name(tool_api)
|
|
198
329
|
tool_type = self.get_bera_tool_type(tool_name)
|
|
199
330
|
tool_args = None
|
|
200
331
|
|
|
201
|
-
if tool_type ==
|
|
202
|
-
tool_args = [
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
332
|
+
if tool_type == "python":
|
|
333
|
+
tool_args = [
|
|
334
|
+
self.work_dir.joinpath(f"tools/{tool_api}.py").as_posix(),
|
|
335
|
+
"-i", args_string,
|
|
336
|
+
"-p", str(self.get_selected_cpu_cores()),
|
|
337
|
+
"-c", CallMode.GUI,
|
|
338
|
+
"-l", "INFO"
|
|
339
|
+
] # fmt: skip
|
|
340
|
+
elif tool_type == "executable":
|
|
206
341
|
print(globals().get(tool_api))
|
|
207
342
|
tool_args = globals()[tool_api](args_string)
|
|
208
|
-
lapis_path = self.work_dir.joinpath(
|
|
343
|
+
lapis_path = self.work_dir.joinpath("./third_party/Lapis_0_8")
|
|
209
344
|
os.chdir(lapis_path.as_posix())
|
|
210
345
|
except Exception as err:
|
|
211
346
|
callback(str(err))
|
|
212
347
|
return 1
|
|
213
348
|
|
|
349
|
+
if tool_args is None:
|
|
350
|
+
tool_args = []
|
|
214
351
|
return tool_type, tool_args
|
|
215
352
|
|
|
216
353
|
def about(self):
|
|
217
354
|
"""Retrieve the description for BERA Tools."""
|
|
218
355
|
try:
|
|
219
|
-
about_text =
|
|
356
|
+
about_text = "BERA Tools provide a series of tools developed by AppliedGRG lab.\n\n"
|
|
220
357
|
about_text += self.ascii_art
|
|
221
358
|
return about_text
|
|
222
359
|
except (OSError, ValueError) as err:
|
|
@@ -225,7 +362,7 @@ class BTData(object):
|
|
|
225
362
|
def license(self):
|
|
226
363
|
"""Retrieve the license information for BERA Tools."""
|
|
227
364
|
try:
|
|
228
|
-
with open(Path(self.current_file_path).joinpath(r
|
|
365
|
+
with open(Path(self.current_file_path).joinpath(r"..\..\LICENSE.txt"), "r") as f:
|
|
229
366
|
ret = f.read()
|
|
230
367
|
|
|
231
368
|
return ret
|
|
@@ -233,60 +370,67 @@ class BTData(object):
|
|
|
233
370
|
return err
|
|
234
371
|
|
|
235
372
|
def load_saved_tool_info(self):
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
data_path.
|
|
373
|
+
if self.setting_file is not None:
|
|
374
|
+
data_path = Path(self.setting_file).parent
|
|
375
|
+
if not data_path.exists():
|
|
376
|
+
data_path.mkdir()
|
|
239
377
|
|
|
240
378
|
saved_parameters = {}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
379
|
+
if self.setting_file is not None:
|
|
380
|
+
json_file = Path(self.setting_file)
|
|
381
|
+
if not json_file.exists():
|
|
382
|
+
self.settings = saved_parameters
|
|
383
|
+
return
|
|
384
|
+
with open(json_file, "r") as open_file:
|
|
385
|
+
try:
|
|
386
|
+
saved_parameters = json.load(open_file, object_pairs_hook=OrderedDict)
|
|
387
|
+
except json.decoder.JSONDecodeError:
|
|
388
|
+
logging.error("Failed to decode settings JSON file of saved tool info.", exc_info=True)
|
|
244
389
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
pass
|
|
390
|
+
self.settings = saved_parameters
|
|
391
|
+
else:
|
|
392
|
+
self.settings = saved_parameters
|
|
393
|
+
return
|
|
250
394
|
|
|
251
395
|
self.settings = saved_parameters
|
|
252
396
|
|
|
253
397
|
# parse file
|
|
254
|
-
if
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
398
|
+
if (
|
|
399
|
+
isinstance(self.settings, dict)
|
|
400
|
+
and "gui_parameters" in self.settings
|
|
401
|
+
and self.settings["gui_parameters"] is not None
|
|
402
|
+
):
|
|
403
|
+
gui_settings = self.settings["gui_parameters"]
|
|
404
|
+
|
|
405
|
+
if "selected_cpu_cores" in gui_settings and gui_settings["selected_cpu_cores"] is not None:
|
|
406
|
+
self.selected_cpu_cores = gui_settings["selected_cpu_cores"]
|
|
407
|
+
|
|
408
|
+
if "recent_tool" in gui_settings and gui_settings["recent_tool"] is not None:
|
|
409
|
+
self.recent_tool = gui_settings["recent_tool"]
|
|
410
|
+
api_result = self.get_bera_tool_api(self.recent_tool)
|
|
411
|
+
if not api_result:
|
|
263
412
|
self.recent_tool = None
|
|
264
|
-
|
|
265
413
|
def load_gui_data(self):
|
|
266
414
|
gui_settings = {}
|
|
267
415
|
if not self.gui_setting_file.exists():
|
|
268
416
|
print("gui.json not exist.")
|
|
269
417
|
else:
|
|
270
418
|
# read the settings.json file if it exists
|
|
271
|
-
with open(self.gui_setting_file,
|
|
419
|
+
with open(self.gui_setting_file, "r") as file_gui:
|
|
272
420
|
try:
|
|
273
421
|
gui_settings = json.load(file_gui)
|
|
274
422
|
except json.decoder.JSONDecodeError:
|
|
275
423
|
pass
|
|
276
424
|
|
|
277
425
|
# parse file
|
|
278
|
-
if
|
|
279
|
-
bera_art =
|
|
280
|
-
for line_of_art in gui_settings[
|
|
426
|
+
if "ascii_art" in gui_settings.keys():
|
|
427
|
+
bera_art = ""
|
|
428
|
+
for line_of_art in gui_settings["ascii_art"]:
|
|
281
429
|
bera_art += line_of_art
|
|
282
430
|
self.ascii_art = bera_art
|
|
283
431
|
|
|
284
432
|
def get_tool_history(self):
|
|
285
|
-
tool_history =
|
|
286
|
-
self.load_saved_tool_info()
|
|
287
|
-
if self.settings:
|
|
288
|
-
if 'tool_history' in self.settings:
|
|
289
|
-
tool_history = self.settings['tool_history']
|
|
433
|
+
tool_history = self.settings_manager.get_tool_history()
|
|
290
434
|
|
|
291
435
|
if tool_history:
|
|
292
436
|
self.tool_history = []
|
|
@@ -295,46 +439,34 @@ class BTData(object):
|
|
|
295
439
|
self.tool_history.append(item)
|
|
296
440
|
|
|
297
441
|
def get_saved_tool_params(self, tool_api, variable=None):
|
|
298
|
-
self.
|
|
299
|
-
|
|
300
|
-
if 'tool_history' in self.settings:
|
|
301
|
-
if tool_api in list(self.settings['tool_history']):
|
|
302
|
-
tool_params = self.settings['tool_history'][tool_api]
|
|
303
|
-
if tool_params:
|
|
304
|
-
if variable:
|
|
305
|
-
if variable in tool_params.keys():
|
|
306
|
-
saved_value = tool_params[variable]
|
|
307
|
-
return saved_value
|
|
308
|
-
else: # return all params
|
|
309
|
-
return tool_params
|
|
310
|
-
|
|
311
|
-
return None
|
|
442
|
+
return self.settings_manager.get_saved_tool_params(tool_api, variable)
|
|
312
443
|
|
|
313
444
|
def get_bera_tools(self):
|
|
314
|
-
|
|
315
|
-
if
|
|
316
|
-
|
|
317
|
-
|
|
445
|
+
tool_json_path = Path(self.current_file_path).joinpath(bt_const.ASSETS_PATH, r"beratools.json")
|
|
446
|
+
if tool_json_path.exists():
|
|
447
|
+
with open(tool_json_path, "r") as tool_json_file:
|
|
448
|
+
self.bera_tools = json.load(tool_json_file)
|
|
318
449
|
else:
|
|
319
|
-
print(
|
|
450
|
+
print("Tool configuration file not exists")
|
|
320
451
|
|
|
321
452
|
def get_bera_tool_list(self):
|
|
322
453
|
self.tools_list = []
|
|
323
454
|
self.sorted_tools = []
|
|
324
455
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
456
|
+
if self.bera_tools and "toolbox" in self.bera_tools:
|
|
457
|
+
for toolbox in self.bera_tools["toolbox"]:
|
|
458
|
+
category = []
|
|
459
|
+
for item in toolbox["tools"]:
|
|
460
|
+
if item["name"]:
|
|
461
|
+
category.append(item["name"])
|
|
462
|
+
self.tools_list.append(item["name"]) # add tool to list
|
|
331
463
|
|
|
332
|
-
|
|
464
|
+
self.sorted_tools.append(category)
|
|
333
465
|
|
|
334
466
|
def sort_toolboxes(self):
|
|
335
467
|
for toolbox in self.toolbox_list:
|
|
336
468
|
# Does not contain a sub toolbox, i.e. does not contain '/'
|
|
337
|
-
if toolbox.find(
|
|
469
|
+
if toolbox.find("/") == (-1):
|
|
338
470
|
# add to both upper toolbox list and lower toolbox list
|
|
339
471
|
self.upper_toolboxes.append(toolbox)
|
|
340
472
|
self.lower_toolboxes.append(toolbox)
|
|
@@ -343,139 +475,358 @@ class BTData(object):
|
|
|
343
475
|
|
|
344
476
|
def get_bera_toolboxes(self):
|
|
345
477
|
toolboxes = []
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
478
|
+
if self.bera_tools and "toolbox" in self.bera_tools:
|
|
479
|
+
for toolbox in self.bera_tools["toolbox"]:
|
|
480
|
+
tb = toolbox["category"]
|
|
481
|
+
toolboxes.append(tb)
|
|
482
|
+
|
|
483
|
+
self.toolbox_list = toolboxes
|
|
484
|
+
else:
|
|
485
|
+
self.toolbox_list = []
|
|
486
|
+
|
|
487
|
+
def _set_param_flag_and_saved_value(self, single_param, param, tool):
|
|
488
|
+
"""Set parameter variable and load saved value if it exists in beratools.json."""
|
|
489
|
+
saved_value = None
|
|
490
|
+
if "variable" in param.keys():
|
|
491
|
+
single_param["variable"] = param["variable"]
|
|
492
|
+
# Only load saved value if tool API exists - discard if API changed
|
|
493
|
+
saved_value = self.get_saved_tool_params(tool["tool_api"], param["variable"])
|
|
494
|
+
if saved_value is not None:
|
|
495
|
+
single_param["saved_value"] = saved_value
|
|
496
|
+
|
|
497
|
+
def _set_param_type_for_input(self, single_param, param):
|
|
498
|
+
# Assume subtype is already a list
|
|
499
|
+
subtypes = param["subtype"]
|
|
500
|
+
|
|
501
|
+
# No mapping, use raw subtypes directly
|
|
502
|
+
if param["type"] == "list":
|
|
503
|
+
single_param["parameter_type"] = {"OptionList": param["data"]}
|
|
504
|
+
single_param["data_type"] = subtypes
|
|
505
|
+
elif param["type"] == "text":
|
|
506
|
+
single_param["parameter_type"] = "Text"
|
|
507
|
+
elif param["type"] == "number":
|
|
508
|
+
single_param["parameter_type"] = subtypes
|
|
509
|
+
elif param["type"] == "file":
|
|
510
|
+
single_param["parameter_type"] = {"ExistingFile": subtypes}
|
|
511
|
+
elif param["type"] == "directory":
|
|
512
|
+
single_param["parameter_type"] = {"Directory": subtypes}
|
|
513
|
+
else:
|
|
514
|
+
raise ValueError(f"Unknown parameter type: {param['type']}")
|
|
349
515
|
|
|
350
|
-
|
|
516
|
+
def _set_param_type_for_output(self, single_param, param):
|
|
517
|
+
# Assume subtype is already a list
|
|
518
|
+
subtypes = param["subtype"]
|
|
519
|
+
single_param["parameter_type"] = {"NewFile": subtypes}
|
|
351
520
|
|
|
352
|
-
def
|
|
353
|
-
|
|
354
|
-
tool
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
521
|
+
def _find_tool_params(self, tool_name):
|
|
522
|
+
"""
|
|
523
|
+
Find raw tool parameters by name.
|
|
524
|
+
|
|
525
|
+
Eliminates duplication across multiple methods.
|
|
526
|
+
|
|
527
|
+
Returns:
|
|
528
|
+
List of parameter definitions from beratools.json, or empty list if not found.
|
|
529
|
+
"""
|
|
530
|
+
if self.bera_tools and "toolbox" in self.bera_tools:
|
|
531
|
+
for toolbox in self.bera_tools["toolbox"]:
|
|
532
|
+
for single_tool in toolbox["tools"]:
|
|
533
|
+
if tool_name == single_tool["name"]:
|
|
534
|
+
return single_tool.get("parameters", [])
|
|
535
|
+
return []
|
|
536
|
+
|
|
537
|
+
def validate_tool_parameter(self, value, param_def):
|
|
538
|
+
"""
|
|
539
|
+
Validate and convert parameter to correct type based on beratools.json definition.
|
|
540
|
+
|
|
541
|
+
Orchestrates validation by dispatching to type-specific validators.
|
|
542
|
+
|
|
543
|
+
Args:
|
|
544
|
+
value: The value from GUI input
|
|
545
|
+
param_def: The original parameter definition from beratools.json
|
|
546
|
+
|
|
547
|
+
Returns:
|
|
548
|
+
Converted and validated value
|
|
549
|
+
|
|
550
|
+
Raises:
|
|
551
|
+
ValueError: If validation fails
|
|
552
|
+
"""
|
|
553
|
+
# GUARD CLAUSE 1: Handle None/empty for optional parameters
|
|
554
|
+
if value is None or value == "":
|
|
555
|
+
if param_def.get("optional", False):
|
|
556
|
+
return param_def.get("default", None)
|
|
557
|
+
|
|
558
|
+
# GUARD CLAUSE 2: Skip validation for output parameters (they don't exist yet)
|
|
559
|
+
if param_def.get("output", False):
|
|
560
|
+
return value
|
|
561
|
+
|
|
562
|
+
# DISPATCH to type-specific validator
|
|
563
|
+
param_type = param_def.get("type")
|
|
564
|
+
if param_type == "number":
|
|
565
|
+
return self._validate_number(value, param_def)
|
|
566
|
+
elif param_type == "file":
|
|
567
|
+
return self._validate_file(value, param_def)
|
|
568
|
+
elif param_type == "directory":
|
|
569
|
+
return self._validate_directory(value, param_def)
|
|
570
|
+
elif param_type == "text":
|
|
571
|
+
return self._validate_text(value, param_def)
|
|
572
|
+
elif param_type == "list":
|
|
573
|
+
return self._validate_list(value, param_def)
|
|
574
|
+
|
|
575
|
+
return value
|
|
576
|
+
|
|
577
|
+
def _validate_number(self, value, param_def):
|
|
578
|
+
"""Validate and convert numeric types (int, float)."""
|
|
579
|
+
subtype = param_def.get("subtype", "")
|
|
580
|
+
variable = param_def.get("variable", "unknown")
|
|
581
|
+
|
|
582
|
+
if subtype == "int":
|
|
583
|
+
if not isinstance(value, int) or isinstance(value, bool):
|
|
584
|
+
try:
|
|
585
|
+
value = int(value)
|
|
586
|
+
except (ValueError, TypeError):
|
|
587
|
+
raise ValueError(f"Parameter '{variable}' must be an integer, got {type(value).__name__}")
|
|
588
|
+
|
|
589
|
+
elif subtype == "float":
|
|
590
|
+
if not isinstance(value, (int, float)) or isinstance(value, bool):
|
|
591
|
+
try:
|
|
592
|
+
value = float(value)
|
|
593
|
+
except (ValueError, TypeError):
|
|
594
|
+
raise ValueError(f"Parameter '{variable}' must be a number, got {type(value).__name__}")
|
|
595
|
+
|
|
596
|
+
return value
|
|
597
|
+
|
|
598
|
+
def _validate_file(self, value, param_def):
|
|
599
|
+
"""Validate file exists and is accessible."""
|
|
600
|
+
variable = param_def.get("variable", "unknown")
|
|
601
|
+
|
|
602
|
+
if not isinstance(value, str):
|
|
603
|
+
raise ValueError(f"Parameter '{variable}' must be a file path string")
|
|
604
|
+
|
|
605
|
+
# Extract file path and layer name (supports both | and :: separators)
|
|
606
|
+
actual_file_path, layer_name = decode_file_layer(value)
|
|
607
|
+
file_path = Path(actual_file_path)
|
|
608
|
+
|
|
609
|
+
if not file_path.exists():
|
|
610
|
+
raise ValueError(f"File not found: {actual_file_path}")
|
|
611
|
+
if not file_path.is_file():
|
|
612
|
+
raise ValueError(f"Path is not a file: {actual_file_path}")
|
|
613
|
+
|
|
614
|
+
return value
|
|
615
|
+
|
|
616
|
+
def _validate_directory(self, value, param_def):
|
|
617
|
+
"""Validate directory exists and is accessible."""
|
|
618
|
+
variable = param_def.get("variable", "unknown")
|
|
619
|
+
|
|
620
|
+
if not isinstance(value, str):
|
|
621
|
+
raise ValueError(f"Parameter '{variable}' must be a directory path string")
|
|
622
|
+
|
|
623
|
+
dir_path = Path(value)
|
|
624
|
+
|
|
625
|
+
if not dir_path.exists():
|
|
626
|
+
raise ValueError(f"Directory not found: {value}")
|
|
627
|
+
if not dir_path.is_dir():
|
|
628
|
+
raise ValueError(f"Path is not a directory: {value}")
|
|
629
|
+
|
|
630
|
+
return value
|
|
631
|
+
|
|
632
|
+
def _validate_text(self, value, param_def):
|
|
633
|
+
"""Validate and convert to text/string type."""
|
|
634
|
+
variable = param_def.get("variable", "unknown")
|
|
635
|
+
|
|
636
|
+
if not isinstance(value, str):
|
|
637
|
+
try:
|
|
638
|
+
value = str(value)
|
|
639
|
+
except Exception:
|
|
640
|
+
raise ValueError(f"Parameter '{variable}' must be text/string")
|
|
641
|
+
|
|
642
|
+
return value
|
|
643
|
+
|
|
644
|
+
def _validate_list(self, value, param_def):
|
|
645
|
+
"""Validate list parameter with allowed values and type conversion."""
|
|
646
|
+
subtype = param_def.get("subtype", "")
|
|
647
|
+
variable = param_def.get("variable", "unknown")
|
|
648
|
+
allowed_values = param_def.get("data", [])
|
|
649
|
+
|
|
650
|
+
# Convert to correct type based on subtype
|
|
651
|
+
if subtype == "bool":
|
|
652
|
+
value = self._convert_bool(value, variable)
|
|
653
|
+
elif subtype == "int":
|
|
654
|
+
value = self._convert_int(value, variable)
|
|
655
|
+
elif subtype == "float":
|
|
656
|
+
value = self._convert_float(value, variable)
|
|
657
|
+
|
|
658
|
+
# Validate against allowed values
|
|
659
|
+
if value not in allowed_values:
|
|
660
|
+
raise ValueError(
|
|
661
|
+
f"Parameter '{variable}' value '{value}' not in allowed options: {allowed_values}"
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
return value
|
|
665
|
+
|
|
666
|
+
def _convert_bool(self, value, variable):
|
|
667
|
+
"""Convert value to boolean."""
|
|
668
|
+
if isinstance(value, str):
|
|
669
|
+
if value.lower() in ["true", "1", "yes"]:
|
|
670
|
+
return True
|
|
671
|
+
elif value.lower() in ["false", "0", "no"]:
|
|
672
|
+
return False
|
|
673
|
+
else:
|
|
674
|
+
raise ValueError(f"Parameter '{variable}' must be boolean, got '{value}'")
|
|
675
|
+
elif not isinstance(value, bool):
|
|
676
|
+
try:
|
|
677
|
+
return bool(value)
|
|
678
|
+
except Exception:
|
|
679
|
+
raise ValueError(f"Parameter '{variable}' must be boolean")
|
|
680
|
+
return value
|
|
681
|
+
|
|
682
|
+
def _convert_int(self, value, variable):
|
|
683
|
+
"""Convert value to integer."""
|
|
684
|
+
if not isinstance(value, int) or isinstance(value, bool):
|
|
685
|
+
try:
|
|
686
|
+
return int(value)
|
|
687
|
+
except (ValueError, TypeError):
|
|
688
|
+
raise ValueError(f"Parameter '{variable}' must be integer")
|
|
689
|
+
return value
|
|
690
|
+
|
|
691
|
+
def _convert_float(self, value, variable):
|
|
692
|
+
"""Convert value to float."""
|
|
693
|
+
if not isinstance(value, (int, float)) or isinstance(value, bool):
|
|
694
|
+
try:
|
|
695
|
+
return float(value)
|
|
696
|
+
except (ValueError, TypeError):
|
|
697
|
+
raise ValueError(f"Parameter '{variable}' must be float")
|
|
698
|
+
return value
|
|
699
|
+
|
|
700
|
+
def validate_tool_params(self, tool_name, kwargs):
|
|
701
|
+
"""
|
|
702
|
+
Validate and convert all tool parameters against beratools.json definitions.
|
|
703
|
+
|
|
704
|
+
Args:
|
|
705
|
+
tool_name: Tool name to lookup in beratools.json
|
|
706
|
+
kwargs: Dict of parameter values from GUI input
|
|
707
|
+
|
|
708
|
+
Returns:
|
|
709
|
+
Dict of validated/converted values
|
|
710
|
+
|
|
711
|
+
Raises:
|
|
712
|
+
ValueError: If any parameter validation fails
|
|
713
|
+
"""
|
|
714
|
+
raw_params = self._find_tool_params(tool_name)
|
|
715
|
+
|
|
716
|
+
# Build a mapping of variable -> beratools.json param definition
|
|
717
|
+
params_by_variable = {}
|
|
718
|
+
for param in raw_params:
|
|
719
|
+
if "variable" in param:
|
|
720
|
+
params_by_variable[param["variable"]] = param
|
|
721
|
+
|
|
722
|
+
validated_kwargs = {}
|
|
723
|
+
for key, value in kwargs.items():
|
|
724
|
+
# Skip framework parameters (handled separately)
|
|
725
|
+
if key in ["processes", "call_mode", "log_level"]:
|
|
726
|
+
validated_kwargs[key] = value
|
|
727
|
+
continue
|
|
728
|
+
|
|
729
|
+
# Validate tool parameters against beratools.json definitions
|
|
730
|
+
if key in params_by_variable:
|
|
731
|
+
param_def = params_by_variable[key]
|
|
732
|
+
try:
|
|
733
|
+
validated_value = self.validate_tool_parameter(value, param_def)
|
|
734
|
+
validated_kwargs[key] = validated_value
|
|
735
|
+
except ValueError as e:
|
|
736
|
+
raise ValueError(f"Invalid argument '{key}': {str(e)}")
|
|
737
|
+
else:
|
|
738
|
+
# Unknown parameter - pass through (may be framework param or typo)
|
|
739
|
+
validated_kwargs[key] = value
|
|
360
740
|
|
|
361
|
-
|
|
362
|
-
tool = single_tool
|
|
741
|
+
return validated_kwargs
|
|
363
742
|
|
|
743
|
+
def get_bera_tool_params(self, tool_name):
|
|
744
|
+
new_param_whole = {"parameters": []}
|
|
745
|
+
tool = {}
|
|
746
|
+
|
|
747
|
+
# Find tool in beratools.json
|
|
748
|
+
if self.bera_tools and "toolbox" in self.bera_tools:
|
|
749
|
+
for toolbox in self.bera_tools["toolbox"]:
|
|
750
|
+
for single_tool in toolbox["tools"]:
|
|
751
|
+
if tool_name == single_tool["name"]:
|
|
752
|
+
tool = single_tool
|
|
753
|
+
|
|
754
|
+
# Copy non-parameter fields to result
|
|
364
755
|
for key, value in tool.items():
|
|
365
|
-
if key !=
|
|
756
|
+
if key != "parameters":
|
|
366
757
|
new_param_whole[key] = value
|
|
367
758
|
|
|
368
759
|
# convert json format for parameters
|
|
369
|
-
if
|
|
370
|
-
print(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
single_param['output'] = param['output']
|
|
384
|
-
if not param['output']:
|
|
385
|
-
if param['type'] == 'list':
|
|
386
|
-
if tool_name == 'Batch Processing':
|
|
387
|
-
single_param['parameter_type'] = {'OptionList': batch_tool_list}
|
|
388
|
-
single_param['data_type'] = 'String'
|
|
389
|
-
else:
|
|
390
|
-
single_param['parameter_type'] = {'OptionList': param['data']}
|
|
391
|
-
single_param['data_type'] = 'String'
|
|
392
|
-
if param['typelab'] == 'text':
|
|
393
|
-
single_param['data_type'] = 'String'
|
|
394
|
-
elif param['typelab'] == 'int':
|
|
395
|
-
single_param['data_type'] = 'Integer'
|
|
396
|
-
elif param['typelab'] == 'float':
|
|
397
|
-
single_param['data_type'] = 'Float'
|
|
398
|
-
elif param['typelab'] == 'bool':
|
|
399
|
-
single_param['data_type'] = 'Boolean'
|
|
400
|
-
elif param['type'] == 'text':
|
|
401
|
-
single_param['parameter_type'] = 'String'
|
|
402
|
-
elif param['type'] == 'number':
|
|
403
|
-
if param['typelab'] == 'int':
|
|
404
|
-
single_param['parameter_type'] = 'Integer'
|
|
405
|
-
else:
|
|
406
|
-
single_param['parameter_type'] = 'Float'
|
|
407
|
-
elif param['type'] == 'file':
|
|
408
|
-
single_param['parameter_type'] = {'ExistingFile': [param['typelab']]}
|
|
760
|
+
if "parameters" not in tool.keys():
|
|
761
|
+
print("issue")
|
|
762
|
+
|
|
763
|
+
parameters = self._find_tool_params(tool_name)
|
|
764
|
+
if parameters:
|
|
765
|
+
for param in parameters:
|
|
766
|
+
# Parse subtype string to list once, here
|
|
767
|
+
if isinstance(param.get("subtype", ""), str):
|
|
768
|
+
param["subtype"] = [s.strip() for s in param["subtype"].split("|")]
|
|
769
|
+
single_param = {"name": param["label"]}
|
|
770
|
+
self._set_param_flag_and_saved_value(single_param, param, tool)
|
|
771
|
+
single_param["output"] = param["output"]
|
|
772
|
+
if not param["output"]:
|
|
773
|
+
self._set_param_type_for_input(single_param, param)
|
|
409
774
|
else:
|
|
410
|
-
single_param
|
|
411
|
-
|
|
412
|
-
single_param["
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
if param['type'] == 'raster':
|
|
417
|
-
for i in single_param["parameter_type"].keys():
|
|
418
|
-
single_param['parameter_type'][i] = 'Raster'
|
|
419
|
-
elif param['type'] == 'lidar':
|
|
420
|
-
for i in single_param["parameter_type"].keys():
|
|
421
|
-
single_param['parameter_type'][i] = 'Lidar'
|
|
422
|
-
elif param['type'] == 'vector':
|
|
423
|
-
for i in single_param["parameter_type"].keys():
|
|
424
|
-
single_param['parameter_type'][i] = 'Vector'
|
|
425
|
-
if 'layer' in param.keys():
|
|
426
|
-
layer_value = self.get_saved_tool_params(tool['tool_api'], param['layer'])
|
|
427
|
-
single_param['layer'] = {'layer_name': param['layer'], 'layer_value': layer_value}
|
|
428
|
-
|
|
429
|
-
elif param['type'] == 'Directory':
|
|
430
|
-
single_param['parameter_type'] = {'Directory': [param['typelab']]}
|
|
431
|
-
|
|
432
|
-
single_param['default_value'] = param['default']
|
|
433
|
-
if "optional" in param.keys():
|
|
434
|
-
single_param['optional'] = param['optional']
|
|
435
|
-
else:
|
|
436
|
-
single_param['optional'] = False
|
|
775
|
+
self._set_param_type_for_output(single_param, param)
|
|
776
|
+
|
|
777
|
+
single_param["description"] = param["description"]
|
|
778
|
+
|
|
779
|
+
single_param["default_value"] = param["default"]
|
|
780
|
+
single_param["optional"] = param.get("optional", False)
|
|
437
781
|
|
|
438
|
-
|
|
782
|
+
new_param_whole["parameters"].append(single_param)
|
|
439
783
|
|
|
440
784
|
return new_param_whole
|
|
441
785
|
|
|
442
786
|
def get_bera_tool_parameters_list(self, tool_name):
|
|
443
787
|
params = self.get_bera_tool_params(tool_name)
|
|
444
788
|
param_list = {}
|
|
445
|
-
|
|
446
|
-
|
|
789
|
+
parameters = params.get("parameters")
|
|
790
|
+
if parameters is None:
|
|
791
|
+
return param_list
|
|
792
|
+
for item in parameters:
|
|
793
|
+
if item is not None and "variable" in item and "default_value" in item:
|
|
794
|
+
param_list[item["variable"]] = item["default_value"]
|
|
447
795
|
|
|
448
796
|
return param_list
|
|
449
797
|
|
|
450
798
|
def get_bera_tool_args(self, tool_name):
|
|
451
799
|
params = self.get_bera_tool_params(tool_name)
|
|
452
|
-
tool_args = params[
|
|
800
|
+
tool_args = params["parameters"]
|
|
453
801
|
|
|
454
802
|
return tool_args
|
|
455
803
|
|
|
456
804
|
def get_bera_tool_name(self, tool_api):
|
|
457
805
|
tool_name = None
|
|
458
|
-
|
|
459
|
-
for
|
|
460
|
-
|
|
461
|
-
|
|
806
|
+
if self.bera_tools and "toolbox" in self.bera_tools:
|
|
807
|
+
for toolbox in self.bera_tools["toolbox"]:
|
|
808
|
+
for tool in toolbox["tools"]:
|
|
809
|
+
if tool_api == tool["tool_api"]:
|
|
810
|
+
tool_name = tool["name"]
|
|
462
811
|
|
|
463
812
|
return tool_name
|
|
464
813
|
|
|
465
814
|
def get_bera_tool_api(self, tool_name):
|
|
466
815
|
tool_api = None
|
|
467
|
-
|
|
468
|
-
for
|
|
469
|
-
|
|
470
|
-
|
|
816
|
+
if self.bera_tools and "toolbox" in self.bera_tools:
|
|
817
|
+
for toolbox in self.bera_tools["toolbox"]:
|
|
818
|
+
for tool in toolbox["tools"]:
|
|
819
|
+
if tool_name == tool["name"]:
|
|
820
|
+
tool_api = tool["tool_api"]
|
|
471
821
|
|
|
472
822
|
return tool_api
|
|
473
823
|
|
|
474
824
|
def get_bera_tool_type(self, tool_name):
|
|
475
825
|
tool_type = None
|
|
476
|
-
|
|
477
|
-
for
|
|
478
|
-
|
|
479
|
-
|
|
826
|
+
if self.bera_tools and "toolbox" in self.bera_tools:
|
|
827
|
+
for toolbox in self.bera_tools["toolbox"]:
|
|
828
|
+
for tool in toolbox["tools"]:
|
|
829
|
+
if tool_name == tool["name"]:
|
|
830
|
+
tool_type = tool["tool_type"]
|
|
480
831
|
|
|
481
832
|
return tool_type
|