analyzers Package

analyzers Package

Indexers produce an “index” of a symbolic musical score. Each index provides one type of data, and each event 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 of the 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 = []

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 six.string_types) – Indices of the parts or the part combinations, or another descriptive label as described in the indexer subclass documentation.
  • indices (list of pandas.Series or a pandas.DataFrame) – 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.series_indexer(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:
  • 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 some other string.
Returns:

The pipe_index argument and the new index. The new index is a pandas.Series where every element is a 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.