Exemplo n.º 1
0
    def __init__(self, incoming_data):
        self._recognition_results = incoming_data
        self.meidoc = mod.mei_()
        self.staff = None
        self.glyph = None

        self._note_elements = None
        self._neume_pitches = []

        self._global_graphic_element = self._create_graphic_element("foo.jpg")
        self.meidoc.add_child(self._global_graphic_element)

        for snum, stf in self._recognition_results.iteritems():
            self.staff = stf
            self.staffel = self._parse_staff(snum, stf)
            z = mod.zone_()
            z.id = self._idgen()
            z.attributes = {
                "ulx": self.staff["coord"][0],
                "uly": self.staff["coord"][1],
                "lrx": self.staff["coord"][2],
                "lry": self.staff["coord"][3],
            }

            self._global_graphic_element.add_child(z)
            self.staffel.facs = z.id

            self.meidoc.add_child(self.staffel)

        self.md = MeiDocument.MeiDocument()
        self.md.addelement(self.meidoc)
Exemplo n.º 2
0
 def _create_zone_element(self):
     zone = mod.zone_()
     zone.id = self._idgen()
     zone.attributes = {'ulx': self.glyph['coord'][0], 'uly': self.glyph['coord'][1], \
                         'lrx': self.glyph['coord'][2], 'lry': self.glyph['coord'][3]}
     self.surface.add_child(zone)
     return zone
Exemplo n.º 3
0
def switch_tie(meifile, tstamp = False, keep_id = False):
    ''' Changes all ties expressed with attributes into elements. 
    If tstamp is set, it will attempt to generate tstamps instead of startid/endid pairs.
    
    @TODO
    At some point search() will support
    passing in args will narrow down the search by only retrieving objects with that attribute.
    Make sure to update this function when that happens 
    '''
    
    meifile_flat = meifile.flat()
    
    for n in meifile_flat:
        if n.has_attribute('tie'):
            if n.tie=='i' or n.tie=='m': #one tie element for each tie!
                #get ancestor measure
                measure = n.ancestor_by_name('measure')
                #create a tie element
                tie = mod.tie_()
                
                #determine attributes according to args
                atts = {'xml:id':generate_mei_id()}
                if tstamp:
                    atts['tstamp'] =  time.id_to_tstamp(n)
                if keep_id or (not keep_id and not tstamp):
                    atts['startid'] = n.id
                    
                #add attributes to tie
                tie.attributes = atts
                
                #add tie to measure
                measure.add_child(tie)
        #remove tie attribute
        n.remove_attribute('tie')
Exemplo n.º 4
0
 def _create_custos_element(self):
     custos = mod.custos_()
     custos.id = self._idgen()
     zone = self._create_zone_element()
     custos.facs = zone.id
     custos.pitchname = self.glyph['strt_pitch']
     return custos
Exemplo n.º 5
0
 def _create_clef_element(self):
     clef = mod.clef_()
     clef.id = self._idgen()
     zone = self._create_zone_element()
     clef.facs = zone.id
     
     clef.attributes = {"line": self.glyph['strt_pos'], 'shape': self.glyph['form'][0].upper() }
     
     return clef
Exemplo n.º 6
0
 def _create_division_element(self):
     division = mod.division_()
     division.id = self._idgen()
     zone = self._create_zone_element()
     division.facs = zone.id
     
     if self.glyph['form']:
         division.attributes = {'form': self.glyph['form'][0]}
     
     return division
Exemplo n.º 7
0
 def _create_zone_element(self):
     zone = mod.zone_()
     zone.id = self._idgen()
     zone.attributes = {
         "ulx": self.glyph["coord"][0],
         "uly": self.glyph["coord"][1],
         "lrx": self.glyph["coord"][2],
         "lry": self.glyph["coord"][3],
     }
     self._global_graphic_element.add_child(zone)
     return zone
Exemplo n.º 8
0
 def _create_alteration_element(self):
     accid = mod.accid_()
     accid.id = self._idgen()
     if self.glyph['form'] is "sharp":
         accid.attributes = {"accid": "s"}
     elif self.glyph['form'] is "flat":
         accid.attributes = {"accid": "f"}
     
     zone = self._create_zone_element()
     note.facs = zone.id
     
     return accid
