示例#1
0
 def is_black_white_adjacent(one_note, other_note):
     """
     Determine if two fingerings of the input notes are interchangeable
     because they are adjacent long fingers of the same hand or adjacent
     fingers on white keys.
     :param one_note: A fingered middle note of a trigram.
     :param other_note: Another fingered middle note of the same sequence.
     :return: True iff they are interchangeable. False otherwise, even if
              finger used is the same.
     """
     one_pf = PianoFingering.fingering(one_note)
     other_pf = PianoFingering.fingering(other_note)
     if one_pf.strike_hand() != other_pf.strike_hand():
         return False
     one_digit = one_pf.strike_digit()
     other_digit = other_pf.strike_digit()
     if one_digit == other_digit:
         return False
     if (one_digit in (2, 3) and other_digit in (2, 3)) or \
             (one_digit in (3, 4) and other_digit in (3, 4)):
         return True
     if DEvalFunction.is_white_key(one_note):
         if (one_digit in (1, 2) and other_digit in (1, 2)) or \
                 (one_digit in (4, 5) and other_digit in (4, 5)):
             return True
     return False
示例#2
0
 def delta_hamming(one_note, other_note):
     one_pf = PianoFingering.fingering(one_note)
     other_pf = PianoFingering.fingering(other_note)
     if one_pf.strike_digit() != other_pf.strike_digit():
         return 1.0
     elif one_pf.strike_hand() != other_pf.strike_hand():
         return 1.0
     return 0.0
示例#3
0
 def get_best_pseudo_model_scores(d_score, staff="upper"):
     system_scores = []
     for i in range(5):
         system_scores.append(copy.deepcopy(d_score))
         PianoFingering.finger_score(d_score=system_scores[i],
                                     staff=staff,
                                     id=i + 1)
     return system_scores
示例#4
0
 def get_worst_pseudo_model_scores(d_score, staff="upper"):
     ann_count = d_score.annotation_count()
     system_scores = []
     for i in range(ann_count - 1, ann_count - 6, -1):
         system_scores.append(copy.deepcopy(d_score))
         PianoFingering.finger_score(d_score=system_scores[i],
                                     staff=staff,
                                     id=i + 1)
     return system_scores
示例#5
0
    def get_all_results(self, corpus_name, model, model_name, k=5, staff="upper", full_context=True, version='0000'):
        if (corpus_name, model_name, version, staff, k, full_context) in self._err_result_cache:
            cached_err_results = self._err_result_cache[(corpus_name, model_name, version, staff, k, full_context)]
            cached_pivot_reports = self._pivot_report_cache[(corpus_name, model_name, version, staff, k, full_context)]
            cached_rank_results = self._rank_result_cache[(corpus_name, model_name, version, staff, k, full_context)]
            return cached_err_results, cached_pivot_reports, cached_rank_results

        rank_results = []
        err_results = []
        pivot_reports = {}
        da_corpus = self.get_corpus(corpus_name=corpus_name)
        for da_score in da_corpus.d_score_list():
            model.load_score_as_corpus(d_score=da_score)
            system_scores = self.get_fingered_system_scores(loaded_model=model,
                                                            model_name=model_name, version=version)
            title = da_score.title()
            note_count = da_score.note_count(staff=STAFF)
            abcdh = da_score.abcd_header()
            last_annot_id = abcdh.annotation_count()
            for annot_id in range(1, last_annot_id + 1):
                annot = abcdh.annotation_by_id(annot_id)
                comment = annot.comments()
                mat = re.match(WEIGHT_RE, comment)
                if mat:
                    weight = int(mat.group(1))
                else:
                    weight = 1

                human_score = copy.deepcopy(da_score)
                PianoFingering.finger_score(d_score=human_score, staff=STAFF, id=annot_id)

                evil = DEvaluation(human_score=human_score, system_scores=system_scores,
                                   staff=staff, full_context=full_context)
                pivot_report_key = (model_name, corpus_name, title)
                pivot_heading = "{} over {} {} human {}".format(model_name, corpus_name, title, annot_id)
                pivot_report = evil.pivot_count_report(heading=pivot_heading)
                if pivot_report_key not in pivot_reports:
                    pivot_reports[pivot_report_key] = []
                pivot_reports[pivot_report_key].append(pivot_report)

                err_result = self._get_err_result_set(evil, corpus_name=corpus_name, model_name=model_name,
                                                     title=title, note_count=note_count,
                                                     annot_id=annot_id, weight=weight)
                err_results.append(err_result)

                for i in range(k):
                    rank = i + 1
                    result = self._get_result_set(evil, corpus_name=corpus_name, model_name=model_name,
                                                 title=title, note_count=note_count,
                                                 annot_id=annot_id, weight=weight, rank=rank)
                    rank_results.append(result)
                    evil.parameterize()  # Reset to defaults.
        self._err_result_cache[(corpus_name, model_name, version, staff, k, full_context)] = err_results
        self._pivot_report_cache[(corpus_name, model_name, version, staff, k, full_context)] = pivot_reports
        self._rank_result_cache[(corpus_name, model_name, version, staff, k, full_context)] = rank_results
        return err_results, pivot_reports, rank_results
