Skip to content

Define Experiments

CompNeuroPy.experiment.CompNeuroExp #

Experiment combining simulations and recordings.

Use this class as a parent class for your experiment. You have to additionally implement a run function which runs the simulations and controlls the recordings. The run function should return the results of the experiment by calling the results function of the CompNeuroExp class.

Attributes:

Name Type Description
monitors CompNeuroMonitors

CompNeuroMonitors object for recordings

data dict

dict for storing optional data

Examples:

from CompNeuroPy import CompNeuroExp
from ANNarchy import simulate

class MyExperiment(CompNeuroExp):
    def run(self):
        # run simulations and control recordings
        self.monitors.start()
        simulate(1000)
        self.reset()
        simulate(1000)
        # store optional data
        self.data["duration"] = 2000
        # return results
        return self.results()
Source code in src/CompNeuroPy/experiment.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
class CompNeuroExp:
    """
    Experiment combining simulations and recordings.

    Use this class as a parent class for your experiment. You have to additionally
    implement a run function which runs the simulations and controlls the recordings.
    The run function should return the results of the experiment by calling the results
    function of the CompNeuroExp class.

    Attributes:
        monitors (CompNeuroMonitors):
            CompNeuroMonitors object for recordings
        data (dict):
            dict for storing optional data

    Examples:
        ```python
        from CompNeuroPy import CompNeuroExp
        from ANNarchy import simulate

        class MyExperiment(CompNeuroExp):
            def run(self):
                # run simulations and control recordings
                self.monitors.start()
                simulate(1000)
                self.reset()
                simulate(1000)
                # store optional data
                self.data["duration"] = 2000
                # return results
                return self.results()
        ```
    """

    def __init__(
        self,
        monitors: CompNeuroMonitors | None = None,
    ):
        """
        Initialize the experiment.

        Args:
            monitors (CompNeuroMonitors):
                CompNeuroMonitors object for recordings
        """
        self.monitors = monitors
        self.data = {}  # dict for optional data
        self._model_state = None

    def store_model_state(self, compartment_list: list[str]):
        """
        Store the state of the model. If this is called, reset does not reset the model
        to compile state but to the state stored here.

        Args:
            compartment_list (list[str]):
                list of compartments to store the state of
        """
        self._model_state = mf._get_all_attributes(compartment_list)

    def reset_model_state(self):
        """
        Reset the stored model state.
        """
        self._model_state = None

    def reset(
        self,
        populations=True,
        projections=False,
        synapses=False,
        model=True,
        model_state=True,
        parameters=True,
    ):
        """
        Reset the ANNarchy model and monitors and the CompNeuroMonitors used for the
        experiment.

        !!! warning
            If you want the network to have the same state at the beginning of each
            experiment run, you should call this function at the beginning of the run
            function of the CompNeuroExp class (except using OptNeuron)! If you only
            want to have the same time for the network at the beginning of each
            experiment run, set populations, projections, and synapses to False and
            model to True. If you want to set parameters during the experiment and also
            reset the dynamic variables without resetting the parameters, set parameters
            to False.

        Args:
            populations (bool, optional):
                reset populations. Defaults to True.
            projections (bool, optional):
                reset projections. Defaults to False.
            synapses (bool, optional):
                reset synapses. Defaults to False.
            model (bool, optional):
                If False, do ignore all other arguments (the network state doesn't
                change) and only reset the CompNeuroMonitors (creating new chunk)
                Default: True.
            model_state (bool, optional):
                If True, reset the model to the stored model state instead of
                compilation state (all compartments not stored in the model state will
                still be resetted to compilation state). Default: True.
            parameters (bool, optional):
                If True, reset the parameters of the model (either to compile or stored
                state). Default: True.
        """
        reset_kwargs = {}
        reset_kwargs["populations"] = populations
        reset_kwargs["projections"] = projections
        reset_kwargs["synapses"] = synapses
        reset_kwargs["monitors"] = True

        ### reset CompNeuroMonitors and ANNarchy model
        if self.monitors is not None:
            ### there are monitors, therefore use theri reset function
            self.monitors.reset(model=model, **reset_kwargs, parameters=parameters)
            ### after reset, set the state of the model to the stored state
            if model_state and self._model_state is not None and model is True:
                ### if parameters=False, they are not set
                mf._set_all_attributes(self._model_state, parameters=parameters)
        elif model is True:
            if parameters is False:
                ### if parameters=False, get parameters before reset and set them after
                ### reset
                parameters_dict = mf._get_all_parameters()
            ### there are no monitors, but model should be resetted, therefore use
            ### ANNarchy's reset function
            reset(**reset_kwargs)
            if parameters is False:
                ### if parameters=False, set parameters after reset
                mf._set_all_parameters(parameters_dict)
            ### after reset, set the state of the model to the stored state
            if model_state and self._model_state is not None:
                ### if parameters=False, they are not set
                mf._set_all_attributes(self._model_state, parameters=parameters)

    def results(self):
        """
        !!! warning
            Call this function at the end of the run function of the CompNeuroExp class!

        !!! warning
            Calling this function resets the CompNeuroMonitors. For example, if you
            simulate two recording chunks in the run function and you run the experiment
            twice, you will get two recording chunks for each experiment run (not two
            for the first and four for the second run). But ANNarchy is not resetted
            automatically! So the network time and state (activity etc.) at the
            beginning of the second run is the same as at the end of the first run. To
            prevent this use the reset function of the CompNeuroExp class.

        Returns:
            results_obj (CompNeuroExp._ResultsCl):
                Object with attributes:
                    recordings (list):
                        list of recordings
                    recording_times (recording_times_cl):
                        recording times object
                    mon_dict (dict):
                        dict of recorded variables of the monitors
                    data (dict):
                        dict with optional data stored during the experiment
        """
        obj = self._ResultsCl()
        if self.monitors is not None:
            (
                obj.recordings,
                obj.recording_times,
            ) = self.monitors.get_recordings_and_clear()
            obj.mon_dict = self.monitors.mon_dict
        else:
            obj.recordings = []
            obj.recording_times = None
            obj.mon_dict = {}
        ### need deepcopy here because experiment can be run mutliple times and within
        ### experiment the entries of self.data can be changed, and without deepcopy
        ### the data of older results objects would also be changed
        obj.data = deepcopy(self.data)

        return obj

    class _ResultsCl:
        """
        Class for storing the results of the experiment.

        Attributes:
            recordings (list):
                list of recordings
            recording_times (recording_times_cl):
                recording times object
            mon_dict (dict):
                dict of recorded variables of the monitors
            data (dict):
                dict with optional data stored during the experiment
        """

        def __init__(self) -> None:
            self.recordings: list
            self.recording_times: RecordingTimes
            self.mon_dict: dict
            self.data: dict

    def run(self) -> _ResultsCl:
        """
        !!! warning
            This function has to be implemented by the user!
        """
        raise NotImplementedError(
            """
                You have to implement a run function which runs the simulations and
                controlls the recordings. The run function should return the results of
                the experiment by calling the results function of the CompNeuroExp class.
            """
        )

