Beispiel #1
0
def test_factory_re_register(function_factory: FunctionFactoryBase):
    from ceed.function.plugin import ConstFunc, LinearFunc
    with pytest.raises(Exception):
        function_factory.register(ConstFunc)

    with pytest.raises(Exception):
        function_factory.register(LinearFunc)
Beispiel #2
0
def test_copy_funcs(function_factory: FunctionFactoryBase):
    from ceed.function import FuncGroup, CeedFuncRef
    f1 = function_factory.get('ConstFunc')(function_factory=function_factory,
                                           a=.5,
                                           name='f1',
                                           duration=1.2)
    f2 = function_factory.get('LinearFunc')(function_factory=function_factory,
                                            m=.5,
                                            b=.2,
                                            name='f2',
                                            duration=1.2)
    f3 = function_factory.get('ExponentialFunc')(
        function_factory=function_factory,
        A=.5,
        B=.2,
        tau1=1.3,
        tau2=1.5,
        name='f3',
        duration=1.2)
    f4 = function_factory.get('CosFunc')(function_factory=function_factory,
                                         f=.5,
                                         A=3.4,
                                         th0=7.5,
                                         b=12.2,
                                         name='f4',
                                         duration=1.2)
    g = FuncGroup(function_factory=function_factory, name='g')

    function_factory.add_func(f1)
    function_factory.add_func(f2)
    function_factory.add_func(f3)
    function_factory.add_func(f4)

    g.add_func(function_factory.get_func_ref(func=f1))
    g.add_func(function_factory.get_func_ref(func=f2))
    g.add_func(function_factory.get_func_ref(func=f3))
    g.add_func(function_factory.get_func_ref(func=f4))

    for func in (f1, f2, f3, f4):
        func_copy = copy.deepcopy(func)
        assert func is not func_copy
        assert isinstance(func_copy, func.__class__)

        for name in func.get_gui_props():
            if name == 'name':
                continue

            assert getattr(func, name) == getattr(func_copy, name)

    func_copy = copy.deepcopy(g)
    assert len(func_copy.funcs) == 4
    for new_f, original_f in zip(func_copy.funcs, g.funcs):
        assert new_f is not original_f
        assert isinstance(new_f, CeedFuncRef)
        assert isinstance(original_f, CeedFuncRef)
        assert new_f.func is original_f.func
Beispiel #3
0
def test_func_ref(function_factory: FunctionFactoryBase):
    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    f2 = const_cls(function_factory=function_factory,
                   duration=5,
                   a=.9,
                   name='f')

    function_factory.add_func(f)

    ref1 = function_factory.get_func_ref(name='f')
    ref2 = function_factory.get_func_ref(func=f2)

    assert ref1.func is f
    assert ref2.func is f2
    assert f.has_ref
    assert f2.has_ref
    assert f in function_factory._ref_funcs
    assert f2 in function_factory._ref_funcs

    function_factory.return_func_ref(ref1)
    assert ref2.func is f2
    assert not f.has_ref
    assert f2.has_ref
    assert f not in function_factory._ref_funcs
    assert f2 in function_factory._ref_funcs

    function_factory.return_func_ref(ref2)
    assert not f.has_ref
    assert not f2.has_ref
    assert f not in function_factory._ref_funcs
    assert f2 not in function_factory._ref_funcs
Beispiel #4
0
def test_return_not_added_func_ref(function_factory: FunctionFactoryBase):
    from ceed.function import CeedFuncRef
    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    ref = CeedFuncRef(function_factory=function_factory, func=f)

    with pytest.raises(ValueError):
        function_factory.return_func_ref(ref)
Beispiel #5
0
def test_factory_func_remove(function_factory: FunctionFactoryBase):
    assert not function_factory.funcs_user
    initial_funcs_n = len(function_factory.funcs_inst)

    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    function_factory.add_func(f)
    f2 = const_cls(function_factory=function_factory,
                   duration=4,
                   a=.7,
                   name='f2')
    function_factory.add_func(f2)

    assert len(function_factory.funcs_inst) == initial_funcs_n + 2

    function_factory.test_changes_count = 0
    assert function_factory.remove_func(f2)

    assert function_factory.test_changes_count
    assert f in function_factory.funcs_user
    assert f2 not in function_factory.funcs_user
    assert len(function_factory.funcs_user) == 1
    assert f.name == 'f'
    assert f2.name == 'f2'

    assert function_factory.funcs_inst['f'] is f
    assert 'f2' not in function_factory.funcs_inst
    assert len(function_factory.funcs_inst) == initial_funcs_n + 1

    function_factory.test_changes_count = 0
    f2.name = 'f'

    assert not function_factory.test_changes_count
    assert f.name == 'f'
    assert f2.name == 'f'

    function_factory.test_changes_count = 0
    assert function_factory.remove_func(f)

    assert function_factory.test_changes_count
    assert f not in function_factory.funcs_user
    assert f2 not in function_factory.funcs_user
    assert not function_factory.funcs_user
    assert f.name == 'f'
    assert f2.name == 'f'

    assert 'f' not in function_factory.funcs_inst
    assert 'f2' not in function_factory.funcs_inst

    assert len(function_factory.funcs_inst) == initial_funcs_n
Beispiel #6
0
def test_auto_register(function_factory: FunctionFactoryBase):
    from ceed.function.plugin import ConstFunc, LinearFunc, CosFunc, \
        ExponentialFunc
    assert not function_factory.funcs_user
    assert function_factory.get('ConstFunc') is ConstFunc
    assert function_factory.get('LinearFunc') is LinearFunc
    assert function_factory.get('CosFunc') is CosFunc
    assert function_factory.get('ExponentialFunc') is ExponentialFunc

    assert isinstance(function_factory.funcs_inst['Const'], ConstFunc)
    assert isinstance(function_factory.funcs_inst['Linear'], LinearFunc)
    assert isinstance(function_factory.funcs_inst['Cos'], CosFunc)
    assert isinstance(function_factory.funcs_inst['Exp'], ExponentialFunc)
Beispiel #7
0
 def __init__(self, open_player_thread=True, **kwargs):
     self.drag_controller = CeedDragNDrop()
     self.function_factory = FunctionFactoryBase()
     register_all_functions(self.function_factory)
     self.stage_factory = StageFactoryBase(
         function_factory=self.function_factory, shape_factory=None)
     self.player = CeedPlayer(open_player_thread=open_player_thread)
     self.view_controller = ControllerSideViewControllerBase()
     self.ceed_data = CeedDataWriterBase()
     self.data_serializer = DataSerializerBase()
     super(CeedApp, self).__init__(**kwargs)
     self.load_app_settings_from_file()
     self.apply_app_settings()
Beispiel #8
0
def test_recover_funcs(function_factory: FunctionFactoryBase):
    f1 = function_factory.get('ConstFunc')(function_factory=function_factory,
                                           a=.5,
                                           name='f1')
    f2 = function_factory.get('LinearFunc')(function_factory=function_factory,
                                            m=.5,
                                            b=.2,
                                            name='f2')
    f3 = function_factory.get('ExponentialFunc')(
        function_factory=function_factory,
        A=.5,
        B=.2,
        tau1=1.3,
        tau2=1.5,
        name='f3')
    f4 = function_factory.get('CosFunc')(function_factory=function_factory,
                                         f=.5,
                                         A=3.4,
                                         th0=7.5,
                                         b=12.2,
                                         name='f4')

    function_factory.add_func(f1)
    function_factory.add_func(f2)
    function_factory.add_func(f3)
    function_factory.add_func(f4)

    funcs = function_factory.save_functions()
    assert len(funcs) == 4

    recovered_funcs, name_mapping = function_factory.recover_funcs(funcs)
    assert len(recovered_funcs) == 4
    assert len(name_mapping) == 4

    for f_name in ('f1', 'f2', 'f3', 'f4'):
        assert f_name in name_mapping
        assert name_mapping[f_name] != f_name
        assert f_name in function_factory.funcs_inst
        assert name_mapping[f_name] in function_factory.funcs_inst

        for name in function_factory.funcs_inst[f_name].get_gui_props():
            original_f = function_factory.funcs_inst[f_name]
            new_f = function_factory.funcs_inst[name_mapping[f_name]]

            if name == 'name':
                assert original_f.name != new_f.name
                assert new_f.name.startswith(original_f.name)
                continue

            assert getattr(original_f, name) == getattr(new_f, name)
