docstr: Run the algorithm on one image set
docstr_tok: ["Run","the","algorithm","on","one","image","set"]
code: def run(self, workspace):
      """Run the algorithm on one image set"""
      #
      # Get the image as a binary image
      #
      image_set = workspace.image_set
      image = image_set.get_image(
          self.image_name.value, must_be_binary=True
      )
      mask = image.pixel_data
      if image.has_mask:
          mask = mask & image.mask
      angle_count = self.angle_count.value
      #
      # We collect the i,j and angle of pairs of points that
      # are 3-d adjacent after erosion.
      #
      # i - the i coordinate of each point found after erosion
      # j - the j coordinate of each point found after erosion
      # a - the angle of the structuring element for each point found
      #
      i = numpy.zeros(0, int)
      j = numpy.zeros(0, int)
      a = numpy.zeros(0, int)
  
      ig, jg = numpy.mgrid[0 : mask.shape[0], 0 : mask.shape[1]]
      this_idx = 0
      for angle_number in range(angle_count):
          angle = float(angle_number) * numpy.pi / float(angle_count)
          strel = self.get_diamond(angle)
          erosion = binary_erosion(mask, strel)
          #
          # Accumulate the count, i, j and angle for all foreground points
          # in the erosion
          #
          this_count = numpy.sum(erosion)
          i = numpy.hstack((i, ig[erosion]))
          j = numpy.hstack((j, jg[erosion]))
          a = numpy.hstack((a, numpy.ones(this_count, float) * angle))
      #
      # Find connections based on distances, not adjacency
      #
      first, second = self.find_adjacent_by_distance(i, j, a)
      #
      # Do all connected components.
      #
      if len(first) > 0:
          ij_labels = all_connected_components(first, second) + 1
          nlabels = numpy.max(ij_labels)
          label_indexes = numpy.arange(1, nlabels + 1)
          #
          # Compute the measurements
          #
          center_x = fixup_scipy_ndimage_result(
              mean_of_labels(j, ij_labels, label_indexes)
          )
          center_y = fixup_scipy_ndimage_result(
              mean_of_labels(i, ij_labels, label_indexes)
          )
          #
          # The angles are wierdly complicated because of the wrap-around.
          # You can imagine some horrible cases, like a circular patch of
          # "worm" in which all angles are represented or a gentle "U"
          # curve.
          #
          # For now, I'm going to use the following heuristic:
          #
          # Compute two different "angles". The angles of one go
          # from 0 to 180 and the angles of the other go from -90 to 90.
          # Take the variance of these from the mean and
          # choose the representation with the lowest variance.
          #
          # An alternative would be to compute the variance at each possible
          # dividing point. Another alternative would be to actually trace through
          # the connected components - both overkill for such an inconsequential
          # measurement I hope.
          #
          angles = fixup_scipy_ndimage_result(
              mean_of_labels(a, ij_labels, label_indexes)
          )
          vangles = fixup_scipy_ndimage_result(
              mean_of_labels(
                  (a - angles[ij_labels - 1]) ** 2,
                  ij_labels,
                  label_indexes,
              )
          )
          aa = a.copy()
          aa[a > numpy.pi / 2] -= numpy.pi
          aangles = fixup_scipy_ndimage_result(
              mean_of_labels(aa, ij_labels, label_indexes)
          )
          vaangles = fixup_scipy_ndimage_result(
              mean_of_labels(
                  (aa - aangles[ij_labels - 1]) ** 2,
                  ij_labels,
                  label_indexes,
              )
          )
          aangles[aangles < 0] += numpy.pi
          angles[vaangles < vangles] = aangles[vaangles < vangles]
          #
          # Squish the labels to 2-d. The labels for overlaps are arbitrary.
          #
          labels = numpy.zeros(mask.shape, int)
          labels[i, j] = ij_labels
      else:
          center_x = numpy.zeros(0, int)
          center_y = numpy.zeros(0, int)
          angles = numpy.zeros(0)
          nlabels = 0
          label_indexes = numpy.zeros(0, int)
          labels = numpy.zeros(mask.shape, int)
  
      m = workspace.measurements
      assert isinstance(m, Measurements)
      object_name = self.object_name.value
      m.add_measurement(object_name, M_LOCATION_CENTER_X, center_x)
      m.add_measurement(object_name, M_LOCATION_CENTER_Y, center_y)
      m.add_measurement(object_name, M_ANGLE, angles * 180 / numpy.pi)
      m.add_measurement(
          object_name,
          M_NUMBER_OBJECT_NUMBER,
          label_indexes,
      )
      m.add_image_measurement(FF_COUNT % object_name, nlabels)
      #
      # Make the objects
      #
      object_set = workspace.object_set
      assert isinstance(object_set, ObjectSet)
      objects = Objects()
      objects.segmented = labels
      objects.parent_image = image
      object_set.add_objects(objects, object_name)
      if self.show_window:
          workspace.display_data.i = center_y
          workspace.display_data.j = center_x
          workspace.display_data.angle = angles
          workspace.display_data.mask = mask
          workspace.display_data.labels = labels
          workspace.display_data.count = nlabels
  
imports: import matplotlib.cm
  import numpy
  from cellprofiler_core.constants.measurement import COLTYPE_INTEGER, M_LOCATION_CENTER_X, M_LOCATION_CENTER_Y, M_NUMBER_OBJECT_NUMBER, FF_COUNT, COLTYPE_FLOAT, IMAGE, C_COUNT, C_LOCATION, C_NUMBER, FTR_CENTER_X, FTR_CENTER_Y, FTR_OBJECT_NUMBER
  from cellprofiler_core.measurement import Measurements
  from cellprofiler_core.module import Module
  from cellprofiler_core.object import Objects, ObjectSet
  from cellprofiler_core.preferences import get_default_colormap
  from cellprofiler_core.setting import Binary
  from cellprofiler_core.setting.subscriber import ImageSubscriber
  from cellprofiler_core.setting.text import LabelName, Integer, Float
  from centrosome.cpmorphology import all_connected_components
  from centrosome.cpmorphology import fixup_scipy_ndimage_result
  from centrosome.cpmorphology import get_line_pts
  from scipy.ndimage import binary_erosion, binary_fill_holes
  from scipy.ndimage import mean
label_desc: Use image node_id 4 for calling the IdentifyDeadWorms obj's underlying member method code with example usage: obj.run(workspace) without return types