Tutorial: Use the WorkflowManager¶
The script developed in Tutorial: Use N-Grams to Find Melodic Patterns is suitable for users doing exploratory work in an interactive Python shell.
When a query becomes regularized and you want it to be easily repeatable, or if you are an application developer making a graphical interface (whether on the Web or in a desktop application) you can take advantage of a further layer of abstraction offered by our WorkflowManager.
The WorkflowManager is designed as the point of interaction for end-user applications, providing a consistent interface and reference implementations of the steps involved in all queries.
While every new query will involve modifying a portion of the run() method’s code, you may be able to re-use the existing input and output methods without change.
The WorkflowManager‘s documentation describes its functionality:
-
class
vis.workflow.WorkflowManager(pathnames)[source] Warning: The WorkflowManager is deprecated as of VIS 3.0 and will be entirely removed in VIS 4.0. Most of its functionality still works with VIS 3.0 but this is not guaranteed and it is no longer being supported in development.
Parameters: pathnames (list or tuple of string or IndexedPiece) – A list of pathnames.The
WorkflowManagerautomates several common music analysis patterns for counterpoint. Use theWorkflowManagerwith these four tasks:load(), to import pieces from symbolic data formats.run(), to perform a pre-defined analysis.output(), to output analysis results.
Before you analyze, you may wish to use these methods:
metadata(), to get or set the metadata of a specificIndexedPiecemanaged by thisWorkflowManager.settings(), to get or set a setting related to analysis (for example, whether to display the quality of intervals).
You may also treat a
WorkflowManageras a container:>>> wm = WorkflowManager(['piece1.mxl', 'piece2.krn']) >>> len(wm) 2 >>> ip = wm[1] >>> type(ip) <class 'vis.models.indexed_piece.IndexedPiece'>
Port a Query into the WorkflowManager¶
Porting an existing query to the WorkflowManager involves fitting its code into the appropriate pre-existing methods.
The load() method prepares IndexedPiece objects and metadata by loading files for analysis.
The output() method outputs query results to a variety of formats, including spreadsheets, charts, and scores.
You will not usually need to modify load(), and you may not need to modify output() either.
The majority of development work will be spent in the run() method or its related hidden methods (like the _intervs(), _inteval_ngrams(), and other methods that are included in the default WorkflowManager).
TODO: continue revising here.
When I add my new query’s logic to the run() method, I get this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def run(self):
ngram_settings = {'vertical': [0], 'n': self.settigns(None, 'n')}
ngram_freqs = []
for i, piece in enumerate(self._data):
interval_settings = {'quality': self.settings(i, 'interval quality')}
intervals = piece.get_data( \
[noterest.NoteRestIndexer, interval.HorizontalIntervalIndexer], \
interval_settings)
for part in intervals:
ngram_freqs.append( \
piece.get_data([ngram.NGramIndexer, frequency.FrequencyExperimenter], \
ngram_settings, \
[part]))
agg_p = AggregatedPieces(ind_ps)
self._result = agg_p.get_data([aggregator.ColumnAggregator], [], {}, ngram_freqs)
|
I made the following changes:
- Remove the
instructionparameter fromrun(), since there is only one experiment. - Use the
importstatements at the top of the file. - Use
self._datarather than building my own list ofIndexedPieceobjects (inenumerate()on line 5). - Set
interval_settingsper-piece, and use the value from built-inWorkflowManagersettings. - Set
nfrom the built-inWorkflowManagersettings.
I could also use the WorkflowManager.settings() method to get other settings by piece or shared across all pieces, like 'simple intervals', which tells the HorizontalIntervalIndexer whether to display all intervals as their single-octave equivalents.
To run the same analysis as in Tutorial: Use N-Grams to Find Melodic Patterns, use the WorkflowManager like this:
1 2 3 4 5 6 7 8 9 | from vis.workflow import WorkflowManager
pathnames = [list_of_pathnames]
work = WorkflowManager(pathnames)
work.load('pieces')
for i in xrange(len(work)):
work.settings(i, 'quality', True)
work.run()
work.export('CSV', 'output_filename.csv')
|
This script actually does more than the program in Tutorial: Use N-Grams to Find Melodic Patterns because export() “converts” the results to a DataFrame, sorts, and outputs the results.