PitchRandomiser

class auxjad.PitchRandomiser(contents: abjad.score.Container, pitches: Union[list, tuple, str, abjad.pitch.segments.PitchSegment], *, weights: Optional[list] = None, omit_time_signatures: bool = False, process_on_first_call: bool = True, use_tenney_selector: bool = False)[source]

Takes an input abjad.Container (or child class) together with a list of pitches and randomises the container’s pitch content using the list of pitches. The pitches can be of type list, tuple, str, or abjad.PitchSegment.

Basic usage:

Calling the object will output a selection of the input container with randomised pitches. Pitches are randomly selected from pitches.

>>> container = abjad.Container(r"\time 4/4 c'4 d'4 e'4 f'4")
>>> abjad.show(container)
../_images/PitchRandomiser-PxSLuwtgn9.png
>>> pitches = r"fs' gs' a' b' cs''"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-134lqskbb6o.png
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-z66g1fy8nm8.png

To get the result of the last operation, use the property current_window.

>>> notes = randomiser.current_window
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-x0e6yduogh.png

Warning

Unlike the other classes in Auxjad, the very first call of this class will already process the initial container. To disable this behaviour and output the initial container once before randomising its pitches, initialise the class with the keyword argument process_on_first_call set to False.

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     process_on_first_call=False,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-640x6vsjwtk.png
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-vsjdj8gkanj.png
len():

Applying the len() function to the randomiser will return the number of pitches in pitches.

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> len(randomiser)
4
>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> pitches = [6, 7, 8, 9, 10, 11, 12]
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> len(randomiser)
7
Arguments and properties:

This class has many keyword arguments, all of which can be altered after instantiation using properties with the same names as shown below. weights takes a list of int’s or float’s representing the weight of each pitch from pitches (their lengths must also match). omit_time_signatures will remove all time signatures from the output (both are False by default). process_on_first_call to True and the random pitch process will be applied on the very first call. Setting use_tenney_selector to True will make the randomiser use auxjad.TenneySelector for the random selection instead of random.choices() (default is False).

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> randomiser = auxjad.PitchRandomiser(
...     container,
...     pitches=r"a b cs' ds' e'",
...     weights=[1.0, 2.0, 1.0, 1.5, 1.3],
...     omit_time_signatures=True,
...     process_on_first_call=True,
...     use_tenney_selector=True,
... )
>>> randomiser.pitches
<a b cs' ds' e'>
>>> randomiser.weights
[1.0, 2.0, 1.0, 1.5, 1.3]
>>> randomiser.omit_time_signatures
True
>>> randomiser.process_on_first_call
True
>>> randomiser.use_tenney_selector
True

Use the properties below to change these values after initialisation.

>>> randomiser.pitches = abjad.PitchSegment(r"c' d' e' f'")
>>> randomiser.weights = [1, 2, 5, 8]
>>> randomiser.omit_time_signatures = False
>>> randomiser.process_on_first_call = False
>>> randomiser.use_tenney_selector = False
>>> randomiser.pitches
<c' d' e' f'>
>>> randomiser.weights
[1, 2, 5, 8]
>>> randomiser.omit_time_signatures
False
>>> randomiser.process_on_first_call
False
>>> randomiser.use_tenney_selector
False
Rests:

Only pitched logical ties are randomised, rests are left untouched.

>>> container = abjad.Container(r"c'8. d'4 r8 r8. e'16 f'8.")
>>> pitches = [6, 7, 8, 9, 10, 11]
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-u4294ozm92.png
Chords:

Each note of a chord is randomised too.

>>> container = abjad.Container(
...     r"<c' e' g'>8. d'4 r8 r8. e'16 <f' a'>8."
... )
>>> pitches = [6, 7, 8, 9, 10, 11]
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-318eldj7tzc.png

The number of notes in a chord stay the same unless there are fewer pitches available in pitches.