__init__(monitors=None) #

Initialize the experiment.

Parameters:

Name Type Description Default
monitors CompNeuroMonitors

CompNeuroMonitors object for recordings

None
Source code in src/CompNeuroPy/experiment.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def __init__(
    self,
    monitors: CompNeuroMonitors | None = None,
):
    """
    Initialize the experiment.

    Args:
        monitors (CompNeuroMonitors):
            CompNeuroMonitors object for recordings
    """
    self.monitors = monitors
    self.data = {}  # dict for optional data
    self._model_state = None

store_model_state(compartment_list) #

Store the state of the model. If this is called, reset does not reset the model to compile state but to the state stored here.

Parameters:

Name Type Description Default
compartment_list list[str]

list of compartments to store the state of

required
Source code in src/CompNeuroPy/experiment.py
57
58
59
60
61
62
63
64
65
66
def store_model_state(self, compartment_list: list[str]):
    """
    Store the state of the model. If this is called, reset does not reset the model
    to compile state but to the state stored here.

    Args:
        compartment_list (list[str]):
            list of compartments to store the state of
    """
    self._model_state = mf._get_all_attributes(compartment_list)

reset_model_state() #

Reset the stored model state.

Source code in src/CompNeuroPy/experiment.py
68
69
70
71
72
def reset_model_state(self):
    """
    Reset the stored model state.
    """
    self._model_state = None

reset(populations=True, projections=False, synapses=False, model=True, model_state=True, parameters=True) #

Reset the ANNarchy model and monitors and the CompNeuroMonitors used for the experiment.

Warning

If you want the network to have the same state at the beginning of each experiment run, you should call this function at the beginning of the run function of the CompNeuroExp class (except using OptNeuron)! If you only want to have the same time for the network at the beginning of each experiment run, set populations, projections, and synapses to False and model to True. If you want to set parameters during the experiment and also reset the dynamic variables without resetting the parameters, set parameters to False.

Parameters:

Name Type Description Default
populations bool

reset populations. Defaults to True.

True
projections bool

reset projections. Defaults to False.

False
synapses bool

reset synapses. Defaults to False.

False
model bool

