Skip to content

Generate Simulations

Introduction#

A CompNeuroPy-simulation can be created using the CompNeuroSim class. Similar to the CompNeuroModel class, a function must be defined that contains the actual simulation (the simulation_function) and the CompNeuroSim object adds a clear framework. A CompNeuroSim is first initialized and can then be run multiple times.

Example:#

from CompNeuroPy import CompNeuroSim
my_simulation = CompNeuroSim(simulation_function=some_simulation,           ### the most important part, this function defines the simulation
                            simulation_kwargs={'pop':pop1, 'duration':100}, ### define the two arguments pop and duration of simulation_function
                            name='my_simulation',                           ### you can give the simulation a name
                            description='my simple example simulation',     ### you can give the simulation a description
                            requirements=[req],                             ### a list of requirements for the simulation (here only a single requirement)
                            kwargs_warning=True,                            ### should a warning be printed if simulation kwargs change in future runs
                            monitor_object = mon)                           ### the Monitors object which is used to record variables                   

A possible simulation_function could be:

def some_simulation(pop, duration=1):
    get_population(pop).a = 5  ### adjust paramter a of pop
    get_population(pop).b = 5  ### adjust paramter b of pop
    simulate(duration)         ### simulate the duration in ms

    ### return some info
    ### will later be accessible for each run
    return {'paramter a': a, 'paramter b': b, 'a_x_duration': a*duration} 

And a corresponding requirement could be:

from CompNeuroPy import ReqPopHasAttr
req = {'req':ReqPopHasAttr, 'pop':pop1, 'attr':['a', 'b']}
Here, one checks if the population pop1 contains the attributes a and b. The ReqPopHasAttr is a built-in requirements-class of CompNeuroPy (see below).

A more detailed example is available in the Examples.

Simulation information#

The function simulation_info() returns a SimInfo object which contains usefull information about the simulation runs (see below). The SimInfo object also provides usefull analysis functions associated with specific simulation functions. Currently it provides the get_current_arr() which returns arrays containing the input current for each time step of the built-in simulation functions current_step(), current_stim(), and current_ramp().

Simulation functions#

Just define a classic ANNarchy simulation in a function. Within the functions, the ANNarchy functions get_population() and get_projection() can be used to access the populations and projections using the population and projection names provided by a CompNeuroModel. The return value of the simulation function can later be retrieved from the SimInfo object (the info attribute) in a list containing the return value for each run of the simulation.

Example:#

from ANNarchy import simulate, get_population

def current_step(pop, t1=500, t2=500, a1=0, a2=100):
    """
        stimulates a given population in two periods with two input currents

        pop: population name of population, which should be stimulated with input current
             neuron model of population has to contain "I_app" as input current in pA
        t1/t2: times in ms before/after current step
        a1/a2: current amplitudes before/after current step in pA
    """

    ### save prev input current
    I_prev = get_population(pop).I_app

    ### first/pre current step simulation
    get_population(pop).I_app = a1
    simulate(t1)

    ### second/post current step simulation
    get_population(pop).I_app = a2
    simulate(t2)

    ### reset input current to previous value
    get_population(pop).I_app = I_prev

    ### return some additional information which could be usefull
    return {'duration':t1+t2}

Requirements#

In order to perform simulations with models, the models must almost always fulfill certain requirements. For example, if the input current of a population is to be set, this population (or the neuron model) must of course have the corresponding variable. Such preconditions can be tested in advance with the simulation_requirements classes. They only need to contain a function run() to test the requirements (if requirements are not met, cause an error). In CompNeuroPy predefined simulation_requirements classes are available (CompNeuroPy.simulation_requirements; currently only ReqPopHasAttr). In the CompNeuroSim class, the requirements are passed as arguments in a list (see above). Each requirement (list entry) must be defined as a dictionary with keys req (the requirement class) and the arguments of the requirement class (e.g., pop and attr for the ReqPopHasAttr).

