示例#1
0
    def from_pitch_carriers(cls, pitch_carrier_1, pitch_carrier_2):
        '''Makes numbered interval from `pitch_carrier_1` and
        `pitch_carrier_2`.

        ::

            >>> pitchtools.NumberedInterval.from_pitch_carriers(
            ...     NamedPitch(-2), 
            ...     NamedPitch(12),
            ...     )
            NumberedInterval(14)

        Returns numbered interval.
        '''
        from abjad.tools import pitchtools
        # get pitches
        pitch_1 = pitchtools.get_named_pitch_from_pitch_carrier(
            pitch_carrier_1)
        pitch_2 = pitchtools.get_named_pitch_from_pitch_carrier(
            pitch_carrier_2)
        # get difference in semitones
        number = abs(pitchtools.NumberedPitch(pitch_2)) - \
            abs(pitchtools.NumberedPitch(pitch_1))
        # change 1.0, 2.0, ... into 1, 2, ...
        number = mathtools.integer_equivalent_number_to_integer(number)
        # return numbered interval
        return cls(number)
示例#2
0
    def from_pitch_carriers(cls, pitch_carrier_1, pitch_carrier_2):
        '''Makes numbered interval from `pitch_carrier_1` and
        `pitch_carrier_2`.

        ::

            >>> pitchtools.NumberedInterval.from_pitch_carriers(
            ...     NamedPitch(-2),
            ...     NamedPitch(12),
            ...     )
            NumberedInterval(14)

        Returns numbered interval.
        '''
        from abjad.tools import pitchtools
        # get pitches
        pitch_1 = pitchtools.get_named_pitch_from_pitch_carrier(
            pitch_carrier_1)
        pitch_2 = pitchtools.get_named_pitch_from_pitch_carrier(
            pitch_carrier_2)
        # get difference in semitones
        number = pitchtools.NumberedPitch(pitch_2).pitch_number - \
            pitchtools.NumberedPitch(pitch_1).pitch_number
        # change 1.0, 2.0, ... into 1, 2, ...
        number = mathtools.integer_equivalent_number_to_integer(number)
        # return numbered interval
        return cls(number)
示例#3
0
    def from_pitch_carriers(cls, pitch_carrier_1, pitch_carrier_2):
        '''Calculate named interval from `pitch_carrier_1` to
        `pitch_carrier_2`:

        ::

            >>> pitchtools.NamedInterval.from_pitch_carriers(
            ...     NamedPitch(-2),
            ...     NamedPitch(12),
            ...     )
            NamedInterval('+M9')

        Returns named interval.
        '''
        from abjad.tools import pitchtools
        pitch_1 = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier_1)
        pitch_2 = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier_2)
        degree_1 = pitch_1.diatonic_pitch_number
        degree_2 = pitch_2.diatonic_pitch_number
        named_interval_number = abs(degree_1 - degree_2) + 1
        numbered_interval_number = abs(
            pitchtools.NumberedPitch(pitch_1).pitch_number -
            pitchtools.NumberedPitch(pitch_2).pitch_number
            )
        absolute_named_interval = \
            pitchtools.spell_numbered_interval_number(
            named_interval_number, numbered_interval_number)
        if pitch_2 < pitch_1:
            named_interval = -absolute_named_interval
        else:
            named_interval = absolute_named_interval
        return cls(named_interval)
示例#4
0
    def from_pitch_carriers(cls, pitch_carrier_1, pitch_carrier_2):
        '''Calculate named interval from `pitch_carrier_1` to
        `pitch_carrier_2`:

        ::

            >>> pitchtools.NamedInterval.from_pitch_carriers(
            ...     NamedPitch(-2),
            ...     NamedPitch(12),
            ...     )
            NamedInterval('+M9')

        Returns named interval.
        '''
        from abjad.tools import pitchtools
        pitch_1 = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier_1)
        pitch_2 = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier_2)
        degree_1 = pitch_1.diatonic_pitch_number
        degree_2 = pitch_2.diatonic_pitch_number
        named_interval_number = abs(degree_1 - degree_2) + 1
        numbered_interval_number = abs(
            pitchtools.NumberedPitch(pitch_1).pitch_number -
            pitchtools.NumberedPitch(pitch_2).pitch_number
            )
        absolute_named_interval = \
            pitchtools.spell_numbered_interval_number(
            named_interval_number, numbered_interval_number)
        if pitch_2 < pitch_1:
            named_interval = -absolute_named_interval
        else:
            named_interval = absolute_named_interval
        return cls(named_interval)