Beispiel #9
0
def function_factory() -> FunctionFactoryBase:
    from ceed.function import FunctionFactoryBase, register_all_functions
    function_factory = FunctionFactoryBase()
    register_all_functions(function_factory)
    add_prop_watch(function_factory, 'on_changed', 'test_changes_count')

    yield function_factory
Beispiel #10
0
def test_can_other_func_be_added_ref(function_factory: FunctionFactoryBase):
    factory = function_factory
    const_cls = factory.get('ConstFunc')

    g1 = FuncGroup(function_factory=factory)

    g2 = FuncGroup(function_factory=factory)
    ref_g2 = function_factory.get_func_ref(func=g2)
    g1.add_func(ref_g2)

    f = const_cls(function_factory=factory, a=.9, duration=2)
    g2.add_func(f)

    f2 = const_cls(function_factory=factory, a=.25, duration=2)
    g1.add_func(f2)

    g3 = FuncGroup(function_factory=factory)
    g1.add_func(g3)
    f4 = const_cls(function_factory=factory, a=.8, duration=2)
    g3.add_func(f4)

    assert g1.can_other_func_be_added(g2)
    assert g1.can_other_func_be_added(ref_g2)
    assert g1.can_other_func_be_added(g3)
    assert not g1.can_other_func_be_added(g1)

    assert not g2.can_other_func_be_added(g1)
    assert g2.can_other_func_be_added(g3)
    assert not g2.can_other_func_be_added(g2)
    assert not g2.can_other_func_be_added(ref_g2)

    assert not g3.can_other_func_be_added(g1)
    assert g3.can_other_func_be_added(g2)
    assert g3.can_other_func_be_added(ref_g2)
    assert not g3.can_other_func_be_added(g3)
Beispiel #11
0
def test_call_funcs_ref(function_factory: FunctionFactoryBase):
    factory = function_factory
    const_cls = factory.get('ConstFunc')

    g1 = FuncGroup(function_factory=factory)

    g2 = FuncGroup(function_factory=factory)
    ref_g2 = function_factory.get_func_ref(func=g2)
    g1.add_func(ref_g2)

    f = const_cls(function_factory=factory, a=.9, duration=2)
    g2.add_func(f)

    f2 = const_cls(function_factory=factory, a=.25, duration=2)
    g1.add_func(f2)

    with pytest.raises(TypeError):
        g1.init_func(0)

    with pytest.raises(TypeError):
        ref_g2.init_func(0)

    with pytest.raises(TypeError):
        ref_g2(0)

    with pytest.raises(TypeError):
        g1(0)
Beispiel #12
0
def test_timebase_group(function_factory: FunctionFactoryBase):
    g = FuncGroup(function_factory=function_factory)
    assert g.get_timebase() == 1

    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory)
    assert f.get_timebase() == 1

    g.add_func(f)
    assert f.get_timebase() == 1

    g.timebase_numerator = 1
    g.timebase_denominator = 4
    assert g.get_timebase() == 1 / 4
    assert f.get_timebase() == 1 / 4

    f.timebase_numerator = 1
    f.timebase_denominator = 8
    assert g.get_timebase() == 1 / 4
    assert f.get_timebase() == 1 / 8

    f.timebase_numerator = 0
    assert g.get_timebase() == 1 / 4
    assert f.get_timebase() == 1 / 4

    f.timebase_numerator = 1
    assert g.get_timebase() == 1 / 4
    assert f.get_timebase() == 1 / 8

    g.timebase_numerator = 0
    assert g.get_timebase() == 1
    assert f.get_timebase() == 1 / 8
Beispiel #13
0
def test_make_function(function_factory: FunctionFactoryBase):
    f1 = function_factory.get('ConstFunc')(function_factory=function_factory,
                                           a=.5,
                                           name='f1')
    f2 = function_factory.get('LinearFunc')(function_factory=function_factory,
                                            m=.5,
                                            b=.2,
                                            name='f2')
    f3 = function_factory.get('ExponentialFunc')(
        function_factory=function_factory,
        A=.5,
        B=.2,
        tau1=1.3,
        tau2=1.5,
        name='f3')
    f4 = function_factory.get('CosFunc')(function_factory=function_factory,
                                         f=.5,
                                         A=3.4,
                                         th0=7.5,
                                         b=12.2,
                                         name='f4')

    funcs = f1, f2, f3, f4
    states = [f.get_state() for f in funcs]
    new_funcs = [function_factory.make_func(state) for state in states]
    assert len(new_funcs) == len(funcs)

    for new_func, f in zip(new_funcs, funcs):
        for name in f.get_gui_props():
            if name == 'name':
                assert f.name != new_func.name
                continue

            assert getattr(f, name) == getattr(new_func, name)

    # close should make them identical in all ways
    new_funcs = [
        function_factory.make_func(state, clone=True) for state in states
    ]
    assert len(new_funcs) == len(funcs)

    for new_func, f in zip(new_funcs, funcs):
        for name in f.get_gui_props():
            assert getattr(f, name) == getattr(new_func, name)

    # provide instances
    new_funcs = [
        function_factory.make_func(state,
                                   instance=function_factory.get(state['cls'])(
                                       function_factory=function_factory),
                                   clone=True) for state in states
    ]
    assert len(new_funcs) == len(funcs)

    for new_func, f in zip(new_funcs, funcs):
        for name in f.get_gui_props():
            assert getattr(f, name) == getattr(new_func, name)
Beispiel #14
0
def test_expand_ref_funcs(function_factory: FunctionFactoryBase):
    from ceed.function import FuncGroup, CeedFuncRef
    factory = function_factory
    const_cls = factory.get('ConstFunc')

    g1 = FuncGroup(function_factory=factory)

    g2 = FuncGroup(function_factory=factory)
    ref_g2 = function_factory.get_func_ref(func=g2)
    g1.add_func(ref_g2)

    f = const_cls(function_factory=factory, a=.9, duration=2)
    g2.add_func(f)
    f1 = const_cls(function_factory=factory, a=.1, duration=2)
    g2.add_func(f1)

    f2 = const_cls(function_factory=factory, a=.25, duration=2)
    g1.add_func(f2)
    f3 = const_cls(function_factory=factory, a=.75, duration=2)
    ref_f3 = function_factory.get_func_ref(func=f3)
    g1.add_func(ref_f3)

    g3 = FuncGroup(function_factory=factory)
    g1.add_func(g3)
    f4 = const_cls(function_factory=factory, a=.8, duration=2)
    ref_f4 = function_factory.get_func_ref(func=f4)
    g3.add_func(ref_f4)
    f5 = const_cls(function_factory=factory, a=.2, duration=2)
    g3.add_func(f5)

    assert list(g1.get_funcs(step_into_ref=False)) == \
        [g1, ref_g2, f2, ref_f3, g3, ref_f4, f5]
    assert list(g1.get_funcs(step_into_ref=True)) == \
        [g1, g2, f, f1, f2, f3, g3, f4, f5]

    g1_copy = g1.copy_expand_ref()
    # the copy shouldn't have any refs
    assert len(list(g1_copy.get_funcs(step_into_ref=False))) == \
        len(list(g1.get_funcs(step_into_ref=True)))

    for original_f, new_f in zip(g1.get_funcs(step_into_ref=True),
                                 g1_copy.get_funcs(step_into_ref=False)):
        for name in original_f.get_gui_props():
            if name == 'name':
                continue

            assert getattr(original_f, name) == getattr(new_f, name)