Here two requirements are defined (both ReqPopHasAttr). All populations of my_model should contain the attribute (variable or parameter) 'I' and all populations of my_other_model should contain the attribute 'v':

req1 = {'req':ReqPopHasAttr, 'pop':my_model.populations, 'attr':'I'}
req2 = {'req':ReqPopHasAttr, 'pop':my_other_model.populations, 'attr':'v'}
my_two_model_simulation = CompNeuroSim(..., requirements=[req1, req2])

As described above, new simulation_kwargs can be passed to the run() function of a CompNeuroSim object. Thus, one could initially pass a particular model as simulation_kwargs and for a later run pass a different model. If the requirements are defined as shown above, it is not tested again whether the new model (e.g. my_third_model) also fulfills the requirements (because the requirements were defined for my_model and my_other_model). To work around this, an argument for a simulation_requirements class can also be linked to a simulation_kwargs entry. Thus, if new simulation_kwargs are used, also the simulation_requirements arguments adapt. This can be done using a string with the syntax "simulation_kwargs.<kwarg_name>.<optional_attribute_of_kwarg>", as shown in this example:

req1 = {'req':ReqPopHasAttr, 'pop':"simulation_kwargs.model1.populations", 'attr':'I'}
req2 = {'req':ReqPopHasAttr, 'pop':"simulation_kwargs.model2.populations", 'attr':'v'}
my_two_model_simulation = CompNeuroSim(simulation_kwargs={'model1':my_model, 'model2':my_other_model, 'parameter':5},
                                        ...,
                                        requirements=[req1, req2])
...
my_two_model_simulation.run({'model1':my_third_model})

Due to the string "simulation_kwargs.model1.populations" the pop argument of req1 is now linked to model1 (defined in the simulation_kwargs). Thus, in the run where a different model (my_third_model) is used for model1, req1 is automatically tested for the new model1.

CompNeuroPy.generate_simulation.CompNeuroSim #

Class for generating a CompNeuroPy simulation.

