.. _moduleBase:

music21.base
============

.. WARNING: DO NOT EDIT THIS FILE: AUTOMATICALLY GENERATED. Edit the .py file directly

.. module:: music21.base


Music21 base classes for :class:`~music21.stream.Stream` objects and elements
contained within them. Additional objects for defining and manipulating
elements are included.

The namespace of this file, as all base.py files, is loaded into the package
that contains this file via __init__.py. Everything in this file is thus
available after importing music21.



>>> import music21
>>> music21.Music21Object
<class 'music21.base.Music21Object'>
⁠ 
>>> music21.VERSION_STR
'1.1.0'

Alternatively, after doing a complete import, these classes are available
under the module "base":



>>> from music21 import *
>>> base.Music21Object
<class 'music21.base.Music21Object'>




Music21Object
-------------

Inherits from: :class:`~music21.base.JSONSerializer`

.. class:: Music21Object(*arguments, **keywords)


    Base class for all music21 objects.

    All music21 objects have six pieces of information:

    1. id: identification string unique to the objects container (optional)
    2. groups: a Groups object: which is a list of strings identifying
       internal subcollections (voices, parts, selections) to which this element belongs
    3. duration: Duration object representing the length of the object
    4. activeSite: a weakreference to the currently active Location
    5. offset: a floating point value, generally in quarter lengths, specifying the position of the object in a site.
    6. priority: int representing the position of an object among all
       objects at the same offset.

    Contexts, locations, and offsets are stored in a  :class:`~music21.base.DefinedContexts` object. Locations specify connections of this object to one location in a Stream subclass. Contexts are weakrefs for current objects that are associated with this object (similar to locations but without an offset)


    Each of these may be passed in as a named keyword to any music21 object.

    Some of these may be intercepted by the subclassing object (e.g., duration within Note)



    **Music21Object** **attributes**

        .. attribute:: classSortOrder

            Property which returns an number (int or otherwise)
            depending on the class of the Music21Object that
            represents a priority for an object based on its class alone --
            used as a tie for stream sorting in case two objects have the
            same offset and priority.  Lower numbers are sorted to the left
            of higher numbers.  For instance, Clef, KeySignature, TimeSignature
            all come (in that order) before Note.

            All undefined classes have classSortOrder of 20 -- same as note.Note



            >>> from music21 import *
            >>> tc = clef.TrebleClef()
            >>> tc.classSortOrder
            0
            >>> ks = key.KeySignature(3)
            >>> ks.classSortOrder
            1


            New classes can define their own default classSortOrder



            >>> class ExampleClass(base.Music21Object):
            ...     classSortOrderDefault = 5
            ...
            >>> ec1 = ExampleClass()
            >>> ec1.classSortOrder
            5



        .. attribute:: hideObjectOnPrint

            if set to True will not print upon output (only to MusicXML at this point)


        .. attribute:: groups

            An instance of a Group object.


        .. attribute:: id

            Unique identification string.


        Attributes without Documentation: `isSpanner`, `isStream`, `isVariant`

    **Music21Object** **properties**

        .. attribute:: activeSite

            A reference to the most-recent object used to
            contain this object. In most cases, this will be a
            Stream or Stream sub-class. In most cases, an object's
            activeSite attribute is automatically set when an the
            object is attached to a Stream.




            >>> from music21 import *
            >>> n = note.Note("C#4")
            >>> p = stream.Part()
            >>> p.insert(20.0, n)
            >>> n.activeSite is p
            True
            >>> n.offset
            20.0
            ⁠ 
            >>> m = stream.Measure()
            >>> m.insert(10.0, n)
            >>> n.activeSite is m
            True
            >>> n.offset
            10.0
            >>> n.activeSite = p
            >>> n.offset
            20.0



        .. attribute:: beat

            Return the beat of this object as found in the most
            recently positioned Measure. Beat values count from 1 and
            contain a floating-point designation between 0 and 1 to
            show proportional progress through the beat.



            >>> from music21 import *
            >>> n = note.Note()
            >>> n.quarterLength = .5
            >>> m = stream.Measure()
            >>> m.timeSignature = meter.TimeSignature('3/4')
            >>> m.repeatAppend(n, 6)
            >>> [m.notes[i].beat for i in range(6)]
            [1.0, 1.5, 2.0, 2.5, 3.0, 3.5]
            ⁠ 
            >>> m.timeSignature = meter.TimeSignature('6/8')
            >>> [m.notes[i].beat for i in range(6)]
            [1.0, 1.3333333..., 1.666666666..., 2.0, 2.33333333..., 2.66666...]



            >>> s = stream.Stream()
            >>> s.insert(0, meter.TimeSignature('3/4'))
            >>> s.repeatAppend(note.Note(), 8)
            >>> [n.beat for n in s.notes]
            [1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0]



        .. attribute:: beatDuration

            Return a :class:`~music21.duration.Duration` of the beat active for this object as found in the most recently positioned Measure.

            If extending beyond the Measure, or in a Stream with a TimeSignature, the meter modulus value will be returned.



            >>> from music21 import *
            >>> n = note.Note()
            >>> n.quarterLength = .5
            >>> m = stream.Measure()
            >>> m.timeSignature = meter.TimeSignature('3/4')
            >>> m.repeatAppend(n, 6)
            >>> [m.notes[i].beatDuration.quarterLength for i in range(6)]
            [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
            ⁠ 
            >>> m.timeSignature = meter.TimeSignature('6/8')
            >>> [m.notes[i].beatDuration.quarterLength for i in range(6)]
            [1.5, 1.5, 1.5, 1.5, 1.5, 1.5]



            >>> s = stream.Stream()
            >>> s.insert(0, meter.TimeSignature('2/4+3/4'))
            >>> s.repeatAppend(note.Note(), 8)
            >>> [n.beatDuration.quarterLength for n in s.notes]
            [2.0, 2.0, 3.0, 3.0, 3.0, 2.0, 2.0, 3.0]



        .. attribute:: beatStr

            Return a string representation of the beat of
            this object as found in the most recently positioned
            Measure. Beat values count from 1 and contain a
            fractional designation to show progress through the beat.



            >>> from music21 import *
            >>> n = note.Note()
            >>> n.quarterLength = .5
            >>> m = stream.Measure()
            >>> m.timeSignature = meter.TimeSignature('3/4')
            >>> m.repeatAppend(n, 6)
            >>> [m.notes[i].beatStr for i in range(6)]
            ['1', '1 1/2', '2', '2 1/2', '3', '3 1/2']
            >>> m.timeSignature = meter.TimeSignature('6/8')
            >>> [m.notes[i].beatStr for i in range(6)]
            ['1', '1 1/3', '1 2/3', '2', '2 1/3', '2 2/3']
            ⁠ 
            >>> s = stream.Stream()
            >>> s.insert(0, meter.TimeSignature('3/4'))
            >>> s.repeatAppend(note.Note(), 8)
            >>> [n.beatStr for n in s.notes]
            ['1', '2', '3', '1', '2', '3', '1', '2']



        .. attribute:: beatStrength

            Return the metrical accent of this object
            in the most recently positioned Measure. Accent values
            are between zero and one, and are derived from the local
            TimeSignature's accent MeterSequence weights. If the offset
            of this object does not match a defined accent weight, a
            minimum accent weight will be returned.



            >>> from music21 import *
            >>> n = note.Note()
            >>> n.quarterLength = .5
            >>> m = stream.Measure()
            >>> m.timeSignature = meter.TimeSignature('3/4')
            >>> m.repeatAppend(n, 6)
            >>> [m.notes[i].beatStrength for i in range(6)]
            [1.0, 0.25, 0.5, 0.25, 0.5, 0.25]
            ⁠ 
            >>> m.timeSignature = meter.TimeSignature('6/8')
            >>> [m.notes[i].beatStrength for i in range(6)]
            [1.0, 0.25, 0.25, 0.5, 0.25, 0.25]


            We can also get the beatStrength for elements not in
            a measure, if the enclosing stream has a :class:`~music21.meter.TimeSignature`.
            We just assume that the time signature carries through to
            hypothetical following measures:




            >>> n = note.QuarterNote("E--3")
            >>> s = stream.Stream()
            >>> s.insert(0.0, meter.TimeSignature('2/2'))
            >>> s.repeatAppend(n, 12)
            >>> [s.notes[i].beatStrength for i in range(12)]
            [1.0, 0.25, 0.5, 0.25, 1.0, 0.25, 0.5, 0.25, 1.0, 0.25, 0.5, 0.25]


            Changing the meter changes the output, of course:



            >>> s.insert(4.0, meter.TimeSignature('3/4'))
            >>> [s.notes[i].beatStrength for i in range(12)]
            [1.0, 0.25, 0.5, 0.25, 1.0, 0.5, 0.5, 1.0, 0.5, 0.5, 1.0, 0.5]




        .. attribute:: classes

            Returns a list containing the names (strings, not objects) of classes that this
            object belongs to -- starting with the object's class name and going up the mro()
            for the object.  Very similar to Perl's @ISA array:



            >>> from music21 import *
            >>> q = note.QuarterNote()
            >>> q.classes[:5]
            ['QuarterNote', 'Note', 'NotRest', 'GeneralNote', 'Music21Object']


            Example: find GClefs that are not Treble clefs (or treble 8vb, etc.):




            >>> s = stream.Stream()
            >>> s.insert(10, clef.GClef())
            >>> s.insert(20, clef.TrebleClef())
            >>> s.insert(30, clef.FrenchViolinClef())
            >>> s.insert(40, clef.Treble8vbClef())
            >>> s.insert(50, clef.BassClef())
            >>> s2 = stream.Stream()
            >>> for t in s:
            ...    if 'GClef' in t.classes and 'TrebleClef' not in t.classes:
            ...        s2.insert(t)
            >>> s2.show('text')
            {10.0} <music21.clef.GClef>
            {30.0} <music21.clef.FrenchViolinClef>



        .. attribute:: derivationHierarchy


            Return a list of Stream subclasses that this Stream
            is contained within. This provides a way of seeing
            Streams contained within Streams.



            >>> from music21 import *
            >>> s = corpus.parse('bach/bwv66.6')
            >>> [str(e.__class__) for e in s[1][2][3].derivationHierarchy]
            ["<class 'music21.stream.Measure'>", "<class 'music21.stream.Part'>", "<class 'music21.stream.Score'>"]



        .. attribute:: duration

            Get and set the duration of this object as a Duration object.



        .. attribute:: isGrace


            Return True or False if this music21 object has a GraceDuration.



            >>> from music21 import *
            >>> n = note.Note()
            >>> n.isGrace
            False
            >>> ng = n.getGrace()
            >>> ng.isGrace
            True




        .. attribute:: measureNumber

            Return the measure number of a Measure that contains this object.



        .. attribute:: offset

            The offset property returns the position of this object from
            the start of its most recently referenced container (a Stream or
            Stream sub-class found in activeSite) in quarter lengths.

            It can also set the offset for the object if no container has been
            set



            >>> from music21 import *
            >>> n1 = note.Note()
            >>> n1.id = 'hi'
            >>> n1.offset = 20
            >>> n1.offset
            20.0
            >>> s1 = stream.Stream()
            >>> s1.append(n1)
            >>> n1.offset
            0.0
            >>> s2 = stream.Stream()
            >>> s2.insert(30.5, n1)
            >>> n1.offset
            30.5
            >>> n2 = s1.getElementById('hi')
            >>> n2 is n1
            True
            >>> n2.offset
            0.0
            >>> for thisElement in s2:
            ...     print thisElement.offset
            30.5




        .. attribute:: priority

            Get and set the priority integer value.

            Priority specifies the order of processing from left (lowest number)
            to right (highest number) of objects at the same offset.  For
            instance, if you want a key change and a clef change to happen at
            the same time but the key change to appear first, then set:
            keySigElement.priority = 1; clefElement.priority = 2 this might be
            a slightly counterintuitive numbering of priority, but it does
            mean, for instance, if you had two elements at the same offset,
            an allegro tempo change and an andante tempo change, then the
            tempo change with the higher priority number would apply to the
            following notes (by being processed second).

            Default priority is 0; thus negative priorities are encouraged
            to have Elements that appear non-priority set elements.

            In case of tie, there are defined class sort orders defined in
            music21.base.CLASS_SORT_ORDER.  For instance, a key signature
            change appears before a time signature change before a
            note at the same offset.  This produces the familiar order of
            materials at the start of a musical score.



            >>> import music21
            >>> a = music21.Music21Object()
            >>> a.priority = 3
            >>> a.priority = 'high'
            Traceback (most recent call last):
            ElementException: priority values must be integers.



        .. attribute:: seconds


            Get or set the the duration of this object in seconds, assuming that this object has a :class:`~music21.tempo.MetronomeMark` or :class:`~music21.tempo.MetricModulation` in its past context.



            >>> from music21 import *
            >>> s = stream.Stream()
            >>> s.repeatAppend(note.Note(), 12)
            >>> s.insert(0, tempo.MetronomeMark(number=120))
            >>> s.insert(6, tempo.MetronomeMark(number=240))
            >>> [n.seconds for n in s.notes]
            [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25]



        Properties inherited from :class:`~music21.base.JSONSerializer`: :attr:`~music21.base.JSONSerializer.json`

    **Music21Object** **methods**

        .. method:: searchActiveSiteByAttr(attrName)

            If this element is contained within a Stream or other Music21 element,
            searchActiveSiteByAttr() permits searching attributes of higher-level
            objects. The first encountered match is returned, or None if no match. All activeSites are recursively searched upward.



        .. method:: getContextAttr(attr)

            Given the name of an attribute, search Conctexts and return
            the best match.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     attr1 = 234
            >>> aObj = Mock()
            >>> aObj.attr1 = 'test'
            >>> a = music21.Music21Object()
            >>> a.addContext(aObj)
            >>> a.getContextAttr('attr1')
            'test'



        .. method:: setContextAttr(attrName, value)

            Given the name of an attribute, search Conctexts and return
            the best match.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     attr1 = 234
            >>> aObj = Mock()
            >>> aObj.attr1 = 'test'
            >>> a = music21.Music21Object()
            >>> a.addContext(aObj)
            >>> a.getContextAttr('attr1')
            'test'
            >>> a.setContextAttr('attr1', 3000)
            >>> a.getContextAttr('attr1')
            3000



        .. method:: addContext(obj)

            Add an object to the :class:`~music21.base.DefinedContexts` object. For adding a location, use :meth:`~music21.base.Music21Object.addLocation`.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     attr1 = 234
            >>> aObj = Mock()
            >>> aObj.attr1 = 'test'
            >>> a = music21.Music21Object()
            >>> a.addContext(aObj)
            >>> a.getContextAttr('attr1')
            'test'



        .. method:: addLocation(site, offset)


            Add a location to the :class:`~music21.base.DefinedContexts` object.
            The supplied object is a reference to the object (the site) that
            contains an offset of this object.  For example, if this
            Music21Object was Note, the site would be a Stream (or Stream
            subclass) and the offset would be a number for the offset.


            This is only for advanced location method and is not a complete
            or sufficient way to add an object to a Stream.




            >>> from music21 import note, stream
            >>> s = stream.Stream()
            >>> n = note.Note('E-5')
            >>> n.addLocation(s, 10)



        .. method:: addLocationAndActiveSite(offset, activeSite, activeSiteWeakRef=None)


            This method is for advanced usage, generally as a speedup tool that adds a
            new location element and a new activeSite.  Formerly called
            by Stream.insert -- this saves some dual processing.
            Does not do safety checks that
            the siteId doesn't already exist etc., because that is done earlier.

            This speeds up things like stream.getElementsById substantially.

            Testing script (N.B. manipulates Stream._elements directly -- so not to be emulated)



            >>> import music21
            >>> from music21.stream import Stream
            >>> st1 = Stream()
            >>> o1 = music21.Music21Object()
            >>> st1_wr = common.wrapWeakref(st1)
            >>> offset = 20.0
            >>> st1._elements = [o1]
            >>> o1.addLocationAndActiveSite(offset, st1, st1_wr)
            >>> o1.activeSite is st1
            True
            >>> o1.getOffsetBySite(st1)
            20.0



        .. method:: freezeIds()

            Temporarily replace are stored keys with a different value.



            >>> import music21
            >>> aM21Obj = music21.Music21Object()
            >>> bM21Obj = music21.Music21Object()
            >>> aM21Obj.offset = 30
            >>> aM21Obj.getOffsetBySite(None)
            30.0
            >>> bM21Obj.addLocationAndActiveSite(50, aM21Obj)
            >>> bM21Obj.activeSite != None
            True
            >>> oldActiveSiteId = bM21Obj._activeSiteId
            >>> bM21Obj.freezeIds()
            >>> newActiveSiteId = bM21Obj._activeSiteId
            >>> oldActiveSiteId == newActiveSiteId
            False



        .. method:: getAllContextsByClass(className, found=None, idFound=None, memo=None)

            Search both DefinedContexts as well as associated
            objects to find all matchinging classes.
            Returns [] if not match is found.



        .. method:: getCommonSiteIds(other)

            Given another music21 object, return a
            list of all common site ids. Do not include
            the default empty site, None.




            >>> from music21 import note, stream
            >>> s1 = stream.Stream()
            >>> s2 = stream.Stream()
            >>> n1 = note.Note()
            >>> n2 = note.Note()
            >>> s1.append(n1)
            >>> s1.append(n2)
            >>> s2.append(n2)
            >>> n1.getCommonSiteIds(n2) == [id(s1)]
            True
            >>> s2.append(n1)
            >>> n1.getCommonSiteIds(n2) == [id(s1), id(s2)]
            True



        .. method:: getCommonSites(other)

            Given another object, return a list of all sites
            in common between the two objects.



            >>> from music21 import note, stream
            >>> s1 = stream.Stream()
            >>> s2 = stream.Stream()
            >>> n1 = note.Note()
            >>> n2 = note.Note()
            >>> s1.append(n1)
            >>> s1.append(n2)
            >>> s2.append(n2)
            >>> n1.getCommonSites(n2) == [s1]
            True
            >>> s2.append(n1)
            >>> n1.getCommonSites(n2) == [s1, s2]
            True




        .. method:: getContextByClass(className, serialReverseSearch=True, callerFirst=None, sortByCreationTime=False, prioritizeActiveSite=True, getElementMethod='getElementAtOrBefore', memo=None)

            Search both DefinedContexts as well as associated objects
            to find a matching class. Returns None if not match is found.

            The a reference to the caller is required to find the offset of the
            object of the caller. This is needed for serialReverseSearch.

            The caller may be a DefinedContexts reference from a lower-level object.
            If so, we can access the location of that lower-level object. However,
            if we need a flat representation, the caller needs to be the source
            Stream, not its DefinedContexts reference.

            The `callerFirst` is the first object from which this method
            was called. This is needed in order to determine the final offset from which to search.

            The `prioritizeActiveSite` parameter searches the object's activeSite
            before any other object. By default this is True

            The `getElementMethod` is a string that selects which Stream method is used to
            get elements for searching. The strings 'getElementAtOrBefore' and 'getElementBeforeOffset' are currently accepted.




        .. method:: getOffsetBySite(site)

            If this class has been registered in a container such as a Stream,
            that container can be provided here, and the offset in that object
            can be returned.

            Note that this is different than the getOffsetByElement() method on
            Stream in that this can never access the flat representation of a Stream.



            >>> from music21 import *
            >>> a = base.Music21Object()
            >>> a.offset = 30
            >>> a.getOffsetBySite(None)
            30.0
            ⁠ 
            >>> s1 = stream.Stream()
            >>> s1.insert(20.5, a)
            >>> a.getOffsetBySite(s1)
            20.5
            >>> s2 = stream.Stream()
            >>> a.getOffsetBySite(s2)
            Traceback (most recent call last):
            ...
            DefinedContextsException: Could not find the object with id ...




        .. method:: getSiteIds()

            Return a list of all site Ids, or the
            id() value of the sites of this object.



        .. method:: getSites(idExclude=None)

            Return a list of all objects that store
            a location for this object. Will inlcude None,
            the default empty site placeholder.


            If `idExclude` is provided, matching site ids will not be returned.




            >>> from music21 import note, stream
            >>> s1 = stream.Stream()
            >>> s2 = stream.Stream()
            >>> n = note.Note()
            >>> s1.append(n)
            >>> s2.append(n)
            >>> n.getSites() == [None, s1, s2]
            True



        .. method:: getSpannerSites()

            Return a list of all sites that are
            Spanner or Spanner subclasses. This provides a way for
            objects to be aware of what Spanners they
            reside in. Note that Spanners are not Stream
            subclasses, but Music21Objects that are composed with
            a specialized Stream subclass, SapnnerStroage



            >>> from music21 import *
            >>> n1 = note.Note()
            >>> n2 = note.Note()
            >>> sp1 = spanner.Slur(n1, n2)
            >>> n1.getSpannerSites() == [sp1]
            True
            >>> sp2 = spanner.Slur(n2, n1)
            >>> n2.getSpannerSites() == [sp1, sp2]
            True



        .. method:: hasContext(obj)


            Return a Boolean if an object reference is stored
            in the object's DefinedContexts object.

            This checks both all locations as well as all sites.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     attr1 = 234
            >>> aObj = Mock()
            >>> aObj.attr1 = 'test'
            >>> a = music21.Music21Object()
            >>> a.addContext(aObj)
            >>> a.hasContext(aObj)
            True
            >>> a.hasContext(None)
            True
            >>> a.hasContext(45)
            False



        .. method:: hasSite(other)

            Return True if other is a site in this Music21Object



            >>> from music21 import *
            >>> s = stream.Stream()
            >>> n = note.Note()
            >>> s.append(n)
            >>> n.hasSite(s)
            True
            >>> n.hasSite(stream.Stream())
            False



        .. method:: hasSpannerSite()

            Return True if this object is found in
            any Spanner (i.e. has any spanners attached).
            This is determined by looking
            for a SpannerStorage Stream class as a Site.




            >>> from music21 import *
            >>> n1 = note.Note()
            >>> n2 = note.Note()
            >>> n3 = note.Note()
            >>> sp1 = spanner.Slur(n1, n2)
            >>> n1.getSpannerSites() == [sp1]
            True
            >>> sp2 = spanner.Slur(n2, n1)
            >>> n1.hasSpannerSite()
            True
            >>> n2.hasSpannerSite()
            True
            >>> n3.hasSpannerSite()
            False



        .. method:: hasVariantSite()

            Return True if this object is found in
            any Variant
            This is determined by looking
            for a VariantStorage Stream class as a Site.




            >>> from music21 import *
            >>> n1 = note.Note()
            >>> n2 = note.Note()
            >>> n3 = note.Note()
            >>> v1 = variant.Variant([n1, n2])
            >>> n1.hasSpannerSite()
            False
            >>> n1.hasVariantSite()
            True
            >>> n2.hasVariantSite()
            True
            >>> n3.hasVariantSite()
            False



        .. method:: isClassOrSubclass(classFilterList)

            Given a class filter list (a list or tuple must be submitted), which may have strings or class objects, determine if this class is of the provided classes or a subclasses.



        .. method:: mergeAttributes(other)


            Merge all elementary, static attributes. Namely,
            `id` and `groups` attributes from another music21 object.
            Can be useful for copy-like operations.



        .. method:: next(classFilterList=None, flattenLocalSites=False, beginNearest=True)

            Get the next element found in a site of this Music21Object.

            The `classFilterList` can be used to specify one or more classes to match.

            The `flattenLocalSites` parameter determines if the sites of this element (e.g., a Measure's Part) are flattened on first search. When True, elements contained in adjacent containers may be selected first.



            >>> from music21 import *
            >>> s = corpus.parse('bwv66.6')
            >>> s.parts[0].measure(3).next() == s.parts[0].measure(4)
            True
            >>> s.parts[0].measure(3).next('Note', flattenLocalSites=True) == s.parts[0].measure(3).notes[0]
            True



        .. method:: previous(classFilterList=None, flattenLocalSites=False, beginNearest=True)

            Get the previous element found in a site of this Music21Object.

            The `classFilterList` can be used to specify one or more classes to match.

            The `flattenLocalSites` parameter determines if the sites of this element (e.g., a Measure's Part) are flattened on first search. When True, elements contained in adjacent containers may be selected first.



            >>> from music21 import *
            >>> s = corpus.parse('bwv66.6')
            >>> s.parts[0].measure(3).previous() == s.parts[0].measure(2)
            True
            >>> s.parts[0].measure(3).previous('Note', flattenLocalSites=True) == s.parts[0].measure(2).notes[-1]
            True



        .. method:: purgeLocations(rescanIsDead=False)

            Remove references to all locations in objects that no longer exist.



        .. method:: purgeOrphans(excludeStorageStreams=True)

            A Music21Object may, due to deep copying or other reasons, have contain a site (with an offset); yet, that site may no longer contain the Music21Object. These lingering sites are called orphans. This methods gets rid of them.

            The `excludeStorageStreams` are SpannerStorage and VariantStorage.



        .. method:: purgeUndeclaredIds(declaredIds, excludeStorageStreams=True)

            Remove all sites except those that are declared with the `declaredIds` list.

            The `excludeStorageStreams` are SpannerStorage and VariantStorage.

            This method is used in Stream serialization to remove lingering sites that are the result of temporary Streams.



        .. method:: removeLocationBySite(site)

            Remove a location in the :class:`~music21.base.DefinedContexts` object.

            This is only for advanced location method and
            is not a complete or sufficient way to remove an object from a Stream.



            >>> from music21 import note, stream
            >>> s = stream.Stream()
            >>> n = note.Note()
            >>> n.addLocation(s, 10)
            >>> n.activeSite = s
            >>> n.removeLocationBySite(s)
            >>> n.activeSite == None
            True



        .. method:: removeLocationBySiteId(siteId)

            Remove a location in the
            :class:`~music21.base.DefinedContexts` object by id.



            >>> from music21 import note, stream
            >>> s = stream.Stream()
            >>> n = note.Note()
            >>> n.addLocation(s, 10)
            >>> n.activeSite = s
            >>> n.removeLocationBySiteId(id(s))
            >>> n.activeSite == None
            True



        .. method:: setOffsetBySite(site, value)


            Direct access to the DefinedContexts setOffsetBySite() method.
            This should only be used for advanced processing of known site
            that already has been added.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> a = music21.Music21Object()
            >>> a.addLocation(aSite, 20)
            >>> a.setOffsetBySite(aSite, 30)
            >>> a.getOffsetBySite(aSite)
            30



        .. method:: show(fmt=None, app=None)


            Displays an object in a format provided by the
            fmt argument or, if not provided, the format set in the user's Environment

            Valid formats include (but are not limited to)::
                xml (musicxml)
                text
                midi
                lily (or lilypond)
                lily.png
                lily.pdf
                lily.svg
                braille
                vexflow

            N.B. score.write('lily') returns a bare lilypond file,
            score.show('lily') gives a png of a rendered lilypond file.




        .. method:: splitAtDurations()


            Takes a Music21Object (e.g., a note.Note) and returns a list of similar
            objects with only a single
            duration.DurationUnit in each. Ties are added if the object supports ties.

            Articulations only appear on the first note.  Same with lyrics.

            Fermatas should be on last note, but not done yet.



            >>> from music21 import *
            >>> a = note.Note()
            >>> a.duration.clear() # remove defaults
            >>> a.duration.addDurationUnit(duration.Duration('half'))
            >>> a.duration.quarterLength
            2.0
            >>> a.duration.addDurationUnit(duration.Duration('whole'))
            >>> a.duration.quarterLength
            6.0
            >>> b = a.splitAtDurations()
            >>> b[0].pitch == b[1].pitch
            True
            >>> b[0].duration.type
            'half'
            >>> b[1].duration.type
            'whole'




            >>> c = note.Note()
            >>> c.quarterLength = 2.5
            >>> d, e = c.splitAtDurations()
            >>> d.duration.type
            'half'
            >>> e.duration.type
            'eighth'
            >>> d.tie.type
            'start'
            >>> print e.tie
            <music21.tie.Tie stop>

            Assume c is tied to the next note.  Then the last split note should also be tied



            >>> c.tie = tie.Tie()
            >>> d, e = c.splitAtDurations()
            >>> e.tie.type
            'start'


            Rests have no ties:



            >>> f = note.Rest()
            >>> f.quarterLength = 2.5
            >>> g, h = f.splitAtDurations()
            >>> (g.duration.type, h.duration.type)
            ('half', 'eighth')
            >>> g.tie is None
            True



        .. method:: splitAtQuarterLength(quarterLength, retainOrigin=True, addTies=True, displayTiedAccidentals=False, delta=1e-06)


            Split an Element into two Elements at a provided
            QuarterLength into the Element.



            >>> from music21 import *
            >>> a = note.Note('C#5')
            >>> a.duration.type = 'whole'
            >>> a.articulations = [articulations.Staccato()]
            >>> a.lyric = 'hi'
            >>> a.expressions = [expressions.Mordent(), expressions.Trill(), expressions.Fermata()]
            >>> b, c = a.splitAtQuarterLength(3)
            >>> b.duration.type
            'half'
            >>> b.duration.dots
            1
            >>> b.duration.quarterLength
            3.0
            >>> b.articulations
            [<music21.articulations.Staccato>]
            >>> b.lyric
            'hi'
            >>> b.expressions
            [<music21.expressions.Mordent>, <music21.expressions.Trill>]
            >>> c.duration.type
            'quarter'
            >>> c.duration.dots
            0
            >>> c.duration.quarterLength
            1.0
            >>> c.articulations
            []
            >>> c.lyric
            >>> c.expressions
            [<music21.expressions.Trill>, <music21.expressions.Fermata>]




        .. method:: splitByQuarterLengths(quarterLengthList, addTies=True, displayTiedAccidentals=False)

            Given a list of quarter lengths, return a list of
            Music21Object objects, copied from this Music21Object,
            that are partitioned and tied with the specified quarter
            length list durations.



            >>> from music21 import *
            >>> n = note.Note()
            >>> n.quarterLength = 3
            >>> post = n.splitByQuarterLengths([1,1,1])
            >>> [n.quarterLength for n in post]
            [1.0, 1.0, 1.0]



        .. method:: unfreezeIds()

            Restore keys to be the id() of the object they contain



            >>> import music21
            >>> aM21Obj = music21.Music21Object()
            >>> bM21Obj = music21.Music21Object()
            >>> aM21Obj.offset = 30
            >>> aM21Obj.getOffsetBySite(None)
            30.0
            >>> bM21Obj.addLocationAndActiveSite(50, aM21Obj)
            >>> bM21Obj.activeSite != None
            True
            >>> oldActiveSiteId = bM21Obj._activeSiteId
            >>> bM21Obj.freezeIds()
            >>> newActiveSiteId = bM21Obj._activeSiteId
            >>> oldActiveSiteId == newActiveSiteId
            False
            >>> bM21Obj.unfreezeIds()
            >>> postActiveSiteId = bM21Obj._activeSiteId
            >>> oldActiveSiteId == postActiveSiteId
            True



        .. method:: unwrapWeakref()

            Public interface to operation on DefinedContexts.

            NOTE: Any Music21Object subclass that contains private Streams (like Spanner and Variant) must override theses methods



            >>> import music21
            >>> aM21Obj = music21.Music21Object()
            >>> bM21Obj = music21.Music21Object()
            >>> aM21Obj.offset = 30
            >>> aM21Obj.getOffsetBySite(None)
            30.0
            >>> aM21Obj.addLocationAndActiveSite(50, bM21Obj)
            >>> aM21Obj.unwrapWeakref()




        .. method:: wrapWeakref()

            Public interface to operation on DefinedContexts.



            >>> import music21
            >>> aM21Obj = music21.Music21Object()
            >>> bM21Obj = music21.Music21Object()
            >>> aM21Obj.offset = 30
            >>> aM21Obj.getOffsetBySite(None)
            30.0
            >>> aM21Obj.addLocationAndActiveSite(50, bM21Obj)
            >>> aM21Obj.unwrapWeakref()
            >>> aM21Obj.wrapWeakref()



        .. method:: write(fmt=None, fp=None)

            Write a file.

            A None file path will result in temporary file



        Methods inherited from :class:`~music21.base.JSONSerializer`: :meth:`~music21.base.JSONSerializer.jsonAttributes`, :meth:`~music21.base.JSONSerializer.jsonComponentFactory`, :meth:`~music21.base.JSONSerializer.jsonPrint`, :meth:`~music21.base.JSONSerializer.jsonRead`, :meth:`~music21.base.JSONSerializer.jsonWrite`


ElementWrapper
--------------

Inherits from: :class:`~music21.base.Music21Object`, :class:`~music21.base.JSONSerializer`

.. class:: ElementWrapper(obj=None)


    An element wraps any object that is not a
    :class:`~music21.base.Music21Object`, so that that object can
    be positioned within a :class:`~music21.stream.Stream`.

    The object stored within ElementWrapper is available from
    the the :attr:`~music21.base.ElementWrapper.obj` attribute.
    All the attributes of the stored object (except .id and
    anything else that conflicts with a Music21Object attribute)
    are gettable and settable by querying the ElementWrapper.
    This feature makes it possible easily to mix Music21Objects
    and non-Music21Objects with similarly named attributes in the
    same Stream.


    This example inserts 10 random wave files into a music21
    Stream and then reports their filename and number of
    audio channels (in this example, it's always 2) if they
    fall on a strong beat in fast 6/8




    >>> import music21
    >>> from music21 import stream, meter
    >>> import wave
    >>> import random
    ⁠ 
    >>> s = stream.Stream()
    >>> s.append(meter.TimeSignature('fast 6/8'))
    >>> for i in range(10):
    ...    fileName = 'thisSound_' + str(random.randint(1,20)) + '.wav'
    ...    soundFile = wave.open(fileName)
    ...    soundFile.fileName = fileName
    ...    el = music21.ElementWrapper(soundFile)
    ...    s.insert(i, el)



    >>> for j in s.getElementsByClass('ElementWrapper'):
    ...    if j.beatStrength > 0.4:
    ...        print j.offset, j.beatStrength, j.getnchannels(), j.fileName
    0.0 1.0 2 thisSound_1.wav
    3.0 1.0 2 thisSound_16.wav
    6.0 1.0 2 thisSound_12.wav
    9.0 1.0 2 thisSound_8.wav





    **ElementWrapper** **attributes**

        .. attribute:: obj

            The object this wrapper wraps.


        Attributes inherited from :class:`~music21.base.Music21Object`: :attr:`~music21.base.Music21Object.classSortOrder`, :attr:`~music21.base.Music21Object.isSpanner`, :attr:`~music21.base.Music21Object.isStream`, :attr:`~music21.base.Music21Object.isVariant`, :attr:`~music21.base.Music21Object.hideObjectOnPrint`, :attr:`~music21.base.Music21Object.groups`, :attr:`~music21.base.Music21Object.id`

    **ElementWrapper** **properties**

        Properties inherited from :class:`~music21.base.Music21Object`: :attr:`~music21.base.Music21Object.activeSite`, :attr:`~music21.base.Music21Object.beat`, :attr:`~music21.base.Music21Object.beatDuration`, :attr:`~music21.base.Music21Object.beatStr`, :attr:`~music21.base.Music21Object.beatStrength`, :attr:`~music21.base.Music21Object.classes`, :attr:`~music21.base.Music21Object.derivationHierarchy`, :attr:`~music21.base.Music21Object.duration`, :attr:`~music21.base.Music21Object.isGrace`, :attr:`~music21.base.Music21Object.measureNumber`, :attr:`~music21.base.Music21Object.offset`, :attr:`~music21.base.Music21Object.priority`, :attr:`~music21.base.Music21Object.seconds`

        Properties inherited from :class:`~music21.base.JSONSerializer`: :attr:`~music21.base.JSONSerializer.json`

    **ElementWrapper** **methods**

        .. method:: isTwin(other)

            A weaker form of equality.  a.isTwin(b) is true if
            a and b store either the same object OR objects that are equal.
            In other words, it is essentially the same object in a different context



            >>> import music21
            >>> from music21 import note
            ⁠ 
            >>> aE = music21.ElementWrapper(obj = "hello")



            >>> bE = copy.copy(aE)
            >>> aE is bE
            False
            >>> aE == bE
            True
            >>> aE.isTwin(bE)
            True
            ⁠ 
            >>> bE.offset = 14.0
            >>> bE.priority = -4
            >>> aE == bE
            False
            >>> aE.isTwin(bE)
            True



        Methods inherited from :class:`~music21.base.Music21Object`: :meth:`~music21.base.Music21Object.addContext`, :meth:`~music21.base.Music21Object.addLocation`, :meth:`~music21.base.Music21Object.addLocationAndActiveSite`, :meth:`~music21.base.Music21Object.freezeIds`, :meth:`~music21.base.Music21Object.getAllContextsByClass`, :meth:`~music21.base.Music21Object.getCommonSiteIds`, :meth:`~music21.base.Music21Object.getCommonSites`, :meth:`~music21.base.Music21Object.getContextAttr`, :meth:`~music21.base.Music21Object.getContextByClass`, :meth:`~music21.base.Music21Object.getOffsetBySite`, :meth:`~music21.base.Music21Object.getSiteIds`, :meth:`~music21.base.Music21Object.getSites`, :meth:`~music21.base.Music21Object.getSpannerSites`, :meth:`~music21.base.Music21Object.hasContext`, :meth:`~music21.base.Music21Object.hasSite`, :meth:`~music21.base.Music21Object.hasSpannerSite`, :meth:`~music21.base.Music21Object.hasVariantSite`, :meth:`~music21.base.Music21Object.isClassOrSubclass`, :meth:`~music21.base.Music21Object.mergeAttributes`, :meth:`~music21.base.Music21Object.next`, :meth:`~music21.base.Music21Object.previous`, :meth:`~music21.base.Music21Object.purgeLocations`, :meth:`~music21.base.Music21Object.purgeOrphans`, :meth:`~music21.base.Music21Object.purgeUndeclaredIds`, :meth:`~music21.base.Music21Object.removeLocationBySite`, :meth:`~music21.base.Music21Object.removeLocationBySiteId`, :meth:`~music21.base.Music21Object.searchActiveSiteByAttr`, :meth:`~music21.base.Music21Object.setContextAttr`, :meth:`~music21.base.Music21Object.setOffsetBySite`, :meth:`~music21.base.Music21Object.show`, :meth:`~music21.base.Music21Object.splitAtDurations`, :meth:`~music21.base.Music21Object.splitAtQuarterLength`, :meth:`~music21.base.Music21Object.splitByQuarterLengths`, :meth:`~music21.base.Music21Object.unfreezeIds`, :meth:`~music21.base.Music21Object.unwrapWeakref`, :meth:`~music21.base.Music21Object.wrapWeakref`, :meth:`~music21.base.Music21Object.write`

        Methods inherited from :class:`~music21.base.JSONSerializer`: :meth:`~music21.base.JSONSerializer.jsonAttributes`, :meth:`~music21.base.JSONSerializer.jsonComponentFactory`, :meth:`~music21.base.JSONSerializer.jsonPrint`, :meth:`~music21.base.JSONSerializer.jsonRead`, :meth:`~music21.base.JSONSerializer.jsonWrite`


DefinedContexts
---------------

Inherits from: :class:`~music21.base.JSONSerializer`

.. class:: DefinedContexts(containedById=None)

    An object, stored within a Music21Object, that stores (weak) references to a collection of objects that may be contextually relevant to this object.

    Some of these objects are locations (also called sites), or Streams that contain this object. In this case the DefinedContexts object stores an offset value, used for determining position within a Stream.

    All defined contexts are stored as dictionaries in a dictionary. The outermost dictionary stores objects.



    **DefinedContexts** **attributes**

        Attributes without Documentation: `containedById`

    **DefinedContexts** **properties**

        Properties inherited from :class:`~music21.base.JSONSerializer`: :attr:`~music21.base.JSONSerializer.json`

    **DefinedContexts** **methods**

        .. method:: add(obj, offset=None, timeValue=None, idKey=None, classString=None)

            Add a reference to the DefinedContexts collection.
            If offset is None, it is interpreted as a context
            If offset is a value, it is intereted as location, i.e., a Stream.

            The `timeValue` argument is used to store the time at which an object is added to locations. This is not the same as `offset`




        .. method:: clear()

            Clear all stored data.



        .. method:: freezeIds()

            Temporarily replace all stored keys (object ids) with a temporary values suitable for usage in pickling.



            >>> class Mock(Music21Object):
            ...     pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> aContexts = DefinedContexts()
            >>> aContexts.add(aObj)
            >>> aContexts.add(bObj)
            >>> oldKeys = aContexts._definedContexts.keys()
            >>> aContexts.freezeIds()
            >>> newKeys = aContexts._definedContexts.keys()
            >>> oldKeys == newKeys
            False



        .. method:: get(locationsTrail=False, sortByCreationTime=False, priorityTarget=None, excludeNone=False)

            Get references; unwrap from weakrefs; order, based on dictionary keys, is from most recently added to least recently added.

            The `locationsTrail` option forces locations to come after all other defined contexts.

            The `sortByCreationTime` option will sort objects by creation time, where most-recently assigned objects are returned first.

            If `priorityTarget` is defined, this object will be placed first in the list of objects.




            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> cObj = Mock()
            >>> aContexts = music21.DefinedContexts()
            >>> aContexts.add(cObj, 345) # a locations
            >>> aContexts.add(aObj)
            >>> aContexts.add(bObj)
            >>> aContexts.get() == [cObj, aObj, bObj]
            True
            >>> aContexts.get(locationsTrail=True) == [aObj, bObj, cObj]
            True
            >>> aContexts.get(sortByCreationTime=True) == [bObj, aObj, cObj]
            True



        .. method:: getAllByClass(className, found=None, idFound=None, memo=None)

            Return all known references of a given class found
            in any association with this DefinedContexts.

            This will recursively search the defined contexts
            of existing defined contexts, and return a list of all
            objects that match the given class.




            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...    pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> dc = music21.DefinedContexts()
            >>> dc.add(aObj)
            >>> dc.add(bObj)
            >>> dc.getAllByClass = [aObj, bObj]



        .. method:: getAttrByName(attrName)

            Given an attribute name, search all objects and find the first
            that matches this attribute name; then return a reference to this attribute.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     attr1 = 234
            >>> aObj = Mock()
            >>> aObj.attr1 = 234
            >>> bObj = Mock()
            >>> bObj.attr1 = 98
            >>> aContexts = music21.DefinedContexts()
            >>> aContexts.add(aObj)
            >>> len(aContexts)
            1
            >>> aContexts.getAttrByName('attr1') == 234
            True
            >>> aContexts.removeById(id(aObj))
            >>> aContexts.add(bObj)
            >>> aContexts.getAttrByName('attr1') == 98
            True



        .. method:: getByClass(className, serialReverseSearch=True, callerFirst=None, sortByCreationTime=False, prioritizeActiveSite=False, priorityTarget=None, getElementMethod='getElementAtOrBefore', memo=None)

            Return the most recently added reference based on className. Class name can be a string or the class name.

            This will recursively search the defined contexts of existing defined contexts.

            The `callerFirst` parameters is simply used to pass a reference of the first caller; this
            is necessary if we are looking within a Stream for a flat offset position.

            If `priorityTarget` is specified, this location will be searched first. The `prioritizeActiveSite` is pased to to any recursively called getContextByClass() calls.

            The `getElementMethod` is a string that selects which Stream method is used to get elements for searching with getElementsByClass() calls.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> import time
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> aContexts = music21.DefinedContexts()
            >>> aContexts.add(aObj)
            >>> #time.sleep(.05)
            >>> aContexts.add(bObj)
            >>> # we get the most recently added object first
            >>> aContexts.getByClass('Mock', sortByCreationTime=True) == bObj
            True
            >>> aContexts.getByClass(Mock, sortByCreationTime=True) == bObj
            True



        .. method:: getById(id)

            Return the object specified by an id.
            Used for testing and debugging.



        .. method:: getOffsetByObjectMatch(obj)

            For a given object, return the
            offset using a direct object match.
            The stored id value is not used;
            instead, the id() of both the stored
            object reference and the supplied
            object is used.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 23)
            >>> aLocations.add(bSite, 121.5)
            >>> aLocations.getOffsetBySite(aSite)
            23
            >>> aLocations.getOffsetBySite(bSite)
            121.5



        .. method:: getOffsetBySite(site)

            For a given site return this
            DefinedContexts'
            offset in it. The None site is
            permitted. The id() of the site is used to find the offset.




            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 23)
            >>> aLocations.add(bSite, 121.5)
            >>> aLocations.getOffsetBySite(aSite)
            23
            >>> aLocations.getOffsetBySite(bSite)
            121.5



        .. method:: getOffsetBySiteId(siteId)

            For a given site id, return its offset.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...    pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 23)
            >>> aLocations.add(bSite, 121.5)
            >>> aLocations.getOffsetBySiteId(id(aSite))
            23
            >>> aLocations.getOffsetBySiteId(id(bSite))
            121.5



        .. method:: getOffsets()

            Return a list of all offsets.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> cSite = Mock()
            >>> dSite = Mock()
            ⁠ 
            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 0)
            >>> aLocations.add(cSite) # a context
            >>> aLocations.add(bSite, 234) # can add at same offset or another
            >>> aLocations.add(dSite) # a context
            >>> aLocations.getOffsets()
            [0, 234]



        .. method:: getSiteByOffset(offset)

            For a given offset return the site that fits it

            More than one Site may have the same offset;
            this at one point returned the last site added by sorting time,
            but now we use a dict, so there's no guarantee that the
            one you want will be there -- need orderedDicts!



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> cSite = Mock()
            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 23)
            >>> aLocations.add(bSite, 23121.5)
            >>> aSite == aLocations.getSiteByOffset(23)
            True



        .. method:: getSiteCount()

            Return the number of non-dead sites, including None. This does not unwrap weakrefs for performance.



        .. method:: getSiteIds()

            Return a list of all site Ids.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> dc = music21.DefinedContexts()
            >>> dc.add(aSite, 0)
            >>> dc.add(bSite) # a context
            >>> dc.getSiteIds() == [id(aSite)]
            True



        .. method:: getSites(idExclude=None, excludeNone=False)

            Get all defined contexts that are locations. Note that this unwraps all sites from weakrefs and is thus an expensive operation.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> aContexts = music21.DefinedContexts()
            >>> aContexts.add(aObj, 234)
            >>> aContexts.add(bObj, 3000)
            >>> len(aContexts._locationKeys) == 2
            True
            >>> len(aContexts.getSites()) == 2
            True



        .. method:: getSitesByClass(className)

            Return sites that match the provided class.

            Input can be either a Class object or a string



            >>> import music21
            >>> from music21 import stream
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> cObj = stream.Stream()
            >>> aContexts = music21.DefinedContexts()
            >>> aContexts.add(aObj, 234)
            >>> aContexts.add(bObj, 3000)
            >>> aContexts.add(cObj, 200)
            >>> aContexts.getSitesByClass(Mock) == [aObj, bObj]
            True
            >>> aContexts.getSitesByClass('Stream') == [cObj]
            True



        .. method:: hasSiteId(siteId)

            Return True or False if this
            DefinedContexts object already has
            this site id defined as a location



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> dc = music21.DefinedContexts()
            >>> dc.add(aSite, 0)
            >>> dc.add(bSite) # a context
            >>> dc.hasSiteId(id(aSite))
            True
            >>> dc.hasSiteId(id(bSite))
            False



        .. method:: hasSpannerSite()


            Return True if this object is found in
            any Spanner. This is determined by looking for
            a SpannerStorage Stream class as a Site.



        .. method:: hasVariantSite()


            Return True if this object is found in
            any Variant. This is determined by looking for
            a VariantStorage Stream class as a Site.



        .. method:: isSite(obj)


            Given an object, determine if it is a site stored
            in this DefinedContexts. This will return False
            if the object is simply a context and not a location.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 0)
            >>> aLocations.add(bSite) # a context
            >>> aLocations.isSite(aSite)
            True
            >>> aLocations.isSite(bSite)
            False



        .. method:: purgeLocations(rescanIsDead=False)

            Clean all locations that refer to objects that no longer exist.

            The `removeOrphanedSites` option removes sites that may have been the result of deepcopy: the element has the site, but the site does not have
            the element. This results b/c DefinedContexts are shallow-copied, and then elements are re-added.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> cSite = Mock()
            >>> dSite = Mock()
            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 0)
            >>> aLocations.add(cSite) # a context
            >>> del aSite
            >>> len(aLocations)
            2
            >>> aLocations.purgeLocations(rescanIsDead=True)
            >>> len(aLocations)
            1



        .. method:: remove(site)

            Remove the object (a context or location site) specified from DefinedContexts. Object provided can be a location site or a defined context.



            >>> class Mock(Music21Object):
            ...     pass
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> cSite = Mock()
            >>> aContexts = DefinedContexts()
            >>> aContexts.add(aSite, 23)
            >>> len(aContexts)
            1
            >>> aContexts.add(bSite, 233)
            >>> len(aContexts)
            2
            >>> aContexts.add(cSite, 232223)
            >>> len(aContexts)
            3
            >>> aContexts.remove(aSite)
            >>> len(aContexts)
            2



        .. method:: removeById(idKey)

            Remove a defined contexts entry by id key, which is id() of the object.



        .. method:: setAttrByName(attrName, value)

            Given an attribute name, search all objects and find the first
            that matches this attribute name; then return a reference to this attribute.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     attr1 = 234
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> bObj.attr1 = 98
            >>> aContexts = music21.DefinedContexts()
            >>> aContexts.add(aObj)
            >>> aContexts.add(bObj)
            >>> aContexts.setAttrByName('attr1', 'test')
            >>> aContexts.getAttrByName('attr1') == 'test'
            True



        .. method:: setOffsetBySite(site, value)

            Changes the offset of the site specified.  Note that this can also be
            done with add, but the difference is that if the site is not in
            DefinedContexts, it will raise an exception.



            >>> import music21
            >>> class Mock(music21.Music21Object):
            ...     pass
            ⁠ 
            >>> aSite = Mock()
            >>> bSite = Mock()
            >>> cSite = Mock()



            >>> aLocations = music21.DefinedContexts()
            >>> aLocations.add(aSite, 23)
            >>> aLocations.add(bSite, 121.5)
            >>> aLocations.setOffsetBySite(aSite, 20)
            >>> aLocations.getOffsetBySite(aSite)
            20
            ⁠ 
            >>> aLocations.setOffsetBySite(cSite, 30)
            Traceback (most recent call last):
            DefinedContextsException: an entry for this object (<...Mock object at 0x...>) is not stored in DefinedContexts



        .. method:: setOffsetBySiteId(siteId, value)

            Set an offset by siteId. This assumes that
            the site is valid, is best used for advanced,
            performance critical usage only.

            The `siteId` parameter can be None.



        .. method:: unfreezeIds()

            Restore keys to be the id() of the object they contain.



            >>> class Mock(Music21Object):
            ...     pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> cObj = Mock()
            >>> aContexts = DefinedContexts()
            >>> aContexts.add(aObj)
            >>> aContexts.add(bObj)
            >>> aContexts.add(cObj, 200) # a location
            ⁠ 
            >>> oldKeys = aContexts._definedContexts.keys()
            >>> oldLocations = aContexts._locationKeys[:]
            >>> aContexts.freezeIds()
            >>> newKeys = aContexts._definedContexts.keys()
            >>> oldKeys == newKeys
            False
            >>> aContexts.unfreezeIds()
            >>> postKeys = aContexts._definedContexts.keys()
            >>> postKeys == newKeys
            False
            >>> # restored original ids b/c objs are alive
            >>> sorted(postKeys) == sorted(oldKeys)
            True
            >>> oldLocations == aContexts._locationKeys
            True



        .. method:: unwrapWeakref()

            Unwrap any and all weakrefs stored.



            >>> class Mock(Music21Object):
            ...     pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> aContexts = DefinedContexts()
            >>> aContexts.add(aObj)
            >>> aContexts.add(bObj)
            >>> common.isWeakref(aContexts.get()[0]) # unwrapping happens
            False
            >>> common.isWeakref(aContexts._definedContexts[id(aObj)]['obj'])
            True
            >>> aContexts.unwrapWeakref()
            >>> common.isWeakref(aContexts._definedContexts[id(aObj)]['obj'])
            False
            >>> common.isWeakref(aContexts._definedContexts[id(bObj)]['obj'])
            False



        .. method:: wrapWeakref()

            Wrap all stored objects with weakrefs.



            >>> class Mock(Music21Object):
            ...     pass
            >>> aObj = Mock()
            >>> bObj = Mock()
            >>> aContexts = DefinedContexts()
            >>> aContexts.add(aObj)
            >>> aContexts.add(bObj)
            >>> aContexts.unwrapWeakref()
            >>> aContexts.wrapWeakref()
            >>> common.isWeakref(aContexts._definedContexts[id(aObj)]['obj'])
            True
            >>> common.isWeakref(aContexts._definedContexts[id(bObj)]['obj'])
            True



        Methods inherited from :class:`~music21.base.JSONSerializer`: :meth:`~music21.base.JSONSerializer.jsonAttributes`, :meth:`~music21.base.JSONSerializer.jsonComponentFactory`, :meth:`~music21.base.JSONSerializer.jsonPrint`, :meth:`~music21.base.JSONSerializer.jsonRead`, :meth:`~music21.base.JSONSerializer.jsonWrite`


