symbolic

symbolic

class pyampact.symbolic.Score(score_path)[source]

A class to import a score via music21 and expose pyAMPACT’s analysis utilities.

The analysis utilities are generally formatted as pandas dataframes. This class also ports over some matlab code to help with alignment of scores in symbolic notation and audio analysis of recordings of those scores. Score objects can insert analysis into an MEI file, and can export any type of file to a kern format, optionally also including analysis from a JSON file. Similarly, Score objects can serve clickable URLs of short excerpts of their associated score in symbolic notation. These links open in the Verovio Humdrum Viewer.

Parameters:

score_path – A string representing the path to the score file.

Returns:

A Score object.

Example

url_or_path = 'https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn'
piece = Score(url_or_path)
cdata(snap_to=None, filler='forward', output='dataframe')[source]

Get the cdata records from **cdata spines in a kern file if there are any and return it as a pandas DataFrame. This is similar to the .harm, .functions, .chords, and .keys methods, with the exception that this method defaults to returning a dataframe since there are often more than one cdata spine in a kern score. If want to get the results of a different spine type (i.e. not one of the ones listed above), see getSpines().

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.cdata()

If you want to align these results so that they match the columnar (time) axis of the pianoRoll, sampled, or mask results, you can pass the pianoRoll or mask that you want to align to as the snap_to parameter. Doing that makes it easier to combine these results with any of the pianoRoll, sampled, or mask tables to have both in a single table which can make data analysis easier. Passing a snap_to argument will automatically cause the return value to be a pandas series since that’s facilitates combining the two. Here’s how you would use the snap_to parameter and then combine the results with the pianoRoll to create a single table.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
pianoRoll = piece.pianoRoll()
cdata = piece.cdata(snap_to=pianoRoll)
combined = pd.concat((pianoRoll, cdata))

The sampled and mask dfs often have more observations than the spine contents, so you may want to fill in these new empty slots somehow. The kern format uses ‘.’ as a filler token so you can pass this as the filler parameter to fill all the new empty slots with this as well. If you choose some other value, say filler=’_’, then in addition to filling in the empty slots with underscores, this will also replace the kern ‘.’ observations with ‘_’. If you want to fill them in with NaN’s as pandas usually does, you can pass filler=’nan’ as a convenience. If you want to “forward fill” these results, you can pass filler=’forward’ (default). This will propagate the last non-period (‘.’) observation until a new one is found. Finally, you can pass filler=’drop’ to drop all empty observations (both NaNs and humdrum periods).

Parameters:
  • snap_to – A pandas DataFrame to align the results to. Default is None.

  • filler – A string representing the filler token. Default is ‘forward’.

  • output – A string representing the output format. Default is ‘array’.

Returns:

A numpy array or pandas Series representing the harmonic keys analysis.

chords(snap_to=None, filler='forward', output='array')[source]

Get the chord labels from the **chord spine in a kern file if there is one and return it as an array or a time-aligned pandas Series. This is similar to the .functions, .harm, .keys, and .cdata methods. The default is for the results to be returned as a 1-d array, but you can set output=’series’ for a pandas series instead. If want to get the results of a different spine type (i.e. not one of the ones listed above), see getSpines().

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.chords()

If you want to align these results so that they match the columnar (time) axis of the pianoRoll, sampled, or mask results, you can pass the pianoRoll or mask that you want to align to as the snap_to parameter. Doing that makes it easier to combine these results with any of the pianoRoll, sampled, or mask tables to have both in a single table which can make data analysis easier. Passing a snap_to argument will automatically cause the return value to be a pandas series since that’s facilitates combining the two. Here’s how you would use the snap_to parameter and then combine the results with the pianoRoll to create a single table.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
pianoRoll = piece.pianoRoll()
chords = piece.chords(snap_to=pianoRoll)
combined = pd.concat((pianoRoll, chords))

