def _split_payload_at_offsets(self, offsets):
     assert isinstance(self.payload, containertools.Container)
     music = self.payload
     self._payload = containertools.Container()
     shards = mutationtools.mutate([music]).split(
         offsets, 
         cyclic=False, 
         fracture_spanners=True,
         )
     shards = [shard[0] for shard in shards]
     for shard in shards:
         if not inspect(shard).is_well_formed():
             wellformednesstools.tabulate_well_formedness_violations_in_expr(shard)
     return shards
    def evaluate(self):
        r'''Evaluate counttime component select expression.

        Returns none when nonevaluable.

        Returns start-positioned rhythm payload expression when evaluable.
        '''
        from experimental.tools import musicexpressiontools
        anchor_timespan = self._evaluate_anchor_timespan()
        voice_proxy = \
            self.score_specification.voice_data_structures_by_voice[
                self.voice_name]
        rhythm_payload_expressions = \
            voice_proxy.payload_expressions_by_attribute['rhythm']
        # TODO: will this have to be optimized with bisect?
        rhythm_payload_expressions = \
            rhythm_payload_expressions.get_timespans_that_satisfy_time_relation(
            timerelationtools.timespan_2_intersects_timespan_1(
            timespan_1=anchor_timespan))
        if not rhythm_payload_expressions:
            return
        rhythm_payload_expressions = \
            copy.deepcopy(rhythm_payload_expressions)
        rhythm_payload_expressions = \
            timespantools.TimespanInventory(rhythm_payload_expressions)
        rhythm_payload_expressions.sort()
        assert anchor_timespan.is_well_formed, repr(anchor_timespan)
        rhythm_payload_expressions &= anchor_timespan
        expression = \
            musicexpressiontools.StartPositionedRhythmPayloadExpression(
            start_offset=anchor_timespan.start_offset)
        for rhythm_payload_expression in rhythm_payload_expressions:
            expression.payload.extend(rhythm_payload_expression.payload)
        assert inspect(expression.payload).is_well_formed()
        # TODO: eventually make this be able to work
        #callback_cache = self.score_specification.interpreter.callback_cache
        #expression = expression.get_elements_that_satisfy_time_relation(
        #    time_relation, callback_cache)
        expression = self._apply_callbacks(expression)
        expression._voice_name = self.voice_name
        return expression
    def rotate(self, n, fracture_spanners=True):
        r'''Rotate start-positioned rhythm payload expression.

        Example 1. Rotate by count:

        ::

            >>> payload = [Container("c'8 d'8 e'8 f'8")]
            >>> expression = \
            ...     musicexpressiontools.StartPositionedRhythmPayloadExpression(
            ...     payload, Offset(0))

        ::

            >>> result = expression.rotate(-1)

        ::

            >>> print expression.storage_format
            musicexpressiontools.StartPositionedRhythmPayloadExpression(
                payload=containertools.Container(
                    music=[{d'8, e'8, f'8}, {c'8}]
                    ),
                start_offset=durationtools.Offset(0, 1)
                )

        Example 2. Rotate by duration:

        ::

            >>> payload = [Container("c'8 d'8 e'8 f'8")]
            >>> expression = \
            ...     musicexpressiontools.StartPositionedRhythmPayloadExpression(
            ...     payload, Offset(0))

        ::

            >>> result = expression.rotate(-Duration(3, 16))

        ::

            >>> print expression.storage_format
            musicexpressiontools.StartPositionedRhythmPayloadExpression(
                payload=containertools.Container(
                    music=[{d'16, e'8, f'8}, {c'8, d'16}]
                    ),
                start_offset=durationtools.Offset(0, 1)
                )

        Operates in place and returns start-positioned rhythm 
        payload expression.
        '''
        from experimental.tools import musicexpressiontools
        if isinstance(n, int):
            leaves = datastructuretools.CyclicTuple(self.payload.select_leaves())
            if 0 < n:
                split_offset = leaves[-n]._get_timespan().start_offset
            elif n == 0:
                return self
            else:
                split_offset = leaves[-(n+1)]._get_timespan().stop_offset
        elif isinstance(n, musicexpressiontools.RotationIndicator):
            rotation_indicator = n
            if rotation_indicator.level is None:
                components_at_level = self.payload.select_leaves()
            else:
                components_at_level = []
                for component in \
                    iterationtools.iterate_components_in_expr(self.payload):
                    score_index = component._get_parentage().score_index
                    if len(score_index) == rotation_indicator.level:
                        components_at_level.append(component)
            components_at_level = datastructuretools.CyclicTuple(components_at_level)
            if isinstance(rotation_indicator.index, int):
                if 0 < rotation_indicator.index:
                    split_offset = components_at_level[
                        -rotation_indicator.index]._get_timespan().start_offset
                elif n == 0:
                    return self
                else:
                    split_offset = components_at_level[
                        -(rotation_indicator.index+1)]._get_timespan().stop_offset
            else:
                index = durationtools.Duration(rotation_indicator.index)
                if 0 <= index:
                    split_offset = self.payload._get_duration() - index
                else:
                    split_offset = abs(index)
            if rotation_indicator.fracture_spanners is not None:
                fracture_spanners = rotation_indicator.fracture_spanners
        else:
            n = durationtools.Duration(n)
            if 0 <= n:
                split_offset = self.payload._get_duration() - n
            else:
                split_offset = abs(n)
        #self._debug(split_offset, 'split offset')
        try:
            payload_duration = getattr(self, 'payload')
        except AttributeError:
            payload_duration = self.payload._get_duration()
        if split_offset == payload_duration:
            return self
        if fracture_spanners:
            result = mutationtools.mutate([self.payload]).split(
                [split_offset],
                cyclic=False,
                fracture_spanners=True,
                tie_split_notes=False,
                )
            left_half, right_half = result[0][0], result[-1][0]
            payload = containertools.Container()
            payload.extend(right_half)
            payload.extend(left_half)
            assert inspect(payload).is_well_formed()
            self._payload = payload
        else:
            result = mutationtools.mutate(self.payload[:]).split(
                [split_offset],
                cyclic=False,
                fracture_spanners=False,
                tie_split_notes=False,
                )
            left_half, right_half = result[0], result[-1]
            spanner_classes = (spannertools.DuratedComplexBeamSpanner, )
            descendants = self.payload._get_descendants()
            for spanner in descendants.get_spanners(spanner_classes):
                if left_half[-1] in spanner and right_half[0] in spanner:
                    leaf_right_of_split = right_half[0]
                    split_offset_in_beam = spanner._duration_offset_in_me(
                        leaf_right_of_split)
                    left_durations, right_durations = \
                        sequencetools.split_sequence_by_weights(
                        spanner.durations,
                        [split_offset_in_beam],
                        cyclic=False,
                        overhang=True,
                        )
                    new_durations = right_durations + left_durations
                    spanner._durations = new_durations
            new_payload = right_half + left_half
            self.payload._music = new_payload
            for component in new_payload:
                component._update_later(offsets=True)
            for spanner in self.payload._get_descendants().get_spanners():
                spanner._components.sort(
                    lambda x, y: cmp(x._get_parentage().score_index, y._get_parentage().score_index))
            assert inspect(self.payload).is_well_formed()
        return self