Beispiel #15
0
def test_timebase_func(function_factory: FunctionFactoryBase):
    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory)
    assert f.get_timebase() == 1

    f = const_cls(function_factory=function_factory,
                  timebase_numerator=1,
                  timebase_denominator=2)
    assert f.get_timebase() == 0.5
Beispiel #16
0
def test_t_offset(function_factory: FunctionFactoryBase):
    f1 = function_factory.get('ConstFunc')(function_factory=function_factory,
                                           a=.5,
                                           name='f1',
                                           t_offset=3.5,
                                           duration=1.2)
    f2 = function_factory.get('LinearFunc')(function_factory=function_factory,
                                            m=.5,
                                            b=.2,
                                            name='f2',
                                            t_offset=3.5,
                                            duration=1.2)
    f3 = function_factory.get('ExponentialFunc')(
        function_factory=function_factory,
        A=.5,
        B=.2,
        tau1=1.3,
        tau2=1.5,
        name='f3',
        t_offset=3.5,
        duration=1.2)
    f4 = function_factory.get('CosFunc')(function_factory=function_factory,
                                         f=.5,
                                         A=3.4,
                                         th0=7.5,
                                         b=12.2,
                                         name='f4',
                                         t_offset=3.5,
                                         duration=1.2)

    for f in (f1, f2, f3, f4):
        f.init_func(2.3)

    t = 1 + 3.5
    assert math.isclose(f1(3.3), .5)
    assert math.isclose(f2(3.3), t * .5 + .2)
    assert math.isclose(f3(3.3),
                        .5 * math.exp(-t / 1.3) + .2 * math.exp(-t / 1.5))
    assert math.isclose(
        f4(3.3),
        3.4 * math.cos(2 * math.pi * .5 * t + 7.5 * math.pi / 180.) + 12.2)
Beispiel #17
0
    def __init__(self, **kwargs):
        self.view_controller = ViewSideViewControllerBase()
        self.ceed_data = CeedDataWriterBase()
        self.data_serializer = DataSerializerBase()
        self.function_factory = FunctionFactoryBase()
        register_all_functions(self.function_factory)
        self.shape_factory = CeedPaintCanvasBehavior()
        self.stage_factory = StageFactoryBase(
            function_factory=self.function_factory,
            shape_factory=self.shape_factory)

        super(CeedViewApp, self).__init__(**kwargs)
Beispiel #18
0
    def load_experiment(self, experiment):
        self._block = block = self._nix_file.blocks[
            CeedDataWriterBase.get_experiment_block_name(experiment)]
        section = self._nix_file.sections['experiment{}_metadata'.format(
            experiment)]
        self.loaded_experiment = experiment

        self.experiment_stage_name = section['stage']
        self.experiment_notes = section['notes'] if 'notes' in section else ''
        self.experiment_start_time = float(
            section['save_time']) if 'save_time' in section else 0
        config = section.sections['app_config']

        config_data = {}
        for prop in config.props:
            config_data[prop.name] = yaml_loads(read_nix_prop(prop))

        view = self.view_controller = ViewControllerBase()
        ser = self.data_serializer = DataSerializerBase()
        func = self.function_factory = FunctionFactoryBase()
        register_all_functions(func)
        shape = self.shape_factory = CeedPaintCanvasBehavior()
        stage = self.stage_factory = StageFactoryBase(function_factory=func,
                                                      shape_factory=shape)

        for name, obj in {
                'view': view,
                'serializer': ser,
                'function': func
        }.items():
            if name in config_data['app_settings']:
                apply_config(obj, config_data['app_settings'][name])
        self.populate_config(config_data, shape, func, stage)

        self.experiment_cam_image = self.read_image_from_block(self._block)

        data = self.shapes_intensity = {}
        for item in block.data_arrays:
            if not item.name.startswith('shape_'):
                continue
            data[item.name[6:]] = item

        self.led_state = block.data_arrays['led_state']

        if ('ceed_mcs_alignment' in self._nix_file.blocks
                and 'experiment_{}'.format(experiment)
                in self._nix_file.blocks['ceed_mcs_alignment'].data_arrays):
            self.electrode_intensity_alignment = self._nix_file.blocks[
                'ceed_mcs_alignment'].data_arrays['experiment_{}'.format(
                    experiment)]
        else:
            self.electrode_intensity_alignment = None
Beispiel #19
0
def test_factory_func_unique_names(function_factory: FunctionFactoryBase):
    assert not function_factory.funcs_user
    function_factory.test_changes_count = 0

    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    function_factory.add_func(f)
    f2 = const_cls(function_factory=function_factory,
                   duration=4,
                   a=.7,
                   name='f')
    function_factory.add_func(f2)

    def assert_not_f():
        assert function_factory.test_changes_count
        assert f in function_factory.funcs_user
        assert f2 in function_factory.funcs_user
        assert len(function_factory.funcs_user) == 2
        f2_name = f2.name
        assert f.name == 'f'
        assert f2_name != 'f'
        assert f2_name

        assert function_factory.funcs_inst['f'] is f
        assert function_factory.funcs_inst[f2_name] is f2

    assert_not_f()

    function_factory.test_changes_count = 0
    f2.name = 'f2'
    assert function_factory.test_changes_count
    assert f in function_factory.funcs_user
    assert f2 in function_factory.funcs_user
    assert len(function_factory.funcs_user) == 2
    assert f.name == 'f'
    assert f2.name == 'f2'

    assert function_factory.funcs_inst['f'] is f
    assert function_factory.funcs_inst['f2'] is f2

    function_factory.test_changes_count = 0
    f2.name = 'f'
    assert_not_f()
Beispiel #20
0
 def __init__(self, **kwargs):
     drag = self.drag_controller = CeedDragNDrop()
     drag.knsname = 'dragger'
     self.function_factory = FunctionFactoryBase()
     register_all_functions(self.function_factory)
     self.stage_factory = StageFactoryBase(
         function_factory=self.function_factory, shape_factory=None)
     self.player = CeedPlayer()
     self.view_controller = ControllerSideViewControllerBase()
     self.ceed_data = CeedDataWriterBase()
     self.data_serializer = DataSerializerBase()
     self.remote_viewer = RemoteViewerListenerBase()
     self.remote_player = CeedRemotePlayer()
     super(CeedApp, self).__init__(**kwargs)
     self.load_app_settings_from_file()
     self.apply_app_settings()
Beispiel #21
0
def test_clear_funcs(function_factory: FunctionFactoryBase):
    assert not function_factory.funcs_user
    initial_funcs_n = len(function_factory.funcs_inst)

    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    function_factory.add_func(f)
    f2 = const_cls(function_factory=function_factory,
                   duration=4,
                   a=.7,
                   name='f2')
    function_factory.add_func(f2)

    assert len(function_factory.funcs_inst) == initial_funcs_n + 2

    function_factory.test_changes_count = 0
    function_factory.clear_added_funcs()
    assert len(function_factory.funcs_inst) == initial_funcs_n
    assert not function_factory.funcs_user