示例#5
0
def _get_intervals_in_subrun(subrun_source):
    from abjad.tools import pitchtools

    subrun_source = list(subrun_source)
    result = [0]
    for first, second in sequencetools.iterate_sequence_nwise(subrun_source):
        first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(first)
        second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(second)
        interval = pitchtools.NumberedPitch(second_pitch).pitch_number - \
            pitchtools.NumberedPitch(first_pitch).pitch_number
        result.append(interval + result[-1])
    result.pop(0)
    return result
def _get_intervals_in_subrun(subrun_source):
    from abjad.tools import pitchtools

    subrun_source = list(subrun_source)
    result = [0]
    for first, second in sequencetools.iterate_sequence_pairwise_strict(
        subrun_source):
        first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(first)
        second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(second)
        interval = abs(pitchtools.NumberedPitch(second_pitch)) - \
            abs(pitchtools.NumberedPitch(first_pitch))
        result.append(interval + result[-1])
    result.pop(0)
    return result
示例#7
0
def color_note_head_by_numbered_pitch_class_color_map(pitch_carrier):
    r'''Color `pitch_carrier` note head:

    ::

        >>> note = Note("c'4")

    ::

        >>> labeltools.color_note_head_by_numbered_pitch_class_color_map(note)
        Note("c'4")

    ..  doctest::

        >>> print(format(note))
        \once \override NoteHead #'color = #(x11-color 'red)
        c'4

    ::

        >>> show(note) # doctest: +SKIP

    Numbered pitch-class color map:

    ::

        0: red
        1: MediumBlue
        2: orange
        3: LightSlateBlue
        4: ForestGreen
        5: MediumOrchid
        6: firebrick
        7: DeepPink
        8: DarkOrange
        9: IndianRed
        10: CadetBlue
        11: SeaGreen
        12: LimeGreen

    Numbered pitch-class color map can not be changed.

    Raise type error when `pitch_carrier` is not a pitch carrier.

    Raise extra pitch error when `pitch_carrier` carries more than 1 note head.

    Raise missing pitch error when `pitch_carrier` carries no note head.

    Return `pitch_carrier`.
    '''

    pitch = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier)
    color = _pc_number_to_color(pitch.numbered_pitch_class.pitch_class_number)
    if color is not None:
        override(pitch_carrier).note_head.color = color
    return pitch_carrier
def color_note_head_by_numbered_pitch_class_color_map(pitch_carrier):
    r'''Color `pitch_carrier` note head:

    ::

        >>> note = Note("c'4")

    ::

        >>> labeltools.color_note_head_by_numbered_pitch_class_color_map(note)
        Note("c'4")

    ..  doctest::

        >>> f(note)
        \once \override NoteHead #'color = #(x11-color 'red)
        c'4

    ::

        >>> show(note) # doctest: +SKIP

    Numbered pitch-class color map:

    ::

        0: red
        1: MediumBlue
        2: orange
        3: LightSlateBlue
        4: ForestGreen
        5: MediumOrchid
        6: firebrick
        7: DeepPink
        8: DarkOrange
        9: IndianRed
        10: CadetBlue
        11: SeaGreen
        12: LimeGreen

    Numbered pitch-class color map can not be changed.

    Raise type error when `pitch_carrier` is not a pitch carrier.

    Raise extra pitch error when `pitch_carrier` carries more than 1 note head.

    Raise missing pitch error when `pitch_carrier` carries no note head.

    Return `pitch_carrier`.
    '''

    pitch = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier)
    color = _pc_number_to_color(abs(pitch.numbered_pitch_class))
    if color is not None:
        pitch_carrier.override.note_head.color = color
    return pitch_carrier
def get_numbered_pitch_class_from_pitch_carrier(pitch_carrier):
    '''Get numbered pitch-class from `pitch_carrier`:

    ::

        >>> note = Note("cs'4")
        >>> pitchtools.get_numbered_pitch_class_from_pitch_carrier(note)
        NumberedPitchClass(1)

    Raise missing pitch error on empty chords.

    Raise extra pitch error on many-note chords.

    Returns numbered pitch-class.
    '''
    from abjad.tools import pitchtools

    pitch = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier)
    pitch_class = pitchtools.NumberedPitchClass(pitch)

    return pitch_class
