psychopy 2024.1.3__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/localizedStrings.py +11 -9
- 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 +1258 -1176
- 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 +152 -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/Feature Demos/progress/progressBar.psyexp +4 -4
- 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/buttonBox/__init__.py +21 -12
- 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/progress/__init__.py +1 -1
- 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 +7 -6
- 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 -11
- 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 +184 -16
- 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/progress.py +1 -1
- 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/web.py +5 -2
- {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/METADATA +8 -13
- {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/RECORD +313 -219
- {psychopy-2024.1.3.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.3.dist-info → psychopy-2024.2.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/licenses/AUTHORS.md +0 -0
- {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -300,6 +300,8 @@ class BaseComponent:
|
|
|
300
300
|
loop = currLoop.params['name']
|
|
301
301
|
name = self.params['name']
|
|
302
302
|
|
|
303
|
+
# NOTE: this function does not write any code right now!
|
|
304
|
+
|
|
303
305
|
def writeRoutineEndCodeJS(self, buff):
|
|
304
306
|
"""Write the code that will be called at the end of
|
|
305
307
|
a routine (e.g. to save data)
|
|
@@ -312,7 +314,7 @@ class BaseComponent:
|
|
|
312
314
|
"""
|
|
313
315
|
pass
|
|
314
316
|
|
|
315
|
-
def writeStartTestCode(self, buff):
|
|
317
|
+
def writeStartTestCode(self, buff, extra=""):
|
|
316
318
|
"""
|
|
317
319
|
Test whether we need to start (if there is a start time at all)
|
|
318
320
|
|
|
@@ -326,50 +328,76 @@ class BaseComponent:
|
|
|
326
328
|
buff.writeIndentedLines(code % self.params)
|
|
327
329
|
buff.setIndentLevel(-indented, relative=True)
|
|
328
330
|
```
|
|
331
|
+
|
|
332
|
+
Parameters
|
|
333
|
+
----------
|
|
334
|
+
buff : io.StringIO
|
|
335
|
+
Text buffer to write code to.
|
|
336
|
+
extra : str
|
|
337
|
+
Additional conditions to check, including any boolean operators (and, or, etc.). Use
|
|
338
|
+
`%(key)s` syntax to insert the values of any necessary params. Default is an empty
|
|
339
|
+
string.
|
|
329
340
|
"""
|
|
341
|
+
# create copy of params dict so we can change stuff without harm
|
|
342
|
+
params = self.params.copy()
|
|
330
343
|
|
|
331
344
|
# Get starting indent level
|
|
332
345
|
startIndent = buff.indentLevel
|
|
333
346
|
|
|
334
|
-
if
|
|
335
|
-
|
|
336
|
-
|
|
347
|
+
if params['startVal'].val in ('', None, -1, 'None'):
|
|
348
|
+
if extra:
|
|
349
|
+
# if we have extra and no stop condition, extra is the only stop condition
|
|
350
|
+
params['startType'] = params['startType'].copy()
|
|
351
|
+
params['startVal'] = params['startVal'].copy()
|
|
352
|
+
params['startType'].val = "condition"
|
|
353
|
+
params['startVal'].val = "False"
|
|
354
|
+
else:
|
|
355
|
+
# if we just have no stop time, don't write stop code
|
|
356
|
+
return buff.indentLevel - startIndent
|
|
337
357
|
|
|
338
358
|
# Newline
|
|
339
359
|
buff.writeIndentedLines("\n")
|
|
340
360
|
|
|
341
|
-
if
|
|
361
|
+
if params['syncScreenRefresh']:
|
|
342
362
|
tCompare = 'tThisFlip'
|
|
343
363
|
else:
|
|
344
364
|
tCompare = 't'
|
|
345
|
-
params = self.params
|
|
346
365
|
t = tCompare
|
|
347
366
|
# add handy comment
|
|
348
367
|
code = (
|
|
349
368
|
"# if %(name)s is starting this frame...\n"
|
|
350
369
|
)
|
|
351
370
|
buff.writeIndentedLines(code % params)
|
|
352
|
-
|
|
371
|
+
# add starting if statement
|
|
372
|
+
if params['startType'].val == 'time (s)':
|
|
353
373
|
# if startVal is an empty string then set to be 0.0
|
|
354
|
-
if (
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
elif
|
|
363
|
-
code = (
|
|
364
|
-
|
|
374
|
+
if (
|
|
375
|
+
isinstance(params['startVal'].val, str)
|
|
376
|
+
and not params['startVal'].val.strip()
|
|
377
|
+
):
|
|
378
|
+
params['startVal'].val = '0.0'
|
|
379
|
+
code = (
|
|
380
|
+
"if %(name)s.status == NOT_STARTED and {} >= %(startVal)s-frameTolerance"
|
|
381
|
+
).format(t)
|
|
382
|
+
elif params['startType'].val == 'frame N':
|
|
383
|
+
code = (
|
|
384
|
+
"if %(name)s.status == NOT_STARTED and frameN >= %(startVal)s"
|
|
385
|
+
)
|
|
386
|
+
elif params['startType'].val == 'condition':
|
|
387
|
+
code = (
|
|
388
|
+
"if %(name)s.status == NOT_STARTED and %(startVal)s"
|
|
389
|
+
)
|
|
365
390
|
else:
|
|
366
|
-
msg = f"Not a known startType (
|
|
367
|
-
raise CodeGenerationException(msg %
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
391
|
+
msg = f"Not a known startType (%(startVal)s) for %(name)s"
|
|
392
|
+
raise CodeGenerationException(msg % params)
|
|
393
|
+
# add any other conditions and finish the statement
|
|
394
|
+
if extra and not extra.startswith(" "):
|
|
395
|
+
extra = " " + extra
|
|
396
|
+
code += f"{extra}:\n"
|
|
397
|
+
# write if statement and indent
|
|
398
|
+
buff.writeIndentedLines(code % params)
|
|
371
399
|
buff.setIndentLevel(+1, relative=True)
|
|
372
|
-
|
|
400
|
+
|
|
373
401
|
code = (f"# keep track of start time/frame for later\n"
|
|
374
402
|
f"{params['name']}.frameNStart = frameN # exact frame index\n"
|
|
375
403
|
f"{params['name']}.tStart = t # local t and not account for scr refresh\n"
|
|
@@ -380,12 +408,12 @@ class BaseComponent:
|
|
|
380
408
|
# on the *expected* time of the flip
|
|
381
409
|
code += (f"win.timeOnFlip({params['name']}, 'tStartRefresh')"
|
|
382
410
|
f" # time at next scr refresh\n")
|
|
383
|
-
if
|
|
411
|
+
if params['saveStartStop']:
|
|
384
412
|
code += f"# add timestamp to datafile\n"
|
|
385
|
-
if self.type=='Sound' and
|
|
413
|
+
if self.type=='Sound' and params['syncScreenRefresh']:
|
|
386
414
|
# use the time we *expect* the flip
|
|
387
415
|
code += f"thisExp.addData('{params['name']}.started', tThisFlipGlobal)\n"
|
|
388
|
-
elif 'syncScreenRefresh' in
|
|
416
|
+
elif 'syncScreenRefresh' in params and params['syncScreenRefresh']:
|
|
389
417
|
# use the time we *detect* the flip (in the future)
|
|
390
418
|
code += f"thisExp.timestampOnFlip(win, '{params['name']}.started')\n"
|
|
391
419
|
else:
|
|
@@ -406,42 +434,69 @@ class BaseComponent:
|
|
|
406
434
|
"# update status\n"
|
|
407
435
|
"%(name)s.status = STARTED\n"
|
|
408
436
|
)
|
|
409
|
-
buff.writeIndentedLines(code %
|
|
437
|
+
buff.writeIndentedLines(code % params)
|
|
410
438
|
|
|
411
439
|
# Return True if start test was written
|
|
412
440
|
return buff.indentLevel - startIndent
|
|
413
441
|
|
|
414
|
-
def writeStartTestCodeJS(self, buff):
|
|
442
|
+
def writeStartTestCodeJS(self, buff, extra=""):
|
|
415
443
|
"""Test whether we need to start
|
|
444
|
+
|
|
445
|
+
Parameters
|
|
446
|
+
----------
|
|
447
|
+
buff : io.StringIO
|
|
448
|
+
Text buffer to write code to.
|
|
449
|
+
extra : str
|
|
450
|
+
Additional conditions to check, including any boolean operators (and, or, etc.). Use
|
|
451
|
+
`%(key)s` syntax to insert the values of any necessary params. Default is an empty
|
|
452
|
+
string.
|
|
416
453
|
"""
|
|
454
|
+
# create copy of params dict so we can change stuff without harm
|
|
455
|
+
params = self.params.copy()
|
|
456
|
+
|
|
417
457
|
# Get starting indent level
|
|
418
458
|
startIndent = buff.indentLevel
|
|
419
459
|
|
|
420
|
-
if
|
|
421
|
-
|
|
422
|
-
|
|
460
|
+
if params['startVal'].val in ('', None, -1, 'None'):
|
|
461
|
+
if extra:
|
|
462
|
+
# if we have extra and no stop condition, extra is the only stop condition
|
|
463
|
+
params['startType'] = params['startType'].copy()
|
|
464
|
+
params['startVal'] = params['startVal'].copy()
|
|
465
|
+
params['startType'].val = "condition"
|
|
466
|
+
params['startVal'].val = "False"
|
|
467
|
+
else:
|
|
468
|
+
# if we just have no stop time, don't write stop code
|
|
469
|
+
return buff.indentLevel - startIndent
|
|
423
470
|
|
|
424
|
-
params
|
|
425
|
-
if self.params['startType'].val == 'time (s)':
|
|
471
|
+
if params['startType'].val == 'time (s)':
|
|
426
472
|
# if startVal is an empty string then set to be 0.0
|
|
427
|
-
if (
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
elif
|
|
436
|
-
code = (
|
|
437
|
-
|
|
473
|
+
if (
|
|
474
|
+
isinstance(params['startVal'].val, str)
|
|
475
|
+
and not params['startVal'].val.strip()
|
|
476
|
+
):
|
|
477
|
+
params['startVal'].val = '0.0'
|
|
478
|
+
code = (
|
|
479
|
+
"if (t >= %(startVal)s && %(name)s.status === PsychoJS.Status.NOT_STARTED"
|
|
480
|
+
)
|
|
481
|
+
elif params['startType'].val == 'frame N':
|
|
482
|
+
code = (
|
|
483
|
+
"if (frameN >= %(startVal)s && %(name)s.status === PsychoJS.Status.NOT_STARTED"
|
|
484
|
+
)
|
|
485
|
+
elif params['startType'].val == 'condition':
|
|
486
|
+
code = (
|
|
487
|
+
"if ((%(startVal)s) && %(name)s.status === PsychoJS.Status.NOT_STARTED"
|
|
488
|
+
)
|
|
438
489
|
else:
|
|
439
|
-
msg = f"Not a known startType (
|
|
490
|
+
msg = f"Not a known startType (%(startVal)s) for %(name)s"
|
|
440
491
|
raise CodeGenerationException(msg)
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
492
|
+
# add any other conditions and finish the statement
|
|
493
|
+
if extra and not extra.startswith(" "):
|
|
494
|
+
extra = " " + extra
|
|
495
|
+
code += f"{extra}) {{\n"
|
|
496
|
+
# write if statement and indent
|
|
497
|
+
buff.writeIndentedLines(code % params)
|
|
444
498
|
buff.setIndentLevel(+1, relative=True)
|
|
499
|
+
|
|
445
500
|
code = (f"// keep track of start time/frame for later\n"
|
|
446
501
|
f"{params['name']}.tStart = t; // (not accounting for frame time here)\n"
|
|
447
502
|
f"{params['name']}.frameNStart = frameN; // exact frame index\n\n")
|
|
@@ -450,7 +505,7 @@ class BaseComponent:
|
|
|
450
505
|
# Return True if start test was written
|
|
451
506
|
return buff.indentLevel - startIndent
|
|
452
507
|
|
|
453
|
-
def writeStopTestCode(self, buff):
|
|
508
|
+
def writeStopTestCode(self, buff, extra=""):
|
|
454
509
|
"""
|
|
455
510
|
Test whether we need to stop (if there is a stop time at all)
|
|
456
511
|
|
|
@@ -461,22 +516,39 @@ class BaseComponent:
|
|
|
461
516
|
code = (
|
|
462
517
|
"%(name)s.attribute = value\n"
|
|
463
518
|
)
|
|
464
|
-
buff.writeIndentedLines(code %
|
|
519
|
+
buff.writeIndentedLines(code % params)
|
|
465
520
|
buff.setIndentLevel(-indented, relative=True)
|
|
466
521
|
```
|
|
522
|
+
|
|
523
|
+
Parameters
|
|
524
|
+
----------
|
|
525
|
+
buff : io.StringIO
|
|
526
|
+
Text buffer to write code to.
|
|
527
|
+
extra : str
|
|
528
|
+
Additional conditions to check, including any boolean operators (and, or, etc.). Use
|
|
529
|
+
`%(key)s` syntax to insert the values of any necessary params. Default is an empty
|
|
530
|
+
string.
|
|
467
531
|
"""
|
|
532
|
+
# create copy of params dict so we can change stuff without harm
|
|
533
|
+
params = self.params.copy()
|
|
468
534
|
|
|
469
535
|
# Get starting indent level
|
|
470
536
|
startIndent = buff.indentLevel
|
|
471
537
|
|
|
472
|
-
if
|
|
473
|
-
|
|
474
|
-
|
|
538
|
+
if params['stopVal'].val in ('', None, -1, 'None'):
|
|
539
|
+
if extra:
|
|
540
|
+
# if we have extra and no stop condition, extra is the only stop condition
|
|
541
|
+
params['stopType'] = params['stopType'].copy()
|
|
542
|
+
params['stopVal'] = params['stopVal'].copy()
|
|
543
|
+
params['stopType'].val = "condition"
|
|
544
|
+
params['stopVal'].val = "False"
|
|
545
|
+
else:
|
|
546
|
+
# if we just have no stop time, don't write stop code
|
|
547
|
+
return buff.indentLevel - startIndent
|
|
475
548
|
|
|
476
549
|
# Newline
|
|
477
550
|
buff.writeIndentedLines("\n")
|
|
478
551
|
|
|
479
|
-
params = self.params
|
|
480
552
|
# add handy comment
|
|
481
553
|
code = (
|
|
482
554
|
"# if %(name)s is stopping this frame...\n"
|
|
@@ -487,39 +559,54 @@ class BaseComponent:
|
|
|
487
559
|
buff.setIndentLevel(+1, relative=True)
|
|
488
560
|
|
|
489
561
|
# If start time is blank ad stop is a duration, raise alert
|
|
490
|
-
if
|
|
491
|
-
if ('startVal' not in
|
|
492
|
-
alerttools.alert(4120, strFields={'component':
|
|
493
|
-
|
|
494
|
-
if
|
|
495
|
-
code = (
|
|
496
|
-
|
|
497
|
-
|
|
562
|
+
if params['stopType'] in ('duration (s)', 'duration (frames)'):
|
|
563
|
+
if ('startVal' not in params) or (params['startVal'] in ("", "None", None)):
|
|
564
|
+
alerttools.alert(4120, strFields={'component': params['name']})
|
|
565
|
+
|
|
566
|
+
if params['stopType'].val == 'time (s)':
|
|
567
|
+
code = (
|
|
568
|
+
"# is it time to stop? (based on local clock)\n"
|
|
569
|
+
"if tThisFlip > %(stopVal)s-frameTolerance"
|
|
570
|
+
)
|
|
498
571
|
# duration in time (s)
|
|
499
|
-
elif (
|
|
500
|
-
code = (
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
elif
|
|
505
|
-
code =
|
|
506
|
-
|
|
507
|
-
|
|
572
|
+
elif (params['stopType'].val == 'duration (s)'):
|
|
573
|
+
code = (
|
|
574
|
+
"# is it time to stop? (based on global clock, using actual start)\n"
|
|
575
|
+
"if tThisFlipGlobal > %(name)s.tStartRefresh + %(stopVal)s-frameTolerance"
|
|
576
|
+
)
|
|
577
|
+
elif params['stopType'].val == 'duration (frames)':
|
|
578
|
+
code = (
|
|
579
|
+
"if frameN >= (%(name)s.frameNStart + %(stopVal)s)"
|
|
580
|
+
)
|
|
581
|
+
elif params['stopType'].val == 'frame N':
|
|
582
|
+
code = (
|
|
583
|
+
"if frameN >= %(stopVal)s"
|
|
584
|
+
)
|
|
585
|
+
elif params['stopType'].val == 'condition':
|
|
586
|
+
code = (
|
|
587
|
+
"if bool(%(stopVal)s)"
|
|
588
|
+
)
|
|
508
589
|
else:
|
|
509
|
-
msg = (
|
|
510
|
-
|
|
590
|
+
msg = (
|
|
591
|
+
"Didn't write any stop line for startType=%(startType)s, stopType=%(stopType)s"
|
|
592
|
+
)
|
|
511
593
|
raise CodeGenerationException(msg)
|
|
512
|
-
|
|
513
|
-
|
|
594
|
+
# add any other conditions and finish the statement
|
|
595
|
+
if extra and not extra.startswith(" "):
|
|
596
|
+
extra = " " + extra
|
|
597
|
+
code += f"{extra}:\n"
|
|
598
|
+
# write if statement and indent
|
|
599
|
+
buff.writeIndentedLines(code % params)
|
|
514
600
|
buff.setIndentLevel(+1, relative=True)
|
|
601
|
+
|
|
515
602
|
code = (f"# keep track of stop time/frame for later\n"
|
|
516
603
|
f"{params['name']}.tStop = t # not accounting for scr refresh\n"
|
|
517
604
|
f"{params['name']}.tStopRefresh = tThisFlipGlobal # on global time\n"
|
|
518
605
|
f"{params['name']}.frameNStop = frameN # exact frame index\n"
|
|
519
606
|
)
|
|
520
|
-
if
|
|
607
|
+
if params['saveStartStop']:
|
|
521
608
|
code += f"# add timestamp to datafile\n"
|
|
522
|
-
if 'syncScreenRefresh' in
|
|
609
|
+
if 'syncScreenRefresh' in params and params['syncScreenRefresh']:
|
|
523
610
|
# use the time we *detect* the flip (in the future)
|
|
524
611
|
code += f"thisExp.timestampOnFlip(win, '{params['name']}.stopped')\n"
|
|
525
612
|
else:
|
|
@@ -542,62 +629,94 @@ class BaseComponent:
|
|
|
542
629
|
"# update status\n"
|
|
543
630
|
"%(name)s.status = FINISHED\n"
|
|
544
631
|
)
|
|
545
|
-
buff.writeIndentedLines(code %
|
|
632
|
+
buff.writeIndentedLines(code % params)
|
|
546
633
|
|
|
547
634
|
# Return True if stop test was written
|
|
548
635
|
return buff.indentLevel - startIndent
|
|
549
636
|
|
|
550
|
-
def writeStopTestCodeJS(self, buff):
|
|
637
|
+
def writeStopTestCodeJS(self, buff, extra=""):
|
|
551
638
|
"""Test whether we need to stop
|
|
639
|
+
|
|
640
|
+
Parameters
|
|
641
|
+
----------
|
|
642
|
+
buff : io.StringIO
|
|
643
|
+
Text buffer to write code to.
|
|
644
|
+
extra : str
|
|
645
|
+
Additional conditions to check, including any boolean operators (and, or, etc.). Use
|
|
646
|
+
`%(key)s` syntax to insert the values of any necessary params. Default is an empty
|
|
647
|
+
string.
|
|
552
648
|
"""
|
|
649
|
+
# create copy of params dict so we can change stuff without harm
|
|
650
|
+
params = self.params.copy()
|
|
651
|
+
|
|
553
652
|
# Get starting indent level
|
|
554
653
|
startIndent = buff.indentLevel
|
|
555
654
|
|
|
556
|
-
if
|
|
557
|
-
|
|
558
|
-
|
|
655
|
+
if params['stopVal'].val in ('', None, -1, 'None'):
|
|
656
|
+
if extra:
|
|
657
|
+
# if we have extra and no stop time, extra is only stop condition
|
|
658
|
+
params['stopType'] = params['stopType'].copy()
|
|
659
|
+
params['stopVal'] = params['stopVal'].copy()
|
|
660
|
+
params['stopType'].val = "condition"
|
|
661
|
+
params['stopVal'].val = "false"
|
|
662
|
+
else:
|
|
663
|
+
# if we just have no stop time, don't write stop code
|
|
664
|
+
return buff.indentLevel - startIndent
|
|
559
665
|
|
|
560
|
-
params
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
666
|
+
if params['stopType'].val == 'time (s)':
|
|
667
|
+
code = (
|
|
668
|
+
"frameRemains = %(stopVal)s - psychoJS.window.monitorFramePeriod * 0.75;"
|
|
669
|
+
"// most of one frame period left\n"
|
|
670
|
+
"if ((%(name)s.status === PsychoJS.Status.STARTED || %(name)s.status === "
|
|
671
|
+
"PsychoJS.Status.FINISHED) && t >= frameRemains"
|
|
672
|
+
)
|
|
567
673
|
# duration in time (s)
|
|
568
|
-
elif (
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
674
|
+
elif (
|
|
675
|
+
params['stopType'].val == 'duration (s)'
|
|
676
|
+
and params['startType'].val == 'time (s)'
|
|
677
|
+
):
|
|
678
|
+
code = (
|
|
679
|
+
"frameRemains = %(startVal)s + %(stopVal)s - psychoJS.window.monitorFramePeriod "
|
|
680
|
+
"* 0.75;"
|
|
681
|
+
"// most of one frame period left\n"
|
|
682
|
+
"if (%(name)s.status === PsychoJS.Status.STARTED && t >= frameRemains"
|
|
683
|
+
)
|
|
575
684
|
# start at frame and end with duratio (need to use approximate)
|
|
576
|
-
elif
|
|
577
|
-
code = (
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
685
|
+
elif params['stopType'].val == 'duration (s)':
|
|
686
|
+
code = (
|
|
687
|
+
"if (%(name)s.status === PsychoJS.Status.STARTED && t >= (%(name)s.tStart + "
|
|
688
|
+
"%(stopVal)s)"
|
|
689
|
+
)
|
|
690
|
+
elif params['stopType'].val == 'duration (frames)':
|
|
691
|
+
code = (
|
|
692
|
+
"if (%(name)s.status === PsychoJS.Status.STARTED && frameN >= "
|
|
693
|
+
"(%(name)s.frameNStart + %(stopVal)s)"
|
|
694
|
+
)
|
|
695
|
+
elif params['stopType'].val == 'frame N':
|
|
696
|
+
code = (
|
|
697
|
+
"if (%(name)s.status === PsychoJS.Status.STARTED && frameN >= %(stopVal)s"
|
|
698
|
+
)
|
|
699
|
+
elif params['stopType'].val == 'condition':
|
|
700
|
+
code = (
|
|
701
|
+
"if (%(name)s.status === PsychoJS.Status.STARTED && Boolean(%(stopVal)s)"
|
|
702
|
+
)
|
|
588
703
|
else:
|
|
589
|
-
msg = (
|
|
590
|
-
|
|
591
|
-
|
|
704
|
+
msg = (
|
|
705
|
+
"Didn't write any stop line for startType=%(startType)s, stopType=%(stopType)s"
|
|
706
|
+
)
|
|
592
707
|
raise CodeGenerationException(msg)
|
|
593
|
-
|
|
594
|
-
|
|
708
|
+
# add any other conditions and finish the statement
|
|
709
|
+
if extra and not extra.startswith(" "):
|
|
710
|
+
extra = " " + extra
|
|
711
|
+
code += f"{extra}) {{\n"
|
|
712
|
+
# write if statement and indent
|
|
713
|
+
buff.writeIndentedLines(code % params)
|
|
595
714
|
buff.setIndentLevel(+1, relative=True)
|
|
596
715
|
|
|
597
716
|
# Return True if stop test was written
|
|
598
717
|
return buff.indentLevel - startIndent
|
|
599
718
|
|
|
600
|
-
def writeActiveTestCode(self, buff):
|
|
719
|
+
def writeActiveTestCode(self, buff, extra=""):
|
|
601
720
|
"""
|
|
602
721
|
Test whether component is started and has not finished.
|
|
603
722
|
|
|
@@ -611,25 +730,41 @@ class BaseComponent:
|
|
|
611
730
|
buff.writeIndentedLines(code % self.params)
|
|
612
731
|
self.exitActiveTest(buff)
|
|
613
732
|
```
|
|
733
|
+
|
|
734
|
+
Parameters
|
|
735
|
+
----------
|
|
736
|
+
buff : io.StringIO
|
|
737
|
+
Text buffer to write code to.
|
|
738
|
+
extra : str
|
|
739
|
+
Additional conditions to check, including any boolean operators (and, or, etc.). Use
|
|
740
|
+
`%(key)s` syntax to insert the values of any necessary params. Default is an empty
|
|
741
|
+
string.
|
|
614
742
|
"""
|
|
743
|
+
# create copy of params dict so we can change stuff without harm
|
|
744
|
+
params = self.params.copy()
|
|
745
|
+
|
|
615
746
|
# Newline
|
|
616
747
|
buff.writeIndentedLines("\n")
|
|
617
748
|
# Get starting indent level
|
|
618
749
|
startIndent = buff.indentLevel
|
|
619
750
|
|
|
620
|
-
#
|
|
751
|
+
# construct if statement
|
|
621
752
|
code = (
|
|
622
753
|
"# if %(name)s is active this frame...\n"
|
|
623
|
-
"if %(name)s.status == STARTED
|
|
754
|
+
"if %(name)s.status == STARTED"
|
|
624
755
|
)
|
|
625
|
-
|
|
756
|
+
# add any other conditions and finish the statement
|
|
757
|
+
if extra and not extra.startswith(" "):
|
|
758
|
+
extra = " " + extra
|
|
759
|
+
code += f"{extra}:\n"
|
|
760
|
+
buff.writeIndentedLines(code % params)
|
|
626
761
|
# Indent
|
|
627
762
|
buff.setIndentLevel(+1, relative=True)
|
|
628
763
|
# Write param updates (if needed)
|
|
629
764
|
code = (
|
|
630
765
|
"# update params\n"
|
|
631
766
|
)
|
|
632
|
-
buff.writeIndentedLines(code %
|
|
767
|
+
buff.writeIndentedLines(code % params)
|
|
633
768
|
if self.checkNeedToUpdate('set every frame'):
|
|
634
769
|
self.writeParamUpdates(buff, 'set every frame')
|
|
635
770
|
else:
|
|
@@ -639,7 +774,7 @@ class BaseComponent:
|
|
|
639
774
|
buff.writeIndentedLines(code)
|
|
640
775
|
return buff.indentLevel - startIndent
|
|
641
776
|
|
|
642
|
-
def writeActiveTestCodeJS(self, buff):
|
|
777
|
+
def writeActiveTestCodeJS(self, buff, extra=""):
|
|
643
778
|
"""
|
|
644
779
|
Test whether component is started and has not finished.
|
|
645
780
|
|
|
@@ -652,20 +787,36 @@ class BaseComponent:
|
|
|
652
787
|
)
|
|
653
788
|
self.exitActiveTestJS(buff)
|
|
654
789
|
```
|
|
790
|
+
|
|
791
|
+
Parameters
|
|
792
|
+
----------
|
|
793
|
+
buff : io.StringIO
|
|
794
|
+
Text buffer to write code to.
|
|
795
|
+
extra : str
|
|
796
|
+
Additional conditions to check, including any boolean operators (and, or, etc.). Use
|
|
797
|
+
`%(key)s` syntax to insert the values of any necessary params. Default is an empty
|
|
798
|
+
string.
|
|
655
799
|
"""
|
|
800
|
+
# create copy of params dict so we can change stuff without harm
|
|
801
|
+
params = self.params.copy()
|
|
802
|
+
|
|
656
803
|
# Get starting indent level
|
|
657
804
|
startIndent = buff.indentLevel
|
|
658
805
|
|
|
659
806
|
# Newline
|
|
660
807
|
buff.writeIndentedLines("\n")
|
|
661
808
|
|
|
662
|
-
#
|
|
809
|
+
# construct if statement
|
|
663
810
|
code = (
|
|
664
811
|
"// if %(name)s is active this frame...\n"
|
|
665
|
-
"if (%(name)s.status == STARTED
|
|
812
|
+
"if (%(name)s.status == STARTED"
|
|
666
813
|
)
|
|
667
|
-
|
|
668
|
-
|
|
814
|
+
# add any other conditions and finish the statement
|
|
815
|
+
if extra and not extra.startswith(" "):
|
|
816
|
+
extra = " " + extra
|
|
817
|
+
code += f"{extra}) {{\n"
|
|
818
|
+
# write if statement and indent
|
|
819
|
+
buff.writeIndentedLines(code % params)
|
|
669
820
|
buff.setIndentLevel(+1, relative=True)
|
|
670
821
|
|
|
671
822
|
if self.checkNeedToUpdate('set every frame'):
|
|
@@ -673,7 +824,7 @@ class BaseComponent:
|
|
|
673
824
|
code = (
|
|
674
825
|
"// update params\n"
|
|
675
826
|
)
|
|
676
|
-
buff.writeIndentedLines(code %
|
|
827
|
+
buff.writeIndentedLines(code % params)
|
|
677
828
|
self.writeParamUpdates(buff, 'set every frame')
|
|
678
829
|
|
|
679
830
|
return buff.indentLevel - startIndent
|
|
@@ -821,11 +972,6 @@ class BaseComponent:
|
|
|
821
972
|
elif paramName == 'lineColor':
|
|
822
973
|
buff.writeIndented(f"{compName}.setLineColor(new util.Color({params['lineColor']})")
|
|
823
974
|
buff.write(f"{loggingStr}){endStr}\n")
|
|
824
|
-
elif paramName == 'sound':
|
|
825
|
-
stopVal = params['stopVal']
|
|
826
|
-
if stopVal in ['', None, -1, 'None']:
|
|
827
|
-
stopVal = '-1'
|
|
828
|
-
buff.writeIndented(f"{compName}.setSound({params['sound']}, secs={stopVal}){endStr}\n")
|
|
829
975
|
elif paramName == 'emotiv_marker_label' or paramName == "emotiv_marker_value" or paramName == "emotiv_stop_marker":
|
|
830
976
|
# This allows the eeg_marker to be updated by a code component or a conditions file
|
|
831
977
|
# There is no setMarker_label or setMarker_value function in the eeg_marker object
|
|
@@ -886,7 +1032,7 @@ class BaseComponent:
|
|
|
886
1032
|
|
|
887
1033
|
return duration, numericStop
|
|
888
1034
|
|
|
889
|
-
def getStartAndDuration(self):
|
|
1035
|
+
def getStartAndDuration(self, params=None):
|
|
890
1036
|
"""Determine the start and duration of the stimulus
|
|
891
1037
|
purely for Routine rendering purposes in the app (does not affect
|
|
892
1038
|
actual drawing during the experiment)
|
|
@@ -895,7 +1041,16 @@ class BaseComponent:
|
|
|
895
1041
|
|
|
896
1042
|
nonSlipSafe indicates that the component's duration is a known fixed
|
|
897
1043
|
value and can be used in non-slip global clock timing (e.g for fMRI)
|
|
1044
|
+
|
|
1045
|
+
Parameters
|
|
1046
|
+
----------
|
|
1047
|
+
params : dict[Param]
|
|
1048
|
+
Dict of params to use. If None, will use the values in `self.params`.
|
|
898
1049
|
"""
|
|
1050
|
+
# if not given any params, use from self
|
|
1051
|
+
if params is None:
|
|
1052
|
+
params = self.params
|
|
1053
|
+
|
|
899
1054
|
# If has a start, calculate it
|
|
900
1055
|
if 'startType' in self.params:
|
|
901
1056
|
startTime, numericStart = self.getStart()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|