diff --git a/.changeset/pretty-wolves-type.md b/.changeset/pretty-wolves-type.md new file mode 100644 index 0000000..8836a52 --- /dev/null +++ b/.changeset/pretty-wolves-type.md @@ -0,0 +1,6 @@ +--- +"@jspsych/metadata-cli": minor +"@jspsych/metadata": patch +--- + +Updating metadata-cli to implement Psych-DS validator and small build changes to metadata module diff --git a/.gitignore b/.gitignore index c6bba59..ec961c2 100644 --- a/.gitignore +++ b/.gitignore @@ -128,3 +128,6 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +# DS Store +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index bc55acb..ce520b5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ -# metadata -Library and CLI tool to generate Psych-DS compliant metadata for jsPsych experiments +# Psych-DS and metadata + +## What is Psych-DS and metadata? + +Psych-DS is a template data schema to standardize the representation of data files for common Psychology and Cognitive Science experiments. This representation aims to help facilate data sharing by making data more understandable using common structures and metadata files that describe the data. Metadata files describe the data and including relevant information about the types of variables present as well as what each file represents. + +## How does it relate to Jspsych? + +JsPsych is one software among many to begin implementing this data standard and has many different tools to generate metadata automatically from data files. + +# Creating metadata and Psych-DS directories + +## How do I create a metadata file and organize my project according to Psych-DS? + +There are many different ways to generate metadata. Each tool has it's own pros and cons, + +# Developer Roadmap diff --git a/dev/jspsych-metadata-generated/CHANGES.md b/dev/jspsych-metadata-generated/CHANGES.md new file mode 100644 index 0000000..c105f4d --- /dev/null +++ b/dev/jspsych-metadata-generated/CHANGES.md @@ -0,0 +1 @@ +For version tracking - if the dataset is updated after being uploaded/shared, changes (with human-readable descriptions) may be recorded here. \ No newline at end of file diff --git a/dev/jspsych-metadata-generated/README.md b/dev/jspsych-metadata-generated/README.md new file mode 100644 index 0000000..9d52faa --- /dev/null +++ b/dev/jspsych-metadata-generated/README.md @@ -0,0 +1,2 @@ +# My Project + Human-readable description of the project and dataset. \ No newline at end of file diff --git a/dev/jspsych-metadata-generated/data/study-exampleStudy_responsetype-audioSlider_data.csv b/dev/jspsych-metadata-generated/data/study-exampleStudy_responsetype-audioSlider_data.csv new file mode 100644 index 0000000..a708e18 --- /dev/null +++ b/dev/jspsych-metadata-generated/data/study-exampleStudy_responsetype-audioSlider_data.csv @@ -0,0 +1,6 @@ +"success","timeout","failed_images","failed_audio","failed_video","trial_type","trial_index","plugin_version","time_elapsed","rt","stimulus","response","slider_start" +"true","false","[]","[]","[]","preload","0","2.0.0","26","","","","" +"","","","","","html-button-response","1","2.0.0","1200","920","
Some browsers now require the user to interact with a page before it can play audio. Clicking the button below counts as an interaction.
Be aware of this when planning audio experiments if you want the first trial to include audio.
Trial data:
\n[\n {\n \"task\": \"draw\",\n \"rt\": 1995,\n \"stimulus\": \"\",\n \"response\": 0,\n \"trial_type\": \"html-button-response\",\n \"trial_index\": 0,\n \"plugin_version\": \"2.0.0\",\n \"time_elapsed\": 1997,\n \"extension_type\": [\n \"mouse-tracking\"\n ],\n \"extension_version\": [\n \"1.1.0\"\n ],\n \"mouse_tracking_data\": [\n {\n \"x\": 503,\n \"y\": 272,\n \"t\": 1364,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 526,\n \"y\": 285,\n \"t\": 1367,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 583,\n \"y\": 315,\n \"t\": 1380,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 670,\n \"y\": 362,\n \"t\": 1397,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 777,\n \"y\": 417,\n \"t\": 1414,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 844,\n \"y\": 457,\n \"t\": 1430,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 914,\n \"y\": 501,\n \"t\": 1447,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 950,\n \"y\": 525,\n \"t\": 1464,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 980,\n \"y\": 547,\n \"t\": 1480,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 988,\n \"y\": 557,\n \"t\": 1497,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 996,\n \"y\": 566,\n \"t\": 1514,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 997,\n \"y\": 569,\n \"t\": 1530,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 997,\n \"y\": 570,\n \"t\": 1547,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 993,\n \"y\": 573,\n \"t\": 1564,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 983,\n \"y\": 577,\n \"t\": 1580,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 967,\n \"y\": 580,\n \"t\": 1597,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 959,\n \"y\": 583,\n \"t\": 1614,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 948,\n \"y\": 587,\n \"t\": 1630,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 942,\n \"y\": 590,\n \"t\": 1647,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 937,\n \"y\": 592,\n \"t\": 1664,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 933,\n \"y\": 594,\n \"t\": 1680,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 929,\n \"y\": 595,\n \"t\": 1697,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 925,\n \"y\": 595,\n \"t\": 1714,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 917,\n \"y\": 595,\n \"t\": 1730,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 906,\n \"y\": 594,\n \"t\": 1747,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 897,\n \"y\": 593,\n \"t\": 1764,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 869,\n \"y\": 593,\n \"t\": 1780,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 851,\n \"y\": 593,\n \"t\": 1797,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 840,\n \"y\": 593,\n \"t\": 1814,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 830,\n \"y\": 593,\n \"t\": 1830,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 824,\n \"y\": 593,\n \"t\": 1847,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 820,\n \"y\": 593,\n \"t\": 1864,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 818,\n \"y\": 593,\n \"t\": 1881,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 818,\n \"y\": 593,\n \"t\": 1897,\n \"event\": \"mousemove\"\n },\n {\n \"x\": 818,\n \"y\": 593,\n \"t\": 1914,\n \"event\": \"mousemove\"\n }\n ],\n \"mouse_tracking_targets\": {\n \"#target\": {\n \"x\": 465.984375,\n \"y\": 170.046875,\n \"width\": 250,\n \"height\": 250,\n \"top\": 170.046875,\n \"right\": 715.984375,\n \"bottom\": 420.046875,\n \"left\": 465.984375\n }\n }\n }\n]","response":0,"trial_type":"html-button-response","trial_index":2,"plugin_version":"2.0.0","time_elapsed":55644}]
\ No newline at end of file
diff --git a/dev/jspsych-metadata-generated/data/study-exampleStudy_responsetype-timelineVariables_data.csv b/dev/jspsych-metadata-generated/data/study-exampleStudy_responsetype-timelineVariables_data.csv
new file mode 100644
index 0000000..c784869
--- /dev/null
+++ b/dev/jspsych-metadata-generated/data/study-exampleStudy_responsetype-timelineVariables_data.csv
@@ -0,0 +1,14 @@
+"success","timeout","failed_images","failed_audio","failed_video","trial_type","trial_index","plugin_version","time_elapsed","rt","stimulus","response"
+"true","false","[]","[]","[]","preload","0","2.0.0","5","","",""
+"","","","","","html-keyboard-response","1","2.0.0","1088","null","+
","null" +"","","","","","image-keyboard-response","2","2.0.0","2739","1398","img/happy_face_2.jpg","y" +"","","","","","html-keyboard-response","3","2.0.0","3494","null","+
","null" +"","","","","","image-keyboard-response","4","2.0.0","4002","255","img/happy_face_3.jpg","n" +"","","","","","html-keyboard-response","5","2.0.0","4756","null","+
","null" +"","","","","","image-keyboard-response","6","2.0.0","5073","64","img/happy_face_1.jpg","y" +"","","","","","html-keyboard-response","7","2.0.0","5828","null","+
","null" +"","","","","","image-keyboard-response","8","2.0.0","6462","381","img/happy_face_2.jpg","n" +"","","","","","html-keyboard-response","9","2.0.0","7217","null","+
","null" +"","","","","","image-keyboard-response","10","2.0.0","7639","168","img/happy_face_3.jpg","y" +"","","","","","html-keyboard-response","11","2.0.0","8393","null","+
","null" +"","","","","","image-keyboard-response","12","2.0.0","8697","50","img/happy_face_1.jpg","n" diff --git a/dev/jspsych-metadata-generated/dataset_description.json b/dev/jspsych-metadata-generated/dataset_description.json new file mode 100644 index 0000000..3bbafa1 --- /dev/null +++ b/dev/jspsych-metadata-generated/dataset_description.json @@ -0,0 +1,237 @@ +{ + "name": "title", + "schemaVersion": "Psych-DS 0.4.0", + "@context": "https://schema.org", + "@type": "Dataset", + "description": "Dataset generated using JsPsych", + "randomField": "this is a field", + "author": [ + { + "@type":"Person", + "name": "John", + "givenName": "Johnathan" + } + ], + "variableMeasured": [ + { + "@type": "PropertyValue", + "name": "trial_type", + "description": "The name of the plugin used to run the trial.", + "value": "string", + "levels": [ + "preload", + "html-keyboard-response", + "image-keyboard-response", + "html-button-response", + "audio-slider-response", + "categorize-html", + "initialize-camera" + ] + }, + { + "@type": "PropertyValue", + "name": "trial_index", + "description": "The index of the current trial across the whole experiment.", + "value": "numeric", + "minValue": 0, + "maxValue": 16 + }, + { + "@type": "PropertyValue", + "name": "time_elapsed", + "description": "The number of milliseconds between the start of the experiment and when the trial ended.", + "value": "numeric", + "minValue": 5, + "maxValue": 55644 + }, + { + "@type": "PropertyValue", + "name": "success", + "description": "If `true`, then all files loaded successfully within the `max_load_time`. If `false`, then one or * more file requests returned a failure and/or the file loading did not complete within the `max_load_time` duration.", + "value": "boolean", + "levels": [ + true + ] + }, + { + "@type": "PropertyValue", + "name": "timeout", + "description": "If `true`, then the files did not finish loading within the `max_load_time` duration. * If `false`, then the file loading did not timeout. Note that when the preload trial does not timeout * (`timeout: false`), it is still possible for loading to fail (`success: false`). This happens if * one or more files fails to load and all file requests trigger either a success or failure event before * the `max_load_time` duration.", + "value": "boolean", + "levels": [ + false + ] + }, + { + "@type": "PropertyValue", + "name": "failed_images", + "description": "One or more image file paths that produced a loading failure before the trial ended.", + "value": "object", + "levels": [ + "[]" + ] + }, + { + "@type": "PropertyValue", + "name": "failed_audio", + "description": "One or more audio file paths that produced a loading failure before the trial ended.", + "value": "object", + "levels": [ + "[]" + ] + }, + { + "@type": "PropertyValue", + "name": "failed_video", + "description": "One or more video file paths that produced a loading failure before the trial ended.", + "value": "object", + "levels": [ + "[]" + ] + }, + { + "@type": "PropertyValue", + "name": "plugin_version", + "description": "unknown", + "value": "string", + "levels": [ + "1.1.3", + "2.0.0" + ] + }, + { + "@type": "PropertyValue", + "name": "stimulus", + "description": { + "image-keyboard-response": "The path of the image that was displayed.", + "html-keyboard-response, html-button-response": "The HTML content that was displayed on the screen.", + "audio-slider-response": "The path of the audio file that was played.", + "categorize-html": "Either the path to the image file or the string containing the HTML formatted content that the participant saw on this trial." + }, + "value": "string", + "levels": [ + "+
", + "img/happy_face_1.jpg", + "img/happy_face_2.jpg", + "img/happy_face_3.jpg", + "img/happy_face_4.jpg", + "+
Some browsers now...", + "sound/speech_joke.mp3", + "sound/speech_red.mp3", + "sound/hammer.mp3", + "