示例#10
0
def get_numbered_pitch_class_from_pitch_carrier(pitch_carrier):
    '''Get numbered pitch-class from `pitch_carrier`:

    ::

        >>> note = Note("cs'4")
        >>> pitchtools.get_numbered_pitch_class_from_pitch_carrier(note)
        NumberedPitchClass(1)

    Raise missing pitch error on empty chords.

    Raise extra pitch error on many-note chords.

    Returns numbered pitch-class.
    '''
    from abjad.tools import pitchtools

    pitch = pitchtools.get_named_pitch_from_pitch_carrier(pitch_carrier)
    pitch_class = pitchtools.NumberedPitchClass(pitch)

    return pitch_class
示例#11
0
 def _initialize_by_pitch_carrier(self, expr):
     from abjad.tools import pitchtools
     named_pitch = pitchtools.get_named_pitch_from_pitch_carrier(
         expr)
     self._initialize_by_named_pitch(named_pitch)
def list_named_pitches_in_expr(expr):
    '''List named pitches in `expr`:

    ::

        >>> staff = Staff("c'4 d'4 e'4 f'4")
        >>> beam = spannertools.Beam()
        >>> attach(beam, staff[:])

    ::

        >>> for x in pitchtools.list_named_pitches_in_expr(beam):
        ...     x
        ...
        NamedPitch("c'")
        NamedPitch("d'")
        NamedPitch("e'")
        NamedPitch("f'")

    Returns tuple.
    '''
    from abjad.tools import pitchtools
    from abjad.tools import scoretools
    from abjad.tools import spannertools

    # TODO: remove try-except
    try:
        result = pitchtools.get_named_pitch_from_pitch_carrier(expr)
        return pitchtools.PitchSegment(
            items=(result,),
            item_class=pitchtools.NamedPitch,
            )
    except (TypeError, ValueError):
        result = []
        if hasattr(expr, 'written_pitches'):
            result.extend(expr.written_pitches)
        # for pitch arrays
        elif hasattr(expr, 'pitches'):
            result.extend(expr.pitches)
        elif isinstance(expr, spannertools.Spanner):
            for leaf in expr._leaves:
                if hasattr(leaf, 'written_pitch') and \
                    not isinstance(leaf, scoretools.Rest):
                    result.append(leaf.written_pitch)
                elif hasattr(leaf, 'written_pitches'):
                    result.extend(leaf.written_pitches)
        elif isinstance(expr, pitchtools.PitchSet):
            result.extend(sorted(list(expr)))
        elif isinstance(expr, (list, tuple, set)):
            for x in expr:
                result.extend(list_named_pitches_in_expr(x))
        else:
            for leaf in iterate(expr).by_class(scoretools.Leaf):
                if hasattr(leaf, 'written_pitch') and not isinstance(leaf, scoretools.Rest):
                    result.append(leaf.written_pitch)
                elif hasattr(leaf, 'written_pitches'):
                    result.extend(leaf.written_pitches)
        return pitchtools.PitchSegment(
            items=result,
            item_class=pitchtools.NamedPitch,
            )
