Example #1
0
    def __contains__(self, argument: int) -> bool:
        r'''Is true when talea contains ``argument``.

        ..  container:: example

            With preamble:

            >>> talea = abjad.rhythmmakertools.Talea(
            ...     counts=[10],
            ...     denominator=16,
            ...     preamble=[1, -1, 1],
            ...     )

            >>> for i in range(1, 23 + 1):
            ...     i, i in talea
            ...
            (1, True)
            (2, True)
            (3, True)
            (4, False)
            (5, False)
            (6, False)
            (7, False)
            (8, False)
            (9, False)
            (10, False)
            (11, False)
            (12, False)
            (13, True)
            (14, False)
            (15, False)
            (16, False)
            (17, False)
            (18, False)
            (19, False)
            (20, False)
            (21, False)
            (22, False)
            (23, True)

        '''
        assert isinstance(argument, int), repr(argument)
        assert 0 < argument, repr(argument)
        if self.preamble:
            preamble = Sequence([abs(_) for _ in self.preamble])
            cumulative = mathtools.cumulative_sums(preamble)[1:]
            if argument in cumulative:
                return True
            preamble_weight = preamble.weight()
        else:
            preamble_weight = 0
        if self.counts is not None:
            counts = [abs(_) for _ in self.counts]
        else:
            counts = []
        cumulative = mathtools.cumulative_sums(counts)[:-1]
        argument -= preamble_weight
        argument %= self.period
        return argument in cumulative
def test_mathtools_cumulative_sums_zero_01():
    r'''Returns list of the cumulative sums of the integer elements in input.
    '''

    assert mathtools.cumulative_sums([1, 2, 3]) == [0, 1, 3, 6]
    assert mathtools.cumulative_sums([10, -9, -8]) == [0, 10, 1, -7]
    assert mathtools.cumulative_sums([0, 0, 0, 5]) == [0, 0, 0, 0, 5]
    assert mathtools.cumulative_sums([-10, 10, -10, 10]) == \
        [0, -10, 0, -10, 0]
Example #3
0
 def __init__(
     self,
     durations=None,
     include_long_duration_notes=False,
     include_long_duration_rests=False,
     isolated_nib_direction=None,
     use_stemlets=False,
     vertical_direction=None,
     ):
     Spanner.__init__(
         self,
         )
     if durations:
         durations = tuple(durationtools.Duration(x) for x in durations)
     self._durations = durations
     self._include_long_duration_notes = bool(include_long_duration_notes)
     self._include_long_duration_rests = bool(include_long_duration_rests)
     assert isolated_nib_direction in (Left, Right, None)
     self._isolated_nib_direction = isolated_nib_direction
     if self._durations is not None:
         self._span_points = mathtools.cumulative_sums(self.durations)[1:]
     else:
         self._span_points = [self._get_duration()]
     self._use_stemlets = bool(use_stemlets)
     assert vertical_direction in (Up, Down, Center, None)
     self._vertical_direction = vertical_direction
Example #4
0
    def partition_by_ratio_of_durations(self, ratio):
        r'''Partition start-positioned payload expression
        by ratio of durations.

        Operates in place and returns newly constructed inventory.
        '''
        from experimental.tools import musicexpressiontools
        element_durations = [
            self._get_duration_of_expr(leaf) for leaf in self.elements
        ]
        integers = self._durations_to_integers(element_durations)
        parts = sequencetools.partition_sequence_by_ratio_of_weights(
            integers, ratio)
        part_lengths = [len(part) for part in parts]
        parts = sequencetools.partition_sequence_by_counts(
            self.elements, part_lengths)
        durations = [self._get_duration_of_list(part) for part in parts]
        payload_parts = self._split_payload_at_offsets(durations)
        start_offsets = mathtools.cumulative_sums(durations)[:-1]
        start_offsets = [
            self.start_offset + start_offset for start_offset in start_offsets
        ]
        payload_expressions = \
            musicexpressiontools.TimespanScopedSingleContextSetExpressionInventory()
        for payload_part, start_offset in zip(payload_parts, start_offsets):
            timespan = timespantools.Timespan(start_offset)
            payload_expression = type(self)(
                [],
                start_offset=timespan.start_offset,
                voice_name=self.voice_name,
            )
            payload_expression._payload = payload_part
            payload_expressions.append(payload_expression)
        return payload_expressions
Example #5
0
    def from_tempo_scaled_durations(class_, durations, tempo=None):
        r'''Convert ``durations``, scaled by ``tempo``
        into a ``QEventSequence``:

        >>> tempo = abjad.MetronomeMark((1, 4), 174)
        >>> durations = [(1, 4), (-3, 16), (1, 16), (-1, 2)]
        >>> sequence = \
        ...     abjad.quantizationtools.QEventSequence.from_tempo_scaled_durations(
        ...     durations, tempo=tempo)

        >>> for q_event in sequence:
        ...     print(format(q_event, 'storage'))
        ...
        abjad.quantizationtools.PitchedQEvent(
            offset=abjad.Offset(0, 1),
            pitches=(
                abjad.NamedPitch("c'"),
                ),
            )
        abjad.quantizationtools.SilentQEvent(
            offset=abjad.Offset(10000, 29),
            )
        abjad.quantizationtools.PitchedQEvent(
            offset=abjad.Offset(17500, 29),
            pitches=(
                abjad.NamedPitch("c'"),
                ),
            )
        abjad.quantizationtools.SilentQEvent(
            offset=abjad.Offset(20000, 29),
            )
        abjad.quantizationtools.TerminalQEvent(
            offset=abjad.Offset(40000, 29),
            )

        Returns ``QEventSequence`` instance.
        '''
        import abjad
        from abjad.tools import quantizationtools
        durations = [abjad.Duration(x) for x in durations]
        assert isinstance(tempo, indicatortools.MetronomeMark)
        durations = [
            x for x in abjad.sequence(durations).sum_by_sign(sign=[-1]) if x
        ]
        durations = [tempo.duration_to_milliseconds(_) for _ in durations]
        offsets = mathtools.cumulative_sums([abs(_) for _ in durations])
        q_events = []
        for pair in zip(offsets, durations):
            offset = abjad.Offset(pair[0])
            duration = pair[1]
            # negative duration indicates silence
            if duration < 0:
                q_event = quantizationtools.SilentQEvent(offset)
            # otherwise use middle C
            else:
                q_event = quantizationtools.PitchedQEvent(offset, [0])
            q_events.append(q_event)
        # insert terminating silence QEvent
        q_events.append(quantizationtools.TerminalQEvent(offsets[-1]))
        return class_(q_events)
 def __call__(self, position):
     position = durationtools.Offset(position)
     if position < 0:
         position = durationtools.Offset(0)
     if 1 < position:
         position = durationtools.Offset(1)
     if position == 0:
         return self.inflections[0]
     elif position == 1:
         return self.inflections[-1]
     ratio_sum = sum(self.ratio)
     positions = [durationtools.Offset(x) / ratio_sum for x in mathtools.cumulative_sums(self.ratio)]
     index = bisect.bisect(positions, position)
     position = float(position)
     x0 = float(positions[index - 1])
     x1 = float(positions[index])
     y0 = float(self.inflections[index - 1])
     y1 = float(self.inflections[index])
     dx = x1 - x0
     dy = y1 - y0
     m = float(dy) / float(dx)
     b = y0 - (m * x0)
     result = (position * m) + b
     result = pitchtools.NumberedInterval(int(result))
     return result