>>> container = abjad.Container(
...     r"<c' e' g' a'>2 <cs' ds' e' f' g' a' b'>2"
... )
>>> pitches = [6, 7, 8]
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-cciyee49qrj.png
use_tenney_selector:

Setting use_tenney_selector to True will make the randomiser use auxjad.TenneySelector for the random selection instead of random.choices() (default is False). auxjad.TenneySelector will raise the chance of a pitch being selected the longer it hasn’t been selected, and will forbid immediate repetitions of pitches. See its documentation for more information.

>>> container = abjad.Container(r"c'8 d'8 e'8 f'8 g'8 a'8 b'8 c'8")
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     use_tenney_selector=True,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-tmxllu13pa8.png
weights:

Individual pitches can have different weights, defined by the weights property. It takes a list of float’s or int’s.

>>> container = abjad.Container(r"c'8 d'8 e'8 f'8 g'8 a'8 b'8 c'8")
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     weights=[5.0, 2.0, 1.5, 1.0],
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-zkvbzd1brgq.png
weights and use_tenney_selector:

Non-uniform weights can also be used when use_tenney_selector is set to True.

>>> container = abjad.Container(r"c'8 d'8 e'8 f'8 g'8 a'8 b'8 c'8")
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     weights=[5.0, 2.0, 1.5, 1.0],
...                                     use_tenney_selector=True,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-cq1nobkjozg.png
Resetting weights:

Setting weights to None will reset it back to a uniform distribution.

>>> container = abjad.Container(r"c'8 d'8 e'8 f'8 g'8 a'8 b'8 c'8")
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     weights=[100.0, 1.0, 1.0, 1.0],
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-wtl5o15q5qp.png
>>> randomiser.weights = None
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-4bqe6cbawg6.png
Changing pitches:

When using a custom list of weights, changing the pitches to a series of new values with the same length will preserve the weights values. If on the other hand pitches changes in length, weights is reset to None (i.e. uniform distribution).

>>> container = abjad.Container(r"c'8 d'8 e'8 f'8 g'8 a'8 b'8 c'8")
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     weights=[100.0, 1.0, 1.0, 1.0],
...                                     )
>>> randomiser.pitches = r"c'' d'' e'' f''"
>>> randomiser.pitches
<c'' d'' e'' f''>
>>> randomiser.weights
[100.0, 1.0, 1.0, 1.0]
>>> randomiser.pitches = r"c'' d'' e'' f'' g'' a'' b''"
>>> randomiser.pitches
<c'' d'' e'' f'' g'' a'' b''>
>>> randomiser.weights
None

Error

Note that weights must always have the same length as pitches, otherwise a ValueError exception will be raised.

>>> container = abjad.Container(r"c'4 d'4 e'4 f'4")
>>> pitches = r"fs' gs' a' b'"
>>> weights = [1, 1, 5, 2, 3, 4, 8]
>>> auxjad.PitchRandomiser(container, pitches, weights=weights)
ValueError: 'weights' must have the same length as 'pitches'
output_n():

To output several randomised containers at once, use the method output_n(), inputting the desired number of iterations.

>>> container = abjad.Container(r"c'4 ~ c'16 r8. d'4 e'8. r16")
>>> pitches = [6, 7, 8, 9, 10]
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> notes = randomiser.output_n(3)
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-fvwaaz3vgi.png
Indicators:

This class preserves indicators.

>>> container = abjad.Container(
...     r"c'4\p\< ~ c'8. d'16-.\f e'4--\pp f'8.( g'16)"
... )
>>> pitches = [6, 7, 8, 9, 10, 11, 12]
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-2e647eng8yc.png
Example:

This class also preserves the time signature structure.

>>> container = abjad.Container(
...     r"\time 3/4 c'4 d'2 \time 2/4 e'8 f'8 g'8 a'8"
... )
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-c9t7r3thrqg.png
omit_time_signatures:

To omit time signatures altogether, set omit_time_signatures to True (default is False).

