Exemplo n.º 1
0
def test_polygon():
    poly = flex.vec2_double(((0, 0), (1, 0), (1, 1), (0, 1)))
    assert is_inside_polygon(poly, 0, 0)
    assert is_inside_polygon(poly, 0.5, 0.5)
    assert not is_inside_polygon(poly, 1, 1.01)
    points = flex.vec2_double(((0.3, 0.8), (0.3, 1.5), (-8, 9), (0.00001, 0.9999)))
    assert list(is_inside_polygon(poly, points)) == [True, False, False, True]
Exemplo n.º 2
0
def filter_shadowed_reflections(experiments, reflections, experiment_goniometer=False):
    from dxtbx.masking import is_inside_polygon
    from scitbx.array_family import flex

    shadowed = flex.bool(reflections.size(), False)
    for expt_id in range(len(experiments)):
        expt = experiments[expt_id]
        imageset = expt.imageset
        masker = imageset.masker()
        detector = expt.detector
        sel = reflections["id"] == expt_id
        isel = sel.iselection()
        x, y, z = reflections["xyzcal.px"].select(isel).parts()
        start, end = expt.scan.get_array_range()
        for i in range(start, end):
            shadow = masker.project_extrema(
                detector, expt.scan.get_angle_from_array_index(i)
            )
            img_sel = (z >= i) & (z < (i + 1))
            img_isel = img_sel.iselection()
            for p_id in range(len(detector)):
                panel = reflections["panel"].select(img_isel)
                if shadow[p_id].size() < 4:
                    continue
                panel_isel = img_isel.select(panel == p_id)
                inside = is_inside_polygon(
                    shadow[p_id],
                    flex.vec2_double(
                        x.select(isel.select(panel_isel)),
                        y.select(isel.select(panel_isel)),
                    ),
                )
                shadowed.set_selected(panel_isel, inside)

    return shadowed
Exemplo n.º 3
0
    def project_extrema(self, detector, scan_angle):
        coords = self.extrema_at_scan_angle(scan_angle)
        shadow_boundary = []

        for p_id, p in enumerate(detector):
            # project coordinates onto panel plane
            a = p.get_D_matrix() * coords
            x, y, z = a.parts()
            valid = z > 0
            x.set_selected(valid, x.select(valid) / z.select(valid))
            y.set_selected(valid, y.select(valid) / z.select(valid))

            if valid.count(True) < 3:
                # no shadow projected onto this panel
                shadow_boundary.append(flex.vec2_double())
                continue

            # Compute convex hull of shadow points
            points = flex.vec2_double(x.select(valid), y.select(valid))
            shadow = flex.vec2_double(_convex_hull(points))
            shadow *= 1 / p.get_pixel_size()[0]

            shadow_orig = shadow.deep_copy()

            for i in (0, p.get_image_size()[0]):
                points = flex.vec2_double(
                    flex.double(p.get_image_size()[1], i),
                    flex.double_range(0, p.get_image_size()[1]),
                )
                inside = is_inside_polygon(shadow_orig, points)
                # only add those points needed to define vertices of shadow
                inside_isel = inside.iselection()
                outside_isel = (~inside).iselection()
                while inside_isel.size():
                    j = inside_isel[0]
                    shadow.append(points[j])
                    outside_isel = outside_isel.select(outside_isel > j)
                    if outside_isel.size() == 0:
                        shadow.append(points[inside_isel[-1]])
                        break
                    sel = inside_isel >= outside_isel[0]
                    if sel.count(True) == 0:
                        shadow.append(points[inside_isel[-1]])
                        break
                    inside_isel = inside_isel.select(sel)

            for i in (0, p.get_image_size()[1]):
                points = flex.vec2_double(
                    flex.double_range(0, p.get_image_size()[0]),
                    flex.double(p.get_image_size()[0], i),
                )
                inside = is_inside_polygon(shadow_orig, points)
                # only add those points needed to define vertices of shadow
                inside_isel = inside.iselection()
                outside_isel = (~inside).iselection()
                while inside_isel.size():
                    j = inside_isel[0]
                    shadow.append(points[j])
                    outside_isel = outside_isel.select(outside_isel > j)
                    if outside_isel.size() == 0:
                        shadow.append(points[inside_isel[-1]])
                        break
                    sel = inside_isel >= outside_isel[0]
                    if sel.count(True) == 0:
                        shadow.append(points[inside_isel[-1]])
                        break
                    inside_isel = inside_isel.select(sel)

            # Select only those vertices that are within the panel dimensions
            n_px = p.get_image_size()
            x, y = shadow.parts()
            valid = (x >= 0) & (x <= n_px[0]) & (y >= 0) & (y <= n_px[1])
            shadow = shadow.select(valid)

            # sort vertices clockwise from centre of mass
            com = principal_axes_of_inertia_2d(shadow).center_of_mass()
            sx, sy = shadow.parts()
            shadow = shadow.select(
                flex.sort_permutation(flex.atan2(sy - com[1], sx - com[0]))
            )

            shadow_boundary.append(shadow)

        return shadow_boundary