Source code in src/CompNeuroPy/generate_simulation.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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
class CompNeuroSim:
    """
    Class for generating a CompNeuroPy simulation.
    """

    _initialized_simulations = []

    def __init__(
        self,
        simulation_function: Callable,
        simulation_kwargs: dict | None = None,
        name: str = "simulation",
        description: str = "",
        requirements: list | None = None,
        kwargs_warning: bool = False,
        monitor_object: CompNeuroMonitors | None = None,
    ):
        """
        Args:
            simulation_function (function):
                Function which runs the simulation.
            simulation_kwargs (dict, optional):
                Dictionary of arguments for the simulation_function. Default: None.
            name (str, optional):
                Name of the simulation. Default: "simulation".
            description (str, optional):
                Description of the simulation. Default: "".
            requirements (list, optional):
                List of requirements for the simulation. It's a list of dictionaries
                which contain the requirement class itself (key: "req") and the
                corresponding arguments (keys are the names of the arguments). The
                arguments can be inherited from the simulation kwargs by using the
                syntax 'simulation_kwargs.<kwarg_name>'. Default: None.
            kwargs_warning (bool, optional):
                If True, a warning is printed if the simulation_kwargs are changed
                during the simulation. Default: False.
            monitor_object (CompNeuroMonitors object, optional):
                CompNeuroMonitors object to automatically track the recording chunk for each
                simulation run. Default: None.
        """
        # set simulation function
        self.name = name
        if name == "simulation":
            self.name = name + str(self._nr_simulations())
        self._initialized_simulations.append(self.name)
        self.description = description
        self.simulation_function = simulation_function
        self.simulation_kwargs = simulation_kwargs
        if requirements is None:
            self.requirements = []
        else:
            self.requirements = requirements
        self.start = []
        self.end = []
        self.info = []
        self.kwargs = []
        if kwargs_warning:
            self._warned = False
        else:
            self._warned = True
        self.monitor_object = monitor_object
        if monitor_object is not None:
            self.monitor_chunk = []
        else:
            self.monitor_chunk = None

        ### test initial requirements
        self._test_req(simulation_kwargs=simulation_kwargs)

    def run(self, simulation_kwargs: dict | None = None):
        """
        Runs the simulation function. With each run extend start, end list containing
        start and end time of the corresponding run and the info list containing the
        return value of the simulation function.

        Args:
            simulation_kwargs (dict, optional):
                Temporary simulation kwargs which override the initialized simulation
                kwargs. Default: None, i.e., use values from initialization.
        """

        ### define the current simulation kwargs
        if simulation_kwargs is not None:
            if self.simulation_kwargs is not None:
                ### not replace initialized kwargs completely but only the kwargs which are given
                tmp_kwargs = self.simulation_kwargs.copy()
                for key, val in simulation_kwargs.items():
                    tmp_kwargs[key] = val
            else:
                ### there are no initial kwargs --> only use the kwargs which are given
                tmp_kwargs = simulation_kwargs
            if not (self._warned) and len(self.requirements) > 0:
                print(
                    "\nWARNING! run",
                    self.name,
                    "changed simulation kwargs, initial requirements may no longer be fulfilled!\n",
                )
                self._warned = True
        else:
            tmp_kwargs = self.simulation_kwargs

        ### before each run, test requirements
        self._test_req(simulation_kwargs=tmp_kwargs)

        ### and append current simulation kwargs to the kwargs variable
        self.kwargs.append(tmp_kwargs)

        ### and append the current chunk of the monitors object to the chunk variable
        if self.monitor_object is not None:
            self.monitor_chunk.append(self.monitor_object.current_chunk())

        ### run the simulation, store start and end simulation time
        self.start.append(get_time())
        if tmp_kwargs is not None:
            self.info.append(self.simulation_function(**tmp_kwargs))
        else:
            self.info.append(self.simulation_function())
        self.end.append(get_time())

    def _nr_simulations(self):
        """
        Returns the current number of initialized CompNeuroPy simulations.
        """
        return len(self._initialized_simulations)

    def _test_req(self, simulation_kwargs=None):
        """
        Tests the initialized requirements with the current simulation_kwargs.
        """

        if simulation_kwargs is None:  # --> use the initial simulation_kwargs
            simulation_kwargs = self.simulation_kwargs

        for req in self.requirements:
            ### check if requirement_kwargs are given besides the requirement itself
            if len(list(req.keys())) > 1:
                ### remove the requirement itself from the kwargs
                req_kwargs = ef.remove_key(req, "req")
                ### check if req_kwargs reference to simulation_kwargs, if yes, use the
                ### current simulation kwargs instead of the intial ones
                for key, val in req_kwargs.items():
                    if isinstance(val, str):
                        val_split = val.split(".")
                        ### check if val is a reference to simulation_kwargs
                        if val_split[0] == "simulation_kwargs":
                            if len(val_split) == 1:
                                ### val is only simulation_kwargs
                                req_kwargs = simulation_kwargs
                            elif len(val_split) == 2:
                                ### val is simulation_kwargs.something
                                req_kwargs[key] = simulation_kwargs[val_split[1]]
                            else:
                                ### val is simulation_kwargs.something.something... e.g. key='pops' and val= 'simulation_kwargs.model.populations'
                                req_kwargs[key] = eval(
                                    'simulation_kwargs["'
                                    + val_split[1]
                                    + '"].'
                                    + ".".join(val_split[2:])
                                )
                ### run the requirement using the current req_kwargs
                req["req"](**req_kwargs).run()

            else:
                ### a requirement is given without kwargs --> just run it
                req["req"]().run()

    def get_current_arr(self, dt, flat=False):
        """
        Method exclusively for current_step simulation functions. Gets the current array
        (input current value for each time step) of all runs.

        !!! warning
            This method will be removed soon. Use the get_current_arr method of the
            SimInfo class instead.

        Args:
            dt (float):
                Time step size of the simulation.
            flat (bool, optional):
                If True, returns a flattened array. Assumes that all runs are run
                consecutively without brakes. Default: False, i.e., returns a list of
                arrays.

        Returns:
            current_arr (list of arrays):
                List of arrays containing the current values for each time step of each
                run. If flat=True, returns a flattened array.
        """
        assert (
            self.simulation_function.__name__ == "current_step"
        ), 'ERROR get_current_arr: Simulation has to be "current_step"!'
        ### TODO: remove because deprecated
        print(
            "WARNING get_current_arr function will only be available in SimInfo soon."
        )
        current_arr = []
        for run in range(len(self.kwargs)):
            t1 = self.kwargs[run]["t1"]
            t2 = self.kwargs[run]["t2"]
            a1 = self.kwargs[run]["a1"]
            a2 = self.kwargs[run]["a2"]

            if t1 > 0 and t2 > 0:
                current_arr.append(
                    np.concatenate(
                        [
                            np.ones(int(round(t1 / dt))) * a1,
                            np.ones(int(round(t2 / dt))) * a2,
                        ]
                    )
                )
            elif t2 > 0:
                current_arr.append(np.ones(int(round(t2 / dt))) * a2)
            else:
                current_arr.append(np.ones(int(round(t1 / dt))) * a1)

        if flat:
            return np.concatenate(current_arr)
        else:
            return current_arr

    def simulation_info(self):
        """
        Returns a SimInfo object containing the simulation information.

        Returns:
            simulation_info_obj (SimInfo):
                Simulation information object.
        """

        simulation_info_obj = SimInfo(
            self.name,
            self.description,
            self.simulation_function.__name__,
            self.start,
            self.end,
            self.info,
            self.kwargs,
            self.monitor_chunk,
        )

        return simulation_info_obj

