def select(expr=None, contiguous=False): r'''Selects `expr`. Returns selection. ''' from abjad.tools import scoretools from abjad.tools import selectiontools from abjad.tools import spannertools Selection = selectiontools.Selection if contiguous: if isinstance(expr, (list, tuple)): assert Selection._all_are_contiguous_components_in_same_logical_voice( expr) return selectiontools.ContiguousSelection(expr) elif isinstance(expr, scoretools.Component): return selectiontools.ContiguousSelection(expr) elif hasattr(expr, '_music'): music = expr._music return selectiontools.Selection(music) elif isinstance(expr, spannertools.Spanner): music = expr._components return selectiontools.Selection(music) elif expr is None: return selectiontools.Selection() else: return selectiontools.Selection(expr)
def __call__(self, expr, rotation=None): r'''Iterates tuple `expr`. Returns tuple in which each item is a selection or component. ''' if rotation is None: rotation = 0 rotation = int(rotation) if not self.pattern: return expr result = [] if self.apply_to_each: for subexpr in expr: subresult = [] length = len(subexpr) for index, item in enumerate(subexpr): if self.pattern.matches_index( index, length, rotation=rotation, ): subresult.append(item) if subresult: subresult = selectiontools.Selection(subresult) result.append(subresult) else: length = len(expr) for index, item in enumerate(expr): if self.pattern.matches_index( index, length, rotation=rotation, ): result.append(item) return tuple(result)
def make_skips( written_duration, multiplied_durations, ): '''Make `written_duration` skips with `multiplied_durations`: :: >>> scoretools.make_skips( ... Duration(1, 4), [(1, 2), (1, 3), (1, 4), (1, 5)]) Selection(Skip('s4 * 2'), Skip('s4 * 4/3'), Skip('s4 * 1'), Skip('s4 * 4/5')) Useful for making invisible layout voices. Returns selection. ''' from abjad.tools import scoretools # initialize skips and written duration skips = [] written_duration = durationtools.Duration(written_duration) # make skips for multiplied_duration in multiplied_durations: multiplied_duration = durationtools.Duration(multiplied_duration) skip = scoretools.Skip(written_duration) multiplier = multiplied_duration / written_duration attach(multiplier, skip) skips.append(skip) # return skips skips = selectiontools.Selection(skips) return skips
def _get_contents(self, include_self=True): result = [] if include_self: result.append(self) result.extend(getattr(self, '_music', [])) result = selectiontools.Selection(result) return result
def _make_music(self, divisions, seeds): from abjad.tools import rhythmmakertools selections = [] for division in divisions: assert isinstance(division, durationtools.Division), division for division in divisions: container = self._make_container(division) selection = selectiontools.Selection(container) selections.append(selection) beam_specifier = self.beam_specifier if not beam_specifier: beam_specifier = rhythmmakertools.BeamSpecifier() if beam_specifier.beam_divisions_together: durations = [] for selection in selections: duration = selection.get_duration() durations.append(duration) beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, nibs_towards_nonbeamable_components=False, ) components = [] for selection in selections: components.extend(selection) attach(beam, components) elif beam_specifier.beam_each_division: for selection in selections: beam = spannertools.MultipartBeam() attach(beam, selection) return selections
def __call__(self, expr, rotation=None): r'''Iterates tuple `expr`. Returns tuple in which each item is a selection or component. ''' from abjad.tools import scoretools from abjad.tools import selectiontools from abjad.tools.topleveltools import select assert isinstance(expr, tuple), repr(expr) result = [] for subexpr in expr: if isinstance(subexpr, scoretools.Leaf): subexpr = selectiontools.Selection([subexpr]) subresult = [] if self.with_previous_leaf: first_leaf = subexpr[0] previous_leaf = first_leaf._get_leaf(-1) if previous_leaf is not None: subresult.append(previous_leaf) if isinstance(subexpr, selectiontools.Selection): subresult.extend(subexpr) else: subresult.append(subexpr) if self.with_next_leaf: last_leaf = subexpr[-1] next_leaf = last_leaf._get_leaf(1) if next_leaf is not None: subresult.append(next_leaf) subresult = select(subresult) result.append(subresult) return tuple(result)
def components(self): r'''Gets components in spanner. Returns selection. ''' from abjad.tools import selectiontools return selectiontools.Selection(self._components[:])
def make_notes_with_multiplied_durations( pitch, written_duration, multiplied_durations, ): '''Make `written_duration` notes with `pitch` and `multiplied_durations`: :: >>> args = [0, Duration(1, 4), [(1, 2), (1, 3), (1, 4), (1, 5)]] >>> scoretools.make_notes_with_multiplied_durations(*args) Selection(Note("c'4 * 2"), Note("c'4 * 4/3"), Note("c'4 * 1"), Note("c'4 * 4/5")) Useful for making spatially positioned notes. Returns list of notes. ''' from abjad.tools import scoretools from abjad.tools import selectiontools # initialize input written_duration = durationtools.Duration(written_duration) # make notes notes = [] for multiplied_duration in multiplied_durations: multiplied_duration = durationtools.Duration(multiplied_duration) note = scoretools.Note(pitch, written_duration) multiplier = multiplied_duration / written_duration attach(multiplier, note) notes.append(note) # return notes notes = selectiontools.Selection(notes) return notes
def _cast_selection(self, selection, target_class): new_selection = [] for leaf in selection: new_leaf = target_class(leaf) new_selection.append(new_leaf) new_selection = selectiontools.Selection(new_selection) return new_selection
def _make_music(self, divisions, rotation): selections = [] for division in divisions: prototype = mathtools.NonreducedFraction assert isinstance(division, prototype), division for division in divisions: container = self._make_container(division) selection = selectiontools.Selection(container) selections.append(selection) beam_specifier = self._get_beam_specifier() if beam_specifier.beam_divisions_together: durations = [] for selection in selections: duration = selection.get_duration() durations.append(duration) beam = spannertools.DuratedComplexBeam( durations=durations, span_beam_count=1, nibs_towards_nonbeamable_components=False, ) components = [] for selection in selections: components.extend(selection) leaves = select(components).by_leaf() #attach(beam, components) attach(beam, leaves) elif beam_specifier.beam_each_division: for selection in selections: beam = spannertools.MultipartBeam() leaves = select(selection).by_leaf() #attach(beam, selection) attach(beam, leaves) return selections
def __call__(self, expr): r'''Iterates tuple `expr`. Returns tuple of selections. ''' assert isinstance(expr, tuple), repr(tuple) result = [] if self.flatten: visited_logical_ties = set() for subexpr in expr: for logical_tie in self._iterate_expr(subexpr): if logical_tie in visited_logical_ties: continue result.append(logical_tie) visited_logical_ties.add(logical_tie) else: for subexpr in expr: subresult = [] visited_logical_ties = set() for logical_tie in self._iterate_expr(subexpr): if logical_tie in visited_logical_ties: continue subresult.append(logical_tie) visited_logical_ties.add(logical_tie) subresult = selectiontools.Selection(subresult) result.append(subresult) return tuple(result)
def get_counttime_components(self, counttime_components): r'''Get `counttime_components` that satisfy `time_relation`: :: >>> voice = Voice( ... [Note(i % 36, Duration(1, 4)) for i in range(200)]) >>> timespan_1 = timespantools.Timespan(20, 22) >>> time_relation = \ ... timespantools.timespan_2_starts_during_timespan_1( ... timespan_1=timespan_1) :: >>> result = time_relation.get_counttime_components(voice[:]) :: >>> for counttime_component in result: ... counttime_component Note("af'4") Note("a'4") Note("bf'4") Note("b'4") Note("c''4") Note("cs''4") Note("d''4") Note("ef''4") :: >>> result.get_timespan() Timespan(start_offset=Offset(20, 1), stop_offset=Offset(22, 1)) `counttime_components` must belong to a single voice. `counttime_components` must be time-contiguous. The call shown here takes 78355 function calls under r9686. Returns selection. ''' from abjad.tools import selectiontools from abjad.tools import timespantools # check input assert isinstance( counttime_components, (list, selectiontools.Selection)), repr(counttime_components) assert self.timespan_1 is not None # iterate counttime components result = [] for counttime_component in counttime_components: if self(timespan_2=counttime_component._get_timespan()): result.append(counttime_component) # return result return selectiontools.Selection(result)
def __getitem__(self, expr): r'''Gets item from spanner. Returns component. ''' if isinstance(expr, slice): return selectiontools.Selection(self._components.__getitem__(expr)) return self._components.__getitem__(expr)
def _extract(self, scale_contents=False): from abjad.tools import selectiontools if scale_contents: self._scale_contents(self.multiplier) selection = selectiontools.Selection([self]) parent, start, stop = selection._get_parent_and_start_stop_indices() music_list = list(getattr(self, '_music', ())) parent.__setitem__(slice(start, stop + 1), music_list) return self
def select(expr=None): r'''Selects `expr`. .. container:: example **Example 1.** Returns selection when `expr` is not none: :: >>> staff = Staff("c'8 d'8 e'8 f'8") >>> select(staff[:2]) Selection(Note("c'8"), Note("d'8")) .. container:: example **Example 2.** Returns selector when `expr` is none: :: >>> select() Selector() Returns selection. ''' from abjad.tools import scoretools from abjad.tools import selectiontools from abjad.tools import selectortools from abjad.tools import spannertools if expr is None: return selectortools.Selector() Selection = selectiontools.Selection if isinstance(expr, scoretools.Component): return selectiontools.Selection(expr) elif hasattr(expr, '_music'): music = expr._music return selectiontools.Selection(music) elif isinstance(expr, spannertools.Spanner): music = expr._components return selectiontools.Selection(music) elif expr is None: return selectiontools.Selection() else: return selectiontools.Selection(expr)
def leaves_grouped_by_immediate_parents(self): r'''Leaves in logical tie grouped by immediate parents of leaves. Returns list of lists. ''' from abjad.tools import selectiontools result = [] pairs_generator = itertools.groupby(self, lambda x: id(x._parent)) for key, values_generator in pairs_generator: group = selectiontools.Selection(list(values_generator)) result.append(group) return result
def make_score(self): r'''Make MIDI playback score from scale: :: >>> scale = tonalanalysistools.Scale('E', 'major') >>> score = scale.make_score() .. doctest:: >>> print(format(score)) \new Score \with { tempoWholesPerMinute = #(ly:make-moment 30 1) } << \new Staff { \key e \major e'8 fs'8 gs'8 a'8 b'8 cs''8 ds''8 e''8 ds''8 cs''8 b'8 a'8 gs'8 fs'8 e'4 } >> :: >>> show(score) # doctest: +SKIP Returns score. ''' ascending_notes = self.make_notes(8, durationtools.Duration(1, 8)) descending_notes = copy.deepcopy(ascending_notes[:-1]) descending_notes = list(descending_notes) descending_notes.reverse() descending_notes = selectiontools.Selection(descending_notes) notes = ascending_notes + descending_notes notes[-1].written_duration = durationtools.Duration(1, 4) staff = scoretools.Staff(notes) key_signature = copy.copy(self.key_signature) attach(key_signature, staff) score = scoretools.Score([staff]) set_(score).tempo_wholes_per_minute = schemetools.SchemeMoment(30) return score
def _group(self, expr): selections = [] first_component = self._get_first_component(expr) first_component._update_logical_measure_numbers() pairs = itertools.groupby( expr, lambda _: self._get_logical_measure_number(_), ) for value, group in pairs: selection = selectiontools.Selection(list(group)) selections.append(selection) return tuple(selections)
def _initialize_rhythm(self, rhythm): from abjad.tools import scoretools from abjad.tools import selectiontools if isinstance(rhythm, scoretools.Component): selection = selectiontools.Selection([rhythm]) elif isinstance(rhythm, selectiontools.Selection): selection = rhythm else: message = 'rhythm must be duration, component or selection: {!r}.' message = message.format(rhythm) raise TypeError(message) assert isinstance(selection, selectiontools.Selection) return selection
def __call__(self, expr, rotation=None): r'''Iterates tuple `expr`. Returns tuple in which each item is a selection or component. ''' assert isinstance(expr, tuple), repr(expr) if rotation is None: rotation = 0 rotation = int(rotation) result = [] counts = self.counts if self.rotate: counts = sequencetools.rotate_sequence(counts, -rotation) for subexpr in expr: groups = sequencetools.partition_sequence_by_counts( subexpr, [abs(_) for _ in counts], cyclic=self.cyclic, overhang=self.overhang, ) if self.overhang and self.fuse_overhang and 1 < len(groups): last_count = counts[(len(groups) - 1) % len(counts)] if len(groups[-1]) != last_count: last_group = groups.pop() groups[-1] += last_group subresult = [] for i, group in enumerate(groups): count = counts[i] if count < 0: continue items = selectiontools.Selection(group) subresult.append(items) if self.nonempty and not subresult: group = selectiontools.Selection(groups[0]) subresult.append(group) result.extend(subresult) if self.rotate: counts = sequencetools.rotate_sequence(counts, -1) return tuple(result)
def _make_music(self, divisions, seeds): #assert not seeds, repr(seeds) if seeds is None: seeds = 0 selections = [] divisions = [durationtools.Division(_) for _ in divisions] denominators = datastructuretools.CyclicTuple(self.denominators) extra_counts_per_division = self.extra_counts_per_division or (0,) extra_counts_per_division = datastructuretools.CyclicTuple( extra_counts_per_division ) for i, division in enumerate(divisions, seeds): # not yet extended to work with non-power-of-two divisions assert mathtools.is_positive_integer_power_of_two( division.denominator), repr(division) denominator = denominators[i] extra_count = extra_counts_per_division[i] basic_duration = durationtools.Duration(1, denominator) unprolated_note_count = None if division < 2 * basic_duration: notes = scoretools.make_notes([0], [division]) else: unprolated_note_count = division / basic_duration unprolated_note_count = int(unprolated_note_count) unprolated_note_count = unprolated_note_count or 1 if 0 < extra_count: modulus = unprolated_note_count extra_count = extra_count % modulus elif extra_count < 0: modulus = int(math.ceil(unprolated_note_count / 2.0)) extra_count = abs(extra_count) % modulus extra_count *= -1 note_count = unprolated_note_count + extra_count durations = note_count * [basic_duration] notes = scoretools.make_notes([0], durations) assert all( _.written_duration.denominator == denominator for _ in notes ) tuplet_duration = durationtools.Duration(division) tuplet = scoretools.FixedDurationTuplet( duration=tuplet_duration, music=notes, ) if unprolated_note_count is not None: preferred_denominator = unprolated_note_count tuplet.preferred_denominator = preferred_denominator selection = selectiontools.Selection(tuplet) selections.append(selection) self._apply_beam_specifier(selections) return selections
def _split_by_duration( self, duration, fracture_spanners=False, tie_split_notes=True, use_messiaen_style_ties=False, ): from abjad.tools import indicatortools from abjad.tools import pitchtools from abjad.tools import selectiontools # check input duration = durationtools.Duration(duration) # calculate durations leaf_multiplied_duration = self._multiplied_duration prolation = self._get_parentage(include_self=False).prolation preprolated_duration = duration / prolation # handle boundary cases if preprolated_duration <= 0: return ([], [self]) if leaf_multiplied_duration <= preprolated_duration: return ([self], []) # create new leaf new_leaf = copy.copy(self) self._splice([new_leaf], grow_spanners=True) # adjust leaf self._detach_grace_containers(kind='after') # adjust new leaf new_leaf._detach_grace_containers(kind='grace') left_leaf_list = self._set_duration( preprolated_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) right_preprolated_duration = \ leaf_multiplied_duration - preprolated_duration right_leaf_list = new_leaf._set_duration( right_preprolated_duration, use_messiaen_style_ties=use_messiaen_style_ties, ) leaf_left_of_split = left_leaf_list[-1] leaf_right_of_split = right_leaf_list[0] leaves_around_split = (leaf_left_of_split, leaf_right_of_split) if fracture_spanners: for spanner in leaf_left_of_split._get_spanners(): index = spanner._index(leaf_left_of_split) spanner._fracture(index, direction=Right) # tie split notes, rests and chords as specified if pitchtools.Pitch.is_pitch_carrier(self) and tie_split_notes: selection = selectiontools.Selection(leaves_around_split) selection._attach_tie_spanner_to_leaf_pair( use_messiaen_style_ties=use_messiaen_style_ties, ) return left_leaf_list, right_leaf_list
def make_multiplied_quarter_notes( pitches, multiplied_durations, ): r'''Make quarter notes with `pitches` and `multiplied_durations`: :: >>> args = [[0, 2, 4, 5], [(1, 4), (1, 5), (1, 6), (1, 7)]] >>> scoretools.make_multiplied_quarter_notes(*args) Selection(Note("c'4 * 1"), Note("d'4 * 4/5"), Note("e'4 * 2/3"), Note("f'4 * 4/7")) Read `pitches` cyclically where the length of `pitches` is less than the length of `multiplied_durations`: :: >>> args = [[0], [(1, 4), (1, 5), (1, 6), (1, 7)]] >>> scoretools.make_multiplied_quarter_notes(*args) Selection(Note("c'4 * 1"), Note("c'4 * 4/5"), Note("c'4 * 2/3"), Note("c'4 * 4/7")) Read `multiplied_durations` cyclically where the length of `multiplied_durations` is less than the length of `pitches`: :: >>> args = [[0, 2, 4, 5], [(1, 5)]] >>> scoretools.make_multiplied_quarter_notes(*args) Selection(Note("c'4 * 4/5"), Note("d'4 * 4/5"), Note("e'4 * 4/5"), Note("f'4 * 4/5")) Returns list of zero or more newly constructed notes. ''' from abjad.tools import scoretools multiplied_durations = [ durationtools.Duration(x) for x in multiplied_durations ] quarter_notes = [] sequences = [pitches, multiplied_durations] for pitch, duration in sequencetools.zip_sequences(sequences, cyclic=True): quarter_note = scoretools.Note(pitch, durationtools.Duration(1, 4)) duration = durationtools.Duration(duration) multiplier = durationtools.Multiplier(duration / durationtools.Duration(1, 4)) attach(multiplier, quarter_note) quarter_notes.append(quarter_note) quarter_notes = selectiontools.Selection(quarter_notes) return quarter_notes
def __add__(self, expr): '''Adds `expr` to selection. Returns new selection. ''' from abjad.tools import selectiontools assert isinstance(expr, (Selection, list, tuple)) if isinstance(expr, type(self)): music = self._music + expr._music elif isinstance(expr, (tuple, list)): music = self._music + tuple(expr) if self._all_are_contiguous_components_in_same_logical_voice(music): return type(self)(music) else: return selectiontools.Selection(music)
def __call__(self, expr): r'''Iterates tuple `expr`. Returns tuple of selections. ''' assert isinstance(expr, tuple), repr(tuple) result = [] prototype = self.prototype if not isinstance(prototype, tuple): prototype = (prototype, ) for subexpr in expr: for run in iterate(subexpr).by_run(prototype): run = selectiontools.Selection(run) result.append(run) return tuple(result)
def __mul__(self, n): r'''Copies component `n` times and detaches spanners. Returns list of new components. ''' from abjad.tools import spannertools result = mutate(self).copy(n=n) for component in iterate(result).by_class(): detach(spannertools.Spanner, component) if isinstance(result, type(self)): result = [result] else: result = list(result) result = selectiontools.Selection(result) return result
def make_spacer_skip_measures(time_signatures, implicit_scaling=False): r'''Makes measures with full-measure spacer skips from `time_signatures`. .. container:: example :: >>> measures = scoretools.make_spacer_skip_measures( ... [(1, 8), (5, 16), (5, 16)]) >>> staff = Staff(measures) >>> show(staff) # doctest: +SKIP .. doctest:: >>> print(format(staff)) \new Staff { { \time 1/8 s1 * 1/8 } { \time 5/16 s1 * 5/16 } { s1 * 5/16 } } Returns selection of unincorporated measures. ''' from abjad.tools import indicatortools from abjad.tools import scoretools # make measures measures = [] for time_signature in time_signatures: time_signature = indicatortools.TimeSignature(time_signature) measure = scoretools.Measure( time_signature, implicit_scaling=implicit_scaling, ) measures.append(measure) scoretools.fill_measures_in_expr_with_full_measure_spacer_skips(measures) # return measures measures = selectiontools.Selection(measures) return measures
def __call__(self, expr): r'''Iterates tuple `expr`. Returns tuple of selections. ''' assert isinstance(expr, tuple), repr(tuple) result = [] if self.flatten: for subexpr in expr: result.extend(self._iterate_expr(subexpr)) else: for subexpr in expr: subresult = selectiontools.Selection( self._iterate_expr(subexpr), ) result.append(subresult) return tuple(result)
def select_notes_and_chords(self): r'''Selects notes and chords in container. .. container:: example :: >>> container.select_notes_and_chords() Selection(Note("c'8"), Note("d'8"), Note("e'8")) Returns leaf selection. ''' from abjad.tools import scoretools from abjad.tools import selectiontools generator = iterate(self).by_class((scoretools.Note, scoretools.Chord)) return selectiontools.Selection(generator)
def _make_repeated_skips_from_time_signature(time_signature): from abjad.tools import scoretools # afford basic input polymorphism time_signature = indicatortools.TimeSignature(time_signature) # check input if time_signature.has_non_power_of_two_denominator: message = 'TODO: extend this function for time signatures' message += ' with non-power-of-two denominators.' raise NotImplementedError(message) # make and return repeated skips skip = scoretools.Skip((1, time_signature.denominator)) skips = time_signature.numerator * skip result = selectiontools.Selection(skips)