This module defines objects for tracking the derivation of one
Stream from another.
- class music21.derivation.Derivation(client: base.Music21Object | None = None)¶
A Derivation object keeps track of which Streams (or perhaps other Music21Objects) a Stream or other music21 object has come from and how.
Derivation is automatically updated by many methods:
>>> import copy >>> sOrig = stream.Stream(id='orig') >>> sNew = copy.deepcopy(sOrig) >>> sNew.id = 'copy' >>> sNew.derivation <Derivation of <music21.stream.Stream copy> from <music21.stream.Stream orig> via '__deepcopy__'>
>>> sNew.derivation.client <music21.stream.Stream copy> >>> sNew.derivation.client is sNew True >>> sNew.derivation.origin <music21.stream.Stream orig> >>> sNew.derivation.method '__deepcopy__'
>>> s1 = stream.Stream() >>> s1.id = 'DerivedStream' >>> d1 = derivation.Derivation(s1)
>>> s2 = stream.Stream() >>> s2.id = 'OriginalStream'
>>> d1.method = 'manual' >>> d1.origin = s2 >>> d1 <Derivation of <music21.stream.Stream DerivedStream> from <music21.stream.Stream OriginalStream> via 'manual'> >>> d1.origin is s2 True
>>> d1.client is s1 True
>>> import copy >>> d2 = copy.deepcopy(d1) >>> d2.origin is s2 True
>>> d1.method = 'measure' >>> d1.method 'measure'
Deleting the origin stream does not change the Derivation, since origin is held by strong ref:
>>> import gc # Garbage collection... >>> del s2 >>> unused = gc.collect() # ensure Garbage collection is run >>> d1 <Derivation of <music21.stream.Stream DerivedStream> from <music21.stream.Stream OriginalStream> via 'measure'>
But deleting the client stream changes the Derivation, since client is held by weak ref, and will also delete the origin (so long as client was ever set)
>>> del s1 >>> unused = gc.collect() # ensure Garbage collection is run >>> d1 <Derivation of None from None via 'measure'>
Derivation read-only properties
Return the Python id (=memory location) of the origin. (Same as id(derivation.origin). Not the same as derivation.origin.ind)
Return a reference to the oldest source of this Stream; that is, chain calls to
derivesFromuntil we get to a Stream that cannot be further derived.
>>> s1 = stream.Stream() >>> s1.repeatAppend(note.Note(), 10) >>> s1.repeatAppend(note.Rest(), 10) >>> s2 = s1.notesAndRests.stream() >>> s3 = s2.getElementsByClass(note.Note).stream() >>> s3.derivation.rootDerivation is s1 True
Derivation read/write properties
Returns or sets the string of the method that was used to generate this Stream.
>>> s = stream.Stream() >>> s.derivation.method is None True
>>> sNotes = s.notes.stream() >>> sNotes.derivation.method 'notes'
Some examples are ‘getElementsByClass’ etc.
>>> s = stream.Stream() >>> s.id = 'lonelyStream' >>> s.append(clef.TrebleClef()) >>> s.append(note.Note()) >>> sNotes = s.notes.stream() >>> sNotes.derivation <Derivation of <music21.stream.Stream lonelyStream> from <music21.stream.Stream lonelyStream> via 'notes'>
>>> derived = sNotes.derivation >>> derived.method 'notes'
>>> derived.method = 'blah' >>> derived.method 'blah'
>>> derived is sNotes.derivation True >>> sNotes.derivation.method 'blah'
- Derivation.chain() Generator[base.Music21Object, None, None] ¶
Yields the Streams which this Derivation’s client Stream was derived from. This provides a way to obtain all Streams that the client passed through, such as those created by
>>> s1 = stream.Stream() >>> s1.id = 's1' >>> s1.repeatAppend(note.Note(), 10) >>> s1.repeatAppend(note.Rest(), 10) >>> s2 = s1.notesAndRests.stream() >>> s2.id = 's2' >>> s3 = s2.getElementsByClass(note.Note).stream() >>> s3.id = 's3' >>> for y in s3.derivation.chain(): ... print(y) <music21.stream.Stream s2> <music21.stream.Stream s1>
>>> list(s3.derivation.chain()) == [s2, s1] True
This decorator can be used for creating a function that returns a new derivation. But is currently unused, since it does not take into account inPlace=True. Stream.cloneEmpty(derivationMethod=’derivationMethod’) is preferred for Streams.
>>> from copy import deepcopy >>> @derivation.derivationMethod ... def allGreen(n): ... n2 = deepcopy(n) ... n2.style.color = 'green' ... return n2
>>> n = note.Note('C#') >>> n2 = allGreen(n) >>> n2.style.color 'green'
>>> n2.name = 'D-' >>> n2.derivation <Derivation of <music21.note.Note D-> from <music21.note.Note C#> via 'allGreen'>