__init__(simulation_function, simulation_kwargs=None, name='simulation', description='', requirements=None, kwargs_warning=False, monitor_object=None) #

Parameters:

Name Type Description Default
simulation_function function

Function which runs the simulation.

required
simulation_kwargs dict

Dictionary of arguments for the simulation_function. Default: None.

None
name str

Name of the simulation. Default: "simulation".

'simulation'
description str

Description of the simulation. Default: "".

''
requirements list

List of requirements for the simulation. It's a list of dictionaries which contain the requirement class itself (key: "req") and the corresponding arguments (keys are the names of the arguments). The arguments can be inherited from the simulation kwargs by using the syntax 'simulation_kwargs.'. Default: None.

None
kwargs_warning bool

If True, a warning is printed if the simulation_kwargs are changed during the simulation. Default: False.

False
monitor_object CompNeuroMonitors object

CompNeuroMonitors object to automatically track the recording chunk for each simulation run. Default: None.

None
Source code in src/CompNeuroPy/generate_simulation.py
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
def __init__(
    self,
    simulation_function: Callable,
    simulation_kwargs: dict | None = None,
    name: str = "simulation",
    description: str = "",
    requirements: list | None = None,
    kwargs_warning: bool = False,
    monitor_object: CompNeuroMonitors | None = None,
):
    """
    Args:
        simulation_function (function):
            Function which runs the simulation.
        simulation_kwargs (dict, optional):
            Dictionary of arguments for the simulation_function. Default: None.
        name (str, optional):
            Name of the simulation. Default: "simulation".
        description (str, optional):
            Description of the simulation. Default: "".
        requirements (list, optional):
            List of requirements for the simulation. It's a list of dictionaries
            which contain the requirement class itself (key: "req") and the
            corresponding arguments (keys are the names of the arguments). The
            arguments can be inherited from the simulation kwargs by using the
            syntax 'simulation_kwargs.<kwarg_name>'. Default: None.
        kwargs_warning (bool, optional):
            If True, a warning is printed if the simulation_kwargs are changed
            during the simulation. Default: False.
        monitor_object (CompNeuroMonitors object, optional):
            CompNeuroMonitors object to automatically track the recording chunk for each
            simulation run. Default: None.
    """
    # set simulation function
    self.name = name
    if name == "simulation":
        self.name = name + str(self._nr_simulations())
    self._initialized_simulations.append(self.name)
    self.description = description
    self.simulation_function = simulation_function
    self.simulation_kwargs = simulation_kwargs
    if requirements is None:
        self.requirements = []
    else:
        self.requirements = requirements
    self.start = []
    self.end = []
    self.info = []
    self.kwargs = []
    if kwargs_warning:
        self._warned = False
    else:
        self._warned = True
    self.monitor_object = monitor_object
    if monitor_object is not None:
        self.monitor_chunk = []
    else:
        self.monitor_chunk = None

    ### test initial requirements
    self._test_req(simulation_kwargs=simulation_kwargs)