The sampled and mask dfs often have more observations than the spine contents, so you may want to fill in these new empty slots somehow. The kern format uses ‘.’ as a filler token so you can pass this as the filler parameter to fill all the new empty slots with this as well. If you choose some other value, say filler=’_’, then in addition to filling in the empty slots with underscores, this will also replace the kern ‘.’ observations with ‘_’. If you want to fill them in with NaN’s as pandas usually does, you can pass filler=’nan’ as a convenience. If you want to “forward fill” these results, you can pass filler=’forward’ (default). This will propagate the last non-period (‘.’) observation until a new one is found. Finally, you can pass filler=’drop’ to drop all empty observations (both NaNs and humdrum periods).

Parameters:
  • snap_to – A pandas DataFrame to align the results to. Default is None.

  • filler – A string representing the filler token. Default is ‘forward’.

  • output – A string representing the output format. Default is ‘array’.

Returns:

A numpy array or pandas Series representing the harmonic keys analysis.

contextualize(df, offsets=True, measures=True, beats=True)[source]

Add measure and beat numbers to a DataFrame.

Parameters:
  • df – A DataFrame to which to add measure and beat numbers.

  • measures – Boolean, default True. If True, measure numbers will be added.

  • beats – Boolean, default True. If True, beat numbers will be added.

Returns:

A DataFrame with measure and beat numbers added.

dez(path='')[source]

Get the labels data from a .dez file/url and return it as a dataframe. Calls fromJSON to do this. The “meta” portion of the dez file is ignored. If no path is provided, the last dez table imported with this method is returned.

Parameters:

path – A string representing the path to the .dez file.

Returns:

A pandas DataFrame representing the labels in the .dez file.

durations(multi_index=False, df=None)[source]

Return a DataFrame of durations of note and rest objects in the piece.

If a DataFrame is provided as df, the method calculates the difference between cell offsets per column in the passed DataFrame, skipping memoization.

Parameters:
  • multi_index – Boolean, default False. If True, the returned DataFrame will have a MultiIndex.

  • df – Optional DataFrame. If provided, the method calculates the difference between cell offsets per column in this DataFrame.

Returns:

A DataFrame of durations of note and rest objects in the piece.

See also

notes()

Return a DataFrame of the notes and rests given in American Standard Pitch Notation

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.durations()
dynamics()[source]

Extract the dynamics from the score.

The dynamics are extracted from each part and returned as a pandas DataFrame where each column represents a part and each row represents a dynamic marking. The DataFrame is indexed by the offset of the dynamic markings.

Returns:

A pandas DataFrame representing the dynamics in the score.

See also

lyrics()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.dynamics()
form(snap_to=None, filler='forward', output='array', dez_path='')[source]

Get the “Structure” labels from a .dez file/url and return it as an array or a time-aligned pandas Series. The default is for the results to be returned as a 1-d array, but you can set output=’series’ for a pandas series instead. If you want to align these results so that they match the columnar (time) axis of the pianoRoll, sampled, or mask results, you can pass the pianoRoll or mask that you want to align to as the snap_to parameter. Doing that makes it easier to combine these results with any of the pianoRoll, sampled, or mask tables to have both in a single table which can make data analysis easier. This example shows how to get the form analysis from a .dez file.

Example

piece = Score('test_files/K279-1.krn')
form = piece.form(dez_path='test_files/K279-1_harmony_texture.dez')
functions(snap_to=None, filler='forward', output='array')[source]

Get the harmonic function labels from a **function spine in a kern file if there is one and return it as an array or a time-aligned pandas Series. This is similar to the .harm, .keys, .chords, and .cdata methods. The default is for the results to be returned as a 1-d array, but you can set output=’series’ for a pandas series instead. If want to get the results of a different spine type (i.e. not one of the ones listed above), see getSpines().

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.functions()

If you want to align these results so that they match the columnar (time) axis of the pianoRoll, sampled, or mask results, you can pass the pianoRoll or mask that you want to align to as the snap_to parameter. Doing that makes it easier to combine these results with any of the pianoRoll, sampled, or mask tables to have both in a single table which can make data analysis easier. Passing a snap_to argument will automatically cause the return value to be a pandas series since that’s facilitates combining the two. Here’s how you would use the snap_to parameter and then combine the results with the pianoRoll to create a single table.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
pianoRoll = piece.pianoRoll()
functions = piece.functions(snap_to=pianoRoll)
combined = pd.concat((pianoRoll, functions))

