BERATools 0.2.0__py3-none-any.whl → 0.2.2__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.
Files changed (153) hide show
  1. beratools/__init__.py +1 -7
  2. beratools/core/algo_centerline.py +491 -351
  3. beratools/core/algo_common.py +497 -0
  4. beratools/core/algo_cost.py +192 -0
  5. beratools/core/{dijkstra_algorithm.py → algo_dijkstra.py} +503 -460
  6. beratools/core/algo_footprint_rel.py +577 -0
  7. beratools/core/algo_line_grouping.py +944 -0
  8. beratools/core/algo_merge_lines.py +214 -0
  9. beratools/core/algo_split_with_lines.py +304 -0
  10. beratools/core/algo_tiler.py +428 -0
  11. beratools/core/algo_vertex_optimization.py +469 -0
  12. beratools/core/constants.py +52 -86
  13. beratools/core/logger.py +76 -85
  14. beratools/core/tool_base.py +196 -133
  15. beratools/gui/__init__.py +11 -15
  16. beratools/gui/{beratools.json → assets/beratools.json} +2185 -2300
  17. beratools/gui/batch_processing_dlg.py +513 -463
  18. beratools/gui/bt_data.py +481 -487
  19. beratools/gui/bt_gui_main.py +710 -691
  20. beratools/gui/main.py +26 -0
  21. beratools/gui/map_window.py +162 -146
  22. beratools/gui/tool_widgets.py +725 -493
  23. beratools/tools/Beratools_r_script.r +1120 -1120
  24. beratools/tools/Ht_metrics.py +116 -116
  25. beratools/tools/__init__.py +7 -7
  26. beratools/tools/batch_processing.py +136 -132
  27. beratools/tools/canopy_threshold_relative.py +672 -670
  28. beratools/tools/canopycostraster.py +222 -222
  29. beratools/tools/centerline.py +136 -176
  30. beratools/tools/common.py +857 -885
  31. beratools/tools/fl_regen_csf.py +428 -428
  32. beratools/tools/forest_line_attributes.py +408 -408
  33. beratools/tools/line_footprint_absolute.py +213 -363
  34. beratools/tools/line_footprint_fixed.py +436 -282
  35. beratools/tools/line_footprint_functions.py +733 -720
  36. beratools/tools/line_footprint_relative.py +73 -64
  37. beratools/tools/line_grouping.py +45 -0
  38. beratools/tools/ln_relative_metrics.py +615 -615
  39. beratools/tools/r_cal_lpi_elai.r +24 -24
  40. beratools/tools/r_generate_pd_focalraster.r +100 -100
  41. beratools/tools/r_interface.py +79 -79
  42. beratools/tools/r_point_density.r +8 -8
  43. beratools/tools/rpy_chm2trees.py +86 -86
  44. beratools/tools/rpy_dsm_chm_by.py +81 -81
  45. beratools/tools/rpy_dtm_by.py +63 -63
  46. beratools/tools/rpy_find_cellsize.py +43 -43
  47. beratools/tools/rpy_gnd_csf.py +74 -74
  48. beratools/tools/rpy_hummock_hollow.py +85 -85
  49. beratools/tools/rpy_hummock_hollow_raster.py +71 -71
  50. beratools/tools/rpy_las_info.py +51 -51
  51. beratools/tools/rpy_laz2las.py +40 -40
  52. beratools/tools/rpy_lpi_elai_lascat.py +466 -466
  53. beratools/tools/rpy_normalized_lidar_by.py +56 -56
  54. beratools/tools/rpy_percent_above_dbh.py +80 -80
  55. beratools/tools/rpy_points2trees.py +88 -88
  56. beratools/tools/rpy_vegcoverage.py +94 -94
  57. beratools/tools/tiler.py +48 -206
  58. beratools/tools/tool_template.py +69 -54
  59. beratools/tools/vertex_optimization.py +61 -620
  60. beratools/tools/zonal_threshold.py +144 -144
  61. beratools-0.2.2.dist-info/METADATA +108 -0
  62. beratools-0.2.2.dist-info/RECORD +74 -0
  63. {beratools-0.2.0.dist-info → beratools-0.2.2.dist-info}/WHEEL +1 -1
  64. {beratools-0.2.0.dist-info → beratools-0.2.2.dist-info}/licenses/LICENSE +22 -22
  65. beratools/gui/cli.py +0 -18
  66. beratools/gui/gui.json +0 -8
  67. beratools/gui_tk/ASCII Banners.txt +0 -248
  68. beratools/gui_tk/__init__.py +0 -20
  69. beratools/gui_tk/beratools_main.py +0 -515
  70. beratools/gui_tk/bt_widgets.py +0 -442
  71. beratools/gui_tk/cli.py +0 -18
  72. beratools/gui_tk/img/BERALogo.png +0 -0
  73. beratools/gui_tk/img/closed.gif +0 -0
  74. beratools/gui_tk/img/closed.png +0 -0
  75. beratools/gui_tk/img/open.gif +0 -0
  76. beratools/gui_tk/img/open.png +0 -0
  77. beratools/gui_tk/img/tool.gif +0 -0
  78. beratools/gui_tk/img/tool.png +0 -0
  79. beratools/gui_tk/main.py +0 -14
  80. beratools/gui_tk/map_window.py +0 -144
  81. beratools/gui_tk/runner.py +0 -1481
  82. beratools/gui_tk/tooltip.py +0 -55
  83. beratools/third_party/pyqtlet2/__init__.py +0 -9
  84. beratools/third_party/pyqtlet2/leaflet/__init__.py +0 -26
  85. beratools/third_party/pyqtlet2/leaflet/control/__init__.py +0 -6
  86. beratools/third_party/pyqtlet2/leaflet/control/control.py +0 -59
  87. beratools/third_party/pyqtlet2/leaflet/control/draw.py +0 -52
  88. beratools/third_party/pyqtlet2/leaflet/control/layers.py +0 -20
  89. beratools/third_party/pyqtlet2/leaflet/core/Parser.py +0 -24
  90. beratools/third_party/pyqtlet2/leaflet/core/__init__.py +0 -2
  91. beratools/third_party/pyqtlet2/leaflet/core/evented.py +0 -180
  92. beratools/third_party/pyqtlet2/leaflet/layer/__init__.py +0 -5
  93. beratools/third_party/pyqtlet2/leaflet/layer/featuregroup.py +0 -34
  94. beratools/third_party/pyqtlet2/leaflet/layer/icon/__init__.py +0 -1
  95. beratools/third_party/pyqtlet2/leaflet/layer/icon/icon.py +0 -30
  96. beratools/third_party/pyqtlet2/leaflet/layer/imageoverlay.py +0 -18
  97. beratools/third_party/pyqtlet2/leaflet/layer/layer.py +0 -105
  98. beratools/third_party/pyqtlet2/leaflet/layer/layergroup.py +0 -45
  99. beratools/third_party/pyqtlet2/leaflet/layer/marker/__init__.py +0 -1
  100. beratools/third_party/pyqtlet2/leaflet/layer/marker/marker.py +0 -91
  101. beratools/third_party/pyqtlet2/leaflet/layer/tile/__init__.py +0 -2
  102. beratools/third_party/pyqtlet2/leaflet/layer/tile/gridlayer.py +0 -4
  103. beratools/third_party/pyqtlet2/leaflet/layer/tile/tilelayer.py +0 -16
  104. beratools/third_party/pyqtlet2/leaflet/layer/vector/__init__.py +0 -5
  105. beratools/third_party/pyqtlet2/leaflet/layer/vector/circle.py +0 -15
  106. beratools/third_party/pyqtlet2/leaflet/layer/vector/circlemarker.py +0 -18
  107. beratools/third_party/pyqtlet2/leaflet/layer/vector/path.py +0 -5
  108. beratools/third_party/pyqtlet2/leaflet/layer/vector/polygon.py +0 -14
  109. beratools/third_party/pyqtlet2/leaflet/layer/vector/polyline.py +0 -18
  110. beratools/third_party/pyqtlet2/leaflet/layer/vector/rectangle.py +0 -14
  111. beratools/third_party/pyqtlet2/leaflet/map/__init__.py +0 -1
  112. beratools/third_party/pyqtlet2/leaflet/map/map.py +0 -220
  113. beratools/third_party/pyqtlet2/mapwidget.py +0 -45
  114. beratools/third_party/pyqtlet2/web/custom.js +0 -43
  115. beratools/third_party/pyqtlet2/web/map.html +0 -23
  116. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers-2x.png +0 -0
  117. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers.png +0 -0
  118. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon-2x.png +0 -0
  119. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon.png +0 -0
  120. beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-shadow.png +0 -0
  121. beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.css +0 -656
  122. beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.js +0 -6
  123. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.codeclimate.yml +0 -14
  124. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.editorconfig +0 -4
  125. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.gitattributes +0 -22
  126. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.travis.yml +0 -43
  127. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/LICENSE +0 -20
  128. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers-2x.png +0 -0
  129. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers.png +0 -0
  130. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon-2x.png +0 -0
  131. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon.png +0 -0
  132. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-shadow.png +0 -0
  133. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet-2x.png +0 -0
  134. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.png +0 -0
  135. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.svg +0 -156
  136. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.css +0 -10
  137. beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.js +0 -10
  138. beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/LICENSE +0 -22
  139. beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/leaflet.rotatedMarker.js +0 -57
  140. beratools/tools/forest_line_ecosite.py +0 -216
  141. beratools/tools/lapis_all.py +0 -103
  142. beratools/tools/least_cost_path_from_chm.py +0 -152
  143. beratools-0.2.0.dist-info/METADATA +0 -63
  144. beratools-0.2.0.dist-info/RECORD +0 -142
  145. /beratools/gui/{img → assets}/BERALogo.png +0 -0
  146. /beratools/gui/{img → assets}/closed.gif +0 -0
  147. /beratools/gui/{img → assets}/closed.png +0 -0
  148. /beratools/{gui_tk → gui/assets}/gui.json +0 -0
  149. /beratools/gui/{img → assets}/open.gif +0 -0
  150. /beratools/gui/{img → assets}/open.png +0 -0
  151. /beratools/gui/{img → assets}/tool.gif +0 -0
  152. /beratools/gui/{img → assets}/tool.png +0 -0
  153. {beratools-0.2.0.dist-info → beratools-0.2.2.dist-info}/entry_points.txt +0 -0
