Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
mrbannon committed Jan 11, 2016
2 parents b62d06f + 8e00def commit 85b44d6
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 128 deletions.
2 changes: 1 addition & 1 deletion vis/analyzers/indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def __init__(self, score, settings=None):
except KeyError:
raise TypeError(Indexer._INIT_KEY_ERR.format(self.__class__))
# if "score" is a list, check it's of the right type
if isinstance(score, list) and (req_s_type is pandas.Series or req_s_type is stream.Part):
if isinstance(score, list) and (req_s_type in (pandas.DataFrame, pandas.Series, stream.Part)):
if not all([isinstance(e, req_s_type) for e in score]):
raise TypeError(Indexer._INIT_TYPE_ERR.format(self.__class__,
self.required_score_type))
Expand Down
19 changes: 8 additions & 11 deletions vis/analyzers/indexers/dissonance.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
from numpy import nan, isnan # pylint: disable=no-name-in-module
from music21 import stream
from vis.analyzers import indexer
import pdb
import time

_d3q_label = 'Q'
_pass_dp_label = 'D'
Expand Down Expand Up @@ -70,10 +68,13 @@ class DissonanceIndexer(indexer.Indexer):
Indexer that locates vertical dissonances between pairs of voices in a piece. It then
categorizes intervals as consonant or dissonant and in the case of fourths (perfect or
augmented) and diminished fifths it examines the other parts sounding with that fourth or fifth
(if there are any) to see if the interval can be considered consonant. This analysis step can be
saved and output but currently isn't. Finally, this dissonance analysis allows for the
assignment of a dissonance type name or a consonance label for each voice at each offset. This
last step is the DataFrame that gets returned.
(if there are any) to see if the interval can be considered consonant. This dissonance analysis
allows for the assignment of a dissonance type name or a consonance label for each voice at
each offset. This last step is the DataFrame that gets returned.
The score type must be a list of dataframes of the results of the following indexers (order
matters): horizontal, duration, beatstrength, vertical.
"""
required_score_type = 'pandas.DataFrame'

Expand All @@ -89,6 +90,7 @@ def __init__(self, score, settings=None):
:raises: :exc:`RuntimeError` if ``score`` is not a list of the same types.
"""
super(DissonanceIndexer, self).__init__(score)
self._score = pandas.concat(score, axis=1)