The sampled and mask dfs often have more observations than the spine contents, so you may want to fill in these new empty slots somehow. The kern format uses ‘.’ as a filler token so you can pass this as the filler parameter to fill all the new empty slots with this as well. If you choose some other value, say filler=’_’, then in addition to filling in the empty slots with underscores, this will also replace the kern ‘.’ observations with ‘_’. If you want to fill them in with NaN’s as pandas usually does, you can pass filler=’nan’ as a convenience. If you want to “forward fill” these results, you can pass filler=’forward’ (default). This will propagate the last non-period (‘.’) observation until a new one is found. Finally, you can pass filler=’drop’ to drop all empty observations (both NaNs and humdrum periods).

Parameters:
  • snap_to – A pandas DataFrame to align the results to. Default is None.

  • filler – A string representing the filler token. Default is ‘forward’.

  • output – A string representing the output format. Default is ‘array’.

Returns:

A numpy array or pandas Series representing the harmonic keys analysis.

getSpines(spineType)[source]

Return a pandas DataFrame of a less common spine type. This method is a window into the vast ecosystem of Humdrum tools making them accessible to pyAMPACT.

Parameters:

spineType – A string representing the spine type to return. You can pass the spine type with or without the “**” prefix.

Returns:

A pandas DataFrame of the given spine type.

Similar to the .harm, .keys, .functions, .chords, and .cdata methods, this method returns the contents of a specific spine type from a kern file. This is a generic method that can be used to get the contents of any spine type other than: **kern, **dynam, **text, **cdata, **chord, **harm, or **function. Many of the other spine types that you may be interested provide partwise data. For example, the results of Humlib’s Renaissance dissonance analysis are given as one “**cdata-rdiss” spine per part. Note that a **cdata-rdiss spine is not the same as a **cdata spine. This is why we return a DataFrame rather than an array or series. If there is just one spine of the spine type you request, the data will still be given as a 1-column dataframe. When you import a kern file, it automatically gets scanned for other spine types and if any are found you can see them with the foundSpines attribute.

This example takes a score with **cdata-rdiss spines (Renaissance dissonance analysis), and makes a DataFrame of just the **cdata-rdiss spines. The full score with color-coded dissonance labels can be seen on the Verovio Humdrum Viewer here.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/O_Virgo_Miserere.krn')
rdiss = piece.getSpines('cdata-rdiss')
harm(snap_to=None, filler='forward', output='array')[source]

Get the harmonic analysis portion of the **harm spine in a kern file if there is one and return it as an array or a time-aligned pandas Series. The prevailing key signature information is not included here from the harm spine, but that key information is available in the .keys method. This is similar to the .keys, .functions, .chords, and .cdata methods. The default is for the results to be returned as a 1-d array, but you can set output=’series’ for a pandas series instead which is helpful if you’re going to concatenate the results to a dataframe. If want to get the results of a different spine type (i.e. not one of the ones listed above), see getSpines().

If you want to align these results so that they match the columnar (time) axis of the pianoRoll, sampled, or mask results, you can pass the pianoRoll or mask that you want to align to as the snap_to parameter. Doing that makes it easier to combine these results with any of the pianoRoll, sampled, or mask tables to have both in a single table which can make data analysis easier. Passing a snap_to argument will automatically cause the return value to be a pandas series since that’s facilitates combining the two. Here’s how you would use the snap_to parameter and then combine the results with the pianoRoll to create a single table.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
pianoRoll = piece.pianoRoll()
harm = piece.harm(snap_to=pianoRoll, output='series')
combined = pd.concat((pianoRoll, harm))

The sampled and mask dfs often have more observations than the spine contents, so you may want to fill in these new empty slots somehow. The kern format uses ‘.’ as a filler token so you can pass this as the filler parameter to fill all the new empty slots with this as well. If you choose some other value, say filler=’_’, then in addition to filling in the empty slots with underscores, this will also replace the kern ‘.’ observations with ‘_’. If you want to fill them in with NaN’s as pandas usually does, you can pass filler=’nan’ as a convenience. If you want to “forward fill” these results, you can pass filler=’forward’ (default). This will propagate the last non-period (‘.’) observation until a new one is found. Finally, you can pass filler=’drop’ to drop all empty observations (both NaNs and humdrum periods).

