# Path: moonlight/glyphs/geometry.py
# def glyph_y(staff, glyph):
# 
# Path: moonlight/glyphs/glyph_types.py
# def is_notehead(glyph):
# def is_stemmed_notehead(glyph):
# def is_beamed_notehead(glyph):
# def is_dotted_notehead(glyph):
# def is_clef(glyph):
# def is_rest(glyph):
# 
# Path: moonlight/structure/components.py
# class ConnectedComponentsColumns(enum.IntEnum):
# class ConnectedComponents(object):
# class ComputedComponents(object):
#   X0 = 0
#   Y0 = 1
#   X1 = 2
#   Y1 = 3
#   SIZE = 4
# def from_staff_remover(staff_remover, threshold=127):
#   def __init__(self, components):
#   def __init__(self, components):
# def get_component_bounds(image):
# def _unsorted_segment_min(data, segment_ids, num_segments):


import numpy as np
from moonlight.glyphs import geometry
from moonlight.glyphs import glyph_types
from moonlight.protobuf import musicscore_pb2
from moonlight.structure import components
            y_max = y + staff.staffline_distance / 2.
            dots = self.dots[_is_in_range(x_min, self.dots[:, 0], x_max)
                             & _is_in_range(y_min, self.dots[:, 1], y_max)]
            glyph.dot.extend(
                musicscore_pb2.Point(x=dot[0], y=dot[1]) for dot in dots)

    return page


def _is_in_range(min_value, values, max_value):
  return np.logical_and(min_value <= values, values <= max_value)


def _extract_dots(structure):
  """Returns candidate note dots.

  Note dots must be connected components which are roundish (the area of the
  component's bounds is at least half full), and are the expected size.

  Args:
    structure: A computed `Structure`.

  Returns:
    A numpy array of shape `(N, 2)`. Each entry holds the center `(x, y)` of a
    candidate note dot.
  """
  min_height_width = structure.staff_detector.staffline_thickness + 1
  # TODO(ringw): Are note dots typically smaller in ossia parts?
  max_height_width = np.median(
      structure.staff_detector.staffline_distance) * 2 / 3

# Path: moonlight/glyphs/geometry.py
# def glyph_y(staff, glyph):
# 
# Path: moonlight/glyphs/glyph_types.py
# def is_notehead(glyph):
# def is_stemmed_notehead(glyph):
# def is_beamed_notehead(glyph):
# def is_dotted_notehead(glyph):
# def is_clef(glyph):
# def is_rest(glyph):
# 
# Path: moonlight/structure/components.py
# class ConnectedComponentsColumns(enum.IntEnum):
# class ConnectedComponents(object):
# class ComputedComponents(object):
#   X0 = 0
#   Y0 = 1
#   X1 = 2
#   Y1 = 3
#   SIZE = 4
# def from_staff_remover(staff_remover, threshold=127):
#   def __init__(self, components):
#   def __init__(self, components):
# def get_component_bounds(image):
# def _unsorted_segment_min(data, segment_ids, num_segments):


# Path: moonlight/glyphs/note_dots.py
import numpy as np
from moonlight.glyphs import geometry
from moonlight.glyphs import glyph_types
from moonlight.protobuf import musicscore_pb2
from moonlight.structure import components

            y_max = y + staff.staffline_distance / 2.
            dots = self.dots[_is_in_range(x_min, self.dots[:, 0], x_max)
                             & _is_in_range(y_min, self.dots[:, 1], y_max)]
            glyph.dot.extend(
                musicscore_pb2.Point(x=dot[0], y=dot[1]) for dot in dots)

    return page


def _is_in_range(min_value, values, max_value):
  return np.logical_and(min_value <= values, values <= max_value)


def _extract_dots(structure):
  """Returns candidate note dots.

  Note dots must be connected components which are roundish (the area of the
  component's bounds is at least half full), and are the expected size.

  Args:
    structure: A computed `Structure`.

  Returns:
    A numpy array of shape `(N, 2)`. Each entry holds the center `(x, y)` of a
    candidate note dot.
  """
  min_height_width = structure.staff_detector.staffline_thickness + 1
  # TODO(ringw): Are note dots typically smaller in ossia parts?
  max_height_width = np.median(
      structure.staff_detector.staffline_distance) * 2 / 3

  connected_components = structure.connected_components.components