run(simulation_kwargs=None) #

Runs the simulation function. With each run extend start, end list containing start and end time of the corresponding run and the info list containing the return value of the simulation function.

Parameters:

Name Type Description Default
simulation_kwargs dict

Temporary simulation kwargs which override the initialized simulation kwargs. Default: None, i.e., use values from initialization.

None
Source code in src/CompNeuroPy/generate_simulation.py
 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
def run(self, simulation_kwargs: dict | None = None):
    """
    Runs the simulation function. With each run extend start, end list containing
    start and end time of the corresponding run and the info list containing the
    return value of the simulation function.

    Args:
        simulation_kwargs (dict, optional):
            Temporary simulation kwargs which override the initialized simulation
            kwargs. Default: None, i.e., use values from initialization.
    """

    ### define the current simulation kwargs
    if simulation_kwargs is not None:
        if self.simulation_kwargs is not None:
            ### not replace initialized kwargs completely but only the kwargs which are given
            tmp_kwargs = self.simulation_kwargs.copy()
            for key, val in simulation_kwargs.items():
                tmp_kwargs[key] = val
        else:
            ### there are no initial kwargs --> only use the kwargs which are given
            tmp_kwargs = simulation_kwargs
        if not (self._warned) and len(self.requirements) > 0:
            print(
                "\nWARNING! run",
                self.name,
                "changed simulation kwargs, initial requirements may no longer be fulfilled!\n",
            )
            self._warned = True
    else:
        tmp_kwargs = self.simulation_kwargs

    ### before each run, test requirements
    self._test_req(simulation_kwargs=tmp_kwargs)

    ### and append current simulation kwargs to the kwargs variable
    self.kwargs.append(tmp_kwargs)

    ### and append the current chunk of the monitors object to the chunk variable
    if self.monitor_object is not None:
        self.monitor_chunk.append(self.monitor_object.current_chunk())

    ### run the simulation, store start and end simulation time
    self.start.append(get_time())
    if tmp_kwargs is not None:
        self.info.append(self.simulation_function(**tmp_kwargs))
    else:
        self.info.append(self.simulation_function())
    self.end.append(get_time())

get_current_arr(dt, flat=False) #

Method exclusively for current_step simulation functions. Gets the current array (input current value for each time step) of all runs.

Warning

This method will be removed soon. Use the get_current_arr method of the SimInfo class instead.

Parameters:

Name Type Description Default
dt float

Time step size of the simulation.

required
flat bool

If True, returns a flattened array. Assumes that all runs are run consecutively without brakes. Default: False, i.e., returns a list of arrays.

False

Returns:

Name Type Description
current_arr list of arrays

List of arrays containing the current values for each time step of each run. If flat=True, returns a flattened array.