Exemplo n.º 9
0
def add_text_lines(hocrfile, surface, section):
	"""
	helper method that adds lines in hocr file to 'surface' and 'section' in mei file
	"""
	div=mod.div_()
	div.id=generate_mei_id()
	lg=mod.lg_()
	lg.id=generate_mei_id()
	section.add_child(div)
	div.add_child(lg)
	for line in getlines(hocrfile):
		# for each line: make new zone and l objects, add zone to surface
		zone=mod.zone_()
		zone.id=generate_mei_id()
		zone.ulx=line['bbox'][0]
		zone.uly=line['bbox'][1]
		zone.lrx=line['bbox'][2]
		zone.lry=line['bbox'][3]
		l=mod.l_()
		l.id=generate_mei_id()
		l.facs=zone.id
		l.value=correct_text(line)
		lg.add_child(l)
		surface.add_child(zone)
Exemplo n.º 10
0
 def _create_staff_element(self):
     staff = mod.staff_()
     staff.id = self._idgen()
     return staff
Exemplo n.º 11
0
    def _create_neume_element(self):
        if "climacus" in self.glyph["form"]:
            neume = mod.ineume_()
        else:
            neume = mod.uneume_()

        neume.id = self._idgen()
        zone = self._create_zone_element()
        neume.facs = zone.id

        neume.attributes = {"name": self.glyph["form"][0]}

        # get the form so we can find the number of notes we need to construct.
        try:
            # since we define the form of the intervals, we're always off-by-one in the number of notes.
            num_notes = len(self.NEUME_NOTES[self.glyph["form"][0]]) + 1
        except KeyError:
            raise GameraMeiFormNotFoundError("The form {0} was not found.".format(self.glyph["form"][0]))

        # do we need to add any further notes? form is pretty loaded, so we
        # have to check manually, from idx 1 on (since the primary form is always first)

        # we don't have an off-by-one problem here, since an added interval means an added note
        check_additional = [i for i in self.ADD_NOTES.keys() if i in self.glyph["form"][1:]]
        num_notes = num_notes + len(check_additional)

        self._neume_pitches = []
        # note elements are everything after the first form. This determines the shape a note takes.
        self._note_elements = self.glyph["form"][1:]
        self._neume_pitches.append(self.glyph["strt_pitch"])

        nc = []
        if num_notes > 1:
            # we need to figure out the rest of the pitches in the neume.
            ivals = [int(d) for d in self._note_elements if d.isdigit()]
            try:
                idx = self.SCALE.index(self.glyph["strt_pitch"].upper())
            except ValueError:
                raise GameraMeiPitchNotFoundError(
                    "The pitch {0} was not found in the scale".format(self.glyph["strt_pitch"])
                )

            if len(ivals) != (num_notes - 1):
                raise GameraMeiNoteIntervalMismatchError(
                    "There is a mismatch between the number of notes and number of intervals."
                )

            # note elements = torculus.2.2.he.ve
            # ivals = [2,2]
            # torculus = ['u','d']

            lg.debug(ivals)
            for n in xrange(len(ivals)):
                # get the direction
                dir = self.NEUME_NOTES[self.glyph["form"][0]][n]
                lg.debug("direction is {0}".format(dir))
                iv = ivals[n]
                n_idx = idx

                lg.debug("index: {0}".format(idx))

                if dir == "u":
                    if (idx + (iv - 1)) >= len(self.SCALE):
                        n_idx = 0 + (iv - 1)
                    else:
                        n_idx = idx + (iv - 1)
                elif dir == "d":
                    if idx - (iv - 1) < 0:
                        n_idx = len(self.SCALE) + (idx - (iv - 1))
                    else:
                        n_idx = idx - (iv - 1)
                idx = n_idx

                lg.debug("Picking pitch {0}".format(self.SCALE[n_idx]))
                self._neume_pitches.append(self.SCALE[n_idx])

        for n in xrange(num_notes):
            p = self._neume_pitches[n]
            nc.append(self._create_note_element(p))
        neume.add_children(nc)

        lg.debug(neume.children)

        return neume
Exemplo n.º 12
0
 def _create_clef_element(self):
     clef = mod.clef_()
     clef.id = self._idgen()
     zone = self._create_zone_element()
     clef.facs = zone.id
     return clef
Exemplo n.º 13
0
 def _create_dot_element(self):
     dot = mod.dot_()
     dot.id = self._idgen()
     dot.attributes = {"form": "aug"}
     return dot