Parameters:
  • snap_to – A pandas DataFrame to align the results to. Default is None.

  • filler – A string representing the filler token. Default is ‘forward’.

  • output – A string representing the output format. Default is ‘array’.

Returns:

A numpy array or pandas Series representing the harmonic keys analysis.

insertAudioAnalysis(output_filename, data, mimetype='', target='', mei_tree=None)[source]

Insert a <performance> element into the MEI score given the analysis data (data) in the format of a json file or an nmat dictionary with audio data already included. If the original score is not an MEI file, a new MEI file will be created and used. The JSON data will be extracted via the .nmats() method. If provided, the mimetype and target get passed as attributes to the <avFile> element. The performance element will nest the DataFrame data in the <performance> element as a child of <music> and a sibling of <body>. A new file will be saved to the output_filename in the current working directory.

<music>
    <performance xml:id="pyAMPACT-1">
        <recording xml:id="pyAMPACT-2">
            <avFile mimetype="audio/aiff" target="song.wav" xml:id="pyAMPACT-3" />
            <when absolute="00:00:12:428" xml:id="pyAMPACT-4" data="#note_1">
                <extData xml:id="pyAMPACT-5">
                    <![CDATA[>
                        {"ppitch":221.30926295063591, "jitter":0.7427361, ...}
                    ]]>
                </extData>
            </when>
            <when absolute="00:00:12:765" xml:id="pyAMPACT-6" data="#note_2">
            ...
        </recording>
    </performance>
    <body>
        ...
    </body>
</music>
Parameters:
  • output_filename – The name of the output file.

  • data – Path to a JSON file containing analysis data or an nmats dictionary.

  • mimetype – Optional MIME type to be set as an attribute to the <avFile> element.

  • target – Optional target to be set as an attribute to the <avFile> element.

  • mei_tree – Optional ElementTree object to use as the base for the new file. If this is not passed, then the original MEI file is used if the Score is an MEI file. Otherwise a new MEI file is created with .toMEI().

Returns:

None but a new file is written

See also

nmats(), toKern(), toMEI()

Example

piece = Score('./test_files/CloseToYou.mei.xml')
piece.insertAudioAnalysis(output_filename='newfile.mei.xml'
    data='./test_files/CloseToYou.json',
    mimetype='audio/aiff',
    target='Close to You vocals.wav')
insertScoreDef(root)[source]

Insert a scoreDef element into an MEI (Music Encoding Initiative) document.

This function inserts a scoreDef element into an MEI document if one is not already present. It modifies the input element in-place.

Parameters:

root – An xml.etree.ElementTree.Element representing the root of the MEI document.

Returns:

None

jsonCDATA(json_path)[source]

Return a dictionary of pandas DataFrames, one for each voice. These DataFrames contain the cdata from the JSON file designated in json_path with each nested key in the JSON object becoming a column name in the DataFrame. The outermost keys of the JSON cdata will become the “absolute” column. While the columns are different, there are as many rows in these DataFrames as there are in those of the nmats DataFrames for each voice.

Parameters:

json_path – Path to a JSON file containing cdata.

Returns:

A dictionary of pandas DataFrames, one for each voice.

See also

fromJSON(), insertAudioAnalysis(), nmats(), xmlIDs()

Example

piece = Score('./test_files/CloseToYou.mei.xml')
piece.jsonCDATA(json_path='./test_files/CloseToYou.json')
kernNotes()[source]

Return a DataFrame of the notes and rests given in kern notation.

This is not the same as creating a kern format of a score, but is an important step in that process.

Returns:

A DataFrame of notes and rests in kern notation.

See also

meth:

midiPitches

notes()

Return a DataFrame of the notes and rests given in American Standard Pitch Notation

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.kernNotes()
keys(snap_to=None, filler='forward', output='array')[source]

Get the key signature portion of the **harm spine in a kern file if there is one and return it as an array or a time-aligned pandas Series. This is similar to the .harm, .functions, .chords, and .cdata methods. The default is for the results to be returned as a 1-d array, but you can set output=’series’ for a pandas series instead. If want to get the results of a different spine type (i.e. not one of the ones listed above), see getSpines().

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.keys()

