def _make_numeric_map_part( self, numerator, prefix, suffix, is_note_filled=True, ): prefix_weight = mathtools.weight(prefix) suffix_weight = mathtools.weight(suffix) middle = numerator - prefix_weight - suffix_weight if numerator < prefix_weight: weights = [numerator] prefix = sequencetools.split_sequence( prefix, weights, cyclic=False, overhang=False)[0] middle = self._make_middle_of_numeric_map_part(middle) suffix_space = numerator - prefix_weight if suffix_space <= 0: suffix = () elif suffix_space < suffix_weight: weights = [suffix_space] suffix = sequencetools.split_sequence( suffix, weights, cyclic=False, overhang=False, )[0] numeric_map_part = prefix + middle + suffix return [durationtools.Duration(x) for x in numeric_map_part]
def _make_numeric_map_part( self, numerator, prefix, suffix, is_note_filled=True, ): prefix_weight = mathtools.weight(prefix) suffix_weight = mathtools.weight(suffix) middle = numerator - prefix_weight - suffix_weight if numerator < prefix_weight: weights = [numerator] prefix = sequencetools.split_sequence(prefix, weights, cyclic=False, overhang=False)[0] middle = self._make_middle_of_numeric_map_part(middle) suffix_space = numerator - prefix_weight if suffix_space <= 0: suffix = () elif suffix_space < suffix_weight: weights = [suffix_space] suffix = sequencetools.split_sequence( suffix, weights, cyclic=False, overhang=False, )[0] numeric_map_part = prefix + middle + suffix return [durationtools.Duration(x) for x in numeric_map_part]
def split(self, weights, cyclic=False, overhang=False): r'''Splits sequence by `weights`. .. todo:: Port remaining examples from ``sequencetools.split_sequence()``. .. container:: example **Example 1.** Splits sequence cyclically by weights with overhang: :: >>> sequence_ = Sequence((10, -10, 10, -10)) >>> sequence_.split( ... (3, 15, 3), ... cyclic=True, ... overhang=True, ... ) Sequence((Sequence((3,)), Sequence((7, -8)), Sequence((-2, 1)), Sequence((3,)), Sequence((6, -9)), Sequence((-1,)))) Returns new sequence. ''' from abjad.tools import sequencetools parts = sequencetools.split_sequence( self.items, weights, cyclic=cyclic, overhang=overhang, ) parts = [type(self)(_) for _ in parts] return type(self)(parts)
def _make_secondary_divisions( self, divisions, split_divisions_by_counts, ): if not split_divisions_by_counts: return divisions[:] numerators = [ division.numerator for division in divisions ] secondary_numerators = sequencetools.split_sequence( numerators, split_divisions_by_counts, cyclic=True, overhang=True, ) secondary_numerators = \ sequencetools.flatten_sequence(secondary_numerators) denominator = divisions[0].denominator secondary_divisions = [ (n, denominator) for n in secondary_numerators ] return secondary_divisions
def split_at_offset(self, offset): from abjad.tools import timespantools offset = durationtools.Offset(offset) result = timespantools.TimespanInventory() if self._start_offset < offset < self._stop_offset: left_divisions, right_divisions = None, None if self.divisions is not None: left_divisions, right_divisions = sequencetools.split_sequence( self.divisions, [offset - self.start_offset], overhang=True, ) left = new( self, start_offset=self._start_offset, stop_offset=offset, divisions=left_divisions, ) right = new( self, start_offset=offset, stop_offset=self._stop_offset, divisions=right_divisions, ) if left.duration: result.append(left) if right.duration: result.append(right) else: result.append(new(self)) return result
def _split_payload_at_offsets(self, offsets): from experimental.tools import musicexpressiontools divisions = self.payload.divisions self._payload = musicexpressiontools.DivisionList( [], voice_name=self.voice_name, start_offset=self.start_offset) shards = sequencetools.split_sequence( divisions, offsets, cyclic=False, overhang=True) result, total_duration = [], durationtools.Duration(0) for shard in shards: shard = musicexpressiontools.DivisionList( shard, voice_name=self.voice_name, start_offset=total_duration) result.append(shard) total_duration += shard.duration return result
def _split_payload_at_offsets(self, offsets): from experimental.tools import musicexpressiontools divisions = self.payload.divisions self._payload = musicexpressiontools.DivisionList( [], voice_name=self.voice_name, start_offset=self.start_offset) shards = sequencetools.split_sequence(divisions, offsets, cyclic=False, overhang=True) result, total_duration = [], durationtools.Duration(0) for shard in shards: shard = musicexpressiontools.DivisionList( shard, voice_name=self.voice_name, start_offset=total_duration) result.append(shard) total_duration += shard.duration return result
def _fracture_right(self, i): self, left, right = ComplexBeam._fracture_right(self, i) weights = [ inspect_(left).get_duration(), inspect_(right).get_duration(), ] assert sum(self.durations) == sum(weights) split_durations = sequencetools.split_sequence( self.durations, weights, cyclic=False, overhang=False, ) left_durations, right_durations = split_durations left._durations = left_durations right._durations = right_durations return self, left, right
def _make_secondary_divisions( self, divisions, split_divisions_by_counts, ): if not split_divisions_by_counts: return divisions[:] numerators = [division.numerator for division in divisions] secondary_numerators = sequencetools.split_sequence( numerators, split_divisions_by_counts, cyclic=True, overhang=True, ) secondary_numerators = \ sequencetools.flatten_sequence(secondary_numerators) denominator = divisions[0].denominator secondary_divisions = [(n, denominator) for n in secondary_numerators] return secondary_divisions
def partition_sequence_by_weights( sequence, weights, cyclic=False, overhang=False, allow_part_weights=Exact, ): r'''Partitions `sequence` by `weights` exactly. :: >>> sequence = [3, 3, 3, 3, 4, 4, 4, 4, 5] .. container:: example **Example 1.** Partition sequence once by weights exactly without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [3, 9], ... cyclic=False, ... overhang=False, ... ) [[3], [3, 3, 3]] .. container:: example **Example 2.** Partition sequence once by weights exactly with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [3, 9], ... cyclic=False, ... overhang=True, ... ) [[3], [3, 3, 3], [4, 4, 4, 4, 5]] .. container:: example **Example 3.** Partition sequence cyclically by weights exactly without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [12], ... cyclic=True, ... overhang=False, ... ) [[3, 3, 3, 3], [4, 4, 4]] .. container:: example **Example 4.** Partition sequence cyclically by weights exactly with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [12], ... cyclic=True, ... overhang=True, ... ) [[3, 3, 3, 3], [4, 4, 4], [4, 5]] :: >>> sequence = [3, 3, 3, 3, 4, 4, 4, 4, 5, 5] .. container:: example **Example 1.** Partition sequence once by weights at most without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=False, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3]] .. container:: example **Example 2.** Partition sequence once by weights at most with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=True, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3], [4, 4, 4, 4, 5, 5]] .. container:: example **Example 3.** Partition sequence cyclically by weights at most without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 5], ... cyclic=True, ... overhang=False, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3], [4, 4], [4], [4, 5], [5]] .. container:: example **Example 4.** Partition sequence cyclically by weights at most with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 5], ... cyclic=True, ... overhang=True, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3], [4, 4], [4], [4, 5], [5]] :: >>> sequence = [3, 3, 3, 3, 4, 4, 4, 4, 5, 5] .. container:: example **Example 1.** Partition sequence once by weights at least without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=False, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4]] .. container:: example **Example 2.** Partition sequence once by weights at least with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=True, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4], [4, 4, 4, 5, 5]] .. container:: example **Example 3.** Partition sequence cyclically by weights at least without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=True, ... overhang=False, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4], [4, 4, 4], [5]] .. container:: example **Example 4.** Partition sequence cyclically by weights at least with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=True, ... overhang=True, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4], [4, 4, 4], [5], [5]] Returns list sequence objects. ''' from abjad.tools import sequencetools if allow_part_weights == Exact: candidate = sequencetools.split_sequence( sequence, weights, cyclic=cyclic, overhang=overhang, ) flattened_candidate = sequencetools.flatten_sequence(candidate) if flattened_candidate == sequence[:len(flattened_candidate)]: return candidate else: message = 'can not partition exactly.' raise Exception(message) elif allow_part_weights == More: if not cyclic: return _partition_sequence_once_by_weights_at_least( sequence, weights, overhang=overhang) else: return _partition_sequence_cyclically_by_weights_at_least( sequence, weights, overhang=overhang) elif allow_part_weights == Less: if not cyclic: return _partition_sequence_once_by_weights_at_most( sequence, weights, overhang=overhang, ) else: return _partition_sequence_cyclically_by_weights_at_most( sequence, weights, overhang=overhang, ) else: message = 'not an ordinal value constant: {!r}.' message = message.format(allow_part_weights) raise ValueError(message)
def rotate(self, n, fracture_spanners=True): r'''Rotate start-positioned rhythm payload expression. Example 1. Rotate by count: :: >>> payload = [Container("c'8 d'8 e'8 f'8")] >>> expression = \ ... musicexpressiontools.StartPositionedRhythmPayloadExpression( ... payload, Offset(0)) :: >>> result = expression.rotate(-1) :: >>> print(format(expression)) musicexpressiontools.StartPositionedRhythmPayloadExpression( payload=scoretools.Container( "{ d'8 e'8 f'8 } { c'8 }" ), start_offset=durationtools.Offset(0, 1), ) Example 2. Rotate by duration: :: >>> payload = [Container("c'8 d'8 e'8 f'8")] >>> expression = \ ... musicexpressiontools.StartPositionedRhythmPayloadExpression( ... payload, Offset(0)) :: >>> result = expression.rotate(-Duration(3, 16)) :: >>> print(format(expression)) musicexpressiontools.StartPositionedRhythmPayloadExpression( payload=scoretools.Container( "{ d'16 e'8 f'8 } { c'8 d'16 }" ), start_offset=durationtools.Offset(0, 1), ) Operates in place and returns start-positioned rhythm payload expression. ''' from experimental.tools import musicexpressiontools if isinstance(n, int): leaves = datastructuretools.CyclicTuple( self.payload.select_leaves()) if 0 < n: split_offset = leaves[-n]._get_timespan().start_offset elif n == 0: return self else: split_offset = leaves[-(n + 1)]._get_timespan().stop_offset elif isinstance(n, musicexpressiontools.RotationExpression): rotation_expression = n if rotation_expression.level is None: components_at_level = self.payload.select_leaves() else: components_at_level = [] for component in \ iterate(self.payload).by_class(): score_index = component._get_parentage().score_index if len(score_index) == rotation_expression.level: components_at_level.append(component) components_at_level = datastructuretools.CyclicTuple( components_at_level) if isinstance(rotation_expression.index, int): if 0 < rotation_expression.index: split_offset = components_at_level[-rotation_expression. index]._get_timespan( ).start_offset elif n == 0: return self else: split_offset = components_at_level[-( rotation_expression.index + 1)]._get_timespan().stop_offset else: index = durationtools.Duration(rotation_expression.index) if 0 <= index: split_offset = self.payload._get_duration() - index else: split_offset = abs(index) if rotation_expression.fracture_spanners is not None: fracture_spanners = rotation_expression.fracture_spanners else: n = durationtools.Duration(n) if 0 <= n: split_offset = self.payload._get_duration() - n else: split_offset = abs(n) #self._debug(split_offset, 'split offset') try: payload_duration = getattr(self, 'payload') except AttributeError: payload_duration = self.payload._get_duration() if split_offset == payload_duration: return self if fracture_spanners: result = mutate([self.payload]).split( [split_offset], cyclic=False, fracture_spanners=True, tie_split_notes=False, ) left_half, right_half = result[0][0], result[-1][0] payload = scoretools.Container() payload.extend(right_half) payload.extend(left_half) assert inspect_(payload).is_well_formed() self._payload = payload else: result = mutate(self.payload[:]).split( [split_offset], cyclic=False, fracture_spanners=False, tie_split_notes=False, ) left_half, right_half = result[0], result[-1] prototype = (spannertools.DuratedComplexBeam, ) descendants = self.payload._get_descendants() for spanner in descendants.get_spanners(prototype): if left_half[-1] in spanner and right_half[0] in spanner: leaf_right_of_split = right_half[0] split_offset_in_beam = spanner._start_offset_in_me( leaf_right_of_split) left_durations, right_durations = \ sequencetools.split_sequence( spanner.durations, [split_offset_in_beam], cyclic=False, overhang=True, ) new_durations = right_durations + left_durations spanner._durations = new_durations new_payload = right_half + left_half self.payload._music = new_payload for component in new_payload: component._update_later(offsets=True) for spanner in self.payload._get_descendants().get_spanners(): spanner._components.sort( key=lambda x: x._get_parentage().score_index) assert inspect_(self.payload).is_well_formed() return self
def partition_sequence_by_weights( sequence, weights, cyclic=False, overhang=False, allow_part_weights=Exact, ): r'''Partitions `sequence` by `weights` exactly. :: >>> sequence = [3, 3, 3, 3, 4, 4, 4, 4, 5] .. container:: example **Example 1.** Partition sequence once by weights exactly without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [3, 9], ... cyclic=False, ... overhang=False, ... ) [[3], [3, 3, 3]] .. container:: example **Example 2.** Partition sequence once by weights exactly with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [3, 9], ... cyclic=False, ... overhang=True, ... ) [[3], [3, 3, 3], [4, 4, 4, 4, 5]] .. container:: example **Example 3.** Partition sequence cyclically by weights exactly without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [12], ... cyclic=True, ... overhang=False, ... ) [[3, 3, 3, 3], [4, 4, 4]] .. container:: example **Example 4.** Partition sequence cyclically by weights exactly with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [12], ... cyclic=True, ... overhang=True, ... ) [[3, 3, 3, 3], [4, 4, 4], [4, 5]] :: >>> sequence = [3, 3, 3, 3, 4, 4, 4, 4, 5, 5] .. container:: example **Example 1.** Partition sequence once by weights at most without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=False, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3]] .. container:: example **Example 2.** Partition sequence once by weights at most with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=True, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3], [4, 4, 4, 4, 5, 5]] .. container:: example **Example 3.** Partition sequence cyclically by weights at most without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 5], ... cyclic=True, ... overhang=False, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3], [4, 4], [4], [4, 5], [5]] .. container:: example **Example 4.** Partition sequence cyclically by weights at most with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 5], ... cyclic=True, ... overhang=True, ... allow_part_weights=Less, ... ) [[3, 3, 3], [3], [4, 4], [4], [4, 5], [5]] :: >>> sequence = [3, 3, 3, 3, 4, 4, 4, 4, 5, 5] .. container:: example **Example 1.** Partition sequence once by weights at least without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=False, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4]] .. container:: example **Example 2.** Partition sequence once by weights at least with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=False, ... overhang=True, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4], [4, 4, 4, 5, 5]] .. container:: example **Example 3.** Partition sequence cyclically by weights at least without overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=True, ... overhang=False, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4], [4, 4, 4], [5]] .. container:: example **Example 4.** Partition sequence cyclically by weights at least with overhang: :: >>> sequencetools.partition_sequence_by_weights( ... sequence, ... [10, 4], ... cyclic=True, ... overhang=True, ... allow_part_weights=More, ... ) [[3, 3, 3, 3], [4], [4, 4, 4], [5], [5]] Returns list sequence objects. ''' from abjad.tools import sequencetools if allow_part_weights == Exact: candidate = sequencetools.split_sequence( sequence, weights, cyclic=cyclic, overhang=overhang, ) flattened_candidate = sequencetools.flatten_sequence(candidate) if flattened_candidate == sequence[:len(flattened_candidate)]: return candidate else: message = 'can not partition exactly.' raise PartitionError(message) elif allow_part_weights == More: if not cyclic: return _partition_sequence_once_by_weights_at_least( sequence, weights, overhang=overhang) else: return _partition_sequence_cyclically_by_weights_at_least( sequence, weights, overhang=overhang) elif allow_part_weights == Less: if not cyclic: return _partition_sequence_once_by_weights_at_most( sequence, weights, overhang=overhang, ) else: return _partition_sequence_cyclically_by_weights_at_most( sequence, weights, overhang=overhang, ) else: message = 'not an ordinal value constant: {!r}.' message = message.format(allow_part_weights) raise ValueError(message)
count = 12 mask = H([[1, 1, 2], [1, 2], [1, 2, 3]]) mask = sequencetools.repeat_to_weight(mask, measures * len(reflections)) #mask = tools.rout(mask, window) window_period = len(window) window_true_indices = sequencetools.true_indices(window) mask = sequencetools.negate_elements( mask, absolute=True, window_true_indices=indices, window_period=period, ) mask = sequencetools.split_sequence(mask, measures, cyclic=True, overhang=True) mask = sequencetools.flatten_sequence(mask) mask = sequencetools.split_sequence(mask, [count], cyclic=True, overhang=True) mask = sequencetools.flatten_sequence(mask) window = sequencetools.repeat_sequence_to_length(window, count) #mask = tools.rout(mask, window) window_period = len(window) window_true_indices = sequencetools.true_indices(window) mask = sequencetools.negate_elements( mask, absolute=True, indices=window_true_indices, period=window_period, )
def rotate(self, n, fracture_spanners=True): r'''Rotate start-positioned rhythm payload expression. Example 1. Rotate by count: :: >>> payload = [Container("c'8 d'8 e'8 f'8")] >>> expression = \ ... musicexpressiontools.StartPositionedRhythmPayloadExpression( ... payload, Offset(0)) :: >>> result = expression.rotate(-1) :: >>> print(format(expression)) musicexpressiontools.StartPositionedRhythmPayloadExpression( payload=scoretools.Container( "{ d'8 e'8 f'8 } { c'8 }" ), start_offset=durationtools.Offset(0, 1), ) Example 2. Rotate by duration: :: >>> payload = [Container("c'8 d'8 e'8 f'8")] >>> expression = \ ... musicexpressiontools.StartPositionedRhythmPayloadExpression( ... payload, Offset(0)) :: >>> result = expression.rotate(-Duration(3, 16)) :: >>> print(format(expression)) musicexpressiontools.StartPositionedRhythmPayloadExpression( payload=scoretools.Container( "{ d'16 e'8 f'8 } { c'8 d'16 }" ), start_offset=durationtools.Offset(0, 1), ) Operates in place and returns start-positioned rhythm payload expression. ''' from experimental.tools import musicexpressiontools if isinstance(n, int): leaves = datastructuretools.CyclicTuple(self.payload.select_leaves()) if 0 < n: split_offset = leaves[-n]._get_timespan().start_offset elif n == 0: return self else: split_offset = leaves[-(n+1)]._get_timespan().stop_offset elif isinstance(n, musicexpressiontools.RotationExpression): rotation_expression = n if rotation_expression.level is None: components_at_level = self.payload.select_leaves() else: components_at_level = [] for component in \ iterate(self.payload).by_class(): score_index = component._get_parentage().score_index if len(score_index) == rotation_expression.level: components_at_level.append(component) components_at_level = datastructuretools.CyclicTuple(components_at_level) if isinstance(rotation_expression.index, int): if 0 < rotation_expression.index: split_offset = components_at_level[ -rotation_expression.index]._get_timespan().start_offset elif n == 0: return self else: split_offset = components_at_level[ -(rotation_expression.index+1)]._get_timespan().stop_offset else: index = durationtools.Duration(rotation_expression.index) if 0 <= index: split_offset = self.payload._get_duration() - index else: split_offset = abs(index) if rotation_expression.fracture_spanners is not None: fracture_spanners = rotation_expression.fracture_spanners else: n = durationtools.Duration(n) if 0 <= n: split_offset = self.payload._get_duration() - n else: split_offset = abs(n) #self._debug(split_offset, 'split offset') try: payload_duration = getattr(self, 'payload') except AttributeError: payload_duration = self.payload._get_duration() if split_offset == payload_duration: return self if fracture_spanners: result = mutate([self.payload]).split( [split_offset], cyclic=False, fracture_spanners=True, tie_split_notes=False, ) left_half, right_half = result[0][0], result[-1][0] payload = scoretools.Container() payload.extend(right_half) payload.extend(left_half) assert inspect_(payload).is_well_formed() self._payload = payload else: result = mutate(self.payload[:]).split( [split_offset], cyclic=False, fracture_spanners=False, tie_split_notes=False, ) left_half, right_half = result[0], result[-1] prototype = (spannertools.DuratedComplexBeam, ) descendants = self.payload._get_descendants() for spanner in descendants.get_spanners(prototype): if left_half[-1] in spanner and right_half[0] in spanner: leaf_right_of_split = right_half[0] split_offset_in_beam = spanner._start_offset_in_me( leaf_right_of_split) left_durations, right_durations = \ sequencetools.split_sequence( spanner.durations, [split_offset_in_beam], cyclic=False, overhang=True, ) new_durations = right_durations + left_durations spanner._durations = new_durations new_payload = right_half + left_half self.payload._music = new_payload for component in new_payload: component._update_later(offsets=True) for spanner in self.payload._get_descendants().get_spanners(): spanner._components.sort( key=lambda x: x._get_parentage().score_index ) assert inspect_(self.payload).is_well_formed() return self