Esempio n. 1
0
def exercise_polygon():
  from dials.util import is_inside_polygon
  from scitbx.array_family import flex

  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]
Esempio n. 2
0
def exercise_polygon():
  from dials.util import is_inside_polygon
  from scitbx.array_family import flex

  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]
Esempio n. 3
0
def filter_shadowed_reflections(experiments, reflections):
  from dials.util import mask_untrusted_polygon
  from dials.util import is_inside_polygon
  shadowed = flex.bool(reflections.size(), False)
  for expt_id in range(len(experiments)):
    expt = experiments[expt_id]
    imgset = expt.imageset
    masker = imgset.reader().get_format().get_goniometer_shadow_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
Esempio n. 4
0
    def project_extrema(self, detector, scan_angle):
        from dials.util import is_inside_polygon
        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
            from scitbx.math import principal_axes_of_inertia_2d
            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
Esempio n. 5
0
  def project_extrema(self, detector, scan_angle):
    from dials.util import is_inside_polygon
    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
      from scitbx.math import principal_axes_of_inertia_2d
      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