From 1e76b640f0ffa9af8e33fce6803f3fa1bad8eb54 Mon Sep 17 00:00:00 2001 From: sildater Date: Wed, 25 Sep 2024 14:44:02 +0200 Subject: [PATCH 1/8] measure feature wip --- partitura/musicanalysis/note_features.py | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/partitura/musicanalysis/note_features.py b/partitura/musicanalysis/note_features.py index 92e07c0b..8e1f39f8 100644 --- a/partitura/musicanalysis/note_features.py +++ b/partitura/musicanalysis/note_features.py @@ -1073,6 +1073,35 @@ def metrical_strength_feature(na, part, **kwargs): return W, names +def measure_feature(na, part, **kwargs): + """Measure feature + + This feature encodes the measure each note is in. + + """ + notes = part.notes_tied if not np.all(na["pitch"] == 0) else part.rests + bm = part.beat_map + eps = 10**-6 + + names = [ + "measure_number", + "measure_name", + "measure_start_beats", + "measure_end_beats", + ] + + for i, n in enumerate(notes): + measure = next(n.start.iter_prev(score.Measure, eq=True), None) + + if measure: + measure_start = measure.start.t + else: + pass + + W = np.zeros((len(notes), 4)) + + return W, names + def time_signature_feature(na, part, **kwargs): """TIme Signature feature From e5d8938c7b7945423a32a7166aca697b781d3b1a Mon Sep 17 00:00:00 2001 From: sildater Date: Wed, 25 Sep 2024 14:47:33 +0200 Subject: [PATCH 2/8] single measure wip --- partitura/musicanalysis/note_features.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/partitura/musicanalysis/note_features.py b/partitura/musicanalysis/note_features.py index 8e1f39f8..05918ab5 100644 --- a/partitura/musicanalysis/note_features.py +++ b/partitura/musicanalysis/note_features.py @@ -1083,9 +1083,14 @@ def measure_feature(na, part, **kwargs): bm = part.beat_map eps = 10**-6 + measures = np.array([(m.start.t, m.end.t) for m in part.iter_all(score.Measure)]) + if len(measures) == 0: + start = bm(part.first_point.t) + end = bm(part.last_point.t) + number = 1 + names = [ "measure_number", - "measure_name", "measure_start_beats", "measure_end_beats", ] From de5cc0bd28e7f4624fbcab9bf15bcafecc7b0771 Mon Sep 17 00:00:00 2001 From: sildater Date: Wed, 25 Sep 2024 14:50:14 +0200 Subject: [PATCH 3/8] rework default wip --- partitura/musicanalysis/note_features.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/partitura/musicanalysis/note_features.py b/partitura/musicanalysis/note_features.py index 05918ab5..ff288abb 100644 --- a/partitura/musicanalysis/note_features.py +++ b/partitura/musicanalysis/note_features.py @@ -1083,11 +1083,10 @@ def measure_feature(na, part, **kwargs): bm = part.beat_map eps = 10**-6 - measures = np.array([(m.start.t, m.end.t) for m in part.iter_all(score.Measure)]) - if len(measures) == 0: - start = bm(part.first_point.t) - end = bm(part.last_point.t) - number = 1 + + global_start = bm(part.first_point.t) + global_end = bm(part.last_point.t) + global_number = 0 # default global measure number names = [ "measure_number", @@ -1099,9 +1098,14 @@ def measure_feature(na, part, **kwargs): measure = next(n.start.iter_prev(score.Measure, eq=True), None) if measure: - measure_start = measure.start.t + start = bm(measure.start.t) + end = bm(measure.end.t) + number = measure.number else: - pass + start = bm(measure.start.t) + end = bm(measure.end.t) + number = measure.number + W = np.zeros((len(notes), 4)) From 7db9f9b7776929d534fa88cbec0bf867b9dca6e8 Mon Sep 17 00:00:00 2001 From: sildater Date: Wed, 25 Sep 2024 14:52:23 +0200 Subject: [PATCH 4/8] fill measure info wip --- partitura/musicanalysis/note_features.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/partitura/musicanalysis/note_features.py b/partitura/musicanalysis/note_features.py index ff288abb..b2d6c9c6 100644 --- a/partitura/musicanalysis/note_features.py +++ b/partitura/musicanalysis/note_features.py @@ -1081,8 +1081,6 @@ def measure_feature(na, part, **kwargs): """ notes = part.notes_tied if not np.all(na["pitch"] == 0) else part.rests bm = part.beat_map - eps = 10**-6 - global_start = bm(part.first_point.t) global_end = bm(part.last_point.t) @@ -1093,6 +1091,7 @@ def measure_feature(na, part, **kwargs): "measure_start_beats", "measure_end_beats", ] + W = np.zeros((len(notes), 3)) for i, n in enumerate(notes): measure = next(n.start.iter_prev(score.Measure, eq=True), None) @@ -1105,9 +1104,10 @@ def measure_feature(na, part, **kwargs): start = bm(measure.start.t) end = bm(measure.end.t) number = measure.number - - W = np.zeros((len(notes), 4)) + W[i, 0] = number + W[i, 1] = start + W[i, 2] = end return W, names From 4306340bb7d329d17bb1c3fa2c8ccf264e9bf363 Mon Sep 17 00:00:00 2001 From: sildater Date: Wed, 25 Sep 2024 15:00:30 +0200 Subject: [PATCH 5/8] measure feature complete --- partitura/musicanalysis/note_features.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/partitura/musicanalysis/note_features.py b/partitura/musicanalysis/note_features.py index b2d6c9c6..92935aca 100644 --- a/partitura/musicanalysis/note_features.py +++ b/partitura/musicanalysis/note_features.py @@ -1088,8 +1088,8 @@ def measure_feature(na, part, **kwargs): names = [ "measure_number", - "measure_start_beats", - "measure_end_beats", + "measure_start_beat", + "measure_end_beat", ] W = np.zeros((len(notes), 3)) @@ -1101,9 +1101,9 @@ def measure_feature(na, part, **kwargs): end = bm(measure.end.t) number = measure.number else: - start = bm(measure.start.t) - end = bm(measure.end.t) - number = measure.number + start = global_start + end = global_end + number = global_number W[i, 0] = number W[i, 1] = start From c85acf95f566f1148926436cc6e511e01be41f79 Mon Sep 17 00:00:00 2001 From: sildater Date: Tue, 15 Oct 2024 14:28:51 +0200 Subject: [PATCH 6/8] measure feature ordered --- partitura/musicanalysis/note_features.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/partitura/musicanalysis/note_features.py b/partitura/musicanalysis/note_features.py index 92935aca..799d340f 100644 --- a/partitura/musicanalysis/note_features.py +++ b/partitura/musicanalysis/note_features.py @@ -1079,7 +1079,8 @@ def measure_feature(na, part, **kwargs): This feature encodes the measure each note is in. """ - notes = part.notes_tied if not np.all(na["pitch"] == 0) else part.rests + notes_list = part.notes_tied if not np.all(na["pitch"] == 0) else part.rests + notes = {n.id:n for n in notes_list} bm = part.beat_map global_start = bm(part.first_point.t) @@ -1093,7 +1094,8 @@ def measure_feature(na, part, **kwargs): ] W = np.zeros((len(notes), 3)) - for i, n in enumerate(notes): + for i, na_n in enumerate(na): + n = notes[na_n["id"]] measure = next(n.start.iter_prev(score.Measure, eq=True), None) if measure: From 115d3a7678fe88375aab05ceea912ccacf4419f5 Mon Sep 17 00:00:00 2001 From: sildater Date: Tue, 15 Oct 2024 14:46:37 +0200 Subject: [PATCH 7/8] measure test and data --- tests/data/musicxml/test_note_features.xml | 4 ++-- tests/test_note_features.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/data/musicxml/test_note_features.xml b/tests/data/musicxml/test_note_features.xml index 371ed54d..a206da7e 100644 --- a/tests/data/musicxml/test_note_features.xml +++ b/tests/data/musicxml/test_note_features.xml @@ -60,7 +60,7 @@ - + @@ -138,7 +138,7 @@ - + diff --git a/tests/test_note_features.py b/tests/test_note_features.py index 891a254b..b47a2540 100644 --- a/tests/test_note_features.py +++ b/tests/test_note_features.py @@ -59,6 +59,17 @@ def test_slur_grace_art_dyn_orn(self): self.assertTrue(np.all(dyntest), "forte feature does not match") self.assertTrue(np.all(slurtest), "slur feature does not match") + def test_measure_feature(self): + for fn in MUSICXML_NOTE_FEATURES: + score = load_musicxml(fn, force_note_ids=True) + feats = [ + "measure_feature" + ] + na = compute_note_array(score[0], feature_functions=feats) + + + + if __name__ == "__main__": unittest.main() From 5f265a2021091e9ad69ee5dd4cf164a2e081d3a3 Mon Sep 17 00:00:00 2001 From: sildater Date: Tue, 15 Oct 2024 15:08:26 +0200 Subject: [PATCH 8/8] add measure feature asserts --- tests/test_note_features.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_note_features.py b/tests/test_note_features.py index b47a2540..86fb92bc 100644 --- a/tests/test_note_features.py +++ b/tests/test_note_features.py @@ -67,7 +67,12 @@ def test_measure_feature(self): ] na = compute_note_array(score[0], feature_functions=feats) - + numtest = na["measure_feature.measure_number"] == np.array([1, 1, 1, 2, 2, 2]) + starttest = na["measure_feature.measure_start_beat"] == np.array([0, 0, 0, 4, 4, 4]) + endtest = na["measure_feature.measure_end_beat"] == np.array([4, 4, 4, 8, 8, 8]) + self.assertTrue(np.all(numtest), "measure number feature does not match") + self.assertTrue(np.all(starttest), "measure start feature does not match") + self.assertTrue(np.all(endtest), "measure end feature does not match")