def _get_all_geom(self, g_id): g_arr = [] for g in radia.ObjCntStuf(g_id): if len(radia.ObjCntStuf(g)) > 0: g_arr.extend(self._get_all_geom(g)) else: g_arr.append(g) return g_arr
def get_geom_tree(g_id, recurse_depth=0): g_arr = [] for g in radia.ObjCntStuf(g_id): if len(radia.ObjCntStuf(g)) > 0: if recurse_depth > 0: g_arr.extend(get_geom_tree(g, recurse_depth=recurse_depth - 1)) else: g_arr.extend([g]) else: g_arr.append(g) return g_arr
def geom_to_data(g_id, name=None, divide=True): n = (name if name is not None else str(g_id)) + '.Geom' pd = PKDict(name=n, id=g_id, data=[]) d = template_common.to_pkdict(radia.ObjDrwVTK(g_id, 'Axes->No')) n_verts = len(d.polygons.vertices) c = radia.ObjCntStuf(g_id) l = len(c) if not divide or l == 0: pd.data = [d] else: d_arr = [] n_s_verts = 0 # for g in get_geom_tree(g_id): for g in c: # for fully recursive array # for g in get_all_geom(geom): s_d = template_common.to_pkdict(radia.ObjDrwVTK(g, 'Axes->No')) n_s_verts += len(s_d.polygons.vertices) d_arr.append(s_d) # if the number of vertices of the container is more than the total # across its elements, a symmetry or other "additive" transformation has # been applied and we cannot get at the individual elements if n_verts > n_s_verts: d_arr = [d] pd.data=d_arr return pd
def check_segments(self, container): """Loop through all the objects in a container and evaluate the segmentation. Good shapes will have a magnetisation perpendicular to one of the faces. So find the normal of each face and evaluate the dot product with the magnetisation, both normalised to 1. The best have a max dot product of 1. Theoretical min is 1/sqrt(3) though most will be above 1/sqrt(2).""" shapes = rad.ObjCntStuf(container) xmin, xmax, ymin, ymax, zmin, zmax = rad.ObjGeoLim(container) print(f'Checking {len(shapes)} shapes in {container}, extent: x {xmin:.1f} to {xmax:.1f}, y {ymin:.1f} to {ymax:.1f}, z {zmin:.1f} to {zmax:.1f}') dot_products = {} for shape in shapes: sub_shapes = rad.ObjCntStuf(shape) if len(sub_shapes) > 0: # this shape is a container dot_products.update(self.check_segments(shape)) # recurse and update dict else: # it's an atomic shape mag = rad.ObjM(shape)[0] # returns [[mx, my, mz]], select the first element i.e. [mx, my, mz] norm = np.linalg.norm(mag) # normalise so total is 1 if norm == 0: continue mag = mag / norm # Have to parse the information from rad.UtiDmp, no other way of getting polyhedron faces! info = rad.UtiDmp(shape).replace('{', '[').replace('}', ']') # convert from Mathematica list format in_face_list = False # print(info) lines = info.split('\n') description = lines[0].split(': ') # print(description) object_type = description[-1] # print('Type is', object_type) if object_type == 'RecMag': # cuboid with axes parallel to x, y, z # simply find the largest component of normalised magnetisation - the closer to 1, the better dot_products[shape] = max(abs(mag)) elif object_type == 'Polyhedron': # need to loop over the faces product_list = [] for line in lines[1:]: if in_face_list: if '[' not in line: # reached the end of the face list break points = np.array(eval(line.rstrip(','))) normal = np.cross(points[1] - points[0], points[2] - points[0]) product_list.append(np.dot(normal / np.linalg.norm(normal), mag)) # normalise->unit vector elif 'Face Vertices' in line: in_face_list = True dot_products[shape] = max(product_list) # max seems to be a reasonable figure of merit return dot_products
def geom_to_data(geom, name=None, divide=True): d_arr = [] if not divide: d_arr.append( template_common.to_pkdict(radia.ObjDrwVTK(geom, 'Axes->No'))) else: for g in radia.ObjCntStuf(geom): # for fully recursive array # for g in self._get_all_geom(geom): d_arr.append( template_common.to_pkdict(radia.ObjDrwVTK(g, 'Axes->No'))) n = name if name is not None else str(geom) return PKDict(name=n + '.Geom', id=geom, data=d_arr)
def geom_to_data(g_id, name=None, divide=True): def _to_pkdict(d): if not isinstance(d, dict): return d rv = PKDict() for k, v in d.items(): rv[k] = _to_pkdict(v) return rv n = (name if name is not None else str(g_id)) + '.Geom' pd = PKDict(name=n, id=g_id, data=[]) d = _to_pkdict(radia.ObjDrwVTK(g_id, 'Axes->No')) d.update(_geom_bnds(g_id)) n_verts = len(d.polygons.vertices) c = radia.ObjCntStuf(g_id) l = len(c) if not divide or l == 0: d.id = g_id pd.data = [d] else: d_arr = [] n_s_verts = 0 # for g in get_geom_tree(g_id): for g in c: # for fully recursive array # for g in get_all_geom(geom): s_d = _to_pkdict(radia.ObjDrwVTK(g, 'Axes->No')) s_d.update(_geom_bnds(g)) n_s_verts += len(s_d.polygons.vertices) s_d.id = g d_arr.append(s_d) # if the number of vertices of the container is more than the total # across its elements, a symmetry or other "additive" transformation has # been applied and we cannot get at the individual elements if n_verts > n_s_verts: d.id = g_id d_arr = [d] pd.data = d_arr pd.bounds = radia.ObjGeoLim(g_id) return pd
mag06 = rad.ObjMltExtTri(25, 8, [[0,-15],[-15,0],[0,15],[15,0]], [[5,1],[5,2],[5,3],[5,1]], 'z', [0,0,1], 'ki->Numb,TriAngMin->20,TriAreaMax->10') mag07 = rad.ObjCylMag([0,20,0], 5, 10, 21, 'z', [0,0,1]) mag08 = rad.ObjRecCur([-15,0,0], [5,7,15], [0.5,0.5,1.]) mag09 = rad.ObjArcCur([0,0,-5], [10,13], [0,2.5], 10, 15, 1.7, 'man', 'z') mag10 = rad.ObjRaceTrk([0,0,0], [27,28], [1,2.5], 5, 15, 1.7, 'man', 'z') mag11 = rad.ObjFlmCur([[-10,-30,-10],[30,-30,-10],[30,25,25],[-30,25,25],[-30,-30,-10]], 10.2) magBkg = rad.ObjBckg([1,2,3]) mag = rad.ObjCnt([mag00, mag01, mag02, mag03, mag04, mag05, mag06, mag07, mag08, mag09]) print('Container Content:', rad.ObjCntStuf(mag)) print('Container Size:', rad.ObjCntSize(mag)) rad.ObjAddToCnt(mag, [mag10, mag11]) cnt02 = rad.ObjCnt([mag00, mag]) mat = rad.MatLin([1.01, 1.2], [0, 0, 1.3]) #mat = rad.MatStd('NdFeB', 1.2) rad.MatApl(mag01, mat) print('Magn. Material index:', mat, ' appled to object:', mag01) mag00a = rad.ObjFullMag([10,0,40],[12,18,5],[0,0,1],[2,2,2],cnt02,mat,[0.5,0,0]) rad.ObjDrwOpenGL(cnt02) data_cnt = rad.ObjDrwVTK(cnt02)