def list_numbered_interval_numbers_pairwise(pitch_carriers, wrap=False):
    r'''List numbered interval numbers pairwise between `pitch_carriers`:

    ::

        >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8")

    ..  doctest::

        >>> print format(staff)
        \new Staff {
            c'8
            d'8
            e'8
            f'8
            g'8
            a'8
            b'8
            c''8
        }

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... staff)
        [2, 2, 1, 2, 2, 2, 1]

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... staff, wrap=True)
        [2, 2, 1, 2, 2, 2, 1, -12]

    ::

        >>> notes = [
        ...     Note("c'8"), Note("d'8"), Note("e'8"), Note("f'8"),
        ...     Note("g'8"), Note("a'8"), Note("b'8"), Note("c''8")]

    ::

        >>> notes.reverse()

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... notes)
        [-1, -2, -2, -2, -1, -2, -2]

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... notes, wrap=True)
        [-1, -2, -2, -2, -1, -2, -2, 12]

    When ``wrap = False`` do not return ``pitch_carriers[-1] - pitch_carriers[0]``
    as last in series.

    When ``wrap = True`` do return ``pitch_carriers[-1] - pitch_carriers[0]``
    as last in series.

    Returns list.
    '''
    from abjad.tools import pitchtools

    result = []

    if len(pitch_carriers) == 0:
        return result
    elif len(pitch_carriers) == 1:
        if pitchtools.Pitch.is_pitch_carrier(pitch_carriers[0]):
            return result
        else:
            message = 'must be pitch, not, note-head or chord.'
            raise TypeError(message)

    if wrap:
        pairs = sequencetools.iterate_sequence_pairwise_wrapped(pitch_carriers)
    else:
        pairs = sequencetools.iterate_sequence_pairwise_strict(pitch_carriers)

    for first_carrier, second_carrier in pairs:
        first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(first_carrier)
        second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(second_carrier)
        signed_interval = abs(pitchtools.NumberedPitch(second_pitch)) - \
            abs(pitchtools.NumberedPitch(first_pitch))
        result.append(signed_interval)

    return result
示例#14
0
 def _initialize_by_pitch_carrier(self, expr):
     from abjad.tools import pitchtools
     named_pitch = pitchtools.get_named_pitch_from_pitch_carrier(
         expr)
     self._initialize_by_named_pitch(named_pitch)
示例#15
0
def insert_and_transpose_nested_subruns_in_pitch_class_number_list(
    notes,
    subrun_tokens,
):
    '''Insert and transpose nested subruns in `pitch_class_number_list`
    according to `subrun_tokens`:

    ::

        >>> notes = [Note(p, (1, 4)) for p in [0, 2, 7, 9, 5, 11, 4]]
        >>> subrun_tokens = [(0, [2, 4]), (4, [3, 1])]
        >>> pitchtools.insert_and_transpose_nested_subruns_in_pitch_class_number_list(
        ... notes, subrun_tokens)

        >>> t = []
        >>> for x in notes:
        ...   try:
        ...        t.append(x.written_pitch.pitch_number)
        ...   except AttributeError:
        ...        t.append([y.written_pitch.pitch_number for y in x])

        >>> t
        [0, [5, 7], 2, [4, 0, 6, 11], 7, 9, 5, [10, 6, 8], 11, [7], 4]

    Set `subrun_tokens` to a list of zero or more ``(index, length_list)`` pairs.

    For each ``(index, length_list)`` pair in *subrun_tokens*
    the function will read *index* mod ``len(notes)`` and insert
    a subrun of length ``length_list[0]`` immediately after ``notes[index]``,
    a subrun of length ``length_list[1]`` immediately after ``notes[index+1]``,
    and, in general, a subrun of ``length_list[i]`` immediately after
    ``notes[index+i]``, for ``i < length(length_list)``.

    New subruns are wrapped with lists.
    These wrapper lists are designed
    to allow inspection of the structural changes to *notes*
    immediately after the function returns.
    For this reason most calls to this function will be followed
    by ``notes = sequencetools.flatten_sequence(notes)``:

    ::

        >>> for note in notes: note
        ...
        Note("c'4")
        [Note("f'4"), Note("g'4")]
        Note("d'4")
        [Note("e'4"), Note("c'4"), Note("fs'4"), Note("b'4")]
        Note("g'4")
        Note("a'4")
        Note("f'4")
        [Note("bf'4"), Note("fs'4"), Note("af'4")]
        Note("b'4")
        [Note("g'4")]
        Note("e'4")

    This function is designed to work on a built-in Python list
    of notes. This function is **not** designed to work on Abjad
    voices, staves or other containers because the function currently
    implements no spanner-handling.
    That is, this function is designed to be used during
    precomposition when other, similar abstract pitch transforms
    may be common.

    Returns list of integers and / or floats.
    '''
    from abjad.tools import scoretools
    from abjad.tools import pitchtools

    assert isinstance(notes, list)
    assert all(isinstance(x, scoretools.Note) for x in notes)
    assert isinstance(subrun_tokens, list)

    len_notes = len(notes)
    instructions = []

    for subrun_token in subrun_tokens:
        pairs = _make_index_length_pairs(subrun_token)
        for anchor_index, subrun_length in pairs:
            anchor_note = notes[anchor_index % len_notes]
            anchor_pitch = pitchtools.get_named_pitch_from_pitch_carrier(
                anchor_note)
            anchor_written_duration = anchor_note.written_duration
            source_start_index = anchor_index + 1
            source_stop_index = source_start_index + subrun_length + 1
            cyclic_notes = datastructuretools.CyclicTuple(notes)
            subrun_source = cyclic_notes[source_start_index:source_stop_index]
            subrun_intervals = _get_intervals_in_subrun(subrun_source)
            new_notes = _make_new_notes(anchor_pitch, anchor_written_duration,
                                        subrun_intervals)
            instruction = (anchor_index, new_notes)
            instructions.append(instruction)

    for anchor_index, new_notes in reversed(sorted(instructions)):
        notes.insert(anchor_index + 1, new_notes)