Beispiel #22
0
def test_group_remove_func(function_factory: FunctionFactoryBase):
    factory = function_factory
    const_cls = factory.get('ConstFunc')

    g1 = FuncGroup(function_factory=factory)

    g2 = FuncGroup(function_factory=factory)
    ref_g2 = function_factory.get_func_ref(func=g2)
    g1.add_func(ref_g2)
    f = const_cls(function_factory=factory, a=.9, duration=2)
    g2.add_func(f)
    f1 = const_cls(function_factory=factory, a=.9, duration=2)
    g2.add_func(f1)

    f2 = const_cls(function_factory=factory, a=.25, duration=2)
    g1.add_func(f2)

    assert list(g1.get_funcs(step_into_ref=False)) == [g1, ref_g2, f2]
    assert g1.duration == 6
    assert g1.duration_min == 6
    assert g1.duration_min_total == 6

    g1.remove_func(f2)
    assert list(g1.get_funcs(step_into_ref=False)) == [g1, ref_g2]
    assert g1.duration == 4
    assert g1.duration_min == 4
    assert g1.duration_min_total == 4

    g2.remove_func(f)
    assert list(g1.get_funcs(step_into_ref=False)) == [g1, ref_g2]
    assert g1.duration == 2
    assert g1.duration_min == 2
    assert g1.duration_min_total == 2

    g1.remove_func(ref_g2)
    assert list(g1.get_funcs(step_into_ref=False)) == [
        g1,
    ]
    assert g1.duration == 0
    assert g1.duration_min == 0
    assert g1.duration_min_total == 0
Beispiel #23
0
    def load_application_data(self):
        self.app_logs = self.app_notes = ''
        if 'app_logs' in self._nix_file.sections:
            self.app_logs = self._nix_file.sections['app_logs']['log_data']
            self.app_notes = self._nix_file.sections['app_logs']['notes']

        config = self._nix_file.sections['app_config']

        config_data = {}
        for prop in config.props:
            config_data[prop.name] = yaml_loads(read_nix_prop(prop))

        self.ceed_version = config_data.get('ceed_version', '')

        view = ViewControllerBase()
        ser = DataSerializerBase()
        func = FunctionFactoryBase()
        register_all_functions(func)
        shape = CeedPaintCanvasBehavior()
        stage = StageFactoryBase(function_factory=func, shape_factory=shape)

        for name, obj in {
                'view': view,
                'serializer': ser,
                'function': func
        }.items():
            if name in config_data['app_settings']:
                apply_config(obj, config_data['app_settings'][name])
        self.populate_config(config_data, shape, func, stage)

        self.app_config = {
            'view_controller': view,
            'data_serializer': ser,
            'function_factory': func,
            'shape_factory': shape,
            'stage_factory': stage,
        }
Beispiel #24
0
def test_register_user_func(function_factory: FunctionFactoryBase):
    assert not function_factory.funcs_user

    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    f2 = const_cls(function_factory=function_factory,
                   duration=5,
                   a=.9,
                   name='f2')

    function_factory.test_changes_count = 0
    function_factory.add_func(f)
    assert function_factory.test_changes_count
    assert f in function_factory.funcs_user
    assert function_factory.funcs_inst['f'] is f

    function_factory.test_changes_count = 0
    function_factory.add_func(f2)
    assert function_factory.test_changes_count
    assert f2 in function_factory.funcs_user
    assert function_factory.funcs_inst['f2'] is f2
Beispiel #25
0
class CeedApp(CPLComApp):
    '''The app which runs the GUI.
    '''

    function_factory = None

    player = None

    view_controller = None

    ceed_data = None

    data_serializer = None

    remote_viewer = None

    stage_factory = None

    shape_factory = None

    remote_player = None

    agreed_discard = False

    drag_controller = None
    '''
    '''

    @classmethod
    def get_config_classes(cls):
        d = super(CeedApp, cls).get_config_classes()
        d['function'] = FunctionFactoryBase
        d['view'] = ControllerSideViewControllerBase
        d['data'] = CeedDataWriterBase
        d['serializer'] = DataSerializerBase
        d['player'] = CeedPlayer
        d['point_gray_cam'] = CeedPTGrayPlayer
        d['video_file_playback'] = CeedFFmpegPlayer
        d['remote_viewer'] = RemoteViewerListenerBase

        app = cls.get_running_app()
        if app is not None:
            d['function'] = app.function_factory
            d['view'] = app.view_controller
            d['data'] = app.ceed_data
            d['serializer'] = app.data_serializer
            p = d['player'] = app.player
            d['point_gray_cam'] = p.pt_player
            d['video_file_playback'] = p.ff_player
            d['remote_viewer'] = app.remote_viewer
        return d

    def __init__(self, **kwargs):
        drag = self.drag_controller = CeedDragNDrop()
        drag.knsname = 'dragger'
        self.function_factory = FunctionFactoryBase()
        register_all_functions(self.function_factory)
        self.stage_factory = StageFactoryBase(
            function_factory=self.function_factory, shape_factory=None)
        self.player = CeedPlayer()
        self.view_controller = ControllerSideViewControllerBase()
        self.ceed_data = CeedDataWriterBase()
        self.data_serializer = DataSerializerBase()
        self.remote_viewer = RemoteViewerListenerBase()
        self.remote_player = CeedRemotePlayer()
        super(CeedApp, self).__init__(**kwargs)
        self.load_app_settings_from_file()
        self.apply_app_settings()

    def build(self):
        base = dirname(__file__)
        # Builder.load_file(join(base, 'graphics', 'graphics.kv'))
        Builder.load_file(join(base, 'ceed_style.kv'))
        Builder.load_file(join(base, 'player', 'player_style.kv'))
        Builder.load_file(join(base, 'shape', 'shape_style.kv'))
        Builder.load_file(join(base, 'function', 'func_style.kv'))
        Builder.load_file(join(base, 'stage', 'stage_style.kv'))
        Builder.load_file(join(base, 'view', 'view_style.kv'))
        Builder.load_file(join(base, 'storage', 'storage_style.kv'))
        self.yesno_prompt = Factory.CeedYesNoPrompt()

        root = Factory.get('MainView')()
        return super(CeedApp, self).build(root)

    def on_start(self):
        self.stage_factory.shape_factory = self.shape_factory = knspace.painter
        remove_shapes_upon_deletion(
            self.stage_factory, self.shape_factory,
            knspace.stages.remove_shape_from_stage)
        knspace.painter.shapes_canvas = knspace.painter.canvas
        knspace.painter.shape_widgets_list = knspace.shapes

        def clear_all():
            knspace.funcs.clear_all()
            knspace.stages.clear_all()

        self.ceed_data.stage_display_callback = knspace.stages.show_stage
        self.ceed_data.func_display_callback = knspace.funcs.show_function
        self.ceed_data.clear_all_callback = clear_all

        HighightButtonBehavior.init_class()

        self.ceed_data.create_file('')

        self.stage_factory.fbind('on_changed', self.changed_callback)
        self.function_factory.fbind('on_changed', self.changed_callback)
        for func in self.function_factory.funcs_inst_default.values():
            func.fbind('on_changed', self.changed_callback)
        knspace.painter.fbind('on_changed', self.changed_callback)
        self.view_controller.fbind('on_changed', self.changed_callback)

        self.set_tittle()
        self.ceed_data.fbind('filename', self.set_tittle)
        self.ceed_data.fbind('config_changed', self.set_tittle)
        self.ceed_data.fbind('has_unsaved', self.set_tittle)
        self.ceed_data.fbind('read_only_file', self.set_tittle)

        try:
            self.view_controller.set_led_mode(self.view_controller.LED_mode_idle)
        except ImportError:
            pass

    def set_tittle(self, *largs):
        ''' Sets the title of the window using the currently running
        tab. This is called at 1Hz. '''
        star = ''
        if self.ceed_data.has_unsaved or self.ceed_data.config_changed:
            star = '*'

        read_only = ''
        if self.ceed_data.read_only_file:
            read_only = ' - Read Only'

        if self.ceed_data.filename:
            filename = ' - {}'.format(self.ceed_data.filename)
        else:
            filename = ' - Unnamed File'

        Window.set_title('Ceed v{}, CPL lab{}{}{}'.format(
            ceed.__version__, star, filename, read_only))

    def changed_callback(self, *largs, **kwargs):
        self.ceed_data.config_changed = True

    def check_close(self):
        if CeedPlayer.is_player_active():
            self._close_message = 'Cannot close while player is active.'
            return False
        if self.view_controller.stage_active or self.ceed_data.data_thread:
            self._close_message = 'Cannot close during an experiment.'
            return False
        self.view_controller.stop_process()
        self.view_controller.finish_stop_process()
        if not self.ceed_data.ui_close(app_close=True):
            self._close_message = ''
            return False
        return True

    def handle_exception(self, *largs, **kwargs):
        val = super(CeedApp, self).handle_exception(*largs, **kwargs)
        self.view_controller.request_stage_end()
        return val
