def _partition_by_rgf(sequence, rgf): """ Partitions ``sequence`` by restricted growth function ``rgf``. >>> sequence = abjad.sequence(range(10)) >>> rgf = [1, 1, 2, 2, 1, 2, 3, 3, 2, 4] >>> abjad.Enumerator._partition_by_rgf(sequence, rgf) Sequence([Sequence([0, 1, 4]), Sequence([2, 3, 5, 8]), Sequence([6, 7]), Sequence([9])]) Returns list of lists. """ import abjad rgf = abjad.sequence(items=rgf) if not Enumerator._is_restricted_growth_function(rgf): message = "must be restricted growth function: {!r}." message = message.format(rgf) raise ValueError(message) if not len(sequence) == len(rgf): message = "lengths must be equal." raise ValueError(message) partition = [] for part_index in range(max(rgf)): part = [] partition.append(part) for n, part_number in zip(sequence, rgf): part_index = part_number - 1 part = partition[part_index] part.append(n) partition = [abjad.sequence(_) for _ in partition] return abjad.sequence(items=partition)
def __call__(self, pitches, durations): """ Calls note-maker on ``pitches`` and ``durations``. Returns selection. """ import abjad if isinstance(pitches, str): pitches = pitches.split() if not isinstance(pitches, collections.Iterable): pitches = [pitches] if isinstance(durations, (numbers.Number, tuple)): durations = [durations] nonreduced_fractions = [abjad.NonreducedFraction(_) for _ in durations] size = max(len(nonreduced_fractions), len(pitches)) nonreduced_fractions = abjad.sequence(nonreduced_fractions) nonreduced_fractions = nonreduced_fractions.repeat_to_length(size) pitches = abjad.sequence(pitches).repeat_to_length(size) Duration = abjad.Duration durations = Duration._group_by_implied_prolation(nonreduced_fractions) result = [] for duration in durations: # get factors in denominator of duration group duration not 1 or 2 factors = set(abjad.mathtools.factors(duration[0].denominator)) factors.discard(1) factors.discard(2) ps = pitches[0:len(duration)] pitches = pitches[len(duration):] if len(factors) == 0: result.extend( self._make_unprolated_notes( ps, duration, decrease_monotonic=self.decrease_monotonic, repeat_ties=self.repeat_ties, )) else: # compute prolation denominator = duration[0].denominator numerator = abjad.mathtools.greatest_power_of_two_less_equal( denominator) multiplier = (numerator, denominator) ratio = 1 / abjad.Fraction(*multiplier) duration = [ratio * abjad.Duration(d) for d in duration] ns = self._make_unprolated_notes( ps, duration, decrease_monotonic=self.decrease_monotonic, repeat_ties=self.repeat_ties, ) tuplet = abjad.Tuplet(multiplier, ns) result.append(tuplet) result = abjad.select(result) return result
def yield_partitions(self): """ Yields partitions of sequence. .. container:: example >>> enumerator = abjad.Enumerator([0, 1, 2]) >>> for partition in enumerator.yield_partitions(): ... partition ... Sequence([Sequence([0, 1, 2])]) Sequence([Sequence([0, 1]), Sequence([2])]) Sequence([Sequence([0]), Sequence([1, 2])]) Sequence([Sequence([0]), Sequence([1]), Sequence([2])]) .. container:: example >>> enumerator = abjad.Enumerator([0, 1, 2, 3]) >>> for partition in enumerator.yield_partitions(): ... partition ... Sequence([Sequence([0, 1, 2, 3])]) Sequence([Sequence([0, 1, 2]), Sequence([3])]) Sequence([Sequence([0, 1]), Sequence([2, 3])]) Sequence([Sequence([0, 1]), Sequence([2]), Sequence([3])]) Sequence([Sequence([0]), Sequence([1, 2, 3])]) Sequence([Sequence([0]), Sequence([1, 2]), Sequence([3])]) Sequence([Sequence([0]), Sequence([1]), Sequence([2, 3])]) Sequence([Sequence([0]), Sequence([1]), Sequence([2]), Sequence([3])]) Returns generator of nested sequences. """ import abjad length = len(self.sequence) - 1 for i in range(2**length): binary_string = abjad.mathtools.integer_to_binary_string(i) binary_string = binary_string.zfill(length) part = list(self.sequence[0:1]) partition = [part] for n, token in zip(self.sequence[1:], binary_string): if int(token) == 0: part.append(n) else: part = [n] partition.append(part) parts = [abjad.sequence(items=_) for _ in partition] partition = abjad.sequence(items=parts) yield partition
def yield_partitions(self): """ Yields partitions of sequence. .. container:: example >>> enumerator = abjad.Enumerator([0, 1, 2]) >>> for partition in enumerator.yield_partitions(): ... partition ... Sequence([Sequence([0, 1, 2])]) Sequence([Sequence([0, 1]), Sequence([2])]) Sequence([Sequence([0]), Sequence([1, 2])]) Sequence([Sequence([0]), Sequence([1]), Sequence([2])]) .. container:: example >>> enumerator = abjad.Enumerator([0, 1, 2, 3]) >>> for partition in enumerator.yield_partitions(): ... partition ... Sequence([Sequence([0, 1, 2, 3])]) Sequence([Sequence([0, 1, 2]), Sequence([3])]) Sequence([Sequence([0, 1]), Sequence([2, 3])]) Sequence([Sequence([0, 1]), Sequence([2]), Sequence([3])]) Sequence([Sequence([0]), Sequence([1, 2, 3])]) Sequence([Sequence([0]), Sequence([1, 2]), Sequence([3])]) Sequence([Sequence([0]), Sequence([1]), Sequence([2, 3])]) Sequence([Sequence([0]), Sequence([1]), Sequence([2]), Sequence([3])]) Returns generator of nested sequences. """ import abjad length = len(self.sequence) - 1 for i in range(2 ** length): binary_string = abjad.mathtools.integer_to_binary_string(i) binary_string = binary_string.zfill(length) part = list(self.sequence[0:1]) partition = [part] for n, token in zip(self.sequence[1:], binary_string): if int(token) == 0: part.append(n) else: part = [n] partition.append(part) parts = [abjad.sequence(items=_) for _ in partition] partition = abjad.sequence(items=parts) yield partition
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, container, imbrication_token): r'''Calls imbrication specifier on `container`. Returns new container. ''' container = copy.deepcopy(container) imbrication_token = abjad.sequence(imbrication_token) imbrication_token = imbrication_token.flatten() cursor = baca.tools.Cursor( imbrication_token, singletons=True, suppress_exception=True, ) pitch_number = cursor.next() logical_ties = abjad.iterate(container).by_logical_tie(pitched=True) for logical_tie in logical_ties: if logical_tie.head.written_pitch.pitch_number == pitch_number: pitch_number = cursor.next() if self.truncate_ties: for note in logical_tie[1:]: duration = note.written_duration skip = abjad.Skip(duration) abjad.mutate(note).replace([skip]) else: for note in logical_tie: duration = note.written_duration skip = abjad.Skip(duration) abjad.mutate(note).replace([skip]) self._apply_specifiers(container) return container
def test_scoretools_Mutation_replace_measure_contents_06(): r'''Preserves ties. ''' maker = abjad.NoteMaker() durations = [(5, 16), (3, 16)] leaf_lists = maker([0], durations) leaves = abjad.sequence(leaf_lists).flatten(depth=-1) maker = abjad.MeasureMaker() measures = maker(durations) staff = abjad.Staff(measures) measures = abjad.mutate(staff).replace_measure_contents(leaves) assert format(staff) == abjad.String.normalize(r''' \new Staff { { % measure \time 5/16 c'4 ~ c'16 } % measure { % measure \time 3/16 c'8. } % measure } ''') assert abjad.inspect(staff).is_well_formed()
def _shift_downbeat_q_events_to_next_q_grid(self): beats = self.beats for one, two in abjad.sequence(beats).nwise(): one_q_events = one.q_grid.next_downbeat.q_event_proxies two_q_events = two.q_grid.leaves[0].q_event_proxies while one_q_events: two_q_events.append(one_q_events.pop())
def yield_permutations(self): """ Yields permutations of sequence. .. container:: example >>> enumerator = abjad.Enumerator([1, 2, 3]) >>> for permutation in enumerator.yield_permutations(): ... permutation ... Sequence([1, 2, 3]) Sequence([1, 3, 2]) Sequence([2, 1, 3]) Sequence([2, 3, 1]) Sequence([3, 1, 2]) Sequence([3, 2, 1]) Returns sequence generator. """ import abjad length = len(self.sequence) for permutation in itertools.permutations(tuple(range(length))): permutation = abjad.sequence(items=permutation) yield self.sequence.permute(permutation)
def from_millisecond_durations(class_, milliseconds, fuse_silences=False): r""" Convert a sequence of millisecond durations ``durations`` into a ``QEventSequence``: >>> durations = [-250, 500, -1000, 1250, -1000] >>> sequence = \ ... abjadext.nauert.QEventSequence.from_millisecond_durations( ... durations) >>> for q_event in sequence: ... print(format(q_event, 'storage')) ... abjadext.nauert.SilentQEvent( offset=abjad.Offset((0, 1)), ) abjadext.nauert.PitchedQEvent( offset=abjad.Offset((250, 1)), pitches=( abjad.NamedPitch("c'"), ), ) abjadext.nauert.SilentQEvent( offset=abjad.Offset((750, 1)), ) abjadext.nauert.PitchedQEvent( offset=abjad.Offset((1750, 1)), pitches=( abjad.NamedPitch("c'"), ), ) abjadext.nauert.SilentQEvent( offset=abjad.Offset((3000, 1)), ) abjadext.nauert.TerminalQEvent( offset=abjad.Offset((4000, 1)), ) Returns ``QEventSequence`` instance. """ if fuse_silences: durations = [ x for x in abjad.sequence(milliseconds).sum_by_sign(sign=[-1]) if x ] else: durations = milliseconds offsets = abjad.mathx.cumulative_sums([abs(x) for x 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 = SilentQEvent(offset) else: q_event = PitchedQEvent(offset, [0]) q_events.append(q_event) q_events.append(TerminalQEvent(abjad.Offset(offsets[-1]))) return class_(q_events)
def __call__(self): r'''Calls time signature maker. Returns measures per stage, tempo map and time signatures. ''' time_signatures = abjad.sequence(self.time_signatures) time_signatures = time_signatures.rotate(self.rotation) time_signatures = time_signatures.flatten(depth=1) items = [] for item in self.stage_specifier: if isinstance(item, abjad.indicatortools.Fermata): item = abjad.indicatortools.TimeSignature((1, 4)) items.append(item) stage_specifier = baca.tools.StageSpecifier(items=items) time_signature_groups = self._make_time_signature_groups( self.repeat_count, stage_specifier, time_signatures, ) measures_per_stage = [len(_) for _ in time_signature_groups] time_signatures = abjad.sequencetools.flatten_sequence( time_signature_groups, depth=1, ) fermata_entries = self.stage_specifier.make_fermata_entries() items = self.tempo_specifier.items + fermata_entries tempo_specifier = baca.tools.TempoSpecifier(items=items) return measures_per_stage, tempo_specifier, time_signatures
def _find_divisible_leaf_indices_and_subdivisions(self, q_grid): # TODO: This should actually check for all QEvents which fall # within the leaf's duration, # including QEvents attached to the next leaf # It may be prudent to actually store QEvents in two lists: # before_offset and after_offset import abjad indices, subdivisions = [], [] leaves = list(q_grid.leaves) i = 0 for leaf_one, leaf_two in abjad.sequence(leaves).nwise(): if leaf_one.is_divisible: succeeding_proxies = leaf_one.succeeding_q_event_proxies preceding_proxies = leaf_two.preceding_q_event_proxies if not preceding_proxies and \ all(proxy.offset == leaf_one.start_offset for proxy in succeeding_proxies): pass # proxies align perfectly with this leaf elif preceding_proxies or succeeding_proxies: parentage_ratios = leaf_one.parentage_ratios leaf_subdivisions = \ self._find_leaf_subdivisions(parentage_ratios) if leaf_subdivisions: indices.append(i) subdivisions.append(tuple(leaf_subdivisions)) i += 1 return indices, subdivisions
def attach_glissandi(nucleus_voice): selections = [[]] leaves = abjad.iterate(nucleus_voice).leaves() for leaf_index, leaf in enumerate(leaves): if 641 <= leaf_index: leaf_index += 2 string = letter_maker.nuclei[leaf_index] if string == 0: glissando = False else: result = letter_maker.get_body_pitch_shape_glissando(string) pitch, shape, glissando = result if glissando: assert isinstance(leaf, abjad.Note), repr(leaf) selections[-1].append(leaf) elif not selections[-1] == []: selections.append([]) if selections[-1] == []: selections.pop() selections = [abjad.select(_) for _ in selections] for selection in selections: next_leaf = abjad.inspect(selection[-1]).leaf(1) if next_leaf is not None: selection = selection + [next_leaf] abjad.glissando(selection, allow_repeats=True) triples = abjad.sequence(selection).nwise(n=3) for left_note, middle_note, right_note in triples: if not (left_note.written_pitch == middle_note.written_pitch == right_note.written_pitch): continue abjad.override(middle_note).note_head.transparent = True grob_proxy = abjad.override(middle_note).glissando grob_proxy.bound_details__left__padding = -1.2
def named_interval_class_segment(self): r'''Gets named interval class segment. .. container:: example >>> scale = abjad.tonalanalysistools.Scale(('c', 'minor')) >>> str(scale.named_interval_class_segment) '<+M2, +m2, +M2, +M2, +m2, +M2, +M2>' >>> scale = abjad.tonalanalysistools.Scale(('d', 'dorian')) >>> str(scale.named_interval_class_segment) '<+M2, +m2, +M2, +M2, +M2, +m2, +M2>' Returns interval-class segment. ''' import abjad dics = [] for left, right in abjad.sequence(self).nwise(wrapped=True): dic = left - right dics.append(dic) dicg = abjad.IntervalClassSegment( items=dics, item_class=abjad.NamedInversionEquivalentIntervalClass, ) return dicg
def __call__(self): r'''Calls time signature maker. Returns mesaures per stage, tempo map and time signatures. ''' import akasha if self.series == 'A': time_signatures = akasha.materials.time_signatures_a elif self.series == 'B': time_signatures = akasha.materials.time_signatures_b else: message = 'unknown time signature series: {!r}.' message = message.format(series) raise Exception(message) time_signatures = abjad.sequence(time_signatures) time_signatures = time_signatures.rotate(self.rotation) time_signatures = time_signatures.flatten() items = [] for item in self.stage_specifier: if isinstance(item, Fermata): item = TimeSignature((1, 4)) items.append(item) stage_specifier = baca.tools.StageSpecifier(items=items) preprocessor = baca.tools.TimeSignaturePreprocessor( repeat_count=self.repeat_count, stage_specifier=stage_specifier, time_signatures=time_signatures, ) time_signature_groups = preprocessor() measures_per_stage = [len(_) for _ in time_signature_groups] time_signatures = abjad.sequencetools.flatten_sequence(time_signature_groups) fermata_entries = self.stage_specifier.make_fermata_entries() items = self.tempo_specifier.items + fermata_entries tempo_specifier = baca.tools.TempoSpecifier(items=items) return measures_per_stage, tempo_specifier, time_signatures
def __call__(self, sequence_): r'''Calls LMR specifier on `sequence_`. Returns list of subsequences. ''' top_lengths = self._get_top_lengths(len(sequence_)) top_parts = abjad.sequence(sequence_).partition_by_counts( top_lengths, cyclic=False, overhang=Exact, ) parts = [] left_part, middle_part, right_part = top_parts if left_part: if self.left_counts: parts_ = abjad.sequence(left_part).partition_by_counts( self.left_counts, cyclic=self.left_cyclic, overhang=True, reversed_=self.left_reversed, ) parts.extend(parts_) else: parts.append(left_part) if middle_part: if self.middle_counts: parts_ = abjad.sequence(middle_part).partition_by_counts( self.middle_counts, cyclic=self.middle_cyclic, overhang=True, reversed_=self.middle_reversed, ) parts.extend(parts_) else: parts.append(middle_part) if right_part: if self.right_counts: parts_ = abjad.sequence(right_part).partition_by_counts( self.right_counts, cyclic=self.right_cyclic, overhang=True, reversed_=self.right_reversed, ) parts.extend(parts_) else: parts.append(right_part) return parts
def yield_pairs(self): """ Yields pairs sequence items. .. container:: example Without duplicate items: >>> enumerator = abjad.Enumerator([1, 2, 3, 4]) >>> for pair in enumerator.yield_pairs(): ... pair ... Sequence([1, 2]) Sequence([1, 3]) Sequence([1, 4]) Sequence([2, 3]) Sequence([2, 4]) Sequence([3, 4]) .. container:: example With duplicate items: >>> enumerator = abjad.Enumerator([1, 1, 1]) >>> for pair in enumerator.yield_pairs(): ... pair ... Sequence([1, 1]) Sequence([1, 1]) Sequence([1, 1]) .. container:: example Length-1 sequence: >>> enumerator = abjad.Enumerator([1]) >>> for pair in enumerator.yield_pairs(): ... pair ... .. container:: example Empty sequence: >>> enumerator = abjad.Enumerator([]) >>> for pair in enumerator.yield_pairs(): ... pair ... Returns generator of length-2 sequences. """ import abjad for i, item in enumerate(self.sequence): start = i + 1 for item_ in self.sequence[start:]: pair = [item, item_] yield abjad.sequence(items=pair)
def _initialize_with_mode_name(self, mode_name): import abjad mdi_segment = [] m2 = pitchtools.NamedInterval('m2') M2 = pitchtools.NamedInterval('M2') A2 = pitchtools.NamedInterval('aug2') dorian = [M2, m2, M2, M2, M2, m2, M2] if mode_name == 'dorian': mdi_segment.extend(abjad.sequence(dorian).rotate(n=0)) elif mode_name == 'phrygian': mdi_segment.extend(abjad.sequence(dorian).rotate(n=-1)) elif mode_name == 'lydian': mdi_segment.extend(abjad.sequence(dorian).rotate(n=-2)) elif mode_name == 'mixolydian': mdi_segment.extend(abjad.sequence(dorian).rotate(n=-3)) elif mode_name in ('aeolian', 'minor', 'natural minor'): mdi_segment.extend(abjad.sequence(dorian).rotate(n=-4)) elif mode_name == 'locrian': mdi_segment.extend(abjad.sequence(dorian).rotate(n=-5)) elif mode_name in ('ionian', 'major'): mdi_segment.extend(abjad.sequence(dorian).rotate(n=-6)) elif mode_name == 'melodic minor': mdi_segment.extend([M2, m2, M2, M2, M2, M2, m2]) elif mode_name == 'harmonic minor': mdi_segment.extend([M2, m2, M2, M2, m2, A2, m2]) else: message = 'unknown mode name: {!r}.' message = message.format(mode_name) raise ValueError(message) return pitchtools.IntervalSegment( items=mdi_segment, item_class=pitchtools.NamedInterval, )
def __init__(self, items=None, item_class=None): import abjad if isinstance(items, abjad.PitchSegment): intervals = [] for one, two in abjad.sequence(items).nwise(): intervals.append(one - two) items = intervals Segment.__init__(self, items=items, item_class=item_class)
def test_Mutation_split_05(): """ Cyclically splits orphan measures. """ measures = [ abjad.Container("c'8 d'8"), abjad.Container("e'8 f'8"), ] leaves = abjad.select(measures).leaves() abjad.beam(leaves[:2]) abjad.beam(leaves[-2:]) result = abjad.mutate(measures).split( [abjad.Duration(3, 32)], cyclic=True, tie_split_notes=False, ) components = abjad.sequence(result).flatten(depth=-1) staff = abjad.Staff(components) assert format(staff) == abjad.String.normalize(r""" \new Staff { { c'16. [ } { c'32 d'16 } { d'16 ] } { e'32 [ } { e'16. } { f'16. } { f'32 ] } } """), print(format(staff)) assert abjad.inspect(staff).wellformed() assert len(result) == 6
def is_link_chord(ais): for sextuple in abjad.sequence(ais).nwise(n=6): pc_set = abjad.PitchClassSet(sextuple) try: set_class = abjad.SetClass.from_pitch_class_set(pc_set) if set_class.rank == 17: return True except KeyError as e: print(e) return False
def __call__(self, argument): """ Calls retrograde on `argument`. .. container:: example Gets retrograde pitch classes: >>> retrograde = abjad.Retrograde() >>> segment = abjad.PitchClassSegment([0, 1, 4, 7]) >>> retrograde(segment) PitchClassSegment([7, 4, 1, 0]) .. container:: example Does not retrograde single pitches or pitch-classes: >>> retrogresion = abjad.Retrograde() >>> pitch_class = abjad.NumberedPitchClass(6) >>> retrograde(pitch_class) NumberedPitchClass(6) .. container:: example Periodic retrograde: .. todo:: Deprecated. >>> retrograde = abjad.Retrograde(period=3) >>> segment = abjad.PitchSegment("c' d' e' f' g' a' b' c''") >>> retrograde(segment) PitchSegment("e' d' c' a' g' f' c'' b'") Returns new object with type equal to that of `argument`. """ import abjad if isinstance(argument, (abjad.Pitch, abjad.PitchClass)): return argument if not isinstance(argument, ( abjad.PitchSegment, abjad.PitchClassSegment, )): argument = abjad.PitchSegment(argument) if not self.period: return type(argument)(reversed(argument)) result = abjad.new(argument, items=()) for shard in abjad.sequence(argument).partition_by_counts( [self.period], cyclic=True, overhang=True, ): shard = type(argument)(shard) shard = type(argument)(reversed(shard)) result = result + shard return result
def graph_order(self): r'''Graph order of tree node. Returns tuple. ''' import abjad order = [] components = abjad.sequence(reversed(self.improper_parentage)) for parent, child in components.nwise(): order.append(parent.index(child)) return tuple(order)
def _make_secondary_divisions( self, divisions, split_divisions_by_counts, ): import abjad if not split_divisions_by_counts: return divisions[:] numerators = [division.numerator for division in divisions] secondary_numerators = abjad.sequence(numerators) secondary_numerators = secondary_numerators.split( split_divisions_by_counts, cyclic=True, overhang=True, ) secondary_numerators = abjad.sequence(secondary_numerators) secondary_numerators = secondary_numerators.flatten(depth=-1) denominator = divisions[0].denominator secondary_divisions = [(n, denominator) for n in secondary_numerators] return secondary_divisions
def test_Mutation_split_05(): """ Cyclically splits orphan measures. """ measures = [abjad.Container("c'8 d'8"), abjad.Container("e'8 f'8")] leaves = abjad.select(measures).leaves() abjad.beam(leaves[:2]) abjad.beam(leaves[-2:]) result = abjad.mutate(measures).split( [abjad.Duration(3, 32)], cyclic=True, tie_split_notes=False ) components = abjad.sequence(result).flatten(depth=-1) staff = abjad.Staff(components) assert format(staff) == abjad.String.normalize( r""" \new Staff { { c'16. [ } { c'32 d'16 } { d'16 ] } { e'32 [ } { e'16. } { f'16. } { f'32 ] } } """ ), print(format(staff)) assert abjad.inspect(staff).wellformed() assert len(result) == 6
def prolations(self): r'''Prolations of rhythm tree node. Returns tuple. ''' import abjad prolations = [abjad.Multiplier(1)] improper_parentage = self.improper_parentage pairs = abjad.sequence(improper_parentage).nwise() for child, parent in pairs: prolations.append(abjad.Multiplier( parent.preprolated_duration, parent._get_contents_duration())) return tuple(prolations)
def _populate_pitches(self, voice, pitch_range): import abjad assert isinstance(pitch_range, abjad.PitchRange) pitch_numbers = [ _ for _ in self._test_pitch_numbers if _ in pitch_range ] pitch_numbers = abjad.sequence(pitch_numbers).remove_repeats() pitch_numbers = abjad.CyclicTuple(pitch_numbers) logical_ties = abjad.iterate(voice).logical_ties(pitched=True) for i, logical_tie in enumerate(logical_ties): pitch_number = pitch_numbers[i] for note in logical_tie: note.written_pitch = pitch_number
def _invert_chord_quality(intervals, inversion): import abjad if isinstance(inversion, int): intervals = abjad.sequence(intervals).rotate(n=-inversion) rotation = -inversion elif inversion == 'root': rotation = 0 elif inversion == 'first': intervals = abjad.sequence(intervals).rotate(n=-1) rotation = -1 elif inversion == 'second': intervals = abjad.sequence(intervals).rotate(n=-2) rotation = -2 elif inversion == 'third': intervals = abjad.sequence(intervals).rotate(n=-3) rotation = -3 elif inversion == 'fourth': intervals = abjad.sequence(intervals).rotate(n=-4) rotation = -4 else: message = 'unknown chord inversion: {!r}.' raise ValueError(message.format(inversion)) return intervals, rotation
def make_perforated_counts(degree=0, rotation=None): r'''Makes perforated counts. :: >>> import akasha .. container:: example **Example 1.** Makes perforated counts: :: >>> akasha.tools.make_perforated_counts(degree=0) Sequence([-4, 1, 1, 1, 1, 1, 1, 1, 1, -4, 1, 1, 1, 1, -8, 1, 1, 1, 1, 1, 1, 1, 1, -8, 1, 1, 1, 1, -4, 1, 1, 1, 1, 1, 1, 1, 1]) :: >>> akasha.tools.make_perforated_counts(degree=1) Sequence([1, 1, 1, -9, 1, 1, -7, 1, -9, 1, 1, 1, -2]) Returns sequence. ''' counts = [] if degree == 0: pattern_1 = abjad.patterntools.select_every([0, 1, 2, 3], period=12) pattern_2 = abjad.patterntools.select_every([0, 1, 2, 3], period=20) pattern = pattern_1 | pattern_2 pattern = ~pattern elif degree == 1: pattern = abjad.patterntools.select_every( [0, 1, 2, 12, 13, 21, 31, 32, 33], period=36, ) else: message = 'degree must be between 0 and 1: {!r}.' message = message.format(degree) raise ValueError(message) vector = pattern.get_boolean_vector() parts = abjad.sequencetools.partition_sequence_by_value_of_elements(vector) for part in parts: if part[0] == 0: counts.append(-len(part)) elif part[0] == 1: counts.extend(part) else: raise ValueError(part) return abjad.sequence(counts).rotate(n=rotation)
def cumulative_sums_pairwise(argument): r'''Gets pairwise cumulative sums of `argument` from zero. .. container:: example >>> abjad.mathtools.cumulative_sums_pairwise([1, 2, 3, 4, 5, 6]) [(0, 1), (1, 3), (3, 6), (6, 10), (10, 15), (15, 21)] Returns pairs in new object of `argument` type. ''' import abjad sums = abjad.mathtools.cumulative_sums(argument) pairs = abjad.sequence(sums).nwise() return type(argument)([tuple(_) for _ in pairs])
def _notate( self, attach_tempos=True, attack_point_optimizer=None, grace_handler=None, ): voice = abjad.Voice() # generate the first q_target_measure = self.items[0] time_signature = q_target_measure.time_signature measure = abjad.Container() for beat in q_target_measure.beats: measure.extend(beat.q_grid(beat.beatspan)) leaf = abjad.get.leaf(measure, 0) abjad.attach(time_signature, leaf) if attach_tempos: tempo = copy.deepcopy(q_target_measure.tempo) leaf = abjad.get.leaf(measure, 0) abjad.attach(tempo, leaf) voice.append(measure) # generate the rest pairwise, comparing tempi pairs = abjad.sequence(self.items).nwise() for q_target_measure_one, q_target_measure_two in pairs: measure = abjad.Container() for beat in q_target_measure_two.beats: measure.extend(beat.q_grid(beat.beatspan)) if (q_target_measure_two.time_signature != q_target_measure_one.time_signature): time_signature = q_target_measure_two.time_signature leaf = abjad.get.leaf(measure, 0) abjad.attach(time_signature, leaf) if (q_target_measure_two.tempo != q_target_measure_one.tempo) and attach_tempos: tempo = copy.deepcopy(q_target_measure_two.tempo) # abjad.attach(tempo, measure) leaf = abjad.get.leaf(measure, 0) abjad.attach(tempo, leaf) voice.append(measure) # apply logical ties, pitches, grace containers self._notate_leaves(grace_handler=grace_handler, voice=voice) # partition logical ties in each measure for measure in voice: attack_point_optimizer(measure) return voice
def check_duplicate_ids(self, argument=None): r'''Checks duplicate IDs. Returns violators and total. ''' import abjad violators = [] components = abjad.iterate(argument).components() total_ids = [id(_) for _ in components] unique_ids = abjad.sequence(total_ids).remove_repeats() if len(unique_ids) < len(total_ids): for current_id in unique_ids: if 1 < total_ids.count(current_id): violators.extend( [_ for _ in components if id(_) == current_id]) return violators, len(total_ids)
def are_scalar_notes(self): r'''Is true when notes in client are scalar. Otherwise false .. container:: example >>> staff = abjad.Staff("c'4 cs'") >>> abjad.analyze(staff[:]).are_scalar_notes() True >>> staff = abjad.Staff("c'4 d'") >>> abjad.analyze(staff[:]).are_scalar_notes() True >>> staff = abjad.Staff("c'4 ds'") >>> abjad.analyze(staff[:]).are_scalar_notes() True >>> staff = abjad.Staff("c'4 b") >>> abjad.analyze(staff[:]).are_scalar_notes() True .. container:: example >>> staff = abjad.Staff("c'4 c'") >>> abjad.analyze(staff[:]).are_scalar_notes() False >>> staff = abjad.Staff("c'4 e'") >>> abjad.analyze(staff[:]).are_scalar_notes() False Returns true or false. ''' import abjad direction_string = None notes = abjad.iterate(self._client).components(abjad.Note) for left, right in abjad.sequence(notes).nwise(): try: assert not (left.written_pitch == right.written_pitch) mdi = pitchtools.NamedInterval.from_pitch_carriers(left, right) assert mdi.number <= 2 if direction_string is None: direction_string = mdi.direction_string assert direction_string == mdi.direction_string except AssertionError: return False return True
def _burnish_each_division(class_, input_, divisions): import abjad left_classes = input_['left_classes'] middle_classes = input_['middle_classes'] right_classes = input_['right_classes'] left_counts = input_['left_counts'] left_counts = left_counts or abjad.CyclicTuple([0]) right_counts = input_['right_counts'] right_counts = right_counts or abjad.CyclicTuple([0]) lefts_index, rights_index = 0, 0 burnished_divisions = [] for division_index, division in enumerate(divisions): left_count = left_counts[division_index] left = left_classes[lefts_index:lefts_index + left_count] lefts_index += left_count right_count = right_counts[division_index] right = right_classes[rights_index:rights_index + right_count] rights_index += right_count available_left_count = len(division) left_count = min([left_count, available_left_count]) available_right_count = len(division) - left_count right_count = min([right_count, available_right_count]) middle_count = len(division) - left_count - right_count left = left[:left_count] if middle_classes: middle = middle_count * [middle_classes[division_index]] else: middle = middle_count * [0] right = right[:right_count] result = abjad.sequence(division).partition_by_counts( [left_count, middle_count, right_count], cyclic=False, overhang=False, ) left_part, middle_part, right_part = result left_part = class_._burnish_division_part(left_part, left) middle_part = class_._burnish_division_part(middle_part, middle) right_part = class_._burnish_division_part(right_part, right) burnished_division = left_part + middle_part + right_part burnished_divisions.append(burnished_division) unburnished_weights = [abjad.mathtools.weight(x) for x in divisions] burnished_weights = [ abjad.mathtools.weight(x) for x in burnished_divisions ] assert burnished_weights == unburnished_weights return burnished_divisions
def prolations(self): """ Prolations of rhythm tree node. Returns tuple. """ import abjad prolations = [abjad.Multiplier(1)] pairs = abjad.sequence(self.parentage).nwise() for child, parent in pairs: prolations.append( abjad.Multiplier( parent.preprolated_duration, parent._get_contents_duration(), )) return tuple(prolations)
def _tie_across_divisions_(self, divisions): import abjad if not self.tie_across_divisions: return if self.strip_ties: return if self.tie_consecutive_notes: return length = len(divisions) tie_across_divisions = self.tie_across_divisions if isinstance(tie_across_divisions, bool): tie_across_divisions = [tie_across_divisions] if not isinstance(tie_across_divisions, abjad.Pattern): tie_across_divisions = abjad.Pattern.from_vector( tie_across_divisions) pairs = abjad.sequence(divisions).nwise() rest_prototype = (abjad.Rest, abjad.MultimeasureRest) for i, pair in enumerate(pairs): if not tie_across_divisions.matches_index(i, length): continue division_one, division_two = pair leaf_one = next(abjad.iterate(division_one).leaves(reverse=True)) leaf_two = next(abjad.iterate(division_two).leaves()) leaves = [leaf_one, leaf_two] if isinstance(leaf_one, rest_prototype): continue if isinstance(leaf_two, rest_prototype): continue pitched_prototype = (abjad.Note, abjad.Chord) if not all(isinstance(_, pitched_prototype) for _ in leaves): continue logical_tie_one = abjad.inspect(leaf_one).get_logical_tie() logical_tie_two = abjad.inspect(leaf_two).get_logical_tie() if logical_tie_one == logical_tie_two: continue combined_logical_tie = logical_tie_one + logical_tie_two for leaf in combined_logical_tie: abjad.detach(abjad.Tie, leaf) tie = abjad.Tie(repeat=self.repeat_ties) tie._unconstrain_contiguity() if tie._attachment_test_all(combined_logical_tie) is True: try: abjad.attach(tie, combined_logical_tie) except: raise Exception(tie, combined_logical_tie) tie._constrain_contiguity()
def _fracture_right(self, i): import abjad self, left, right = ComplexBeam._fracture_right(self, i) weights = [ abjad.inspect(left).get_duration(), abjad.inspect(right).get_duration(), ] assert sum(self.durations) == sum(weights) split_durations = abjad.sequence(self.durations) split_durations = split_durations.split( 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_spanner_score_09(self): r'''Make 200-note voice with (vanilla) beam spanner on every 100 notes. 2.12 (r9724) initialization: 249,339 function calls 2.12 (r9703) LilyPond format: 121,497 function calls 2.12 (r9724) LilyPond format: 128,494 function calls ''' import abjad voice = abjad.Voice(200 * abjad.Note("c'16")) for part in abjad.sequence(voice[:]).partition_by_counts( [100], cyclic=True, ): beam = abjad.Beam() abjad.attach(beam, part) return voice
def prolations(self): """ Prolations of rhythm tree node. Returns tuple. """ import abjad prolations = [abjad.Multiplier(1)] pairs = abjad.sequence(self.parentage).nwise() for child, parent in pairs: prolations.append( abjad.Multiplier( parent.preprolated_duration, parent._get_contents_duration(), ) ) return tuple(prolations)
def make_polyphony_rhythm_specifier(rotation=0): counts = abjad.sequence([4, 14, 4, 6, 18]) counts = counts.rotate(n=rotation) return baca.tools.RhythmSpecifier( rewrite_meter=True, rhythm_maker=abjad.rhythmmakertools.TaleaRhythmMaker( talea=abjad.rhythmmakertools.Talea( counts=counts, denominator=16, ), tie_specifier=abjad.rhythmmakertools.TieSpecifier( use_messiaen_style_ties=True, ), tuplet_spelling_specifier=abjad.rhythmmakertools.TupletSpellingSpecifier( simplify_redundant_tuplets=True, ), ), )
def partition(self, cursor, number, counts, operators=None): r'''Partitions next `number` cells in `cursor` by `counts`. Appies optional `operators` to resulting parts of partition. Returns none. ''' cells = cursor.next(number) list_ = [] for cell in cells: list_.extend(cell) segment = abjad.pitchtools.PitchClassSegment(list_) operators = operators or [] for operator in operators: segment = self._apply_operator(segment, operator) sequence_ = abjad.sequence(segment) parts = sequence_.partition_by_counts(counts, overhang=True) parts = [abjad.pitchtools.PitchClassSegment(_) for _ in parts] self._result.extend(parts)
def register(self, pitch_classes): """ Registers `pitch_classes` by pitch set. .. container:: example >>> pitch_set = abjad.PitchSet( ... items=[10, 19, 20, 23, 24, 26, 27, 29, 30, 33, 37, 40], ... item_class=abjad.NumberedPitch, ... ) >>> pitch_classes = [10, 0, 2, 6, 8, 7, 5, 3, 1, 9, 4, 11] >>> pitches = pitch_set.register(pitch_classes) >>> for pitch in pitches: ... pitch NumberedPitch(10) NumberedPitch(24) NumberedPitch(26) NumberedPitch(30) NumberedPitch(20) NumberedPitch(19) NumberedPitch(29) NumberedPitch(27) NumberedPitch(37) NumberedPitch(33) NumberedPitch(40) NumberedPitch(23) Returns list of zero or more numbered pitches. """ import abjad if isinstance(pitch_classes, collections.abc.Iterable): result = [ [_ for _ in self if _.number % 12 == pc] for pc in [x % 12 for x in pitch_classes] ] result = abjad.sequence(result).flatten(depth=-1) elif isinstance(pitch_classes, int): result = [p for p in pitch_classes if p % 12 == pitch_classes][0] else: message = "must be pitch-class or list of pitch-classes." raise TypeError(message) return result
def make_score_with_indicators_01(self): """ Make 200-note voice with dynamic on every 20th note: 2.12 (r9704) initialization: 630,433 function calls 2.12 (r9710) initialization: 235,120 function calls 2.12 r(9726) initialization: 235,126 function calls 2.12 (r9704) LilyPond format: 136,637 function calls 2.12 (r9710) LilyPond format: 82,730 function calls 2.12 (r9726) LilyPond format: 88,382 function calls """ import abjad staff = abjad.Staff(200 * abjad.Note("c'16")) for part in abjad.sequence(staff[:]).partition_by_counts( [20], cyclic=True ): dynamic = abjad.Dynamic("f") abjad.attach(dynamic, part[0]) return staff
def make_score_with_indicators_02(self): """ Make 200-note staff with dynamic on every 4th note. 2.12 (r9704) initialization: 4,632,761 function calls 2.12 (r9710) initialization: 327,280 function calls 2.12 (r9726) initialization: 325,371 function calls 2.12 (r9704) LilyPond format: 220,277 function calls 2.12 (r9710) LilyPond format: 84,530 function calls 2.12 (r9726) LilyPond format: 90,056 function calls """ import abjad staff = abjad.Staff(200 * abjad.Note("c'16")) for part in abjad.sequence(staff[:]).partition_by_counts( [4], cyclic=True ): dynamic = abjad.Dynamic("f") abjad.attach(dynamic, part[0]) return staff
def make_key_region_indices(): """ Makes key region indices. >>> import cary .. container:: example Key region start indices: >>> ranges = cary.make_key_region_indices() >>> start_indices = [0] >>> for range_ in ranges: ... start_index = start_indices[-1] + len(range_) ... start_indices.append(start_index) >>> start_indices [0, 118, 254, 384, 487, 640, 760] .. container:: example Key region lengths: >>> indices = cary.make_key_region_indices() >>> [len(_) for _ in indices] [118, 136, 130, 103, 153, 120] """ start_indices = [0, 118, 254, 384, 487, 640, 760] ranges = [] pairs = abjad.sequence(start_indices).nwise() for pair in pairs: range_ = range(*pair) ranges.append(range_) assert len(ranges) == 6 assert [len(_) for _ in ranges] == [118, 136, 130, 103, 153, 120] return ranges
def __call__(self, argument): """ Calls rotation on `argument`. .. container:: example Rotates pitch classes: >>> rotation = abjad.Rotation(n=1) >>> pitch_classes = abjad.PitchClassSegment([0, 1, 4, 7]) >>> rotation(pitch_classes) PitchClassSegment([7, 0, 1, 4]) .. container:: example Rotates pitch classes with Stravinsky-style back-transposition to zero: >>> rotation = abjad.Rotation(n=1, stravinsky=True) >>> pitch_classes = abjad.PitchClassSegment([0, 1, 4, 7]) >>> rotation(pitch_classes) PitchClassSegment([0, 5, 6, 9]) .. container:: example Does not rotate single pitches or pitch-classes: >>> rotation = abjad.Rotation(n=1) >>> pitch_class = abjad.NumberedPitchClass(6) >>> rotation(pitch_class) NumberedPitchClass(6) .. container:: example Periodic rotation: .. todo:: Deprecated. >>> rotation = abjad.Rotation(n=1, period=3) >>> pitches = abjad.PitchSegment("c' d' e' f' g' a' b' c''") >>> rotation(pitches) PitchSegment("e' c' d' a' f' g' c'' b'") .. container:: example Stravinsky-style periodic rotation: .. todo:: Deprecated. >>> rotation = abjad.Rotation( ... n=1, ... period=3, ... stravinsky=True, ... ) >>> pitches = abjad.PitchSegment("c' d' e' f' g' a' b' c''") >>> rotation(pitches) PitchSegment("c' af bf f' df' ef' b' as'") Returns new object with type equal to that of `argument`. """ import abjad if isinstance(argument, (abjad.Pitch, abjad.PitchClass)): return argument if not isinstance( argument, (abjad.PitchSegment, abjad.PitchClassSegment) ): argument = abjad.PitchSegment(argument) if not self.period: return argument.rotate(self.n, stravinsky=self.stravinsky) result = abjad.new(argument, items=()) for shard in abjad.sequence(argument).partition_by_counts( [self.period], cyclic=True, overhang=True ): shard = type(argument)(shard) shard = shard.rotate(self.n, stravinsky=self.stravinsky) result = result + shard return result
if literal.argument in (r'\break', r'\pageBreak'): measure_number = first_measure_number + i bol_measure_numbers.append(measure_number) continue bols = bol_measure_numbers count = len(bols) numbers = abjad.String('number').pluralize(count) if count <= 4: items = ', '.join([str(_) for _ in bols]) print( f' Writing BOL measure {{numbers}} {{items}} to metadata ...') else: print(f' Writing BOL measure {{numbers}} to metadata ...') parts = abjad.sequence(bols).partition_by_counts( [12], cyclic=True, overhang=True, ) for part in parts: items = ', '.join(str(_) for _ in part) print(f' {{items}} ...') buildspace_directory.add_buildspace_metadatum( 'bol_measure_numbers', bol_measure_numbers, document_name=document_name, ) except: traceback.print_exc() sys.exit(1) sys.exit(0)
def rotate(self, n=0, stravinsky=False): r""" Rotates pitch segment by index `n`. .. container:: example >>> segment = abjad.PitchSegment([-2, -1.5, 6, 7, -1.5, 7]) >>> abjad.show(segment) # doctest: +SKIP .. docs:: >>> lilypond_file = segment.__illustrate__() >>> abjad.f(lilypond_file[abjad.StaffGroup]) \new PianoStaff << \context Staff = "Treble_Staff" { \clef "treble" r1 * 1/8 r1 * 1/8 fs'1 * 1/8 g'1 * 1/8 r1 * 1/8 g'1 * 1/8 } \context Staff = "Bass_Staff" { \clef "bass" bf1 * 1/8 bqf1 * 1/8 r1 * 1/8 r1 * 1/8 bqf1 * 1/8 r1 * 1/8 } >> >>> segment = segment.rotate(n=1) >>> str(segment) '<7, -2, -1.5, 6, 7, -1.5>' >>> abjad.show(segment) # doctest: +SKIP .. docs:: >>> lilypond_file = segment.__illustrate__() >>> abjad.f(lilypond_file[abjad.StaffGroup]) \new PianoStaff << \context Staff = "Treble_Staff" { \clef "treble" g'1 * 1/8 r1 * 1/8 r1 * 1/8 fs'1 * 1/8 g'1 * 1/8 r1 * 1/8 } \context Staff = "Bass_Staff" { \clef "bass" r1 * 1/8 bf1 * 1/8 bqf1 * 1/8 r1 * 1/8 r1 * 1/8 bqf1 * 1/8 } >> Returns new pitch segment. """ import abjad rotated_pitches = abjad.sequence(self._collection).rotate(n=n) new_segment = abjad.new(self, items=rotated_pitches) if stravinsky: if self[0] != new_segment[0]: interval = new_segment[0] - self[0] new_segment = new_segment.transpose(interval) return new_segment
def _apply_spanners(self, leaves): import abjad spanner_references = { abjad.Beam: None, abjad.Slur: None, } first_leaf = leaves[0] pairs = abjad.sequence(leaves).nwise(wrapped=True) for leaf, next_leaf in pairs: span_events = self._get_span_events(leaf) for current_class, directions in span_events.items(): starting, stopping = [], [] for direction in directions: if direction is Left: starting.append(Left) else: stopping.append(Right) # apply undirected events immediately, # and do not maintain a reference to them if current_class is abjad.Tie: if next_leaf is first_leaf: message = 'unterminated {} at {}.' message = message.format(current_class.__name__, leaf) raise Exception(message) previous_tie = [ x for x in leaf._get_spanners() if isinstance(x, abjad.Tie) ] if previous_tie: previous_tie[0]._append(next_leaf) else: tie = abjad.Tie() selection = abjad.select([leaf, next_leaf]) attach(tie, selection) elif current_class is abjad.Beam: # A beam may begin and end on the same leaf # but only one beam spanner may cover any given leaf, # and starting events are processed before ending ones for _ in starting: if spanner_references[current_class] is not None: message = 'already have beam.' raise Exception(message) else: spanner_references[current_class] = current_class() for _ in stopping: if spanner_references[current_class] is not None: spanner_references[current_class]._append(leaf) spanner_references[current_class] = None elif current_class is spannertools.Slur: # Slurs process stop events before start events, # they must contain more than one leaf, # but they can stop on a leaf and start on the same leaf. for _ in stopping: if spanner_references[current_class] is not None: spanner_references[current_class]._append(leaf) spanner_references[current_class] = None else: message = 'can not end: {}.' message = message.format(current_class.__name) raise Exception(message) for _ in starting: if spanner_references[current_class] is None: spanner_references[current_class] = current_class() else: message = 'already have: {}.' message = message.format(current_class.__name) raise Exception(message) # append leaf to all tracked spanners, for current_class, instance in spanner_references.items(): if instance is not None: instance._append(leaf) # check for unterminated spanners for current_class, instance in spanner_references.items(): if instance is not None: message = 'unterminated {}.' message = message.format(current_class.__name__) raise Exception(message)
def __call__(self, argument): """ Calls rotation on `argument`. .. container:: example Duplicates once without period: >>> operator_ = abjad.Duplication(counts=1) >>> numbers = [1, 2, 3, 4] >>> operator_(numbers) [1, 2, 3, 4, 1, 2, 3, 4] .. container:: example Duplicates twice without period: >>> operator_ = abjad.Duplication(counts=2) >>> pitch_classes = abjad.PitchClassSegment([0, 1, 4, 7]) >>> operator_(pitch_classes) PitchClassSegment([0, 1, 4, 7, 0, 1, 4, 7, 0, 1, 4, 7]) .. container:: example Duplicates periodically: >>> operator_ = abjad.Duplication(counts=1, period=3) >>> pitches = abjad.PitchSegment("c' d' e' f' g' a' b' c''") >>> for pitch in operator_(pitches): ... pitch ... NamedPitch("c'") NamedPitch("d'") NamedPitch("e'") NamedPitch("c'") NamedPitch("d'") NamedPitch("e'") NamedPitch("f'") NamedPitch("g'") NamedPitch("a'") NamedPitch("f'") NamedPitch("g'") NamedPitch("a'") NamedPitch("b'") NamedPitch("c''") NamedPitch("b'") NamedPitch("c''") .. container:: example Duplicate indices: >>> operator_ = abjad.Duplication( ... counts=1, ... indices=(0, -1), ... ) >>> pitch_classes = abjad.PitchClassSegment([0, 1, 4, 7]) >>> operator_(pitch_classes) PitchClassSegment([0, 0, 1, 4, 7, 7]) .. container:: example Duplicate indices periodically: >>> operator_ = abjad.Duplication( ... counts=1, ... indices=(0,), ... period=2, ... ) >>> pitch_classes = abjad.PitchClassSegment([0, 1, 4, 7, 9]) >>> operator_(pitch_classes) PitchClassSegment([0, 0, 1, 4, 4, 7, 9, 9]) .. container:: example Duplicate indices periodically with different counts: >>> operator_ = abjad.Duplication( ... counts=(1, 2), ... indices=(0,), ... period=2, ... ) >>> pitch_classes = abjad.PitchClassSegment([0, 1, 4, 7, 9]) >>> operator_(pitch_classes) PitchClassSegment([0, 0, 1, 4, 4, 4, 7, 9, 9]) .. container:: example Cyclic counts: >>> operator_ = abjad.Duplication(counts=(0, 1, 2, 3)) >>> pitch_classes = abjad.PitchClassSegment([0, 1, 4, 7, 9]) >>> operator_(pitch_classes) PitchClassSegment([0, 1, 1, 4, 4, 4, 7, 7, 7, 7, 9]) Returns new object with type equal to that of `argument`. """ import abjad if not isinstance(argument, collections.abc.Sequence): argument = (argument,) counts = self.counts if isinstance(counts, int): counts = counts + 1 else: counts = [_ + 1 for _ in counts] if not self.period and not self.indices: if isinstance(counts, int): return type(argument)(argument * counts) else: counts = CyclicTuple(counts) result = [] for i, x in enumerate(argument): count = counts[i] result.extend([x] * count) if isinstance(argument, abjad.TypedCollection): result = abjad.new(argument, items=result) else: result = type(argument)(result) return result if isinstance(counts, int): counts = [counts] counts = CyclicTuple(counts) if not self.indices: if isinstance(argument, abjad.TypedCollection): result = abjad.new(argument, items=()) else: result = type(argument)() iterator = abjad.sequence(argument).partition_by_counts( [self.period], cyclic=True, overhang=True ) for i, shard in enumerate(iterator): shard = type(argument)(shard) * counts[i] result = result + shard return result pattern = abjad.Pattern(indices=self.indices, period=self.period) result = [] length = len(argument) j = 0 for i, x in enumerate(argument): if pattern.matches_index(i, length): count = counts[j] result.extend([x] * count) j += 1 else: result.append(x) if isinstance(argument, abjad.TypedCollection): result = abjad.new(argument, items=result) else: result = type(argument)(result) return result
def yield_combinations(self, minimum_length=None, maximum_length=None): """ Yields combinations of sequence items. .. container:: example >>> enumerator = abjad.Enumerator([1, 2, 3, 4]) >>> for combination in enumerator.yield_combinations(): ... combination Sequence([]) Sequence([1]) Sequence([2]) Sequence([1, 2]) Sequence([3]) Sequence([1, 3]) Sequence([2, 3]) Sequence([1, 2, 3]) Sequence([4]) Sequence([1, 4]) Sequence([2, 4]) Sequence([1, 2, 4]) Sequence([3, 4]) Sequence([1, 3, 4]) Sequence([2, 3, 4]) Sequence([1, 2, 3, 4]) .. container:: example >>> enumerator = abjad.Enumerator([1, 2, 3, 4]) >>> for combination in enumerator.yield_combinations( ... minimum_length=3, ... ): ... combination Sequence([1, 2, 3]) Sequence([1, 2, 4]) Sequence([1, 3, 4]) Sequence([2, 3, 4]) Sequence([1, 2, 3, 4]) .. container:: example >>> enumerator = abjad.Enumerator([1, 2, 3, 4]) >>> for combination in enumerator.yield_combinations( ... maximum_length=2, ... ): ... combination Sequence([]) Sequence([1]) Sequence([2]) Sequence([1, 2]) Sequence([3]) Sequence([1, 3]) Sequence([2, 3]) Sequence([4]) Sequence([1, 4]) Sequence([2, 4]) Sequence([3, 4]) .. container:: example >>> enumerator = abjad.Enumerator([1, 2, 3, 4]) >>> for combination in enumerator.yield_combinations( ... minimum_length=2, ... maximum_length=2, ... ): ... combination Sequence([1, 2]) Sequence([1, 3]) Sequence([2, 3]) Sequence([1, 4]) Sequence([2, 4]) Sequence([3, 4]) .. container:: example >>> enumerator = abjad.Enumerator('text') >>> for combination in enumerator.yield_combinations(): ... ''.join([str(_) for _ in combination]) '' 't' 'e' 'te' 'x' 'tx' 'ex' 'tex' 't' 'tt' 'et' 'tet' 'xt' 'txt' 'ext' 'text' Yields combinations in binary string order. Returns sequence generator. """ import abjad length = len(self.sequence) for i in range(2 ** length): binary_string = abjad.mathtools.integer_to_binary_string(i) binary_string = binary_string.zfill(length) sublist = [] for j, digit in enumerate(reversed(binary_string)): if digit == "1": sublist.append(self.sequence[j]) yield_sublist = True if minimum_length is not None: if len(sublist) < minimum_length: yield_sublist = False if maximum_length is not None: if maximum_length < len(sublist): yield_sublist = False if yield_sublist: if isinstance(self.sequence, str): yield "".join(sublist) else: yield abjad.sequence(items=sublist)
def get_normal_order(self): """ Gets normal order. .. container:: example Gets normal order of empty pitch-class set: >>> pc_set = abjad.PitchClassSet() >>> pc_set.get_normal_order() PitchClassSegment([]) .. container:: example Gets normal order: >>> pc_set = abjad.PitchClassSet([0, 1, 10, 11]) >>> pc_set.get_normal_order() PitchClassSegment([10, 11, 0, 1]) .. container:: example Gets normal order: >>> pc_set = abjad.PitchClassSet([2, 8, 9]) >>> pc_set.get_normal_order() PitchClassSegment([8, 9, 2]) .. container:: example Gets normal order of pitch-class set with degree of symmetry equal to 2: >>> pc_set = abjad.PitchClassSet([1, 2, 7, 8]) >>> pc_set.get_normal_order() PitchClassSegment([1, 2, 7, 8]) .. container:: example Gets normal order of pitch-class set with degree of symmetry equal to 4: >>> pc_set = abjad.PitchClassSet([0, 3, 6, 9]) >>> pc_set.get_normal_order() PitchClassSegment([0, 3, 6, 9]) Returns pitch-class segment. """ import abjad if not len(self): return abjad.PitchClassSegment( items=None, item_class=abjad.NumberedPitchClass ) pitch_classes = list(self) pitch_classes.sort() candidates = [] for i in range(self.cardinality): candidate = [abjad.NumberedPitch(_) for _ in pitch_classes] candidate = abjad.sequence(candidate).rotate(n=-i) candidates.append(candidate) return self._get_most_compact_ordering(candidates)
def yield_outer_product(self): """ Yields outer product of sequences in sequence. .. container:: example >>> sequences = [[1, 2, 3], ['a', 'b']] >>> enumerator = abjad.Enumerator(sequences) >>> for sequence_ in enumerator.yield_outer_product(): ... sequence_ ... Sequence([1, 'a']) Sequence([1, 'b']) Sequence([2, 'a']) Sequence([2, 'b']) Sequence([3, 'a']) Sequence([3, 'b']) .. container:: example >>> sequences = [[1, 2, 3], ['a', 'b'], ['X', 'Y']] >>> enumerator = abjad.Enumerator(sequences) >>> for sequence_ in enumerator.yield_outer_product(): ... sequence_ ... Sequence([1, 'a', 'X']) Sequence([1, 'a', 'Y']) Sequence([1, 'b', 'X']) Sequence([1, 'b', 'Y']) Sequence([2, 'a', 'X']) Sequence([2, 'a', 'Y']) Sequence([2, 'b', 'X']) Sequence([2, 'b', 'Y']) Sequence([3, 'a', 'X']) Sequence([3, 'a', 'Y']) Sequence([3, 'b', 'X']) Sequence([3, 'b', 'Y']) .. container:: example >>> sequences = [[1, 2, 3], [4, 5], [6, 7, 8]] >>> enumerator = abjad.Enumerator(sequences) >>> for sequence_ in enumerator.yield_outer_product(): ... sequence_ ... Sequence([1, 4, 6]) Sequence([1, 4, 7]) Sequence([1, 4, 8]) Sequence([1, 5, 6]) Sequence([1, 5, 7]) Sequence([1, 5, 8]) Sequence([2, 4, 6]) Sequence([2, 4, 7]) Sequence([2, 4, 8]) Sequence([2, 5, 6]) Sequence([2, 5, 7]) Sequence([2, 5, 8]) Sequence([3, 4, 6]) Sequence([3, 4, 7]) Sequence([3, 4, 8]) Sequence([3, 5, 6]) Sequence([3, 5, 7]) Sequence([3, 5, 8]) Returns sequence generator. """ def _helper(sequence_1, sequence_2): result = [] for item_1 in sequence_1: for item_2 in sequence_2: result.extend([item_1 + [item_2]]) return result import abjad sequences = [abjad.sequence(_) for _ in self.sequence] sequences[0] = [[_] for _ in sequences[0]] result = functools.reduce(_helper, sequences) for element in result: yield abjad.sequence(items=element)
def helper(argument): result = abjad.sequence(argument).sum_by_sign(sign=[-1]) return list(result)