If you want to align these results so that they match the columnar (time) axis of the pianoRoll, sampled, or mask results, you can pass the pianoRoll or mask that you want to align to as the snap_to parameter. Doing that makes it easier to combine these results with any of the pianoRoll, sampled, or mask tables to have both in a single table which can make data analysis easier. Passing a snap_to argument will automatically cause the return value to be a pandas series since that’s facilitates combining the two. Here’s how you would use the snap_to parameter and then combine the results with the pianoRoll to create a single table.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
pianoRoll = piece.pianoRoll()
keys = piece.keys(snap_to=pianoRoll)
combined = pd.concat((pianoRoll, keys))

The sampled and mask dfs often have more observations than the spine contents, so you may want to fill in these new empty slots somehow. The kern format uses ‘.’ as a filler token so you can pass this as the filler parameter to fill all the new empty slots with this as well. If you choose some other value, say filler=’_’, then in addition to filling in the empty slots with underscores, this will also replace the kern ‘.’ observations with ‘_’. If you want to fill them in with NaN’s as pandas usually does, you can pass filler=’nan’ as a convenience. If you want to “forward fill” these results, you can pass filler=’forward’ (default). This will propagate the last non-period (‘.’) observation until a new one is found. Finally, you can pass filler=’drop’ to drop all empty observations (both NaNs and humdrum periods).

Parameters:
  • snap_to – A pandas DataFrame to align the results to. Default is None.

  • filler – A string representing the filler token. Default is ‘forward’.

  • output – A string representing the output format. Default is ‘array’.

Returns:

A numpy array or pandas Series representing the harmonic keys analysis.

lyrics(strip=True)[source]

Extract the lyrics from the score.

The lyrics are extracted from each part and returned as a pandas DataFrame where each column represents a part and each row represents a lyric. The DataFrame is indexed by the offset of the lyrics.

Parameters:

strip – Boolean, default True. If True, the method will strip leading and trailing whitespace from the lyrics.

Returns:

A pandas DataFrame representing the lyrics in the score.

See also

dynamics()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/Busnoys_In_hydraulis.krn')
piece.lyrics()
mask(winms=100, sample_rate=2000, num_harmonics=1, width=0, bpm=60, aFreq=440, base_note=0, tuning_factor=1, obs=20)[source]

Construct a mask from the sampled piano roll using width and harmonics. This builds on the intermediate representations of the pianoRoll and sampled methods. The sampled method already put the x-axis (columns) in regular time intervals. The mask keeps these columns and then alters the y-axis (rows) into frequency bins. The number of bins is determined by the winms and sample_rate values, and is equal to some power of 2 plus 1. The frequency bins serve to “blur” the sampled pitch data that we expect from the score. This allows us to detect real performed sounds in audio recordings that are likely slightly above or below the precise notated pitches. The mask is what allows pyAMPACT to connect symbolic events in a score to observed sounds in an audio recording. Increasing the num_harmonics will also include that many harmonics of a notated score pitch in the mask. Note that the first harmonic is the fundamental frequency which is why the num_harmonics parameter defaults to 1. The width parameter controls how broad or “blurry” the mask is compared to the notated score.

Parameters:
  • winms – Integer, default 100. The window size in milliseconds.

  • sample_rate – Integer, default 2000. The sample rate in Hz.

  • num_harmonics – Integer, default 1. The number of harmonics to use.

  • width – Integer, default 0. The width of the mask.

  • bpm – Integer, default 60. The beats per minute to use for sampling.

  • aFreq – Integer, default 440. The frequency of A4 in Hz.

  • base_note – Integer, default 0. The base MIDI note to use.

  • tuning_factor – Float, default 1. The tuning factor to use.

  • obs – Integer, default 20. The desired observations per second.

Returns:

A DataFrame representing the mask. Each row corresponds to a frequency bin, and each column corresponds to a timepoint in the sampled score. The values are 1 for a note onset and 0 otherwise.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.mask()
midiPitches(multi_index=False)[source]

Return a DataFrame of notes and rests as MIDI pitches.

MIDI does not have a representation for rests, so -1 is used as a placeholder.

Parameters:

