psychopy 2024.1.4__py3-none-any.whl → 2024.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of psychopy might be problematic. Click here for more details.
- psychopy/.DS_Store +0 -0
- psychopy/CHANGELOG.txt +206 -0
- psychopy/GIT_SHA +1 -0
- psychopy/VERSION +1 -0
- psychopy/__init__.py +77 -15
- psychopy/app/Resources/classic/plugin16.png +0 -0
- psychopy/app/Resources/classic/plugin16@2x.png +0 -0
- psychopy/app/Resources/dark/plugin16.png +0 -0
- psychopy/app/Resources/dark/plugin16@2x.png +0 -0
- psychopy/app/Resources/light/plugin16.png +0 -0
- psychopy/app/Resources/light/plugin16@2x.png +0 -0
- psychopy/app/__init__.py +76 -2
- psychopy/app/_psychopyApp.py +126 -101
- psychopy/app/builder/builder.py +14 -10
- psychopy/app/builder/dialogs/__init__.py +8 -8
- psychopy/app/builder/dialogs/dlgsConditions.py +12 -13
- psychopy/app/builder/dialogs/paramCtrls.py +24 -57
- psychopy/app/builder/validators.py +2 -2
- psychopy/app/coder/codeEditorBase.py +8 -8
- psychopy/app/coder/coder.py +4 -4
- psychopy/app/connections/sendusage.py +2 -2
- psychopy/app/connections/updates.py +9 -9
- psychopy/app/dialogs.py +34 -2
- psychopy/app/idle.py +31 -0
- psychopy/app/jobs.py +21 -3
- psychopy/app/linuxconfig/__init__.py +9 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4602 -2540
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +53 -43
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1011 -942
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +9415 -5
- psychopy/app/pavlovia_ui/_base.py +33 -3
- psychopy/app/pavlovia_ui/search.py +0 -1
- psychopy/app/plugin_manager/dialog.py +104 -51
- psychopy/app/plugin_manager/packages.py +5 -0
- psychopy/app/plugin_manager/plugins.py +145 -67
- psychopy/app/preferencesDlg.py +8 -8
- psychopy/app/psychopyApp.py +11 -5
- psychopy/app/ribbon.py +124 -14
- psychopy/app/runner/runner.py +6 -1
- psychopy/app/stdout/stdOutRich.py +27 -11
- psychopy/app/themes/icons.py +52 -2
- psychopy/assets/__init__.py +0 -0
- psychopy/assets/click.png +0 -0
- psychopy/assets/clicknext.png +0 -0
- psychopy/assets/next.png +0 -0
- psychopy/assets/psychopy.ico +0 -0
- psychopy/assets/psychopy.png +0 -0
- psychopy/assets/templates/__init__.py +0 -0
- psychopy/assets/touch.png +0 -0
- psychopy/assets/touchnext.png +0 -0
- psychopy/assets/window.ico +0 -0
- psychopy/changes/2023.1.0.md +9 -0
- psychopy/changes/2024.1.0.md +16 -0
- psychopy/changes/__init__.py +0 -0
- psychopy/clock.py +2 -2
- psychopy/colors.py +2 -1
- psychopy/compatibility.py +53 -1
- psychopy/contrib/.DS_Store +0 -0
- psychopy/contrib/configobj/__init__.py +10 -8
- psychopy/data/__init__.py +3 -2
- psychopy/data/base.py +5 -5
- psychopy/data/experiment.py +130 -4
- psychopy/data/routine.py +56 -0
- psychopy/data/staircase.py +2 -2
- psychopy/data/trial.py +559 -97
- psychopy/data/utils.py +56 -21
- psychopy/demos/.DS_Store +0 -0
- psychopy/demos/builder/.DS_Store +0 -0
- psychopy/demos/builder/Design Templates/.DS_Store +0 -0
- psychopy/demos/builder/Experiments/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +375 -0
- psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +433 -0
- psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
- psychopy/demos/builder/Hardware/.DS_Store +0 -0
- psychopy/demos/builder/Helper Tools/.DS_Store +0 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/hardware/testSoundLatency.py +2 -2
- psychopy/demos/coder/iohub/.DS_Store +0 -0
- psychopy/demos/coder/misc/hdf5_2_csv +33 -0
- psychopy/event.py +30 -29
- psychopy/experiment/.DS_Store +0 -0
- psychopy/experiment/_experiment.py +6 -6
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/__init__.py +6 -3
- psychopy/experiment/components/_base.py +286 -131
- psychopy/experiment/components/aperture/.DS_Store +0 -0
- psychopy/experiment/components/brush/.DS_Store +0 -0
- psychopy/experiment/components/button/.DS_Store +0 -0
- psychopy/experiment/components/button/__init__.py +5 -1
- psychopy/experiment/components/buttonBox/.DS_Store +0 -0
- psychopy/experiment/components/camera/.DS_Store +0 -0
- psychopy/experiment/components/code/.DS_Store +0 -0
- psychopy/experiment/components/dots/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/__init__.py +92 -30
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/form/__init__.py +6 -2
- psychopy/experiment/components/grating/.DS_Store +0 -0
- psychopy/experiment/components/grating/__init__.py +14 -3
- psychopy/experiment/components/image/.DS_Store +0 -0
- psychopy/experiment/components/image/__init__.py +14 -3
- psychopy/experiment/components/joyButtons/.DS_Store +0 -0
- psychopy/experiment/components/joystick/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/__init__.py +22 -10
- psychopy/experiment/components/microphone/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py +59 -39
- psychopy/experiment/components/mouse/.DS_Store +0 -0
- psychopy/experiment/components/mouse/__init__.py +44 -29
- psychopy/experiment/components/movie/.DS_Store +0 -0
- psychopy/experiment/components/movie/__init__.py +1 -1
- psychopy/experiment/components/panorama/.DS_Store +0 -0
- psychopy/experiment/components/parallelOut/.DS_Store +0 -0
- psychopy/experiment/components/patch/.DS_Store +0 -0
- psychopy/experiment/components/polygon/.DS_Store +0 -0
- psychopy/experiment/components/polygon/__init__.py +26 -6
- psychopy/experiment/components/progress/.DS_Store +0 -0
- psychopy/experiment/components/ratingScale/.DS_Store +0 -0
- psychopy/experiment/components/resourceManager/.DS_Store +0 -0
- psychopy/experiment/components/roi/.DS_Store +0 -0
- psychopy/experiment/components/roi/__init__.py +5 -0
- psychopy/experiment/components/routineSettings/.DS_Store +0 -0
- psychopy/experiment/components/routineSettings/__init__.py +57 -10
- psychopy/experiment/components/serialOut/.DS_Store +0 -0
- psychopy/experiment/components/settings/.DS_Store +0 -0
- psychopy/experiment/components/settings/__init__.py +117 -42
- psychopy/experiment/components/slider/.DS_Store +0 -0
- psychopy/experiment/components/sound/.DS_Store +0 -0
- psychopy/experiment/components/sound/__init__.py +54 -19
- psychopy/experiment/components/static/.DS_Store +0 -0
- psychopy/experiment/components/static/__init__.py +1 -1
- psychopy/experiment/components/text/.DS_Store +0 -0
- psychopy/experiment/components/text/__init__.py +28 -3
- psychopy/experiment/components/textbox/.DS_Store +0 -0
- psychopy/experiment/components/textbox/__init__.py +12 -2
- psychopy/experiment/components/unknown/.DS_Store +0 -0
- psychopy/experiment/components/unknown/__init__.py +1 -2
- psychopy/experiment/components/unknownPlugin/.DS_Store +0 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +2 -2
- psychopy/experiment/components/variable/.DS_Store +0 -0
- psychopy/experiment/flow.py +11 -4
- psychopy/experiment/loops.py +85 -37
- psychopy/experiment/params.py +74 -32
- psychopy/experiment/py2js_transpiler.py +8 -1
- psychopy/experiment/routines/.DS_Store +0 -0
- psychopy/experiment/routines/_base.py +102 -22
- psychopy/experiment/routines/counterbalance/.DS_Store +0 -0
- psychopy/experiment/routines/counterbalance/__init__.py +5 -1
- psychopy/experiment/routines/eyetracker_calibrate/.DS_Store +0 -0
- psychopy/experiment/routines/eyetracker_validate/.DS_Store +0 -0
- psychopy/experiment/routines/pavlovia_survey/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/__init__.py +6 -5
- psychopy/experiment/routines/unknown/.DS_Store +0 -0
- psychopy/gui/wxgui.py +4 -4
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/__init__.py +1 -1
- psychopy/hardware/base.py +12 -0
- psychopy/hardware/camera/__init__.py +1 -15
- psychopy/hardware/cedrus.py +10 -11
- psychopy/hardware/crs/colorcal.py +13 -22
- psychopy/hardware/crs/optical.py +10 -20
- psychopy/hardware/emulator.py +17 -14
- psychopy/hardware/eyetracker.py +42 -118
- psychopy/hardware/gammasci.py +4 -15
- psychopy/hardware/keyboard.py +102 -10
- psychopy/hardware/listener.py +3 -0
- psychopy/hardware/microphone.py +148 -18
- psychopy/hardware/minolta.py +8 -15
- psychopy/hardware/photodiode.py +191 -16
- psychopy/hardware/photometer/__init__.py +11 -19
- psychopy/hardware/pr.py +8 -15
- psychopy/hardware/speaker.py +39 -4
- psychopy/info.py +0 -71
- psychopy/iohub/.DS_Store +0 -0
- psychopy/iohub/__init__.py +1 -1
- psychopy/iohub/client/__init__.py +30 -20
- psychopy/iohub/client/keyboard.py +24 -24
- psychopy/iohub/datastore/__init__.py +2 -2
- psychopy/iohub/datastore/util.py +2 -2
- psychopy/iohub/default_config.yaml +1 -1
- psychopy/iohub/devices/.DS_Store +0 -0
- psychopy/iohub/devices/__init__.py +112 -25
- psychopy/iohub/devices/deviceConfigValidation.py +2 -1
- psychopy/iohub/devices/experiment/default_experiment.yaml +12 -1
- psychopy/iohub/devices/experiment/supported_config_settings.yaml +5 -1
- psychopy/iohub/devices/eyetracker/.DS_Store +0 -0
- psychopy/iohub/devices/eyetracker/__init__.py +46 -0
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +2 -2
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +14 -2
- psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +3 -4
- psychopy/iohub/server.py +2 -2
- psychopy/iohub/start_iohub_process.py +3 -0
- psychopy/iohub/util/__init__.py +62 -70
- psychopy/layout.py +5 -5
- psychopy/logging.py +8 -1
- psychopy/microphone.py +10 -37
- psychopy/platform_specific/__init__.py +0 -2
- psychopy/platform_specific/darwin.py +1 -3
- psychopy/platform_specific/linux.py +31 -33
- psychopy/platform_specific/win32.py +38 -13
- psychopy/plugins/__init__.py +148 -116
- psychopy/plugins/util.py +39 -0
- psychopy/preferences/Darwin.spec +4 -2
- psychopy/preferences/FreeBSD.spec +4 -2
- psychopy/preferences/Linux.spec +4 -2
- psychopy/preferences/Windows.spec +4 -2
- psychopy/preferences/baseNoArch.spec +4 -2
- psychopy/preferences/preferences.py +47 -24
- psychopy/projects/pavlovia.py +47 -4
- psychopy/scripts/psyexpCompile.py +0 -4
- psychopy/session.py +153 -21
- psychopy/sound/__init__.py +31 -21
- psychopy/sound/_base.py +20 -3
- psychopy/sound/audioclip.py +320 -33
- psychopy/sound/backend_ptb.py +47 -58
- psychopy/sound/backend_pygame.py +1 -1
- psychopy/sound/backend_pysound.py +6 -15
- psychopy/sound/transcribe.py +53 -0
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestUnknownPluginComponent_load_resave.psyexp +135 -0
- psychopy/tests/data/Test_textbox/test_ori_0_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_top left.png +0 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
- psychopy/tests/data/test_session/.DS_Store +0 -0
- psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
- psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/conftest.py +2 -2
- psychopy/tests/test_app/test_speed.py +4 -1
- psychopy/tests/test_data/test_TrialHandler2.py +146 -1
- psychopy/tests/test_experiment/.DS_Store +0 -0
- psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +3 -3
- psychopy/tests/test_experiment/needs_wx/test_components.py +2 -2
- psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
- psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
- psychopy/tests/test_experiment/test_components/test_base_components.py +58 -0
- psychopy/tests/test_experiment/test_py2js.py +1 -1
- psychopy/tests/test_hardware/test_keyboard.py +31 -0
- psychopy/tests/test_hardware/test_ports.py +1 -11
- psychopy/tests/test_liaison/test_Liaison.py +47 -0
- psychopy/tests/test_misc/test_core.py +5 -0
- psychopy/tests/test_session/test_Session.py +5 -1
- psychopy/tests/test_tools/test_versionchooser.py +39 -8
- psychopy/tests/test_visual/test_all_stimuli.py +0 -97
- psychopy/tests/test_visual/test_image.py +6 -5
- psychopy/tests/test_visual/test_textbox.py +36 -0
- psychopy/tests/utils.py +4 -0
- psychopy/tools/filetools.py +1 -1
- psychopy/tools/pkgtools.py +160 -137
- psychopy/tools/versionchooser.py +10 -10
- psychopy/tools/wizard.py +3 -3
- psychopy/visual/.DS_Store +0 -0
- psychopy/visual/backends/pygletbackend.py +24 -13
- psychopy/visual/basevisual.py +5 -11
- psychopy/visual/button.py +2 -14
- psychopy/visual/helpers.py +5 -5
- psychopy/visual/line.py +1 -2
- psychopy/visual/movie2.py +7 -816
- psychopy/visual/movie3.py +7 -589
- psychopy/visual/movies/__init__.py +8 -11
- psychopy/visual/movies/frame.py +5 -2
- psychopy/visual/movies/players/ffpyplayer_player.py +5 -2
- psychopy/visual/noise.py +8 -7
- psychopy/visual/patch.py +7 -16
- psychopy/visual/radial.py +9 -7
- psychopy/visual/ratingscale.py +8 -1415
- psychopy/visual/secondorder.py +10 -9
- psychopy/visual/shape.py +7 -2
- psychopy/visual/text.py +1 -1
- psychopy/visual/textbox2/textbox2.py +28 -5
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/METADATA +8 -13
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/RECORD +307 -213
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/WHEEL +1 -1
- psychopy/app/Resources/click.png +0 -0
- psychopy/app/Resources/next.png +0 -0
- psychopy/experiment/components/patch/__init__.py +0 -121
- psychopy/experiment/components/patch/classic/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
- psychopy/experiment/components/patch/light/patch.png +0 -0
- psychopy/experiment/components/patch/light/patch@2x.png +0 -0
- psychopy/experiment/components/ratingScale/__init__.py +0 -337
- psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
- psychopy/platform_specific/posix.py +0 -16
- psychopy/tests/test_sound/test_microphone.py +0 -217
- psychopy/tests/test_visual/test_ratingScale.py +0 -299
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@16w.png +0 -0
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@32w.png +0 -0
- /psychopy/{app/Resources → assets}/USB-C.png +0 -0
- /psychopy/{app/Resources → assets}/USB.png +0 -0
- /psychopy/{app/Resources → assets}/creditCard.png +0 -0
- /psychopy/{app/Resources → assets}/default.mp3 +0 -0
- /psychopy/{app/Resources → assets}/default.mp4 +0 -0
- /psychopy/{app/Resources → assets}/default.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct1.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct2.png +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/AUTHORS.md +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,6 +7,7 @@ import socket
|
|
|
7
7
|
import os
|
|
8
8
|
import numbers # numbers.Integral is like (int, long) but supports Py3
|
|
9
9
|
from psychopy import colors
|
|
10
|
+
from psychopy.iohub.devices import importDeviceModule
|
|
10
11
|
from psychopy.tools import arraytools
|
|
11
12
|
from ..util import yload, yLoader, module_directory, getSupportedConfigSettings
|
|
12
13
|
from ..errors import print2err
|
|
@@ -488,7 +489,7 @@ def validateDeviceConfiguration(
|
|
|
488
489
|
current_device_config):
|
|
489
490
|
"""Validate the device configuration settings provided.
|
|
490
491
|
"""
|
|
491
|
-
validation_module =
|
|
492
|
+
validation_module = importDeviceModule(relative_module_path)
|
|
492
493
|
validation_file_path = getSupportedConfigSettings(validation_module)
|
|
493
494
|
|
|
494
495
|
# use a default config if we can't get the YAML file
|
|
@@ -6,13 +6,24 @@
|
|
|
6
6
|
# indicated here.
|
|
7
7
|
#
|
|
8
8
|
Experiment:
|
|
9
|
-
# name: The unique name to assign to the
|
|
9
|
+
# name: The unique name to assign to the device instance created.
|
|
10
10
|
# The device is accessed from within the PsychoPy script
|
|
11
11
|
# using the name's value; therefore it must be a valid Python
|
|
12
12
|
# variable name as well.
|
|
13
13
|
#
|
|
14
14
|
name: experiment
|
|
15
15
|
|
|
16
|
+
# filename: The name of files saved by an attached PsychoPy experiment.
|
|
17
|
+
# This is usually provided as PsychoPy ExperimentHandler.dataFileName.
|
|
18
|
+
# It gives ioHub server awareness of filenames used by PsychoPy when a
|
|
19
|
+
# DataStore file is not being saved by the ioHub. This handle is useful
|
|
20
|
+
# when the ioHub is being used to monitor the PsychoPy experiment, but
|
|
21
|
+
# all data is being saved by the PsychoPy ExperimentHandler, while there
|
|
22
|
+
# are external data files transferred through the ioHub server that need
|
|
23
|
+
# to be saved in the same naming convention as the PsychoPy data files.
|
|
24
|
+
# Default value is Python None type. Valid value is any string.
|
|
25
|
+
filename:
|
|
26
|
+
|
|
16
27
|
# monitor_event_types: Specify which of the device's supported event
|
|
17
28
|
# types you would like the ioHub to monitor for.
|
|
18
29
|
#
|
|
@@ -4,7 +4,11 @@ Experiment:
|
|
|
4
4
|
IOHUB_STRING:
|
|
5
5
|
min_length: 1
|
|
6
6
|
max_length: 32
|
|
7
|
-
first_char_alpha: True
|
|
7
|
+
first_char_alpha: True
|
|
8
|
+
filename:
|
|
9
|
+
IOHUB_STRING:
|
|
10
|
+
min_length: 0
|
|
11
|
+
first_char_alpha: False
|
|
8
12
|
save_events: IOHUB_BOOL
|
|
9
13
|
stream_events: True
|
|
10
14
|
auto_report_events: True
|
|
Binary file
|
|
@@ -250,6 +250,52 @@ class EyeTrackerDevice(Device):
|
|
|
250
250
|
None
|
|
251
251
|
"""
|
|
252
252
|
return EyeTrackerConstants.EYETRACKER_INTERFACE_METHOD_NOT_SUPPORTED
|
|
253
|
+
|
|
254
|
+
@staticmethod
|
|
255
|
+
def getCalibrationDict(calib):
|
|
256
|
+
"""
|
|
257
|
+
Create a dict describing the given Calibration object, respecting this
|
|
258
|
+
eyetracker's specific limitations. If not overloaded by a subclass, this
|
|
259
|
+
will use the same fields and values as MouseGaze.
|
|
260
|
+
|
|
261
|
+
Parameters
|
|
262
|
+
----------
|
|
263
|
+
calib : psychopy.hardware.eyetracker.EyetrackerCalibration
|
|
264
|
+
Object to create a dict from
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
dict
|
|
269
|
+
Dict describing the given Calibration object
|
|
270
|
+
"""
|
|
271
|
+
return {
|
|
272
|
+
'target_attributes': {
|
|
273
|
+
# target outer circle
|
|
274
|
+
'outer_diameter': calib.target.radius * 2,
|
|
275
|
+
'outer_stroke_width': calib.target.outer.lineWidth,
|
|
276
|
+
'outer_fill_color': getattr(calib.target.outer._fillColor, calib.colorSpace) if calib.target.outer._fillColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
277
|
+
'outer_line_color': getattr(calib.target.outer._borderColor, calib.colorSpace) if calib.target.outer._borderColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
278
|
+
# target inner circle
|
|
279
|
+
'inner_diameter': calib.target.innerRadius * 2,
|
|
280
|
+
'inner_stroke_width': calib.target.inner.lineWidth,
|
|
281
|
+
'inner_fill_color': getattr(calib.target.inner._borderColor, calib.colorSpace) if calib.target.inner._borderColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
282
|
+
'inner_line_color': getattr(calib.target.inner._borderColor, calib.colorSpace) if calib.target.inner._borderColor else getattr(calib.target.win._color, calib.colorSpace),
|
|
283
|
+
# target animation
|
|
284
|
+
'animate':{
|
|
285
|
+
'enable': calib.movementAnimation,
|
|
286
|
+
'expansion_ratio': calib.expandScale,
|
|
287
|
+
'contract_only': calib.expandScale == 1,
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
'type': calib.targetLayout,
|
|
291
|
+
'randomize': calib.randomisePos,
|
|
292
|
+
'auto_pace': calib.progressMode == "time",
|
|
293
|
+
'pacing_speed': calib.targetDelay,
|
|
294
|
+
'unit_type': calib.units,
|
|
295
|
+
'color_type': calib.colorSpace,
|
|
296
|
+
'text_color': calib.textColor if str(calib.textColor).lower() != "auto" else None,
|
|
297
|
+
'screen_background_color': getattr(calib.win._color, calib.colorSpace),
|
|
298
|
+
}
|
|
253
299
|
|
|
254
300
|
def setRecordingState(self, recording):
|
|
255
301
|
"""The setRecordingState method is used to start or stop the recording
|
|
@@ -157,10 +157,10 @@ class BaseCalibrationProcedure:
|
|
|
157
157
|
def setDefaultCalibrationTarget():
|
|
158
158
|
# convert sizes to stimulus units
|
|
159
159
|
radiusPix = self.getCalibSetting(['target_attributes', 'outer_diameter']) / 2
|
|
160
|
-
radiusObj = layout.Size(radiusPix, units=
|
|
160
|
+
radiusObj = layout.Size(radiusPix, units=unit_type, win=self.window)
|
|
161
161
|
radius = getattr(radiusObj, unit_type)[1]
|
|
162
162
|
innerRadiusPix = self.getCalibSetting(['target_attributes', 'inner_diameter']) / 2
|
|
163
|
-
innerRadiusObj = layout.Size(innerRadiusPix, units=
|
|
163
|
+
innerRadiusObj = layout.Size(innerRadiusPix, units=unit_type, win=self.window)
|
|
164
164
|
innerRadius = getattr(innerRadiusObj, unit_type)[1]
|
|
165
165
|
# make target
|
|
166
166
|
self.targetStim = visual.TargetStim(
|
|
@@ -6,7 +6,19 @@
|
|
|
6
6
|
import psychopy.logging as logging
|
|
7
7
|
|
|
8
8
|
try:
|
|
9
|
-
from psychopy_eyetracker_gazepoint.gazepoint import
|
|
9
|
+
from psychopy_eyetracker_gazepoint.gazepoint.gp3 import (
|
|
10
|
+
__file__,
|
|
11
|
+
EyeTracker,
|
|
12
|
+
MonocularEyeSampleEvent,
|
|
13
|
+
BinocularEyeSampleEvent,
|
|
14
|
+
FixationStartEvent,
|
|
15
|
+
FixationEndEvent,
|
|
16
|
+
SaccadeStartEvent,
|
|
17
|
+
SaccadeEndEvent,
|
|
18
|
+
BlinkStartEvent,
|
|
19
|
+
BlinkEndEvent,
|
|
20
|
+
GazepointSampleEvent
|
|
21
|
+
)
|
|
10
22
|
except (ModuleNotFoundError, ImportError, NameError):
|
|
11
23
|
logging.error(
|
|
12
24
|
"The Gazepoint eyetracker requires package "
|
|
@@ -14,4 +26,4 @@ except (ModuleNotFoundError, ImportError, NameError):
|
|
|
14
26
|
"package and restart the session to enable support.")
|
|
15
27
|
|
|
16
28
|
if __name__ == "__main__":
|
|
17
|
-
pass
|
|
29
|
+
pass
|
|
@@ -408,11 +408,10 @@ class EyeTracker(EyeTrackerDevice):
|
|
|
408
408
|
cal_run = calibration.runCalibration()
|
|
409
409
|
calibration.window.close()
|
|
410
410
|
|
|
411
|
-
|
|
412
|
-
# losing keyboard input after the window is closed. The new keyboard
|
|
413
|
-
# input system does not require this call anymore.
|
|
414
|
-
# calibration._unregisterEventMonitors()
|
|
411
|
+
calibration._unregisterEventMonitors()
|
|
415
412
|
calibration.clearAllEventBuffers()
|
|
413
|
+
del calibration.window
|
|
414
|
+
del calibration
|
|
416
415
|
|
|
417
416
|
if cal_run:
|
|
418
417
|
return {"RESULT": "CALIBRATION_OK"}
|
psychopy/iohub/server.py
CHANGED
|
@@ -28,7 +28,7 @@ from .net import MAX_PACKET_SIZE
|
|
|
28
28
|
from .util import convertCamelToSnake, win32MessagePump
|
|
29
29
|
from .util import yload, yLoader
|
|
30
30
|
from .constants import DeviceConstants, EventConstants
|
|
31
|
-
from .devices import DeviceEvent, import_device
|
|
31
|
+
from .devices import DeviceEvent, import_device, importDeviceModule
|
|
32
32
|
from .devices import Computer
|
|
33
33
|
from .devices.deviceConfigValidation import validateDeviceConfiguration
|
|
34
34
|
getTime = Computer.getTime
|
|
@@ -846,7 +846,7 @@ class ioServer():
|
|
|
846
846
|
else:
|
|
847
847
|
dev_mod_pth += dev_cls_name.lower()
|
|
848
848
|
# convert subdirectory to path
|
|
849
|
-
dev_mod =
|
|
849
|
+
dev_mod = importDeviceModule(dev_mod_pth)
|
|
850
850
|
dev_file_pth = os.path.dirname(dev_mod.__file__)
|
|
851
851
|
# get config from path
|
|
852
852
|
dev_conf_pth = os.path.join(dev_file_pth,
|
|
@@ -79,6 +79,9 @@ def run(rootScriptPathDir, configFilePath):
|
|
|
79
79
|
else:
|
|
80
80
|
gevent.joinall(glets)
|
|
81
81
|
|
|
82
|
+
# Wait for the server to be ready to shutdown
|
|
83
|
+
gevent.wait()
|
|
84
|
+
|
|
82
85
|
lrtime = Computer.global_clock.getLastResetTime()
|
|
83
86
|
s.log('Server END Time Offset: {0}'.format(lrtime), 'DEBUG')
|
|
84
87
|
return True
|
psychopy/iohub/util/__init__.py
CHANGED
|
@@ -16,6 +16,10 @@ import collections.abc
|
|
|
16
16
|
import pathlib
|
|
17
17
|
import psychopy.logging as logging
|
|
18
18
|
import psychopy.plugins as plugins
|
|
19
|
+
from psychopy.plugins.util import getEntryPoints
|
|
20
|
+
from importlib.metadata import entry_points
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from psychopy.preferences import prefs
|
|
19
23
|
|
|
20
24
|
########################
|
|
21
25
|
#
|
|
@@ -33,8 +37,6 @@ try:
|
|
|
33
37
|
except ImportError:
|
|
34
38
|
from collections import Iterable
|
|
35
39
|
|
|
36
|
-
from psychopy.preferences import prefs
|
|
37
|
-
|
|
38
40
|
|
|
39
41
|
def saveConfig(config, dst_path):
|
|
40
42
|
'''
|
|
@@ -141,7 +143,7 @@ def module_directory(local_function):
|
|
|
141
143
|
def getSupportedConfigSettings(moduleName, deviceClassName=None):
|
|
142
144
|
"""Get the supported configuration settings for a device.
|
|
143
145
|
|
|
144
|
-
These are usually stored as YAML files within the module directory that
|
|
146
|
+
These are usually stored as YAML files within the module directory that
|
|
145
147
|
defines the device class.
|
|
146
148
|
|
|
147
149
|
Parameters
|
|
@@ -150,10 +152,10 @@ def getSupportedConfigSettings(moduleName, deviceClassName=None):
|
|
|
150
152
|
The name of the module to get the path for. Must be a package that defines
|
|
151
153
|
`__init__.py`.
|
|
152
154
|
deviceClassName : str, optional
|
|
153
|
-
The name of the specific device class to get the path for. If not provided,
|
|
154
|
-
the default configuration file will be searched for in the module
|
|
155
|
+
The name of the specific device class to get the path for. If not provided,
|
|
156
|
+
the default configuration file will be searched for in the module
|
|
155
157
|
directory.
|
|
156
|
-
|
|
158
|
+
|
|
157
159
|
Returns
|
|
158
160
|
-------
|
|
159
161
|
str
|
|
@@ -174,13 +176,13 @@ def getSupportedConfigSettings(moduleName, deviceClassName=None):
|
|
|
174
176
|
"Found ioHub device configuration file: {0}".format(yamlFile))
|
|
175
177
|
|
|
176
178
|
return str(yamlFile)
|
|
177
|
-
|
|
179
|
+
|
|
178
180
|
# file name for yaml file name convention for single file
|
|
179
181
|
yamlFile = yamlRoot / pathlib.Path('supported_config_settings.yaml')
|
|
180
182
|
if not yamlFile.exists(): # nothing is found
|
|
181
183
|
raise FileNotFoundError(
|
|
182
184
|
"No config file found in module dir {0}".format(moduleName))
|
|
183
|
-
|
|
185
|
+
|
|
184
186
|
logging.debug(
|
|
185
187
|
"Found ioHub device configuration file: {0}".format(yamlFile))
|
|
186
188
|
|
|
@@ -231,9 +233,17 @@ def getDevicePaths(device_name=""):
|
|
|
231
233
|
|
|
232
234
|
"""
|
|
233
235
|
yaml_paths = []
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
|
|
237
|
+
if '.zip' in iohub_device_path:
|
|
238
|
+
# if the entry point is in a zip file, it is likely loading from a precompiled
|
|
239
|
+
# library instead of a user installed plugin module. Raise warning.
|
|
240
|
+
logging.error(
|
|
241
|
+
f"Bad entry point loaded: {ep}\n"
|
|
242
|
+
f"It is pointing into a zip file: {iohub_device_path}"
|
|
243
|
+
)
|
|
244
|
+
else:
|
|
245
|
+
# search the provided iohub_device_path for device config files
|
|
246
|
+
for root, _, files in os.walk(iohub_device_path):
|
|
237
247
|
# check each file in the route to see if it's a config yaml
|
|
238
248
|
device_folder = None
|
|
239
249
|
for file in files:
|
|
@@ -253,65 +263,40 @@ def getDevicePaths(device_name=""):
|
|
|
253
263
|
scs_yaml_paths = [] # stores the paths to the device config files
|
|
254
264
|
plugins.refreshBundlePaths() # make sure eyetracker external plugins are reachable
|
|
255
265
|
|
|
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
|
-
if deviceConfig:
|
|
282
|
-
logging.debug("Found Gazepoint device configuration file.")
|
|
283
|
-
scs_yaml_paths.extend(deviceConfig)
|
|
284
|
-
except ImportError:
|
|
285
|
-
logging.debug("No Gazepoint device configuration file found.")
|
|
286
|
-
|
|
287
|
-
try: # for PupilLabs eye trackers
|
|
288
|
-
logging.debug("Looking for PupilLabs device configuration file...")
|
|
289
|
-
import psychopy_eyetracker_pupil_labs.pupil_labs.pupil_core as pupil_core
|
|
290
|
-
deviceConfig = _getDevicePaths(os.path.dirname(pupil_core.__file__))
|
|
291
|
-
if deviceConfig:
|
|
292
|
-
logging.debug("Found PupilLabs device configuration file.")
|
|
293
|
-
scs_yaml_paths.extend(deviceConfig)
|
|
294
|
-
|
|
295
|
-
import psychopy_eyetracker_pupil_labs.pupil_labs.neon as neon
|
|
296
|
-
deviceConfig = _getDevicePaths(os.path.dirname(neon.__file__))
|
|
297
|
-
if deviceConfig:
|
|
298
|
-
logging.debug("Found PupilLabs Neon device configuration file.")
|
|
299
|
-
scs_yaml_paths.extend(deviceConfig)
|
|
300
|
-
|
|
301
|
-
except ImportError:
|
|
302
|
-
logging.debug("No PupilLabs device configuration file found.")
|
|
303
|
-
|
|
304
|
-
# use this method for built-in devices
|
|
266
|
+
# NOTE: The “selectable” entry points were introduced in importlib_metadata 3.6 and Python 3.10.
|
|
267
|
+
# Prior to those changes, entry_points accepted no parameters and always returned a dictionary
|
|
268
|
+
# of entry points, keyed by group. With importlib_metadata 5.0 and Python 3.12, entry_points
|
|
269
|
+
# always returns an EntryPoints object.
|
|
270
|
+
|
|
271
|
+
if 'eyetracker' in device_name.lower():
|
|
272
|
+
# Find entry points targeting psychopy.iohub.devices.eyetracker
|
|
273
|
+
for ep in getEntryPoints('psychopy.iohub.devices.eyetracker', submodules=False, flatten=True):
|
|
274
|
+
# load the target the entry point points to, it could be a class or a module
|
|
275
|
+
try:
|
|
276
|
+
ep_target = ep.load()
|
|
277
|
+
except: # noqa: E722
|
|
278
|
+
logging.error(f"Failed to load entry point: {ep}")
|
|
279
|
+
continue
|
|
280
|
+
|
|
281
|
+
if hasattr(ep_target, "configFile"):
|
|
282
|
+
# if entry point target binds to a yaml file, use it
|
|
283
|
+
scs_yaml_paths.append(
|
|
284
|
+
(ep_target.configFile.parent, ep_target.configFile.name)
|
|
285
|
+
)
|
|
286
|
+
else: # otherwise, check the local folder of the target module or class
|
|
287
|
+
deviceConfig = _getDevicePaths(os.path.dirname(inspect.getfile(ep_target)))
|
|
288
|
+
scs_yaml_paths.extend(deviceConfig)
|
|
289
|
+
|
|
290
|
+
# Use import_device() method for built-in devices
|
|
305
291
|
iohub_device_path = module_directory(import_device)
|
|
306
292
|
if device_name:
|
|
307
293
|
iohub_device_path = os.path.join(
|
|
308
294
|
iohub_device_path, device_name.replace('.', os.path.sep))
|
|
309
|
-
|
|
310
295
|
deviceConfigs = _getDevicePaths(iohub_device_path)
|
|
311
|
-
|
|
312
|
-
scs_yaml_paths.extend(deviceConfigs)
|
|
296
|
+
scs_yaml_paths.extend(deviceConfigs)
|
|
313
297
|
|
|
314
|
-
|
|
298
|
+
# Return a unique list of device config paths
|
|
299
|
+
return list(set(scs_yaml_paths))
|
|
315
300
|
|
|
316
301
|
|
|
317
302
|
def getDeviceDefaultConfig(device_name, builder_hides=True):
|
|
@@ -381,10 +366,10 @@ def getDeviceNames(device_name="eyetracker.hw", get_paths=True):
|
|
|
381
366
|
print(eyetrackers)
|
|
382
367
|
|
|
383
368
|
Output:
|
|
384
|
-
[('GazePoint', 'eyetracker.
|
|
369
|
+
[('GazePoint', 'eyetracker.gazepoint.EyeTracker'),
|
|
385
370
|
('MouseGaze', 'eyetracker.hw.mouse.EyeTracker'),
|
|
386
|
-
('SR Research Ltd', 'eyetracker.
|
|
387
|
-
('Tobii Technology', 'eyetracker.
|
|
371
|
+
('SR Research Ltd', 'eyetracker.eyelink.EyeTracker'),
|
|
372
|
+
('Tobii Technology', 'eyetracker.tobii.EyeTracker')]
|
|
388
373
|
"""
|
|
389
374
|
names = []
|
|
390
375
|
dconfigs = getDeviceDefaultConfig(device_name)
|
|
@@ -397,6 +382,7 @@ def getDeviceNames(device_name="eyetracker.hw", get_paths=True):
|
|
|
397
382
|
names.append((d_config.get('manufacturer_name'), d_path))
|
|
398
383
|
return names
|
|
399
384
|
|
|
385
|
+
|
|
400
386
|
def getDeviceFile(device_name, file_name):
|
|
401
387
|
"""
|
|
402
388
|
Returns the contents of file_name for the specified device. If file_name does not exist, None is returned.
|
|
@@ -408,6 +394,7 @@ def getDeviceFile(device_name, file_name):
|
|
|
408
394
|
if device_name.endswith(".EyeTracker"):
|
|
409
395
|
device_name = device_name[:-11]
|
|
410
396
|
device_paths = getDevicePaths(device_name)
|
|
397
|
+
|
|
411
398
|
device_sconfigs = []
|
|
412
399
|
for dpath, _ in device_paths:
|
|
413
400
|
device_sconfigs.append(readConfig(os.path.join(dpath, file_name)))
|
|
@@ -416,6 +403,7 @@ def getDeviceFile(device_name, file_name):
|
|
|
416
403
|
return list(device_sconfigs[0].values())[0]
|
|
417
404
|
return device_sconfigs
|
|
418
405
|
|
|
406
|
+
|
|
419
407
|
def getDeviceSupportedConfig(device_name):
|
|
420
408
|
"""
|
|
421
409
|
Returns the contents of the supported_config_settings.yaml for the specified device.
|
|
@@ -425,6 +413,7 @@ def getDeviceSupportedConfig(device_name):
|
|
|
425
413
|
"""
|
|
426
414
|
return getDeviceFile(device_name, 'supported_config_settings.yaml')
|
|
427
415
|
|
|
416
|
+
|
|
428
417
|
if sys.platform == 'win32':
|
|
429
418
|
import pythoncom
|
|
430
419
|
|
|
@@ -446,6 +435,7 @@ else:
|
|
|
446
435
|
def win32MessagePump():
|
|
447
436
|
pass
|
|
448
437
|
|
|
438
|
+
|
|
449
439
|
# PsychoPy Window Hide / Show functions.
|
|
450
440
|
# Windows 10 and macOS have different code that needs to be called
|
|
451
441
|
# to show a second full screen window on top of an existing one, like
|
|
@@ -468,6 +458,7 @@ def hideWindow(win, force=False):
|
|
|
468
458
|
else:
|
|
469
459
|
print("Warning: Unhandled sys.platform: ", sys.platform)
|
|
470
460
|
|
|
461
|
+
|
|
471
462
|
def showWindow(win, force=False):
|
|
472
463
|
"""
|
|
473
464
|
If needed, hide / minimize the in.
|
|
@@ -486,6 +477,7 @@ def showWindow(win, force=False):
|
|
|
486
477
|
else:
|
|
487
478
|
print("Warning: Unhandled sys.platform: ", sys.platform)
|
|
488
479
|
|
|
480
|
+
|
|
489
481
|
def createCustomCalibrationStim(win, cal_settings):
|
|
490
482
|
"""
|
|
491
483
|
Create a custom calibration target using the CUSTOM eyetracker calibration settings. Returns an instance of
|
|
@@ -549,12 +541,12 @@ def updateDict(add_to, add_from):
|
|
|
549
541
|
|
|
550
542
|
def updateSettings(d, u):
|
|
551
543
|
for k, v in u.items():
|
|
552
|
-
if
|
|
544
|
+
if isinstance(k, bytes):
|
|
553
545
|
k = k.decode('UTF-8')
|
|
554
546
|
if isinstance(v, collections.abc.Mapping):
|
|
555
547
|
d[k] = updateSettings(d.get(k, {}), v)
|
|
556
548
|
else:
|
|
557
|
-
if
|
|
549
|
+
if isinstance(v, bytes):
|
|
558
550
|
v = v.decode('UTF-8')
|
|
559
551
|
d[k] = v
|
|
560
552
|
return d
|
|
@@ -575,7 +567,7 @@ def convertCamelToSnake(name, lower_snake=True):
|
|
|
575
567
|
# A couple date / time related utility functions
|
|
576
568
|
|
|
577
569
|
getCurrentDateTime = datetime.datetime.now
|
|
578
|
-
getCurrentDateTimeString = lambda: getCurrentDateTime().strftime("%Y-%m-%d %H:%M")
|
|
570
|
+
getCurrentDateTimeString = lambda: getCurrentDateTime().strftime("%Y-%m-%d %H:%M") # noqa: E731
|
|
579
571
|
|
|
580
572
|
|
|
581
573
|
# rgb255 color utils
|
psychopy/layout.py
CHANGED
|
@@ -171,16 +171,16 @@ class Vector:
|
|
|
171
171
|
self.valid = False
|
|
172
172
|
|
|
173
173
|
# Replace None with the matching window dimension
|
|
174
|
-
if (value == None).any() or np.isnan(value).any():
|
|
174
|
+
if (value == None).any() or np.isnan(value).any(): # noqa: E711
|
|
175
175
|
win = Vector((1, 1), units="norm", win=self.win)
|
|
176
176
|
if len(value.shape) == 1:
|
|
177
|
-
value[value == None] = getattr(win, units)[value == None]
|
|
177
|
+
value[value == None] = getattr(win, units)[value == None] # noqa: E711
|
|
178
178
|
value[np.isnan(value)] = getattr(win, units)[np.isnan(value)]
|
|
179
179
|
else:
|
|
180
180
|
value[np.isnan(value[:, 0]), 0] = getattr(win, units)[0]
|
|
181
181
|
value[np.isnan(value[:, 1]), 1] = getattr(win, units)[1]
|
|
182
|
-
value[value[:, 0] == None, 0] = getattr(win, units)[0]
|
|
183
|
-
value[value[:, 1] == None, 1] = getattr(win, units)[1]
|
|
182
|
+
value[value[:, 0] == None, 0] = getattr(win, units)[0] # noqa: E711
|
|
183
|
+
value[value[:, 1] == None, 1] = getattr(win, units)[1] # noqa: E711
|
|
184
184
|
|
|
185
185
|
assert self.valid, (f"Array of position/size values must be either "
|
|
186
186
|
f"Nx1, Nx2 or Nx3, not {value.shape}")
|
|
@@ -913,4 +913,4 @@ class Vertices:
|
|
|
913
913
|
|
|
914
914
|
|
|
915
915
|
if __name__ == "__main__":
|
|
916
|
-
pass
|
|
916
|
+
pass
|
psychopy/logging.py
CHANGED
|
@@ -76,6 +76,9 @@ _levelNames = {
|
|
|
76
76
|
'DEBUG': DEBUG,
|
|
77
77
|
'NOTSET': NOTSET}
|
|
78
78
|
|
|
79
|
+
# string to search for level names in a log message
|
|
80
|
+
_levelNamesRe = "|".join(key for key in _levelNames if isinstance(key, str))
|
|
81
|
+
|
|
79
82
|
_prefEncoding = locale.getpreferredencoding()
|
|
80
83
|
|
|
81
84
|
def getLevel(level):
|
|
@@ -188,6 +191,10 @@ class LogFile():
|
|
|
188
191
|
def setLevel(self, level):
|
|
189
192
|
"""Set a new minimal level for the log file/stream
|
|
190
193
|
"""
|
|
194
|
+
# if given a name, get corresponding integer value
|
|
195
|
+
if isinstance(level, str):
|
|
196
|
+
level = getLevel(level)
|
|
197
|
+
# make sure we (now) have an integer
|
|
191
198
|
if type(level) is not int:
|
|
192
199
|
raise TypeError("LogFile.setLevel() should be given an int, which"
|
|
193
200
|
"is usually one of logging.INFO (not logging.info)")
|
|
@@ -305,7 +312,7 @@ class _Logger():
|
|
|
305
312
|
self.toFlush = [] # a new empty list
|
|
306
313
|
|
|
307
314
|
root = _Logger()
|
|
308
|
-
console = LogFile()
|
|
315
|
+
console = LogFile(level=WARNING)
|
|
309
316
|
|
|
310
317
|
|
|
311
318
|
def flush(logger=root):
|
psychopy/microphone.py
CHANGED
|
@@ -12,43 +12,16 @@ These are optional components that can be obtained by installing the
|
|
|
12
12
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
getDftBins,
|
|
26
|
-
getDft,
|
|
27
|
-
getRMSBins,
|
|
28
|
-
getRMS,
|
|
29
|
-
SoundFormatNotSupported,
|
|
30
|
-
SoundFileError,
|
|
31
|
-
MicrophoneError,
|
|
32
|
-
Speech2Text,
|
|
33
|
-
BatchSpeech2Text,
|
|
34
|
-
flac2wav,
|
|
35
|
-
wav2flac,
|
|
36
|
-
switchOn,
|
|
37
|
-
switchOff,
|
|
38
|
-
_getFlacPath)
|
|
39
|
-
except (ModuleNotFoundError, ImportError, NameError):
|
|
40
|
-
logging.error(
|
|
41
|
-
"Support for `psychopy.microphone` hardware is not available this "
|
|
42
|
-
"session. Please install `psychopy-legacy-mic` and restart the session "
|
|
43
|
-
"to enable support.")
|
|
44
|
-
else:
|
|
45
|
-
# if we successfully load the package, warn the user to use the newer stuff
|
|
46
|
-
logging.warning(
|
|
47
|
-
"Attempting to import `psychopy.microphone`. Note that this library is "
|
|
48
|
-
"deprecated for the purpose of audio capture, but may still provide "
|
|
49
|
-
"other useful functionality. Use `psychopy.sound.microphone` for audio "
|
|
50
|
-
"capture instead."
|
|
51
|
-
)
|
|
15
|
+
|
|
16
|
+
from psychopy.tools.pkgtools import PluginStub
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AudioCapture(
|
|
20
|
+
PluginStub,
|
|
21
|
+
plugin="psychopy-legacy-mic"
|
|
22
|
+
):
|
|
23
|
+
pass
|
|
24
|
+
|
|
52
25
|
|
|
53
26
|
if __name__ == "__main__":
|
|
54
27
|
pass
|
|
@@ -44,5 +44,3 @@ elif sys.platform == 'darwin':
|
|
|
44
44
|
from .darwin import * # pylint: disable=W0401
|
|
45
45
|
elif sys.platform.startswith('linux'): # normally 'linux2'
|
|
46
46
|
from .linux import * # pylint: disable=W0401
|
|
47
|
-
elif sys.platform == 'posix': # ever?!
|
|
48
|
-
from .posix import * # pylint: disable=W0401
|
|
@@ -105,8 +105,6 @@ def getBusFreq():
|
|
|
105
105
|
def rush(value=True, realtime=False):
|
|
106
106
|
"""Raise the priority of the current thread / process.
|
|
107
107
|
|
|
108
|
-
Win32 and macOS only so far - on linux use os.nice(niceIncrement)
|
|
109
|
-
|
|
110
108
|
Set with rush(True) or rush(False).
|
|
111
109
|
|
|
112
110
|
realtime arg is not used by osx implementation.
|
|
@@ -149,7 +147,7 @@ def rush(value=True, realtime=False):
|
|
|
149
147
|
# send the address of the struct
|
|
150
148
|
ctypes.byref(extendedPolicy),
|
|
151
149
|
THREAD_STANDARD_POLICY_COUNT)
|
|
152
|
-
return
|
|
150
|
+
return err == KERN_SUCCESS
|
|
153
151
|
|
|
154
152
|
|
|
155
153
|
def getThreadPolicy(getDefault, flavour):
|