Exemplo n.º 14
0
    def _create_neume_element(self):
        full_width_episema = False
        has_dot = False
        has_vertical_episema = False
        has_horizontal_episema = False
        has_quilisma = False
        this_neume_form = None
        local_horizontal_episema = None
        
        start_octave = self.glyph['octv']
        clef_pos = self.glyph['clef_pos']
        clef_type = self.glyph['clef'].split(".")[-1] # f or c.
        
        neume = mod.neume_()
        neume.id = self._idgen()
        zone = self._create_zone_element()
        neume.facs = zone.id
        
        neumecomponent = mod.nc_()
        neumecomponent.id = self._idgen()
        neume.add_child(neumecomponent)
        if self.glyph['form'][0] == "he":
            full_width_episema = True
            del self.glyph['form'][0]
        
        # we've removed any global he's, so 
        # any leftovers should be local.
        if 'he' in self.glyph['form']:
            has_horizontal_episema = True
        
        if 'dot' in self.glyph['form']:
            has_dot = True
        
        if 'q' in self.glyph['form']:
            has_quilisma = True
        
        if 've' in self.glyph['form']:
            has_vertical_episema = True
        
        if 'inclinatum' in self.glyph['form']:
            neumecomponent.attributes = {'inclinatum': 'true'}
            
        neume.attributes = {'name': self.glyph['form'][0]}
        
        if 'compound' in self.glyph['form']:
            # do something and create a new set of pitch contours
            this_neume_form = [y for y in (self.__parse_contour(n) for n in self.glyph['form']) if y]
            self._note_elements = [y for y in (self.__parse_steps(n) for n in self.glyph['form']) if y]
        else:
            this_neume_form = copy.deepcopy(self.NEUME_NOTES[self.glyph['form'][0]])
            self._note_elements = self.glyph['form'][1:]
        # get the form so we can find the number of notes we need to construct.
        
        num_notes = len(this_neume_form) + 1
        # we don't have an off-by-one problem here, since an added interval means an added note
        check_additional = [i for i in self.ADD_NOTES.keys() if i in self.glyph['form'][1:]]
        if check_additional:
            for f in check_additional:
                this_neume_form.extend(self.ADD_NOTES[f])
                
                ## THIS SHOULD BE CHANGED. Otherwise we may end up with two attributes with the
                # same name.
                neume.attributes = {"variant": f}
            
            num_notes = num_notes + len(check_additional)
            
        self._neume_pitches = []
        # note elements are everything after the first form. This determines the shape a note takes.
        self._neume_pitches.append(self.glyph['strt_pitch'])
        nc = []
        note_octaves = [start_octave]
        if num_notes > 1:
            # we need to figure out the rest of the pitches in the neume.
            ivals = [int(d) for d in self._note_elements if d.isdigit()]
            try:
                idx = self.SCALE.index(self.glyph['strt_pitch'])
            except ValueError:
                raise AomrMeiPitchNotFoundError("The pitch {0} was not found in the scale".format(self.glyph['strt_pitch']))
                
            if len(ivals) != (num_notes - 1):
                if 'scandicus' in self.glyph['form']:
                    diffr = abs(len(ivals) - (num_notes - 1))
                    num_notes = num_notes + diffr
                    this_neume_form.extend(diffr * 'u')
                else:
                    raise AomrMeiNoteIntervalMismatchError("There is a mismatch between the number of notes and number of intervals.")
            
            # note elements = torculus.2.2.he.ve
            # ivals = [2,2]
            # torculus = ['u','d']
            this_pos = copy.deepcopy(self.glyph['strt_pos'])
            for n in xrange(len(ivals)):
                # get the direction
                dir = this_neume_form[n]
                iv = ivals[n]
                n_idx = idx
                if dir == "u":
                    n_idx = ((idx + iv) % len(self.SCALE)) - 1
                    this_pos -= (iv - 1)
                elif dir == "d":
                    n_idx = idx - (iv -1)
                    this_pos += (iv - 1)
                    if n_idx < 0:
                        n_idx += len(self.SCALE)
                idx = n_idx
                self._neume_pitches.append(self.SCALE[n_idx])

                actual_line = 10 - (2*(clef_pos-1))

                if clef_type == "c":
                    if this_pos <= actual_line:
                        note_octaves.append(4)
                    elif this_pos > actual_line + 7:
                        note_octaves.append(2)
                    else:
                        note_octaves.append(3)
                elif clef_type == "f":
                    if (actual_line + 3) >= this_pos > (actual_line - 3):
                        note_octaves.append(3)
                    elif this_pos < (actual_line - 3):
                        note_octaves.append(4)
                    elif this_pos > (actual_line + 3):
                        note_octaves.append(2)
            
        if full_width_episema is True:
            epi = self._create_episema_element()
            epi.attributes = {"form": "horizontal"}
            self.layer.add_child(epi)
        
        qidxs = []
        if has_quilisma:
            self.__note_addition_figurer_outer("q", qidxs)
            
        dotidxs = []
        if has_dot:
            self.__note_addition_figurer_outer("dot", dotidxs)
            
        veidxs = []
        if has_vertical_episema:
            self.__note_addition_figurer_outer("ve", veidxs)
                            
        heidxs = []
        if has_horizontal_episema:
            self.__note_addition_figurer_outer("he", heidxs)
            
        for n in xrange(num_notes):
            p = self._neume_pitches[n]
            o = note_octaves[n]
            nt = self._create_note_element(p)
            nt.attributes = {"oct": o}
            
            if n == 0 and full_width_episema is True:
                epi.attributes = {"startid": nt.id}
            elif n == num_notes and full_width_episema is True:
                epi.attributes = {"endid": nt.id}
            
            if has_quilisma:
                if n in qidxs:
                    neumecomponent.attributes = {"quilisma": "true"}
            
            if has_dot:
                if n in dotidxs:
                    d = self._create_dot_element()
                    nt.add_child(d)
            
            if has_vertical_episema:
                if n in veidxs:
                    ep = self._create_episema_element()
                    ep.attributes = {"form": "vertical", "startid": nt.id}
                    self.layer.add_child(ep)
            
            if has_horizontal_episema:
                if n in heidxs:
                    local_horizontal_episema = self._create_episema_element()
                    local_horizontal_episema.attributes = {"form": "horizontal", "startid": nt.id}
                    self.layer.add_child(local_horizontal_episema)
                    
            
            if n == num_notes - 1 and local_horizontal_episema:
                # we've reached the end, and we have an HE we need to close up.
                local_horizontal_episema.attributes = {"endid": nt.id}
                
            nc.append(nt)
        neumecomponent.add_children(nc)
        
        return neume
