def exercise_float_asu(space_group_info, n_grid=6): unit_cell = space_group_info.any_compatible_unit_cell(volume=1000) ref_asu = reference_table.get_asu(space_group_info.type().number()) exercise_cut_planes(ref_asu.cuts) inp_asu = space_group_info.direct_space_asu() assert sgtbx.space_group(inp_asu.hall_symbol) == space_group_info.group() exercise_cut_planes(inp_asu.cuts) exercise_shape_vertices(inp_asu, unit_cell) float_asu = inp_asu.add_buffer(unit_cell=unit_cell, thickness=0.001) cb_mx_ref_inp = space_group_info.type().cb_op().c_inv().as_rational() n = n_grid for ref_n in flex.nested_loop((-n // 2, -n // 2, -n // 2), (n, n, n), False): # check correctness of space_group_info.direct_space_asu() ref_r = matrix.col([rational.int(g, n) for g in ref_n]) inp_r = cb_mx_ref_inp * ref_r assert ref_asu.is_inside(ref_r.elems) == inp_asu.is_inside(inp_r.elems) # check correctness of cut_plane.add_buffer() inp_r = inp_r.elems inp_f = [float(r) for r in inp_r] for cut in inp_asu.cuts: r_cut = cut.strip() r_inside = r_cut.is_inside(inp_r) for buffer_thickness in [0.001, 1, -1][:1]: f_cut = cut.as_float_cut_plane().add_buffer( unit_cell=unit_cell, thickness=buffer_thickness) f_inside = f_cut.is_inside(inp_f) if (buffer_thickness < 0): if (r_inside != f_inside): assert r_inside elif (buffer_thickness < 0.01): assert r_inside == f_inside elif (r_inside != f_inside): assert f_inside # check correctness of float_asu.add_buffer() assert float_asu.is_inside(inp_f) == inp_asu.shape_only().is_inside( inp_r) asu_with_metric = inp_asu.define_metric(unit_cell) assert asu_with_metric.hall_symbol is inp_asu.hall_symbol assert len(asu_with_metric.cuts) == len(inp_asu.cuts) assert asu_with_metric.unit_cell is unit_cell asu_tight = asu_with_metric.as_float_asu() asu_buffer = asu_with_metric.add_buffer(thickness=2) asu_shrunk = asu_with_metric.add_buffer(relative_thickness=-1.e-5) vertices = facet_analysis.shape_vertices(inp_asu) for vertex in vertices: assert inp_asu.shape_only().is_inside(vertex) for vertex in vertices: assert asu_tight.is_inside(matrix.col(vertex).as_float().elems) for vertex in vertices: assert asu_buffer.is_inside(matrix.col(vertex).as_float().elems) for vertex in vertices: assert not asu_shrunk.is_inside(matrix.col(vertex).as_float().elems)
def exercise_float_asu(space_group_info, n_grid=6): unit_cell = space_group_info.any_compatible_unit_cell(volume=1000) ref_asu = reference_table.get_asu(space_group_info.type().number()) exercise_cut_planes(ref_asu.cuts) inp_asu = space_group_info.direct_space_asu() assert sgtbx.space_group(inp_asu.hall_symbol) == space_group_info.group() exercise_cut_planes(inp_asu.cuts) exercise_shape_vertices(inp_asu, unit_cell) float_asu = inp_asu.add_buffer(unit_cell=unit_cell, thickness=0.001) cb_mx_ref_inp = space_group_info.type().cb_op().c_inv().as_rational() n = n_grid for ref_n in flex.nested_loop((-n//2,-n//2,-n//2),(n,n,n),False): # check correctness of space_group_info.direct_space_asu() ref_r = matrix.col([rational.int(g,n) for g in ref_n]) inp_r = cb_mx_ref_inp * ref_r assert ref_asu.is_inside(ref_r.elems) == inp_asu.is_inside(inp_r.elems) # check correctness of cut_plane.add_buffer() inp_r = inp_r.elems inp_f = [float(r) for r in inp_r] for cut in inp_asu.cuts: r_cut = cut.strip() r_inside = r_cut.is_inside(inp_r) for buffer_thickness in [0.001, 1, -1][:1]: f_cut = cut.as_float_cut_plane().add_buffer( unit_cell=unit_cell, thickness=buffer_thickness) f_inside = f_cut.is_inside(inp_f) if (buffer_thickness < 0): if (r_inside != f_inside): assert r_inside elif (buffer_thickness < 0.01): assert r_inside == f_inside elif (r_inside != f_inside): assert f_inside # check correctness of float_asu.add_buffer() assert float_asu.is_inside(inp_f) == inp_asu.shape_only().is_inside(inp_r) asu_with_metric = inp_asu.define_metric(unit_cell) assert asu_with_metric.hall_symbol is inp_asu.hall_symbol assert len(asu_with_metric.cuts) == len(inp_asu.cuts) assert asu_with_metric.unit_cell is unit_cell asu_tight = asu_with_metric.as_float_asu() asu_buffer = asu_with_metric.add_buffer(thickness=2) asu_shrunk = asu_with_metric.add_buffer(relative_thickness=-1.e-5) vertices = facet_analysis.shape_vertices(inp_asu) for vertex in vertices: assert inp_asu.shape_only().is_inside(vertex) for vertex in vertices: assert asu_tight.is_inside(matrix.col(vertex).as_float().elems) for vertex in vertices: assert asu_buffer.is_inside(matrix.col(vertex).as_float().elems) for vertex in vertices: assert not asu_shrunk.is_inside(matrix.col(vertex).as_float().elems)
def exercise_shape_vertices(asu, unit_cell): volume_asu = asu.shape_only() asu_shape_vertices = asu.shape_vertices() assert len(asu_shape_vertices) >= 4 facet_analysis_shape_vertices = facet_analysis.shape_vertices(asu) assert len(asu_shape_vertices) == len(facet_analysis_shape_vertices) asu_shape_vertices.sort() facet_analysis_shape_vertices.sort() assert asu_shape_vertices == facet_analysis_shape_vertices for box_min, box_max in zip( asu.box_min(shape_vertices=asu_shape_vertices), asu.box_max(shape_vertices=asu_shape_vertices)): assert box_min < box_max if (unit_cell is None): return float_asu = asu.add_buffer(unit_cell=unit_cell, thickness=0) asu_shrunk = float_asu.add_buffer(relative_thickness=-1.e-5) mcs = asu.define_metric(unit_cell).minimum_covering_sphere() center = matrix.col(mcs.center()) radius = mcs.radius() n_near_sphere_surface = 0 for vertex in asu_shape_vertices: assert volume_asu.is_inside(vertex) float_vertex = [float(e) for e in vertex] assert float_asu.is_inside(float_vertex) assert not asu_shrunk.is_inside(float_vertex) r = abs(matrix.col(unit_cell.orthogonalize(float_vertex)) - center) assert r < radius + 1.e-5 if (radius - r < radius * 1.e-2): n_near_sphere_surface += 1 assert n_near_sphere_surface >= 2 float_asu_shape_vertices = float_asu.shape_vertices() assert len(float_asu_shape_vertices) >= len(asu_shape_vertices) m_near_sphere_surface = 0 for vertex in float_asu_shape_vertices: assert float_asu.is_inside(point=vertex) assert not asu_shrunk.is_inside(vertex) r = abs(matrix.col(unit_cell.orthogonalize(vertex)) - center) assert r < radius + 1.e-5 if (radius - r < radius * 1.e-2): m_near_sphere_surface += 1 assert m_near_sphere_surface >= n_near_sphere_surface line_asu = copy.copy(asu) line_asu.add_planes([(0, 0, 1), (1, 1, 1)], both_directions=True) assert len(line_asu.cuts) == len(asu.cuts) + 4 assert line_asu.cuts[-2].n == (-line_asu.cuts[-1]).n
def exercise_shape_vertices(asu, unit_cell): volume_asu = asu.shape_only() asu_shape_vertices = asu.shape_vertices() assert len(asu_shape_vertices) >= 4 facet_analysis_shape_vertices = facet_analysis.shape_vertices(asu) assert len(asu_shape_vertices) == len(facet_analysis_shape_vertices) asu_shape_vertices.sort() facet_analysis_shape_vertices.sort() assert asu_shape_vertices == facet_analysis_shape_vertices for box_min,box_max in zip(asu.box_min(shape_vertices=asu_shape_vertices), asu.box_max(shape_vertices=asu_shape_vertices)): assert box_min < box_max if (unit_cell is None): return float_asu = asu.add_buffer(unit_cell=unit_cell, thickness=0) asu_shrunk = float_asu.add_buffer(relative_thickness=-1.e-5) mcs = asu.define_metric(unit_cell).minimum_covering_sphere() center = matrix.col(mcs.center()) radius = mcs.radius() n_near_sphere_surface = 0 for vertex in asu_shape_vertices: assert volume_asu.is_inside(vertex) float_vertex = [float(e) for e in vertex] assert float_asu.is_inside(float_vertex) assert not asu_shrunk.is_inside(float_vertex) r = abs(matrix.col(unit_cell.orthogonalize(float_vertex)) - center) assert r < radius + 1.e-5 if (radius - r < radius * 1.e-2): n_near_sphere_surface += 1 assert n_near_sphere_surface >= 2 float_asu_shape_vertices = float_asu.shape_vertices() assert len(float_asu_shape_vertices) >= len(asu_shape_vertices) m_near_sphere_surface = 0 for vertex in float_asu_shape_vertices: assert float_asu.is_inside(point=vertex) assert not asu_shrunk.is_inside(vertex) r = abs(matrix.col(unit_cell.orthogonalize(vertex)) - center) assert r < radius + 1.e-5 if (radius - r < radius * 1.e-2): m_near_sphere_surface += 1 assert m_near_sphere_surface >= n_near_sphere_surface line_asu = copy.copy(asu) line_asu.add_planes([(0,0,1),(1,1,1)], both_directions=True) assert len(line_asu.cuts) == len(asu.cuts) + 4 assert line_asu.cuts[-2].n == (-line_asu.cuts[-1]).n
def asu_as_jvx(group_type_number, asu, colored_grid_points=None, http_server_name=None, html_subdir="asu_gallery", jars_url="http://%s/jv395/jars", explore_symmetry_url= "http://%s/cctbx/cctbx_web.cgi" \ +"?target_module=explore_symmetry&sgsymbol="): if (http_server_name is None): http_server_name = web_links.default_http_server_name xy_plane_only = (group_type_number < 0) space_group_info = sgtbx.space_group(asu.hall_symbol).info() if (not xy_plane_only): assert space_group_info.type().number() == group_type_number list_of_polygons = facet_analysis.asu_polygons(asu) all_edge_segments = facet_analysis.get_all_edge_segments( asu, list_of_polygons) all_vertices = facet_analysis.get_all_vertices(all_edge_segments) unit_cell = space_group_info.any_compatible_unit_cell(volume=100) ortho = orthogonalizer(unit_cell) shrink_length = get_diagonal_extend(ortho, all_vertices) * 0.02 geometries = [] if (colored_grid_points is None): for polygons in list_of_polygons: for polygon, inclusive_flag in polygons: def exclude(): for vertex in polygon: if (vertex[0][2] != 0): return True return False if (xy_plane_only and exclude()): continue vertices_cart = cartesian_polygon(ortho, polygon) vertices_inside_cart = shrink_polygon(vertices_cart, shrink_length) points_int = jvx.pointSet() g = jvx.geometry("facet", backface=["hide", "show"][int(xy_plane_only)]) points_cart = g.points points_cart.hide_points() i = -1 for vertex in polygon: i += 1 points_int.append(vertex[0]) points_cart.append(vertices_inside_cart[i]) faces = g.faces point_indices = [] for vertex in polygon: point_indices.append(points_int.index(vertex[0])) faces.append( jvx.face(point_indices, select_color(inclusive_flag))) geometries.append(g) geometries.append( edge_geometry(ortho, all_edge_segments, shrink_length, xy_plane_only=xy_plane_only)) geometries.append( vertex_geometry(ortho, all_vertices, xy_plane_only=xy_plane_only)) else: g = jvx.geometry("grid") for frac in colored_grid_points: if (xy_plane_only and frac.site[2] != 0): continue g.points.append(jvx.point(ortho(frac.site), color=frac.color)) geometries.append(g) if (colored_grid_points is None): grid_label = "" alternative_html_infix = "_grid" alternative_label = "Grid view" else: grid_label = "_grid" alternative_html_infix = "" alternative_label = "Polygon view" if (xy_plane_only): fmt = "asu_%02d%s" else: fmt = "asu_%03d%s" base_file_name = fmt % (abs(group_type_number), grid_label) jvx_file_name = os.path.join(html_subdir, base_file_name + ".jvx") jvx_in_html = base_file_name + ".jvx" html_file_name = os.path.join(html_subdir, base_file_name + ".html") prev_html = None next_html = None if (xy_plane_only): fmt = "asu_%02d%s.html" last_group_type_number = 17 else: fmt = "asu_%03d%s.html" last_group_type_number = 230 if (abs(group_type_number) > 1): prev_html = fmt % (abs(group_type_number) - 1, grid_label) else: prev_html = fmt % (last_group_type_number, grid_label) if (abs(group_type_number) < last_group_type_number): next_html = fmt % (abs(group_type_number) + 1, grid_label) else: next_html = fmt % (1, grid_label) alternative_html = fmt % (abs(group_type_number), alternative_html_infix) if (colored_grid_points is None or len(colored_grid_points) > 0): f = open(jvx_file_name, "w") jvx.head(f) unit_cell_geometry(ortho, xy_plane_only=xy_plane_only).jvx(f) basis_vector_geometry(ortho, get_min_fractional(all_vertices)).jvx(f) for g in geometries: g.jvx(f) jvx.tail(f) f.close() legend = [] l = legend.append l("Surface area: green = inside the asymmetric unit, red = outside") l("<br>") l("Basis vectors: a = red, b = green, c = blue") l("<p>") shape_vertices = facet_analysis.shape_vertices(asu) l("<table border=2 cellpadding=8>") l("<tr valign=top>") l("<td>") remaining = [] for vertex in shape_vertices: if (xy_plane_only and vertex[2] != 0): continue remaining.append(vertex) remaining.sort() l("<pre>Number of vertices: %d" % len(remaining)) if (xy_plane_only): j = -4 else: j = -1 for vertex in remaining: l(" " + str(vertex)[1:j]) l("</pre>") l("</td>") l("<td>") remaining = [] for cut in asu.cuts: if (xy_plane_only and cut.as_xyz() in ["z>=0", "z<1"]): continue remaining.append(cut) l("<pre>Number of faces: %d" % len(remaining)) for cut in remaining: l(" " + cut.as_xyz()) l("</pre>") l('<a href="guide_to_notation.html">[Guide to notation]</a>') l("</td>") l("<td>") l("<pre>Geometric notation:") for cut in remaining: l(" " + str(cut)) l("</pre>") l('<a href="http://scripts.iucr.org/cgi-bin/paper?pz5088" target="external">' '[Acta Cryst. article]</a>') l("</td>") l("</tr>") l("</table>") if (not xy_plane_only): title = "ASU " + str(space_group_info) header = 'Space group: <a href="%s">%s</a> (No. %d)' % ( explore_symmetry_url % http_server_name + urllib.quote_plus(str(space_group_info)), str(space_group_info), group_type_number) sub_header = None else: from cctbx.sgtbx import plane_groups pg_symbol = plane_groups.hermann_mauguin_hall_table[-group_type_number - 1][0].replace( "_", " ") title = "ASU " + pg_symbol header = 'Plane group: %s (No. %d)' % (pg_symbol, -group_type_number) sub_header = 'Corresponding space group: <a href="%s">%s</a> (No. %d)' % ( explore_symmetry_url % http_server_name + urllib.quote_plus(str(space_group_info)), str(space_group_info), space_group_info.type().number()) f = open(html_file_name, "w") jvx.html_loader(jvx_in_html, title=title, header=header, sub_header=sub_header, index_html="index.html", prev_html=prev_html, next_html=next_html, alternative_label=alternative_label, alternative_html=alternative_html, legend=legend, jars_url=jars_url % http_server_name, f=f) f.close()
def asu_as_jvx( group_type_number, asu, colored_grid_points=None, http_server_name=None, html_subdir="asu_gallery", jars_url="http://%s/jv395/jars", explore_symmetry_url="http://%s/cctbx/cctbx_web.cgi" + "?target_module=explore_symmetry&sgsymbol=", ): if http_server_name is None: http_server_name = web_links.default_http_server_name xy_plane_only = group_type_number < 0 space_group_info = sgtbx.space_group(asu.hall_symbol).info() if not xy_plane_only: assert space_group_info.type().number() == group_type_number list_of_polygons = facet_analysis.asu_polygons(asu) all_edge_segments = facet_analysis.get_all_edge_segments(asu, list_of_polygons) all_vertices = facet_analysis.get_all_vertices(all_edge_segments) unit_cell = space_group_info.any_compatible_unit_cell(volume=100) ortho = orthogonalizer(unit_cell) shrink_length = get_diagonal_extend(ortho, all_vertices) * 0.02 geometries = [] if colored_grid_points is None: for polygons in list_of_polygons: for polygon, inclusive_flag in polygons: def exclude(): for vertex in polygon: if vertex[0][2] != 0: return True return False if xy_plane_only and exclude(): continue vertices_cart = cartesian_polygon(ortho, polygon) vertices_inside_cart = shrink_polygon(vertices_cart, shrink_length) points_int = jvx.pointSet() g = jvx.geometry("facet", backface=["hide", "show"][int(xy_plane_only)]) points_cart = g.points points_cart.hide_points() i = -1 for vertex in polygon: i += 1 points_int.append(vertex[0]) points_cart.append(vertices_inside_cart[i]) faces = g.faces point_indices = [] for vertex in polygon: point_indices.append(points_int.index(vertex[0])) faces.append(jvx.face(point_indices, select_color(inclusive_flag))) geometries.append(g) geometries.append(edge_geometry(ortho, all_edge_segments, shrink_length, xy_plane_only=xy_plane_only)) geometries.append(vertex_geometry(ortho, all_vertices, xy_plane_only=xy_plane_only)) else: g = jvx.geometry("grid") for frac in colored_grid_points: if xy_plane_only and frac.site[2] != 0: continue g.points.append(jvx.point(ortho(frac.site), color=frac.color)) geometries.append(g) if colored_grid_points is None: grid_label = "" alternative_html_infix = "_grid" alternative_label = "Grid view" else: grid_label = "_grid" alternative_html_infix = "" alternative_label = "Polygon view" if xy_plane_only: fmt = "asu_%02d%s" else: fmt = "asu_%03d%s" base_file_name = fmt % (abs(group_type_number), grid_label) jvx_file_name = os.path.join(html_subdir, base_file_name + ".jvx") jvx_in_html = base_file_name + ".jvx" html_file_name = os.path.join(html_subdir, base_file_name + ".html") prev_html = None next_html = None if xy_plane_only: fmt = "asu_%02d%s.html" last_group_type_number = 17 else: fmt = "asu_%03d%s.html" last_group_type_number = 230 if abs(group_type_number) > 1: prev_html = fmt % (abs(group_type_number) - 1, grid_label) else: prev_html = fmt % (last_group_type_number, grid_label) if abs(group_type_number) < last_group_type_number: next_html = fmt % (abs(group_type_number) + 1, grid_label) else: next_html = fmt % (1, grid_label) alternative_html = fmt % (abs(group_type_number), alternative_html_infix) if colored_grid_points is None or len(colored_grid_points) > 0: f = open(jvx_file_name, "w") jvx.head(f) unit_cell_geometry(ortho, xy_plane_only=xy_plane_only).jvx(f) basis_vector_geometry(ortho, get_min_fractional(all_vertices)).jvx(f) for g in geometries: g.jvx(f) jvx.tail(f) f.close() legend = [] l = legend.append l("Surface area: green = inside the asymmetric unit, red = outside") l("<br>") l("Basis vectors: a = red, b = green, c = blue") l("<p>") shape_vertices = facet_analysis.shape_vertices(asu) l("<table border=2 cellpadding=8>") l("<tr valign=top>") l("<td>") remaining = [] for vertex in shape_vertices: if xy_plane_only and vertex[2] != 0: continue remaining.append(vertex) remaining.sort() l("<pre>Number of vertices: %d" % len(remaining)) if xy_plane_only: j = -4 else: j = -1 for vertex in remaining: l(" " + str(vertex)[1:j]) l("</pre>") l("</td>") l("<td>") remaining = [] for cut in asu.cuts: if xy_plane_only and cut.as_xyz() in ["z>=0", "z<1"]: continue remaining.append(cut) l("<pre>Number of faces: %d" % len(remaining)) for cut in remaining: l(" " + cut.as_xyz()) l("</pre>") l('<a href="guide_to_notation.html">[Guide to notation]</a>') l("</td>") l("<td>") l("<pre>Geometric notation:") for cut in remaining: l(" " + str(cut)) l("</pre>") l('<a href="http://scripts.iucr.org/cgi-bin/paper?pz5088" target="external">' "[Acta Cryst. article]</a>") l("</td>") l("</tr>") l("</table>") if not xy_plane_only: title = "ASU " + str(space_group_info) header = 'Space group: <a href="%s">%s</a> (No. %d)' % ( explore_symmetry_url % http_server_name + urllib.quote_plus(str(space_group_info)), str(space_group_info), group_type_number, ) sub_header = None else: from cctbx.sgtbx import plane_groups pg_symbol = plane_groups.hermann_mauguin_hall_table[-group_type_number - 1][0].replace("_", " ") title = "ASU " + pg_symbol header = "Plane group: %s (No. %d)" % (pg_symbol, -group_type_number) sub_header = 'Corresponding space group: <a href="%s">%s</a> (No. %d)' % ( explore_symmetry_url % http_server_name + urllib.quote_plus(str(space_group_info)), str(space_group_info), space_group_info.type().number(), ) f = open(html_file_name, "w") jvx.html_loader( jvx_in_html, title=title, header=header, sub_header=sub_header, index_html="index.html", prev_html=prev_html, next_html=next_html, alternative_label=alternative_label, alternative_html=alternative_html, legend=legend, jars_url=jars_url % http_server_name, f=f, ) f.close()