Ejemplo n.º 1
0
    def test_get_descendants(self):

        measure = MeiElement('measure')
        layer   = MeiElement('layer')
        note1   = MeiElement('note')
        note2   = MeiElement('note')
        note3   = MeiElement('note')
        rest1   = MeiElement('rest')
        rest2   = MeiElement('rest')

        note1.addAttribute('pname', 'c')
        note1.addAttribute('oct', '4')
        note1.addAttribute('dur', 'breve')
        note2.addAttribute('pname', 'd')
        note2.addAttribute('dur', '1')
        note3.addAttribute('pname', 'd')
        note3.addAttribute('dur', '2')
        rest1.addAttribute('dur', '1')
        rest2.addAttribute('dur', '2')

        layer.addChild(note1)
        layer.addChild(note2)
        layer.addChild(note3)
        layer.addChild(rest1)
        layer.addChild(rest2)
        measure.addChild(layer)

        self.assertEqual(3, len(utilities.get_descendants(measure, 'note')))
        self.assertEqual(5, len(utilities.get_descendants(measure, 'note rest')))
        self.assertEqual(1, len(utilities.get_descendants(measure, 'note[dur=1]')))
        self.assertEqual(1, len(utilities.get_descendants(measure, 'note[pname=d,dur=1]')))
        self.assertEqual(4, len(utilities.get_descendants(measure, 'note[pname=d,dur=1] note[pname=c,oct=4,dur=breve] rest[dur=2] layer')))
Ejemplo n.º 2
0
    def test_emendations_02(self):
        name = 'TC_Emendations.02 - Emendations across barlines'
        mei_file = 'dat/TC.Emendations.02.mei'
        transform_data = TransformData()
        transform_data.editorial_resp = 'ZK'
        transform_data.alternates_list = [
                ('1', VARIANT, '1', ''),
                ('2', EMENDATION, '1', 'Editor1'),
                ('3', EMENDATION, '1', 'Editor2'),
                ]
        transformed_mei_doc = TransformTestCase(name, mei_file, transform_data).Run()
        MEI_tree = transformed_mei_doc.getRootElement()
        annots = utilities.get_descendants(MEI_tree, 'annot')
        self.assertEqual(len(annots), 2)
        choices = get_descendants(MEI_tree, 'choice')
        self.assertEqual(len(choices), 8)

        idtokens = get_attribute_val(annots[0], 'plist').split(' ')
        self.assertEqual(len(idtokens), 2)
        self.assertEqual(idtokens[0], '#' + choices[0].getId())
        self.assertEqual(idtokens[1], '#' + choices[1].getId())

        idtokens = get_attribute_val(annots[1], 'plist').split(' ')
        self.assertEqual(len(idtokens), 2)
        self.assertEqual(idtokens[0], '#' + choices[2].getId())
        self.assertEqual(idtokens[1], '#' + choices[3].getId())
Ejemplo n.º 3
0
def renumber_measures(MEI_tree, difference=1):
    all_measures = get_descendants(MEI_tree, 'measure')
    for measure in all_measures:
        # Get measure number attribute
        measure_n_attr = measure.getAttribute('n')
        # Get its value, as a number
        measure_number = eval(measure_n_attr.getValue())
        # Reduce number by one
        measure_n_attr.setValue(str(measure_number - difference))
Ejemplo n.º 4
0
def process_tune(args, filename, music_group, index):
    logging.info("Processing file: " + filename)
    doc = pymei.XmlImport.documentFromFile(filename)
    music = doc.getElementsByName('music')[0]
    fileDesc = doc.getElementsByName('fileDesc')[0]
    subtitles = get_descendants(fileDesc, 'title[type=subtitle]')
    title = get_descendants(fileDesc, 'title')[0]
    if (music):
        music_copy = pymei.MeiElement(music)
        music_copy.addAttribute('n', 'tune-' + str(index))
        music_copy.addAttribute('label', title.getValue())
        music_group.addChild(music_copy)
        mdiv = get_descendants(music_copy, 'mdiv')[0]
        if (len(subtitles)>0):
            mdiv.addAttribute('label', subtitles[0].getValue())
        filename_tokens = string.split(os.path.basename(filename), '.')
        if filename_tokens != None and len(filename_tokens)>0:
            mdiv.addAttribute('label', filename_tokens[0])
    return music_group
