Exemplo n.º 1
0
 def descendants_by_name(self, desc_name):
     """ Gets all sub-elements that match a query name """
     r = (d for d in flatten(self) if d.name == desc_name)
     res = tuple(r)
     if not res:
         return None
     return res
Exemplo n.º 2
0
 def get_by_id_ref(self, attrref, attrvalue, tagfilter=None):
     """ Generic function by pointer references within the document to get all
         other tags that contain this ID. For example, given:
         
             ...
             <system sbref="123" />
             ...
             <sb xml:id="123" />
             ...
         
         The call:
         
         get_by_id_ref("sbref", "123")
         
         will return a pointer to the <system /> element in the tree.
         
         If tagfilter is not None, it will only return the attribute values on
         a specific tag, e.g., 
         
         get_by_id_ref("sbref", "123", "system").
         
         This is useful if you have multiple possible places where an attribute is being
         used in the document.
         
         Returns a list of MeiElements that match.
     """
     if not self.__flattened_elements:
         self.__flattened_elements = flatten(self.root)
         
     if tagfilter:
         filt_elements = self.search(tagfilter)
         return [f for f in filt_elements if f.has_attribute(attrref) and f.attribute_by_name(attrref).value == attrvalue]
     else:
         return [f for f in self.__flattened_elements if f.has_attribute(attrref) and f.attribute_by_name(attrref).value == attrvalue]
Exemplo n.º 3
0
 def flat(self):
     """ Returns a flattened list of the elements in this document. Useful
         for searching and doing document-wide operations on many related
         elements in different places in the document.
     """
     if not self.__flattened_elements:
         self.__flattened_elements = flatten(self.root)
     return self.__flattened_elements
Exemplo n.º 4
0
 def descendant_by_id(self, desc_id):
     """ Get a descendant element by that element's unique id """
     r = (d for d in flatten(self) if d.id == desc_id)
     res = tuple(r)
     if not res:
         return None
     elif len(res) > 1:
         raise MeiError("There is more than one element with that ID. Someone screwed up.")
         return None
     else:
         return res[0]
Exemplo n.º 5
0
 def get_by_id(self, id):
     """ Gets a document object by ID. Returns None if the element
         does not exist.
     """
     if not self.__flattened_elements:
         self.__flattened_elements = flatten(self.root)
     # return (o for o in self.__flattened_elements if o.id == id)
     els = self.get_by_id_ref("xml:id", id)
     if not els:
         return None
     else:
         return els[0]
Exemplo n.º 6
0
 def get_system(self, element):
     """ Returns the 'n' attribute of the system break immediately preceding the given MEI Element. 
         If the element is not found, None will be returned. If the element occurs before the first system break,
         -1 will be returned.
     """
     current_system = -1
     if not self.__flattened_elements:
         self.__flattened_elements = flatten(self.root)
     
     for e in self.__flattened_elements:
         if e.name == 'sb':
             current_system = e.attribute_by_name('n').value
         if e.id == element.id:
             return current_system
     return None
Exemplo n.º 7
0
 def search(self, searchterm, *args, **kwargs):
     """ 
         Searches an MEI Document for an object name that matches the
         search term.
         
         @TODO:
         Passing in args will narrow down the search by only retrieving
         objects with that attribute.
         
         Passing in kwargs will narrow down the search by only retrieving
         objects where k = v.
     """
     # there should only be one toplevel element
     if not self.__flattened_elements:
         self.__flattened_elements = flatten(self.root)
         
     return [o for o in self.__flattened_elements if o.name == searchterm]
Exemplo n.º 8
0
 def get_by_id_ref(self, attrref, attrvalue, tagfilter=None):
     """ Generic function by pointer references within the document to get all
         other tags that contain this ID. For example, given:
         
             ...
             <system sbref="123" />
             ...
             <sb xml:id="123" />
             ...
         
         The call:
         
         get_by_id_ref("sbref", "123")
         
         will return a pointer to the <system /> element in the tree.
         
         If tagfilter is not None, it will only return the attribute values on
         a specific tag, e.g., 
         
         get_by_id_ref("sbref", "123", "system").
         
         This is useful if you have multiple possible places where an attribute is being
         used in the document.
         
         Returns a list of MeiElements that match.
     """
     if not self.__flattened_elements:
         self.__flattened_elements = flatten(self.gettoplevel())
     
     def __idfilt(ob, ar=attrref, av=attrvalue, tf=tagfilter):
         try:
             if ob.attribute_by_name(ar).value == av:
                 if not tf:
                     return ob
                 else:
                     if ob.name == tf:
                         return ob
         except AttributeError, e:
             return None