Groups
------

Inherits from: list

.. class:: Groups

    A list of strings used to identify associations that an element might
    have. Enforces that all elements must be strings, and that the same element cannot be provided more than once.



    >>> g = Groups()
    >>> g.append("hello")
    >>> g[0]
    'hello'
    >>> g.append("hello") # not added as already present
    >>> len(g)
    1
    >>> g
    ['hello']
    ⁠ 
    >>> g.append(5)
    Traceback (most recent call last):
    GroupException: Only strings can be used as list names




JSONSerializer
--------------



.. class:: JSONSerializer()

    Class that provides JSON output and input routines. Objects can inherit this class directly, or gain its functional through inheriting Music21Object.



    **JSONSerializer** **properties**

        .. attribute:: json

            Get or set string JSON data for this object. This method is only available if a JSONSerializer subclass object has been customized and configured by overriding the following methods: :meth:`~music21.base.JSONSerializer.jsonAttributes`, :meth:`~music21.base.JSONSerializer.jsonComponentFactory`.



    **JSONSerializer** **methods**

        .. method:: jsonAttributes()

            Define all attributes of this object that should be JSON serialized for storage and re-instantiation. Attributes that name basic Python objects or :class:`~music21.base.JSONSerializer` subclasses, or dictionaries or lists that contain Python objects or :class:`~music21.base.JSONSerializer` subclasses, can be provided.



        .. method:: jsonComponentFactory(idStr)


            Given a stored string during JSON serialization, return an object.
            This method effectively converts a string class specification into
            a vanilla instance ready for specialization via stored data attributes.

            A subclass that overrides this method will have access to all
            modules necessary to create whatever objects necessary.




        .. method:: jsonPrint()

            No documentation.


        .. method:: jsonRead(fp)

            Given a file path, read JSON from a file to this object. Default file extension should be .json. File is opened and closed within this method call.



        .. method:: jsonWrite(fp, format=True)

            Given a file path, write JSON to a file for this object. Default file extension should be .json. File is opened and closed within this method call.