Beispiel #26
0
class CeedApp(BaseKivyApp):
    """The app which runs the main Ceed GUI.
    """

    _config_props_ = ('last_directory', 'external_function_plugin_package',
                      'external_stage_plugin_package')

    _config_children_ = {
        'function': 'function_factory',
        'view': 'view_controller',
        'data': 'ceed_data',
        'serializer': 'data_serializer',
        'player': 'player',
    }

    last_directory = StringProperty('~')
    """The last directory opened in the GUI.
    """

    external_function_plugin_package: str = ''
    """The name of an external function plugin package that contains additional
    functions to be displayed in the GUI to the user.

    See :mod:`~ceed.function.plugin` for details.
    """

    external_stage_plugin_package: str = ''
    """The name of an external stage plugin package that contains additional
    stages to be displayed in the GUI to the user.

    See :mod:`~ceed.stage.plugin` for details.
    """

    kv_loaded = False
    """For tests, we don't want to load kv multiple times so we only load kv if
    it wasn't loaded before.
    """

    yesno_prompt = ObjectProperty(None, allownone=True)
    '''Stores a instance of :class:`YesNoPrompt` that is automatically created
    by this app class. That class is described in ``base_kivy_app/graphics.kv``
    and shows a prompt with yes/no options and callback.
    '''

    function_factory: FunctionFactoryBase = None
    """The :class:`~ceed.function.FunctionFactoryBase` that contains all the
    functions shown in the GUI.
    """

    player: CeedPlayer = None
    """The :class:`ceed.player.CeedPlayer` used to play the video camera and
    record the images to disk.
    """

    view_controller: ControllerSideViewControllerBase = None
    """The :class:`~ceed.view.controller.ControllerSideViewControllerBase` used
    to run the experiment and display the stages.
    """

    ceed_data: CeedDataWriterBase = None
    """The :class:`~ceed.storage.controller.CeedDataWriterBase` used to load
    and save the data to disk.
    """

    data_serializer: DataSerializerBase = None
    """The :class:`~ceed.storage.controller.DataSerializerBase` used to
    generate the corner pixel values for Ceed-MCS temporal synchronization.
    """

    stage_factory: StageFactoryBase = None
    """The :class:`~ceed.stage.StageFactoryBase` that contains all the
    stages shown in the GUI.
    """

    shape_factory: CeedPainter = ObjectProperty(None, rebind=True)
    """The :class:`~ceed.shape.shape_widgets.CeedPainter` used to draw shapes
    and contains all the shapes shown in the GUI.
    """

    agreed_discard = False

    drag_controller: CeedDragNDrop = ObjectProperty(None, rebind=True)
    """The :class:`~ceed.graphics.CeedDragNDrop` used for dragging and
    dropping widgets on in the GUI.
    """

    stages_container: StageList = ObjectProperty(None, rebind=True)
    """The :class:`~ceed.stage.stage_widgets.StageList` widget that contains
    all the root stages' widgets in the GUI.
    """

    funcs_container: FuncList = ObjectProperty(None, rebind=True)
    """The :class:`~ceed.function.func_widgets.FuncList` widget that contains
    all the root functions' widgets in the GUI.
    """

    shapes_container: ShapeList = ObjectProperty(None, rebind=True)
    """The :class:`~ceed.shape.shape_widgets.ShapeList` widget that contains
    all the shapes' widgets in the GUI.
    """

    shape_groups_container = ObjectProperty(
        None, rebind=True)  # type: ShapeGroupList
    """The :class:`~ceed.shape.shape_widgets.ShapeGroupList` widget that
    contains all the shape groups' widgets in the GUI.
    """

    pinned_graph = None
    """PinnedGraph widget into which the experiment preview graph may be pinned.

    When pinned, it's displayed not as a popup, but as a flat widget.
    """

    mea_align_widget: MEAArrayAlign = ObjectProperty(None, rebind=True)
    """The :class:`~ceed.view.view_widgets.MEAArrayAlign` widget used to align
    the MEA grid to the camera.
    """

    central_display: BufferImage = ObjectProperty(None, rebind=True)
    """The :class:`~base_kivy_app.graphics.BufferImage` widget into which the
    camera widget is drawn.
    """

    _processing_error = False

    def __init__(self, open_player_thread=True, **kwargs):
        self.drag_controller = CeedDragNDrop()
        self.function_factory = FunctionFactoryBase()
        register_all_functions(self.function_factory)

        self.stage_factory = StageFactoryBase(
            function_factory=self.function_factory, shape_factory=None)
        register_all_stages(self.stage_factory)
        self.player = CeedPlayer(open_player_thread=open_player_thread)
        self.view_controller = ControllerSideViewControllerBase()
        self.ceed_data = CeedDataWriterBase()
        self.data_serializer = DataSerializerBase()
        super(CeedApp, self).__init__(**kwargs)
        self.load_app_settings_from_file()
        self.apply_app_settings()

    def load_app_kv(self):
        """Loads the app's kv files, if not yet loaded.
        """
        if CeedApp.kv_loaded:
            return
        CeedApp.kv_loaded = True

        base = dirname(__file__)
        # Builder.load_file(join(base, 'graphics', 'graphics.kv'))
        Builder.load_file(join(base, 'ceed_style.kv'))
        Builder.load_file(join(base, 'player', 'player_style.kv'))
        Builder.load_file(join(base, 'shape', 'shape_style.kv'))
        Builder.load_file(join(base, 'function', 'func_style.kv'))
        Builder.load_file(join(base, 'stage', 'stage_style.kv'))
        Builder.load_file(join(base, 'view', 'view_style.kv'))
        Builder.load_file(join(base, 'storage', 'storage_style.kv'))

    def build(self):
        self.load_app_kv()
        self.yesno_prompt = Factory.FlatYesNoPrompt()
        self.player.create_widgets()

        root = Factory.get('MainView')()
        return super(CeedApp, self).build(root)

    def _clear_all(self):
        self.funcs_container.clear_all()
        self.stages_container.clear_all()

    def on_start(self):
        if self.external_function_plugin_package:
            register_external_functions(self.function_factory,
                                        self.external_function_plugin_package)

        if self.external_stage_plugin_package:
            register_external_stages(self.stage_factory,
                                     self.external_stage_plugin_package)

        self.stage_factory.shape_factory = self.shape_factory
        remove_shapes_upon_deletion(
            self.stage_factory, self.shape_factory,
            self.stages_container.remove_shape_from_stage)
        self.shape_factory.shape_widgets_list = self.shapes_container

        self.ceed_data.stage_display_callback = \
            self.stages_container.show_stage
        self.ceed_data.func_display_callback = \
            self.funcs_container.show_function
        self.ceed_data.clear_all_callback = self._clear_all

        HighightButtonBehavior.init_class()

        self.ceed_data.create_file('')

        self.stage_factory.fbind('on_changed', self.changed_callback)
        for stage in self.stage_factory.stages_inst_default.values():
            stage.fbind('on_changed', self.changed_callback)
        self.function_factory.fbind('on_changed', self.changed_callback)
        for func in self.function_factory.funcs_inst_default.values():
            func.fbind('on_changed', self.changed_callback)
        self.shape_factory.fbind('on_changed', self.changed_callback)
        self.view_controller.fbind('on_changed', self.changed_callback)

        self.set_tittle()
        self.ceed_data.fbind('filename', self.set_tittle)
        self.ceed_data.fbind('config_changed', self.set_tittle)
        self.ceed_data.fbind('has_unsaved', self.set_tittle)
        self.ceed_data.fbind('read_only_file', self.set_tittle)

        self.view_controller.set_led_mode(self.view_controller.LED_mode_idle)

    def set_tittle(self, *largs):
        """Periodically called by the Kivy Clock to update the title.
        """
        star = ''
        if self.ceed_data.has_unsaved or self.ceed_data.config_changed:
            star = '*'

        read_only = ''
        if self.ceed_data.read_only_file:
            read_only = ' - Read Only'

        if self.ceed_data.filename:
            filename = ' - {}'.format(self.ceed_data.filename)
        else:
            filename = ' - Unnamed File'

        Window.set_title('Ceed v{}, CPL lab{}{}{}'.format(
            ceed.__version__, star, filename, read_only))

    def changed_callback(self, *largs, **kwargs):
        """Callback bound to anything that can change the Ceed data to indicate
        whether it needs to be re-saved.
        """
        self.ceed_data.config_changed = True

    def check_close(self):
        if self.view_controller.stage_active or self.ceed_data.data_thread:
            self._close_message = 'Cannot close during an experiment.'
            return False
        self.player.stop()
        self.view_controller.stop_process()
        self.view_controller.finish_stop_process()
        if not self.ceed_data.ui_close(app_close=True):
            self._close_message = ''
            return False
        return True

    def handle_exception(self, *largs, **kwargs):
        processing = self._processing_error
        self._processing_error = True
        val = super(CeedApp, self).handle_exception(*largs, **kwargs)
        if not processing:
            self.view_controller.request_stage_end()
            self._processing_error = False
        return val

    def clean_up(self):
        super(CeedApp, self).clean_up()
        if self.ceed_data is not None:
            if self.ceed_data.backup_event is not None:
                self.ceed_data.backup_event.cancel()
                self.ceed_data.backup_event = None
            self.ceed_data.clear_all_callback = None

        if self.stage_factory is not None:
            self.stage_factory.funbind('on_changed', self.changed_callback)
        if self.function_factory is not None:
            self.function_factory.funbind('on_changed', self.changed_callback)
        if self.shape_factory is not None:
            self.shape_factory.funbind('on_changed', self.changed_callback)
        if self.view_controller is not None:
            self.view_controller.funbind('on_changed', self.changed_callback)

        for stage in self.stage_factory.stages_inst_default.values():
            stage.funbind('on_changed', self.changed_callback)
        for func in self.function_factory.funcs_inst_default.values():
            func.funbind('on_changed', self.changed_callback)

        if self.view_controller is not None:
            self.view_controller.stop_process()
            self.view_controller.finish_stop_process()

        if self.ceed_data is not None:
            self.ceed_data.stop_experiment()
            self.ceed_data.funbind('filename', self.set_tittle)
            self.ceed_data.funbind('config_changed', self.set_tittle)
            self.ceed_data.funbind('has_unsaved', self.set_tittle)
            self.ceed_data.funbind('read_only_file', self.set_tittle)

        self.dump_app_settings_to_file()
        self.player.clean_up()
        HighightButtonBehavior.uninit_class()