Example #7
0
 def __init__(
     self,
     durations=None,
     include_long_duration_notes=False,
     include_long_duration_rests=False,
     isolated_nib_direction=None,
     use_stemlets=False,
     vertical_direction=None,
     ):
     Spanner.__init__(
         self,
         )
     if durations:
         durations = tuple(durationtools.Duration(x) for x in durations)
     self._durations = durations
     self._include_long_duration_notes = bool(include_long_duration_notes)
     self._include_long_duration_rests = bool(include_long_duration_rests)
     assert isolated_nib_direction in (Left, Right, None)
     self._isolated_nib_direction = isolated_nib_direction
     if self._durations is not None:
         self._span_points = mathtools.cumulative_sums(self.durations)[1:]
     else:
         self._span_points = [self._get_duration()]
     self._use_stemlets = bool(use_stemlets)
     assert vertical_direction in (Up, Down, Center, None)
     self._vertical_direction = vertical_direction
    def partition_by_ratio_of_durations(self, ratio):
        r'''Partition start-positioned payload expression
        by ratio of durations.

        Operates in place and returns newly constructed inventory.
        '''
        from experimental.tools import musicexpressiontools
        element_durations = [
            self._get_duration_of_expr(leaf) for leaf in self.elements]
        integers = self._durations_to_integers(element_durations)
        parts = sequencetools.partition_sequence_by_ratio_of_weights(
            integers, ratio)
        part_lengths = [len(part) for part in parts]
        parts = sequencetools.partition_sequence_by_counts(
            self.elements, part_lengths)
        durations = [self._get_duration_of_list(part) for part in parts]
        payload_parts = self._split_payload_at_offsets(durations)
        start_offsets = mathtools.cumulative_sums(durations)[:-1]
        start_offsets = [
            self.start_offset + start_offset
            for start_offset in start_offsets]
        payload_expressions = \
            musicexpressiontools.TimespanScopedSingleContextSetExpressionInventory()
        for payload_part, start_offset in zip(payload_parts, start_offsets):
            timespan = timespantools.Timespan(start_offset)
            payload_expression = type(self)(
                [],
                start_offset=timespan.start_offset,
                voice_name=self.voice_name,
                )
            payload_expression._payload = payload_part
            payload_expressions.append(payload_expression)
        return payload_expressions
Example #9
0
def join_subsequences(sequence):
    '''Join subsequences in `sequence`.

    ..  container:: example

        **Example 1.** Joins tuples:

        ::

            >>> tuples = [(1, 2, 3), (), (4, 5), (), (6,)]
            >>> sequencetools.join_subsequences(tuples)
            (1, 2, 3, 4, 5, 6)

    ..  container:: example

        **Example 2.** Joins lists:

        ::

            >>> lists = [[1, 2, 3], [], [4, 5], [], [6]]
            >>> sequencetools.join_subsequences(lists)
            [1, 2, 3, 4, 5, 6]

    Returns new object of `sequence` type.
    '''

    if not isinstance(sequence, collections.Sequence):
        message = 'must be sequence: {!r}.'
        message = message.format(sequence)
        raise Exception(message)

    return mathtools.cumulative_sums(sequence, start=None)[-1]
