Objects for processing roman numeral analysis text files, as defined and demonstrated by Dmitri Tymoczko.
RTAnalyticKey bases
RTAnalyticKey methods
Methods inherited from RTKeyTypeAtom:
Methods inherited from RTAtom:
Methods inherited from RTToken:
In RomanText, definitions of chords, phrases boundaries, open/close parenthesis, beat indicators, etc. appear within measures (RTMeasure objects). These individual elements will be called Atoms, as they are data that is not tagged.
Each atom store a reference to its container (normally an RTMeasure).
>>> chordIV = romanText.rtObjects.RTAtom('IV')
>>> beat4 = romanText.rtObjects.RTAtom('b4')
>>> beat4
<RTAtom 'b4'>
>>> beat4.isAtom()
True
However, see RTChord, RTBeat, etc. which are subclasses of RTAtom specifically for storing chords, beats, etc.
RTAtom bases
RTAtom methods
Methods inherited from RTToken:
An RTAtom subclass that defines a beat definition. Also contains a reference to the container.
>>> beatFour = romanText.rtObjects.RTBeat('b4')
>>> beatFour
<RTBeat 'b4'>
RTBeat bases
RTBeat methods
Given a time signature, return the offset position specified by this beat.
>>> rtb = romanText.rtObjects.RTBeat('b1.5')
>>> rtb.getOffset(meter.TimeSignature('3/4'))
0.5
>>> rtb.getOffset(meter.TimeSignature('6/8'))
0.75
>>> rtb.getOffset(meter.TimeSignature('2/2'))
1.0
>>> rtb = romanText.rtObjects.RTBeat('b2')
>>> rtb.getOffset(meter.TimeSignature('3/4'))
1.0
>>> rtb.getOffset(meter.TimeSignature('6/8'))
1.5
>>> rtb = romanText.rtObjects.RTBeat('b1.66')
>>> rtb.getOffset(meter.TimeSignature('6/8'))
1.0
>>> rtc = romanText.rtObjects.RTBeat('b1.66.5')
>>> rtc.getOffset(meter.TimeSignature('6/8'))
1.25
Methods inherited from RTAtom:
Methods inherited from RTToken:
An RTAtom subclass that defines a chord. Also contains a reference to the container.
>>> chordIV = romanText.rtObjects.RTChord('IV')
>>> chordIV
<RTChord 'IV'>
RTChord bases
RTChord methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
A simple close parenthesis Atom with a sensible default
>>> romanText.rtObjects.RTCloseParens(')')
<RTCloseParens ')'>
RTCloseParens bases
RTCloseParens methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTEllisonStart bases
RTEllisonStart methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTEllisonStop bases
RTEllisonStop methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
Roman Text File access.
RTFile methods
Open a file for reading, trying a variety of codecs and then trying them again with an ignore if it is not possible.
Assign a file-like object, such as those provided by StringIO, as an open file object.
Read a file. Note that this calls readstring, which processes all tokens.
If number is given, a work number will be extracted if possible.
Read a string and process all Tokens. Returns a ABCHandler instance.
RTHandler read/write properties
Get or set tokens for this Handler.
RTHandler methods
Return True if this handler has 1 or more movement.
>>> rth = romanText.rtObjects.RTHandler()
>>> rth.process('Movement: 1 \n \n m1')
>>> rth.definesMovements()
False
>>> rth.definesMovement()
True
Return True if more than one movement is defined in a RT file.
>>> rth = romanText.rtObjects.RTHandler()
>>> rth.process('Movement: 1 \n Movement: 2 \n \n m1')
>>> rth.definesMovements()
True
>>> rth.process('Movement: 1 \n m1')
>>> rth.definesMovements()
False
Given an entire specification as a single source string, strSrc, tokenize it. This is usually provided in a file.
Divide string into header and non-header; this is done before tokenization.
>>> rth = romanText.rtObjects.RTHandler()
>>> rth.splitAtHeader(['Title: s', 'Time Signature:', '', 'm1 g: i'])
(['Title: s', 'Time Signature:', ''], ['m1 g: i'])
If we have movements defined, return a list of RTHandler rtObjects, representing header information and each movement, in order.
>>> rth = romanText.rtObjects.RTHandler()
>>> rth.process('Title: Test \n Movement: 1 \n m1 \n Movement: 2 \n m1')
>>> post = rth.splitByMovement(False)
>>> len(post)
3
>>> len(post[0])
1
>>> post[0].__class__
<class 'music21.romanText.rtObjects.RTHandler'>
>>> len(post[1]), len(post[2])
(2, 2)
>>> post = rth.splitByMovement(duplicateHeader=True)
>>> len(post)
2
>>> len(post[0]), len(post[1])
(3, 3)
Walk the RT string, creating RT rtObjects along the way.
Given a line of data stored in measure consisting only of Atoms, tokenize and return a list.
>>> rth = romanText.rtObjects.RTHandler()
>>> str(rth.tokenizeAtoms('IV b3 ii7 b4 ii'))
"[<RTChord 'IV'>, <RTBeat 'b3'>, <RTChord 'ii7'>, <RTBeat 'b4'>, <RTChord 'ii'>]"
>>> str(rth.tokenizeAtoms('V7 b2 V13 b3 V7 iio6/5[no5]'))
"[<RTChord 'V7'>, <RTBeat 'b2'>, <RTChord 'V13'>, <RTBeat 'b3'>, <RTChord 'V7'>, <RTChord 'iio6/5[no5]'>]"
>>> tokenList = rth.tokenizeAtoms('I b2 I b2.25 V/ii b2.5 bVII b2.75 V g: IV')
>>> str(tokenList)
"[<RTChord 'I'>, <RTBeat 'b2'>, <RTChord 'I'>, <RTBeat 'b2.25'>, <RTChord 'V/ii'>, <RTBeat 'b2.5'>, <RTChord 'bVII'>, <RTBeat 'b2.75'>, <RTChord 'V'>, <RTAnalyticKey 'g:'>, <RTChord 'IV'>]"
>>> tokenList[9].getKey()
<music21.key.Key of g minor>
>>> str(rth.tokenizeAtoms('= m3'))
'[]'
>>> tokenList = rth.tokenizeAtoms('g;: ||: V b2 ?(Bb: VII7 b3 III b4 ?)Bb: i :||')
>>> str(tokenList)
"[<RTKey 'g;:'>, <RTRepeatStart '||:'>, <RTChord 'V'>, <RTBeat 'b2'>, <RTOptionalKeyOpen '?(Bb:'>, <RTChord 'VII7'>, <RTBeat 'b3'>, <RTChord 'III'>, <RTBeat 'b4'>, <RTOptionalKeyClose '?)Bb:'>, <RTChord 'i'>, <RTRepeatStop ':||'>]"
In the body, we may have measure, time signature, or note declarations, as well as possible other tagged definitions.
In the header, we only have RTTagged tokens. We can this process these all as the same class.
RTKey bases
RTKey methods
Methods inherited from RTKeyTypeAtom:
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTKeySignature bases
RTKeySignature methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTKeyTypeAtoms contain utility functions for all Key-type tokens, i.e. RTKey, RTAnalyticKey, but not KeySignature.
>>> gminor = romanText.rtObjects.RTKeyTypeAtom('g;:')
>>> gminor
<RTKeyTypeAtom 'g;:'>
RTKeyTypeAtom bases
RTKeyTypeAtom methods
This returns a Key, not a KeySignature object
Get a KeySignature object.
Methods inherited from RTAtom:
Methods inherited from RTToken:
In RomanText, measures are given one per line and always start with ‘m’.
For instance:
m4 i b3 v b4 VI m5 b2 g: IV b4 V m6 i m7 D: V
Measure ranges can be used and copied, such as:
m8-m9=m4-m5
RTMeasure objects can also define variant readings for a measure:
m1 ii m1var1 ii b2 ii6 b3 IV
Variants are not part of the tag, but are read into an attribute.
Endings are indicated by a single letter after the measure number, such as “a” for first ending.
>>> rtm = romanText.rtObjects.RTMeasure('m15a V6 b1.5 V6/5 b2 I b3 viio6')
>>> rtm.data
'V6 b1.5 V6/5 b2 I b3 viio6'
>>> rtm.number
[15]
>>> rtm.repeatLetter
['a']
>>> rtm.isMeasure()
True
RTMeasure bases
RTMeasure methods
If this measure defines a copy operation, return two lists defining the measures to copy; the second list has the repeat data.
>>> rtm = romanText.rtObjects.RTMeasure('m35-36 = m29-30')
>>> rtm.number
[35, 36]
>>> rtm.getCopyTarget()
([29, 30], ['', ''])
>>> rtm = romanText.rtObjects.RTMeasure('m4 = m1')
>>> rtm.number
[4]
>>> rtm.getCopyTarget()
([1], [''])
Methods inherited from RTToken:
An RTAtom subclass that defines absence of a chord. Also contains a reference to the container.
>>> chordNC = romanText.rtObjects.RTNoChord('NC')
>>> chordNC
<RTNoChord 'NC'>
RTNoChord bases
RTNoChord methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
A simple open parenthesis Atom with a sensible default
>>> romanText.rtObjects.RTOpenParens('(')
<RTOpenParens '('>
RTOpenParens bases
RTOpenParens methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTOptionalKeyClose bases
RTOptionalKeyClose methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTOptionalKeyOpen bases
RTOptionalKeyOpen methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTPhraseBoundary bases
RTPhraseBoundary methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
A Phrase Marker:
>>> rtpm = romanText.rtObjects.RTPhraseMarker('')
>>> rtpm
<RTPhraseMarker ''>
RTPhraseMarker bases
RTPhraseMarker methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTRepeat bases
RTRepeat methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTRepeatStart bases
RTRepeatStart methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
RTRepeatStop bases
RTRepeatStop methods
Methods inherited from RTAtom:
Methods inherited from RTToken:
In romanText, some data elements are tags, that is a tag name, a colon, optional whitespace, and data. In non-RTTagged elements, there is just data.
All tagged tokens are subclasses of this class. Examples are:
Title: Die Jahrzeiten Composer: Fanny Mendelssohn
>>> rttag = romanText.rtObjects.RTTagged('Title: Die Jahrzeiten')
>>> rttag.tag
'Title'
>>> rttag.data
'Die Jahrzeiten'
>>> rttag.isTitle()
True
>>> rttag.isComposer()
False
RTTagged bases
RTTagged methods
True if tag represents a analyst, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Analyst: This is an analyst.')
>>> tag.isAnalyst()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isAnalyst()
False
True is the tag represents a composer.
>>> rth = romanText.rtObjects.RTTagged('Composer: Claudio Monteverdi')
>>> rth.isComposer()
True
>>> rth.isTitle()
False
>>> rth.isWork()
False
>>> rth.data
'Claudio Monteverdi'
True if tag represents a form, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Form: This is a form.')
>>> tag.isForm()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isForm()
False
True if tag represents a key signature, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('KeySignature: This is a key signature.')
>>> tag.isKeySignature()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isKeySignature()
False
KeySignatures are a type of tagged data found outside of measures, such as “Key Signature: Bb,” meaning one flat.
Note: this is not the same as a key definition found inside of a Measure. These are represented by RTKey rtObjects, defined below, and are not RTTagged rtObjects, but RTAtom subclasses.
True if tag represents a movement, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Movement: This is a movement.')
>>> tag.isMovement()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isMovement()
False
True if tag represents a note, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Note: This is a note.')
>>> tag.isNote()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isNote()
False
True if tag represents a pedal, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Pedal: This is a pedal.')
>>> tag.isPedal()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isPedal()
False
True if tag represents a piece, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Piece: This is a piece.')
>>> tag.isPiece()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isPiece()
False
True if tag represents a proofreader, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Proofreader: This is a proofreader.')
>>> tag.isProofreader()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isProofreader()
False
True if tag represents a time signature, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('TimeSignature: This is a time signature.')
>>> tag.isTimeSignature()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isTimeSignature()
False
TimeSignature header data can be found intermingled with measures.
True if tag represents a title, otherwise False.
>>> tag = romanText.rtObjects.RTTagged('Title: This is a title.')
>>> tag.isTitle()
True
>>> tag = romanText.rtObjects.RTTagged('Nothing: Nothing at all.')
>>> tag.isTitle()
False
True if tag represents a work, otherwise False.
The “work” is not defined as a header tag, but is used to represent all tags, often placed after Composer, for the work or pieces designation.
>>> rth = romanText.rtObjects.RTTagged('Madrigal: 4.12')
>>> rth.isTitle()
False
>>> rth.isWork()
True
>>> rth.tag
'Madrigal'
>>> rth.data
'4.12'
Methods inherited from RTToken:
Stores each linear, logical entity of a RomanText.
A multi-pass parsing procedure is likely necessary, as RomanText permits variety of groupings and markings.
>>> rtt = romanText.rtObjects.RTToken('||:')
>>> rtt
<RTToken '||:'>
A standard RTToken returns False for all of the following.
>>> rtt.isComposer() or rtt.isTitle() or rtt.isPiece()
False
>>> rtt.isAnalyst() or rtt.isProofreader()
False
>>> rtt.isTimeSignature() or rtt.isKeySignature() or rtt.isNote()
False
>>> rtt.isForm() or rtt.isPedal() or rtt.isMeasure() or rtt.isWork()
False
>>> rtt.isMovement() or rtt.isAtom()
False
RTToken methods
Atoms are any untagged data; generally only found inside of a measure definition.
Occasionally found in header.