示例#6
0
    def _get_basic_bigram_info(one_stream, index):
        if index >= len(one_stream):
            raise Exception("Stream index is out of range")

        a_pf = PianoFingering.fingering(one_stream[index])
        b_pf = PianoFingering.fingering(one_stream[index + 1])
        this_note = one_stream[index]
        next_note = one_stream[index + 1]
        this_midi = this_note.pitch.midi
        next_midi = next_note.pitch.midi
        direction = next_midi - this_midi
        return a_pf, b_pf, direction
示例#7
0
    def delta_adjacent_long(one_note, other_note, epsilon=None):
        if epsilon is None:
            epsilon = DEvalFunction.delta_epsilon

        one_pf = PianoFingering.fingering(one_note)
        other_pf = PianoFingering.fingering(other_note)
        if one_pf.strike_hand() != other_pf.strike_hand():
            return 1.0
        one_digit = one_pf.strike_digit()
        other_digit = other_pf.strike_digit()
        if one_digit == other_digit:
            return 0.0
        if (one_digit in (2, 3) and other_digit in (2, 3)) or \
                (one_digit in (3, 4) and other_digit in (3, 4)):
            return 1.0 - epsilon
        return 1.0
示例#8
0
    def is_unigram_match(one_note_stream, other_note_stream, index):
        if len(one_note_stream) != len(other_note_stream):
            raise Exception("Mismatched note streams")
        if index < 0:
            return True
        if index >= len(one_note_stream):
            return True

        one_note = one_note_stream[index]
        other_note = other_note_stream[index]
        one_pf = PianoFingering.fingering(one_note)
        other_pf = PianoFingering.fingering(other_note)
        if one_pf.strike_hand() != other_pf.strike_hand():
            return False
        if one_pf.strike_digit() == other_pf.strike_digit():
            return True
        return False
示例#9
0
def abcdf2pf_list(abcdf):
    annot = DAnnotation(abcdf=abcdf)
    sfs = annot.score_fingerings(staff="upper")
    pfs = []
    for sf in sfs:
        pf = PianoFingering(score_fingering=sf)
        pfs.append(pf)
    return pfs
示例#10
0
    def get_system_scores(self, model_name, d_score, k=5, weights=None):
        if model_name == 'ideal':
            return DEvaluation.get_best_pseudo_model_scores(d_score=d_score, staff=STAFF)

        model = self.get_model(model_name=model_name, weights=weights)
        advice = model.generate_advice(staff=STAFF, score_index=0, k=k)
        # print(advice)

        sys_scores = []
        for r in (range(k)):
            sys_score = copy.deepcopy(d_score)
            sys_score.remove_annotations()
            abcdf = advice[0][r]
            ann = DAnnotation(abcdf=abcdf, authority=model_name)
            sys_score.annotate(d_annotation=ann)
            PianoFingering.finger_score(d_score=sys_score, staff=STAFF)
            sys_scores.append(sys_score)
        return sys_scores
示例#11
0
    def get_fingered_system_scores(self, loaded_model: Parncutt, model_name, version=None, score_count=5, weights=None):
        advice = loaded_model.generate_advice(staff=STAFF, score_index=0, k=score_count)
        # print(advice)

        authority = model_name
        if version:
            authority = model_name + '_' + version
        base_score = loaded_model.score_by_index(0)
        sys_scores = []
        for i in range(score_count):
            sys_score = copy.deepcopy(base_score)
            sys_score.remove_annotations()
            abcdf = advice[0][i]
            ann = DAnnotation(abcdf=abcdf, authority=authority)
            sys_score.annotate(d_annotation=ann)
            PianoFingering.finger_score(d_score=sys_score, staff=STAFF)
            sys_scores.append(sys_score)
        return sys_scores
