def test_good_rules(): jake = Jacobs() jake.segment_combiner(method="cost") for id in subcosts: d_corpus = DCorpus( corpus_str=TestConstant.PARNCUTT_HUMAN_FRAGMENT[id]) jake.load_corpus(d_corpus=d_corpus) if id == 'B': suggestions, costs, details = jake.generate_advice( staff="upper", cycle=4, k=20) else: suggestions, costs, details = jake.generate_advice( staff="upper", last_digit=last_digit[id], k=30) details_for_sugg = dict() for i in range(len(details)): details_for_sugg[suggestions[i]] = details[i][ 0] # 0 index because we only have one segment jake.report_on_advice(suggestions, costs, details) for gold_sugg in subcosts[id]: assert gold_sugg in details_for_sugg, \ "Missing suggestion {0} in {1}".format(gold_sugg, id) for rule in subcosts[id][gold_sugg]: if rule == '345': continue gold_cost = subcosts[id][gold_sugg][rule] cost = details_for_sugg[gold_sugg][rule] assert cost == gold_cost, \ "Bad {0} cost for {1} in {2}: {3} should be {4}".format(rule, gold_sugg, id, cost, gold_cost)
def test_four_note_example(self): jacobs = Jacobs(segmenter=ManualDSegmenter(), segment_combiner="cost") d_corpus = DCorpus(corpus_str=TestConstant.FOUR_NOTES) jacobs.load_corpus(d_corpus=d_corpus) suggestions, costs, details = jacobs.generate_advice(staff="upper", k=2) self.assertEqual(len(suggestions), 2, "No loops in that dog in top ten")
def test_distance(self): jacobs = Jacobs(segmenter=ManualDSegmenter(), segment_combiner="cost") c4e4_dist = jacobs.distance(from_midi=60, to_midi=64) e4g4_dist = jacobs.distance(from_midi=64, to_midi=67) self.assertEqual(c4e4_dist, e4g4_dist, "Bad distance") e4c4_dist = jacobs.distance(from_midi=64, to_midi=60) g4e4_dist = jacobs.distance(from_midi=67, to_midi=64) self.assertEqual(e4c4_dist, g4e4_dist, "Bad negative distance")
def test_pivot_alignment(): jake = Jacobs() d_corpus = DCorpus(corpus_str=TestConstant.A_MAJ_SCALE_SHORT) jake.load_corpus(d_corpus=d_corpus) evaluations = jake.evaluate_pivot_alignment(staff="both") # for he in hamming_evaluations: # print(he) assert evaluations[0] > 0, "Undetected pivot alignment costs" assert evaluations[4] == 0, "Bad fish in pivot alignment barrel"
def test_bl1(): jake = Jacobs() jake.segment_combiner(method="cost") midi_1 = None handed_digit_1 = '-' midi_2 = 61 handed_digit_2 = '>1' midi_3 = 65 handed_digit_3 = '>3' trigram_node = TrigramNode(midi_1, handed_digit_1, midi_2, handed_digit_2, midi_3, handed_digit_3) cost, costs = jake.trigram_node_cost(trigram_node=trigram_node) assert costs['bl1'] == 3, "Bad bl1 cost"
def test_fingering_counts(): jake = Jacobs(pruning_method="none") jake.segment_combiner(method="cost") d_corpus = DCorpus(corpus_str=TestConstant.FOUR_NOTES) jake.load_corpus(d_corpus=d_corpus) suggestions, costs, details = jake.generate_advice(staff="upper", k=2) assert jake.last_segment_pruned_count( ) == 320, "Bad none pruning on open-ended problem"
def test_cycles(): jake = Jacobs() jake.segment_combiner(method="cost") d_corpus = DCorpus(corpus_str=TestConstant.FOUR_NOTES) jake.load_corpus(d_corpus=d_corpus) suggestions, costs, details = jake.generate_advice(staff="upper", cycle=4, k=2) assert len(suggestions) == 2, "No loops in that dog in top ten" # jake.report_on_advice(suggestions, costs, details) d_corpus = DCorpus( corpus_str=TestConstant.PARNCUTT_HUMAN_FRAGMENT['B']) jake.load_corpus(d_corpus=d_corpus) suggestions, costs, details = jake.generate_advice(staff="upper", cycle=4, k=16) assert len(suggestions) == 16, "There should be 16 cyclic fingerings!"
def test_reentry(): jake = Jacobs() # We cannot use the longer example A_MAJ_SCALE because the gold standard fingering # requires hand repositionings not allowed by the Parncutt model. This reinforces the need # for segmentation and also (maybe) the need for a more inclusive option for Parncutt where # all paths are possible but some are just very expensive, as we have in Sayegh. d_corpus = DCorpus(corpus_str=TestConstant.A_MAJ_SCALE_SHORT) jake.load_corpus(d_corpus=d_corpus) reentry_hamming_evals = jake.evaluate_strike_reentry( method="hamming", staff="upper", gold_indices=[2, 3]) # Note we are not picking Beringer for the real gold standard because Beringer and Parncutt agree # on the fingering for this scale. # for rhe in reentry_hamming_evals: # print("RHE:{0}".format(rhe)) assert reentry_hamming_evals[ 0] > 0, "Undetected upper Hamming reentry costs" assert reentry_hamming_evals[ 1] == 0, "Bad fish in upper-staff Hamming reentry barrel" reentry_hamming_evals = jake.evaluate_strike_reentry( method="hamming", staff="both", gold_indices=[2, 3]) # for rhe in reentry_hamming_evals: # print("RHE:{0}".format(rhe)) assert reentry_hamming_evals[ 0] > 0, "Undetected both-staff Hamming reentry costs" assert reentry_hamming_evals[ 1] == 0, "Bad fish in both-staff Hamming reentry barrel" hamming_score = reentry_hamming_evals[0] reentry_natural_evals = jake.evaluate_strike_reentry( method="natural", staff="both", gold_indices=[2, 3]) # for rne in reentry_natural_evals: # print("RNE:{0}".format(rne)) assert reentry_natural_evals[0] > 0, "Undetected natural reentry costs" assert reentry_natural_evals[ 1] == 0, "Bad fish in natural reentry barrel" natural_score = reentry_natural_evals[0] assert natural_score > hamming_score, "Reentry: Natural <= Hamming" reentry_pivot_evals = jake.evaluate_strike_reentry(method="pivot", staff="both", gold_indices=[2, 3]) # for rpe in reentry_pivot_evals: # print("RPE:{0}".format(rpe)) assert reentry_pivot_evals[0] > 0, "Undetected pivot reentry costs" assert reentry_pivot_evals[1] == 0, "Bad fish in pivot reentry barrel" pivot_score = reentry_pivot_evals[0] assert natural_score < pivot_score, "Reentry: Natural >= Pivot"
def get_model(self, model_name, weights=None): if model_name == 'random': model = Random() elif model_name == 'parncutt': model = Parncutt() elif model_name == 'jacobs': model = Jacobs() elif model_name == 'jarules': model = Jacobs(finger_spans=FINGER_SPANS, ruler=Ruler()) elif model_name == 'jaball': model = Jacobs(finger_spans=BALLIAUW_LARGE_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) elif model_name == 'jaSball': model = Jacobs(finger_spans=BALLIAUW_SMALL_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) elif model_name == 'jaMball': model = Jacobs(finger_spans=BALLIAUW_MEDIUM_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) elif model_name == 'badgerow': # model = Badgerow(finger_spans=FINGER_SPANS, ruler=PhysicalRuler()) # model = Badgerow(finger_spans=BALLIAUW_LARGE_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) model = Badgerow() elif model_name == 'badpar': # model = Badgerow(finger_spans=FINGER_SPANS, ruler=PhysicalRuler()) # model = Badgerow(finger_spans=BALLIAUW_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) model = Badgerow(finger_spans=FINGER_SPANS) elif model_name == 'balliauw': model = Balliauw() elif model_name == 'badball': model = Badgerow(finger_spans=BALLIAUW_LARGE_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) elif model_name == 'badSball': model = Badgerow(finger_spans=BALLIAUW_SMALL_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) elif model_name == 'badMball': model = Badgerow(finger_spans=BALLIAUW_MEDIUM_FINGER_SPANS, ruler=ImaginaryBlackKeyRuler()) else: raise Exception("Bad model") if weights: model.init_rule_weights(weights) return model
kappa, pairs = d_score.cohens_kappa(16, 17, staff=staff, common_id=3) aggregate_pairs(interpolation2_pairs, pairs) print("Interpol 2 {} staff{} Section {}.1 Kappa: {}".format( staff, plural, score_index + 1, kappa)) print("Interpol 2 {} staff{} Section {}.1 Alpha: {}".format( staff, plural, score_index + 1, alpha)) score_index += 1 print_pairs("Annotation 1 pairs:", annotation_pairs) print_pairs("Interpolation 1 pairs:", interpolation_pairs) print_pairs("Interpolation 2 pairs:", interpolation2_pairs) exit(0) parncutt = Parncutt() d_corpus = DCorpus(paths=phrase_paths) parncutt.load_corpus(d_corpus=d_corpus) jacobs = Jacobs() jacobs.load_corpus(d_corpus=d_corpus) justin = Badgerow() justin.load_corpus(d_corpus=d_corpus) model_years = {'Parncutt': '1997', 'Jacobs': '2001', 'Badgerow': '2019'} models = [parncutt, jacobs, justin] for model in models: model_name = str(type(model)).split('.')[-1] model_name = model_name[0:-2] model_version = model.version() version_str = ".".join(map(str, model_version)) authority = model_name + ' Model (' + model_years[model_name] + ')' for i in range(len(phrase_ids)): id = phrase_ids[i]
def test_distance_metrics(): jake = Jacobs() d_corpus = DCorpus(corpus_str=TestConstant.A_MAJ_SCALE_SHORT) jake.load_corpus(d_corpus=d_corpus) complete_rh_advice = jake.advise(staff="upper") complete_rh_advice_len = len(complete_rh_advice) right_re = re.compile('^>\d+$') assert right_re.match( complete_rh_advice), "Bad right-hand, upper-staff advice" rh_advice = jake.advise(staff="upper", offset=3, first_digit=4) short_advice_len = len(rh_advice) assert complete_rh_advice_len - 3 == short_advice_len, "Bad offset for advise() call" ff_re = re.compile('^>4\d+$') assert ff_re.match(rh_advice), "Bad first finger constraint" rh_advice = jake.advise(staff="upper", offset=10, first_digit=1, last_digit=3) short_advice_len = len(rh_advice) assert complete_rh_advice_len - 10 == short_advice_len, "Bad offset for advise() call" ff_re = re.compile('^>1\d+3$') assert ff_re.match(rh_advice), "Bad first and last finger constraints" lh_advice = jake.advise(staff="lower") left_re = re.compile('^<\d+$') assert left_re.match(lh_advice), "Bad left-hand, lower-staff advice" combo_advice = jake.advise(staff="both") clean_combo_advice = re.sub('[><&]', '', combo_advice) d_score = d_corpus.d_score_by_index(index=0) gold_fingering = d_score.abcdf(index=0) clean_gold_fingering = re.sub('[><&]', '', gold_fingering) combo_re = re.compile('^>\d+@<\d+$') assert combo_re.match(combo_advice), "Bad combined advice" hamming_evaluations = jake.evaluate_strike_distance(method="hamming", staff="both") assert hamming_evaluations[0] > 0, "Undetected Hamming costs" assert hamming_evaluations[4] == 0, "Bad fish in Hamming barrel" natural_evaluations = jake.evaluate_strike_distance(method="natural", staff="both") assert natural_evaluations[0] > 0, "Undetected natural costs" assert natural_evaluations[4] == 0, "Bad fish in natural barrel" pivot_evaluations = jake.evaluate_strike_distance(method="pivot", staff="both") assert pivot_evaluations[0] > 0, "Undetected pivot costs" assert pivot_evaluations[4] == 0, "Bad fish in pivot barrel"
def test_jake(): jake = Jacobs() d_corpus = DCorpus(corpus_str=TestConstant.ONE_NOTE) jake.load_corpus(d_corpus=d_corpus) upper_rh_advice = jake.advise(staff="upper") right_re = re.compile('^>\d$') assert right_re.match( upper_rh_advice), "Bad one-note, right-hand, upper-staff advice" # both_advice = jake.advise(staff="both") # both_re = re.compile('^>\d@$') # assert both_re.match(both_advice), "Bad one-note, segregated, both-staff advice" jake = Jacobs() d_corpus = DCorpus(corpus_str=TestConstant.ONE_BLACK_NOTE_PER_STAFF) jake.load_corpus(d_corpus=d_corpus) upper_advice = jake.advise(staff="upper") right_re = re.compile('^>2$') assert right_re.match( upper_advice), "Bad black-note, upper-staff advice" lower_advice = jake.advise(staff="lower") left_re = re.compile('^<2$') assert left_re.match( lower_advice), "Bad black-note, upper-staff advice" both_advice = jake.advise(staff="both") both_re = re.compile('^>2@<2$') assert both_re.match(both_advice), "Bad black-note, both-staff advice" lower_advice = jake.advise(staff="lower", first_digit=3) lower_re = re.compile('^<3$') assert lower_re.match( lower_advice), "Bad preset black-note, both-staff advice" jake = Jacobs() d_corpus = DCorpus(corpus_str=TestConstant.TWO_WHITE_NOTES_PER_STAFF) jake.load_corpus(d_corpus=d_corpus) upper_advice = jake.advise(staff="upper") right_re = re.compile('^>\d\d$') assert right_re.match( upper_advice), "Bad two white-note, upper-staff advice" upper_advice = jake.advise(staff="upper", first_digit=2, last_digit=4) right_re = re.compile('^>24$') assert right_re.match( upper_advice), "Bad preset two white-note, upper-staff advice"