Source code in src/CompNeuroPy/generate_simulation.py
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
223
224
225
226
227
def get_current_arr(self, dt, flat=False):
    """
    Method exclusively for current_step simulation functions. Gets the current array
    (input current value for each time step) of all runs.

    !!! warning
        This method will be removed soon. Use the get_current_arr method of the
        SimInfo class instead.

    Args:
        dt (float):
            Time step size of the simulation.
        flat (bool, optional):
            If True, returns a flattened array. Assumes that all runs are run
            consecutively without brakes. Default: False, i.e., returns a list of
            arrays.

    Returns:
        current_arr (list of arrays):
            List of arrays containing the current values for each time step of each
            run. If flat=True, returns a flattened array.
    """
    assert (
        self.simulation_function.__name__ == "current_step"
    ), 'ERROR get_current_arr: Simulation has to be "current_step"!'
    ### TODO: remove because deprecated
    print(
        "WARNING get_current_arr function will only be available in SimInfo soon."
    )
    current_arr = []
    for run in range(len(self.kwargs)):
        t1 = self.kwargs[run]["t1"]
        t2 = self.kwargs[run]["t2"]
        a1 = self.kwargs[run]["a1"]
        a2 = self.kwargs[run]["a2"]

        if t1 > 0 and t2 > 0:
            current_arr.append(
                np.concatenate(
                    [
                        np.ones(int(round(t1 / dt))) * a1,
                        np.ones(int(round(t2 / dt))) * a2,
                    ]
                )
            )
        elif t2 > 0:
            current_arr.append(np.ones(int(round(t2 / dt))) * a2)
        else:
            current_arr.append(np.ones(int(round(t1 / dt))) * a1)

    if flat:
        return np.concatenate(current_arr)
    else:
        return current_arr

simulation_info() #

Returns a SimInfo object containing the simulation information.

Returns:

Name Type Description
simulation_info_obj SimInfo

Simulation information object.

Source code in src/CompNeuroPy/generate_simulation.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
def simulation_info(self):
    """
    Returns a SimInfo object containing the simulation information.

    Returns:
        simulation_info_obj (SimInfo):
            Simulation information object.
    """

    simulation_info_obj = SimInfo(
        self.name,
        self.description,
        self.simulation_function.__name__,
        self.start,
        self.end,
        self.info,
        self.kwargs,
        self.monitor_chunk,
    )

    return simulation_info_obj

CompNeuroPy.generate_simulation.SimInfo #

Class for storing the simulation information.

Attributes:

Name Type Description
name str

Name of the simulation.

description str

Description of the simulation.

simulation_function str

Name of the simulation function.

start list

List of start times of the simulation runs.

end list

List of end times of the simulation runs.

info list

List of return values of the simulation function of each simulation run.

kwargs list

List of simulation kwargs of the simulation function of each simulation run.

monitor_chunk list

List of recording chunks of the used CompNeuroMonitors object of each simulation run.