multi_index – Boolean, default False. If True, the returned DataFrame will have a MultiIndex.

Returns:

A DataFrame of notes and rests as MIDI pitches. Rests are represented as -1.

See also

kernNotes()

Return a DataFrame of the notes and rests given in kern notation.

notes()

Return a DataFrame of the notes and rests given in American Standard Pitch Notation

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.midiPitches()
nmats(json_path=None, include_cdata=False)[source]

Return a dictionary of DataFrames, one for each voice, with information about the notes and rests in that voice.

Each DataFrame has the following columns:

MEASURE ONSET DURATION PART MIDI ONSET_SEC OFFSET_SEC

In the MIDI column, notes are represented with their MIDI pitch numbers (0 to 127), and rests are represented with -1s. The ONSET_SEC and OFFSET_SEC columns are taken from the audio analysis from the json_path file if one is given. The XML_IDs of each note or rest serve as the index for this DataFrame. If include_cdata is True and a json_path is provided, the cdata from the json file is included in the DataFrame.

Parameters:
  • json_path – Optional path to a JSON file containing audio analysis data.

  • include_cdata – Boolean, default False. If True and a json_path is provided, the cdata from the json file is included in the DataFrame.

Returns:

A dictionary of DataFrames, one for each voice.

See also

fromJSON(), insertAudioAnalysis(), jsonCDATA(), xmlIDs()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/Mozart_K179_seg.krn')
piece.nmats()
notes(combine_rests=True, combine_unisons=False)[source]

Return a DataFrame of the notes and rests given in American Standard Pitch Notation where middle C is C4. Rests are designated with the string “r”.

If combine_rests is True (default), non-first consecutive rests will be removed, effectively combining consecutive rests in each voice. combine_unisons works the same way for consecutive attacks on the same pitch in a given voice, however, combine_unisons defaults to False.

Parameters:
  • combine_rests – Boolean, default True. If True, non-first consecutive rests will be removed.

  • combine_unisons – Boolean, default False. If True, consecutive attacks on the same pitch in a given voice will be combined.

Returns:

A DataFrame of notes and rests in American Standard Pitch Notation.

See also

kernNotes()

Return a DataFrame of the notes and rests given in kern notation.

midiPitches()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.notes()
pianoRoll()[source]

Construct a MIDI piano roll. This representation of a score plots midi pitches on the y-axis (rows) and time on the x-axis (columns). Midi pitches are given as integers from 0 to 127 inclusive, and time is given in quarter notes counting up from the beginning of the piece. At any given time in the piece (column), all the sounding pitches are shown as 1s in the corresponding rows. There is no midi representation of rests so these are not shown in the pianoRoll. Similarly, in this representation you can’t tell if a single voice is sounding a given note, of if multiple voices are sounding the same note. The end result looks like a player piano roll but 1s are used instead of holes. This method is primarily used as an intermediate step in the construction of a mask.

Note: There are 128 possible MIDI pitches.

Returns:

A DataFrame representing the MIDI piano roll. Each row corresponds to a MIDI pitch (0 to 127), and each column corresponds to an offset in the score. The values are 1 for a note onset and 0 otherwise.

See also

mask(), sampled()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.pianoRoll()
romanNumerals(snap_to=None, filler='forward', output='array', dez_path='')[source]

Get the roman numeral labels from a .dez file/url or **harm spine and return it as an array or a time-aligned pandas Series. The default is for the results to be returned as a 1-d array, but you can set output=’series’ for a pandas series instead. If you want to align these results so that they match the columnar (time) axis of the pianoRoll, sampled, or mask results, you can pass the pianoRoll or mask that you want to align to as the snap_to parameter. Doing that makes it easier to combine these results with any of the pianoRoll, sampled, or mask tables to have both in a single table which can make data analysis easier. This example shows how to get the roman numeral analysis from a kern score that has a **harm spine.

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
pianoRoll = piece.pianoRoll()
romanNumerals = piece.romanNumerals(snap_to=pianoRoll)

The next example shows how to get the roman numeral analysis from a .dez file.

Example

piece = Score('test_files/K279-1.krn')
romanNumerals = piece.romanNumerals(dez_path='test_files/K279-1_harmony_texture.dez')
sampled(bpm=60, obs=20)[source]