Exemplo n.º 15
0
 def _create_system_element(self):
     system = mod.system_()
     system.id = self._idgen()
     return system
Exemplo n.º 16
0
 def _create_layout_element(self):
     layout = mod.layout_()
     layout.id = self._idgen()
     return layout
Exemplo n.º 17
0
 def _create_graphic_element(self, imgfile):
     graphic = mod.graphic_()
     graphic.id = self._idgen()
     graphic.attributes = {'xlink:href': imgfile}
     return graphic
Exemplo n.º 18
0
def create_mei(filename):
	# build new mei file
	meifile=MeiDocument.MeiDocument()
	mei=mod.mei_()
	
	# header
	meihead=mod.meihead_()
	filedesc=mod.filedesc_()
	titlestmt=mod.titlestmt_()
	title=mod.title_()
	pubstmt=mod.pubstmt_()
	
	meihead.add_child(filedesc)
	filedesc.add_children([titlestmt, pubstmt])
	titlestmt.add_child(title)
	
	# music - facsimile, layout, body
	music=mod.music_()
	
	facsimile=mod.facsimile_()
	facsimile.id=generate_mei_id()
	surface=mod.surface_()
	surface.id=generate_mei_id()
	graphic=mod.graphic_()
	graphic.id=generate_mei_id()
	graphic.attributes={'xlink:href':'%s_original_image.tiff' % (filename,)}
	
	facsimile.add_child(surface)
	surface.add_child(graphic)
	
	layout=mod.layout_()
	layout.id=generate_mei_id()
	page=mod.page_()
	page.id=generate_mei_id()
	page.attributes={'n':filename}
	
	layout.add_child(page)
	
	body=mod.body_()
	mdiv=mod.mdiv_()
	mdiv.attributes={'type':'solesmes'}
	score=mod.score_()
	section=mod.section_()
	pb=mod.pb_()
	pb.id=generate_mei_id()
	pb.attributes={'pageref':page.id}
	body.add_child(mdiv)
	mdiv.add_child(score)
	score.add_child(section)
	section.add_child(pb)
	
	music.add_children([facsimile, layout, body])
		
	mei.add_children([meihead, music])
	
	meifile.addelement(mei)
	
	return meifile