beratools/tools/tiler.py CHANGED
@@ -1,206 +1,48 @@
1
- import os
2
- from qtpy.QtWidgets import QApplication, QDialog
3
-
4
- from shapely.geometry import Polygon
5
- from beratools.tools.common import *
6
- from beratools.gui.map_window import MapWindow
7
-
8
-
9
- class Tiler:
10
- def __init__(self, callback, in_line, in_chm, tile_size,
11
- tile_buffer, out_project, processes, verbose):
12
-
13
- self.in_line = in_line
14
- self.in_chm = in_chm
15
- self.boundary = None
16
- self.tile_size = float(tile_size)
17
- self.tile_buffer = float(tile_buffer)
18
- self.out_project = out_project
19
- self.processes = processes
20
- self.verbose = verbose
21
- self.clip_data = []
22
- self.proj_path = ''
23
- self.in_crs = None
24
- self.out_crs = None
25
-
26
- def create_out_file_name(self):
27
- # prepare path
28
- # TODO: more formats later, now only tiff and shp are considered
29
- path_chm = Path(self.in_chm)
30
- path_line = Path(self.in_line)
31
- self.proj_path = path_chm.parent
32
- path_root = self.proj_path.joinpath('cells')
33
-
34
- if not path_root.exists():
35
- path_root.mkdir()
36
-
37
- item_count = len(self.clip_data)
38
- str_len = len(str(item_count))
39
- for i, item in enumerate(self.clip_data):
40
- cell_num = str(i).zfill(str_len)
41
- self.clip_data[i]['raster'] = path_root.joinpath(path_chm.stem + '_' + cell_num + '.tif')
42
- self.clip_data[i]['line'] = path_root.joinpath(path_line.stem + '_' + cell_num + '.shp')
43
-
44
- def save_clip_files(self):
45
- project_data = {'tool_api': 'tiler'}
46
- tasks_list = []
47
- step = 0
48
-
49
- print('Generating {} tiles ...'.format(len(self.clip_data)))
50
- for item in self.clip_data:
51
- return_lines = clip_lines(item['geometry'], self.tile_buffer, self.in_line, item['line'])
52
- return_raster = clip_raster(self.in_chm, item['geometry'], self.tile_buffer, item['raster'])
53
-
54
- if not return_lines.empty and return_raster:
55
- cell_data = {
56
- 'in_line': item['line'].as_posix(),
57
- 'in_chm': item['raster'].as_posix()
58
- }
59
- tasks_list.append(cell_data)
60
- step += 1
61
- print('%{}'.format(step / len(self.clip_data) * 100))
62
-
63
- project_data['tasks'] = tasks_list
64
- with open(self.out_project, 'w') as project_file:
65
- json.dump(project_data, project_file, indent=4)
66
-
67
- def generate_cells(self):
68
- part_x = 0
69
- part_y = 0
70
- width = 0
71
- height = 0
72
-
73
- with(rasterio.open(self.in_chm)) as raster:
74
- self.boundary = raster.bounds
75
- width = raster.width
76
- height = raster.height
77
- self.in_crs = raster.crs
78
-
79
- if self.boundary:
80
- part_x = math.ceil(width / self.tile_size)
81
- part_y = math.ceil(height / self.tile_size)
82
- min_x, min_y, max_x, max_y = self.boundary
83
- polygon_bound = Polygon([(min_x, min_y), (min_x, max_y), (max_x, max_y), (max_x, min_y)])
84
-
85
- step_x = (max_x - min_x) / part_x
86
- step_y = (max_y - min_y) / part_y
87
- cells = []
88
- for i in range(part_x):
89
- for j in range(part_y):
90
- cells.append(Polygon([(min_x + i * step_x, min_y + j * step_y),
91
- (min_x + (i + 1) * step_x, min_y + j * step_y),
92
- (min_x + (i + 1) * step_x, min_y + (j + 1) * step_y),
93
- (min_x + i * step_x, min_y + (j + 1) * step_y)]))
94
-
95
- # remove polygons not in boundary
96
- for cell in cells:
97
- if not polygon_bound.disjoint(cell):
98
- self.clip_data.append({'geometry': cell})
99
-
100
- return True
101
-
102
- return False
103
-
104
- def generate_tiles_info(self):
105
- tiles_info = {'count': len(self.clip_data), 'dimension': self.tile_size}
106
- return tiles_info
107
-
108
- def cells_to_coord_list(self):
109
- self.out_crs = CRS('EPSG:4326')
110
- transformer = Transformer.from_crs(self.in_crs, self.out_crs)
111
- coords_list = []
112
- if self.clip_data:
113
- for item in self.clip_data:
114
- geom = item['geometry']
115
- coords = mapping(geom)['coordinates']
116
- if len(coords) > 0:
117
- wgs84_coords = list(transformer.itransform(coords[0]))
118
- wgs84_coords = [list(pt) for pt in wgs84_coords]
119
- coords_list.append(wgs84_coords)
120
-
121
- # find bounds
122
- x = [pt[0] for polygon in coords_list for pt in polygon]
123
- y = [pt[1] for polygon in coords_list for pt in polygon]
124
- x_min = min(x)
125
- x_max = max(x)
126
- y_min = min(y)
127
- y_max = max(y)
128
-
129
- center = [(x_min + x_max) / 2, (y_min + y_max) / 2]
130
-
131
- return coords_list, [[x_min, y_min], [x_max, y_max]], center
132
-
133
- def shapefile_to_coord_list(self):
134
- lines = read_geoms_from_shapefile(self.in_line)
135
- line_coords = []
136
-
137
- coords_list = []
138
- for line in lines:
139
- coords = line['coordinates']
140
- for pt in coords:
141
- coords_list.append(list(pt))
142
-
143
- line_coords.append(coords_list)
144
-
145
- return line_coords
146
-
147
- def execute(self):
148
- if self.generate_cells():
149
- coords_list, bounds, center = self.cells_to_coord_list()
150
- map_window = MapWindow()
151
-
152
- # add lines to map
153
- # lines = self.shapefile_to_coord_list()
154
- # map_window.add_polylines_to_map(lines, 'gray')
155
-
156
- # generate raster footprint and add to the map
157
- footprint = generate_raster_footprint(self.in_chm)
158
-
159
- # add AOI polygon and tile polygons
160
- map_window.set_tiles_info(self.generate_tiles_info())
161
- map_window.add_polygons_to_map('cells', coords_list, 'magenta')
162
- map_window.add_polygons_to_map('base', footprint, 'green')
163
- map_window.set_view(center, 10)
164
- # bounds = [[56.143426823080134, 111.1130415762259], [56.26141944093645, 110.63627702636289]]
165
- flag = map_window.exec()
166
-
167
- if flag != QDialog.Accepted:
168
- return
169
-
170
- self.create_out_file_name()
171
- self.save_clip_files()
172
-
173
- # save polygons to shapefile
174
- out_cells_file = self.proj_path.joinpath('cells.shp')
175
- schema = {
176
- 'geometry': 'Polygon'
177
- }
178
- driver = 'ESRI Shapefile'
179
- with fiona.open(out_cells_file, 'w', driver, schema, self.in_crs) as out_line_file:
180
- for item in self.clip_data:
181
- feature = {
182
- 'geometry': mapping(item['geometry'])
183
- }
184
- out_line_file.write(feature)
185
-
186
- return
187
-
188
-
189
- if __name__ == '__main__':
190
- # supress web engine logging
191
- os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--enable-logging --log-level=3"
192
-
193
- app = QApplication(sys.argv)
194
-
195
- parser = argparse.ArgumentParser()
196
- parser.add_argument('-i', '--input', type=json.loads)
197
- parser.add_argument('-p', '--processes')
198
- parser.add_argument('-v', '--verbose')
199
- args = parser.parse_args()
200
-
201
- verbose = True if args.verbose == 'True' else False
202
-
203
- tiling = Tiler(print, **args.input, processes=int(args.processes), verbose=verbose)
204
- tiling.execute()
205
-
206
- sys.exit(app.exec_())
1
+ """
2
+ Copyright (C) 2025 Applied Geospatial Research Group.
3
+
4
+ This script is licensed under the GNU General Public License v3.0.
5
+ See <https://gnu.org/licenses/gpl-3.0> for full license details.
6
+
7
+ Author: Richard Zeng
8
+
9
+ Description:
10
+ This script is part of the BERA Tools.
11
+ Webpage: https://github.com/appliedgrg/beratools
12
+
13
+ The purpose of this script is to split input vector and raster data into
14
+ smaller tiles based on a specified tile size and buffer distance.
15
+ """
16
+
17
+ import time
18
+
19
+ import beratools.tools.common as bt_common
20
+ import beratools.core.algo_tiler as bt_tiler
21
+
22
+ def tiler(
23
+ in_line,
24
+ in_raster,
25
+ out_file,
26
+ n_clusters,
27
+ processes,
28
+ verbose,
29
+ tile_buffer=50,
30
+ in_layer=None,
31
+ ):
32
+ clustering = bt_tiler.DensityBasedClustering(
33
+ in_line=in_line,
34
+ in_raster=in_raster,
35
+ out_file=out_file,
36
+ n_clusters=int(n_clusters),
37
+ tile_buffer=tile_buffer,
38
+ layer=in_layer,
39
+ )
40
+
41
+ clustering.run()
42
+
43
+
44
+ if __name__ == "__main__":
45
+ in_args, in_verbose = bt_common.check_arguments()
46
+ start_time = time.time()
47
+ tiler(**in_args.input, processes=int(in_args.processes), verbose=in_verbose)
48
+ print("Elapsed time: {}".format(time.time() - start_time))
@@ -1,54 +1,69 @@
1
- from random import random
2
- import time
3
- from multiprocessing.pool import Pool
4
- from numpy import mean
5
-
6
- from common import *
7
-
8
-
9
- class OperationCancelledException(Exception):
10
- pass
11
-
12
-
13
- def tool_name(callback, in_line, in_cost_raster, line_radius, process_segments, out_center_line):
14
- execute_multiprocessing()
15
- callback('tool_template tool done.')
16
-
17
-
18
- # task executed in a worker process
19
- def worker(task_data):
20
- # report a message
21
- value = mean(task_data)
22
- print(f'Task {len(task_data)} with {value} executed', flush=True)
23
-
24
- # block for a moment
25
- time.sleep(value * 10)
26
-
27
- # return the generated value
28
- return value
29
-
30
-
31
- # protect the entry point
32
- def execute_multiprocessing():
33
- # create and configure the process pool
34
- data = [[random() for n in range(100)] for i in range(300)]
35
- try:
36
- total_steps = 300
37
- with Pool() as pool:
38
- step = 0
39
- # execute tasks in order, process results out of order
40
- for result in pool.imap_unordered(worker, data):
41
- print(f'Got result: {result}', flush=True)
42
- step += 1
43
- print(step)
44
- print('%{}'.format(step / total_steps * 100))
45
-
46
- except OperationCancelledException:
47
- print("Operation cancelled")
48
-
49
-
50
- if __name__ == '__main__':
51
- in_args, in_verbose = check_arguments()
52
- start_time = time.time()
53
- tool_name(print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose)
54
- print('Elapsed time: {}'.format(time.time() - start_time))
1
+ """
2
+ Copyright (C) 2025 Applied Geospatial Research Group.
3
+
4
+ This script is licensed under the GNU General Public License v3.0.
5
+ See <https://gnu.org/licenses/gpl-3.0> for full license details.
6
+
7
+ Author: AUTHOR NAME
8
+
9
+ Description:
10
+ This script is part of the BERA Tools.
11
+ Webpage: https://github.com/appliedgrg/beratools
12
+
13
+ The purpose of this script is to provide template for tool.
14
+ """
15
+ import time
16
+ from multiprocessing.pool import Pool
17
+ from random import random
18
+
19
+ import numpy as np
20
+
21
+ import beratools.tools.common as bt_common
22
+ from beratools.core.tool_base import execute_multiprocessing
23
+
24
+ # Example task_data as a list of numpy ndarrays
25
+ task_data_list = [
26
+ np.array([1, 2, 3]),
27
+ np.array([4, 5, 6]),
28
+ np.array([7, 8, 9])
29
+ ]
30
+
31
+ def tool_name(
32
+ in_line, in_cost_raster, line_radius, out_line, processes, verbose
33
+ ):
34
+ """
35
+ Define tool entry point.
36
+
37
+ These arguments are defined in beratools.json file.
38
+ execute_multiprocessing is common function to run tasks in parallel.
39
+ """
40
+ result = execute_multiprocessing(
41
+ worker,
42
+ task_data_list,
43
+ "tool_template",
44
+ processes,
45
+ verbose=verbose
46
+ )
47
+ print(len(result))
48
+
49
+
50
+ # task executed in a worker process
51
+ def worker(task_data):
52
+ # report a message
53
+ value = np.mean(task_data)
54
+ print(f'Task with {value} executed', flush=True)
55
+
56
+ # block for a moment
57
+ time.sleep(value * 10)
58
+
59
+ # return the generated value
60
+ return value
61
+
62
+
63
+ if __name__ == '__main__':
64
+ in_args, in_verbose = bt_common.check_arguments()
65
+ start_time = time.time()
66
+ tool_name(
67
+ print, **in_args.input, processes=int(in_args.processes), verbose=in_verbose
68
+ )
69
+ print("Elapsed time: {}".format(time.time() - start_time))