If False, do ignore all other arguments (the network state doesn't change) and only reset the CompNeuroMonitors (creating new chunk) Default: True.

True
model_state bool

If True, reset the model to the stored model state instead of compilation state (all compartments not stored in the model state will still be resetted to compilation state). Default: True.

True
parameters bool

If True, reset the parameters of the model (either to compile or stored state). Default: True.

True
Source code in src/CompNeuroPy/experiment.py
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def reset(
    self,
    populations=True,
    projections=False,
    synapses=False,
    model=True,
    model_state=True,
    parameters=True,
):
    """
    Reset the ANNarchy model and monitors and the CompNeuroMonitors used for the
    experiment.

    !!! warning
        If you want the network to have the same state at the beginning of each
        experiment run, you should call this function at the beginning of the run
        function of the CompNeuroExp class (except using OptNeuron)! If you only
        want to have the same time for the network at the beginning of each
        experiment run, set populations, projections, and synapses to False and
        model to True. If you want to set parameters during the experiment and also
        reset the dynamic variables without resetting the parameters, set parameters
        to False.

    Args:
        populations (bool, optional):
            reset populations. Defaults to True.
        projections (bool, optional):
            reset projections. Defaults to False.
        synapses (bool, optional):
            reset synapses. Defaults to False.
        model (bool, optional):
            If False, do ignore all other arguments (the network state doesn't
            change) and only reset the CompNeuroMonitors (creating new chunk)
            Default: True.
        model_state (bool, optional):
            If True, reset the model to the stored model state instead of
            compilation state (all compartments not stored in the model state will
            still be resetted to compilation state). Default: True.
        parameters (bool, optional):
            If True, reset the parameters of the model (either to compile or stored
            state). Default: True.
    """
    reset_kwargs = {}
    reset_kwargs["populations"] = populations
    reset_kwargs["projections"] = projections
    reset_kwargs["synapses"] = synapses
    reset_kwargs["monitors"] = True

    ### reset CompNeuroMonitors and ANNarchy model
    if self.monitors is not None:
        ### there are monitors, therefore use theri reset function
        self.monitors.reset(model=model, **reset_kwargs, parameters=parameters)
        ### after reset, set the state of the model to the stored state
        if model_state and self._model_state is not None and model is True:
            ### if parameters=False, they are not set
            mf._set_all_attributes(self._model_state, parameters=parameters)
    elif model is True:
        if parameters is False:
            ### if parameters=False, get parameters before reset and set them after
            ### reset
            parameters_dict = mf._get_all_parameters()
        ### there are no monitors, but model should be resetted, therefore use
        ### ANNarchy's reset function
        reset(**reset_kwargs)
        if parameters is False:
            ### if parameters=False, set parameters after reset
            mf._set_all_parameters(parameters_dict)
        ### after reset, set the state of the model to the stored state
        if model_state and self._model_state is not None:
            ### if parameters=False, they are not set
            mf._set_all_attributes(self._model_state, parameters=parameters)

results() #

Warning

Call this function at the end of the run function of the CompNeuroExp class!

Warning

Calling this function resets the CompNeuroMonitors. For example, if you simulate two recording chunks in the run function and you run the experiment twice, you will get two recording chunks for each experiment run (not two for the first and four for the second run). But ANNarchy is not resetted automatically! So the network time and state (activity etc.) at the beginning of the second run is the same as at the end of the first run. To prevent this use the reset function of the CompNeuroExp class.

Returns:

Name Type Description
results_obj _ResultsCl

Object with attributes: recordings (list): list of recordings recording_times (recording_times_cl): recording times object mon_dict (dict): dict of recorded variables of the monitors data (dict): dict with optional data stored during the experiment

Source code in src/CompNeuroPy/experiment.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
def results(self):
    """
    !!! warning
        Call this function at the end of the run function of the CompNeuroExp class!

    !!! warning
        Calling this function resets the CompNeuroMonitors. For example, if you
        simulate two recording chunks in the run function and you run the experiment
        twice, you will get two recording chunks for each experiment run (not two
        for the first and four for the second run). But ANNarchy is not resetted
        automatically! So the network time and state (activity etc.) at the
        beginning of the second run is the same as at the end of the first run. To
        prevent this use the reset function of the CompNeuroExp class.

    Returns:
        results_obj (CompNeuroExp._ResultsCl):
            Object with attributes:
                recordings (list):
                    list of recordings
                recording_times (recording_times_cl):
                    recording times object
                mon_dict (dict):
                    dict of recorded variables of the monitors
                data (dict):
                    dict with optional data stored during the experiment
    """
    obj = self._ResultsCl()
    if self.monitors is not None:
        (
            obj.recordings,
            obj.recording_times,
        ) = self.monitors.get_recordings_and_clear()
        obj.mon_dict = self.monitors.mon_dict
    else:
        obj.recordings = []
        obj.recording_times = None
        obj.mon_dict = {}
    ### need deepcopy here because experiment can be run mutliple times and within
    ### experiment the entries of self.data can be changed, and without deepcopy
    ### the data of older results objects would also be changed
    obj.data = deepcopy(self.data)

    return obj

run() #

Warning

This function has to be implemented by the user!

Source code in src/CompNeuroPy/experiment.py
211
212
213
214
215
216
217
218
219
220
221
222
def run(self) -> _ResultsCl:
    """
    !!! warning
        This function has to be implemented by the user!
    """
    raise NotImplementedError(
        """
            You have to implement a run function which runs the simulations and
            controlls the recordings. The run function should return the results of
            the experiment by calling the results function of the CompNeuroExp class.
        """
    )

Full Example#

A full example is available in the Examples.