Beispiel #27
0
class CeedApp(BaseKivyApp):
    '''The app which runs the GUI.
    '''

    __config_props__ = ('last_directory', )

    last_directory = StringProperty('~')

    kv_loaded = False
    """For tests, we don't want to load kv multiple times.
    """

    yesno_prompt = ObjectProperty(None, allownone=True)
    '''Stores a instance of :class:`YesNoPrompt` that is automatically created
    by this app class. That class is described in ``base_kivy_app/graphics.kv``.
    '''

    function_factory = None  # type: FunctionFactoryBase

    player = None  # type: CeedPlayer

    view_controller = None  # type: ControllerSideViewControllerBase

    ceed_data = None  # type: CeedDataWriterBase

    data_serializer = None  # type: DataSerializerBase

    stage_factory = None  # type: StageFactoryBase

    shape_factory = ObjectProperty(None, rebind=True)  # type: CeedPainter

    # remote_player = None  # type: CeedRemotePlayer

    agreed_discard = False

    drag_controller = ObjectProperty(None, rebind=True)  # type: CeedDragNDrop

    stages_container = ObjectProperty(None, rebind=True)  # type: StageList

    funcs_container = ObjectProperty(None, rebind=True)  # type: FuncList

    shapes_container = ObjectProperty(None, rebind=True)  # type: ShapeList

    shape_groups_container = ObjectProperty(
        None, rebind=True)  # type: ShapeGroupList

    pinned_graph = None
    """PinnedGraph into which the stage graph may be pinned.
    """

    mea_align_widget = ObjectProperty(None, rebind=True)  # type: MEAArrayAlign

    central_display = ObjectProperty(None, rebind=True)  # type: BufferImage

    _processing_error = False

    @classmethod
    def get_config_classes(cls):
        d = super(CeedApp, cls).get_config_classes()
        d['function'] = FunctionFactoryBase
        d['view'] = ControllerSideViewControllerBase
        d['data'] = CeedDataWriterBase
        d['serializer'] = DataSerializerBase
        d['player'] = CeedPlayer
        return d

    def get_config_instances(self):
        d = super(CeedApp, self).get_config_instances()
        d['function'] = self.function_factory
        d['view'] = self.view_controller
        d['data'] = self.ceed_data
        d['serializer'] = self.data_serializer
        d['player'] = self.player
        return d

    def __init__(self, open_player_thread=True, **kwargs):
        self.drag_controller = CeedDragNDrop()
        self.function_factory = FunctionFactoryBase()
        register_all_functions(self.function_factory)
        self.stage_factory = StageFactoryBase(
            function_factory=self.function_factory, shape_factory=None)
        self.player = CeedPlayer(open_player_thread=open_player_thread)
        self.view_controller = ControllerSideViewControllerBase()
        self.ceed_data = CeedDataWriterBase()
        self.data_serializer = DataSerializerBase()
        super(CeedApp, self).__init__(**kwargs)
        self.load_app_settings_from_file()
        self.apply_app_settings()

    def load_app_kv(self):
        if CeedApp.kv_loaded:
            return
        CeedApp.kv_loaded = True

        base = dirname(__file__)
        # Builder.load_file(join(base, 'graphics', 'graphics.kv'))
        Builder.load_file(join(base, 'ceed_style.kv'))
        Builder.load_file(join(base, 'player', 'player_style.kv'))
        Builder.load_file(join(base, 'shape', 'shape_style.kv'))
        Builder.load_file(join(base, 'function', 'func_style.kv'))
        Builder.load_file(join(base, 'stage', 'stage_style.kv'))
        Builder.load_file(join(base, 'view', 'view_style.kv'))
        Builder.load_file(join(base, 'storage', 'storage_style.kv'))

    def build(self):
        self.load_app_kv()
        self.yesno_prompt = Factory.FlatYesNoPrompt()
        self.player.create_widgets()

        root = Factory.get('MainView')()
        return super(CeedApp, self).build(root)

    def _clear_all(self):
        self.funcs_container.clear_all()
        self.stages_container.clear_all()

    def on_start(self):
        self.stage_factory.shape_factory = self.shape_factory
        remove_shapes_upon_deletion(
            self.stage_factory, self.shape_factory,
            self.stages_container.remove_shape_from_stage)
        self.shape_factory.shape_widgets_list = self.shapes_container

        self.ceed_data.stage_display_callback = \
            self.stages_container.show_stage
        self.ceed_data.func_display_callback = \
            self.funcs_container.show_function
        self.ceed_data.clear_all_callback = self._clear_all

        HighightButtonBehavior.init_class()

        self.ceed_data.create_file('')

        self.stage_factory.fbind('on_changed', self.changed_callback)
        self.function_factory.fbind('on_changed', self.changed_callback)
        for func in self.function_factory.funcs_inst_default.values():
            func.fbind('on_changed', self.changed_callback)
        self.shape_factory.fbind('on_changed', self.changed_callback)
        self.view_controller.fbind('on_changed', self.changed_callback)

        self.set_tittle()
        self.ceed_data.fbind('filename', self.set_tittle)
        self.ceed_data.fbind('config_changed', self.set_tittle)
        self.ceed_data.fbind('has_unsaved', self.set_tittle)
        self.ceed_data.fbind('read_only_file', self.set_tittle)

        self.view_controller.set_led_mode(self.view_controller.LED_mode_idle)

    def set_tittle(self, *largs):
        ''' Sets the title of the window using the currently running
        tab. This is called at 1Hz. '''
        star = ''
        if self.ceed_data.has_unsaved or self.ceed_data.config_changed:
            star = '*'

        read_only = ''
        if self.ceed_data.read_only_file:
            read_only = ' - Read Only'

        if self.ceed_data.filename:
            filename = ' - {}'.format(self.ceed_data.filename)
        else:
            filename = ' - Unnamed File'

        Window.set_title('Ceed v{}, CPL lab{}{}{}'.format(
            ceed.__version__, star, filename, read_only))

    def changed_callback(self, *largs, **kwargs):
        self.ceed_data.config_changed = True

    def check_close(self):
        if self.view_controller.stage_active or self.ceed_data.data_thread:
            self._close_message = 'Cannot close during an experiment.'
            return False
        self.player.stop()
        self.view_controller.stop_process()
        self.view_controller.finish_stop_process()
        if not self.ceed_data.ui_close(app_close=True):
            self._close_message = ''
            return False
        return True

    def handle_exception(self, *largs, **kwargs):
        processing = self._processing_error
        self._processing_error = True
        val = super(CeedApp, self).handle_exception(*largs, **kwargs)
        if not processing:
            self.view_controller.request_stage_end()
            self._processing_error = False
        return val

    def clean_up(self):
        super(CeedApp, self).clean_up()
        if self.ceed_data is not None:
            if self.ceed_data.backup_event is not None:
                self.ceed_data.backup_event.cancel()
                self.ceed_data.backup_event = None
            self.ceed_data.clear_all_callback = None

        if self.stage_factory is not None:
            self.stage_factory.funbind('on_changed', self.changed_callback)
        if self.function_factory is not None:
            self.function_factory.funbind('on_changed', self.changed_callback)
        if self.shape_factory is not None:
            self.shape_factory.funbind('on_changed', self.changed_callback)
        if self.view_controller is not None:
            self.view_controller.funbind('on_changed', self.changed_callback)

        for func in self.function_factory.funcs_inst_default.values():
            func.funbind('on_changed', self.changed_callback)

        if self.view_controller is not None:
            self.view_controller.stop_process()
            self.view_controller.finish_stop_process()
        if self.ceed_data is not None:
            self.ceed_data.stop_experiment()
            self.ceed_data.funbind('filename', self.set_tittle)
            self.ceed_data.funbind('config_changed', self.set_tittle)
            self.ceed_data.funbind('has_unsaved', self.set_tittle)
            self.ceed_data.funbind('read_only_file', self.set_tittle)

        self.dump_app_settings_to_file()
        self.player.clean_up()
        HighightButtonBehavior.uninit_class()
