File: _miscellaneous.py

package info (click to toggle)
python-expyriment 0.7.0%2Bgit34-g55a4e7e-3.2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,504 kB
  • ctags: 2,094
  • sloc: python: 12,766; makefile: 150
file content (298 lines) | stat: -rw-r--r-- 8,913 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
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
250
251
252
253
254
255
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
"""
The control._miscellaneous module of expyriment.

"""

__author__ = 'Florian Krause <florian@expyriment.org>, \
Oliver Lindemann <oliver@expyriment.org>'
__version__ = '0.7.0'
__revision__ = '55a4e7e'
__date__ = 'Wed Mar 26 14:33:37 2014 +0100'

import sys
import pygame

import defaults
import expyriment
from expyriment.control import defaults as control_defaults


def start_audiosystem():
    """Start the audio system.

    NOTE: The audiosystem is automatically started when initializing an
    Experiment!

    """

    pygame.mixer.init()


def stop_audiosystem():
    """Stop the audio system."""

    pygame.mixer.quit()


def get_audiosystem_is_playing(channel=None):
    """Check if the audiosystem is busy playing sounds.

    Parameters
    ----------
    channel : pygame.mixer.Channel, optional
        specific channel to check

    Returns
    -------
    out : bool
        Returns True if any sound is playing.

    """

    if channel is None:
        rtn = pygame.mixer.get_busy()
    else:
        rtn = channel.get_busy()
    if rtn == 0:
        rtn = False
    elif rtn > 0:
        rtn = True
    return rtn


def wait_end_audiosystem(channel=None):
    """Wait until audiosystem has ended playing sounds.

    Blocks until the audiosystem is not busy anymore and only returns then.

    Parameters
    ----------
    channel : pygame.mixer.Channel, optional
        specific channel to wait for end of playing

    """

    while get_audiosystem_is_playing(channel):
            for event in pygame.event.get(pygame.KEYDOWN):
                if event.type == pygame.KEYDOWN and \
                        (event.key == control_defaults.quit_key or
                         event.key == control_defaults.pause_key):
                    if channel is None:
                        pygame.mixer.stop()
                    else:
                        channel.stop()
                    expyriment.io.Keyboard.process_control_keys(event)


def set_develop_mode(onoff, intensive_logging=False):
    """Set defaults for a more convenient develop mode.

    Notes
    -----
    The function set the following global variables

    >>> expyriment.control.defaults.initialize_delay = 0
    >>> expyriment.control.defaults.window_mode = True
    >>> expyriment.control.defaults.fast_quit = True
    >>> expyriment.control.defaults.auto_create_subject_id = True
    >>> expyriment.io.defaults.outputfile_time_stamp = False

    Parameters
    ----------
    onoff : bool
        set develop_mode on (True) or off (False)
    intensive_logging : bool, optional
        True sets expyriment.io.defaults.event_logging=2
        (default = False)

"""

    if onoff:
        defaults._mode_settings = [defaults.initialize_delay,
                                   defaults.window_mode,
                                   defaults.fast_quit,
                                   expyriment.io.defaults.outputfile_time_stamp,
                                   defaults.auto_create_subject_id]

        print "*** DEVELOP MODE ***"
        defaults.initialize_delay = 0
        defaults.window_mode = True
        defaults.fast_quit = True
        expyriment.io.defaults.outputfile_time_stamp = False
        defaults.auto_create_subject_id = True
    else:
        print "*** NORMAL MODE ***"
        if defaults._mode_settings is not None:
            defaults.initialize_delay = defaults._mode_settings[0]
            defaults.window_mode = defaults._mode_settings[1]
            defaults.fast_quit = defaults._mode_settings[2]
            expyriment.io.defaults.outputfile_time_stamp = \
                defaults._mode_settings[3]
            defaults.auto_create_subject_id = defaults._mode_settings[4]
            defaults._mode_settings = None

        else:
            pass  # Nothing to do

    if intensive_logging:
        expyriment.control.defaults.event_logging = 2


def _get_module_values(goal_dict, module):
    value = None
    for var in dir(module):
        if not var.startswith("_"):
            exec("value = {0}.{1}".format(module.__name__, var))
            goal_dict["{0}.{1}".format(module.__name__, var)] = value
    return goal_dict