示例#16
0
def list_named_pitches_in_expr(expr):
    '''List named pitches in `expr`:

    ::

        >>> staff = Staff("c'4 d'4 e'4 f'4")
        >>> beam = spannertools.Beam()
        >>> attach(beam, staff[:])

    ::

        >>> for x in pitchtools.list_named_pitches_in_expr(beam):
        ...     x
        ...
        NamedPitch("c'")
        NamedPitch("d'")
        NamedPitch("e'")
        NamedPitch("f'")

    Returns tuple.
    '''
    from abjad.tools import pitchtools
    from abjad.tools import scoretools
    from abjad.tools import spannertools

    # TODO: remove try-except
    try:
        result = pitchtools.get_named_pitch_from_pitch_carrier(expr)
        return pitchtools.PitchSegment(
            items=(result, ),
            item_class=pitchtools.NamedPitch,
        )
    except (TypeError, ValueError):
        result = []
        if hasattr(expr, 'written_pitches'):
            result.extend(expr.written_pitches)
        # for pitch arrays
        elif hasattr(expr, 'pitches'):
            result.extend(expr.pitches)
        elif isinstance(expr, spannertools.Spanner):
            for leaf in expr._leaves:
                if hasattr(leaf, 'written_pitch') and \
                    not isinstance(leaf, scoretools.Rest):
                    result.append(leaf.written_pitch)
                elif hasattr(leaf, 'written_pitches'):
                    result.extend(leaf.written_pitches)
        elif isinstance(expr, pitchtools.PitchSet):
            result.extend(sorted(list(expr)))
        elif isinstance(expr, (list, tuple, set)):
            for x in expr:
                result.extend(list_named_pitches_in_expr(x))
        else:
            for leaf in iterate(expr).by_class(scoretools.Leaf):
                if hasattr(leaf, 'written_pitch') and not isinstance(
                        leaf, scoretools.Rest):
                    result.append(leaf.written_pitch)
                elif hasattr(leaf, 'written_pitches'):
                    result.extend(leaf.written_pitches)
        return pitchtools.PitchSegment(
            items=result,
            item_class=pitchtools.NamedPitch,
        )
示例#17
0
def list_numbered_inversion_equivalent_interval_classes_pairwise(pitch_carriers, wrap=False):
    r'''List numbered inversion-equivalent interval-classes pairwise between
    `pitch_carriers`:

    ::

        >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8")

    ..  doctest::

        >>> print(format(staff))
        \new Staff {
            c'8
            d'8
            e'8
            f'8
            g'8
            a'8
            b'8
            c''8
        }

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... staff, wrap=False)

    ::

        >>> for x in result: x
        ...
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... staff, wrap=True)

    ::

        >>> for x in result: x
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(0)

    ::

        >>> notes = staff.select_leaves()
        >>> notes = list(reversed(notes))

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... notes, wrap=False)

    ::

        >>> for x in result: x
        ...
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... notes, wrap=True)

    ::

        >>> for x in result: x
        ...
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(0)

    When ``wrap=False`` do not return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series.

    When ``wrap=True`` do return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series.

    Returns list.
    '''
    from abjad.tools import pitchtools

    result = []

    if len(pitch_carriers) == 0:
        return result
    elif len(pitch_carriers) == 1:
        if pitchtools.Pitch.is_pitch_carrier(pitch_carriers[0]):
            return result
        else:
            message = 'must be pitch, note, note-head or chord.'
            raise TypeError(message)

    if wrap:
        pairs = sequencetools.iterate_sequence_nwise(
            pitch_carriers, wrapped=True)
    else:
        pairs = sequencetools.iterate_sequence_nwise(pitch_carriers)

    for first_carrier, second_carrier in pairs:
        first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(first_carrier)
        second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(second_carrier)
        mdi = second_pitch - first_pitch
        iecic = pitchtools.NumberedInversionEquivalentIntervalClass(mdi)
        result.append(iecic)

    return result
