From b4e2fd8e47b82b05452e24743d3fcb4d90af9a7e Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 26 Jul 2020 10:08:45 +0200 Subject: [PATCH 01/10] add more info on schema description --- docs/30_schema.md | 40 +++++++++++++++++++++++++++++++++++----- docs/index.md | 6 ++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/docs/30_schema.md b/docs/30_schema.md index 02d15f2b4f..550bf605ae 100644 --- a/docs/30_schema.md +++ b/docs/30_schema.md @@ -1,5 +1,35 @@ # The schema +## Overview + +A simplistic way to describe the Reprochema is to say it is organized in a hierarchical manner with roughly 3 levels with a schema describing each level. + +1. The highest level is the `protocol` level that originally define a set of assessments or questionnaires to be +included in a given study. +This schema is defined by the [Protocol schema](https://raw.githubusercontent.com/ReproNim/reproschema/master/terms/Protocol). +1. The second level is the `activity` level that describe a given questionnaire. This level would describe all the questions of this assessment: for example all the items of the Edinburgh handedness inventory would constitute one activity. +This schema is defined by the [Activity schema](https://raw.githubusercontent.com/ReproNim/reproschema/master/terms/Activity). +1. At a lower level we have the `item` level where each `item` represents a question from a given assessment. +On top of containing the text of the actual question, the schema at this level can contain additional +information such as the expected format of the item for the user interface: a boolean +(if this is a yes/no question), a multiple choice (with a list of the response choices), +a float or an integer (if a numerical value is expected)... +This schema is defined by the [Field schema](https://raw.githubusercontent.com/ReproNim/reproschema/master/terms/Field). + + + +You can see an example of those in the [examples folder](https://github.com/ReproNim/reproschema/examples) + +There are in fact more levels than this each and each level has its own schema: +- all of the schemas can be found in the [`terms` folder](https://github.com/ReproNim/reproschema/terms) +- the Reproschema actually allows for a more complex level nesting than the one described above (e.g you can have an `activity` wihtin an `activity`) +- all the properties of each level are described below in the [Properties of ReproSchema objects section](#properties-of-reproschema-objects) + +## Detailed description + The core model of ReproSchema was initially derived from the [CEDAR Metadata Model](https://more.metadatacenter.org/tools-training/outreach/cedar-template-model). To accommodate the needs of neuroimaging and other clinical and behavioral protocols and assessments the schema has evolved significantly. These changes @@ -9,7 +39,7 @@ include: We have used schema.org classes and properties where it maps on to the needs of the model and extended the model with NIDM elements to harmonize across ReproNim projects. -1. Allowing for structued nested elements in a schema +1. Allowing for structured nested elements in a schema `Protocol > Activity > [Activity | Field > ResponseOption]`. This nested structure provides a flexible schema to represent nested activities, which are common in biomedical and other domains. @@ -29,10 +59,10 @@ common in biomedical and other domains. │ ... ... -1. Interaction with git/Github or another Web service to deliver a new Protocol, -Activity or Field with a persistent URI, while tracking changes associated with -any of these elements. By making every Field represented through a persistent URI, -a data collection instrument can link the responses to the exact Field that was +1. Interaction with Git/Github or another Web service to deliver a new `protocol`, +`ativity` or `field` with a persistent URI, while tracking changes associated with +any of these elements. By making every `field` represented through a persistent URI, +a data collection instrument can link the responses to the exact `field` that was used. 1. Addition of computable elements that are derived from the values entered by a participant. diff --git a/docs/index.md b/docs/index.md index 708e219283..a120e952e5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,6 +19,12 @@ could save you from a lot of confusion. 😉 - Not sure how the project is organized? Check out the [project structure](./20_project_structure) page. +- Want more details on how the `Reproschema` itself is structured: check out our [schema page](./30_schema) + + + ## Licence Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. From de80928b72a44b012631978528497f004e1a2fce Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 23 Aug 2020 09:34:49 +0200 Subject: [PATCH 02/10] add a how to create a protocol page --- docs/30_schema.md | 2 +- docs/40_create_new_activity_protocol.md | 304 ++++++++++++++++++++++++ docs/img/phq-9_ui.png | Bin 0 -> 48755 bytes mkdocs.yml | 2 +- 4 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 docs/40_create_new_activity_protocol.md create mode 100644 docs/img/phq-9_ui.png diff --git a/docs/30_schema.md b/docs/30_schema.md index 550bf605ae..88bcda4d28 100644 --- a/docs/30_schema.md +++ b/docs/30_schema.md @@ -18,7 +18,7 @@ This schema is defined by the [Field schema](https://raw.githubusercontent.com/R You can see an example of those in the [examples folder](https://github.com/ReproNim/reproschema/examples) diff --git a/docs/40_create_new_activity_protocol.md b/docs/40_create_new_activity_protocol.md new file mode 100644 index 0000000000..3e3c7ae53f --- /dev/null +++ b/docs/40_create_new_activity_protocol.md @@ -0,0 +1,304 @@ +# How can I use reproschema to create my own questionnaire? + +Broadly speaking, there are two ways to create new assessments (`actitivies`) or combinations +of assessments (`protocols`). IF you only have very few items to put in new activity or you simply want to create a protocol that reuses activities that already exist, you can do that manually by editing the files directly. But if you have to create complex activities or protocols, we suggest that for your own sanity and to avoid wasting time in the long run, you look into scripting the creation of your new tools. + +## Manual schema generation + +Here we will show a step by step approach to create a new protocol that includes activities that already exist and how to create a brand new activity. + +## Requirements + +For this tutorial you will be using some other tools to put your work online. Here is what you will need to install or set up. + +- [Git](https://git-scm.com/downloads) +- a [Github account](https://github.com/) +- a "decent" text editor like [atom](https://atom.io/) or [visual studio code](https://code.visualstudio.com/) and we do recommend that you look for extensions or packages that help you deal with json files. + +We don't assume that you have in-depth knowledge of git and github for this tutorial so we will try to provide with commands you need to type when it is required. Similarly, we will provide some of the commands to create directories and files though you could do many of those actions "by hand" with a couple of mouse clicks. + +For Windows users: + +Most of the commands we will provide should work in the command line interface that will come on your computer when you isntall Git. But you could also look into using one the linux sub-system that provide you with Unix command line and that can be easily installed from the app-store on your computer. + +## Context + +To make this a bit less abstract, we will imagine we want to create a new protocol for a new neuroimaging study we are starting to investigate some aspects of linguistic processing is affected in patients with depression. + +So we would want to have a set of questionnaires: +- to assess the severity of the depression of our participants, +- check which participants can go in an MRI scanner, +- estimate the handedness of the participants (because of the language lateralization organization of the brain). + +## Setting the stage + +We first need to create some folders to host the schema that will represent all our questionnaires. + +```bash +# FYI: this is comment and it will not be executed +# if you copy paste it in the command line + +# Creating the directory for the depression neuroimaging study +mkdir depression_nimg_schema + +# Move into the directory +cd depression_nimg_schema +``` + +Now let's create the `protocol` folder, a protocol file named after our study. + +```bash +mkdir protocol +touch protocol/depression_nimg_schema.jsonld +``` + +Ok so now we are ready to start putting some content into those files. + +Open the `depression_nimg_schema.jsonld` with a text editor and add the following content into it. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1" +} +``` + +To explain a bit what all of this means: + +- `@context` gives the URL where we can find the "definitions" of terms used in the reproschema. It is itself a json file that you [can view directly](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic). +- `@type` just says what type of entity this jsonld file describes. In this case it is a `protocol` entity as defined by the reproschema. +- `@id` is the identity of this entity, its unique identifier. + +You can then use the preferred label field and the description to give more human readable ways to describe this entity. + +You must also specify the version of the schema you are using. + +### Landing page + +Let's now take care of adding a landing page to the list of assessments our participants will have to fill in. + +Let's create a markdown readme file in the `protocol` folder. + +```bash +touch protocol/README.md +``` + +Add some content to it just to get things started, like for example + +```markdown +# README + +Hello world +``` + +Now we want to add this file to our protocol and make it the landing page for the english version of this study. So the content of your protocol file should now read like this. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "landingPage": { + "@id": "README.md", + "@language": "en" + } +} +``` + +## Add a first assessment + +OK now we want to add a questionnaire to assess the severity of the depression of our participants. + +The first thing to do is to browse through the [library of assessments](https://github.com/ReproNim/reproschema-library/tree/master/activities) that already exist on the [dedicated repronim repositor](https://github.com/ReproNim/reproschema-library). + +It seems that we can use the [PHQ-9](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1495268/) that self describes as a "Brief Depression Severity Measure". + +The schema that describe the PHQ-9 activity can be found [here](https://github.com/ReproNim/reproschema-library/blob/master/activities/PHQ-9/PHQ9_schema). + +If you want to visualize this activity on its own, you can use the [reproschema-ui](https://www.repronim.org/reproschema-ui/#/). To do that you can point the UI to the **raw** content of this activity. + +To get access to the raw content of that activity you must click on the `Raw` button on github once you have opened its [page](https://github.com/ReproNim/reproschema-library/blob/master/activities/PHQ-9/PHQ9_schema). This will open this URL: [https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema](https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). + +You can then pass the the URL of raw content to the UI using the following template: + +``` +https://www.repronim.org/reproschema-ui/#/activities/0?url=url-to-activity-schema +``` + +So in the case of the PHQ-9, it would give this URL that we copy-paste in a browser to view the activity on its own. + +``` +https://www.repronim.org/reproschema-ui/#/activities/0?url=https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema +``` + +You should now be able to see something like this and browse directly through the content of the activity. + + + + +OK now that we know what we need to add to our protocol, let's add it our schema. + +To do this, the content of your `depression_nimg_schema.jsonld` should now look like this. + +```json +{ + "@context": [ "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + { + "rl": "https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/" + } + ], + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "landingPage": { + "@id": "README.md", + "@language": "en" + }, + "ui": { + "addProperties": [ + {"isAbout": "rl:PHQ-9/PHQ9_schema", + "variableName": "PHQ9_schema", + "prefLabel": {"en": "Depression"} + } + ], + "order": [ + "rl:PHQ-9/PHQ9_schema" + ] + } +} +``` + +Let's just highlight the things that have changed. + +We have added a `ui` and an `order` fields. + +`ui` contains `addProperties` where we will be listing all the assessments that we add to our protocol. + +Each assessment is represented by an activity that is given a `variableName` and a `prefLabel`. The latter will be used in this case as the name to display on the UI in english. + +The field `isAbout` is the URL to point to the schema of that activity. You might notice that `rl:PHQ-9/PHQ9_schema` does not look like a typical URL and clearly does not match the one we fed the UI earlier (https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). Well this is because we have defined, in the `@context` part of our jsonld, that the `rl` from `rl:PHQ-9/PHQ9_schema` will actually stand for `https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/`. This shorthand makes it faster for us to write URL but the UI will know how to `expand` this into an actual URL. + +The field `order` is there to indicate which activity should be presented first, second... + +### Starting to put things online to see how they look + +So now we want to put things online and see how things look. + +To do that we will use Git and Github. + +Let's first initialize a repository in the folder where we have have been working. + +```bash +git init . # the dot signifies the directory where you currently are +``` + +Now we tell git to make a snapshot of the current state of your folder. + +```bash +git add --all # tell git to include all the new changes into the next snapshot + +git commit -m 'add protocol and README' # make a first snapshot of your protocol +``` + +Now to move things to a github repository, you need to go and create an empty repository to host the folder and files you have created. + +The repository should have an URL that resembles this one where `your_user_name` is your actual Github username: + +``` +https://github.com/your_user_name/depression_nimg_schema.git +``` + +You "push" the content of the `depression_nimg_schema` onto the empty "remote" repository you have just created. + +```bash +# tell git about the existence of this new online repository you have just created +git remote add origin https://github.com/your_user_name/depression_nimg_schema.git + +# Transfer the content there +git push -u origin master +``` + +If everything worked normally, you should be able to use the reproschema-ui to visualize your protocol using the following template: + +``` +https://www.repronim.org/reproschema-ui/#/?url=url-to-protocol-schema +``` + +So once again grab the URL of the **raw** content of your protocol and point the UI to it: + +``` +https://www.repronim.org/reproschema-ui/#/?url=https://raw.githubusercontent.com/your_user_name/depression_nimg_schema/master/protocol/depression_nimg_schema.jsonld +``` + +## In you own time: add the thank-you activity + +For practice you can now add another activity to your protocol: one to thank people for their participation. + +You can find it here in the reproschema library. + +https://github.com/ReproNim/reproschema-library/tree/master/activities/ThankYou + +Once you have changed the `depression_nimg_schema.jsonld`, you can update the oneline content with the following git commands. + +```bash +git add --all +git commit -m 'add a thank you activity' +git push +``` + + + \ No newline at end of file diff --git a/docs/img/phq-9_ui.png b/docs/img/phq-9_ui.png new file mode 100644 index 0000000000000000000000000000000000000000..4d41a7085355a7a2a4f13141fc7223e561b8903d GIT binary patch literal 48755 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 Date: Tue, 25 Aug 2020 11:04:58 +0200 Subject: [PATCH 03/10] splitting tutorial in several pages - stub for creating activities and items - add some tips referring to CI and how to use valueConstraints --- docs/40_using_reproschema.md | 31 +++ ..._protocol.md => 41_create_new_protocol.md} | 177 +++++---------- docs/42_create_new_activity.md | 44 ++++ docs/43_tips_to_make_your_life_easier.md | 204 ++++++++++++++++++ mkdocs.yml | 6 +- 5 files changed, 338 insertions(+), 124 deletions(-) create mode 100644 docs/40_using_reproschema.md rename docs/{40_create_new_activity_protocol.md => 41_create_new_protocol.md} (54%) create mode 100644 docs/42_create_new_activity.md create mode 100644 docs/43_tips_to_make_your_life_easier.md diff --git a/docs/40_using_reproschema.md b/docs/40_using_reproschema.md new file mode 100644 index 0000000000..5afb480ec6 --- /dev/null +++ b/docs/40_using_reproschema.md @@ -0,0 +1,31 @@ +# How can I use reproschema to create my own questionnaire? + +Broadly speaking, there are two ways to create new assessments (`actitivies`) or combinations +of assessments (`protocols`). IF you only have very few items to put in new activity or you simply want to create a protocol that reuses activities that already exist, you can do that manually by editing the files directly. But if you have to create complex activities or protocols, we suggest that for your own sanity and to avoid wasting time in the long run, you look into scripting the creation of your new tools. + +## Manual schema generation + +Here we will show a step by step approach to create a new protocol that includes activities that already exist and how to create a brand new activity. + +## Requirements + +For this tutorial you will be using some other tools to put your work online. Here is what you will need to install or set up. + +- [Git](https://git-scm.com/downloads) +- a [Github account](https://github.com/) +- a "decent" text editor like [atom](https://atom.io/) or [visual studio code](https://code.visualstudio.com/) and we do recommend that you look for extensions or packages that help you deal with json files. + +We don't assume that you have in-depth knowledge of Git and Github for this tutorial so we will try to provide with the commands you need to type when it is required. Similarly, we will provide some of the commands to create directories and files though you could do many of those actions "by hand" with a couple of mouse clicks. + +??? "For Windows users" + Most of the commands we will provide should work in the command line interface that will come on your computer when you isntall Git. But you could also look into using one the linux sub-system that provide you with Unix command line and that can be easily installed from the app-store on your computer. + +## Context + +To make this a bit less abstract, we will imagine we want to create a new protocol for a new neuroimaging study we are starting to investigate some aspects of linguistic processing is affected in patients with depression. + +So we would want to have a set of questionnaires: + +- to assess the severity of the depression of our participants, +- check which participants can go in an MRI scanner, +- estimate the handedness of the participants (because of the language lateralization organization of the brain). diff --git a/docs/40_create_new_activity_protocol.md b/docs/41_create_new_protocol.md similarity index 54% rename from docs/40_create_new_activity_protocol.md rename to docs/41_create_new_protocol.md index 3e3c7ae53f..2ba454d90c 100644 --- a/docs/40_create_new_activity_protocol.md +++ b/docs/41_create_new_protocol.md @@ -1,47 +1,17 @@ -# How can I use reproschema to create my own questionnaire? - -Broadly speaking, there are two ways to create new assessments (`actitivies`) or combinations -of assessments (`protocols`). IF you only have very few items to put in new activity or you simply want to create a protocol that reuses activities that already exist, you can do that manually by editing the files directly. But if you have to create complex activities or protocols, we suggest that for your own sanity and to avoid wasting time in the long run, you look into scripting the creation of your new tools. - -## Manual schema generation - -Here we will show a step by step approach to create a new protocol that includes activities that already exist and how to create a brand new activity. - -## Requirements - -For this tutorial you will be using some other tools to put your work online. Here is what you will need to install or set up. - -- [Git](https://git-scm.com/downloads) -- a [Github account](https://github.com/) -- a "decent" text editor like [atom](https://atom.io/) or [visual studio code](https://code.visualstudio.com/) and we do recommend that you look for extensions or packages that help you deal with json files. - -We don't assume that you have in-depth knowledge of git and github for this tutorial so we will try to provide with commands you need to type when it is required. Similarly, we will provide some of the commands to create directories and files though you could do many of those actions "by hand" with a couple of mouse clicks. - -For Windows users: - -Most of the commands we will provide should work in the command line interface that will come on your computer when you isntall Git. But you could also look into using one the linux sub-system that provide you with Unix command line and that can be easily installed from the app-store on your computer. - -## Context - -To make this a bit less abstract, we will imagine we want to create a new protocol for a new neuroimaging study we are starting to investigate some aspects of linguistic processing is affected in patients with depression. - -So we would want to have a set of questionnaires: -- to assess the severity of the depression of our participants, -- check which participants can go in an MRI scanner, -- estimate the handedness of the participants (because of the language lateralization organization of the brain). +# Creating a new protocol ## Setting the stage We first need to create some folders to host the schema that will represent all our questionnaires. ```bash -# FYI: this is comment and it will not be executed +# FYI: this is comment and it will not be executed # if you copy paste it in the command line # Creating the directory for the depression neuroimaging study mkdir depression_nimg_schema -# Move into the directory +# Move into the directory cd depression_nimg_schema ``` @@ -58,13 +28,13 @@ Open the `depression_nimg_schema.jsonld` with a text editor and add the followin ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema", - "prefLabel": "depression neuroimaging study", - "description": "a study on linguistic processing in depression", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1" + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1" } ``` @@ -100,25 +70,28 @@ Now we want to add this file to our protocol and make it the landing page for th ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema", - "prefLabel": "depression neuroimaging study", - "description": "a study on linguistic processing in depression", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "landingPage": { - "@id": "README.md", - "@language": "en" - } + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "landingPage": { + "@id": "README.md", + "@language": "en" + } } ``` +??? "A note about relative paths" + Reproschema allows for the use of relative paths which means that in the example above the landing page `@id` being "README.md" means that the `README.md` and `depression_nimg_schema` are in the same folder. If the `README.md` had been in the parent directory, the `@id` of the `landingPage` section would have read `"@id": "../README.md"`. + ## Add a first assessment OK now we want to add a questionnaire to assess the severity of the depression of our participants. -The first thing to do is to browse through the [library of assessments](https://github.com/ReproNim/reproschema-library/tree/master/activities) that already exist on the [dedicated repronim repositor](https://github.com/ReproNim/reproschema-library). +The first thing to do is to browse through the [library of assessments](https://github.com/ReproNim/reproschema-library/tree/master/activities) that already exist on the [dedicated repronim repository](https://github.com/ReproNim/reproschema-library). It seems that we can use the [PHQ-9](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1495268/) that self describes as a "Brief Depression Severity Measure". @@ -147,39 +120,38 @@ src="../img/phq-9_ui.png" alt="phq-9_ui.png" style="width: 700px; height: auto; display: block; margin-left: auto; margin-right: auto;"/> - OK now that we know what we need to add to our protocol, let's add it our schema. To do this, the content of your `depression_nimg_schema.jsonld` should now look like this. ```json { - "@context": [ "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - { - "rl": "https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/" - } - ], - "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema", - "prefLabel": "depression neuroimaging study", - "description": "a study on linguistic processing in depression", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "landingPage": { - "@id": "README.md", - "@language": "en" - }, - "ui": { + "@context": [ + "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + { + "rl": "https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/" + } + ], + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "landingPage": { + "@id": "README.md", + "@language": "en" + }, + "ui": { "addProperties": [ - {"isAbout": "rl:PHQ-9/PHQ9_schema", + { + "isAbout": "rl:PHQ-9/PHQ9_schema", "variableName": "PHQ9_schema", - "prefLabel": {"en": "Depression"} - } + "prefLabel": { "en": "Depression" } + } ], - "order": [ - "rl:PHQ-9/PHQ9_schema" - ] - } + "order": ["rl:PHQ-9/PHQ9_schema"] + } } ``` @@ -195,6 +167,9 @@ The field `isAbout` is the URL to point to the schema of that activity. You migh The field `order` is there to indicate which activity should be presented first, second... +??? "Making sure you have a valid json file" + Json files can get a bit long and you might sometimes forget a coma of a closing square brackets, so to make sure that your json file is correctly formatted you can use a linter. For example, you can test individual files on the [json linter website](`https://jsonlint.com/`). + ### Starting to put things online to see how they look So now we want to put things online and see how things look. @@ -245,60 +220,16 @@ So once again grab the URL of the **raw** content of your protocol and point the https://www.repronim.org/reproschema-ui/#/?url=https://raw.githubusercontent.com/your_user_name/depression_nimg_schema/master/protocol/depression_nimg_schema.jsonld ``` -## In you own time: add the thank-you activity +## In you own time: add the `thank-you` activity For practice you can now add another activity to your protocol: one to thank people for their participation. -You can find it here in the reproschema library. - -https://github.com/ReproNim/reproschema-library/tree/master/activities/ThankYou +You can find it [here](https://github.com/ReproNim/reproschema-library/tree/master/activities/ThankYou) in the reproschema library. -Once you have changed the `depression_nimg_schema.jsonld`, you can update the oneline content with the following git commands. +Once you have changed the `depression_nimg_schema.jsonld`, you can update the online content with the following git commands. ```bash git add --all git commit -m 'add a thank you activity' git push ``` - - - \ No newline at end of file diff --git a/docs/42_create_new_activity.md b/docs/42_create_new_activity.md new file mode 100644 index 0000000000..2dd32f8713 --- /dev/null +++ b/docs/42_create_new_activity.md @@ -0,0 +1,44 @@ +# Create a new activity + +Now you would like to add a small questionaire + + + + +Activity directory structure: + +- `/items` (directory) : contains the `jsonld` files for individual items of the activity schema + - `item_1` + - `item_2` + - … +- `activityName_schema` : schema to define the activity +- `activityName_context` : context to define keys used specific to the activity schema + +Creating `activityName_schema` – use the keys defined in [`schemas/Activity`](./schemas/Activity). +If any other keys are used, then define them in `activityName_context` + +Mandatory keys: + +- `@context` - [Array] Include the ReproNim generic context JSON-LD file along with the activity context. +- `@type`- describes type of the schema. +- `@id` - unique id for the schema. should be same as the filename. +- `skos:prefLabel` - display name for the schema +- `ui.addProperties` - defines the various properties of each item. +- `variablename` - variable name used in `ui.order` for the items +- `isAbout` - file name of the corresponding variable name +- `ui.order` - [Array] defines the order in which the items appear in the activity + +### Create items + +To create `item_x` in the items folder: + +- Use keys defined in [`schemas/Field`](./schemas/Field) +- `@type`=`"https://raw.githubusercontent.com/ReproNim/reproschema/master/schemas/Field"` +- `responseOptions` – can be embedded or can point to a remote JSON-LD object. + +## Programmatic schema generation + +Tool to convert redcap CSVs to our schema format. But it cannot be used to convert every +redcap-formatted table as some are customized redcap tables (for example the 100s that are in ABCD) +but does cover most cases. A template of the CSV and how to use the tool can be found +[here](https://github.com/sanuann/reproschema-builder) diff --git a/docs/43_tips_to_make_your_life_easier.md b/docs/43_tips_to_make_your_life_easier.md new file mode 100644 index 0000000000..f699ad897f --- /dev/null +++ b/docs/43_tips_to_make_your_life_easier.md @@ -0,0 +1,204 @@ +# Tips to make your life easier + +## Validating your json files + + + +First, make sure your syntax is in correct jsonld format. Test all files with `@context` from command line: + +``` +npm install -g jsonlint +grep -r "@context" . \ + | cut -d: -f1 | xargs -I fname jsonlint -q fname +``` + +Or test individual files on the [json linter website](`https://jsonlint.com/`). + +## Validating your schema + + + +``` +pip install reproschema requests_cache +reproschema -l DEBUG validate activities +``` + +## Automating those checks + +It can be quickly become cumbersome to type some of the commands described above to always make sure the files you have created are valid. + +Thankfully though there are ways to automate those checks and integrate them into your workflow. They rely on using some of the features of Github or Git. + +### Github actions + +The first one is using Github actions to let Github perform those checks for you every time there some new content is added on a repository. + +To set those up you simply need to create a `.github/workflows` folder inside the repository where you are working. This will contain all the workflows (a set of "actions") that Github has to run on this repository. Each workflow is decribed by a `yml` file. + + + +For example you could create a `validate.yml` file in this repository. + +```bash +├── .git # hidden git folder +├── .github # hidden github folder +│ └── workflows +│ └── validate.xml # file the actions used to validate your schema +├── protocols +│ ├── README-en.md +│ └── protocol-1.jsonld +├── activities +│ ├── items +│ │ └── item-1.jsonld +│ └── activity-1.jsonld +└── README.md +``` + +The content of `validate.yml` file would look like this. + +```yml +name: validate protocol and activities + +# describes when this workfllow is triggered +on: + push: # when pushing to a branch + branches: [master] # on which branch + pull_request: # when opening a new pull request + branches: "*" # * refers to all branches + +jobs: + build: + # describes the operating system that will #be used + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks executed as part of the job + steps: + - name: Setup Node # installing Node.js for all the javascript part + uses: actions/setup-node@v1 + with: + node-version: "12.x" + + # Checks-out your repository under $GITHUB_WORKSPACE, + # so your job can access it + - uses: actions/checkout@v2 + + # Checks that our JSON are valid + # Installing `jsonlint` validate the JSON files + # Looking recursively through the directories `protocol` + # and `activities` for any file with "@context" in them + # (that makes them jsonld files) and validating their content + # with jsonlint + - name: Check for syntax errors + run: | + npm install -g jsonlint + grep -r "@context" activities | cut -d: -f1 | xargs -I fname jsonlint -q fname + grep -r "@context" protocols | cut -d: -f1 | xargs -I fname jsonlint -q fname + + # Checks that the schemas are valid + # Using python and the installing the reproschema tools + # from the reproschema-py repository to then validate + # the content of the `activities` and `protocols` folders. + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools + pip install reproschema requests_cache + + - name: Test with pyshacl + run: | + reproschema -l DEBUG validate activities + reproschema -l DEBUG validate protocols +``` + +### Using git hooks and precommit + + +## Using a template for a new protocol + +If you are starting a new study from scratch and already familiar with some of the basics of reproschema, we recommend you use our template repository that already has some basic set-up to to validate your files... + + + +## Using presets response options + +If you have to create several items that always have the same set of response options, then it might be easier to create a separate file with those response options and point each item to that file instead. This way, if you need to change the characteristics of one response, you only have to change things in one file rather than in many. + +For example, you could create response set file to constrains the possible answers on all the yes / no questions by organizing things this way. + +```bash +activities +├── activity1.jsonld +├── yesNoValueConstraints.jsonld +└── items + ├── item1.jsonld + ├ ... + ... +``` + +The content of the `valueConstraints` file would look like this: + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@id": "yesNoValueConstraints.jsonld", + "@type": "reproschema:ResponseOption", + "valueType": "xsd:integer", + "minValue": 0, + "maxValue": 2, + "multipleChoice": false, + "choices": [ + { + "name": { + "en": "Yes" + }, + "value": 1 + }, + { + "name": { + "en": "No" + }, + "value": 0 + }, + { + "name": { + "en": "Don't know" + }, + "value": 2 + } + ] +} +``` + +And you can point each item to it by referring to the local file in the `responseOptions` field. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "item1.jsonld", + "prefLabel": "pizza", + "description": "favorite food", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "ui": { + "inputType": "radio" + }, + "question": { + "en": "Do you like pizza?" + }, + "responseOptions": "../response_options/booleanValueConstraints" +} +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 2351aea84f..504966e27a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,7 +19,11 @@ nav: - Introduction: "01_introduction.md" - Project structure: "20_project_structure.md" - Schema: "30_schema.md" - - Creating a new activity and protocol: "40_create_new_activity_protocol.md" + - Using reproschema - a tutorial: + - Intro: "40_using_reproschema.md" + - Creating a new protocol: "41_create_new_protocol.md" + - Creating a new activity: "42_create_new_activity.md" + - Tips to make your life easier: "43_tips_to_make_your_life_easier.md" # - Testing your schema and collecting data: "testing_using_schema.md" # - Contribute to the project: # - Reproschema: "81_contribute_to_schema.md" From 4a59c0ea66da79ae64454261b8949708788e1ce5 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 30 Aug 2020 11:35:19 +0200 Subject: [PATCH 04/10] update doc - expand on activity creation and tips - start creating page for translation - pointers to items for collecting demographic info --- docs/40_using_reproschema.md | 54 +++ docs/41_create_new_protocol.md | 45 +- docs/42_create_new_activity.md | 434 ++++++++++++++++-- docs/43_tips_to_make_your_life_easier.md | 72 +-- docs/44_translating_an_activity.md | 212 +++++++++ .../45_collecting_demographics_information.md | 70 +++ mkdocs.yml | 2 + 7 files changed, 814 insertions(+), 75 deletions(-) create mode 100644 docs/44_translating_an_activity.md create mode 100644 docs/45_collecting_demographics_information.md diff --git a/docs/40_using_reproschema.md b/docs/40_using_reproschema.md index 5afb480ec6..986e33bcfb 100644 --- a/docs/40_using_reproschema.md +++ b/docs/40_using_reproschema.md @@ -29,3 +29,57 @@ So we would want to have a set of questionnaires: - to assess the severity of the depression of our participants, - check which participants can go in an MRI scanner, - estimate the handedness of the participants (because of the language lateralization organization of the brain). + + +## A note about this tutorial + +We will be creating several jsonld files in this tutorial. Those can quickly grow big and it can be hard to see what was added to a certain file from one step to the next. This gets even more confusing when you know that the order of the lines does not really matter. So to makes things easier to follow (and unless we explicitly say so) any new content we add to a file we have already worked on will be put at the end of this file. + +So if step 1 looked like this: + +```json +{ + "@context": "some_URL", + "@type": "reproschema:Protocol", + "@id": "some_id", + "schemaVersion": "1.0.0", + "version": "0.0.1", +} +``` + +We will make sure that step 2 where we add a `landingPage` field looks like this: + +```json +{ + "@context": "some_URL", + "@type": "reproschema:Protocol", + "@id": "some_id", + "schemaVersion": "1.0.0", + "version": "0.0.1", + "landingPage": {"@id": "README.md"} +} +``` + +Although some other possibility would be equivalent: + +```json +{ + "landingPage": {"@id": "README.md"}, + "@context": "some_URL", + "@type": "reproschema:Protocol", + "@id": "some_id", + "schemaVersion": "1.0.0", + "version": "0.0.1", +} +``` + +```json +{ + "@context": "some_URL", + "@type": "reproschema:Protocol", + "@id": "some_id", + "landingPage": {"@id": "README.md"}, + "schemaVersion": "1.0.0", + "version": "0.0.1", +} +``` \ No newline at end of file diff --git a/docs/41_create_new_protocol.md b/docs/41_create_new_protocol.md index 2ba454d90c..df268d341f 100644 --- a/docs/41_create_new_protocol.md +++ b/docs/41_create_new_protocol.md @@ -5,7 +5,10 @@ We first need to create some folders to host the schema that will represent all our questionnaires. ```bash -# FYI: this is comment and it will not be executed +# Type this in a terminal window + +# FYI: this line starts with # +# it is comment and it will not be executed # if you copy paste it in the command line # Creating the directory for the depression neuroimaging study @@ -15,11 +18,12 @@ mkdir depression_nimg_schema cd depression_nimg_schema ``` -Now let's create the `protocol` folder, a protocol file named after our study. +Now let's create the `protocols` folder, a protocol file named after our study. ```bash -mkdir protocol -touch protocol/depression_nimg_schema.jsonld +# Type this in a terminal window +mkdir protocols +touch protocols/depression_nimg_schema.jsonld ``` Ok so now we are ready to start putting some content into those files. @@ -30,7 +34,7 @@ Open the `depression_nimg_schema.jsonld` with a text editor and add the followin { "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema", + "@id": "depression_nimg_schema.jsonld", "prefLabel": "depression neuroimaging study", "description": "a study on linguistic processing in depression", "schemaVersion": "1.0.0-rc1", @@ -52,13 +56,14 @@ You must also specify the version of the schema you are using. Let's now take care of adding a landing page to the list of assessments our participants will have to fill in. -Let's create a markdown readme file in the `protocol` folder. +Let's create a markdown readme file in the `protocols` folder. ```bash -touch protocol/README.md +# Type this in a terminal window +touch protocols/README.md ``` -Add some content to it just to get things started, like for example +Add some content in [markdown](https://daringfireball.net/projects/markdown/basics) to it just to get things started, like for example ```markdown # README @@ -72,7 +77,7 @@ Now we want to add this file to our protocol and make it the landing page for th { "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema", + "@id": "depression_nimg_schema.jsonld", "prefLabel": "depression neuroimaging study", "description": "a study on linguistic processing in depression", "schemaVersion": "1.0.0-rc1", @@ -133,7 +138,7 @@ To do this, the content of your `depression_nimg_schema.jsonld` should now look } ], "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema", + "@id": "depression_nimg_schema.jsonld", "prefLabel": "depression neuroimaging study", "description": "a study on linguistic processing in depression", "schemaVersion": "1.0.0-rc1", @@ -155,21 +160,30 @@ To do this, the content of your `depression_nimg_schema.jsonld` should now look } ``` +### What did we add ? + Let's just highlight the things that have changed. We have added a `ui` and an `order` fields. -`ui` contains `addProperties` where we will be listing all the assessments that we add to our protocol. +`ui` is for things realted to the user interface and contains `addProperties` where we will be listing all the assessments that we add to our protocol. -Each assessment is represented by an activity that is given a `variableName` and a `prefLabel`. The latter will be used in this case as the name to display on the UI in english. +Each assessment is represented by an activity that is given a `variableName` and a `prefLabel`. The latter will be used as the name to display on the UI in english. -The field `isAbout` is the URL to point to the schema of that activity. You might notice that `rl:PHQ-9/PHQ9_schema` does not look like a typical URL and clearly does not match the one we fed the UI earlier (https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). Well this is because we have defined, in the `@context` part of our jsonld, that the `rl` from `rl:PHQ-9/PHQ9_schema` will actually stand for `https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/`. This shorthand makes it faster for us to write URL but the UI will know how to `expand` this into an actual URL. +The field `isAbout` is the URL to point to the schema of that activity. The field `order` is there to indicate which activity should be presented first, second... ??? "Making sure you have a valid json file" Json files can get a bit long and you might sometimes forget a coma of a closing square brackets, so to make sure that your json file is correctly formatted you can use a linter. For example, you can test individual files on the [json linter website](`https://jsonlint.com/`). +??? "JSON-LD expansion" + You might notice that `rl:PHQ-9/PHQ9_schema` does not look like a typical URL and clearly does not match the one we fed the UI earlier (https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). Well this is because we have defined, in the `@context` part of our jsonld, that the `rl` from `rl:PHQ-9/PHQ9_schema` will actually stand for `https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/`. This shorthand makes it faster for us to write URL but the UI will know how to `expand` this into an actual URL. + + Similarly the `reproschema:Protocol` in `"@type": "reproschema:Protocol"` expands in `http://schema.repronim.org/Protocol` because `reproschema` has been indirectly defined in the context of `depression_nimg_schema.jsonld`. To be more precise `reproschema` is defined in the [base file](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/base) which is part of the context of the [generic file](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic) that our protocol points to. + + + ### Starting to put things online to see how they look So now we want to put things online and see how things look. @@ -179,12 +193,14 @@ To do that we will use Git and Github. Let's first initialize a repository in the folder where we have have been working. ```bash +# Type this in a terminal window git init . # the dot signifies the directory where you currently are ``` Now we tell git to make a snapshot of the current state of your folder. ```bash +# Type this in a terminal window git add --all # tell git to include all the new changes into the next snapshot git commit -m 'add protocol and README' # make a first snapshot of your protocol @@ -201,6 +217,8 @@ https://github.com/your_user_name/depression_nimg_schema.git You "push" the content of the `depression_nimg_schema` onto the empty "remote" repository you have just created. ```bash +# Type this in a terminal window + # tell git about the existence of this new online repository you have just created git remote add origin https://github.com/your_user_name/depression_nimg_schema.git @@ -229,6 +247,7 @@ You can find it [here](https://github.com/ReproNim/reproschema-library/tree/mast Once you have changed the `depression_nimg_schema.jsonld`, you can update the online content with the following git commands. ```bash +# Type this in a terminal window git add --all git commit -m 'add a thank you activity' git push diff --git a/docs/42_create_new_activity.md b/docs/42_create_new_activity.md index 2dd32f8713..8e9f09a8d3 100644 --- a/docs/42_create_new_activity.md +++ b/docs/42_create_new_activity.md @@ -1,44 +1,420 @@ # Create a new activity -Now you would like to add a small questionaire +Now you would like to add a small questionnaire to estimate the handedness of each participant. We can use the Edinburgh handedness inventory for this. +This tool is not part of the set of questionnaires included in the repronim library so we are going to have to create it ourselves. +There are 2 version for this questionnaire a long and a short version. +- Oldfield, R.C. (1971). The assessment and analysis of handedness: The Edinburgh inventory. Neuropsychologia, 9, 97-113. DOI: https://doi.org/10.1016/0028-3932(71)90067-4 +- Veale, J.F. (2014). Edinburgh Handedness Inventory - Short Form: A revised version based on confirmatory factor analysis. Laterality, 19, 164-177. DOI: https://doi.org/10.1080/1357650X.2013.783045 -Activity directory structure: +The participant is given one question and a set of activities: -- `/items` (directory) : contains the `jsonld` files for individual items of the activity schema - - `item_1` - - `item_2` - - … -- `activityName_schema` : schema to define the activity -- `activityName_context` : context to define keys used specific to the activity schema +``` +Please indicate your preferences in the use of hands in the following activities or objects: -Creating `activityName_schema` – use the keys defined in [`schemas/Activity`](./schemas/Activity). -If any other keys are used, then define them in `activityName_context` +1) Writing (*) +2) Drawing +3) Throwing (*) +4) Using Scissors +5) Using a Toothbrush (*) +6) Using a Knife (without a fork) +7) Using a Spoon (*) +8) Using a broom (upper hand) +9) Striking a Match (holds the match) +10) Opening a Box (holding the lid) -Mandatory keys: +i) Which foot do you prefer to kick with ? +ii) Which eye do you use when using only one? +``` -- `@context` - [Array] Include the ReproNim generic context JSON-LD file along with the activity context. -- `@type`- describes type of the schema. -- `@id` - unique id for the schema. should be same as the filename. -- `skos:prefLabel` - display name for the schema -- `ui.addProperties` - defines the various properties of each item. -- `variablename` - variable name used in `ui.order` for the items -- `isAbout` - file name of the corresponding variable name -- `ui.order` - [Array] defines the order in which the items appear in the activity +The asterisks denote the subset of items that belong to the short form of the questionnaire. -### Create items +The scoring for each item follows the following scheme: -To create `item_x` in the items folder: +- Always right = 100 +- Usually right = 50 +- Both equally = 0 +- Usually left = -50 +- Always left = -100 -- Use keys defined in [`schemas/Field`](./schemas/Field) -- `@type`=`"https://raw.githubusercontent.com/ReproNim/reproschema/master/schemas/Field"` -- `responseOptions` – can be embedded or can point to a remote JSON-LD object. +The Laterality Quotient is given by the mean score over items. And the final classification according to the Laterality Quotient score goes as follow: -## Programmatic schema generation +- Left handers: -100 to -61 +- Mixed handers: -60 to 60 +- Right handers: 61 to 100 -Tool to convert redcap CSVs to our schema format. But it cannot be used to convert every -redcap-formatted table as some are customized redcap tables (for example the 100s that are in ABCD) -but does cover most cases. A template of the CSV and how to use the tool can be found -[here](https://github.com/sanuann/reproschema-builder) + + +## Preparing the JSON for the activity + +Now let's create the `activities` folder, an activity file for the new assessment tool we want to create. For this tutorial we will be using the short form of the Edinburgh handedness inventory. + +```bash +# Type this in a terminal window +mkdir activities +touch activities/edinburgh_handedness_inventory_short.jsonld +``` + +Now let's start by adding the following content in the activity file we have just created. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", +} +``` + +The content is for now very similar to the jsonld that defines our protocol. The main difference is for the `@type` field that mentions that we are now describing an activity as defined in the Reproschema. + +Two other things we can add right away are: +- the references for this questionnaire, +- the "preamble" that is common to all items in this questionnaire. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "citation": "10.1080/1357650X.2013.783045", + "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:" +} +``` + +## Creating items + +Now that we have a basic structure for this new activity, let us start adding some items. + +Let's first start with the item for `writing` + +```bash +# Type this in a terminal window +mkdir activities/items +touch activities/items/writing.jsonld +``` + +The content for items starts like the ones we have seen so far but `"reproschema:Field"` for the `@type` field. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "writing.jsonld", + "prefLabel": "writing", + "description": "writing item of the EHI", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1" +} +``` + +We can now add: + +- the question for this item +- the response options +- and the `inputType` for for the user interface that will decide how this item will displayed to the user. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "writing", + "prefLabel": "writing", + "description": "writing item of the EHI", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "question": "Writing", + "ui": {"inputType": "radio"}, + "responseOptions": { + "valueType": "xsd:integer", + "minValue": -100, + "maxValue": 100, + "multipleChoice": false, + "choices": [ + { + "name": "Always right", + "value": 100 + }, + { + "name": "Usually right", + "value": 50 + }, + { + "name": "Both equally", + "value": 0 + }, + { + "name": "Usually left", + "value": -50 + }, + { + "name": "Always left", + "value": -100 + } + ] + } +} +``` + +### What did we add ? + +```json +"question": "Writing", +``` + +```json +"ui": {"inputType": "radio"}, +``` + +```json +"responseOptions": { + "valueType": "xsd:integer", + "minValue": -100, + "maxValue": 100, + "multipleChoice": false, + "choices": [ + { + "name": "Always right", + "value": 100 + }, + { + "name": "Usually right", + "value": 50 + }, + { + "name": "Both equally", + "value": 0 + }, + { + "name": "Usually left", + "value": -50 + }, + { + "name": "Always left", + "value": -100 + } + ] +} +``` + + + + +## In your own time: create a second item + +For next step you can create on your own the `throwing` item of the questionnaire. + +## Add the items to the activity + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "citation": "10.1080/1357650X.2013.783045", + "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:", + "ui": { + "order": [ + "items/writing.jsonld", + "items/throwing.jsonld" + ], + "shuffle": false, + "addProperties": [ + { + "variableName": "writing", + "isAbout": "items/writing.jsonld", + "isVis": true + }, + { + "variableName": "throwing", + "isAbout": "items/throwing.jsonld", + "isVis": true + } + ] + } +} +``` + +### What did we add ? + +```json +"ui": { + "order": [ + "items/writing.jsonld", + "items/throwing.jsonld" + ], + "shuffle": false, + "addProperties": [ + { + "variableName": "writing", + "isAbout": "items/writing.jsonld", + "isVis": true + }, + { + "variableName": "throwing", + "isAbout": "items/throwing.jsonld", + "isVis": true + } + ] +} +``` + +## Viewing the activity + +Push the content you have created on your repository on github + +```bash +# Type this in a terminal window +git add --all +git commit -m 'adding the EHI activity' +git push +``` + +Use the UI to visualize just the activity. + +``` +https://www.repronim.org/reproschema-ui/#/activities/0?url=url-to-activity-schema +``` + +``` +https://www.repronim.org/reproschema-ui/#/activities/0?url=https://raw.githubusercontent.com/your_user_name/depression_nimg_schema/activities/edinburgh_handedness_inventory_short.jsonld +``` + + + + + + +## Viewing the results + + +### Creating an item for the results + +```bash +# Type this in a terminal window +mkdir activities/items +touch activities/items/EHI_results.jsonld +``` + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "EHI_results.jsonld", + "prefLabel": "EHI results", + "description": "Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "ui": { + "inputType": "number", + "readonlyValue": true + }, + "responseOptions": { + "valueType": "xsd:integer", + "minValue": -100, + "maxValue": 100 + } +} +``` + + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "citation": "10.1080/1357650X.2013.783045", + "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:", + "ui": { + "order": [ + "items/writing.jsonld", + "items/throwing.jsonld", + "items/EHI_results.jsonld" + ], + "shuffle": false, + "addProperties": [ + { + "variableName": "writing", + "isAbout": "items/writing.jsonld", + "valueRequired": true, + "isVis": true + }, + { + "variableName": "throwing", + "isAbout": "items/throwing.jsonld", + "valueRequired": true, + "isVis": true + }, + { + "isAbout": "items/EHI_results.jsonld", + "variableName": "EHI_results", + "isVis": true + } + ] + }, + "compute": [ + { + "variableName": "EHI_results", + "jsExpression": "( writing + throwing ) / 2" + } + ] +} +``` + +### What did we add ? + +```json + "ui": { + "order": [ + ... + "items/EHI_results.jsonld" + ], + "addProperties": [ + ... + { + "isAbout": "items/EHI_results.jsonld", + "variableName": "EHI_results", + "isVis": true + } + ] + } +``` + +```json +"compute": [ + { + "variableName": "EHI_results", + "jsExpression": "( writing + throwing ) / 2" + } +] +``` + +## Adding the activity to the protocol diff --git a/docs/43_tips_to_make_your_life_easier.md b/docs/43_tips_to_make_your_life_easier.md index f699ad897f..f0608cf71a 100644 --- a/docs/43_tips_to_make_your_life_easier.md +++ b/docs/43_tips_to_make_your_life_easier.md @@ -90,10 +90,10 @@ jobs: - uses: actions/checkout@v2 # Checks that our JSON are valid - # Installing `jsonlint` validate the JSON files + # Installing `jsonlint` to validate the JSON files # Looking recursively through the directories `protocol` # and `activities` for any file with "@context" in them - # (that makes them jsonld files) and validating their content + # (that makes them jsonld files) and validate their content # with jsonlint - name: Check for syntax errors run: | @@ -121,7 +121,7 @@ jobs: reproschema -l DEBUG validate protocols ``` -### Using git hooks and precommit +### Using git hooks and pre-commit ## Using a template for a new protocol @@ -136,47 +136,49 @@ If you are starting a new study from scratch and already familiar with some of t If you have to create several items that always have the same set of response options, then it might be easier to create a separate file with those response options and point each item to that file instead. This way, if you need to change the characteristics of one response, you only have to change things in one file rather than in many. -For example, you could create response set file to constrains the possible answers on all the yes / no questions by organizing things this way. +For example, you could create response set file to constrains the possible answers on the questions of the Edinburgh Handedness Inventory we have been working on by organizing things this way. ```bash activities -├── activity1.jsonld -├── yesNoValueConstraints.jsonld +├── edinburgh_handedness_inventory_short.jsonld +├── leftRightValueConstraints.jsonld └── items - ├── item1.jsonld + ├── writing.jsonld ├ ... ... ``` -The content of the `valueConstraints` file would look like this: +The content of the `leftRightValueConstraints.jsonld` file would look like this: ```json { "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@id": "yesNoValueConstraints.jsonld", + "@id": "leftRightValueConstraints.jsonld", "@type": "reproschema:ResponseOption", "valueType": "xsd:integer", - "minValue": 0, - "maxValue": 2, + "minValue": -100, + "maxValue": 100, "multipleChoice": false, "choices": [ { - "name": { - "en": "Yes" - }, - "value": 1 + "name": "Always right", + "value": 100 }, { - "name": { - "en": "No" - }, + "name": "Usually right", + "value": 50 + }, + { + "name": "Both equally", "value": 0 }, { - "name": { - "en": "Don't know" - }, - "value": 2 + "name": "Usually left", + "value": -50 + }, + { + "name": "Always left", + "value": -100 } ] } @@ -188,17 +190,21 @@ And you can point each item to it by referring to the local file in the `respons { "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", "@type": "reproschema:Field", - "@id": "item1.jsonld", - "prefLabel": "pizza", - "description": "favorite food", + "@id": "writing", + "prefLabel": "writing", + "description": "writing item of the EHI", "schemaVersion": "1.0.0-rc1", "version": "0.0.1", - "ui": { - "inputType": "radio" - }, - "question": { - "en": "Do you like pizza?" - }, - "responseOptions": "../response_options/booleanValueConstraints" + "question": "Writing", + "ui": {"inputType": "radio"}, + "responseOptions": "../leftRightValueConstraints.jsonld" } -``` \ No newline at end of file +``` + + + \ No newline at end of file diff --git a/docs/44_translating_an_activity.md b/docs/44_translating_an_activity.md new file mode 100644 index 0000000000..0219fa545a --- /dev/null +++ b/docs/44_translating_an_activity.md @@ -0,0 +1,212 @@ +# Translating a questionnaire + +Imagine that a colleague of yours has heard that you have created this online tool based on the Edinburgh handedness inventory and she wants to use it for her own work. But she would need a French version of the questionnaire. + +Well there is an easy way to reuse the work we have already done to have the tool support several languages. + +First here is the list of the questions of the EHI in French. + +``` +Quelle main utilisez vous de préférence pour: + +1) Écrire (*) +2) Dessiner +3) Lancer (*) +4) Utiliser une paire de ciseaux +5) Utiliser une brosse à dents (*) +6) Tenir un couteau (sans fourchette) +7) Tenir une cuillère (*) +8) Utiliser un balai (main supérieure) +9) Tenir une allumette pour l'allumer +10) Ouvrir une boîte (prendre le couvercle) + +i) Quel est le pied avec lequel vous préférez shooter? +ii) Quel oeil utiliser-vous pour viser? +``` + + + +## Updating the items + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "writing", + "prefLabel": { + "en": "writing", + "fr": "écrire" + }, + "description": "writing item of the EHI", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "question": { + "en": "Writing", + "fr": "Écrire", + }, + "ui": {"inputType": "radio"}, + "responseOptions": "../leftRightValueConstraints.jsonld" +} +``` + +### What did we change ? + +```json +"prefLabel": { + "en": "writing", + "fr": "écrire" +} +``` + +```json +"question": { + "en": "Writing", + "fr": "Écrire" +} +``` + +## Updating the response options + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@id": "leftRightValueConstraints.jsonld", + "@type": "reproschema:ResponseOption", + "valueType": "xsd:integer", + "minValue": -100, + "maxValue": 100, + "multipleChoice": false, + "choices": [ + { + "name": { + "en": "Always right", + "fr": "Toujours la main droite" + }, + "value": 100 + }, + { + "name": { + "en": "Usually right", + "fr": "En général la main droite" + }, + "value": 50 + }, + { + "name": { + "en": "Both equally", + "fr": "Les deux" + }, + "value": 0 + }, + { + "name": { + "en": "Usually left", + "fr": "En général la main gauche" + }, + "value": -50 + }, + { + "name": { + "en": "Always left", + "fr": "Toujours la main gauche" + }, + "value": -100 + } + ] +} +``` + +### What did we change ? + +```json + +``` + +## Updating the activity + +We need to update the `edinburgh_handedness_inventory_short.jsonld` so that the preamble question has both languages: + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": { + "en": "Edinburgh handedness inventory - short form", + "fr": "Version abrégée du test Edinburgh", + }, + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "citation": "10.1080/1357650X.2013.783045", + "preamble": { + "en": "Please indicate your preferences in the use of hands in the following activities or objects:", + "fr": "Quelle main utilisez-vous de préférence pour :" + }, + "ui": { + "order": [ + "items/writing.jsonld", + "items/throwing.jsonld", + "items/EHI_results.jsonld" + ], + "shuffle": false, + "addProperties": [ + { + "variableName": "writing", + "isAbout": "items/writing.jsonld", + "valueRequired": true, + "isVis": true + }, + { + "variableName": "throwing", + "isAbout": "items/throwing.jsonld", + "valueRequired": true, + "isVis": true + }, + { + "isAbout": "items/EHI_results.jsonld", + "variableName": "EHI_results", + "isVis": true + } + ] + }, + "compute": [ + { + "variableName": "EHI_results", + "jsExpression": "( writing + throwing ) / 2" + } + ] +} +``` + +### What did we change ? + +```json +"prefLabel": { + "en": "Edinburgh handedness inventory - short form", + "fr": "Version abrégée du test Edinburgh", +} +``` + +```json +"preamble": { + "en": "Please indicate your preferences in the use of hands in the following activities or objects:", + "fr": "Quelle main utilisez vous de préférence pour :" +} +``` + + diff --git a/docs/45_collecting_demographics_information.md b/docs/45_collecting_demographics_information.md new file mode 100644 index 0000000000..72a4d7fbe7 --- /dev/null +++ b/docs/45_collecting_demographics_information.md @@ -0,0 +1,70 @@ +# Collecting information about your participant + +Before you go and start creating new activities and items to collect the names, surnames and other demographics of your participants make sure you have had a look at these items on the reproschema library: + +See the [demographics_and_background_information_v1](https://github.com/ReproNim/reproschema-library/tree/master/activities/demographics_and_background_information_v1/items) folder: + +``` +demographics_and_background_information_v1/ +└── items + ├── age_months + ├── age_years + ├── ann_fam_income + ├── child_out_psych_cur + ├── child_out_psych_ever + ├── countryOfBirth + ├── demo_init + ├── demo_rpt_date + ├── document + ├── doe + ├── education_level + ├── email + ├── ethnic_category + ├── ethnic_category_informant + ├── fluentLanguages + ├── fullName + ├── handedness + ├── healthCondition + ├── inpatient_psych + ├── inpatient_treat_age + ├── inpatient_treat_dur + ├── inpatient_treatments + ├── interviewed_who + ├── interview_type + ├── knownLanguages + ├── last_period + ├── medication + ├── menarche_start + ├── meneses + ├── mentalHealth + ├── nativeLanguage + ├── other_persons_instructions + ├── outpatient_treat_age + ├── outpatient_treatments + ├── outpatient_treat_weeks + ├── parent_relationship + ├── parent_relationship_1 + ├── parent_relationship_2 + ├── participant_education + ├── participant_id + ├── particpant_grade_level + ├── person1_education + ├── person1_id + ├── person1_occ_lvl + ├── person1_other_id + ├── person2_education + ├── person2_exist + ├── person2_id + ├── person2_occ_lvl + ├── person2_other_id + ├── race_category + ├── race_category_informant + ├── raceEthnicity + ├── record_id + ├── religious_category + ├── sex + ├── share_data + ├── stateOfBirth + ├── stateOfResidence + └── verification_id +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 504966e27a..8fd12d9736 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,6 +24,8 @@ nav: - Creating a new protocol: "41_create_new_protocol.md" - Creating a new activity: "42_create_new_activity.md" - Tips to make your life easier: "43_tips_to_make_your_life_easier.md" + - Translate a questionnaire: "44_translating_an_activity.md" + - Demographic information : "45_collecting_demographics_information.md" # - Testing your schema and collecting data: "testing_using_schema.md" # - Contribute to the project: # - Reproschema: "81_contribute_to_schema.md" From 74310e6acca907bc86bf68caef6af22408a9d414 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 30 Aug 2020 15:29:11 +0200 Subject: [PATCH 05/10] [DOC] use demographics to show how to reuse items --- docs/42_create_new_activity.md | 65 ++++++++++++++++- .../45_collecting_demographics_information.md | 72 ++++++++++++++++++- 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/docs/42_create_new_activity.md b/docs/42_create_new_activity.md index 8e9f09a8d3..a3c44eeece 100644 --- a/docs/42_create_new_activity.md +++ b/docs/42_create_new_activity.md @@ -64,7 +64,7 @@ Now let's create the `activities` folder, an activity file for the new assessmen ```bash # Type this in a terminal window mkdir activities -touch activities/edinburgh_handedness_inventory_short.jsonld +touch activities/EHI/edinburgh_handedness_inventory_short.jsonld ``` Now let's start by adding the following content in the activity file we have just created. @@ -109,8 +109,8 @@ Let's first start with the item for `writing` ```bash # Type this in a terminal window -mkdir activities/items -touch activities/items/writing.jsonld +mkdir activities/EHI/items +touch activities/EHI/items/writing.jsonld ``` The content for items starts like the ones we have seen so far but `"reproschema:Field"` for the `@type` field. @@ -418,3 +418,62 @@ touch activities/items/EHI_results.jsonld ``` ## Adding the activity to the protocol + + +```json +{ + "@context": [ + "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + { + "rl": "https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/" + } + ], + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema.jsonld", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "landingPage": {EHI + "@id": "README.md", + "@language": "en" + }, + "ui": { + "addProperties": [ + { + "isAbout": "rl:PHQ-9/PHQ9_schema", + "variableName": "PHQ9_schema", + "prefLabel": { "en": "Depression" } + }, + { + "isAbout": "../activities/EHI/edinburgh_handedness_inventory_short.jsonld", + "variableName": "EHI_short_schema", + "prefLabel": { "en": "EHI" } + } + ], + "order": [ + "rl:PHQ-9/PHQ9_schema", + "EHI_short_schema" + ] + } +} +``` + +### What did we add ? + +```json +"ui": { +"addProperties": [ + ... + { + "isAbout": "../activities/edinburgh_handedness_inventory_short.jsonld", + "variableName": "EHI_short_schema", + "prefLabel": { "en": "EHI" } + } +], +"order": [ + ... + "EHI_short_schema" + ] +} +``` \ No newline at end of file diff --git a/docs/45_collecting_demographics_information.md b/docs/45_collecting_demographics_information.md index 72a4d7fbe7..5ce66698fb 100644 --- a/docs/45_collecting_demographics_information.md +++ b/docs/45_collecting_demographics_information.md @@ -67,4 +67,74 @@ demographics_and_background_information_v1/ ├── stateOfBirth ├── stateOfResidence └── verification_id -``` \ No newline at end of file +``` + +```json +{ + "@context": [ "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + { + "demo": "https://github.com/ReproNim/reproschema-library/tree/master/activities/demographics_and_background_information_v1/items" + } + ], + "@type": "reproschema:Activity", + "@id": "demographics.jsonld", + "prefLabel": "demographics", + "description": "information about the participant", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "ui": { + "order": [ + "demo:writing.jsonld", + "demo:throwing.jsonld", + "demo:EHI_results.jsonld" + ], + "shuffle": false, + "addProperties": [ + { + "variableName": "participant_id", + "isAbout": "demo:participant_id", + }, + { + "variableName": "fullName", + "isAbout": "demo:fullName", + }, + { + "variableName": "sex", + "isAbout": "demo:sex", + }, + { + "variableName": "age_years", + "isAbout": "demo:age_years", + }, + { + "isAbout": "demo:email", + "variableName": "email", + }, + { + "isAbout": "demo:participant_education", + "variableName": "participant_education", + }, + { + "isAbout": "demo:nativeLanguage", + "variableName": "nativeLanguage", + }, + { + "isAbout": "demo:healthCondition", + "variableName": "healthCondition", + }, + { + "isAbout": "demo:mentalHealth", + "variableName": "mentalHealth", + }, + { + "isAbout": "demo:share_data", + "variableName": "share_data", + }, + { + "isAbout": "demo:medication", + "variableName": "medication", + } + ] + } +} +``` From fa044510e4f37ac3d76e38c0b8c3f5fa10323332 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 30 Aug 2020 15:53:06 +0200 Subject: [PATCH 06/10] fix demographics --- .../45_collecting_demographics_information.md | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/45_collecting_demographics_information.md b/docs/45_collecting_demographics_information.md index 5ce66698fb..a63555541c 100644 --- a/docs/45_collecting_demographics_information.md +++ b/docs/45_collecting_demographics_information.md @@ -73,7 +73,7 @@ demographics_and_background_information_v1/ { "@context": [ "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", { - "demo": "https://github.com/ReproNim/reproschema-library/tree/master/activities/demographics_and_background_information_v1/items" + "demo": "https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/demographics_and_background_information_v1/items" } ], "@type": "reproschema:Activity", @@ -84,57 +84,68 @@ demographics_and_background_information_v1/ "version": "0.0.1", "ui": { "order": [ - "demo:writing.jsonld", - "demo:throwing.jsonld", - "demo:EHI_results.jsonld" + "demo:participant_id", + "demo:fullName", + "demo:sex", + "demo:age_years", + "demo:email", + "demo:participant_education", + "demo:nativeLanguage", + "demo:healthCondition", + "demo:mentalHealth", + "demo:share_data", + "demo:medication" ], "shuffle": false, "addProperties": [ { "variableName": "participant_id", - "isAbout": "demo:participant_id", + "isAbout": "demo:participant_id" }, { "variableName": "fullName", - "isAbout": "demo:fullName", + "isAbout": "demo:fullName" }, { "variableName": "sex", - "isAbout": "demo:sex", + "isAbout": "demo:sex" }, { "variableName": "age_years", - "isAbout": "demo:age_years", + "isAbout": "demo:age_years" }, { "isAbout": "demo:email", - "variableName": "email", + "variableName": "email" }, { "isAbout": "demo:participant_education", - "variableName": "participant_education", + "variableName": "participant_education" }, { "isAbout": "demo:nativeLanguage", - "variableName": "nativeLanguage", + "variableName": "nativeLanguage" }, { "isAbout": "demo:healthCondition", - "variableName": "healthCondition", + "variableName": "healthCondition" }, { "isAbout": "demo:mentalHealth", - "variableName": "mentalHealth", + "variableName": "mentalHealth" }, { "isAbout": "demo:share_data", - "variableName": "share_data", + "variableName": "share_data" }, { "isAbout": "demo:medication", - "variableName": "medication", + "variableName": "medication" } ] } } ``` + + + From 4f0bc46219b38a40292d7de914bedfb4edf8c1ac Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 20 Mar 2024 15:47:36 -0400 Subject: [PATCH 07/10] move files into a different section --- docs/41_create_new_protocol.md | 261 +----------------- ...reproschema.md => 50_using_reproschema.md} | 0 docs/51_create_new_protocol.md | 258 +++++++++++++++++ ..._activity.md => 52_create_new_activity.md} | 0 ...md => 53_tips_to_make_your_life_easier.md} | 0 ...ivity.md => 54_translating_an_activity.md} | 0 ...55_collecting_demographics_information.md} | 0 mkdocs.yml | 12 +- 8 files changed, 268 insertions(+), 263 deletions(-) rename docs/{40_using_reproschema.md => 50_using_reproschema.md} (100%) create mode 100644 docs/51_create_new_protocol.md rename docs/{42_create_new_activity.md => 52_create_new_activity.md} (100%) rename docs/{43_tips_to_make_your_life_easier.md => 53_tips_to_make_your_life_easier.md} (100%) rename docs/{44_translating_an_activity.md => 54_translating_an_activity.md} (100%) rename docs/{45_collecting_demographics_information.md => 55_collecting_demographics_information.md} (100%) diff --git a/docs/41_create_new_protocol.md b/docs/41_create_new_protocol.md index 943eab5517..fa965aefc4 100644 --- a/docs/41_create_new_protocol.md +++ b/docs/41_create_new_protocol.md @@ -1,264 +1,10 @@ # Creating a new protocol -## Setting the stage - -We first need to create some folders to host the schema that will represent all our questionnaires. - -```bash -# Type this in a terminal window - -# FYI: this line starts with # -# it is comment and it will not be executed -# if you copy paste it in the command line - -# Creating the directory for the depression neuroimaging study -mkdir depression_nimg_schema - -# Move into the directory -cd depression_nimg_schema -``` - -Now let's create the `protocols` folder, a protocol file named after our study. - -```bash -# Type this in a terminal window -mkdir protocols -touch protocols/depression_nimg_schema.jsonld -``` - -Ok so now we are ready to start putting some content into those files. - -Open the `depression_nimg_schema.jsonld` with a text editor and add the following content into it. - -```json -{ - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema.jsonld", - "prefLabel": "depression neuroimaging study", - "description": "a study on linguistic processing in depression", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1" -} -``` - -To explain a bit what all of this means: - -- `@context` gives the URL where we can find the "definitions" of terms used in the reproschema. It is itself a json file that you [can view directly](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic). -- `@type` just says what type of entity this jsonld file describes. In this case it is a `protocol` entity as defined by the reproschema. -- `@id` is the identity of this entity, its unique identifier. - -You can then use the preferred label field and the description to give more human readable ways to describe this entity. - -You must also specify the version of the schema you are using. - -### Landing page - -Let's now take care of adding a landing page to the list of assessments our participants will have to fill in. - -Let's create a markdown readme file in the `protocols` folder. - -```bash -# Type this in a terminal window -touch protocols/README.md -``` - -Add some content in [markdown](https://daringfireball.net/projects/markdown/basics) to it just to get things started, like for example - -```markdown -# README - -Hello world -``` - -Now we want to add this file to our protocol and make it the landing page for the english version of this study. So the content of your protocol file should now read like this. - -```json -{ - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema.jsonld", - "prefLabel": "depression neuroimaging study", - "description": "a study on linguistic processing in depression", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "landingPage": { - "@id": "README.md", - "@language": "en" - } -} -``` - -??? "A note about relative paths" - Reproschema allows for the use of relative paths which means that in the example above the landing page `@id` being "README.md" means that the `README.md` and `depression_nimg_schema` are in the same folder. If the `README.md` had been in the parent directory, the `@id` of the `landingPage` section would have read `"@id": "../README.md"`. - -## Add a first assessment - -OK now we want to add a questionnaire to assess the severity of the depression of our participants. - -The first thing to do is to browse through the [library of assessments](https://github.com/ReproNim/reproschema-library/tree/master/activities) that already exist on the [dedicated repronim repository](https://github.com/ReproNim/reproschema-library). - -It seems that we can use the [PHQ-9](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1495268/) that self describes as a "Brief Depression Severity Measure". - -The schema that describe the PHQ-9 activity can be found [here](https://github.com/ReproNim/reproschema-library/blob/master/activities/PHQ-9/PHQ9_schema). - -If you want to visualize this activity on its own, you can use the [reproschema-ui](https://www.repronim.org/reproschema-ui/#/). To do that you can point the UI to the **raw** content of this activity. - -To get access to the raw content of that activity you must click on the `Raw` button on github once you have opened its [page](https://github.com/ReproNim/reproschema-library/blob/master/activities/PHQ-9/PHQ9_schema). This will open this URL: [https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema](https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). - -You can then pass the the URL of raw content to the UI using the following template: - -``` -https://www.repronim.org/reproschema-ui/#/activities/0?url=url-to-activity-schema -``` - -So in the case of the PHQ-9, it would give this URL that we copy-paste in a browser to view the activity on its own. - -``` -https://www.repronim.org/reproschema-ui/#/activities/0?url=https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema -``` - -You should now be able to see something like this and browse directly through the content of the activity. - - - -OK now that we know what we need to add to our protocol, let's add it our schema. - -To do this, the content of your `depression_nimg_schema.jsonld` should now look like this. - -```json -{ - "@context": [ - "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - { - "rl": "https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/" - } - ], - "@type": "reproschema:Protocol", - "@id": "depression_nimg_schema.jsonld", - "prefLabel": "depression neuroimaging study", - "description": "a study on linguistic processing in depression", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "landingPage": { - "@id": "README.md", - "@language": "en" - }, - "ui": { - "addProperties": [ - { - "isAbout": "rl:PHQ-9/PHQ9_schema", - "variableName": "PHQ9_schema", - "prefLabel": { "en": "Depression" } - } - ], - "order": ["rl:PHQ-9/PHQ9_schema"] - } -} -``` - -### What did we add ? - -Let's just highlight the things that have changed. - -We have added a `ui` and an `order` fields. - -`ui` is for things realted to the user interface and contains `addProperties` where we will be listing all the assessments that we add to our protocol. - -Each assessment is represented by an activity that is given a `variableName` and a `prefLabel`. The latter will be used as the name to display on the UI in english. - -The field `isAbout` is the URL to point to the schema of that activity. - -The field `order` is there to indicate which activity should be presented first, second... - -??? "Making sure you have a valid json file" - Json files can get a bit long and you might sometimes forget a coma of a closing square brackets, so to make sure that your json file is correctly formatted you can use a linter. For example, you can test individual files on the [json linter website](`https://jsonlint.com/`). - -??? "JSON-LD expansion" - You might notice that `rl:PHQ-9/PHQ9_schema` does not look like a typical URL and clearly does not match the one we fed the UI earlier (https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). Well this is because we have defined, in the `@context` part of our jsonld, that the `rl` from `rl:PHQ-9/PHQ9_schema` will actually stand for `https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/`. This shorthand makes it faster for us to write URL but the UI will know how to `expand` this into an actual URL. - - Similarly the `reproschema:Protocol` in `"@type": "reproschema:Protocol"` expands in `http://schema.repronim.org/Protocol` because `reproschema` has been indirectly defined in the context of `depression_nimg_schema.jsonld`. To be more precise `reproschema` is defined in the [base file](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/base) which is part of the context of the [generic file](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic) that our protocol points to. - - - -### Starting to put things online to see how they look - -So now we want to put things online and see how things look. - -To do that we will use Git and Github. - -Let's first initialize a repository in the folder where we have have been working. - -```bash -# Type this in a terminal window -git init . # the dot signifies the directory where you currently are -``` - -Now we tell git to make a snapshot of the current state of your folder. - -```bash -# Type this in a terminal window -git add --all # tell git to include all the new changes into the next snapshot - -git commit -m 'add protocol and README' # make a first snapshot of your protocol -``` - -Now to move things to a github repository, you need to go and create an empty repository to host the folder and files you have created. - -The repository should have an URL that resembles this one where `your_user_name` is your actual Github username: - -``` -https://github.com/your_user_name/depression_nimg_schema.git -``` - -You "push" the content of the `depression_nimg_schema` onto the empty "remote" repository you have just created. - -```bash -# Type this in a terminal window - -# tell git about the existence of this new online repository you have just created -git remote add origin https://github.com/your_user_name/depression_nimg_schema.git - -# Transfer the content there -git push -u origin master -``` - -If everything worked normally, you should be able to use the reproschema-ui to visualize your protocol using the following template: - -``` -https://www.repronim.org/reproschema-ui/#/?url=url-to-protocol-schema -``` - -So once again grab the URL of the **raw** content of your protocol and point the UI to it: - -``` -https://www.repronim.org/reproschema-ui/#/?url=https://raw.githubusercontent.com/your_user_name/depression_nimg_schema/master/protocol/depression_nimg_schema.jsonld -``` - -## In you own time: add the `thank-you` activity - -For practice you can now add another activity to your protocol: one to thank people for their participation. - -You can find it [here](https://github.com/ReproNim/reproschema-library/tree/master/activities/ThankYou) in the reproschema library. - -Once you have changed the `depression_nimg_schema.jsonld`, you can update the online content with the following git commands. - -```bash -# Type this in a terminal window -git add --all -git commit -m 'add a thank you activity' -git push -``` - - -# Creating a Research Protocol Using Cookiecutter +## Creating a Research Protocol Using Cookiecutter Ready for your first ReproSchema project?! We are going to use the [Reproschema Protocol Cookiecutter](https://github.com/ReproNim/reproschema-protocol-cookiecutter) to create a demo protocol. -## Getting Started +### Getting Started 1. Prerequisite: Ensure you have Git and Cookiecutter installed on your system. If not, please refer to the installation guides for Git and Cookiecutter. 2. Generate Your Repository: Use the Reproschema Protocol Cookiecutter to create a new repository for your research protocol. Run the following command in your terminal: @@ -269,7 +15,7 @@ cookiecutter gh:ReproNim/reproschema-protocol-cookiecutter 3. Follow the prompts to customize your new protocol, more details see [here](https://github.com/ReproNim/reproschema-protocol-cookiecutter#step-1-generate-the-protocol-files) -## Customizing Your Protocol +### Customizing Your Protocol Once you run the Cookiecutter command, you will be prompted to make choices for your protocol, ranging from 1-5. These choices generate corresponding activities in your repository. Here's what you can do with these activities: @@ -279,4 +25,3 @@ Once you run the Cookiecutter command, you will be prompted to make choices for The inclusion of activity choices aims to provide users with a practical understanding of how activities are structured within ReproSchema protocols. Whether you use these as a starting point or prefer to create your own from the ground up, these templates are there to guide you in structuring your research protocol effectively. We provide more detailed instructions for customizing your protocol in the following pages using [reproschema-demo-protocol](https://github.com/ReproNim/reproschema-demo-protocol) as an example. - diff --git a/docs/40_using_reproschema.md b/docs/50_using_reproschema.md similarity index 100% rename from docs/40_using_reproschema.md rename to docs/50_using_reproschema.md diff --git a/docs/51_create_new_protocol.md b/docs/51_create_new_protocol.md new file mode 100644 index 0000000000..6d522aa100 --- /dev/null +++ b/docs/51_create_new_protocol.md @@ -0,0 +1,258 @@ +# Creating a new protocol + +## Creating a protocol from scratch + +### Setting the stage + +We first need to create some folders to host the schema that will represent all our questionnaires. + +```bash +# Type this in a terminal window + +# FYI: this line starts with # +# it is comment and it will not be executed +# if you copy paste it in the command line + +# Creating the directory for the depression neuroimaging study +mkdir depression_nimg_schema + +# Move into the directory +cd depression_nimg_schema +``` + +Now let's create the `protocols` folder, a protocol file named after our study. + +```bash +# Type this in a terminal window +mkdir protocols +touch protocols/depression_nimg_schema.jsonld +``` + +Ok so now we are ready to start putting some content into those files. + +Open the `depression_nimg_schema.jsonld` with a text editor and add the following content into it. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema.jsonld", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1" +} +``` + +To explain a bit what all of this means: + +- `@context` gives the URL where we can find the "definitions" of terms used in the reproschema. It is itself a json file that you [can view directly](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic). +- `@type` just says what type of entity this jsonld file describes. In this case it is a `protocol` entity as defined by the reproschema. +- `@id` is the identity of this entity, its unique identifier. + +You can then use the preferred label field and the description to give more human readable ways to describe this entity. + +You must also specify the version of the schema you are using. + +#### Landing page + +Let's now take care of adding a landing page to the list of assessments our participants will have to fill in. + +Let's create a markdown readme file in the `protocols` folder. + +```bash +# Type this in a terminal window +touch protocols/README.md +``` + +Add some content in [markdown](https://daringfireball.net/projects/markdown/basics) to it just to get things started, like for example + +```markdown +# README + +Hello world +``` + +Now we want to add this file to our protocol and make it the landing page for the english version of this study. So the content of your protocol file should now read like this. + +```json +{ + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema.jsonld", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "landingPage": { + "@id": "README.md", + "@language": "en" + } +} +``` + +??? "A note about relative paths" + Reproschema allows for the use of relative paths which means that in the example above the landing page `@id` being "README.md" means that the `README.md` and `depression_nimg_schema` are in the same folder. If the `README.md` had been in the parent directory, the `@id` of the `landingPage` section would have read `"@id": "../README.md"`. + +### Add a first assessment + +OK now we want to add a questionnaire to assess the severity of the depression of our participants. + +The first thing to do is to browse through the [library of assessments](https://github.com/ReproNim/reproschema-library/tree/master/activities) that already exist on the [dedicated repronim repository](https://github.com/ReproNim/reproschema-library). + +It seems that we can use the [PHQ-9](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1495268/) that self describes as a "Brief Depression Severity Measure". + +The schema that describe the PHQ-9 activity can be found [here](https://github.com/ReproNim/reproschema-library/blob/master/activities/PHQ-9/PHQ9_schema). + +If you want to visualize this activity on its own, you can use the [reproschema-ui](https://www.repronim.org/reproschema-ui/#/). To do that you can point the UI to the **raw** content of this activity. + +To get access to the raw content of that activity you must click on the `Raw` button on github once you have opened its [page](https://github.com/ReproNim/reproschema-library/blob/master/activities/PHQ-9/PHQ9_schema). This will open this URL: [https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema](https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). + +You can then pass the the URL of raw content to the UI using the following template: + +``` +https://www.repronim.org/reproschema-ui/#/activities/0?url=url-to-activity-schema +``` + +So in the case of the PHQ-9, it would give this URL that we copy-paste in a browser to view the activity on its own. + +``` +https://www.repronim.org/reproschema-ui/#/activities/0?url=https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema +``` + +You should now be able to see something like this and browse directly through the content of the activity. + + + +OK now that we know what we need to add to our protocol, let's add it our schema. + +To do this, the content of your `depression_nimg_schema.jsonld` should now look like this. + +```json +{ + "@context": [ + "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + { + "rl": "https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/" + } + ], + "@type": "reproschema:Protocol", + "@id": "depression_nimg_schema.jsonld", + "prefLabel": "depression neuroimaging study", + "description": "a study on linguistic processing in depression", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "landingPage": { + "@id": "README.md", + "@language": "en" + }, + "ui": { + "addProperties": [ + { + "isAbout": "rl:PHQ-9/PHQ9_schema", + "variableName": "PHQ9_schema", + "prefLabel": { "en": "Depression" } + } + ], + "order": ["rl:PHQ-9/PHQ9_schema"] + } +} +``` + +#### What did we add ? + +Let's just highlight the things that have changed. + +We have added a `ui` and an `order` fields. + +`ui` is for things realted to the user interface and contains `addProperties` where we will be listing all the assessments that we add to our protocol. + +Each assessment is represented by an activity that is given a `variableName` and a `prefLabel`. The latter will be used as the name to display on the UI in english. + +The field `isAbout` is the URL to point to the schema of that activity. + +The field `order` is there to indicate which activity should be presented first, second... + +??? "Making sure you have a valid json file" + Json files can get a bit long and you might sometimes forget a coma of a closing square brackets, so to make sure that your json file is correctly formatted you can use a linter. For example, you can test individual files on the [json linter website](`https://jsonlint.com/`). + +??? "JSON-LD expansion" + You might notice that `rl:PHQ-9/PHQ9_schema` does not look like a typical URL and clearly does not match the one we fed the UI earlier (https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/PHQ-9/PHQ9_schema). Well this is because we have defined, in the `@context` part of our jsonld, that the `rl` from `rl:PHQ-9/PHQ9_schema` will actually stand for `https://raw.githubusercontent.com/ReproNim/reproschema-library/master/activities/`. This shorthand makes it faster for us to write URL but the UI will know how to `expand` this into an actual URL. + + Similarly the `reproschema:Protocol` in `"@type": "reproschema:Protocol"` expands in `http://schema.repronim.org/Protocol` because `reproschema` has been indirectly defined in the context of `depression_nimg_schema.jsonld`. To be more precise `reproschema` is defined in the [base file](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/base) which is part of the context of the [generic file](https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic) that our protocol points to. + + + +#### Starting to put things online to see how they look + +So now we want to put things online and see how things look. + +To do that we will use Git and Github. + +Let's first initialize a repository in the folder where we have have been working. + +```bash +# Type this in a terminal window +git init . # the dot signifies the directory where you currently are +``` + +Now we tell git to make a snapshot of the current state of your folder. + +```bash +# Type this in a terminal window +git add --all # tell git to include all the new changes into the next snapshot + +git commit -m 'add protocol and README' # make a first snapshot of your protocol +``` + +Now to move things to a github repository, you need to go and create an empty repository to host the folder and files you have created. + +The repository should have an URL that resembles this one where `your_user_name` is your actual Github username: + +``` +https://github.com/your_user_name/depression_nimg_schema.git +``` + +You "push" the content of the `depression_nimg_schema` onto the empty "remote" repository you have just created. + +```bash +# Type this in a terminal window + +# tell git about the existence of this new online repository you have just created +git remote add origin https://github.com/your_user_name/depression_nimg_schema.git + +# Transfer the content there +git push -u origin master +``` + +If everything worked normally, you should be able to use the reproschema-ui to visualize your protocol using the following template: + +``` +https://www.repronim.org/reproschema-ui/#/?url=url-to-protocol-schema +``` + +So once again grab the URL of the **raw** content of your protocol and point the UI to it: + +``` +https://www.repronim.org/reproschema-ui/#/?url=https://raw.githubusercontent.com/your_user_name/depression_nimg_schema/master/protocol/depression_nimg_schema.jsonld +``` + +### In you own time: add the `thank-you` activity + +For practice you can now add another activity to your protocol: one to thank people for their participation. + +You can find it [here](https://github.com/ReproNim/reproschema-library/tree/master/activities/ThankYou) in the reproschema library. + +Once you have changed the `depression_nimg_schema.jsonld`, you can update the online content with the following git commands. + +```bash +# Type this in a terminal window +git add --all +git commit -m 'add a thank you activity' +git push +``` + + diff --git a/docs/42_create_new_activity.md b/docs/52_create_new_activity.md similarity index 100% rename from docs/42_create_new_activity.md rename to docs/52_create_new_activity.md diff --git a/docs/43_tips_to_make_your_life_easier.md b/docs/53_tips_to_make_your_life_easier.md similarity index 100% rename from docs/43_tips_to_make_your_life_easier.md rename to docs/53_tips_to_make_your_life_easier.md diff --git a/docs/44_translating_an_activity.md b/docs/54_translating_an_activity.md similarity index 100% rename from docs/44_translating_an_activity.md rename to docs/54_translating_an_activity.md diff --git a/docs/45_collecting_demographics_information.md b/docs/55_collecting_demographics_information.md similarity index 100% rename from docs/45_collecting_demographics_information.md rename to docs/55_collecting_demographics_information.md diff --git a/mkdocs.yml b/mkdocs.yml index 517687b114..f79b6c7456 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -20,17 +20,19 @@ nav: - Project structure: "20_project_structure.md" - Schema: "30_schema.md" - User Guide: - - Intro: "40_using_reproschema.md" - Create a research protocol: "41_create_new_protocol.md" - - Creating a new activity: "42_create_new_activity.md" - Adopt assessments from the library: "42_adopt_assessments.md" - - Tips to make your life easier: "43_tips_to_make_your_life_easier.md" - Create new assessments for a protocol: "43_create_new_assess.md" - - Translate a questionnaire: "44_translating_an_activity.md" - Add a feedback section: "44_setup_feedback.md" - - Demographic information : "45_collecting_demographics_information.md" - Finalize the protocol: "45_finalize_protocol.md" - Toolkit: "46_tools.md" + - Tutorial: + - Intro: "50_using_reproschema.md" + - Create a research protocol: "51_create_new_protocol.md" + - Creating a new activity: "52_create_new_activity.md" + - Tips to make your life easier: "53_tips_to_make_your_life_easier.md" + - Translate a questionnaire: "54_translating_an_activity.md" + - Demographic information : "55_collecting_demographics_information.md" # - Creating a new activity and protocol: "create_new_activity_protocol.md" # - Testing your schema and collecting data: "testing_using_schema.md" # - Contribute to the project: From c859504ca251f360b570e6bc5e1fd9266958d78a Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 20 Mar 2024 15:48:27 -0400 Subject: [PATCH 08/10] revert --- docs/41_create_new_protocol.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/41_create_new_protocol.md b/docs/41_create_new_protocol.md index fa965aefc4..f5f8a63e56 100644 --- a/docs/41_create_new_protocol.md +++ b/docs/41_create_new_protocol.md @@ -1,10 +1,8 @@ -# Creating a new protocol - -## Creating a Research Protocol Using Cookiecutter +# Creating a Research Protocol Using Cookiecutter Ready for your first ReproSchema project?! We are going to use the [Reproschema Protocol Cookiecutter](https://github.com/ReproNim/reproschema-protocol-cookiecutter) to create a demo protocol. -### Getting Started +## Getting Started 1. Prerequisite: Ensure you have Git and Cookiecutter installed on your system. If not, please refer to the installation guides for Git and Cookiecutter. 2. Generate Your Repository: Use the Reproschema Protocol Cookiecutter to create a new repository for your research protocol. Run the following command in your terminal: @@ -15,7 +13,7 @@ cookiecutter gh:ReproNim/reproschema-protocol-cookiecutter 3. Follow the prompts to customize your new protocol, more details see [here](https://github.com/ReproNim/reproschema-protocol-cookiecutter#step-1-generate-the-protocol-files) -### Customizing Your Protocol +## Customizing Your Protocol Once you run the Cookiecutter command, you will be prompted to make choices for your protocol, ranging from 1-5. These choices generate corresponding activities in your repository. Here's what you can do with these activities: From b43591854dc413d86c8e424e015b0cdd8cde5ae4 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 20 Mar 2024 15:57:42 -0400 Subject: [PATCH 09/10] add syntax highlighting --- docs/20_project_structure.md | 4 ++-- docs/52_create_new_activity.md | 2 +- docs/53_tips_to_make_your_life_easier.md | 8 ++++---- mkdocs.yml | 7 +++++++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/20_project_structure.md b/docs/20_project_structure.md index f7270e974f..9ea433097b 100644 --- a/docs/20_project_structure.md +++ b/docs/20_project_structure.md @@ -33,7 +33,7 @@ The ReproSchema is like a blueprint for research projects, ensuring everyone col There is also an [`example`](https://github.com/ReproNim/reproschema/tree/master/examples) schema that can help give you a quick overview of what the protocol and activity -for a study might look like. For more details see the [schema section](../docs/30_schema.md). +for a study might look like. For more details see the [schema section](30_schema.md). ## [reproschema-library](https://github.com/ReproNim/reproschema-library) @@ -72,7 +72,7 @@ You can see it in action [here](https://www.repronim.org/reproschema-ui/) ## [reproschema-protocol-cookiecutter](https://github.com/ReproNim/reproschema-protocol-cookiecutter) -The reproschema-protocol-cookiecutter is a straightforward tool that helps you quickly set up a research study. It offers a ready-to-use template for organizing your study's structure and surveys, ensuring everything meets standard guidelines. Think of it as a quick-start guide to get your research project up and running smoothly. A step-by-step guide see [here](../docs/41_create_new_protocol.md). +The reproschema-protocol-cookiecutter is a straightforward tool that helps you quickly set up a research study. It offers a ready-to-use template for organizing your study's structure and surveys, ensuring everything meets standard guidelines. Think of it as a quick-start guide to get your research project up and running smoothly. A step-by-step guide see [here](41_create_new_protocol.md). ## Other repositories diff --git a/docs/52_create_new_activity.md b/docs/52_create_new_activity.md index a3c44eeece..7468681e00 100644 --- a/docs/52_create_new_activity.md +++ b/docs/52_create_new_activity.md @@ -434,7 +434,7 @@ touch activities/items/EHI_results.jsonld "description": "a study on linguistic processing in depression", "schemaVersion": "1.0.0-rc1", "version": "0.0.1", - "landingPage": {EHI + "landingPage": { "@id": "README.md", "@language": "en" }, diff --git a/docs/53_tips_to_make_your_life_easier.md b/docs/53_tips_to_make_your_life_easier.md index f0608cf71a..d43587c553 100644 --- a/docs/53_tips_to_make_your_life_easier.md +++ b/docs/53_tips_to_make_your_life_easier.md @@ -8,7 +8,7 @@ First, make sure your syntax is in correct jsonld format. Test all files with `@context` from command line: -``` +```bash npm install -g jsonlint grep -r "@context" . \ | cut -d: -f1 | xargs -I fname jsonlint -q fname @@ -23,7 +23,7 @@ Or test individual files on the [json linter website](`https://jsonlint.com/`). - mention that it needs python and add a pointer to reproschema-py --> -``` +```bash pip install reproschema requests_cache reproschema -l DEBUG validate activities ``` @@ -46,7 +46,7 @@ To set those up you simply need to create a `.github/workflows` folder inside th For example you could create a `validate.yml` file in this repository. -```bash +``` ├── .git # hidden git folder ├── .github # hidden github folder │ └── workflows @@ -138,7 +138,7 @@ If you have to create several items that always have the same set of response op For example, you could create response set file to constrains the possible answers on the questions of the Edinburgh Handedness Inventory we have been working on by organizing things this way. -```bash +``` activities ├── edinburgh_handedness_inventory_short.jsonld ├── leftRightValueConstraints.jsonld diff --git a/mkdocs.yml b/mkdocs.yml index f79b6c7456..4c023167aa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -49,3 +49,10 @@ markdown_extensions: - admonition - pymdownx.details - pymdownx.critic + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences \ No newline at end of file From d51b369c2bfa931f551dbe77541ca4e3a576e60c Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 20 Mar 2024 16:08:21 -0400 Subject: [PATCH 10/10] fa044510e fix demographics --- docs/52_create_new_activity.md | 348 ++++++++++++----------- docs/53_tips_to_make_your_life_easier.md | 140 +++++---- 2 files changed, 256 insertions(+), 232 deletions(-) diff --git a/docs/52_create_new_activity.md b/docs/52_create_new_activity.md index 7468681e00..d95e117925 100644 --- a/docs/52_create_new_activity.md +++ b/docs/52_create_new_activity.md @@ -1,13 +1,19 @@ # Create a new activity -Now you would like to add a small questionnaire to estimate the handedness of each participant. We can use the Edinburgh handedness inventory for this. +Now you would like to add a small questionnaire to estimate the handedness of +each participant. We can use the Edinburgh handedness inventory for this. -This tool is not part of the set of questionnaires included in the repronim library so we are going to have to create it ourselves. +This tool is not part of the set of questionnaires included in the repronim +library so we are going to have to create it ourselves. There are 2 version for this questionnaire a long and a short version. -- Oldfield, R.C. (1971). The assessment and analysis of handedness: The Edinburgh inventory. Neuropsychologia, 9, 97-113. DOI: https://doi.org/10.1016/0028-3932(71)90067-4 -- Veale, J.F. (2014). Edinburgh Handedness Inventory - Short Form: A revised version based on confirmatory factor analysis. Laterality, 19, 164-177. DOI: https://doi.org/10.1080/1357650X.2013.783045 +- Oldfield, R.C. (1971). The assessment and analysis of handedness: The + Edinburgh inventory. Neuropsychologia, 9, 97-113. DOI: + https://doi.org/10.1016/0028-3932(71)90067-4 +- Veale, J.F. (2014). Edinburgh Handedness Inventory - Short Form: A revised + version based on confirmatory factor analysis. Laterality, 19, 164-177. DOI: + https://doi.org/10.1080/1357650X.2013.783045 The participant is given one question and a set of activities: @@ -29,9 +35,10 @@ i) Which foot do you prefer to kick with ? ii) Which eye do you use when using only one? ``` -The asterisks denote the subset of items that belong to the short form of the questionnaire. +The asterisks denote the subset of items that belong to the short form of the +questionnaire. -The scoring for each item follows the following scheme: +The scoring for each item follows the following scheme: - Always right = 100 - Usually right = 50 @@ -39,7 +46,8 @@ The scoring for each item follows the following scheme: - Usually left = -50 - Always left = -100 -The Laterality Quotient is given by the mean score over items. And the final classification according to the Laterality Quotient score goes as follow: +The Laterality Quotient is given by the mean score over items. And the final +classification according to the Laterality Quotient score goes as follow: - Left handers: -100 to -61 - Mixed handers: -60 to 60 @@ -59,7 +67,9 @@ Source: http://www.brainmapping.org/shared/Edinburgh.php --> ## Preparing the JSON for the activity -Now let's create the `activities` folder, an activity file for the new assessment tool we want to create. For this tutorial we will be using the short form of the Edinburgh handedness inventory. +Now let's create the `activities` folder, an activity file for the new +assessment tool we want to create. For this tutorial we will be using the short +form of the Edinburgh handedness inventory. ```bash # Type this in a terminal window @@ -67,43 +77,48 @@ mkdir activities touch activities/EHI/edinburgh_handedness_inventory_short.jsonld ``` -Now let's start by adding the following content in the activity file we have just created. +Now let's start by adding the following content in the activity file we have +just created. ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Activity", - "@id": "edinburgh_handedness_inventory_short.jsonld", - "prefLabel": "Edinburgh handedness inventory - short form", - "description": "Short version of the Edinburgh handedness inventory", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1" } ``` -The content is for now very similar to the jsonld that defines our protocol. The main difference is for the `@type` field that mentions that we are now describing an activity as defined in the Reproschema. +The content is for now very similar to the jsonld that defines our protocol. The +main difference is for the `@type` field that mentions that we are now +describing an activity as defined in the Reproschema. + +Two other things we can add right away are: -Two other things we can add right away are: - the references for this questionnaire, - the "preamble" that is common to all items in this questionnaire. ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Activity", - "@id": "edinburgh_handedness_inventory_short.jsonld", - "prefLabel": "Edinburgh handedness inventory - short form", - "description": "Short version of the Edinburgh handedness inventory", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "citation": "10.1080/1357650X.2013.783045", - "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:" + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "citation": "10.1080/1357650X.2013.783045", + "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:" } ``` ## Creating items -Now that we have a basic structure for this new activity, let us start adding some items. +Now that we have a basic structure for this new activity, let us start adding +some items. Let's first start with the item for `writing` @@ -113,65 +128,67 @@ mkdir activities/EHI/items touch activities/EHI/items/writing.jsonld ``` -The content for items starts like the ones we have seen so far but `"reproschema:Field"` for the `@type` field. +The content for items starts like the ones we have seen so far but +`"reproschema:Field"` for the `@type` field. ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Field", - "@id": "writing.jsonld", - "prefLabel": "writing", - "description": "writing item of the EHI", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1" + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "writing.jsonld", + "prefLabel": "writing", + "description": "writing item of the EHI", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1" } ``` We can now add: -- the question for this item -- the response options -- and the `inputType` for for the user interface that will decide how this item will displayed to the user. +- the question for this item +- the response options +- and the `inputType` for for the user interface that will decide how this item + will displayed to the user. ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Field", - "@id": "writing", - "prefLabel": "writing", - "description": "writing item of the EHI", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "question": "Writing", - "ui": {"inputType": "radio"}, - "responseOptions": { - "valueType": "xsd:integer", - "minValue": -100, - "maxValue": 100, - "multipleChoice": false, - "choices": [ - { - "name": "Always right", - "value": 100 - }, - { - "name": "Usually right", - "value": 50 - }, - { - "name": "Both equally", - "value": 0 - }, - { - "name": "Usually left", - "value": -50 - }, - { - "name": "Always left", - "value": -100 - } - ] - } + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "writing", + "prefLabel": "writing", + "description": "writing item of the EHI", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "question": "Writing", + "ui": { "inputType": "radio" }, + "responseOptions": { + "valueType": "xsd:integer", + "minValue": -100, + "maxValue": 100, + "multipleChoice": false, + "choices": [ + { + "name": "Always right", + "value": 100 + }, + { + "name": "Usually right", + "value": 50 + }, + { + "name": "Both equally", + "value": 0 + }, + { + "name": "Usually left", + "value": -50 + }, + { + "name": "Always left", + "value": -100 + } + ] + } } ``` @@ -219,43 +236,40 @@ We can now add: - ## In your own time: create a second item -For next step you can create on your own the `throwing` item of the questionnaire. +For next step you can create on your own the `throwing` item of the +questionnaire. ## Add the items to the activity ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Activity", - "@id": "edinburgh_handedness_inventory_short.jsonld", - "prefLabel": "Edinburgh handedness inventory - short form", - "description": "Short version of the Edinburgh handedness inventory", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "citation": "10.1080/1357650X.2013.783045", - "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:", - "ui": { - "order": [ - "items/writing.jsonld", - "items/throwing.jsonld" - ], - "shuffle": false, - "addProperties": [ - { - "variableName": "writing", - "isAbout": "items/writing.jsonld", - "isVis": true - }, - { - "variableName": "throwing", - "isAbout": "items/throwing.jsonld", - "isVis": true - } - ] - } + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "citation": "10.1080/1357650X.2013.783045", + "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:", + "ui": { + "order": ["items/writing.jsonld", "items/throwing.jsonld"], + "shuffle": false, + "addProperties": [ + { + "variableName": "writing", + "isAbout": "items/writing.jsonld", + "isVis": true + }, + { + "variableName": "throwing", + "isAbout": "items/throwing.jsonld", + "isVis": true + } + ] + } } ``` @@ -303,15 +317,13 @@ https://www.repronim.org/reproschema-ui/#/activities/0?url=url-to-activity-schem ``` https://www.repronim.org/reproschema-ui/#/activities/0?url=https://raw.githubusercontent.com/your_user_name/depression_nimg_schema/activities/edinburgh_handedness_inventory_short.jsonld ``` + - - ## Viewing the results - ### Creating an item for the results ```bash @@ -322,70 +334,69 @@ touch activities/items/EHI_results.jsonld ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Field", - "@id": "EHI_results.jsonld", - "prefLabel": "EHI results", - "description": "Edinburgh handedness inventory", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "ui": { - "inputType": "number", - "readonlyValue": true - }, - "responseOptions": { - "valueType": "xsd:integer", - "minValue": -100, - "maxValue": 100 - } + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "EHI_results.jsonld", + "prefLabel": "EHI results", + "description": "Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "ui": { + "inputType": "number", + "readonlyValue": true + }, + "responseOptions": { + "valueType": "xsd:integer", + "minValue": -100, + "maxValue": 100 + } } ``` - ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Activity", - "@id": "edinburgh_handedness_inventory_short.jsonld", - "prefLabel": "Edinburgh handedness inventory - short form", - "description": "Short version of the Edinburgh handedness inventory", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "citation": "10.1080/1357650X.2013.783045", - "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:", - "ui": { - "order": [ - "items/writing.jsonld", - "items/throwing.jsonld", - "items/EHI_results.jsonld" - ], - "shuffle": false, - "addProperties": [ - { - "variableName": "writing", - "isAbout": "items/writing.jsonld", - "valueRequired": true, - "isVis": true - }, - { - "variableName": "throwing", - "isAbout": "items/throwing.jsonld", - "valueRequired": true, - "isVis": true - }, - { - "isAbout": "items/EHI_results.jsonld", - "variableName": "EHI_results", - "isVis": true - } - ] - }, - "compute": [ - { - "variableName": "EHI_results", - "jsExpression": "( writing + throwing ) / 2" - } + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Activity", + "@id": "edinburgh_handedness_inventory_short.jsonld", + "prefLabel": "Edinburgh handedness inventory - short form", + "description": "Short version of the Edinburgh handedness inventory", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "citation": "10.1080/1357650X.2013.783045", + "preamble": "Please indicate your preferences in the use of hands in the following activities or objects:", + "ui": { + "order": [ + "items/writing.jsonld", + "items/throwing.jsonld", + "items/EHI_results.jsonld" + ], + "shuffle": false, + "addProperties": [ + { + "variableName": "writing", + "isAbout": "items/writing.jsonld", + "valueRequired": true, + "isVis": true + }, + { + "variableName": "throwing", + "isAbout": "items/throwing.jsonld", + "valueRequired": true, + "isVis": true + }, + { + "isAbout": "items/EHI_results.jsonld", + "variableName": "EHI_results", + "isVis": true + } ] + }, + "compute": [ + { + "variableName": "EHI_results", + "jsExpression": "( writing + throwing ) / 2" + } + ] } ``` @@ -419,7 +430,6 @@ touch activities/items/EHI_results.jsonld ## Adding the activity to the protocol - ```json { "@context": [ @@ -476,4 +486,4 @@ touch activities/items/EHI_results.jsonld "EHI_short_schema" ] } -``` \ No newline at end of file +``` diff --git a/docs/53_tips_to_make_your_life_easier.md b/docs/53_tips_to_make_your_life_easier.md index d43587c553..e6585b7ad9 100644 --- a/docs/53_tips_to_make_your_life_easier.md +++ b/docs/53_tips_to_make_your_life_easier.md @@ -3,10 +3,11 @@ ## Validating your json files -First, make sure your syntax is in correct jsonld format. Test all files with `@context` from command line: +First, make sure your syntax is in correct jsonld format. Test all files with +`@context` from command line: ```bash npm install -g jsonlint @@ -19,7 +20,7 @@ Or test individual files on the [json linter website](`https://jsonlint.com/`). ## Validating your schema @@ -30,18 +31,24 @@ reproschema -l DEBUG validate activities ## Automating those checks -It can be quickly become cumbersome to type some of the commands described above to always make sure the files you have created are valid. +It can be quickly become cumbersome to type some of the commands described above +to always make sure the files you have created are valid. -Thankfully though there are ways to automate those checks and integrate them into your workflow. They rely on using some of the features of Github or Git. +Thankfully though there are ways to automate those checks and integrate them +into your workflow. They rely on using some of the features of Github or Git. ### Github actions -The first one is using Github actions to let Github perform those checks for you every time there some new content is added on a repository. +The first one is using Github actions to let Github perform those checks for you +every time there some new content is added on a repository. -To set those up you simply need to create a `.github/workflows` folder inside the repository where you are working. This will contain all the workflows (a set of "actions") that Github has to run on this repository. Each workflow is decribed by a `yml` file. +To set those up you simply need to create a `.github/workflows` folder inside +the repository where you are working. This will contain all the workflows (a set +of "actions") that Github has to run on this repository. Each workflow is +decribed by a `yml` file. For example you could create a `validate.yml` file in this repository. @@ -76,7 +83,7 @@ on: jobs: build: # describes the operating system that will #be used - runs-on: ubuntu-latest + runs-on: ubuntu-latest # Steps represent a sequence of tasks executed as part of the job steps: @@ -85,16 +92,16 @@ jobs: with: node-version: "12.x" - # Checks-out your repository under $GITHUB_WORKSPACE, + # Checks-out your repository under $GITHUB_WORKSPACE, # so your job can access it - uses: actions/checkout@v2 # Checks that our JSON are valid # Installing `jsonlint` to validate the JSON files - # Looking recursively through the directories `protocol` - # and `activities` for any file with "@context" in them - # (that makes them jsonld files) and validate their content - # with jsonlint + # Looking recursively through the directories `protocol` + # and `activities` for any file with "@context" in them + # (that makes them jsonld files) and validate their content + # with jsonlint - name: Check for syntax errors run: | npm install -g jsonlint @@ -102,8 +109,8 @@ jobs: grep -r "@context" protocols | cut -d: -f1 | xargs -I fname jsonlint -q fname # Checks that the schemas are valid - # Using python and the installing the reproschema tools - # from the reproschema-py repository to then validate + # Using python and the installing the reproschema tools + # from the reproschema-py repository to then validate # the content of the `activities` and `protocols` folders. - name: Set up Python 3.8 uses: actions/setup-python@v2 @@ -123,20 +130,27 @@ jobs: ### Using git hooks and pre-commit - ## Using a template for a new protocol -If you are starting a new study from scratch and already familiar with some of the basics of reproschema, we recommend you use our template repository that already has some basic set-up to to validate your files... +If you are starting a new study from scratch and already familiar with some of +the basics of reproschema, we recommend you use our template repository that +already has some basic set-up to to validate your files... ## Using presets response options -If you have to create several items that always have the same set of response options, then it might be easier to create a separate file with those response options and point each item to that file instead. This way, if you need to change the characteristics of one response, you only have to change things in one file rather than in many. +If you have to create several items that always have the same set of response +options, then it might be easier to create a separate file with those response +options and point each item to that file instead. This way, if you need to +change the characteristics of one response, you only have to change things in +one file rather than in many. -For example, you could create response set file to constrains the possible answers on the questions of the Edinburgh Handedness Inventory we have been working on by organizing things this way. +For example, you could create response set file to constrains the possible +answers on the questions of the Edinburgh Handedness Inventory we have been +working on by organizing things this way. ``` activities @@ -152,59 +166,59 @@ The content of the `leftRightValueConstraints.jsonld` file would look like this: ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@id": "leftRightValueConstraints.jsonld", - "@type": "reproschema:ResponseOption", - "valueType": "xsd:integer", - "minValue": -100, - "maxValue": 100, - "multipleChoice": false, - "choices": [ - { - "name": "Always right", - "value": 100 - }, - { - "name": "Usually right", - "value": 50 - }, - { - "name": "Both equally", - "value": 0 - }, - { - "name": "Usually left", - "value": -50 - }, - { - "name": "Always left", - "value": -100 - } - ] + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@id": "leftRightValueConstraints.jsonld", + "@type": "reproschema:ResponseOption", + "valueType": "xsd:integer", + "minValue": -100, + "maxValue": 100, + "multipleChoice": false, + "choices": [ + { + "name": "Always right", + "value": 100 + }, + { + "name": "Usually right", + "value": 50 + }, + { + "name": "Both equally", + "value": 0 + }, + { + "name": "Usually left", + "value": -50 + }, + { + "name": "Always left", + "value": -100 + } + ] } ``` -And you can point each item to it by referring to the local file in the `responseOptions` field. +And you can point each item to it by referring to the local file in the +`responseOptions` field. ```json { - "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", - "@type": "reproschema:Field", - "@id": "writing", - "prefLabel": "writing", - "description": "writing item of the EHI", - "schemaVersion": "1.0.0-rc1", - "version": "0.0.1", - "question": "Writing", - "ui": {"inputType": "radio"}, - "responseOptions": "../leftRightValueConstraints.jsonld" + "@context": "https://raw.githubusercontent.com/ReproNim/reproschema/1.0.0-rc1/contexts/generic", + "@type": "reproschema:Field", + "@id": "writing", + "prefLabel": "writing", + "description": "writing item of the EHI", + "schemaVersion": "1.0.0-rc1", + "version": "0.0.1", + "question": "Writing", + "ui": { "inputType": "radio" }, + "responseOptions": "../leftRightValueConstraints.jsonld" } ``` - \ No newline at end of file +[here](https://github.com/sanuann/reproschema-builder) -->