Source code in src/CompNeuroPy/generate_simulation.py
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
class SimInfo:
    """
    Class for storing the simulation information.

    Attributes:
        name (str):
            Name of the simulation.
        description (str):
            Description of the simulation.
        simulation_function (str):
            Name of the simulation function.
        start (list):
            List of start times of the simulation runs.
        end (list):
            List of end times of the simulation runs.
        info (list):
            List of return values of the simulation function of each simulation run.
        kwargs (list):
            List of simulation kwargs of the simulation function of each simulation run.
        monitor_chunk (list):
            List of recording chunks of the used CompNeuroMonitors object of each simulation run.
    """

    def __init__(
        self,
        name,
        description,
        simulation_function,
        start,
        end,
        info,
        kwargs,
        monitor_chunk,
    ):
        """
        Initialization of the simulation information object.

        Args:
            name (str):
                Name of the simulation.
            description (str):
                Description of the simulation.
            simulation_function (str):
                Name of the simulation function.
            start (list):
                List of start times of the simulation runs.
            end (list):
                List of end times of the simulation runs.
            info (list):
                List of return values of the simulation function of each simulation run.
            kwargs (list):
                List of simulation kwargs of the simulation function of each simulation
                run.
            monitor_chunk (list):
                List of recording chunks of the used CompNeuroMonitors object of each simulation
                run.
        """
        self.name = name
        self.description = description
        self.simulation_function = simulation_function
        self.start = start
        self.end = end
        self.info = info
        self.kwargs = kwargs
        self.monitor_chunk = monitor_chunk

    def get_current_arr(self, dt, flat=False):
        """
        Method exclusively for the following simulation functions (built-in
        CompNeuroPy):
            - current_step
            - current_stim
            - current_ramp
        Gets the current array (input current value for each time step) of all runs.

        Args:
            dt (float):
                Time step size of the simulation.
            flat (bool, optional):
                If True, returns a flattened array. Assumes that all runs are run
                consecutively without brakes. Default: False, i.e., returns a list of
                arrays.

        Returns:
            current_arr (list of arrays):
                List of arrays containing the current values for each time step of each
                run. If flat=True, returns a flattened array.
        """
        assert (
            self.simulation_function == "current_step"
            or self.simulation_function == "current_stim"
            or self.simulation_function == "current_ramp"
        ), 'ERROR get_current_arr: Simulation has to be "current_step", "current_stim" or "current_ramp"!'

        if self.simulation_function == "current_step":
            current_arr = []
            for run in range(len(self.kwargs)):
                t1 = self.kwargs[run]["t1"]
                t2 = self.kwargs[run]["t2"]
                a1 = self.kwargs[run]["a1"]
                a2 = self.kwargs[run]["a2"]

                if t1 > 0 and t2 > 0:
                    current_arr.append(
                        np.concatenate(
                            [
                                np.ones(int(round(t1 / dt))) * a1,
                                np.ones(int(round(t2 / dt))) * a2,
                            ]
                        )
                    )
                elif t2 > 0:
                    current_arr.append(np.ones(int(round(t2 / dt))) * a2)
                else:
                    current_arr.append(np.ones(int(round(t1 / dt))) * a1)

            if flat:
                return np.concatenate(current_arr)
            else:
                return current_arr

        elif self.simulation_function == "current_stim":
            current_arr = []
            for run in range(len(self.kwargs)):
                t = self.kwargs[run]["t"]
                a = self.kwargs[run]["a"]

                if t > 0:
                    current_arr.append(np.ones(int(round(t / dt))) * a)

            if flat:
                return np.concatenate(current_arr)
            else:
                return current_arr

        elif self.simulation_function == "current_ramp":
            current_arr = []
            for run in range(len(self.kwargs)):
                amp = self.kwargs[run]["a0"]
                current_arr_ramp = []
                for stim_idx in range(self.kwargs[run]["n"]):
                    t = self.info[run]["dur_stim"]
                    a = amp
                    current_arr_ramp.append(np.ones(int(round(t / dt))) * a)
                    amp = amp + self.info[run]["da"]
                current_arr.append(list(np.concatenate(current_arr_ramp)))

            if flat:
                return np.concatenate(current_arr)
            else:
                return current_arr

__init__(name, description, simulation_function, start, end, info, kwargs, monitor_chunk) #

Initialization of the simulation information object.

Parameters:

Name Type Description Default
name str

Name of the simulation.

required
description str

Description of the simulation.

required
simulation_function str

Name of the simulation function.

required
start list

List of start times of the simulation runs.

required
end list

List of end times of the simulation runs.

required
info list

List of return values of the simulation function of each simulation run.

required
kwargs list

List of simulation kwargs of the simulation function of each simulation run.

required
monitor_chunk list

List of recording chunks of the used CompNeuroMonitors object of each simulation run.

