Database
Privileges
Add permission to read the xelo2
database but not to modify it.
GRANT SELECT, SHOW VIEW, TRIGGER ON xelo2.* TO `user`@`localhost` ;
FLUSH PRIVILEGES ;
Allowed values
Possible values are stored in the table allowed_values
.
To allow for additional values, you need to add a new row to the allowed_values
table.
The only exception is the name of the experimenters.
You need to change the experimenters
directly (because we use the id
from that table).
Constraints
You should make sure that for each allowed_values
, there is a constraint in the corresponding table.
Alias and Doc
You can add a more informative name (including spaces) and documentation to each column.
You need to edit column_comment
from the columns
table in information_schema
.
Make sure that you use the right syntax: alias: documentation
(use only one column to separate the alias from the doc).
So, for example, “Date of Birth: Date of birth of the participant
”.
Subtables
Subtables should follow the naming format maintable_name
, so for example the subtable for the motor tasks should be runs_motor
.
Note that runs
should be plural, then underscore, then text without underscore.
For example, you can create a table like this:
CREATE TABLE `runs_motor` (
`runs_id` int(11) DEFAULT NULL,
`overt_covert` text DEFAULT NULL COMMENT 'Overt / Covert',
UNIQUE KEY `run_id` (`run_id`),
CONSTRAINT `runs_flip_ibfk_1` FOREIGN KEY (`run_id`) REFERENCES `runs` (`id`) ON DELETE CASCADE
) ;
To make sure that subtables are correctly linked to the main table, you need to create two triggers for each table. Use this syntax:
First trigger
In the maintable
(f.e. runs
), you should specify an INSERT
/ AFTER
trigger (called it insert_id_to_subtable_runs_motor
):
BEGIN
IF NEW.task_name = 'motor'
THEN
INSERT INTO runs_motor (run_id) VALUES (NEW.id) ;
END IF;
END
You need to change:
task_name
to the column name in the main table'motor'
to the value it needs to matchruns_motor
is the name of the subtablerun_id
which should have the syntax(maintable)_id
(main table without trailings
)
If a condition matches multiple values, then you can use this syntax
BEGIN
IF NEW.task_name IN ('motor', 'sensory')
THEN
INSERT INTO runs_motor (run_id) VALUES (NEW.id) ;
END IF;
END
Second trigger
In the maintable
(f.e. runs
), you should specify an UPDATE
/ AFTER
trigger (called it replace_id_to_subtable_runs_motor
):
BEGIN
IF NEW.task_name <> OLD.task_name AND
NEW.task_name = 'motor' AND
NEW.id NOT IN (SELECT `run_id` FROM `runs_motor`)
THEN
INSERT INTO runs_motor (run_id) VALUES (NEW.id) ;
END IF;
END
Change the values as in the first trigger. The 3 conditions are:
- check that the main condition related to the subtable has changed
- check that the main condition has the correct value (you might need
IN
syntax instead of=
when you have multiple values) - check whether the
id
already exists in the subtable. This happens when the task wasmotor
, then it was changed to something else, then back tomotor
. The old info is still stored in the subtable even when the condition does not apply. This approach leaves some old data in the subtables (which is not shown and possibly not relevant) but it’s useful when a user changes the condition by mistake, and then goes back. It would be disappointing to add the info in the subtable again.
SQL examples
3T PRESTO
Update PRESTO sequence with the appropriate parameters:
UPDATE `recordings_mri` SET `SliceOrder` = '3D', `PhaseEncodingDirection` = 'PA', `SliceEncodingDirection` = 'RL' WHERE `Sequence` = '3T PRESTO';
3T T1w
If task is 3T T1w
, use this syntax
UPDATE `recordings_mri` SET `SliceOrder` = 'Sequential', `SliceEncodingDirection` = 'IS' WHERE `Sequence` = '3T T1w';
I don’t think that PhaseEncodingDirection
is relevant here.
FLAIR
If task is flair
, use this syntax
UPDATE `recordings_mri` SET `Sequence` = '3T FLAIR' WHERE `recording_id` IN (SELECT `id` FROM `recordings` WHERE `run_id` IN (SELECT `id` FROM `runs` WHERE `task_name` = 'flair_anatomy_scan'));
Recording Offset
Here is how to compute the offset for the recordings. Event should refer to the same event in the recordings (TRC) and in the run.events.
run = Run(db, id=i_run)
run_start = run.start_time
run_event = run.events[i_event_run]['onset']
d = Dataset(path_to_dat)
rec_start = d.header['start_time']
rec_event = d.read_markers()[i_event_dat]['start']
offset = (rec_start - run_start).total_seconds() + (rec_event - run_event)
print(offset)