Exemplo n.º 19
0
		
	mei.add_children([meihead, music])
	
	meifile.addelement(mei)
	
	return meifile

# import hocr and mei files into lists and strip extension where useful
hocrfiles=[x.split('.')[0] for x in glob.glob('????.html')]
allmeifiles=glob.glob('*.mei')
meifiles=[x.split('_')[0] for x in allmeifiles]
# for each hocr file: if corresponding mei file exists, open mei and edit - if not, create new mei
if options.corrected:
	for hocrfile in hocrfiles:
		output_name='%s_corr.mei' % (hocrfile,) if '%s_corr.mei' % (hocrfile,) in allmeifiles else '%s_uncorr.mei' % (hocrfile,)
		meifile=xmltomei.xmltomei(output_name) if hocrfile in meifiles else create_mei(hocrfile)
		surface=meifile.search('surface')[0]
		section=meifile.search('section')[0]
		add_text_lines(hocrfile, surface, section)
		meitoxml.meitoxml(meifile, '../mei_corrtxt/%s' % (output_name,))
else:
	for hocrfile in hocrfiles:
		meifile=MeiDocument.MeiDocument()
		mei=mod.mei_()
		surface=mod.surface_()
		section=mod.section_()
		mei.add_children([surface, section])
		add_text_lines(hocrfile, surface, section)
		meifile.addelement(mei)
		meitoxml.meitoxml(meifile, '../mei_uncorrtxt/%s_mei_fragment.mei' % (hocrfile,))
Exemplo n.º 20
0
 def _create_division_element(self):
     division = mod.division_()
     division.id = self._idgen()
     zone = self._create_zone_element()
     division.facs = zone.id
     return division
Exemplo n.º 21
0
 def _create_sb_element(self):
     sb = mod.sb_()
     sb.id = self._idgen()
     return sb
Exemplo n.º 22
0
 def _create_pb_element(self):
     pb = mod.pb_()
     pb.id = self._idgen()
     return pb
Exemplo n.º 23
0
 def _create_surface_element(self):
     surface = mod.surface_()
     surface.id = self._idgen()
     return surface
Exemplo n.º 24
0
 def _create_page_element(self):
     page = mod.page_()
     page.id = self._idgen()
     return page
Exemplo n.º 25
0
 def _create_facsimile_element(self):
     facsimile = mod.facsimile_()
     facsimile.id = self._idgen()
     return facsimile
Exemplo n.º 26
0
 def _create_episema_element(self):
     epi = mod.episema_()
     epi.id = self._idgen()
     return epi
Exemplo n.º 27
0
 def _create_note_element(self, pname=None):
     note = mod.note_()
     note.id = self._idgen()
     note.pitchname = pname
     return note
Exemplo n.º 28
0
 def _create_note_element(self, pname=None):
     note = mod.note_()
     note.id = self._idgen()
     note.pitchname = pname
     return note
