Skip to content

Commit 61cff10

Browse files
authored
Merge pull request #32 from chenyangkang/chenyangkang-JOSS-review
Increase modularization & Removed multi-processing (feature in the future)
2 parents d6cdcf8 + eae6360 commit 61cff10

14 files changed

+750
-705
lines changed

.pre-commit-config.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@
33

44
repos:
55
- repo: https://github.com/ambv/black
6-
rev: 23.1.0
6+
rev: 23.12.1
77
hooks:
88
- id: black
99
args: ["stemflow", "--line-length=120", "--target-version=py37"]
1010

1111
- repo: https://github.com/pycqa/flake8
12-
rev: 6.0.0
12+
rev: 7.0.0
1313
hooks:
1414
- id: flake8
1515
args: ["--select=C,E,F,W,B,B950", "--max-line-length=120", "--ignore=E203,E501,W503,F401,F403"]
1616

1717
- repo: https://github.com/timothycrosley/isort
18-
rev: 5.12.0
18+
rev: 5.13.2
1919
hooks:
2020
- id: isort
2121
args: ["-l 120", "--profile", "black", "."]
2222

2323
- repo: https://github.com/pre-commit/pre-commit-hooks
24-
rev: v4.4.0
24+
rev: v4.5.0
2525
hooks:
2626
- id: check-yaml
2727
exclude: recipe/meta.yaml

stemflow/gridding/QTree.py

+31-56
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
import pandas as pd
1313

1414
from ..utils.generate_soft_colors import generate_soft_color
15+
from ..utils.jitterrotation.jitterrotator import JitterRotator
1516
from ..utils.validation import check_random_state
16-
from .Q_blocks import Node, Point
17+
from .Q_blocks import QNode, QPoint
1718

1819
os.environ["MKL_NUM_THREADS"] = "1"
1920
os.environ["NUMEXPR_NUM_THREADS"] = "1"
@@ -23,7 +24,7 @@
2324

2425