示例#12
0
    def get_err_results(self, corpus_name, model, model_name, staff="upper", full_context=True, version='0000'):
        if (corpus_name, model_name, version, staff) in self._err_result_cache:
            cached_err_results = self._err_result_cache[(corpus_name, model_name, version, staff)]
            return cached_err_results

        err_results = []
        da_corpus = self.get_corpus(corpus_name=corpus_name)
        for da_score in da_corpus.d_score_list():
            model.load_score_as_corpus(d_score=da_score)
            system_scores = self.get_fingered_system_scores(loaded_model=model,
                                                            model_name=model_name, version=version)
            title = da_score.title()
            note_count = da_score.note_count(staff=STAFF)
            abcdh = da_score.abcd_header()
            last_annot_id = abcdh.annotation_count()
            for annot_id in range(1, last_annot_id + 1):
                annot = abcdh.annotation_by_id(annot_id)
                comment = annot.comments()
                mat = re.match(WEIGHT_RE, comment)
                if mat:
                    weight = int(mat.group(1))
                else:
                    weight = 1

                human_score = copy.deepcopy(da_score)
                PianoFingering.finger_score(d_score=human_score, staff=STAFF, id=annot_id)

                evil = DEvaluation(human_score=human_score, system_scores=system_scores,
                                   staff=staff, full_context=full_context)
                err_result = self._get_err_result_set(evil, corpus_name=corpus_name, model_name=model_name,
                                                     title=title, note_count=note_count,
                                                     annot_id=annot_id, weight=weight)
                err_results.append(err_result)

        self._err_result_cache[(corpus_name, model_name, version, staff)] = err_results
        return err_results
示例#13
0
 def finger_contour_for_note_stream(stream):
     contour_string = ''
     prior_note = None
     for note in stream:
         if prior_note:
             if DEvaluation._is_ascending(one_note=prior_note,
                                          next_note=note):
                 contour_string += '/'
             elif DEvaluation._is_descending(one_note=prior_note,
                                             next_note=note):
                 contour_string += "\\"
             else:
                 contour_string += '-'
         pf = PianoFingering.fingering(note)
         contour_string += "{}{}".format(pf.strike_hand(),
                                         pf.strike_digit())
         prior_note = note
     return contour_string
示例#14
0
 def abcdf_for_note_stream(stream):
     abcdf_str = ''
     for note in stream:
         pf = PianoFingering.fingering(note)
         abcdf_str += "{}{}".format(pf.strike_hand(), pf.strike_digit())
     return abcdf_str
示例#15
0
 annotator_unigrams = corpus_unigrams[corpus_name][score_id][
     annotator_id]
 annotator_trigrams = corpus_trigrams[corpus_name][score_id][
     annotator_id]
 annotator_distance = {
     'unigram': 0,
     'adjlong': 0,
     'trigram': 0,
     'nuanced': 0
 }
 is_unigram_match = True
 is_unigram_proxy_match = True
 for note_index in range(score_len):
     czerny_finger = CZERNY_PFS[score_id][note_index]
     annotated_finger = annotator_unigrams[note_index]
     annotator_distance['unigram'] += PianoFingering.delta_hamming(
         czerny_finger, annotated_finger)
     annotator_distance[
         'adjlong'] += PianoFingering.delta_adjacent_long(
             czerny_finger, annotated_finger)
     czerny_trigram = CZERNY_TRIGRAMS[score_id][note_index]
     annotated_trigram = annotator_trigrams[note_index]
     annotator_distance['trigram'] += PianoFingering.tau_trigram(
         czerny_trigram, annotated_trigram)
     annotator_distance['nuanced'] += PianoFingering.tau_nuanced(
         czerny_trigram, annotated_trigram)
     if not PianoFingering.is_unigram_match(annotated_finger,
                                            czerny_finger):
         is_unigram_match = False
         if not PianoFingering.is_adjacent_long(
                 annotated_finger, czerny_finger):
             is_unigram_proxy_match = False