示例#18
0
def list_numbered_interval_numbers_pairwise(pitch_carriers, wrap=False):
    r'''List numbered interval numbers pairwise between `pitch_carriers`:

    ::

        >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8")

    ..  doctest::

        >>> print(format(staff))
        \new Staff {
            c'8
            d'8
            e'8
            f'8
            g'8
            a'8
            b'8
            c''8
        }

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... staff)
        [2, 2, 1, 2, 2, 2, 1]

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... staff, wrap=True)
        [2, 2, 1, 2, 2, 2, 1, -12]

    ::

        >>> notes = [
        ...     Note("c'8"), Note("d'8"), Note("e'8"), Note("f'8"),
        ...     Note("g'8"), Note("a'8"), Note("b'8"), Note("c''8")]

    ::

        >>> notes.reverse()

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... notes)
        [-1, -2, -2, -2, -1, -2, -2]

    ::

        >>> pitchtools.list_numbered_interval_numbers_pairwise(
        ... notes, wrap=True)
        [-1, -2, -2, -2, -1, -2, -2, 12]

    When ``wrap = False`` do not return ``pitch_carriers[-1] - pitch_carriers[0]``
    as last in series.

    When ``wrap = True`` do return ``pitch_carriers[-1] - pitch_carriers[0]``
    as last in series.

    Returns list.
    '''
    from abjad.tools import pitchtools

    result = []

    if len(pitch_carriers) == 0:
        return result
    elif len(pitch_carriers) == 1:
        if pitchtools.Pitch.is_pitch_carrier(pitch_carriers[0]):
            return result
        else:
            message = 'must be pitch, not, note-head or chord.'
            raise TypeError(message)

    if wrap:
        pairs = sequencetools.iterate_sequence_nwise(
            pitch_carriers, wrapped=True)
    else:
        pairs = sequencetools.iterate_sequence_nwise(pitch_carriers)

    for first_carrier, second_carrier in pairs:
        first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(
            first_carrier)
        second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(
            second_carrier)
        signed_interval = \
            pitchtools.NumberedPitch(second_pitch).pitch_number - \
            pitchtools.NumberedPitch(first_pitch).pitch_number
        result.append(signed_interval)

    return result
def list_numbered_inversion_equivalent_interval_classes_pairwise(pitch_carriers, wrap=False):
    r'''List numbered inversion-equivalent interval-classes pairwise between
    `pitch_carriers`:

    ::

        >>> staff = Staff("c'8 d'8 e'8 f'8 g'8 a'8 b'8 c''8")

    ..  doctest::

        >>> f(staff)
        \new Staff {
            c'8
            d'8
            e'8
            f'8
            g'8
            a'8
            b'8
            c''8
        }

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... staff, wrap=False)

    ::

        >>> for x in result: x
        ...
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... staff, wrap=True)

    ::

        >>> for x in result: x
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(0)

    ::

        >>> notes = staff.select_leaves()
        >>> notes = list(reversed(notes))

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... notes, wrap=False)

    ::

        >>> for x in result: x
        ...
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)

    ::

        >>> result = pitchtools.list_numbered_inversion_equivalent_interval_classes_pairwise(
        ... notes, wrap=True)

    ::

        >>> for x in result: x
        ...
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(1)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(2)
        NumberedInversionEquivalentIntervalClass(0)

    When ``wrap=False`` do not return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series.

    When ``wrap=True`` do return ``pitch_carriers[-1] - pitch_carriers[0]`` as last in series.

    Returns list.
    '''
    from abjad.tools import pitchtools

    result = []

    if len(pitch_carriers) == 0:
        return result
    elif len(pitch_carriers) == 1:
        if pitchtools.Pitch.is_pitch_carrier(pitch_carriers[0]):
            return result
        else:
            raise TypeError('must be Abjad pitch, note, note head or chord.')

    if wrap:
        pairs = sequencetools.iterate_sequence_pairwise_wrapped(pitch_carriers)
    else:
        pairs = sequencetools.iterate_sequence_pairwise_strict(pitch_carriers)

    for first_carrier, second_carrier in pairs:
        first_pitch = pitchtools.get_named_pitch_from_pitch_carrier(first_carrier)
        second_pitch = pitchtools.get_named_pitch_from_pitch_carrier(second_carrier)
        mdi = second_pitch - first_pitch
        iecic = pitchtools.NumberedInversionEquivalentIntervalClass(mdi)
        result.append(iecic)

    return result