required
Source code in src/CompNeuroPy/generate_simulation.py
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
def __init__(
    self,
    name,
    description,
    simulation_function,
    start,
    end,
    info,
    kwargs,
    monitor_chunk,
):
    """
    Initialization of the simulation information object.

    Args:
        name (str):
            Name of the simulation.
        description (str):
            Description of the simulation.
        simulation_function (str):
            Name of the simulation function.
        start (list):
            List of start times of the simulation runs.
        end (list):
            List of end times of the simulation runs.
        info (list):
            List of return values of the simulation function of each simulation run.
        kwargs (list):
            List of simulation kwargs of the simulation function of each simulation
            run.
        monitor_chunk (list):
            List of recording chunks of the used CompNeuroMonitors object of each simulation
            run.
    """
    self.name = name
    self.description = description
    self.simulation_function = simulation_function
    self.start = start
    self.end = end
    self.info = info
    self.kwargs = kwargs
    self.monitor_chunk = monitor_chunk

get_current_arr(dt, flat=False) #

Method exclusively for the following simulation functions (built-in CompNeuroPy): - current_step - current_stim - current_ramp Gets the current array (input current value for each time step) of all runs.

Parameters:

Name Type Description Default
dt float

Time step size of the simulation.

required
flat bool

If True, returns a flattened array. Assumes that all runs are run consecutively without brakes. Default: False, i.e., returns a list of arrays.

False

Returns:

Name Type Description
current_arr list of arrays

List of arrays containing the current values for each time step of each run. If flat=True, returns a flattened array.

Source code in src/CompNeuroPy/generate_simulation.py
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
def get_current_arr(self, dt, flat=False):
    """
    Method exclusively for the following simulation functions (built-in
    CompNeuroPy):
        - current_step
        - current_stim
        - current_ramp
    Gets the current array (input current value for each time step) of all runs.

    Args:
        dt (float):
            Time step size of the simulation.
        flat (bool, optional):
            If True, returns a flattened array. Assumes that all runs are run
            consecutively without brakes. Default: False, i.e., returns a list of
            arrays.

    Returns:
        current_arr (list of arrays):
            List of arrays containing the current values for each time step of each
            run. If flat=True, returns a flattened array.
    """
    assert (
        self.simulation_function == "current_step"
        or self.simulation_function == "current_stim"
        or self.simulation_function == "current_ramp"
    ), 'ERROR get_current_arr: Simulation has to be "current_step", "current_stim" or "current_ramp"!'

    if self.simulation_function == "current_step":
        current_arr = []
        for run in range(len(self.kwargs)):
            t1 = self.kwargs[run]["t1"]
            t2 = self.kwargs[run]["t2"]
            a1 = self.kwargs[run]["a1"]
            a2 = self.kwargs[run]["a2"]

            if t1 > 0 and t2 > 0:
                current_arr.append(
                    np.concatenate(
                        [
                            np.ones(int(round(t1 / dt))) * a1,
                            np.ones(int(round(t2 / dt))) * a2,
                        ]
                    )
                )
            elif t2 > 0:
                current_arr.append(np.ones(int(round(t2 / dt))) * a2)
            else:
                current_arr.append(np.ones(int(round(t1 / dt))) * a1)

        if flat:
            return np.concatenate(current_arr)
        else:
            return current_arr

    elif self.simulation_function == "current_stim":
        current_arr = []
        for run in range(len(self.kwargs)):
            t = self.kwargs[run]["t"]
            a = self.kwargs[run]["a"]

            if t > 0:
                current_arr.append(np.ones(int(round(t / dt))) * a)

        if flat:
            return np.concatenate(current_arr)
        else:
            return current_arr

    elif self.simulation_function == "current_ramp":
        current_arr = []
        for run in range(len(self.kwargs)):
            amp = self.kwargs[run]["a0"]
            current_arr_ramp = []
            for stim_idx in range(self.kwargs[run]["n"]):
                t = self.info[run]["dur_stim"]
                a = amp
                current_arr_ramp.append(np.ones(int(round(t / dt))) * a)
                amp = amp + self.info[run]["da"]
            current_arr.append(list(np.concatenate(current_arr_ramp)))

        if flat:
            return np.concatenate(current_arr)
        else:
            return current_arr