analyzers Package

analyzers Package

Indexers produce an “index” of a symbolic musical score. Each index provides one type of data, and each event in can be attached to a particular moment in the original score. Some indexers produce their index directly from the score, like the NoteRestIndexer, which describes pitches. Others create new information by analyzing another index, like the IntervalIndexer, which describes harmonic intervals between two-part combinations in the score, or the FilterByRepeatIndexer, which removes consecutive identical events, leaving only the first.

Analysis modules that subclass Experimenter, by contrast, produce results that cannot be attached to a moment in a score.

Indexers work only on single IndexedPiece instances. To analyze many IndexedPiece objects together, use an experimenter with an AggregatedPieces object.

experimenter Module

This module outlines the Experimenter base class, which helps with transforming time-attached analytic information to other types.

class vis.analyzers.experimenter.Experimenter(index, settings=None)[source]

Bases: object

Run an experiment on an IndexedPiece.

Use the “Experimenter.required_indices” attribute to know which Indexer subclasses should be provided to this Experimenter’s constructor. If the list is None or [], use the “Experimenter.required_experiments” attribute to know which Experimenter should be provided to the constructor.

default_settings = None
possible_settings = []
run()[source]

Run an experiment on a piece.

Returns:The result of the experiment. Data is stored uniquely depending on the Experiment.
Return type:pandas.Series or pandas.DataFrame

indexer Module

The controllers that deal with indexing data from music21 Score objects.

class vis.analyzers.indexer.Indexer(score, settings=None)[source]

Bases: object

An object that manages creating an index of a piece, or part of a piece, based on one feature.

Use the required_score_type attribute to know what type of object is required in __init__().

The name of the indexer, as stored in the DataFrame it returns, is the module name and class name. For example, the name of the IntervalIndexer is 'interval.IntervalIndexer'.

Caution

This module underwent significant changes for release 2.0.0. In particular, the constructor’s score argument and the run() method’s return type have changed.

default_settings = {}

Described in the TemplateIndexer.

make_return(labels, indices)[source]

Prepare a properly-formatted DataFrame as should be returned by any Indexer subclass. We intend for this to be called by Indexer subclasses only.

The index of a label in labels should be the same as the index of the Series to which it corresponds in indices. For example, if indices[12] is the tuba part, then labels[12] might say 'Tuba'.

Parameters:
  • labels (list of basestring) – Indices of the parts or the part combinations, or another descriptive label as described in the indexer subclass documentation.
  • indices (list of pandas.Series.) – The results of the indexer.
Returns:

A DataFrame with the appropriate MultiIndex required by the Indexer.run() method signature.

Return type:

pandas.DataFrame

Raises:

IndexError if the number of labels and indices does not match.

possible_settings = {}

Described in the TemplateIndexer.

required_score_type = None

Described in the TemplateIndexer.

run()[source]

Make a new index of the piece.

Returns:The new indices. Refer to the section below.
Return type:pandas.DataFrame

About Return Values:

Every indexer must return a DataFrame with a special kind of MultiIndex that helps organize data across multiple indexers. Programmers making a new indexer should follow the instructions in the TemplateIndexer run() method to ensure this happens properly.

Indexers return a DataFrame where the columns are indexed on two levels: the first level is a string with the name of the indexer, and the second level is a string with the index of the part, the indices of the parts in a combination, or some other value as specified by the indexer.

This allows, for example:

>>> the_score = music21.converter.parse('sibelius_5-i.mei')
>>> the_score.parts[5]
(the first clarinet Part)
>>> the_notes = NoteRestIndexer(the_score).run()
>>> the_notes['noterest.NoteRestIndexer']['5']
(the first clarinet Series)
>>> the_intervals = IntervalIndexer(the_notes).run()
>>> the_intervals['interval.IntervalIndexer']['5,6']
(Series with vertical intervals between first and second clarinet)

This is more useful when you have a larger DataFrame with the results of multiple indexers. Refer to Indexer.combine_results() to see how that works.

>>> some_results = Indexer.combine_results([the_notes, the_intervals])
>>> some_results['noterest.NoteRestIndexer']['5']
(the first clarinet Series)
>>> some_results['interval.IntervalIndexer']['5,6']
(Series with vertical intervals between first and second clarinet)
>>> some_results.to_hdf('brahms3.h5', 'table')

After the call to to_hdf(), your results are stored in the ‘brahms3.h5’ file. When you load them (very quickly!) with the read_hdf() method, the DataFrame returns exactly as it was.

Note

In release 1.0.0, it was sometimes acceptable to use undocumented return values; from release 1.1.0, this is no longer necessary, and you should avoid it. In a future release, the IndexedPiece class will depend on indexers following these rules.

vis.analyzers.indexer.mpi_unique_offsets(streams)[source]

For a set of Stream objects, find the offsets at which events begin. Used by stream_indexer().

Parameters:streams (list of music21.stream.Stream) – A list of Stream objects in which to find the offsets where events begin.
Returns:A list of floating-point numbers representing offsets at which a new event begins in any of the Stream objects. Offsets are sorted from lowest to highest (start to end).
Return type:list of float
vis.analyzers.indexer.series_indexer(pipe_index, parts, indexer_func)[source]

Perform the indexation of a part or part combination. This is a module-level function designed to ease implementation of multiprocessing.

If your Indexer has settings, use the indexer_func() to adjust for them.

Parameters:
  • pipe_index (object) – An identifier value for use by the caller. This is returned unchanged, so a caller may use the pipe_index as a tag with which to keep track of jobs.
  • parts (list of pandas.Series) – A list of at least one Series object. Every new event, or change of simlutaneity, will appear in the outputted index. Therefore, the new index will contain at least as many events as the inputted Series with the most events. This is not a DataFrame, since each part will likely have different offsets.
  • indexer_func (function) – This function transforms found events into a unicode object.
Returns:

The pipe_index argument and the new index. The new index is a pandas.Series where every element is a unicode string. The Index of the Series corresponds to the quarterLength offset of the event in the inputted Stream.

Return type:

2-tuple of object and pandas.Series

Raises:

ValueError if there are multiple events at an offset in any of the inputted Series.

vis.analyzers.indexer.stream_indexer(pipe_index, parts, indexer_func, types=None)[source]

Perform the indexation of a Part or Part combination. This is a module-level function designed to ease implementation of multiprocessing.

If your Indexer subclass has settings, use the indexer_func() to adjust for them.

If an offset has multiple events of the correct type, only the “first” discovered results will be included in the output. This may produce misleading results when, for example, a double-stop was imported as two Note objects in the same Part, rather than as a Chord.

Parameters:
  • pipe_index (object) – An identifier value for use by the caller. This is returned unchanged, so a caller may use the pipe_index as a tag with which to keep track of jobs.
  • parts (list of music21.stream.Stream) – A list of at least one Stream object. Every new event or change of simlutaneity will appear in the outputted index. Therefore, the new index will contain at least as many events as the inputted Part with the most events.
  • indexer_func (function) – This function transforms found events into a unicode object.
  • types (list of type) – Only objects of a type in this list will be passed to the indexer_func() for inclusion in the resulting index.
Returns:

The pipe_index argument and the new index. The new index is a pandas.Series where every element is a unicode string. The Index of the Series corresponds to the quarterLength offset of the event in the inputted Stream.

Return type:

2-tuple of object and pandas.Series