2526
def recursive_subdivide(
26-
node: Node,
27+
node: QNode,
2728
grid_len_lon_upper_threshold: Union[float, int],
2829
grid_len_lon_lower_threshold: Union[float, int],
2930
grid_len_lat_upper_threshold: Union[float, int],
@@ -53,7 +54,7 @@ def recursive_subdivide(
5354
h_ = float(node.height / 2)
5455

5556
p = contains(node.x0, node.y0, w_, h_, node.points)
56-
x1 = Node(node.x0, node.y0, w_, h_, p)
57+
x1 = QNode(node.x0, node.y0, w_, h_, p)
5758
recursive_subdivide(
5859
x1,
5960
grid_len_lon_upper_threshold,
@@ -64,7 +65,7 @@ def recursive_subdivide(
6465
)
6566

6667
p = contains(node.x0, node.y0 + h_, w_, h_, node.points)
67-
x2 = Node(node.x0, node.y0 + h_, w_, h_, p)
68+
x2 = QNode(node.x0, node.y0 + h_, w_, h_, p)
6869
recursive_subdivide(
6970
x2,
7071
grid_len_lon_upper_threshold,
@@ -75,7 +76,7 @@ def recursive_subdivide(
7576
)
7677

7778
p = contains(node.x0 + w_, node.y0, w_, h_, node.points)
78-
x3 = Node(node.x0 + w_, node.y0, w_, h_, p)
79+
x3 = QNode(node.x0 + w_, node.y0, w_, h_, p)
7980
recursive_subdivide(
8081
x3,
8182
grid_len_lon_upper_threshold,
@@ -86,7 +87,7 @@ def recursive_subdivide(
8687
)
8788

8889
p = contains(node.x0 + w_, node.y0 + h_, w_, h_, node.points)
89-
x4 = Node(node.x0 + w_, node.y0 + h_, w_, h_, p)
90+
x4 = QNode(node.x0 + w_, node.y0 + h_, w_, h_, p)
9091
recursive_subdivide(
9192
x4,
9293
grid_len_lon_upper_threshold,
@@ -204,17 +205,12 @@ def add_lon_lat_data(self, indexes: Sequence, x_array: Sequence, y_array: Sequen
204205
if not len(x_array) == len(y_array) or not len(x_array) == len(indexes):
205206
raise ValueError("input longitude and latitude and indexes not in same length!")
206207

207-
data = np.array([x_array, y_array]).T
208-
angle = self.rotation_angle
209-
r = angle / 360
210-
theta = r * np.pi * 2
211-
rotation_matrix = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
212-
data = data @ rotation_matrix
213-
lon_new = (data[:, 0] + self.calibration_point_x_jitter).tolist()
214-
lat_new = (data[:, 1] + self.calibration_point_y_jitter).tolist()
208+
lon_new, lat_new = JitterRotator.rotate_jitter(
209+
x_array, y_array, self.rotation_angle, self.calibration_point_x_jitter, self.calibration_point_y_jitter
210+
)
215211

216212
for index, lon, lat in zip(indexes, lon_new, lat_new):
217-
self.points.append(Point(index, lon, lat))
213+
self.points.append(QPoint(index, lon, lat))
218214

219215
def generate_gridding_params(self):
220216
"""generate the gridding params after data are added
@@ -233,15 +229,15 @@ def generate_gridding_params(self):
233229

234230
self.left_bottom_point = (left_bottom_point_x, left_bottom_point_y)
235231
if self.lon_lat_equal_grid is True:
236-
self.root = Node(
232+
self.root = QNode(
237233
left_bottom_point_x,
238234
left_bottom_point_y,
239235
max(self.grid_length_x, self.grid_length_y),
240236
max(self.grid_length_x, self.grid_length_y),
241237
self.points,
242238
)
243239
elif self.lon_lat_equal_grid is False:
244-
self.root = Node(
240+
self.root = QNode(
245241
left_bottom_point_x, left_bottom_point_y, self.grid_length_x, self.grid_length_y, self.points
246242
)
247243
else:
@@ -272,58 +268,37 @@ def graph(self, scatter: bool = True, ax=None):
272268

273269
c = find_children(self.root)
274270

275-
# areas = set()
276-
# width_set = set()
277-
# height_set = set()
278-
# for el in c:
279-
# areas.add(el.width * el.height)
280-
# width_set.add(el.width)
281-
# height_set.add(el.height)
282-
283-
theta = -(self.rotation_angle / 360) * np.pi * 2
284-
rotation_matrix = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
285-
286271
for n in c:
287-
xy0_trans = np.array([[n.x0, n.y0]])
288-
if self.calibration_point_x_jitter:
289-
new_x = xy0_trans[:, 0] - self.calibration_point_x_jitter
290-
else:
291-
new_x = xy0_trans[:, 0]
292-
293-
if self.calibration_point_y_jitter:
294-
new_y = xy0_trans[:, 1] - self.calibration_point_y_jitter
295-
else:
296-
new_y = xy0_trans[:, 1]
297-
new_xy = np.array([[new_x[0], new_y[0]]]) @ rotation_matrix
298-
new_x = new_xy[:, 0]
299-
new_y = new_xy[:, 1]
272+
old_x, old_y = JitterRotator.inverse_jitter_rotate(
273+
[n.x0], [n.y0], self.rotation_angle, self.calibration_point_x_jitter, self.calibration_point_y_jitter
274+
)
300275

301276
if ax is None:
302277
plt.gcf().gca().add_patch(
303278
patches.Rectangle(
304-
(new_x, new_y), n.width, n.height, fill=False, angle=self.rotation_angle, color=the_color
279+
(old_x, old_y), n.width, n.height, fill=False, angle=self.rotation_angle, color=the_color
305280
)
306281
)
307282
else:
308283
ax.add_patch(
309284
patches.Rectangle(
310-
(new_x, new_y), n.width, n.height, fill=False, angle=self.rotation_angle, color=the_color
285+
(old_x, old_y), n.width, n.height, fill=False, angle=self.rotation_angle, color=the_color
311286
)
312287
)
313288

314-
x = np.array([point.x for point in self.points]) - self.calibration_point_x_jitter
315-
y = np.array([point.y for point in self.points]) - self.calibration_point_y_jitter
316-
317-
data = np.array([x, y]).T @ rotation_matrix
318289
if scatter:
290+
old_x, old_y = JitterRotator.inverse_jitter_rotate(
291+
[point.x for point in self.points],
292+
[point.y for point in self.points],
293+
self.rotation_angle,
294+
self.calibration_point_x_jitter,
295+
self.calibration_point_y_jitter,
296+
)
297+
319298
if ax is None:
320-
plt.scatter(
321-
data[:, 0].tolist(), data[:, 1].tolist(), s=0.2, c="tab:blue", alpha=0.7
322-
) # plots the points as red dots
299+
plt.scatter(old_x, old_y, s=0.2, c="tab:blue", alpha=0.7) # plots the points as red dots
323300
else:
324-
ax.scatter(
325-
data[:, 0].tolist(), data[:, 1].tolist(), s=0.2, c="tab:blue", alpha=0.7
326-
) # plots the points as red dots
301+
ax.scatter(old_x, old_y, s=0.2, c="tab:blue", alpha=0.7) # plots the points as red dots
327302
return
328303

329304
def get_final_result(self) -> pandas.core.frame.DataFrame:
@@ -333,21 +308,21 @@ def get_final_result(self) -> pandas.core.frame.DataFrame:
333308
results (DataFrame): A pandas dataframe containing the gridding information
334309
"""
335310
all_grids = find_children(self.root)
336-
point_indexes_list = []
311+
# point_indexes_list = []
337312
point_grid_width_list = []
338313
point_grid_height_list = []
339314
point_grid_points_number_list = []
340315
calibration_point_list = []
341316
for grid in all_grids:
342-
point_indexes_list.append([point.index for point in grid.points])
317+
# point_indexes_list.append([point.index for point in grid.points])
343318
point_grid_width_list.append(grid.width)
344319
point_grid_height_list.append(grid.height)
345320
point_grid_points_number_list.append(len(grid.points))
346321
calibration_point_list.append((round(grid.x0, 6), round(grid.y0, 6)))
347322

348323
result = pd.DataFrame(
349324
{
350-
"checklist_indexes": point_indexes_list,
325+
# "checklist_indexes": point_indexes_list,
351326
"stixel_indexes": list(range(len(point_grid_width_list))),
352327
"stixel_width": point_grid_width_list,
353328
"stixel_height": point_grid_height_list,

stemflow/gridding/Q_blocks.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"""I call this Q_blocks because they are essential blocks for QTree methods"""
22

3-
from typing import Tuple, Union
3+
from collections.abc import Sequence
4+
from typing import List, Tuple, Union
45

56
from ..utils.sphere.coordinate_transform import lonlat_spherical_transformer
67
from ..utils.sphere.distance import spherical_distance_from_coordinates
78

89

9-
class Point:
10+
class QPoint:
1011
"""A Point class for recording data points"""
1112

1213
def __init__(self, index, x, y):
@@ -15,7 +16,7 @@ def __init__(self, index, x, y):
1516
self.index = index
1617

1718

18-
class Node:
19+
class QNode:
1920
"""A tree-like division node class"""
2021

2122
def __init__(
@@ -24,7 +25,7 @@ def __init__(
2425
y0: Union[float, int],
2526
w: Union[float, int],
2627
h: Union[float, int],
27-
points: list[Point],
28+
points: Sequence,
2829
):
2930
self.x0 = x0
3031
self.y0 = y0
@@ -43,7 +44,7 @@ def get_points(self):
4344
return self.points
4445

4546

46-
class Grid:
47+
class QGrid:
4748
"""Grid class for STEM (fixed gird size)"""
4849

4950
def __init__(self, x_index, y_index, x_range, y_range):
@@ -76,7 +77,7 @@ def __init__(
7677
inclination2: Union[float, int],
7778
azimuth3: Union[float, int],
7879
inclination3: Union[float, int],
79-
points: list[Sphere_Point],
80+
points: Sequence,
8081
):
8182
self.x0 = x0
8283
self.y0 = y0

0 commit comments

Comments
 (0)