femagtools 1.8.2__py3-none-any.whl → 1.8.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.
- femagtools/__init__.py +1 -1
- femagtools/bch.py +10 -6
- femagtools/dxfsl/area.py +69 -1
- femagtools/dxfsl/conv.py +53 -16
- femagtools/dxfsl/converter.py +273 -76
- femagtools/dxfsl/fslrenderer.py +18 -22
- femagtools/dxfsl/functions.py +38 -8
- femagtools/dxfsl/geom.py +112 -35
- femagtools/dxfsl/journal.py +1 -1
- femagtools/dxfsl/machine.py +44 -7
- femagtools/dxfsl/shape.py +4 -0
- femagtools/dxfsl/symmetry.py +105 -32
- femagtools/femag.py +64 -61
- femagtools/fsl.py +4 -2
- femagtools/isa7.py +3 -2
- femagtools/machine/afpm.py +45 -25
- femagtools/machine/effloss.py +31 -20
- femagtools/machine/im.py +6 -8
- femagtools/machine/sizing.py +4 -3
- femagtools/machine/sm.py +35 -37
- femagtools/mcv.py +66 -37
- femagtools/multiproc.py +79 -80
- femagtools/parstudy.py +10 -4
- femagtools/semi_fea.py +108 -0
- femagtools/templates/basic_modpar.mako +0 -3
- femagtools/templates/fe-contr.mako +18 -18
- femagtools/templates/ld_lq_fast.mako +3 -0
- femagtools/templates/mesh-airgap.mako +6 -0
- femagtools/templates/mult_cal_fast.mako +3 -0
- femagtools/templates/pm_sym_f_cur.mako +4 -1
- femagtools/templates/pm_sym_fast.mako +3 -0
- femagtools/templates/pm_sym_loss.mako +3 -0
- femagtools/templates/psd_psq_fast.mako +3 -0
- femagtools/templates/torq_calc.mako +3 -0
- femagtools/tks.py +23 -20
- femagtools/utils.py +1 -1
- femagtools/windings.py +11 -4
- femagtools/zmq.py +213 -0
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/METADATA +3 -3
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/RECORD +49 -47
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/WHEEL +1 -1
- tests/test_afpm.py +15 -6
- tests/test_femag.py +1 -1
- tests/test_fsl.py +4 -4
- tests/test_mcv.py +20 -14
- tests/test_parident.py +2 -1
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/LICENSE +0 -0
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/top_level.txt +0 -0
femagtools/dxfsl/geom.py
CHANGED
@@ -1986,7 +1986,7 @@ class Geometry(object):
|
|
1986
1986
|
startangle=0.0,
|
1987
1987
|
endangle=np.pi/2)
|
1988
1988
|
|
1989
|
-
elif np.isclose(width, height*2,
|
1989
|
+
elif np.isclose(width, height*2, rtol=1e-2, atol=1e-2):
|
1990
1990
|
radius = width/2
|
1991
1991
|
self.set_center([mm[1]-height, mm[2]])
|
1992
1992
|
logger.info("check for half machine")
|
@@ -2005,7 +2005,7 @@ class Geometry(object):
|
|
2005
2005
|
startangle=np.pi,
|
2006
2006
|
endangle=0.0)
|
2007
2007
|
|
2008
|
-
elif np.isclose(width*2, height,
|
2008
|
+
elif np.isclose(width*2, height, rtol=1e-2, atol=1e-2):
|
2009
2009
|
radius = width
|
2010
2010
|
logger.info("check for half machine")
|
2011
2011
|
self.set_center([mm[1], mm[3]-width])
|
@@ -2256,45 +2256,120 @@ class Geometry(object):
|
|
2256
2256
|
return center[0]
|
2257
2257
|
return None
|
2258
2258
|
|
2259
|
-
def
|
2259
|
+
def is_same_center(self, center_lst, center, rtol, atol):
|
2260
|
+
for c in center_lst:
|
2261
|
+
if points_are_close(c['center'], center['center'], rtol, atol):
|
2262
|
+
radius = center['radius'][0]
|
2263
|
+
if not radius in c['radius']:
|
2264
|
+
c['radius'].append(radius)
|
2265
|
+
c['count'] = c['count'] + 1
|
2266
|
+
return True
|
2267
|
+
return False
|
2268
|
+
|
2269
|
+
def get_center_with_x(self, center_lst, x):
|
2270
|
+
c_list = [c for c in center_lst
|
2271
|
+
if np.isclose(c['center'][0], x, rtol=self.rtol, atol=self.atol)]
|
2272
|
+
if not c_list:
|
2273
|
+
return None
|
2274
|
+
cy_list = [(c['center'][1], c) for c in c_list]
|
2275
|
+
cy_list.sort()
|
2276
|
+
y, c = cy_list[0]
|
2277
|
+
return c
|
2278
|
+
|
2279
|
+
def get_center_with_y(self, center_lst, y):
|
2280
|
+
c_list = [c for c in center_lst
|
2281
|
+
if np.isclose(c['center'][1], y, rtol=self.rtol, atol=self.atol)]
|
2282
|
+
if not c_list:
|
2283
|
+
return None
|
2284
|
+
cy_list = [(c['center'][0], c) for c in c_list]
|
2285
|
+
cy_list.sort()
|
2286
|
+
[logger.info("y=%s, c=%s", y, c) for y, c in cy_list]
|
2287
|
+
y, c = cy_list[0]
|
2288
|
+
return c
|
2289
|
+
|
2290
|
+
def get_center_arcs(self, mm):
|
2260
2291
|
logger.debug("begin of get_center_arcs")
|
2261
2292
|
center_list = []
|
2293
|
+
x_min, x_max, y_min, y_max = mm
|
2294
|
+
|
2295
|
+
def center_is_inside(c):
|
2296
|
+
tol = 0.1
|
2297
|
+
x, y = c
|
2298
|
+
if x-tol > x_min and \
|
2299
|
+
x+tol < x_max and \
|
2300
|
+
y-tol > y_min and \
|
2301
|
+
y+tol < y_max:
|
2302
|
+
return True
|
2303
|
+
return False
|
2304
|
+
|
2262
2305
|
circles = [e for e in self.elements() if is_Circle(e)]
|
2263
2306
|
logger.debug(" -- %s Circles", len(circles))
|
2264
2307
|
|
2265
2308
|
for e in circles:
|
2266
2309
|
center = (round(e.center[0], 3), round(e.center[1], 3))
|
2267
|
-
|
2268
|
-
|
2310
|
+
entry = {'center': center,
|
2311
|
+
'radius': [round(e.radius, 1)],
|
2312
|
+
'phi': e.get_angle_of_arc(),
|
2313
|
+
'dist': e.length(),
|
2314
|
+
'inside': center_is_inside(center),
|
2315
|
+
'count': 1}
|
2316
|
+
center_list.append(entry)
|
2269
2317
|
|
2270
2318
|
arcs = [e for e in self.elements() if is_Arc(e)]
|
2271
2319
|
logger.debug(" -- %s Arcs", len(arcs))
|
2272
2320
|
|
2273
2321
|
for e in arcs:
|
2274
2322
|
center = (round(e.center[0], 3), round(e.center[1], 3))
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2323
|
+
entry = {'center': center,
|
2324
|
+
'radius': [round(e.radius, 1)],
|
2325
|
+
'phi': e.get_angle_of_arc(),
|
2326
|
+
'dist': e.length(),
|
2327
|
+
'inside': center_is_inside(center),
|
2328
|
+
'count': 1}
|
2329
|
+
if not self.is_same_center(center_list, entry, self.rtol, self.atol):
|
2330
|
+
center_list.append(entry)
|
2283
2331
|
|
2284
2332
|
center = None
|
2285
|
-
arc_list = [[
|
2333
|
+
arc_list = [[c['count'], len(c['radius']), c['phi'], n, c]
|
2334
|
+
for n, c in enumerate(center_list)]
|
2286
2335
|
arc_list.sort(reverse=True)
|
2287
2336
|
|
2288
|
-
|
2289
|
-
|
2290
|
-
center = c1[2]
|
2291
|
-
if len(arc_list) > 1:
|
2292
|
-
c2 = arc_list[1]
|
2293
|
-
if not c1[0] > c2[0]:
|
2294
|
-
center = None
|
2337
|
+
logger.debug("x min/max = %s/%s", x_min, x_max)
|
2338
|
+
logger.debug("y min/max = %s/%s", y_min, y_max)
|
2295
2339
|
|
2296
|
-
logger.debug("
|
2297
|
-
|
2340
|
+
[logger.debug("Arc %s", arc) for arc in arc_list]
|
2341
|
+
if not arc_list:
|
2342
|
+
logger.debug("end of get_center_arcs: no arcs")
|
2343
|
+
return None
|
2344
|
+
|
2345
|
+
cnt, cr1, p, n, c1 = arc_list[0]
|
2346
|
+
logger.debug("First Entry: %s", c1)
|
2347
|
+
center = c1['center']
|
2348
|
+
if len(arc_list) > 1:
|
2349
|
+
cnt, cr2, p, n, c2 = arc_list[1]
|
2350
|
+
logger.debug("Second Entry: %s", c2)
|
2351
|
+
if not cr1 > cr2:
|
2352
|
+
center = None
|
2353
|
+
|
2354
|
+
if center:
|
2355
|
+
logger.debug("end of get_center_arcs: -> %s", center)
|
2356
|
+
return center
|
2357
|
+
|
2358
|
+
c_entry = self.get_center_with_x(center_list, x_min)
|
2359
|
+
if c_entry:
|
2360
|
+
center = c_entry['center']
|
2361
|
+
if center[1] < y_min:
|
2362
|
+
logger.debug("end of get_center_arcs: x -> %s", center)
|
2363
|
+
return center
|
2364
|
+
c_entry = self.get_center_with_y(center_list, y_min)
|
2365
|
+
if c_entry:
|
2366
|
+
center = c_entry['center']
|
2367
|
+
if center[0] < x_min:
|
2368
|
+
logger.debug("end of get_center_arcs: y -> %s", center)
|
2369
|
+
return center
|
2370
|
+
|
2371
|
+
logger.debug("end of get_center_arcs: no center found")
|
2372
|
+
return None
|
2298
2373
|
|
2299
2374
|
def get_center_dim(self, mm):
|
2300
2375
|
return (round(mm[0], 4), round(mm[2], 4))
|
@@ -2305,7 +2380,9 @@ class Geometry(object):
|
|
2305
2380
|
return None
|
2306
2381
|
|
2307
2382
|
center = None
|
2308
|
-
|
2383
|
+
# Zuerst suchen wir anhand der Circle- und Arc-Segmente nach einem
|
2384
|
+
# möglichen Center-Punkt.
|
2385
|
+
center_arcs = self.get_center_arcs(mm)
|
2309
2386
|
|
2310
2387
|
if center_arcs:
|
2311
2388
|
center = center_arcs
|
@@ -2409,31 +2486,31 @@ class Geometry(object):
|
|
2409
2486
|
logger.debug("end check_airgap: return %s", len(area_id_list) > 1)
|
2410
2487
|
return len(area_id_list) > 1 # bad
|
2411
2488
|
|
2412
|
-
def is_border_line(self, center, startangle, endangle, e, atol):
|
2489
|
+
def is_border_line(self, center, startangle, endangle, e, rtol=1e-3, atol=1e-3):
|
2413
2490
|
if isinstance(e, Line):
|
2414
2491
|
if np.isclose(startangle, endangle):
|
2415
2492
|
return False # full
|
2416
2493
|
|
2417
2494
|
if points_are_close(center, e.p1):
|
2418
2495
|
angle_p2 = alpha_line(center, e.p2)
|
2419
|
-
if np.isclose(startangle, angle_p2,
|
2496
|
+
if np.isclose(startangle, angle_p2, rtol=rtol, atol=atol):
|
2420
2497
|
return True
|
2421
|
-
return np.isclose(endangle, angle_p2,
|
2498
|
+
return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
|
2422
2499
|
|
2423
2500
|
if points_are_close(center, e.p2):
|
2424
2501
|
angle_p1 = alpha_line(center, e.p1)
|
2425
|
-
if np.isclose(startangle, angle_p1,
|
2502
|
+
if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
|
2426
2503
|
return True
|
2427
|
-
return np.isclose(endangle, angle_p1,
|
2504
|
+
return np.isclose(endangle, angle_p1, rtol=rtol, atol=atol)
|
2428
2505
|
|
2429
2506
|
angle_p1 = alpha_line(center, e.p1)
|
2430
|
-
if np.isclose(startangle, angle_p1,
|
2507
|
+
if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
|
2431
2508
|
angle_p2 = alpha_line(center, e.p2)
|
2432
|
-
return np.isclose(startangle, angle_p2,
|
2509
|
+
return np.isclose(startangle, angle_p2, rtol=rtol, atol=atol)
|
2433
2510
|
|
2434
|
-
if np.isclose(endangle, angle_p1,
|
2511
|
+
if np.isclose(endangle, angle_p1, rtol=rtol, atol=atol):
|
2435
2512
|
angle_p2 = alpha_line(center, e.p2)
|
2436
|
-
return np.isclose(endangle, angle_p2,
|
2513
|
+
return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
|
2437
2514
|
return False
|
2438
2515
|
|
2439
2516
|
def get_gaplist(self, center):
|
@@ -2457,7 +2534,7 @@ class Geometry(object):
|
|
2457
2534
|
"""
|
2458
2535
|
gaplist = []
|
2459
2536
|
for e in self.elements(Shape):
|
2460
|
-
if not self.is_border_line(center, startangle, endangle, e, atol):
|
2537
|
+
if not self.is_border_line(center, startangle, endangle, e, atol=atol):
|
2461
2538
|
gaplist += [e.minmax_from_center(center)]
|
2462
2539
|
else:
|
2463
2540
|
min_r, max_r = e.minmax_from_center(center)
|
@@ -3259,7 +3336,7 @@ class Geometry(object):
|
|
3259
3336
|
max_size, max_w = windings_surface[0]
|
3260
3337
|
for sz, w in windings_surface[1:]:
|
3261
3338
|
logger.debug("winding size = %s", sz)
|
3262
|
-
if sz / max_size < 0.
|
3339
|
+
if sz / max_size < 0.70:
|
3263
3340
|
w.set_type(AREA.TYPE_AIR)
|
3264
3341
|
if sz / max_size < 0.2:
|
3265
3342
|
windings_found -= 1
|
femagtools/dxfsl/journal.py
CHANGED
femagtools/dxfsl/machine.py
CHANGED
@@ -135,6 +135,16 @@ class Machine(object):
|
|
135
135
|
self.geom.is_outer = True
|
136
136
|
self.geom.is_inner = False
|
137
137
|
|
138
|
+
def set_attributes(self,
|
139
|
+
kind="",
|
140
|
+
inner=False,
|
141
|
+
outer=False):
|
142
|
+
self.set_kind(kind)
|
143
|
+
if inner:
|
144
|
+
self.set_inner()
|
145
|
+
if outer:
|
146
|
+
self.set_outer()
|
147
|
+
|
138
148
|
def clear_cut_lines(self):
|
139
149
|
self.geom.clear_cut_lines()
|
140
150
|
if self.mirror_geom is not None:
|
@@ -635,9 +645,13 @@ class Machine(object):
|
|
635
645
|
parts = symmetry.find_symmetry() # temp solution
|
636
646
|
logger.debug(">>> Symmetry parts = %s <<<", parts)
|
637
647
|
|
638
|
-
if parts
|
639
|
-
|
640
|
-
|
648
|
+
if parts == 1:
|
649
|
+
# no slices, but ok
|
650
|
+
return False
|
651
|
+
|
652
|
+
found = (parts > 1)
|
653
|
+
|
654
|
+
if not found:
|
641
655
|
found = self.geom.find_symmetry(self.radius,
|
642
656
|
self.startangle,
|
643
657
|
self.endangle,
|
@@ -833,11 +847,11 @@ class Machine(object):
|
|
833
847
|
if dist_start > dist_end:
|
834
848
|
machine.mirror_all_areas(self.startangle)
|
835
849
|
machine.rotate_to(angle)
|
836
|
-
machine.geom.create_list_of_areas(delete=True)
|
837
850
|
machine.startangle -= angle
|
838
851
|
else:
|
839
852
|
machine.mirror_all_areas(self.endangle)
|
840
853
|
machine.endangle += angle
|
854
|
+
machine.geom.create_list_of_areas(delete=True)
|
841
855
|
machine.set_alfa_and_corners()
|
842
856
|
machine.part = machine.part_of_circle()
|
843
857
|
machine.geom.set_subregion_parameters(self.startangle,
|
@@ -907,23 +921,25 @@ class Machine(object):
|
|
907
921
|
first_thirdangle,
|
908
922
|
second_thirdangle)
|
909
923
|
machine_mirror_1.clear_cut_lines()
|
910
|
-
|
911
924
|
machine_mirror_1.repair_hull()
|
912
925
|
machine_mirror_1.set_alfa_and_corners()
|
926
|
+
if machine_mirror_1.geom.number_of_edges() < 2: # very bad
|
927
|
+
logger.debug("end get_third_symmetry_mirror: no remaining elements")
|
928
|
+
return None
|
913
929
|
if not machine_mirror_1.check_symmetry_graph(0.001, 0.05):
|
914
930
|
logger.debug("end get_third_symmetry_mirror: no mirror first third")
|
915
931
|
return None
|
916
932
|
|
917
933
|
if plt:
|
918
934
|
plt.render_elements(machine_mirror_1.geom, Shape,
|
919
|
-
title="Part",
|
935
|
+
title="Part 1",
|
920
936
|
show=True,
|
921
937
|
with_corners=False,
|
922
938
|
with_nodes=False,
|
923
939
|
neighbors=True)
|
924
940
|
|
925
941
|
plt.render_elements(machine_mirror_1.mirror_geom, Shape,
|
926
|
-
title="Counterpart",
|
942
|
+
title="Counterpart 1",
|
927
943
|
show=True,
|
928
944
|
with_corners=False,
|
929
945
|
with_nodes=False,
|
@@ -935,10 +951,28 @@ class Machine(object):
|
|
935
951
|
machine_mirror_2.clear_cut_lines()
|
936
952
|
machine_mirror_2.repair_hull()
|
937
953
|
machine_mirror_2.set_alfa_and_corners()
|
954
|
+
if machine_mirror_2.geom.number_of_edges() < 2: # very bad
|
955
|
+
logger.debug("end get_third_symmetry_mirror: no remaining elements")
|
956
|
+
return None
|
938
957
|
if not machine_mirror_2.check_symmetry_graph(0.001, 0.05):
|
939
958
|
logger.debug("end get_third_symmetry_mirror: no mirror second third")
|
940
959
|
return None
|
941
960
|
|
961
|
+
if plt:
|
962
|
+
plt.render_elements(machine_mirror_2.geom, Shape,
|
963
|
+
title="Part 2",
|
964
|
+
show=True,
|
965
|
+
with_corners=False,
|
966
|
+
with_nodes=False,
|
967
|
+
neighbors=True)
|
968
|
+
|
969
|
+
plt.render_elements(machine_mirror_2.mirror_geom, Shape,
|
970
|
+
title="Counterpart 2",
|
971
|
+
show=True,
|
972
|
+
with_corners=False,
|
973
|
+
with_nodes=False,
|
974
|
+
neighbors=True)
|
975
|
+
|
942
976
|
machine_mirror_1.previous_machine = self
|
943
977
|
logger.debug("end get_third_symmetry_mirror: ok")
|
944
978
|
return machine_mirror_1
|
@@ -992,6 +1026,9 @@ class Machine(object):
|
|
992
1026
|
with_nodes=False,
|
993
1027
|
neighbors=True)
|
994
1028
|
|
1029
|
+
if machine_mirror.geom.number_of_edges() < 2: # very bad
|
1030
|
+
logger.debug("end get_symmetry_mirror: no remaining elements")
|
1031
|
+
return None
|
995
1032
|
if machine_mirror.check_symmetry_graph(0.001, 0.05):
|
996
1033
|
machine_mirror.previous_machine = self
|
997
1034
|
machine_mirror.rotate_to(0.0)
|
femagtools/dxfsl/shape.py
CHANGED
@@ -467,6 +467,10 @@ class Circle(Shape):
|
|
467
467
|
r0 = np.linalg.norm(self.center)
|
468
468
|
return max(abs(r-r0-self.radius), abs(r-r0+self.radius))
|
469
469
|
|
470
|
+
def length(self):
|
471
|
+
"""returns length of this circle"""
|
472
|
+
return self.radius*2*np.pi
|
473
|
+
|
470
474
|
def overlapping_shape(self, e, rtol=1e-03, atol=1e-03):
|
471
475
|
if not (isinstance(e, Arc) or isinstance(e, Circle)):
|
472
476
|
# end overlapping_shape: Circle (not Arc or Circle)
|
femagtools/dxfsl/symmetry.py
CHANGED
@@ -102,6 +102,7 @@ class Symmetry(object):
|
|
102
102
|
a.get_mid_angle(self.geom.center)))
|
103
103
|
|
104
104
|
def area_list_entry(self, a):
|
105
|
+
a.set_symmetry_parameter(self.geom.center)
|
105
106
|
return (round(a.get_alpha(self.geom.center), 3),
|
106
107
|
round(a.min_dist, 1),
|
107
108
|
round(a.height, 1),
|
@@ -119,24 +120,47 @@ class Symmetry(object):
|
|
119
120
|
areas.sort(reverse=True)
|
120
121
|
return areas
|
121
122
|
|
123
|
+
def get_equal_areas(self, areas):
|
124
|
+
return
|
125
|
+
|
122
126
|
def build_results(self, areas):
|
127
|
+
logger.debug("begin of build_results with %s areas", len(areas))
|
128
|
+
[logger.debug("#%s: alpha=%s, min=%s, max=%s",
|
129
|
+
a.get_id(), alpha, a.min_angle, a.max_angle) for
|
130
|
+
alpha, dist, h, mid, a in areas]
|
131
|
+
|
123
132
|
a0_alpha, a0_min_dist, a0_height, a0_mid_angle, a0 = areas[0]
|
124
133
|
equal_areas = [(a0_mid_angle, a0)]
|
125
134
|
check_rslt = []
|
126
135
|
for a1_alpha, a1_min_dist, a1_height, a1_mid_angle, a1 in areas[1:]:
|
127
|
-
if self.equal_area(a0_min_dist, a0_height, a0_alpha,
|
128
|
-
|
129
|
-
|
136
|
+
if (self.equal_area(a0_min_dist, a0_height, a0_alpha,
|
137
|
+
a1_min_dist, a1_height, a1_alpha,
|
138
|
+
rtol=0.001, atol=0.05)):
|
130
139
|
a0_min_dist = (a0_min_dist + a1_min_dist) / 2
|
131
140
|
a0_height = (a0_height + a1_height) / 2
|
132
141
|
a0_alpha = (a0_alpha + a1_alpha) / 2
|
133
142
|
equal_areas.append((a1_mid_angle, a1))
|
134
143
|
else:
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
144
|
+
# alpha Wechsel
|
145
|
+
id_list = []
|
146
|
+
for i in range(len(equal_areas)):
|
147
|
+
mid_angle0, area0 = equal_areas[i]
|
148
|
+
if area0.get_id() in id_list:
|
149
|
+
continue
|
150
|
+
equal_areas_check = [(mid_angle0, area0)]
|
151
|
+
for mid_angle1, area1 in equal_areas[i+1:]:
|
152
|
+
if area1.get_id() in id_list:
|
153
|
+
continue
|
154
|
+
if area0.is_symmetry_equal(area1):
|
155
|
+
equal_areas_check.append((mid_angle1, area1))
|
156
|
+
id_list.append(area1.get_id())
|
157
|
+
|
158
|
+
rslt = self.check_delta(equal_areas_check)
|
159
|
+
areasize = a0.area_size()
|
160
|
+
rslt['area'] = a0
|
161
|
+
rslt['areasize'] = areasize
|
162
|
+
check_rslt.append((areasize, rslt))
|
163
|
+
|
140
164
|
equal_areas = [(a1_mid_angle, a1)]
|
141
165
|
a0_min_dist = a1_min_dist
|
142
166
|
a0_height = a1_height
|
@@ -148,12 +172,14 @@ class Symmetry(object):
|
|
148
172
|
rslt['area'] = a0
|
149
173
|
rslt['areasize'] = areasize
|
150
174
|
check_rslt.append((areasize, rslt))
|
175
|
+
logger.debug("end of build_results")
|
151
176
|
return check_rslt
|
152
177
|
|
153
178
|
def get_winding_symmetry(self, inside=False):
|
154
179
|
if inside:
|
155
180
|
areas = [self.area_list_entry(a) for a in self.geom.list_of_areas()
|
156
181
|
if not a.close_to_ag]
|
182
|
+
areas.sort(reverse=True)
|
157
183
|
else:
|
158
184
|
areas = self.build_area_list((AREA.TYPE_WINDINGS,))
|
159
185
|
|
@@ -228,6 +254,7 @@ class Symmetry(object):
|
|
228
254
|
return 0
|
229
255
|
|
230
256
|
check_rslt = self.build_results(areas)
|
257
|
+
logger.debug("%s results available", len(check_rslt))
|
231
258
|
|
232
259
|
parts, start_delta = self.get_symmetry_parts(check_rslt)
|
233
260
|
if parts < 2:
|
@@ -248,6 +275,7 @@ class Symmetry(object):
|
|
248
275
|
result = {'areas': len(area_list),
|
249
276
|
'startdelta': 0.0,
|
250
277
|
'slices': None}
|
278
|
+
result['area_id_list'] = [a.get_id() for m, a in area_list]
|
251
279
|
if not area_list:
|
252
280
|
logger.debug("end of check_delta: no areas")
|
253
281
|
return result
|
@@ -645,6 +673,9 @@ class Symmetry(object):
|
|
645
673
|
m1 = m2
|
646
674
|
d1 = d2
|
647
675
|
|
676
|
+
if not mid_list:
|
677
|
+
return None
|
678
|
+
|
648
679
|
logger.debug("New Mids: %s", mid_list)
|
649
680
|
delta = positive_angle(mid_list[0] * 2)
|
650
681
|
delta_list = [delta]
|
@@ -692,6 +723,41 @@ class Symmetry(object):
|
|
692
723
|
logger.debug("end check_first_last_difference => %s", n1 + 1)
|
693
724
|
return n1 + 1
|
694
725
|
|
726
|
+
def concatenate_results(self, check_rslt):
|
727
|
+
if len(check_rslt) < 2:
|
728
|
+
return check_rslt
|
729
|
+
# ----------
|
730
|
+
def get_slices(rslt):
|
731
|
+
if rslt['slices'] is None:
|
732
|
+
return 0
|
733
|
+
if rslt.get('startdelta', 0.0) != 0.0:
|
734
|
+
return 0
|
735
|
+
if rslt.get('halfslice', None) is not None:
|
736
|
+
return 0
|
737
|
+
return rslt['slices']
|
738
|
+
# ------
|
739
|
+
new_rslt = []
|
740
|
+
size1, n1, rslt1 = check_rslt[0]
|
741
|
+
slices1 = get_slices(rslt1)
|
742
|
+
for size2, n2, rslt2 in check_rslt[1:]:
|
743
|
+
slices2 = get_slices(rslt2)
|
744
|
+
if slices1 > 0 and \
|
745
|
+
slices1 == slices2 and \
|
746
|
+
np.isclose(size1, size2, rtol=1e-01, atol=1e-01) and \
|
747
|
+
(rslt1.get('delta_corr', 0.0) == 0.0 or \
|
748
|
+
rslt2.get('delta_corr', 0.0) == 0.0):
|
749
|
+
# concatenate
|
750
|
+
rslt1['slices'] = None
|
751
|
+
rslt2['delta_corr'] = 0.0
|
752
|
+
rslt2['areas'] = rslt2['areas'] + rslt1['areas']
|
753
|
+
logger.debug("concatenate results(size %s)", size1)
|
754
|
+
else:
|
755
|
+
new_rslt.append((size1, n1, rslt1))
|
756
|
+
slices1, size1, n1, rslt1 = (slices2, size2, n2, rslt2)
|
757
|
+
|
758
|
+
new_rslt.append((size1, n1, rslt1))
|
759
|
+
return new_rslt
|
760
|
+
|
695
761
|
def get_symmetry_parts(self, check_rslt):
|
696
762
|
max_size = 0
|
697
763
|
max_areas = 0
|
@@ -700,10 +766,11 @@ class Symmetry(object):
|
|
700
766
|
self.delta_angle_corr = None
|
701
767
|
unsure_sym = False
|
702
768
|
|
703
|
-
check_rslt = [(size, n, rslt) for n, (size, rslt) in enumerate(check_rslt)
|
769
|
+
check_rslt = [(size, n, rslt) for n, (size, rslt) in enumerate(check_rslt)
|
770
|
+
if rslt['slices'] is not None]
|
704
771
|
check_rslt.sort(reverse=True)
|
705
|
-
|
706
|
-
|
772
|
+
check_rslt = self.concatenate_results(check_rslt)
|
773
|
+
[logger.debug("Result #%s: %s, %s", n, size, rslt) for size, n, rslt in check_rslt]
|
707
774
|
|
708
775
|
rtol = 1e-3
|
709
776
|
atol = 1e-2
|
@@ -720,40 +787,46 @@ class Symmetry(object):
|
|
720
787
|
for size, n, rslt in check_rslt:
|
721
788
|
areas = rslt['areas']
|
722
789
|
slices = rslt['slices']
|
790
|
+
if slices is None:
|
791
|
+
continue
|
792
|
+
|
723
793
|
size = rslt['areasize']
|
724
794
|
angle_corr = rslt.get('delta_corr', 0.0)
|
725
795
|
|
726
796
|
if rslt.get('halfslice', 0) == 1:
|
727
797
|
halfslice.append(rslt)
|
728
798
|
|
729
|
-
if slices
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
without_angle_corr += areas * size
|
744
|
-
else:
|
745
|
-
with_angle_corr += areas * size
|
799
|
+
if slices > 0:
|
800
|
+
max_size = max(max_size, size)
|
801
|
+
max_areas = max(max_areas, areas)
|
802
|
+
max_slices = max(max_slices, slices)
|
803
|
+
missing_middles += rslt.get('missing_middles', [])
|
804
|
+
area = rslt['area']
|
805
|
+
if not (np.isclose(area.min_dist,
|
806
|
+
self.geom.min_radius,
|
807
|
+
rtol=1e-4, atol=1e-3) and \
|
808
|
+
np.isclose(area.max_dist,
|
809
|
+
self.geom.max_radius,
|
810
|
+
rtol=1e-4, atol=1e-3)):
|
811
|
+
if rslt.get('delta_corr', 0.0) == 0.0:
|
812
|
+
without_angle_corr += areas * size
|
746
813
|
else:
|
747
|
-
|
814
|
+
with_angle_corr += areas * size
|
815
|
+
else:
|
816
|
+
maybe_angle_korr += areas * size
|
817
|
+
|
748
818
|
logger.debug("max size: %s, max areas: %s", max_size, max_areas)
|
819
|
+
logger.debug("Angle-Corrections: %s Yes, %s No, %s Maybe",
|
820
|
+
with_angle_corr,
|
821
|
+
without_angle_corr,
|
822
|
+
maybe_angle_korr)
|
749
823
|
|
750
|
-
logger.debug("Angle-Corrections: %s Yes, %s No",
|
751
|
-
with_angle_corr, without_angle_corr)
|
752
824
|
if np.isclose(with_angle_corr, without_angle_corr):
|
753
825
|
with_angle_corr = (maybe_angle_korr > 0)
|
754
826
|
else:
|
755
827
|
with_angle_corr = (with_angle_corr > without_angle_corr)
|
756
828
|
|
829
|
+
# -------------------------
|
757
830
|
def get_halfslice_counterpart(rslt):
|
758
831
|
if rslt.get('halfslice', 0) != 2:
|
759
832
|
return None
|
@@ -768,7 +841,7 @@ class Symmetry(object):
|
|
768
841
|
np.isclose(alpha1, alpha2, rtol=rtol, atol=atol):
|
769
842
|
return half
|
770
843
|
return None
|
771
|
-
|
844
|
+
# -----------
|
772
845
|
if halfslice:
|
773
846
|
logger.debug("%s halfslice [1] found", len(halfslice))
|
774
847
|
|