Beispiel #28
0
def test_register_funcs():
    from ceed.function.plugin import ConstFunc, LinearFunc
    function_factory = FunctionFactoryBase()
    count = 0

    def count_changes(*largs):
        nonlocal count
        count += 1

    function_factory.fbind('on_changed', count_changes)

    assert not function_factory.funcs_cls
    assert not function_factory.funcs_user
    assert not function_factory.funcs_inst
    assert not function_factory.funcs_inst_default
    assert not function_factory.get_classes()
    assert not function_factory.get_names()

    function_factory.register(ConstFunc)
    assert count
    assert function_factory.funcs_cls['ConstFunc'] is ConstFunc
    assert isinstance(function_factory.funcs_inst['Const'], ConstFunc)
    assert isinstance(function_factory.funcs_inst_default['Const'], ConstFunc)
    assert ConstFunc in function_factory.get_classes()
    assert 'ConstFunc' in function_factory.get_names()

    f = LinearFunc(function_factory=function_factory)
    count = 0
    function_factory.register(LinearFunc, instance=f)
    assert count
    assert function_factory.funcs_cls['LinearFunc'] is LinearFunc
    assert function_factory.funcs_inst['Linear'] is f
    assert function_factory.funcs_inst_default['Linear'] is f
    assert LinearFunc in function_factory.get_classes()
    assert 'LinearFunc' in function_factory.get_names()
    assert not function_factory.funcs_user