Exemplo n.º 29
0
 def __init__(self, incoming_data, original_image, page_number=None):
     self._recognition_results = incoming_data
     self.mei = mod.mei_()
     self.staff = None
     self.staff_num = 1
     self.glyph = None
     
     self._note_elements = None
     self._neume_pitches = []
     
     # set up a basic MEI document structure
     
     # header
     self.meihead = mod.meihead_()
     self.filedesc = mod.filedesc_()
     self.titlestmt = mod.titlestmt_()
     self.title = mod.title_()
     self.pubstmt = mod.pubstmt_()
     
     self.titlestmt.add_child(self.title)
     self.filedesc.add_children([self.titlestmt, self.pubstmt])
     self.meihead.add_child(self.filedesc)
     self.mei.add_child(self.meihead)
     
     # music
     self.music = mod.music_()
     self.facsimile = self._create_facsimile_element()
     self.surface = self._create_surface_element()
     self.graphic = self._create_graphic_element(original_image)
     
     self.surface.add_child(self.graphic)
     self.facsimile.add_child(self.surface)
     self.music.add_child(self.facsimile)
     
     self.layout = self._create_layout_element()
     self.pg = self._create_page_element()
     if page_number:
         self.pg.attributes = {"n": page_number}
         
     self.layout.add_child(self.pg)
     self.music.add_child(self.layout)
     
     self.body = mod.body_()
     self.music.add_child(self.body)
     
     self.mdiv = mod.mdiv_()
     self.mdiv.attributes = {"type": "solesmes"}
     self.body.add_child(self.mdiv)
     
     self.score = mod.score_()
     
     self.mdiv.add_child(self.score)
     
     self.scoredef = mod.scoredef_()
     self.score.add_child(self.scoredef)
     
     self.section = mod.section_()
     self.pagebreak = self._create_pb_element()
     self.pagebreak.attributes = {"pageref": self.pg.id}
     
     self.section.add_child(self.pagebreak)
     self.score.add_child(self.section)
     
     self.staffgrp = self._create_staffgrp_element()
     self.staffdef = self._create_staffdef_element()
     self.staffdef.attributes = {'n': self.staff_num}
     
     self.staffgrp.add_child(self.staffdef)
     self.scoredef.add_child(self.staffgrp)
     
     self.layer = self._create_layer_element()
     self.layer.attributes = {'n': 1}
     self.staffel = self._create_staff_element()
     self.staffel.attributes = {'n': self.staff_num}
     self.staffel.add_child(self.layer)
     self.section.add_child(self.staffel)
     
     for sysnum,syst in self._recognition_results.iteritems():            
         self.system = syst
         self.systembreak = self._parse_system(sysnum, syst)
         z = mod.zone_()
         z.id = self._idgen()
         z.attributes = {'ulx': self.system['coord'][0], 'uly': self.system['coord'][1], \
                             'lrx': self.system['coord'][2], 'lry': self.system['coord'][3]}
         
         self.surface.add_child(z)
         # self.system.facs = z.id
         s = self._create_system_element()
         s.facs = z.id
         self.pg.add_child(s)
         self.systembreak.attributes = {"systemref": s.id}
     
     self.mei.add_child(self.music)
     
     if not self.staffel.descendants_by_name('neume'):
         self.staffgrp.remove_child(self.staffdef)
         self.section.remove_child(self.staffel)
     
     self.md = MeiDocument.MeiDocument()
     self.md.addelement(self.mei)
Exemplo n.º 30
0
 def _create_graphic_element(self, imgfile):
     graphic = mod.graphic_()
     graphic.id = self._idgen()
     graphic.attributes = {"xlink:href": imgfile}
     return graphic
Exemplo n.º 31
0
 def _create_custos_element(self):
     custos = mod.custos_()
     custos.id = self._idgen()
     zone = self._create_zone_element()
     custos.facs = zone.id
     return custos
Exemplo n.º 32
0
 def _create_layer_element(self):
     layer = mod.layer_()
     layer.id = self._idgen()
     return layer
Exemplo n.º 33
0
 def _create_staffgrp_element(self):
     stfgrp = mod.staffgrp_()
     stfgrp.id = self._idgen()
     return stfgrp
Exemplo n.º 34
0
def create(docname):
    doc = MeiDocument.MeiDocument(docname)
    
    # set up the header
    root_el = mod.mei_()
    mei_head = mod.meihead_()
    file_desc = mod.filedesc_()
    title_stmt = mod.titlestmt_()
    title = mod.title_()
    title_stmt.add_children([title])
    
    encoding_desc = mod.encodingdesc_()
    proj_desc = mod.projectdesc_()
    dsc = mod.p_()
    dsc.value = u"This file was generated by PyMEI 1.0"
    proj_desc.addchildren([dsc])
    
    file_desc.add_children([title_stmt])
    encoding_desc.add_children([proj_desc])
    
    mei_head.add_children([file_desc, encoding_desc])
    
    # set up the body
    music = mod.music_()
    bd = mod.body_()
    md = mod.mdiv_()
    sc = mod.score_()
    
    md.add_children([sc])
    bd.add_children([md])
    music.add_children([bd])
    
    root_el.addchildren([mei_head, music])
    doc.addelement(root_el)
    
    
    
    return doc
Exemplo n.º 35
0
 def _create_staff_element(self):
     staff = mod.staff_()
     staff.id = self._idgen()
     return staff