>>> container = abjad.Container(
...     r"\time 3/4 c'4 d'2 \time 2/4 e'8 f'8 g'8 a'8"
... )
>>> pitches = r"fs' gs' a' b'"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     omit_time_signatures=True,
...                                     )
>>> notes = randomiser()
>>> staff = abjad.Staff(notes)
>>> abjad.show(staff)
../_images/PitchRandomiser-mwruvbmgu3o.png
Using as iterator:

The instances of this class can also be used as an iterator, which can then be used in a for loop. Note that unlike the method output_n(), time signatures are added to each window returned by the randomiser. Use the function auxjad.mutate.remove_repeated_time_signatures() to clean the output when using this class in this way. It is also important to note that a break statement is needed when using this class as an iterator. The reason is that pitch randomisation is a process that can happen indefinitely (unlike some of the other classes in this library).

>>> container = abjad.Container(r"\time 3/4 c'4 d'4 e'4")
>>> pitches = r"fs' gs' a' b' cs''"
>>> randomiser = auxjad.PitchRandomiser(container,
...                                     pitches,
...                                     )
>>> staff = abjad.Staff()
>>> for window in randomiser:
...     staff.append(window)
...     if abjad.get.duration(staff) == abjad.Duration((9, 4)):
...         break
>>> auxjad.mutate.remove_repeated_time_signatures(staff)
>>> abjad.show(staff)
../_images/PitchRandomiser-2c9zzip8tpc.png

Tip

The functions auxjad.mutate.remove_repeated_dynamics() and auxjad.mutate.reposition_clefs() can be used to clean the output and remove repeated dynamics and unnecessary clef changes.

Methods

__call__()

Calls the randomise process, returning an abjad.Selection

__init__(contents, pitches, *[, weights, …])

Initialises self.

__iter__()

Returns an iterator, allowing instances to be used as iterators.

__len__()

Returns the number of available pitches.

__next__()

Calls the randomise process for one iteration, returning an abjad.Selection.

__repr__()

Returns interpreter representation of pitches.

output_n(n)

Goes through n iterations of the pitch randomisation process and outputs a single abjad.Selection.

Attributes

contents

The abjad.Container to be shuffled.

current_window

Read-only property, returns the result of the last operation.

omit_time_signatures

When True, the output will contain no time signatures.

pitches

Pitches available for the randomiser.

process_on_first_call

If True then contents will be processed in the very first call.

use_tenney_selector

If True then the pitches will be selected using auxjad.TenneySelector, otherwise they are chosen using a uniform random distribution.

weights

The list with weights for each element of pitches

__call__()abjad.select.Selection[source]

Calls the randomise process, returning an abjad.Selection

__init__(contents: abjad.score.Container, pitches: Union[list, tuple, str, abjad.pitch.segments.PitchSegment], *, weights: Optional[list] = None, omit_time_signatures: bool = False, process_on_first_call: bool = True, use_tenney_selector: bool = False)None[source]

Initialises self.

__iter__()None[source]

Returns an iterator, allowing instances to be used as iterators.

__len__()int[source]

Returns the number of available pitches.

__next__()abjad.select.Selection[source]

Calls the randomise process for one iteration, returning an abjad.Selection.

__repr__()str[source]

Returns interpreter representation of pitches.

property contents: abjad.score.Container

The abjad.Container to be shuffled.

property current_window: abjad.select.Selection

Read-only property, returns the result of the last operation.

property omit_time_signatures: bool

When True, the output will contain no time signatures.

output_n(n: int)abjad.select.Selection[source]

Goes through n iterations of the pitch randomisation process and outputs a single abjad.Selection.

property pitches: abjad.pitch.segments.PitchSegment

Pitches available for the randomiser.

property process_on_first_call: bool

If True then contents will be processed in the very first call.

property use_tenney_selector: bool

If True then the pitches will be selected using auxjad.TenneySelector, otherwise they are chosen using a uniform random distribution.

property weights: list

The list with weights for each element of pitches