Sample the score according to the given beats per minute (bpm) and the desired observations per second (obs). This method is primarily used as an intermediate step in the construction of a mask. It builds on the pianoRoll by sampling the time axis (columns) at the desired rate. The result is a DataFrame where each row corresponds to a MIDI pitch (0 to 127), and each column corresponds to a timepoint in the sampled score. The difference between this and the pianoRoll is that the columns are sampled at a regular time intervals, rather than at each new event as they are in the pianoRoll.

Parameters:
  • bpm – Integer, default 60. The beats per minute to use for sampling.

  • obs – Integer, default 20. The desired observations per second.

Returns:

A DataFrame representing the sampled score. Each row corresponds to a MIDI pitch (0 to 127), and each column corresponds to a timepoint in the sampled score. The values are 1 for a note onset and 0 otherwise.

See also

mask(), pianoRoll()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.sampled()
show(start=None, stop=None)[source]

Print a VerovioHumdrumViewer link to the score in between the start and stop measures (inclusive).

Parameters:
  • start – Optional integer representing the starting measure. If start is greater than stop, they will be swapped.

  • stop – Optional integer representing the last measure.

Returns:

None but a url is printed out

See also

toKern()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.show(5, 10)
toKern(path_name='', data='', lyrics=True, dynamics=True)[source]

Create a kern representation of the score. If no path_name variable is passed, then returns a pandas DataFrame of the kern representation. Otherwise a file is created or overwritten at the path_name path. If path_name does not end in ‘.krn’ then this file extension will be added to the path. If lyrics is True (default) then the lyrics for each part will be added to the output, if there are lyrics. The same applies to dynamics.

Parameters:
  • path_name – Optional string representing the path to save the kern file.

  • data – Optional string representing the data to be converted to kern format.

  • lyrics – Boolean, default True. If True, lyrics for each part will be added.

  • dynamics – Boolean, default True. If True, dynamics for each part will be added.

Returns:

String of new kern score if no path_name is given, or None if writing the new kern file to the location of path_name

See also

show()

Example

# create a kern file from a different symbolic notation file
piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/K179.xml')
piece.toKern()
toMEI(file_name='', indentation='\t', data='', start=None, stop=None, dfs=None, analysis_tag='annot')[source]

Write or return an MEI score optionally including analysis data.

If no file_name is passed then returns a string of the MEI representation. Otherwise a file called file_name is created or overwritten in the current working directory. If file_name does not end in ‘.mei.xml’ or ‘.mei’, then the .mei.xml file extension will be added to the file_name.

Parameters:
  • file_name – Optional string representing the name to save the new MEI file to the current working directory.

  • data – Optional string of the path of score data in json format to be added to the the new mei file.

  • start – Optional integer representing the starting measure. If start is greater than stop, they will be swapped.

  • stop – Optional integer representing the last measure.

  • dfs – Optional dictionary of pandas DataFrames to be added to the new MEI file. The keys of the dictionary will be used as the @type attribute of the analysis_tag parameter element.

  • analysis_tag – Optional string representing the name of the tag to be used for the analysis data.

Returns:

String of new MEI score if no file_name is given, or None if writing the new MEI file to the current working directory.

See also

toKern()

Example

# create an MEI file from a different symbolic notation file
piece = Score('kerntest.krn')
piece.toMEI(file_name='meiFile.mei.xml')
tony(path='')[source]

Get the labels data from a .tony file/url and return it as a dataframe. Calls fromJSON to do this. The “meta” portion of the tony file is ignored. If no path is provided, the last tony table imported with this method is returned.

Parameters:

path – A string representing the path to the .tony file.

Returns:

A pandas DataFrame representing the labels in the .tony file.

xmlIDs()[source]

Return xml ids per part in a pandas.DataFrame time-aligned with the objects offset. If the file is not xml or mei, or an idString wasn’t found, return a DataFrame of the ids of the music21 objects.

Returns:

A pandas DataFrame representing the xml ids in the score.

See also

nmats()

Example

piece = Score('https://github.com/pyampact/pyAMPACTtutorials/blob/main/test_files/M025_00_01a_a.krn')
piece.xmlIDs()