Esempio n. 1
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
Esempio n. 2
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