Exemplo n.º 9
0
 def get_by_id(self, id):
     """ Gets a document object by ID. """
     if not self.__flattened_elements:
         self.__flattened_elements = flatten(self.root)
     # return (o for o in self.__flattened_elements if o.id == id)
     return self.get_by_id_ref("xml:id", id)
Exemplo n.º 10
0
        # grab the next eight neumes
        incipit_neumes = []
        for n in flattened[division_index:]:
            if n.name == "neume":
                incipit_neumes.append(n)
            
            if len(incipit_neumes) == 8:
                break
        
        if len(incipit_neumes) < 8:
            continue

        incipit_notes = []
        # grab all the notes in the neumes
        for neume in incipit_neumes:
            neume_notes = [n for n in flatten(neume) if n.name == "note"]
            incipit_notes.extend(neume_notes)

        
        # grab the locations for each neume
        locs = getLocation(incipit_notes, meifile, zones)

        notes = [n.attribute_by_name('pname').value for n in incipit_notes]
        notes = "".join(notes)

        incipits.append({"id": str(uuid.uuid4()), "incipit": notes, "location": str(locs), "pagen": pagen})
    
    print incipits
    solrconn.add_many(incipits)

Exemplo n.º 11
0
def id_to_tstamp(event, base=None): 
    ''' Returns the tstamp of one event. 
    NB: the event needs to be in a layer; the layer is supposed to start at beginning of measure
    '''
    
    def __add_dot(total, dur):
        '''given a total number of dots and a dotted event's duration, calculates the relative duration'''
        rel_dur = 0.0000
        dur = float(dur)
        while total != 1:
            rel_dur += 1 / (dur * 2) 
            dur = dur*2
            total -= 1
        return rel_dur
        
    context = event.ancestor_by_name('layer')
    if context == None:
        raise MeiError('The current event must be in a mei:layer.')
    
    top = event.ancestor_by_name('music') # is there a better way to go up to the top? (say, root, without using MEIDocument?)
    
    #if base is not provided, get it from scoredef
    if base==None:
            
        scoredef = -1
        # get the preceding::scoreDef[0]
        for e in flatten(top):
            if e.name == 'scoreDef':
                scoredef = e
            if e.id == event.id:
                break
    
        if scoredef != -1:
            base = float(scoredef.attribute_by_name('meter.unit').value)
        else:
            raise MeiError('Could not find a score definition.')
            
    #get all events in context (notes + rests. Other events that should be considered?)
    notes = context.descendants_by_name('note') 
    rests = context.descendants_by_name('rest')
    events = []
    
    if notes:
        events += notes
    if rests:
        events += rests
    
    durations = 0.0000
    
    # sum up the durations of events preceding the current event
    for ev in events:
        # stop when reaching the current event
        if ev.id == event.id:
            break
        
        # add current duration
        durations += 1 /  float(event.attribute_by_name('dur').value)
        
        # add dots if present (either as attribute or element)
        # this assumes that dots are encoded either with attribute OR with element - duplication sums up
        if event.attribute_by_name('dots') != None:
            total = float(event.attribute_by_name('dots').value)
            dur = float(event.attribute_by_name('dur').value)
            durations += __add_dot(total, dur)
            
        elif event.descendants_by_name('dot') != None:
            total = float(len(event.descendants_by_name('dot')))
            dur = float(event.attribute_by_name('dur').value)
            durations += __add_dot(total, dur)
            
    # Finally calculate the current timestamp given the sum of preceding durations and the base.
    tstamp = (durations / ( 1 / base)) + 1
    return tstamp