Beispiel #29
0
def test_replace_ref_func_with_source_funcs(
        function_factory: FunctionFactoryBase):
    from ceed.function import FuncGroup, CeedFuncRef
    factory = function_factory
    const_cls = factory.get('ConstFunc')

    g1 = FuncGroup(function_factory=factory, name='g1')

    g2 = FuncGroup(function_factory=factory, name='g2')
    ref_g2 = function_factory.get_func_ref(func=g2)
    g1.add_func(ref_g2)

    f = const_cls(function_factory=factory, a=.9, duration=2)
    g2.add_func(f)

    f1 = const_cls(function_factory=factory, a=.1, duration=2, name='f1')
    function_factory.add_func(f1)
    ref_f1 = function_factory.get_func_ref(func=f1)
    g2.add_func(ref_f1)

    f2 = const_cls(function_factory=factory, a=.25, duration=2)
    g1.add_func(f2)

    f3 = const_cls(function_factory=factory, a=.75, duration=2, name='f3')
    function_factory.add_func(f3)
    ref_f3 = function_factory.get_func_ref(func=f3)
    g1.add_func(ref_f3)

    with pytest.raises(ValueError):
        g1.replace_ref_func_with_source(f2)

    with pytest.raises(ValueError):
        g1.replace_ref_func_with_source(ref_f1)

    f3_new, i = g1.replace_ref_func_with_source(ref_f3)

    assert i == 2
    assert ref_f3 not in g1.funcs
    assert f3 not in g1.funcs
    assert not isinstance(f3_new, CeedFuncRef)
    assert isinstance(f3_new, f3.__class__)
    assert g1.funcs[i] is f3_new

    for name in f3.get_gui_props():
        if name == 'name':
            continue
        assert getattr(f3, name) == getattr(f3_new, name)

    g2_new: FuncGroup
    g2_new, i = g1.replace_ref_func_with_source(ref_g2)

    assert i == 0
    assert ref_g2 not in g1.funcs
    assert g2 not in g1.funcs
    assert not isinstance(g2_new, CeedFuncRef)
    assert isinstance(g2_new, FuncGroup)
    assert g1.funcs[i] is g2_new

    assert len(g2_new.funcs) == 2
    assert g2_new.funcs[0] is not g2.funcs[0]
    assert g2_new.funcs[1] is not g2.funcs[1]
    assert isinstance(g2_new.funcs[0], f.__class__)
    assert isinstance(g2_new.funcs[1], ref_f1.__class__)
    assert isinstance(g2_new.funcs[1], CeedFuncRef)

    for name in f.get_gui_props():
        if name == 'name':
            continue
        assert getattr(f, name) == getattr(g2_new.funcs[0], name)
    assert g2_new.funcs[1].func is f1
Beispiel #30
0
def test_recover_ref_funcs(function_factory: FunctionFactoryBase):
    from ceed.function import FuncGroup, CeedFuncRef
    f1 = function_factory.get('ConstFunc')(function_factory=function_factory,
                                           a=.5,
                                           name='f1',
                                           duration=1.2)
    f2 = function_factory.get('LinearFunc')(function_factory=function_factory,
                                            m=.5,
                                            b=.2,
                                            name='f2',
                                            duration=1.2)
    f3 = function_factory.get('ExponentialFunc')(
        function_factory=function_factory,
        A=.5,
        B=.2,
        tau1=1.3,
        tau2=1.5,
        name='f3',
        duration=1.2)
    f4 = function_factory.get('CosFunc')(function_factory=function_factory,
                                         f=.5,
                                         A=3.4,
                                         th0=7.5,
                                         b=12.2,
                                         name='f4',
                                         duration=1.2)
    g = FuncGroup(function_factory=function_factory, name='g')

    function_factory.add_func(f1)
    function_factory.add_func(f2)
    function_factory.add_func(f3)
    function_factory.add_func(f4)
    function_factory.add_func(g)

    g.add_func(function_factory.get_func_ref(name='f1'))
    g.add_func(function_factory.get_func_ref(name='f2'))
    g.add_func(function_factory.get_func_ref(name='f3'))
    g.add_func(function_factory.get_func_ref(name='f4'))

    funcs = function_factory.save_functions()
    assert len(funcs) == 5

    recovered_funcs, name_mapping = function_factory.recover_funcs(funcs)
    assert len(recovered_funcs) == 5
    assert len(name_mapping) == 5

    for f_name in ('f1', 'f2', 'f3', 'f4', 'g'):
        assert f_name in name_mapping
        assert name_mapping[f_name] != f_name
        assert f_name in function_factory.funcs_inst
        assert name_mapping[f_name] in function_factory.funcs_inst

        for name in function_factory.funcs_inst[f_name].get_gui_props():
            original_f = function_factory.funcs_inst[f_name]
            new_f = function_factory.funcs_inst[name_mapping[f_name]]

            if name == 'name':
                assert original_f.name != new_f.name
                assert new_f.name.startswith(original_f.name)
                continue

            assert getattr(original_f, name) == getattr(new_f, name)

    new_g: FuncGroup = function_factory.funcs_inst[name_mapping['g']]
    assert len(new_g.funcs) == 4

    func: CeedFuncRef
    for func, name in zip(new_g.funcs, ('f1', 'f2', 'f3', 'f4')):
        assert isinstance(func, CeedFuncRef)
        assert func.func is function_factory.funcs_inst[name_mapping[name]]
Beispiel #31
0
def test_clear_funcs_with_ref(function_factory: FunctionFactoryBase):
    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    f2 = const_cls(function_factory=function_factory,
                   duration=5,
                   a=.9,
                   name='f2')

    function_factory.add_func(f)
    function_factory.add_func(f2)

    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user
    assert function_factory.funcs_inst['f2'] is f2
    assert f2 in function_factory.funcs_user

    ref = function_factory.get_func_ref(name='f')
    function_factory.clear_added_funcs()

    # f should not have been removed, but f2 was removed
    assert ref.func is f
    assert f.has_ref
    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user
    assert 'f2' not in function_factory.funcs_inst
    assert f2 not in function_factory.funcs_user

    function_factory.clear_added_funcs(force=True)

    assert ref.func is f
    assert f.has_ref
    assert 'f' not in function_factory.funcs_inst
    assert f not in function_factory.funcs_user

    function_factory.return_func_ref(ref)
    assert not f.has_ref
Beispiel #32
0
def test_remove_func_with_ref(function_factory: FunctionFactoryBase):
    const_cls = function_factory.get('ConstFunc')
    f = const_cls(function_factory=function_factory,
                  duration=4,
                  a=.7,
                  name='f')
    f2 = const_cls(function_factory=function_factory,
                   duration=5,
                   a=.9,
                   name='f2')
    f3 = const_cls(function_factory=function_factory,
                   duration=5,
                   a=.9,
                   name='f3')

    function_factory.add_func(f)
    function_factory.add_func(f2)
    function_factory.add_func(f3)

    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user
    assert function_factory.funcs_inst['f2'] is f2
    assert f2 in function_factory.funcs_user
    assert function_factory.funcs_inst['f3'] is f3
    assert f3 in function_factory.funcs_user

    ref = function_factory.get_func_ref(name='f')
    ref3 = function_factory.get_func_ref(name='f3')
    assert not function_factory.remove_func(f)

    assert ref.func is f
    assert f.has_ref
    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user
    assert function_factory.funcs_inst['f2'] is f2
    assert f2 in function_factory.funcs_user
    assert function_factory.funcs_inst['f3'] is f3
    assert f3 in function_factory.funcs_user

    assert function_factory.remove_func(f2)

    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user
    assert 'f2' not in function_factory.funcs_inst
    assert f2 not in function_factory.funcs_user
    assert function_factory.funcs_inst['f3'] is f3
    assert f3 in function_factory.funcs_user

    assert not function_factory.remove_func(f3)

    assert ref3.func is f3
    assert f3.has_ref
    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user
    assert function_factory.funcs_inst['f3'] is f3
    assert f3 in function_factory.funcs_user

    assert function_factory.remove_func(f3, force=True)

    assert ref3.func is f3
    assert f3.has_ref
    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user
    assert 'f3' not in function_factory.funcs_inst
    assert f3 not in function_factory.funcs_user

    assert not function_factory.remove_func(f)

    assert ref.func is f
    assert f.has_ref
    assert function_factory.funcs_inst['f'] is f
    assert f in function_factory.funcs_user

    function_factory.return_func_ref(ref)
    assert not f.has_ref

    assert function_factory.remove_func(f)

    assert 'f' not in function_factory.funcs_inst
    assert f not in function_factory.funcs_user

    function_factory.return_func_ref(ref3)
    assert not f3.has_ref