Ejemplo n.º 5
0
    def test_get_descendants(self):
        measure = MeiElement("measure")
        layer = MeiElement("layer")
        note1 = MeiElement("note")
        note2 = MeiElement("note")
        note3 = MeiElement("note")
        rest1 = MeiElement("rest")
        rest2 = MeiElement("rest")

        note1.addAttribute("pname", "c")
        note1.addAttribute("oct", "4")
        note1.addAttribute("dur", "breve")
        note2.addAttribute("pname", "d")
        note2.addAttribute("dur", "1")
        note3.addAttribute("pname", "d")
        note3.addAttribute("dur", "2")
        rest1.addAttribute("dur", "1")
        rest2.addAttribute("dur", "2")

        layer.addChild(note1)
        layer.addChild(note2)
        layer.addChild(note3)
        layer.addChild(rest1)
        layer.addChild(rest2)
        measure.addChild(layer)

        self.assertEqual(3, len(utilities.get_descendants(measure, "note")))
        self.assertEqual(5, len(utilities.get_descendants(measure, "note rest")))
        self.assertEqual(1, len(utilities.get_descendants(measure, "note[dur=1]")))
        self.assertEqual(1, len(utilities.get_descendants(measure, "note[pname=d,dur=1]")))
        self.assertEqual(
            4,
            len(
                utilities.get_descendants(
                    measure, "note[pname=d,dur=1] note[pname=c,oct=4,dur=breve] rest[dur=2] layer"
                )
            ),
        )
Ejemplo n.º 6
0
 def test_variants_continuous(self):
     name = 'TC_Variants.04 - Continuos variant'
     mei_file = 'dat/TC.Variants.04.mei'
     transform_data = TransformData()
     transform_data.editorial_resp = 'ZK'
     transform_data.alternates_list = [
             ('1', VARIANT, '1', ''),
             ('2', VARIANT, '1', 'SourceA 1552/01'),
             ]
     transformed_mei_doc = TransformTestCase(name, mei_file, transform_data).Run()
     MEI_tree = transformed_mei_doc.getRootElement()
     annots = utilities.get_descendants(MEI_tree, 'annot')
     self.assertEqual(len(annots), 1)
     self.assertEqual(len(get_attribute_val(annots[0], 'plist').split(' ')), 4)
Ejemplo n.º 7
0
def number_of_incipit_measures(MEI_tree):
    """Calculate the number of incipit measures by finding the first
    measure with a `label` attribute and comparing that attribute
    with its logical number. The difference between the two numbers
    is the number of measures we will need to remove and also the
    value by which we will need to renumber.
    """
    all_measures = get_descendants(MEI_tree, 'measure')
    for measure in all_measures:
        if measure.getAttribute('label'):
            label_number = eval(measure.getAttribute('label').getValue())
            measure_number = eval(measure.getAttribute('n').getValue())
            if label_number != measure_number:
                return measure_number - label_number
    # If no measure with 'label' exists, there may not be any incipit measures.
    return 0
Ejemplo n.º 8
0
    facsimile   = pymei.MeiElement(pages_doc.getElementsByName('facsimile')[0])
    music_group = pymei.MeiElement(tunes_doc.getElementsByName('group')[0])


    music = pymei.MeiElement("music")
    music.addChild(facsimile)
    music.addChild(music_group)

    book_doc = pymei.MeiDocument()
    mei = pymei.MeiElement('mei')
    book_doc.root = mei
    mei.addChild(music)

    logging.info('merging mdivs...')
    mdivs = get_descendants(music_group, 'mdiv')
    for mdiv in mdivs:
        label = mdiv.getAttribute('label')
        if (label):
            target = label.value + '.jpg'        
            logging.debug('linking ' + target)
            graphics = get_descendants(facsimile, 'graphic[target=' + target + ']')
            if len(graphics) > 0:
                graphic = graphics[0]
                mdiv.addAttribute('facs', '#' + graphic.id)
            else:
                logging.warning('graphic with @target=\'' + target + '\' not found')
        else:
            logging.warning('missing label attribute at mdiv#' + mdiv.id)
    if args.out:
        logging.info('writing output...')