def merge_duration_sequences(*sequences):
    r'''Merge duration `sequences`:

    ::

        >>> sequencetools.merge_duration_sequences([10, 10, 10], [7])
        [7, 3, 10, 10]

    Merge more duration sequences:

    ::

        >>> sequencetools.merge_duration_sequences([10, 10, 10], [10, 10])
        [10, 10, 10]

    The idea is that each sequence element represents a duration.

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

    offset_lists = []
    for sequence in sequences:
        offset_list = mathtools.cumulative_sums(sequence, start=None)
        offset_lists.append(offset_list)

    all_offsets = sequencetools.join_subsequences(offset_lists)
    all_offsets = list(sorted(set(all_offsets)))
    all_offsets.insert(0, 0)
    all_durations = mathtools.difference_series(all_offsets)

    return all_durations
 def __init__(
     self,
     durations: typing.Iterable[Duration] = None,
     include_long_duration_notes: bool = False,
     include_long_duration_rests: bool = False,
     isolated_nib_direction: HorizontalAlignment = None,
     use_stemlets: bool = False,
     vertical_direction: VerticalAlignment = None,
     ) -> None:
     Spanner.__init__(self)
     durations_ = None
     if durations:
         durations_ = tuple(Duration(_) for _ in durations)
     self._durations = durations_
     self._include_long_duration_notes = bool(include_long_duration_notes)
     self._include_long_duration_rests = bool(include_long_duration_rests)
     assert isolated_nib_direction in (Left, Right, None)
     self._isolated_nib_direction = isolated_nib_direction
     if self._durations is not None:
         self._span_points = mathtools.cumulative_sums(self.durations)[1:]
     else:
         self._span_points = [self._get_duration()]
     self._use_stemlets = bool(use_stemlets)
     assert vertical_direction in (Up, Down, Center, None)
     self._vertical_direction = vertical_direction
Example #12
0
def join_subsequences(sequence):
    '''Join subsequences in `sequence`:

    ::

        >>> sequencetools.join_subsequences([(1, 2, 3), (), (4, 5), (), (6,)])
        (1, 2, 3, 4, 5, 6)

    Returns newly constructed object of subsequence type.
    '''

    return mathtools.cumulative_sums(sequence, start=None)[-1]
Example #13
0
def join_subsequences(sequence):
    '''Join subsequences in `sequence`.

    ::

        >>> sequencetools.join_subsequences([(1, 2, 3), (), (4, 5), (), (6,)])
        (1, 2, 3, 4, 5, 6)

    Returns newly constructed object of subsequence type.
    '''

    return mathtools.cumulative_sums(sequence, start=None)[-1]
def cumulative_sums_pairwise(sequence):
    r'''Lists pairwise cumulative sums of `sequence` from ``0``.

    ::

        >>> mathtools.cumulative_sums_pairwise([1, 2, 3, 4, 5, 6])
        [(0, 1), (1, 3), (3, 6), (6, 10), (10, 15), (15, 21)]

    Returns list of pairs.
    '''
    from abjad.tools import mathtools
    from abjad.tools import sequencetools

    return list(sequencetools.iterate_sequence_pairwise_strict(mathtools.cumulative_sums(sequence)))
def cumulative_sums_pairwise(sequence):
    r'''Lists pairwise cumulative sums of `sequence` from ``0``.

    ::

        >>> mathtools.cumulative_sums_pairwise([1, 2, 3, 4, 5, 6])
        [(0, 1), (1, 3), (3, 6), (6, 10), (10, 15), (15, 21)]

    Returns list of pairs.
    '''
    from abjad.tools import mathtools
    from abjad.tools import sequencetools

    sums = mathtools.cumulative_sums(sequence)
    return list(sequencetools.iterate_sequence_nwise(sums))
Example #16
0
    def from_millisecond_durations(cls, milliseconds, fuse_silences=False):
        r'''Convert a sequence of millisecond durations ``durations`` into
        a ``QEventSequence``:

        ::

            >>> durations = [-250, 500, -1000, 1250, -1000]

        ::

            >>> sequence = \
            ...     quantizationtools.QEventSequence.from_millisecond_durations(
            ...     durations)

        ::

            >>> for q_event in sequence:
            ...     print(format(q_event, 'storage'))
            ...
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(0, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(250, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(750, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(1750, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(3000, 1),
                )
            quantizationtools.TerminalQEvent(
                offset=durationtools.Offset(4000, 1),
                )

        Returns ``QEventSequence`` instance.
        '''
        from abjad.tools import quantizationtools
        if fuse_silences:
            durations = [x for x in \
                sequencetools.sum_consecutive_elements_by_sign(
                    milliseconds, sign=[-1]) if x]
        else:
            durations = milliseconds
        offsets = mathtools.cumulative_sums([abs(x) for x in durations])
        q_events = []
        for pair in zip(offsets, durations):
            offset = durationtools.Offset(pair[0])
            duration = pair[1]
            if duration < 0:  # negative duration indicates silence
                q_event = quantizationtools.SilentQEvent(offset)
            else:
                q_event = quantizationtools.PitchedQEvent(offset, [0])
            q_events.append(q_event)
        q_events.append(
            quantizationtools.TerminalQEvent(durationtools.Offset(
                offsets[-1])))
        return cls(q_events)
def partition_sequence_by_ratio_of_weights(sequence, weights):
    '''Partitions `sequence` by ratio of `weights`.

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [1, 1, 1])
        [[1, 1, 1], [1, 1, 1, 1], [1, 1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [1, 1, 1, 1])
        [[1, 1, 1], [1, 1], [1, 1, 1], [1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [2, 2, 3])
        [[1, 1, 1], [1, 1, 1], [1, 1, 1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [3, 2, 2])
        [[1, 1, 1, 1], [1, 1, 1], [1, 1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1])
        [[1, 1, 1, 1, 1, 1, 2, 2], [2, 2, 2, 2]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1, 1])
        [[1, 1, 1, 1, 1, 1], [2, 2, 2], [2, 2, 2]]


    Weights of parts of returned list equal `weights_ratio` proportions
    with some rounding magic.

    Returns list of lists.
    '''
    from abjad.tools import sequencetools

    list_weight = mathtools.weight(sequence)
    weights_parts = mathtools.partition_integer_by_ratio(list_weight, weights)
    cumulative_weights = mathtools.cumulative_sums(weights_parts, start=None)

    result = []
    sublist = []
    result.append(sublist)
    current_cumulative_weight = cumulative_weights.pop(0)
    for n in sequence:
        if not isinstance(n, (int, long, float, fractions.Fraction)):
            message = 'must be number: {!r}.'
            message = message.format(n)
            raise TypeError(message)
        sublist.append(n)
        while current_cumulative_weight <= \
            mathtools.weight(sequencetools.flatten_sequence(result)):
            try:
                current_cumulative_weight = cumulative_weights.pop(0)
                sublist = []
                result.append(sublist)
            except IndexError:
                break

    return result
def partition_integer_by_ratio(n, ratio):
    r'''Partitions positive integer-equivalent `n` by `ratio`.

    ..  container:: example

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, 2])
        [3, 7]

    ..  container:: example

        Partitions positive integer-equivalent `n` by `ratio` with negative
        parts:

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, -2])
        [3, -7]

    ..  container:: example

        Partitions negative integer-equivalent `n` by `ratio`:

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 2])
        [-3, -7]

    ..  container:: example

        Partitions negative integer-equivalent `n` by `ratio` with negative
        parts:

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, -2])
        [-3, 7]

    ..  container:: example

        More examples:

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1])
        [10]

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, 1])
        [5, 5]

        >>> abjad.mathtools.partition_integer_by_ratio(10, [1, -1, -1])
        [3, -4, -3]

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1])
        [-3, -2, -3, -2]

        >>> abjad.mathtools.partition_integer_by_ratio(-10, [1, 1, 1, 1, 1])
        [-2, -2, -2, -2, -2]

    Returns result with weight equal to absolute value of `n`.

    Returns list of integers.
    '''
    from abjad.tools import mathtools
    if not mathtools.is_integer_equivalent_number(n):
        message = 'is not integer-equivalent number: {!r}.'
        message = message.format(n)
        raise TypeError(message)
    ratio = mathtools.Ratio(ratio).numbers
    if not all(mathtools.is_integer_equivalent_number(part) for part in ratio):
        message = 'some parts in {!r} not integer-equivalent numbers.'
        message = message.format(ratio)
        raise TypeError(message)
    result = [0]
    divisions = [
        float(abs(n)) * abs(part) / mathtools.weight(ratio) for part in ratio
    ]
    cumulative_divisions = mathtools.cumulative_sums(divisions, start=None)
    for division in cumulative_divisions:
        rounded_division = int(round(division)) - sum(result)
        if division - round(division) == 0.5:
            rounded_division += 1
        result.append(rounded_division)
    result = result[1:]
    if mathtools.sign(n) == -1:
        result = [-x for x in result]
    ratio_signs = [mathtools.sign(x) for x in ratio]
    result = [pair[0] * pair[1] for pair in zip(ratio_signs, result)]
    return result
    def __call__(
        self,
        durations=None,
        layer=None,
        division_mask_seed=0,
        division_masks=None,
        padding=None,
        seed=None,
        start_offset=None,
        timespan_specifier=None,
        voice_name=None,
        ):
        import consort
        timespans = abjad.TimespanList()
        timespan_specifier = timespan_specifier or \
            consort.TimespanSpecifier()
        seed = seed or 0
        division_mask_seed = division_mask_seed or 0
        durations = [_ for _ in durations if _]
        offsets = mathtools.cumulative_sums(durations, start_offset)
        if not offsets:
            return timespans
        offset_pair_count = len(offsets) - 1
        if offset_pair_count == 1:
            offset_pair_count = 2  # make patterns happy
        iterator = consort.iterate_nwise(offsets)
        for i, offset_pair in enumerate(iterator):
            start_offset, stop_offset = offset_pair
            music_specifier = self[seed % len(self)]
            timespan = consort.PerformedTimespan(
                forbid_fusing=timespan_specifier.forbid_fusing,
                forbid_splitting=timespan_specifier.forbid_splitting,
                layer=layer,
                minimum_duration=timespan_specifier.minimum_duration,
                music_specifier=music_specifier,
                start_offset=start_offset,
                stop_offset=stop_offset,
                voice_name=voice_name,
                )
            if not division_masks:
                timespans.append(timespan)
            else:
                output_mask = division_masks.get_matching_pattern(
                    i, offset_pair_count + 1, rotation=division_mask_seed)
                if output_mask is None:
                    timespans.append(timespan)
                elif isinstance(output_mask, rhythmmakertools.SustainMask):
                    timespans.append(timespan)
                elif isinstance(output_mask, rhythmmakertools.SilenceMask):
                    pass
            division_mask_seed += 1
            if self.application_rate == 'division':
                seed += 1

        if padding:
            silent_timespans = abjad.TimespanList()
            for shard in timespans.partition(True):
                silent_timespan_one = consort.SilentTimespan(
                    layer=layer,
                    start_offset=shard.start_offset - padding,
                    stop_offset=shard.start_offset,
                    voice_name=voice_name,
                    )
                silent_timespans.append(silent_timespan_one)
                silent_timespan_two = consort.SilentTimespan(
                    layer=layer,
                    start_offset=shard.stop_offset,
                    stop_offset=shard.stop_offset + padding,
                    voice_name=voice_name,
                    )
                silent_timespans.append(silent_timespan_two)
            silent_timespans.compute_logical_or()
            for timespan in timespans:
                silent_timespans - timespan
            timespans.extend(silent_timespans)
            timespans.sort()

        return timespans
Example #20
0
 def _span_points(self):
     if self.durations is not None:
         return mathtools.cumulative_sums(self.durations)[1:]
     return []
Example #21
0
    def from_tempo_scaled_durations(cls, durations, tempo=None):
        r'''Convert ``durations``, scaled by ``tempo``
        into a ``QEventSequence``:

        ::

            >>> tempo = Tempo((1, 4), 174)
            >>> durations = [(1, 4), (-3, 16), (1, 16), (-1, 2)]

        ::

            >>> sequence = \
            ...     quantizationtools.QEventSequence.from_tempo_scaled_durations(
            ...     durations, tempo=tempo)

        ::

            >>> for q_event in sequence:
            ...     print format(q_event, 'storage')
            ...
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(0, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(10000, 29),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(17500, 29),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(20000, 29),
                )
            quantizationtools.TerminalQEvent(
                offset=durationtools.Offset(40000, 29),
                )

        Returns ``QEventSequence`` instance.
        '''
        from abjad.tools import quantizationtools
        durations = [durationtools.Duration(x) for x in durations]
        assert isinstance(tempo, indicatortools.Tempo)
        durations = [x for x in
            sequencetools.sum_consecutive_sequence_elements_by_sign(
                durations,
                sign=[-1],
                ) if x]
        durations = [tempo.duration_to_milliseconds(x) for x in durations]
        offsets = mathtools.cumulative_sums(abs(x) for x in durations)
        q_events = []
        for pair in zip(offsets, durations):
            offset = durationtools.Offset(pair[0])
            duration = pair[1]
            if duration < 0: # negative duration indicates silence
                q_event = quantizationtools.SilentQEvent(offset)
            else: # otherwise, use middle-C
                q_event = quantizationtools.PitchedQEvent(offset, [0])
            q_events.append(q_event)
        # insert terminating silence QEvent
        q_events.append(quantizationtools.TerminalQEvent(offsets[-1]))
        return cls(q_events)
Example #22
0
    def __illustrate__(self, denominator=16, range_=None, scale=None):
        r'''Illustrates meter inventory.

        ..  container:: example

            ::

                >>> meter_inventory = metertools.MeterInventory([
                ...     (3, 4), (5, 16), (7, 8),
                ...     ])
                >>> show(meter_inventory, scale=0.5) # doctest: +SKIP

            ..  doctest

                >>> illustration = meter_inventory.__illustrate__()
                >>> print(format(illustration))
                % ...
                <BLANKLINE>
                \version "..."
                \language "english"
                <BLANKLINE>
                \header {
                    tagline = \markup {}
                }
                <BLANKLINE>
                \layout {}
                <BLANKLINE>
                \paper {}
                <BLANKLINE>
                \markup {
                    \column
                        {
                            \combine
                                \combine
                                    \translate
                                        #'(1.0 . 1)
                                        \sans
                                            \fontsize
                                                #-3
                                                \center-align
                                                    \fraction
                                                        3
                                                        4
                                    \translate
                                        #'(49.387... . 1)
                                        \sans
                                            \fontsize
                                                #-3
                                                \center-align
                                                    \fraction
                                                        5
                                                        16
                                \translate
                                    #'(69.548... . 1)
                                    \sans
                                        \fontsize
                                            #-3
                                            \center-align
                                                \fraction
                                                    7
                                                    8
                            \combine
                                \postscript
                                    #"
                                    0.2 setlinewidth
                                    1 0.5 moveto
                                    49.387... 0.5 lineto
                                    stroke
                                    1 1.25 moveto
                                    1 -0.25 lineto
                                    stroke
                                    49.387... 1.25 moveto
                                    49.387... -0.25 lineto
                                    stroke
                                    49.387... 0.5 moveto
                                    69.548... 0.5 lineto
                                    stroke
                                    49.387... 1.25 moveto
                                    49.387... -0.25 lineto
                                    stroke
                                    69.548... 1.25 moveto
                                    69.548... -0.25 lineto
                                    stroke
                                    69.548... 0.5 moveto
                                    126 0.5 lineto
                                    stroke
                                    69.548... 1.25 moveto
                                    69.548... -0.25 lineto
                                    stroke
                                    126 1.25 moveto
                                    126 -0.25 lineto
                                    stroke
                                    "
                                \postscript
                                    #"
                                    1 -2 moveto
                                    0 -6.153... rlineto
                                    stroke
                                    5.032... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    9.064... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    13.096... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    17.129... -2 moveto
                                    0 -4.615... rlineto
                                    stroke
                                    21.161... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    25.193... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    29.225... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    33.258... -2 moveto
                                    0 -4.615... rlineto
                                    stroke
                                    37.290... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    41.322... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    45.354... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    49.387... -2 moveto
                                    0 -6.153... rlineto
                                    stroke
                                    49.387... -2 moveto
                                    0 -10.909... rlineto
                                    stroke
                                    53.419... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    57.451... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    61.483... -2 moveto
                                    0 -7.272... rlineto
                                    stroke
                                    65.516... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    69.548... -2 moveto
                                    0 -10.909... rlineto
                                    stroke
                                    69.548... -2 moveto
                                    0 -5.517... rlineto
                                    stroke
                                    73.580... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    77.612... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    81.645... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    85.677... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    89.709... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    93.741... -2 moveto
                                    0 -4.137... rlineto
                                    stroke
                                    97.774... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    101.806... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    105.838... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    109.870... -2 moveto
                                    0 -4.137... rlineto
                                    stroke
                                    113.903... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    117.935... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    121.967... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    126 -2 moveto
                                    0 -5.517... rlineto
                                    stroke
                                    "
                        }
                    }


        Returns LilyPond file.
        '''
        from abjad.tools import metertools
        durations = [_.duration for _ in self]
        total_duration = sum(durations)
        offsets = mathtools.cumulative_sums(durations, start=0)
        timespan_inventory = timespantools.TimespanInventory()
        for one, two in sequencetools.iterate_sequence_nwise(offsets):
            timespan = timespantools.Timespan(
                start_offset=one,
                stop_offset=two,
                )
            timespan_inventory.append(timespan)

        if range_ is not None:
            minimum, maximum = range_
        else:
            minimum, maximum = 0, total_duration
        minimum = float(durationtools.Offset(minimum))
        maximum = float(durationtools.Offset(maximum))
        if scale is None:
            scale = 1.
        assert 0 < scale
        postscript_scale = 125. / (maximum - minimum)
        postscript_scale *= float(scale)
        postscript_x_offset = (minimum * postscript_scale) - 1
        timespan_markup = timespan_inventory._make_timespan_inventory_markup(
            timespan_inventory,
            postscript_x_offset,
            postscript_scale,
            draw_offsets=False,
            )
        ps = markuptools.Postscript()
        rational_x_offset = durationtools.Offset(0)
        for meter in self:
            kernel_denominator = denominator or meter.denominator
            kernel = metertools.MetricAccentKernel.from_meter(
                meter, kernel_denominator)
            for offset, weight in sorted(kernel.kernel.items()):
                weight = float(weight) * -40
                ps_x_offset = float(rational_x_offset + offset)
                ps_x_offset *= postscript_scale
                ps_x_offset += 1
                ps = ps.moveto(ps_x_offset, -2)
                ps = ps.rlineto(0, weight)
                ps = ps.stroke()
            rational_x_offset += meter.duration
        ps = markuptools.Markup.postscript(ps)
        lines_markup = markuptools.Markup.combine(timespan_markup, ps)
        fraction_markups = []
        for meter, offset in zip(self, offsets):
            numerator, denominator = meter.numerator, meter.denominator
            fraction = markuptools.Markup.fraction(numerator, denominator)
            fraction = fraction.center_align().fontsize(-3).sans()
            x_translation = (float(offset) * postscript_scale)
            x_translation -= postscript_x_offset
            fraction = fraction.translate((x_translation, 1))
            fraction_markups.append(fraction)
        fraction_markup = fraction_markups[0]
        for markup in fraction_markups[1:]:
            fraction_markup = markuptools.Markup.combine(
                fraction_markup, markup)
        markup = markuptools.Markup.column([fraction_markup, lines_markup])
        return markup.__illustrate__()
Example #23
0
    def from_millisecond_durations(cls, milliseconds, fuse_silences=False):
        r'''Convert a sequence of millisecond durations ``durations`` into
        a ``QEventSequence``:

        ::

            >>> durations = [-250, 500, -1000, 1250, -1000]

        ::

            >>> sequence = \
            ...     quantizationtools.QEventSequence.from_millisecond_durations(
            ...     durations)

        ::

            >>> for q_event in sequence:
            ...     print format(q_event, 'storage')
            ...
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(0, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(250, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(750, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(1750, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(3000, 1),
                )
            quantizationtools.TerminalQEvent(
                offset=durationtools.Offset(4000, 1),
                )

        Returns ``QEventSequence`` instance.
        '''
        from abjad.tools import quantizationtools
        if fuse_silences:
            durations = [x for x in \
                sequencetools.sum_consecutive_sequence_elements_by_sign(
                    milliseconds, sign=[-1]) if x]
        else:
            durations = milliseconds
        offsets = mathtools.cumulative_sums([abs(x) for x in durations])
        q_events = []
        for pair in zip(offsets, durations):
            offset = durationtools.Offset(pair[0])
            duration = pair[1]
            if duration < 0: # negative duration indicates silence
                q_event = quantizationtools.SilentQEvent(offset)
            else:
                q_event = quantizationtools.PitchedQEvent(offset, [0])
            q_events.append(q_event)
        q_events.append(quantizationtools.TerminalQEvent(
            durationtools.Offset(offsets[-1])))
        return cls(q_events)
Example #24
0
    def __illustrate__(self, denominator=16, range_=None, scale=None):
        r'''Illustrates meter inventory.

        ..  container:: example

            ::

                >>> meter_inventory = metertools.MeterInventory([
                ...     (3, 4), (5, 16), (7, 8),
                ...     ])
                >>> show(meter_inventory, scale=0.5) # doctest: +SKIP

            ..  doctest

                >>> illustration = meter_inventory.__illustrate__()
                >>> print(format(illustration))
                % ...
                <BLANKLINE>
                \version "..."
                \language "english"
                <BLANKLINE>
                \header {
                    tagline = ##f
                }
                <BLANKLINE>
                \layout {}
                <BLANKLINE>
                \paper {}
                <BLANKLINE>
                \markup {
                    \column
                        {
                            \combine
                                \combine
                                    \translate
                                        #'(1.0 . 1)
                                        \sans
                                            \fontsize
                                                #-3
                                                \center-align
                                                    \fraction
                                                        3
                                                        4
                                    \translate
                                        #'(49.387... . 1)
                                        \sans
                                            \fontsize
                                                #-3
                                                \center-align
                                                    \fraction
                                                        5
                                                        16
                                \translate
                                    #'(69.548... . 1)
                                    \sans
                                        \fontsize
                                            #-3
                                            \center-align
                                                \fraction
                                                    7
                                                    8
                            \combine
                                \postscript
                                    #"
                                    0.2 setlinewidth
                                    1 0.5 moveto
                                    49.387... 0.5 lineto
                                    stroke
                                    1 1.25 moveto
                                    1 -0.25 lineto
                                    stroke
                                    49.387... 1.25 moveto
                                    49.387... -0.25 lineto
                                    stroke
                                    49.387... 0.5 moveto
                                    69.548... 0.5 lineto
                                    stroke
                                    49.387... 1.25 moveto
                                    49.387... -0.25 lineto
                                    stroke
                                    69.548... 1.25 moveto
                                    69.548... -0.25 lineto
                                    stroke
                                    69.548... 0.5 moveto
                                    126 0.5 lineto
                                    stroke
                                    69.548... 1.25 moveto
                                    69.548... -0.25 lineto
                                    stroke
                                    126 1.25 moveto
                                    126 -0.25 lineto
                                    stroke
                                    "
                                \postscript
                                    #"
                                    1 -2 moveto
                                    0 -6.153... rlineto
                                    stroke
                                    5.032... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    9.064... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    13.096... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    17.129... -2 moveto
                                    0 -4.615... rlineto
                                    stroke
                                    21.161... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    25.193... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    29.225... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    33.258... -2 moveto
                                    0 -4.615... rlineto
                                    stroke
                                    37.290... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    41.322... -2 moveto
                                    0 -3.076... rlineto
                                    stroke
                                    45.354... -2 moveto
                                    0 -1.538... rlineto
                                    stroke
                                    49.387... -2 moveto
                                    0 -6.153... rlineto
                                    stroke
                                    49.387... -2 moveto
                                    0 -10.909... rlineto
                                    stroke
                                    53.419... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    57.451... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    61.483... -2 moveto
                                    0 -7.272... rlineto
                                    stroke
                                    65.516... -2 moveto
                                    0 -3.636... rlineto
                                    stroke
                                    69.548... -2 moveto
                                    0 -10.909... rlineto
                                    stroke
                                    69.548... -2 moveto
                                    0 -5.517... rlineto
                                    stroke
                                    73.580... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    77.612... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    81.645... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    85.677... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    89.709... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    93.741... -2 moveto
                                    0 -4.137... rlineto
                                    stroke
                                    97.774... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    101.806... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    105.838... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    109.870... -2 moveto
                                    0 -4.137... rlineto
                                    stroke
                                    113.903... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    117.935... -2 moveto
                                    0 -2.758... rlineto
                                    stroke
                                    121.967... -2 moveto
                                    0 -1.379... rlineto
                                    stroke
                                    126 -2 moveto
                                    0 -5.517... rlineto
                                    stroke
                                    "
                        }
                    }


        Returns LilyPond file.
        '''
        from abjad.tools import metertools
        durations = [_.duration for _ in self]
        total_duration = sum(durations)
        offsets = mathtools.cumulative_sums(durations, start=0)
        timespan_inventory = timespantools.TimespanInventory()
        for one, two in sequencetools.iterate_sequence_nwise(offsets):
            timespan = timespantools.Timespan(
                start_offset=one,
                stop_offset=two,
                )
            timespan_inventory.append(timespan)

        if range_ is not None:
            minimum, maximum = range_
        else:
            minimum, maximum = 0, total_duration
        minimum = float(durationtools.Offset(minimum))
        maximum = float(durationtools.Offset(maximum))
        if scale is None:
            scale = 1.
        assert 0 < scale
        postscript_scale = 125. / (maximum - minimum)
        postscript_scale *= float(scale)
        postscript_x_offset = (minimum * postscript_scale) - 1
        timespan_markup = timespan_inventory._make_timespan_inventory_markup(
            timespan_inventory,
            postscript_x_offset,
            postscript_scale,
            draw_offsets=False,
            )
        ps = markuptools.Postscript()
        rational_x_offset = durationtools.Offset(0)
        for meter in self:
            kernel_denominator = denominator or meter.denominator
            kernel = metertools.MetricAccentKernel.from_meter(
                meter, kernel_denominator)
            for offset, weight in sorted(kernel.kernel.items()):
                weight = float(weight) * -40
                ps_x_offset = float(rational_x_offset + offset)
                ps_x_offset *= postscript_scale
                ps_x_offset += 1
                ps = ps.moveto(ps_x_offset, -2)
                ps = ps.rlineto(0, weight)
                ps = ps.stroke()
            rational_x_offset += meter.duration
        ps = markuptools.Markup.postscript(ps)
        lines_markup = markuptools.Markup.combine(timespan_markup, ps)
        fraction_markups = []
        for meter, offset in zip(self, offsets):
            numerator, denominator = meter.numerator, meter.denominator
            fraction = markuptools.Markup.fraction(numerator, denominator)
            fraction = fraction.center_align().fontsize(-3).sans()
            x_translation = (float(offset) * postscript_scale)
            x_translation -= postscript_x_offset
            fraction = fraction.translate((x_translation, 1))
            fraction_markups.append(fraction)
        fraction_markup = fraction_markups[0]
        for markup in fraction_markups[1:]:
            fraction_markup = markuptools.Markup.combine(
                fraction_markup, markup)
        markup = markuptools.Markup.column([fraction_markup, lines_markup])
        return markup.__illustrate__()
# -*- coding: utf-8 -*-
from abjad.tools import mathtools
#meter_map = archipel.etc.implementation.data.archipel_meter_map_rev_2.copy()
from archipel.etc.implementation.data.archipel_meter_map_rev_2 \
    import archipel_meter_map_rev_2 as meter_map
meter_map = meter_map.copy()
from archipel.etc.implementation.utilities.keep_data import keep_data


measures_per_section = []
for region in sorted(meter_map.keys()):
    for meter_list, tempo in meter_map[region]:
        measures_per_section.append(len(meter_list))

start_measure_indices = mathtools.cumulative_sums(measures_per_section)

cur_section = 0
for region in sorted(meter_map.keys()):
    sections = meter_map[region]
    indices = start_measure_indices[cur_section:cur_section+len(sections)]
    new_sections = []
    for (meters, tempo), index in zip(sections, indices):
        new_sections.append((meters, tempo, index))
    meter_map[region] = new_sections
    cur_section += len(sections)

#keep_data(
#    meter_map, 
#    'archipel_meter_map_rev_4',
#    header_line='from abjad.tools.mathtools import NonreducedFraction',
#    )
def partition_sequence_by_backgrounded_weights(sequence, weights):
    r'''Partition `sequence` by backgrounded `weights`:

    ::

        >>> sequencetools.partition_sequence_by_backgrounded_weights(
        ...     [-5, -15, -10], [20, 10])
        [[-5, -15], [-10]]

    Further examples:

    ::

        >>> sequencetools.partition_sequence_by_backgrounded_weights(
        ...     [-5, -15, -10], [5, 5, 5, 5, 5, 5])
        [[-5], [-15], [], [], [-10], []]

    ::

        >>> sequencetools.partition_sequence_by_backgrounded_weights(
        ...     [-5, -15, -10], [1, 29])
        [[-5], [-15, -10]]

    ::

        >>> sequencetools.partition_sequence_by_backgrounded_weights(
        ...     [-5, -15, -10], [2, 28])
        [[-5], [-15, -10]]

    ::

        >>> sequencetools.partition_sequence_by_backgrounded_weights(
        ...     [-5, -15, -10], [1, 1, 1, 1, 1, 25])
        [[-5], [], [], [], [], [-15, -10]]

    The term `backgrounded` is a short-hand concocted specifically
    for this function; rely on the formal definition to understand
    the function actually does.

    Input constraint: the weight of `sequence` must equal the weight
    of `weights` exactly.

    The signs of the elements in `sequence` are ignored.

    Formal definition: partition `sequence` into `parts` such that
    (1.) the length of `parts` equals the length of `weights`;
    (2.) the elements in `sequence` appear in order in `parts`; and
    (3.) some final condition that is difficult to formalize.

    Notionally what's going on here is that the elements of `weights`
    are acting as a list of successive time intervals into which the
    elements of `sequence` are being fit in accordance with the start
    offset of each `sequence` element.

    The function models the grouping together of successive timespans
    according to which of an underlying sequence of time intervals
    it is in which each time span begins.

    Note that, for any input to this function, the flattened output
    of this function always equals `sequence` exactly.

    Note too that while `partition` is being used here in the sense of
    the other partitioning functions in the API, the distinguishing feature
    is this funciton is its ability to produce empty lists as output.

    Returns list of `sequence` objects.
    '''
    from abjad.tools import sequencetools

    assert all(0 < x for x in weights)
    assert mathtools.weight(sequence) == mathtools.weight(weights)

    start_offsets = \
        mathtools.cumulative_sums([abs(x) for x in sequence])[:-1]
    indicator = zip(start_offsets, sequence)

    result = []
    for interval_start, interval_stop in \
        mathtools.cumulative_sums_pairwise(weights):
        part = []
        for pair in indicator[:]:
            if interval_start <= pair[0] < interval_stop:
                part.append(pair[1])
                indicator.remove(pair)
        result.append(part)

    return result
Example #27
0
def partition_sequence_by_ratio_of_weights(sequence, weights):
    '''Partitions `sequence` by ratio of `weights`.

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [1, 1, 1])
        [[1, 1, 1], [1, 1, 1, 1], [1, 1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [1, 1, 1, 1])
        [[1, 1, 1], [1, 1], [1, 1, 1], [1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [2, 2, 3])
        [[1, 1, 1], [1, 1, 1], [1, 1, 1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1] * 10, [3, 2, 2])
        [[1, 1, 1, 1], [1, 1, 1], [1, 1, 1]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1])
        [[1, 1, 1, 1, 1, 1, 2, 2], [2, 2, 2, 2]]

    ::

        >>> sequencetools.partition_sequence_by_ratio_of_weights(
        ...     [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], [1, 1, 1])
        [[1, 1, 1, 1, 1, 1], [2, 2, 2], [2, 2, 2]]


    Weights of parts of returned list equal `weights_ratio` proportions
    with some rounding magic.

    Returns list of lists.
    '''
    from abjad.tools import sequencetools

    if not isinstance(sequence, collections.Sequence):
        message = 'must be sequence: {!r}.'
        message = message.format(sequence)
        raise Exception(message)

    list_weight = mathtools.weight(sequence)
    weights_parts = mathtools.partition_integer_by_ratio(list_weight, weights)
    cumulative_weights = mathtools.cumulative_sums(weights_parts, start=None)

    result = []
    sublist = []
    result.append(sublist)
    current_cumulative_weight = cumulative_weights.pop(0)
    for n in sequence:
        if not isinstance(n, (int, float, fractions.Fraction)):
            message = 'must be number: {!r}.'
            message = message.format(n)
            raise TypeError(message)
        sublist.append(n)
        while current_cumulative_weight <= \
            mathtools.weight(sequencetools.flatten_sequence(result)):
            try:
                current_cumulative_weight = cumulative_weights.pop(0)
                sublist = []
                result.append(sublist)
            except IndexError:
                break

    return result
def partition_integer_by_ratio(n, ratio):
    r'''Partitions positive integer-equivalent `n` by `ratio`.

    ::

        >>> mathtools.partition_integer_by_ratio(10, [1, 2])
        [3, 7]

    Partitions positive integer-equivalent `n` by `ratio` with negative parts:

    ::

        >>> mathtools.partition_integer_by_ratio(10, [1, -2])
        [3, -7]

    Partitions negative integer-equivalent `n` by `ratio`:

    ::

        >>> mathtools.partition_integer_by_ratio(-10, [1, 2])
        [-3, -7]

    Partitions negative integer-equivalent `n` by `ratio` with negative parts:

    ::

        >>> mathtools.partition_integer_by_ratio(-10, [1, -2])
        [-3, 7]

    Returns result with weight equal to absolute value of `n`.

    Raises type error on noninteger `n`.

    Returns list of integers.
    '''
    from abjad.tools import mathtools

    if not mathtools.is_integer_equivalent_number(n):
        message = 'is not integer-equivalent number: {!r}.'
        message = message.format(n)
        raise TypeError(message)

    ratio = mathtools.Ratio(ratio).numbers

    if not all(
        mathtools.is_integer_equivalent_number(part)
        for part in ratio
        ):
        message = 'some parts in {!r} not integer-equivalent numbers.'
        message = message.format(ratio)
        raise TypeError(message)

    result = [0]

    divisions = [
        float(abs(n)) * abs(part) / mathtools.weight(ratio)
        for part in ratio
        ]
    cumulative_divisions = mathtools.cumulative_sums(divisions, start=None)

    for division in cumulative_divisions:
        rounded_division = int(round(division)) - sum(result)
        #This makes rounding behave like python 2. Would be good to remove
        # in the long run
        if sys.version_info[0] == 3:
            if division - round(division) == 0.5:
                rounded_division += 1
        result.append(rounded_division)

    result = result[1:]

    # adjust signs of output elements
    if mathtools.sign(n) == -1:
        result = [-x for x in result]
    ratio_signs = [mathtools.sign(x) for x in ratio]
    result = [pair[0] * pair[1] for pair in zip(ratio_signs, result)]

    # return result
    return result
Example #29
0
    def from_millisecond_pitch_pairs(cls, pairs):
        r'''Convert millisecond-duration:pitch pairs ``pairs`` into a
        ``QEventSequence``:

        ::

            >>> durations = [250, 500, 1000, 1250, 1000]
            >>> pitches = [(0,), None, (2, 3), None, (1,)]
            >>> pairs = tuple(zip(durations, pitches))

        ::

            >>> sequence = \
            ...     quantizationtools.QEventSequence.from_millisecond_pitch_pairs(
            ...     pairs)

        ::

            >>> for q_event in sequence:
            ...     print(format(q_event, 'storage'))
            ...
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(0, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(250, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(750, 1),
                pitches=(
                    pitchtools.NamedPitch("d'"),
                    pitchtools.NamedPitch("ef'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(1750, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(3000, 1),
                pitches=(
                    pitchtools.NamedPitch("cs'"),
                    ),
                )
            quantizationtools.TerminalQEvent(
                offset=durationtools.Offset(4000, 1),
                )

        Returns ``QEventSequence`` instance.
        '''
        from abjad.tools import quantizationtools
        assert isinstance(pairs, collections.Iterable)
        assert all(isinstance(x, collections.Iterable) for x in pairs)
        assert all(len(x) == 2 for x in pairs)
        assert all(0 < x[0] for x in pairs)
        for pair in pairs:
            assert isinstance(
                pair[1], (numbers.Number, type(None), collections.Iterable))
            if isinstance(pair[1], collections.Iterable):
                assert 0 < len(pair[1])
                assert all(isinstance(x, numbers.Number) for x in pair[1])
        # fuse silences
        g = itertools.groupby(pairs, lambda x: x[1] is not None)
        groups = []
        for value, group in g:
            if value:
                groups.extend(list(group))
            else:
                duration = sum(x[0] for x in group)
                groups.append((duration, None))
        # find offsets
        offsets = mathtools.cumulative_sums([abs(x[0]) for x in groups])
        # build QEvents
        q_events = []
        for pair in zip(offsets, groups):
            offset = durationtools.Offset(pair[0])
            pitches = pair[1][1]
            if isinstance(pitches, collections.Iterable):
                assert all(isinstance(x, numbers.Number) for x in pitches)
                q_events.append(
                    quantizationtools.PitchedQEvent(offset, pitches))
            elif isinstance(pitches, type(None)):
                q_events.append(quantizationtools.SilentQEvent(offset))
            elif isinstance(pitches, numbers.Number):
                q_events.append(
                    quantizationtools.PitchedQEvent(offset, [pitches]))
        q_events.append(
            quantizationtools.TerminalQEvent(durationtools.Offset(
                offsets[-1])))
        return cls(q_events)
Example #30
0
    def from_millisecond_pitch_pairs(cls, pairs):
        r'''Convert millisecond-duration:pitch pairs ``pairs`` into a
        ``QEventSequence``:

        ::

            >>> durations = [250, 500, 1000, 1250, 1000]
            >>> pitches = [(0,), None, (2, 3), None, (1,)]
            >>> pairs = zip(durations, pitches)

        ::

            >>> sequence = \
            ...     quantizationtools.QEventSequence.from_millisecond_pitch_pairs(
            ...     pairs)

        ::

            >>> for q_event in sequence:
            ...     print format(q_event, 'storage')
            ...
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(0, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(250, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(750, 1),
                pitches=(
                    pitchtools.NamedPitch("d'"),
                    pitchtools.NamedPitch("ef'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(1750, 1),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(3000, 1),
                pitches=(
                    pitchtools.NamedPitch("cs'"),
                    ),
                )
            quantizationtools.TerminalQEvent(
                offset=durationtools.Offset(4000, 1),
                )

        Returns ``QEventSequence`` instance.
        '''
        from abjad.tools import quantizationtools
        assert isinstance(pairs, collections.Iterable)
        assert all(isinstance(x, collections.Iterable) for x in pairs)
        assert all(len(x) == 2 for x in pairs)
        assert all(0 < x[0] for x in pairs)
        for pair in pairs:
            assert isinstance(pair[1], (
                numbers.Number, type(None), collections.Iterable))
            if isinstance(pair[1], collections.Iterable):
                assert 0 < len(pair[1])
                assert all(isinstance(x, numbers.Number) for x in pair[1])
        # fuse silences
        g = itertools.groupby(pairs, lambda x: x[1] is not None)
        groups = []
        for value, group in g:
            if value:
                groups.extend(list(group))
            else:
                duration = sum(x[0] for x in group)
                groups.append((duration, None))
        # find offsets
        offsets = mathtools.cumulative_sums([abs(x[0]) for x in groups])
        # build QEvents
        q_events = []
        for pair in zip(offsets, groups):
            offset = durationtools.Offset(pair[0])
            pitches = pair[1][1]
            if isinstance(pitches, collections.Iterable):
                assert all(isinstance(x, numbers.Number) for x in pitches)
                q_events.append(quantizationtools.PitchedQEvent(offset, pitches))
            elif isinstance(pitches, type(None)):
                q_events.append(quantizationtools.SilentQEvent(offset))
            elif isinstance(pitches, numbers.Number):
                q_events.append(quantizationtools.PitchedQEvent(offset, [pitches]))
        q_events.append(quantizationtools.TerminalQEvent(
            durationtools.Offset(offsets[-1])))
        return cls(q_events)
Example #31
0
    def from_tempo_scaled_durations(cls, durations, tempo=None):
        r'''Convert ``durations``, scaled by ``tempo``
        into a ``QEventSequence``:

        ::

            >>> tempo = Tempo((1, 4), 174)
            >>> durations = [(1, 4), (-3, 16), (1, 16), (-1, 2)]

        ::

            >>> sequence = \
            ...     quantizationtools.QEventSequence.from_tempo_scaled_durations(
            ...     durations, tempo=tempo)

        ::

            >>> for q_event in sequence:
            ...     print(format(q_event, 'storage'))
            ...
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(0, 1),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(10000, 29),
                )
            quantizationtools.PitchedQEvent(
                offset=durationtools.Offset(17500, 29),
                pitches=(
                    pitchtools.NamedPitch("c'"),
                    ),
                )
            quantizationtools.SilentQEvent(
                offset=durationtools.Offset(20000, 29),
                )
            quantizationtools.TerminalQEvent(
                offset=durationtools.Offset(40000, 29),
                )

        Returns ``QEventSequence`` instance.
        '''
        from abjad.tools import quantizationtools
        durations = [durationtools.Duration(x) for x in durations]
        assert isinstance(tempo, indicatortools.Tempo)
        durations = [
            x for x in sequencetools.sum_consecutive_elements_by_sign(
                durations,
                sign=[-1],
            ) if x
        ]
        durations = [tempo.duration_to_milliseconds(x) for x in durations]
        offsets = mathtools.cumulative_sums(abs(x) for x in durations)
        q_events = []
        for pair in zip(offsets, durations):
            offset = durationtools.Offset(pair[0])
            duration = pair[1]
            if duration < 0:  # negative duration indicates silence
                q_event = quantizationtools.SilentQEvent(offset)
            else:  # otherwise, use middle-C
                q_event = quantizationtools.PitchedQEvent(offset, [0])
            q_events.append(q_event)
        # insert terminating silence QEvent
        q_events.append(quantizationtools.TerminalQEvent(offsets[-1]))
        return cls(q_events)
Example #32
0
def partition_integer_by_ratio(n, ratio):
    r'''Partitions positive integer-equivalent `n` by `ratio`.

    ::

        >>> mathtools.partition_integer_by_ratio(10, [1, 2])
        [3, 7]

    Partitions positive integer-equivalent `n` by `ratio` with negative parts:

    ::

        >>> mathtools.partition_integer_by_ratio(10, [1, -2])
        [3, -7]

    Partitions negative integer-equivalent `n` by `ratio`:

    ::

        >>> mathtools.partition_integer_by_ratio(-10, [1, 2])
        [-3, -7]

    Partitions negative integer-equivalent `n` by `ratio` with negative parts:

    ::

        >>> mathtools.partition_integer_by_ratio(-10, [1, -2])
        [-3, 7]

    Returns result with weight equal to absolute value of `n`.

    Raises type error on noninteger `n`.

    Returns list of integers.
    '''
    from abjad.tools import mathtools

    if not mathtools.is_integer_equivalent_number(n):
        message = 'is not integer-equivalent number: {!r}.'
        message = message.format(n)
        raise TypeError(message)

    ratio = mathtools.Ratio(ratio).numbers

    if not all(mathtools.is_integer_equivalent_number(part) for part in ratio):
        message = 'some parts in {!r} not integer-equivalent numbers.'
        message = message.format(ratio)
        raise TypeError(message)

    result = [0]

    divisions = [
        float(abs(n)) * abs(part) / mathtools.weight(ratio) for part in ratio
    ]
    cumulative_divisions = mathtools.cumulative_sums(divisions, start=None)

    for division in cumulative_divisions:
        rounded_division = int(round(division)) - sum(result)
        #This makes rounding behave like python 2. Would be good to remove
        # in the long run
        if sys.version_info[0] == 3:
            if division - round(division) == 0.5:
                rounded_division += 1
        result.append(rounded_division)

    result = result[1:]

    # adjust signs of output elements
    if mathtools.sign(n) == -1:
        result = [-x for x in result]
    ratio_signs = [mathtools.sign(x) for x in ratio]
    result = [pair[0] * pair[1] for pair in zip(ratio_signs, result)]

    # return result
    return result