def _set_horiz_invl(self, indx, col_indx):
"""
Expand Down Expand Up @@ -893,7 +895,6 @@ def run(self):

diss_ints = self._score[int_ind].copy(deep=True)
simuls = diss_ints.ffill()
t1 = time.clock()

iterables = [[diss_types], self._score[dur_ind].columns]
d_types_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
Expand Down Expand Up @@ -948,8 +949,4 @@ def run(self):
if passable:
ret.iat[ndx, unknowns[1][x]] = _only_diss_w_diss

t2 = time.clock()
# print 'Time to analyze dissonances: ' + str(t2-t1)

# print ret['dissonance.DissonanceIndexer'].stack().value_counts()
return ret
218 changes: 110 additions & 108 deletions vis/scripts/Dissonance_Test_Script.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,127 +26,129 @@ def main():
#piece_path = '/home/amor/Code/vis-framework/vis/tests/corpus/Jos2308.mei'
# piece_path = '/home/amor/Code/vis-framework/vis/tests/corpus/Sanctus.krn'
ind_piece = IndexedPiece(piece_path)

test_piece = ind_piece._import_score()
test_parts = test_piece.parts

# bwv603 = converter.parse(os.path.join(VIS_PATH, 'tests', 'corpus/bwv603.xml'))
# test_part = [bwv603.parts[0], bwv603.parts[1], bwv603.parts[2], bwv603.parts[3]]

setts = {'quality': True, 'simple or compound': 'simple'}
horiz_setts = {'quality': False, 'simple or compound': 'compound'}

actual = ind_piece.get_data([noterest.NoteRestIndexer]) #dur_indexer.run()['metre.DurationIndexer']
t0 = time.time()
actual = ind_piece.get_data([noterest.NoteRestIndexer])

filter_setts = {'quarterLength': 2.0, 'method':None}
filtered_results = offset.FilterByOffsetIndexer(actual, filter_setts).run()
pdb.set_trace()

# filter_setts = {'quarterLength': 2.0, 'method':None}
# filtered_results = offset.FilterByOffsetIndexer(actual, filter_setts).run()
# pdb.set_trace()
dur_ind = metre.DurationIndexer(test_parts).run()
bs_ind = metre.NoteBeatStrengthIndexer(test_parts).run()
horiz = interval.HorizontalIntervalIndexer(actual, horiz_setts).run()
vert_ints = interval.IntervalIndexer(actual, setts).run()

t0 = time.time()
actual2 = actual.T
# actual = ind_piece.get_data([noterest.NoteRestIndexer]) #dur_indexer.run()['metre.DurationIndexer']
# actual = ind_piece.get_data([metre.NoteBeatStrengthIndexer]) #dur_indexer.run()['metre.DurationIndexer']
t1 = time.time()
print 'Noterest Indexer Runtime: ' + str(t1-t0)
pdb.set_trace()
# actual2 = actual.T
# # actual = ind_piece.get_data([noterest.NoteRestIndexer]) #dur_indexer.run()['metre.DurationIndexer']
# # actual = ind_piece.get_data([metre.NoteBeatStrengthIndexer]) #dur_indexer.run()['metre.DurationIndexer']
# t1 = time.time()
# print 'Noterest Indexer Runtime: ' + str(t1-t0)
# pdb.set_trace()




# basic1 = time.time()
# parts_fm = []
# parts_nr = []
# # parts_dur = []
# parts_bs = []
# parts_ms = []
# test_piece = converter.parse(piece_path)
# part_numbers = range(len(test_piece.parts))
# from vis.analyzers.indexers.noterest import indexer_func as nr_ind_func
# from vis.analyzers.indexers.metre import duration_ind_func as dur_ind_func
# from vis.analyzers.indexers.metre import beatstrength_ind_func as bs_ind_func
# from vis.analyzers.indexers.fermata import indexer_func as fm_ind_func
# for x in part_numbers:
# temp_part = test_piece.parts[x]
# fm = []
# fermata_index = []
# nr = []
# # dur = []
# bs = []
# part_index = []
# ms = []
# measure_index = []
# for event in temp_part.recurse():
# # pdb.set_trace()
# if 'GeneralNote' in event.classes:
# found_fm = False
# for expression in event.expressions:
# if isinstance(expression, expressions.Fermata):
# fm.append('Fermata')
# found_fm = True
# break
# if not found_fm:
# fm.append(nan)
# # fm.append(fm_ind_func((event,)))
# for y in event.contextSites():
# if y[0] is temp_part:
# fermata_index.append(y[1])
# if hasattr(event, 'tie') and event.tie is not None and event.tie.type in ('stop', 'continue'):
# # dur[-1] += event.quarterLength
# continue
# nr.append(nr_ind_func((event,)))
# part_index.append(fermata_index[-1])
# # dur.append(dur_ind_func((event,)))
# bs.append(event.beatStrength)
# bs.append(bs_ind_func((event,)))
# elif 'Measure' in event.classes:
# ms.append(event.measureNumber)
# measure_index.append(event.offset)

basic1 = time.clock()
parts_fm = []
parts_nr = []
parts_dur = []
parts_bs = []
parts_ms = []
test_piece = converter.parse(piece_path)
part_numbers = range(len(test_piece.parts))
from vis.analyzers.indexers.noterest import indexer_func as nr_ind_func
from vis.analyzers.indexers.metre import duration_ind_func as dur_ind_func
from vis.analyzers.indexers.metre import beatstrength_ind_func as bs_ind_func
from vis.analyzers.indexers.fermata import indexer_func as fm_ind_func
for x in part_numbers:
temp_part = test_piece.parts[x]
fm = []
fermata_index = []
nr = []
# dur = []
bs = []
part_index = []
ms = []
measure_index = []
for event in temp_part.recurse():
# pdb.set_trace()
if 'GeneralNote' in event.classes:
found_fm = False
for expression in event.expressions:
if isinstance(expression, expressions.Fermata):
fm.append('Fermata')
found_fm = True
break
if not found_fm:
fm.append(nan)
# fm.append(fm_ind_func((event,)))
for y in event.contextSites():
if y[0] is temp_part:
fermata_index.append(y[1])
if hasattr(event, 'tie') and event.tie is not None and event.tie.type in ('stop', 'continue'):
# dur[-1] += event.quarterLength
continue
nr.append(nr_ind_func((event,)))
part_index.append(fermata_index[-1])
# dur.append(dur_ind_func((event,)))
bs.append(event.beatStrength)
# bs.append(bs_ind_func((event,)))
elif 'Measure' in event.classes:
ms.append(event.measureNumber)
measure_index.append(event.offset)

parts_nr.append(pandas.Series(nr, index=part_index))
# parts_dur.append(pandas.Series(dur, index=part_index))
parts_bs.append(pandas.Series(bs, index=part_index))
parts_ms.append(pandas.Series(ms, index=measure_index))
parts_fm.append(pandas.Series(fm, index=fermata_index))

basic_nr = pandas.concat([s for s in parts_nr], axis=1)
# basic_dur = pandas.concat([s for s in parts_dur], axis=1)
basic_bs = pandas.concat([s for s in parts_bs], axis=1)
basic_ms = pandas.concat([s for s in parts_ms], axis=1)
basic_fm = pandas.concat([s for s in parts_fm], axis=1)
# parts_nr.append(pandas.Series(nr, index=part_index))
# # parts_dur.append(pandas.Series(dur, index=part_index))
# parts_bs.append(pandas.Series(bs, index=part_index))
# parts_ms.append(pandas.Series(ms, index=measure_index))
# parts_fm.append(pandas.Series(fm, index=fermata_index))

# basic_nr = pandas.concat([s for s in parts_nr], axis=1)
# # basic_dur = pandas.concat([s for s in parts_dur], axis=1)
# basic_bs = pandas.concat([s for s in parts_bs], axis=1)
# basic_ms = pandas.concat([s for s in parts_ms], axis=1)
# basic_fm = pandas.concat([s for s in parts_fm], axis=1)

part_strings = []
for num in part_numbers:
part_strings.append(str(num))
# part_strings = []
# for num in part_numbers:
# part_strings.append(str(num))

iterables = [['basic.NoteRestIndexer'], part_strings]
basic_nr_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
basic_nr.columns = basic_nr_multi_index
# iterables = [['basic.NoteRestIndexer'], part_strings]
# basic_nr_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
# basic_nr.columns = basic_nr_multi_index

# iterables = [['basic.DurationIndexer'], part_strings]
# basic_dur_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
# basic_dur.columns = basic_dur_multi_index
# # iterables = [['basic.DurationIndexer'], part_strings]
# # basic_dur_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
# # basic_dur.columns = basic_dur_multi_index

iterables = [['basic.NoteBeatStrengthIndexer'], part_strings]
basic_bs_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
basic_bs.columns = basic_bs_multi_index
# iterables = [['basic.NoteBeatStrengthIndexer'], part_strings]
# basic_bs_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
# basic_bs.columns = basic_bs_multi_index

iterables = [['basic.MeasureIndexer'], part_strings]
basic_ms_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
basic_ms.columns = basic_ms_multi_index
# iterables = [['basic.MeasureIndexer'], part_strings]
# basic_ms_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
# basic_ms.columns = basic_ms_multi_index

iterables = [['fermata.FermataIndexer'], part_strings]
basic_fm_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
basic_fm.columns = basic_fm_multi_index
# iterables = [['fermata.FermataIndexer'], part_strings]
# basic_fm_multi_index = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
# basic_fm.columns = basic_fm_multi_index


basic2 = time.clock()
print 'Basic-Indexer Runtime: ' + str(basic2 - basic1)
# basic2 = time.time()
# print 'Basic-Indexer Runtime: ' + str(basic2 - basic1)


horiz = interval.HorizontalIntervalIndexer(basic_nr, horiz_setts).run()
vert_ints = interval.IntervalIndexer(basic_nr, setts).run()
dissonances = dissonance.DissonanceIndexer(pandas.concat([horiz, basic_dur, basic_bs, vert_ints], axis=1)).run()
# horiz = interval.HorizontalIntervalIndexer(basic_nr, horiz_setts).run()
# vert_ints = interval.IntervalIndexer(basic_nr, setts).run()
dissonances = dissonance.DissonanceIndexer([horiz, dur_ind, bs_ind, vert_ints]).run()



Expand All @@ -157,22 +159,22 @@ def main():
pdb.set_trace()


t2 = time.time()
# t2 = time.time()

workm = WorkflowManager([piece_path])
workm.settings(None, 'voice combinations', '[[0, 1]]')
workm.settings(None, 'count frequency', False)
# workm = WorkflowManager([piece_path])
# workm.settings(None, 'voice combinations', '[[0, 1]]')
# workm.settings(None, 'count frequency', False)

iterables = [[''], basic_nr['basic.NoteRestIndexer'].columns]
d_types_multi_index_for_LilyPond = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
dissonances.columns = d_types_multi_index_for_LilyPond
# iterables = [[''], basic_nr['basic.NoteRestIndexer'].columns]
# d_types_multi_index_for_LilyPond = pandas.MultiIndex.from_product(iterables, names = ['Indexer', 'Parts'])
# dissonances.columns = d_types_multi_index_for_LilyPond

workm._result = [dissonances]
workm.output('LilyPond', '/Users/amor/Documents/Code/VIS/test_output/combined_dissonances')
# workm._result = [dissonances]
# workm.output('LilyPond', '/Users/amor/Documents/Code/VIS/test_output/combined_dissonances')

t3 = time.time()
print 'Time to produce score output: '
print t3 - t2
# t3 = time.time()
# print 'Time to produce score output: '
# print t3 - t2

if __name__ == "__main__":
main()
Expand Down
6 changes: 0 additions & 6 deletions vis/tests/test_dissonance_indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ def test_diss_indexer_is_passing_1a(self):
Check that (False,) is returned whenprevious_event is None.
"""
in_dfs = [qh_b_df, qh_dur_df, qh_h_df, asc_q_v_df]
in_dfs = pd.concat(in_dfs, axis=1)
expected = (False,)
init = dissonance.DissonanceIndexer(in_dfs)
actual = init._is_passing_or_neigh('dummy', 'dummy', 'dummy', None)
Expand All @@ -156,7 +155,6 @@ def test_diss_indexer_is_passing_1b(self):
Check that (False,) is returned when previous_event is not in dissonance._consonances.
"""
in_dfs = [qh_b_df, qh_dur_df, qh_h_df, asc_q_v_df]
in_dfs = pd.concat(in_dfs, axis=1)
expected = (False,)
init = dissonance.DissonanceIndexer(in_dfs)
actual = init._is_passing_or_neigh(1, '0,1', 'M2', 'm2')
Expand All @@ -167,7 +165,6 @@ def test_diss_indexer_is_passing_2a(self):
Detection of rising passing tone in quarter notes.
"""
in_dfs = [qh_b_df, qh_dur_df, qh_h_df, asc_q_v_df]
in_dfs = pd.concat(in_dfs, axis=1)
expected = (True, '0', dissonance._pass_rp_label, '1', dissonance._no_diss_label)
init = dissonance.DissonanceIndexer(in_dfs)
actual = init._is_passing_or_neigh(1, '0,1', 'M2', 'P1')
Expand All @@ -178,7 +175,6 @@ def test_diss_indexer_is_passing_2b(self):
Detection of rising passing tone in quarter notes.
"""
in_dfs = [hq_b_df, hq_dur_df, hdescq_h_df, asc_q_v_df]
in_dfs = pd.concat(in_dfs, axis=1)
expected = (True, '0', dissonance._no_diss_label, '1', dissonance._pass_dp_label)
init = dissonance.DissonanceIndexer(in_dfs)
actual = init._is_passing_or_neigh(1, '0,1', 'M2', 'P1')
Expand All @@ -189,7 +185,6 @@ def test_diss_indexer_run_1a(self):
Detection of two rising passing tones in a mini-piece.
"""
in_dfs = [qh_b_df, qh_dur_df, qh_h_df, asc_q_v_df]
in_dfs = pd.concat(in_dfs, axis=1)
expected = empty_df.copy()
expected.iat[1, 0] = 'R'
expected.iat[3, 0] = 'R'
Expand All @@ -202,7 +197,6 @@ def test_diss_indexer_run_1b(self):
though the passing tones are descending because the passing tones are in the lower voice
"""
in_dfs = [hq_b_df, hq_dur_df, hdescq_h_df, asc_q_v_df]
in_dfs = pd.concat(in_dfs, axis=1)
expected = empty_df.copy()
expected.iat[1, 1] = 'D'
expected.iat[3, 1] = 'D'
Expand Down
2 changes: 0 additions & 2 deletions vis/tests/test_workflow_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ def test_intervals_3(self):
actual = actual['aggregator.ColumnAggregator']
exp_ind = list(IntervalsTests.EXPECTED_3.index)
act_ind = list(actual.index)
# import pdb
# pdb.set_trace()
for ind_item in exp_ind:
self.assertTrue(ind_item in act_ind)
for ind_item in exp_ind:
Expand Down

0 comments on commit 85b44d6

Please sign in to comment.