Ejemplo n.º 9
0
def orig_clefs(MEI_tree, alternates_list):
    def is_placeholder(staff_n, alternates_list):
        """A staff is PLACEHOLDER if there's at least one other
        staff that is a reconstruction or concordance of it.
        """
        for a in alternates_list:
            # if a is reconstruction of alt_list_item:
            if a[2] == staff_n and a[1] in (RECONSTRUCTION, CONCORDANCE):
                return True
        return False

    def staff_role(staff_n, alternates_list):
        for a in alternates_list:
            if a[0] == staff_n:
                return a[1]

    def mergeClefAttributes(staffDef, clef):
        # merge the following attributes:
        #  * shape
        #  * line
        #  * oct
        #  * dis
        #  * dis.place
        def mergeAttr(attr_name):
            if (clef.hasAttribute(attr_name)):
                staffDef.addAttribute('clef.' + attr_name,
                                      clef.getAttribute(attr_name).getValue()
                                      )
        mergeAttr('shape')
        mergeAttr('line')
        mergeAttr('oct')
        mergeAttr('dis')
        mergeAttr('dis.place')

    def mergeScoreDefAttributes(scoreDef1, scoreDef2):
        # merge the following attributes:
        #  * meter.count
        #  * meter.unit
        #  * meter.sym
        #  * clef.line
        #  * clef.shape
        #  * clef.oct
        #  * clef.dis
        #  * clef.dis.place
        #  * key.sig
        #  * key.pname
        #  * key.accid
        #  * key.mode
        #  * key.sig.mixed

        def mergeAttr(attr_name):
            if (scoreDef2.hasAttribute(attr_name)):
                scoreDef1.addAttribute(attr_name, scoreDef2.getAttribute(attr_name).getValue())
        mergeAttr('meter.count')
        mergeAttr('meter.unit')
        mergeAttr('meter.sym')
        mergeAttr('clef.line')
        mergeAttr('clef.oct')
        mergeAttr('clef.dis')
        mergeAttr('clef.dis.place')
        mergeAttr('key.sig')
        mergeAttr('key.pname')
        mergeAttr('key.accid')
        mergeAttr('key.mode')
        mergeAttr('key.sig.mixed')

    # copy initial scoreDef to meiHead/workDesc/work/incip/score/
    scoreDefs = get_descendants(MEI_tree, 'scoreDef')
    # make a copy of the main scoreDef
    mainScoreDef = MeiElement(scoreDefs[0])
    # remove unwanted staves:
    #  - Reconstructed (placeholder) staves
    #  - Reconstruction (actual reconstruction) staves
    #  - Emendation staves
    staffDefs = get_descendants(mainScoreDef, 'staffDef')
    for staffDef in staffDefs:
        staff_n = staffDef.getAttribute('n').getValue()
        if (is_placeholder(staff_n, alternates_list) or
                staff_role(staff_n, alternates_list) in (RECONSTRUCTION, EMENDATION, CONCORDANCE)):
            staffDef.parent.removeChild(staffDef)
    meiHead = get_descendants(MEI_tree, 'meiHead')[0]

    head_score = chain_elems(meiHead, ['workDesc', 'work', 'incip', 'score'])
    head_score.addChild(mainScoreDef)

    # remove the milestone scoreDef and update the
    # main scoreDef accordingly, and:
    #  1. find <clef> elements (they should be in the first measure:
    #     assert this, and signal warning if it's not the case)
    #  2. update main scoreDef according to <clef>s

    music = get_descendants(MEI_tree, 'music')[0]
    section = music.getDescendantsByName('section')[0]

    mainScoreDef = music.getDescendantsByName('scoreDef')[0]
    i = 0
    for scoreDef in music.getDescendantsByName('scoreDef'):
        # Choosing 3 as a convenient value for a measure early
        # in the piece, hence unlikely to give false positives,
        # with a little wiggle room
        if i > 0 and measures_before_element(scoreDef) < 3:
            mergeScoreDefAttributes(mainScoreDef, scoreDef)
            scoreDef.getParent().removeChild(scoreDef)
        i += 1

    clefs = section.getDescendantsByName('clef')
    for clef in clefs:
        clef_in_measure = False
        clef_in_staff = False
        if clef.hasAncestor('measure'):
            measure = clef.getAncestor('measure')
            if (measure.hasAttribute('n') and
                    measure.getAttribute('n').getValue() == '1'):
                clef_in_measure = True
        if clef.hasAncestor('staff'):
            staff = clef.getAncestor('staff')
            clef_in_staff = True

        if not clef_in_measure:
            logging.warning("<clef> is only valid under the first <measure>.")
            # continue

        if not clef_in_staff:
            logging.warning("<clef> is only valid under a <staff>.")
            # continue

        if staff.hasAttribute('n'):
            clef_staff_n = staff.getAttribute('n').getValue()
        else:
            clef_staff_n = '1'

        staffDefs = music.getDescendantsByName('staffDef')
        for staffDef in staffDefs:
            staff_n = staffDef.getAttribute('n').getValue()
            if (staff_n == clef_staff_n):
                mergeClefAttributes(staffDef, clef)
Ejemplo n.º 10
0
def obliterate_incipit(MEI_tree, iterations=1):
    all_measures = get_descendants(MEI_tree, 'measure')
    for i in range(iterations):
        measure_to_remove = all_measures[i]
        measure_to_remove.getParent().removeChild(measure_to_remove)