def insert_and_transpose_nested_subruns_in_pitch_class_number_list(notes, subrun_indicators):
    '''Insert and transpose nested subruns in `pitch_class_number_list`
    according to `subrun_indicators`:

    ::

        >>> notes = [Note(p, (1, 4)) for p in [0, 2, 7, 9, 5, 11, 4]]
        >>> subrun_indicators = [(0, [2, 4]), (4, [3, 1])]
        >>> pitchtools.insert_and_transpose_nested_subruns_in_pitch_class_number_list(
        ... notes, subrun_indicators)

        >>> t = []
        >>> for x in notes:
        ...   try:
        ...        t.append(x.written_pitch.pitch_number)
        ...   except AttributeError:
        ...        t.append([y.written_pitch.pitch_number for y in x])

        >>> t
        [0, [5, 7], 2, [4, 0, 6, 11], 7, 9, 5, [10, 6, 8], 11, [7], 4]

    Set `subrun_indicators` to a list of zero or more ``(index, length_list)`` pairs.

    For each ``(index, length_list)`` pair in *subrun_indicators*
    the function will read *index* mod ``len(notes)`` and insert
    a subrun of length ``length_list[0]`` immediately after ``notes[index]``,
    a subrun of length ``length_list[1]`` immediately after ``notes[index+1]``,
    and, in general, a subrun of ``length_list[i]`` immediately after
    ``notes[index+i]``, for ``i < length(length_list)``.

    New subruns are wrapped with lists.
    These wrapper lists are designed
    to allow inspection of the structural changes to *notes*
    immediately after the function returns.
    For this reason most calls to this function will be followed
    by ``notes = sequencetools.flatten_sequence(notes)``:

    ::

        >>> for note in notes: note
        ...
        Note("c'4")
        [Note("f'4"), Note("g'4")]
        Note("d'4")
        [Note("e'4"), Note("c'4"), Note("fs'4"), Note("b'4")]
        Note("g'4")
        Note("a'4")
        Note("f'4")
        [Note("bf'4"), Note("fs'4"), Note("af'4")]
        Note("b'4")
        [Note("g'4")]
        Note("e'4")

    This function is designed to work on a built-in Python list
    of notes. This function is **not** designed to work on Abjad
    voices, staves or other containers because the function currently
    implements no spanner-handling.
    That is, this function is designed to be used during
    precomposition when other, similar abstract pitch transforms
    may be common.

    Returns list of integers and / or floats.
    '''
    from abjad.tools import notetools
    from abjad.tools import pitchtools

    assert isinstance(notes, list)
    assert all(isinstance(x, notetools.Note) for x in notes)
    assert isinstance(subrun_indicators, list)

    len_notes = len(notes)
    instructions = []

    for subrun_indicator in subrun_indicators:
        pairs = _make_index_length_pairs(subrun_indicator)
        for anchor_index, subrun_length in pairs:
            anchor_note = notes[anchor_index % len_notes]
            anchor_pitch = pitchtools.get_named_pitch_from_pitch_carrier(anchor_note)
            anchor_written_duration = anchor_note.written_duration
            source_start_index = anchor_index + 1
            source_stop_index = source_start_index + subrun_length + 1
            subrun_source = sequencetools.iterate_sequence_cyclically_from_start_to_stop(
                notes, source_start_index, source_stop_index)
            subrun_intervals = _get_intervals_in_subrun(subrun_source)
            new_notes = _make_new_notes(
                anchor_pitch, anchor_written_duration, subrun_intervals)
            instruction = (anchor_index, new_notes)
            instructions.append(instruction)

    for anchor_index, new_notes in reversed(sorted(instructions)):
        notes.insert(anchor_index + 1, new_notes)