def get_defaults(search_str="", as_string=False):
    """Return a dictionary with all default values in the current Expyriment
    environment. The keys represent the variables names.

    Parameters
    ----------
    search_str : str, optional
        search for a specific expression
    as_string : bool, optional
        print as string instead of dict

    """

    defaults = {}
    defaults = _get_module_values(defaults, expyriment.design.defaults)
    defaults = _get_module_values(defaults, expyriment.control.defaults)
    defaults = _get_module_values(defaults, expyriment.stimuli.defaults)
    defaults = _get_module_values(defaults, expyriment.io.defaults)
    defaults = _get_module_values(defaults, expyriment.misc.defaults)
    defaults = _get_module_values(defaults, expyriment.design.extras.defaults)
    defaults = _get_module_values(defaults, expyriment.stimuli.extras.defaults)
    defaults = _get_module_values(defaults, expyriment.io.extras.defaults)
    defaults = _get_module_values(defaults, expyriment.misc.extras.defaults)
    if len(search_str) >= 0:
        tmp = {}
        for key in defaults.keys():
            if key.lower().find(search_str.lower()) >= 0:
                tmp[key] = defaults[key]
        defaults = tmp
    if as_string:
        sorted_keys = defaults.keys()
        sorted_keys.sort()
        rtn = ""
        for key in sorted_keys:
            tabs = "\t" * (4 - int((len(key) + 1) / 8))
            rtn += key + ":" + tabs + repr(defaults[key]) + "\n"
    else:
        rtn = defaults

    return rtn


def register_wait_callback_function(function, exp=None):
    """Register a wait callback function.

    The registered wait callback function will be repetitively executed in
    all Expyriment wait and event loops that wait for an external input.
    That is, they are executed by the following functions (at least once!):

        control.wait_end_audiosystem,
        misc.clock.wait,         misc.clock.wait_seconds,
        misc.clock.wait_minutes  io.keyboard.wait,
        io.keyboard.wait_char,   io.buttonbox.wait,
        io.gamepad.wait_press,   io.triggerinput.wait,
        io.mouse.wait_press,     io.serialport.read_line,
        io.textinput.get,        stimulus.video.wait_frame,
        stimulus.video.wait_end

    Parameters
    ----------
    function : function
        the wait function
    exp : design.Experiment, optional
        specific experiment for which to register wait function

    Notes
    -----
    CAUTION! If wait callback function takes longer than 1 ms to process,
    Expyriment timing will be affected!

    """

    if exp is not None:
        exp.register_wait_callback_function(function)
    else:
        expyriment._active_exp.register_wait_callback_function(function)


def unregister_wait_callback_function(exp=None):
    """Unregister wait function.

    Parameters
    ----------
    exp : design.Experiment, optional
        specific experiment for which to unregister wait function

    """

    if exp is not None:
        exp.unregister_wait_callback_function()
    else:
        expyriment._active_exp.unregister_wait_callback_function()


def is_ipython_running():
    """Return True if IPython is running."""

    try:
        __IPYTHON__
        return True
    except NameError:
        return False


def is_idle_running():
    """Return True if IDLE is running."""

    return "idlelib.run" in sys.modules


def _set_stdout_logging(event_file):
    """Set logging of stdout and stderr to event file.

    Note that if the script is called via IPython or IDLE logging will not
    work.

    Parameters
    ----------
    event_file : io.EventFile
        the event file

    """

    class Logger(object):
        def __init__(self, event_file, log_tag):
            self.terminal = sys.stdout
            self.event_file = event_file
            self.tag = log_tag
            self._buffer = []

        def write(self, message):
            self.terminal.write(message)
            self._buffer.append(message)
            if message.endswith("\n"):
                tmp = "".join(self._buffer).strip("\n")
                self.event_file.log("{0},received,{1}".format(self.tag,
                                                              repr(tmp)))
                self._buffer = []

        def flush(self):  # required for some modules (e.g. multiprocessing)
            pass

    if is_ipython_running():
        print "Standard output and error logging is switched off under IPython."
    elif is_idle_running():
        print "Standard output and error logging is switched off under IDLE."
    else:
        sys.stderr = Logger(event_file, "stderr")
        sys.stdout = Logger(event_file, "stdout")