class maelzel.scoring.node.Node(items, ratio=(1, 1), parent=None, properties=None, measure=None, readonly=False, _duration=Fraction(0, 1))[source]

A Node is a recursive container, grouping Notations and other Nodes under one time modifier

Notations within a Node are quantized. When a measure is quantized, its contents are grouped in a tree structure made out of Nodes (see QuantizedMeasure.tree)

A Node consists of a sequence of Notations or Nodes, allowing to define nested tuplets or beats. The notations inside a Node already hold the real beat-duration. The durRatio is a ratio by which to multiply a given duration to obtain the notated duration.

A Node is used to represent the result of quantization.

Quantization happens first at the beat level and after that all quantized beats within a measure are merged together to create a tree structure spanning along the entire measure

See also

QuantizedMeasure.tree

durRatio

a tuple ``(num, den)` indication the ratio by which to multiply the duration of the items to obtain the notated items: the items inside this tree For example, a quarternote triplet would have a durRatio (3, 2) and the items inside it would have a duration of 1/3. When multiplied by the durRatio each item would have a duration of 1/2

items

the items in this tree (an item can be a Notation or a Node)

In the case of a simple triplet, the items would hold something like:

>>> from maelzel.scoring import *
>>> notations = [makeNote(60, duration=F(1, 3)),
...              makeNote(61, duration=F(2, 3))]
>>> Node(ratio=(3, 2), items=notations)
append(item)[source]

Add an item or Node to this Node

Return type:

None

static asTree(nodes, readonly=False)[source]

Transform a list of Nodes into a tree structure

A tree has a root and leaves, where each leave can be the root of a subtree

Parameters:

nodes (list[Node]) – the tree to get/make the root for

Return type:

Node

Returns:

the root of a tree structure

static beatToTree(notations, division, beatOffset, beatDur)[source]

Create a tree from a quantized beat

Parameters:
  • notations (list[Notation]) – the notations in this beat

  • division (int | tuple[int, ...]) – the division for this beat

  • beatOffset (Fraction) – the offset within the measure

  • beatDur (Fraction) – the duration of the beat

Return type:

Node

Returns:

a Node representing the tree structure of this beat

breakBeamsAt(offset)[source]

Breaks beams at the given offset

This method will not split a notation if the given offset is placed inside a syncopation

Parameters:

offset (Fraction) – the offset to break beams at

Return type:

Notation | None

Returns:

the notation at the right of the split, or None if no split was performed

static breakIrregularDurationInNode(n, beatstruct)[source]

Break irregular durations in a node

Parameters:
  • n (Notation) – the notation to break

  • beatstruct (Sequence[QuantizedBeatDef]) – the beatstructure

Return type:

list[Notation]

Returns:

the resulting notations.

dump(numindents=0, indent='  ', stream=None)[source]

Dump this node, recursively

Parameters:
  • numindents – the number of indents to use for this node

  • indent – indentation string

  • stream – the stream to dumo to

Return type:

None

empty()[source]

Is this node empty?

Return type:

bool

property end: Fraction

The end of the last item within this Node

findNextNotation(notation)[source]

Find the notation next to the given notation

Parameters:

notation (Notation) – the notation to query. The returned notation, if found, will be the notation next to this

Return type:

Notation | None

Returns:

the notation next to the given notation, or None if no notation found. The returned notation does not need to be on the same node.

findNodeForNotation(notation)[source]

Find the node of the given notation

Parameters:

notation (Notation) – the notation for which to find its node

Return type:

Node | None

Returns:

the node parent to the given notation

firstNotation()[source]

Return the first Notation of this Node (recursively)

Return type:

Notation

fixEnharmonics(options, prevTree=None)[source]

Find the best enharmonic spelling for the notations within this tree, inplace

Parameters:
  • options (EnharmonicOptions) – the enharmonic options used

  • prevTree (Optional[Node]) – the previous tree (the tree corrsponding to the previous measure), if applicable.

Return type:

None

getProperty(key, default=None)[source]

Get the value of a property for this Node

glissMarkTiedNotesAsHidden()[source]

Within a glissando, notes tied to previous and next notes can be hidden

Return type:

None

isFlat()[source]

True if self has no Nodes as children

Return type:

bool

lastNotation()[source]

Return the last Notation of this Node (recursively)

Return type:

Notation

logicalTieLocations(measureIndex=None)[source]

Like logicalTies, but for each notation returns a TreeLocation

Parameters:

measureIndex (Optional[int]) – if given, it is used to fill the .measureIndex attribute in the returned TreeLocation

Return type:

list[LogicalTie]

Returns:

a list of ties, where each tie is a list of TreeLocations

logicalTies()[source]

Iterate over all logical ties within self (recursively)

Return type:

list[list[Notation]]

Returns:

an iterator over the logical ties within self (recursively), where a logical tie is a list of Notations which are tied together

mergeWith(other, readonly=None)[source]

Merge this tree with other

It is assumed that these Nodes can merge

Parameters:

other (Node) – the other node

Return type:

Node

Returns:

the merged node / tree

mergedNotations(flatten=True)[source]

Returns a new tree with all items merged (recursively)

Parameters:

flatten – if True, superfluous children are flattened

Return type:

Node

Returns:

a new Node with merged items (whenever possible)

property offset: Fraction

The offset of this Node within the measure

property qoffset: Fraction

The offset of this Node within the measure

This is the same as .offset, since all Nodes are quantized, but it is present to match quantized Notations, where .offset can be None if they are not quantized, and .qoffset is always a F, raising an error if the Notation is not quantized

recurse(reverse=False)[source]

Iterate over the items in self, recursively

Parameters:

reverse – if True, iterate backwards

Return type:

Iterator[Notation]

Returns:

an iterator over all Notations within this Node

recurseWithNode(reverse=False)[source]

Iterate over the items if self, recursively

The same as Node.recurse() but for each item yields a tuple (notation, node) where node is the node to which the notation belongs. This is useful in order to modify the tree in the case one needs to, for example, remove a notation from its tree

Parameters:

reverse – if True, iterate in reverse

Return type:

Iterator[tuple[Notation, Node]]

Returns:

an iterator of tuples (notation, node)

removeUnnecessaryGracenotes()[source]

Removes unnecessary gracenotes

Return type:

int

Returns:

the number of modifications

An unnecessary gracenote:

  • has the same pitch as the next real note and starts a glissando. Such gracenotes might be created during quantization.

  • has the same pitch as the previous real note and ends a glissando

  • n0/real – gliss – n1/grace n2/real and n1.pitches == n2.pitches

  • has the same pitch as the previous real note and has no attribute itself

Repair ties and glissandi inplace

Return type:

int

Returns:

the number of modifications

root()[source]

Find the root of this node

Nodes are organized in tree structures. This method will climb the tree structure until the root of the tree (the node without a parent) is found

Return type:

Node

setParentRecursively()[source]

Set the parent of each Node downstream

setProperty(key, value)[source]

Set a property for this Node

Return type:

None

splitNotationAtBeat(beats, beatIndex, callback=None, repair=True)[source]

Split any notation which crosses the given beat offset, inplace

A notation will be split if it crosses the given offset. Raises SplitError if it cannot split at the given offset

Parameters:
  • beats (Sequence[QuantizedBeatDef]) – the sequence of beats in the measure where this node is defined (see QuantizedMeasure.beatStructure)

  • beatIndex (int) – the index of the beat at which to split

  • callback (Optional[Callable[[Notation, Fraction], bool]]) – if given, a function which returns True if the note should be split

Return type:

list[Notation] | None

Returns:

the parts resulting from splitting this notation at the given beat boundary, or None if no split operation was performed

splitNotationAtOffset(offset, tie=True, mergeable=True, beatstruct=None)[source]

Splits a notation present at the given offset, returns a list of parts

Assumes that the offset divides a notation within this tree. Since a tree represents a quantized structure, this split can only be performed at offsets which themselves belong to this quantization. An invalid offset will raise a ValueError exception2

Parameters:
  • offset (Fraction) – the offset to split at

  • tie – tie the resulting notations, if a notation was in fact split

  • mergeable – the split notations should be mergeable. Set it to False to avoid any future remerges

Return type:

list[Notation] | None

Returns:

the resulting notations (they can be more than one if any part results in an irregular duration). None if no need to split

symbolicDuration()[source]

The symbolic total duration of this tree.

This represents the notated figure (1=quarter, 1/2=eighth note, 1/4=16th note, etc) at the level of this node.

Return type:

Fraction

totalDuration()[source]

The duration of the items in this tree, in quarter notes (recursively)

Return type:

Fraction