def apply()

in moonlight/structure/stems.py [0:0]


  def apply(self, page):
    """Detects stems on the page.

    Using `self.stem_candidates`, finds verticals that align with a notehead
    glyph, and adds the stems.

    Args:
      page: The Page message.

    Returns:
      The same page, updated with stems.
    """
    for system in page.system:
      for staff, staff_ys in zip(system.staff,
                                 self.staff_detector.staves_interpolated_y):
        allowed_distance = np.multiply(
            _STEM_NOTEHEAD_DISTANCE_STAFFLINE_DISTANCE,
            staff.staffline_distance)
        expected_horizontal_distance = np.multiply(
            _STEM_NOTEHEAD_HORIZONTAL_STAFFLINE_DISTANCE,
            staff.staffline_distance)
        for glyph in staff.glyph:
          if glyph_types.is_stemmed_notehead(glyph):
            glyph_y = (
                staff_ys[glyph.x] -
                glyph.y_position * staff.staffline_distance / 2.0)
            # Compute the ideal coordinates for the glyph to be assigned to each
            # stem.

            # Clip the glyph_y to the stem start and end y to get the ideal y.
            ideal_y = np.clip(glyph_y, self.stem_candidates[:, 0, 1],
                              self.stem_candidates[:, 1, 1])
            # If the glyph is left of the stem, subtract the expected distance
            # from the stem x; otherwise, add it.
            ideal_x = self.stem_candidates[:, 0, 0] + np.where(
                glyph.x < self.stem_candidates[:, 0, 0],
                -expected_horizontal_distance, expected_horizontal_distance)
            stem_distance = np.linalg.norm(
                np.c_[ideal_x - glyph.x, ideal_y - glyph_y], axis=1)
            stem = np.argmin(stem_distance)
            if stem_distance[stem] <= allowed_distance:
              stem_coords = self.stem_candidates[stem]
              glyph.stem.CopyFrom(
                  musicscore_pb2.LineSegment(
                      start=musicscore_pb2.Point(
                          x=stem_coords[0, 0], y=stem_coords[0, 1]),
                      end=musicscore_pb2.Point(
                          x=stem_coords[1, 0], y=stem_coords[1, 1])))
    return page