Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[electrophysiology_browser] Replace Physiological Annotations with Events #9032

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 0 additions & 135 deletions SQL/0000-00-05-ElectrophysiologyTables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -382,105 +382,6 @@ CREATE TABLE `physiological_archive` (
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- SQL tables for BIDS derivative file structure
-- Create physiological_annotation_file_type table
CREATE TABLE `physiological_annotation_file_type` (
`FileType` VARCHAR(20) NOT NULL UNIQUE,
`Description` VARCHAR(255),
PRIMARY KEY (`FileType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Create physiological_annotation_file table
CREATE TABLE `physiological_annotation_file` (
`AnnotationFileID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`PhysiologicalFileID` INT(10) UNSIGNED NOT NULL,
`FileType` VARCHAR(20) NOT NULL,
`FilePath` VARCHAR(255),
`LastUpdate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`LastWritten` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`AnnotationFileID`),
CONSTRAINT `FK_phys_file_ID`
FOREIGN KEY (`PhysiologicalFileID`)
REFERENCES `physiological_file` (`PhysiologicalFileID`),
CONSTRAINT `FK_annotation_file_type`
FOREIGN KEY (`FileType`)
REFERENCES `physiological_annotation_file_type` (`FileType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Create annotation_archive which will store archives of all the annotation files for
-- Front-end download
CREATE TABLE `physiological_annotation_archive` (
`AnnotationArchiveID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`PhysiologicalFileID` INT(10) UNSIGNED NOT NULL,
`Blake2bHash` VARCHAR(128) NOT NULL,
`FilePath` VARCHAR(255) NOT NULL,
PRIMARY KEY (`AnnotationArchiveID`),
CONSTRAINT `FK_physiological_file_ID`
FOREIGN KEY (`PhysiologicalFileID`)
REFERENCES `physiological_file` (`PhysiologicalFileID`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Create annotation_parameter table
-- Note: This corresponds with the JSON annotation files
CREATE TABLE `physiological_annotation_parameter` (
`AnnotationParameterID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`AnnotationFileID` INT(10) UNSIGNED NOT NULL,
`Description` TEXT DEFAULT NULL,
`Sources` VARCHAR(255),
`Author` VARCHAR(255),
PRIMARY KEY (`AnnotationParameterID`),
CONSTRAINT `FK_annotation_file_ID`
FOREIGN KEY (`AnnotationFileID`)
REFERENCES `physiological_annotation_file` (`AnnotationFileID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Create an annotation_label_type table
CREATE TABLE `physiological_annotation_label` (
`AnnotationLabelID` INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
`AnnotationFileID` INT(10) UNSIGNED DEFAULT NULL,
`LabelName` VARCHAR(255) NOT NULL,
`LabelDescription` TEXT DEFAULT NULL,
PRIMARY KEY (`AnnotationLabelID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Create annotation_tsv table
-- Note: This corresponds with the .tsv annotation files
CREATE TABLE `physiological_annotation_instance` (
`AnnotationInstanceID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`AnnotationFileID` INT(10) UNSIGNED NOT NULL,
`AnnotationParameterID` INT(10) UNSIGNED NOT NULL,
`Onset` DECIMAL(10, 4),
`Duration` DECIMAL(10, 4) DEFAULT 0,
`AnnotationLabelID` INT(5) UNSIGNED NOT NULL,
`Channels` TEXT,
`AbsoluteTime` TIMESTAMP,
`Description` VARCHAR(255),
PRIMARY KEY (`AnnotationInstanceID`),
CONSTRAINT `FK_annotation_parameter_ID`
FOREIGN KEY (`AnnotationParameterID`)
REFERENCES `physiological_annotation_parameter` (`AnnotationParameterID`),
CONSTRAINT `FK_annotation_file`
FOREIGN KEY (`AnnotationFileID`)
REFERENCES `physiological_annotation_file` (`AnnotationFileID`),
CONSTRAINT `FK_annotation_label_ID`
FOREIGN KEY (`AnnotationLabelID`)
REFERENCES `physiological_annotation_label` (`AnnotationLabelID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Create physiological_annotation_rel table
CREATE TABLE `physiological_annotation_rel` (
`AnnotationTSV` INT(10) UNSIGNED NOT NULL,
`AnnotationJSON` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`AnnotationTSV`, `AnnotationJSON`),
CONSTRAINT `FK_AnnotationTSV`
FOREIGN KEY (`AnnotationTSV`)
REFERENCES `physiological_annotation_file` (`AnnotationFileID`),
CONSTRAINT `FK_AnnotationJSON`
FOREIGN KEY (`AnnotationJSON`)
REFERENCES `physiological_annotation_file` (`AnnotationFileID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Create EEG upload table
CREATE TABLE `electrophysiology_uploader` (
`UploadID` int(10) unsigned NOT NULL AUTO_INCREMENT,
Expand Down Expand Up @@ -634,39 +535,3 @@ INSERT INTO ImagingFileTypes
('edf', 'European data format (EEG)'),
('cnt', 'Neuroscan CNT data format (EEG)'),
('archive', 'Archive file');

-- Insert into annotation_file_type
INSERT INTO physiological_annotation_file_type
(FileType, Description)
VALUES
('tsv', 'TSV File Type, contains information about each annotation'),
('json', 'JSON File Type, metadata for annotations');

-- Insert into annotation_label_type
INSERT INTO physiological_annotation_label
(AnnotationLabelID, LabelName, LabelDescription)
VALUES
(1, 'artifact', 'artifactual data'),
(2, 'motion', 'motion related artifact'),
(3, 'flux_jump', 'artifactual data due to flux jump'),
(4, 'line_noise', 'artifactual data due to line noise (e.g., 50Hz)'),
(5, 'muscle', 'artifactual data due to muscle activity'),
(6, 'epilepsy_interictal', 'period deemed interictal'),
(7, 'epilepsy_preictal', 'onset of preictal state prior to onset of epilepsy'),
(8, 'epilepsy_seizure', 'onset of epilepsy'),
(9, 'epilepsy_postictal', 'postictal seizure period'),
(10, 'epileptiform', 'unspecified epileptiform activity'),
(11, 'epileptiform_single', 'a single epileptiform graphoelement (including possible slow wave)'),
(12, 'epileptiform_run', 'a run of one or more epileptiform graphoelements'),
(13, 'eye_blink', 'Eye blink'),
(14, 'eye_movement', 'Smooth Pursuit / Saccadic eye movement'),
(15, 'eye_fixation', 'Fixation onset'),
(16, 'sleep_N1', 'sleep stage N1'),
(17, 'sleep_N2', 'sleep stage N2'),
(18, 'sleep_N3', 'sleep stage N3'),
(19, 'sleep_REM', 'REM sleep'),
(20, 'sleep_wake', 'sleep stage awake'),
(21, 'sleep_spindle', 'sleep spindle'),
(22, 'sleep_k-complex', 'sleep K-complex'),
(23, 'scorelabeled', 'a global label indicating that the EEG has been annotated with SCORE.');

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- Dropping all tables regarding annotations
DROP TABLE physiological_annotation_archive;
DROP TABLE physiological_annotation_rel;
DROP TABLE physiological_annotation_instance;
DROP TABLE physiological_annotation_parameter;
DROP TABLE physiological_annotation_label;
DROP TABLE physiological_annotation_file;
DROP TABLE physiological_annotation_file_type;

-- Event files are always associated to Projects, sometimes exclusively (dataset-scope events.json files)
-- Add ProjectID and make PhysiologicalFileID DEFAULT NULL (ProjectID should ideally not be NULLable)
ALTER TABLE `physiological_event_file`
CHANGE `PhysiologicalFileID` `PhysiologicalFileID` int(10) unsigned DEFAULT NULL,
ADD COLUMN `ProjectID` int(10) unsigned DEFAULT NULL AFTER `PhysiologicalFileID`,
ADD KEY `FK_physiological_event_file_project_id` (`ProjectID`),
ADD CONSTRAINT `FK_physiological_event_file_project_id`
FOREIGN KEY (`ProjectID`) REFERENCES `Project` (`ProjectID`);
14 changes: 7 additions & 7 deletions modules/electrophysiology_browser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

The Electrophysiology Browser is intended to allow users to view candidate
electrophysiology (EEG, MEG...) sessions collected for a study and any associated
annotations for each recording.
events for each recording.

## Intended Users

The primary types of users are:
1. Electrophysiology researchers who want to know details about the inserted datasets.
2. Site coordinators or researchers ensuring the uploaded electrophysiology data have
been correctly inserted into LORIS.
been correctly inserted into LORIS.

## Scope

Expand All @@ -26,22 +26,22 @@ sufficient to provide access to view data in the module. The third permission pr
permissions to add or modify annotations for data from the sites the user has access to in this module.

electrophysiology_browser_view_allsites
- This permission gives the user access to all electrophysiology datasets present in the database.
- This permission gives the user access to all electrophysiology datasets present in the database.

electrophysiology_browser_view_site
- This permission gives the user access to electrophysiology datasets from their own site(s) only.
- This permission gives the user access to electrophysiology datasets from their own site(s) only.

electrophysiology_browser_edit_annotations
- This permission allows the user to add, edit, and delete annotations for raw or derived datasets
- This permission allows the user to add, edit, and delete annotations for raw or derived datasets

## Download

You can download all the files related to a recording (channel information,
electrode information, task event information, the actual recording) -- as well as its annotations and their related metadata.
electrode information, task event information, the actual recording) -- as well as its events and their related metadata.

## Updating Derivative Files

New annotations or edits to existing annotations made through the browser must also be updated in the derivative files stored in the filesystem, before a user tries to download a derivative file package. To do this automatically, a script is provided under `tools/update_annotation_files.php`, and a cron job should be set up to execute it regularly, e.g. every evening.
New events or edits to existing events made through the browser must also be updated in the derivative files stored in the filesystem, before a user tries to download a derivative file package. To do this automatically, a script is provided under `tools/update_event_files.php`, and a cron job should be set up to execute it regularly, e.g. every evening.

## Installation requirements to use the visualization features

Expand Down
74 changes: 60 additions & 14 deletions modules/electrophysiology_browser/css/electrophysiology_browser.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
}

.react-series-data-viewer-scoped .dropdown-menu li {
margin-top: 0;
margin: 0;
padding: 0 10px;
}

Expand All @@ -14,6 +14,38 @@
width: 100%;
}

.checkbox-flex-label > div > input[type="checkbox"] {
vertical-align: top;
}

.checkbox-flex-label {
display: flex;
align-items: center;
margin-bottom: 0;
justify-content: flex-end;
}

.btn-dropdown-toggle {
padding: 5px 10%;
}

.col-xs-12 > .btn-dropdown-toggle {
padding: 5px;
max-width: fit-content;
}

.col-xs-12 > .dropdown-menu {
width: max-content;
line-height: 14px;
padding: 0
}

.col-xs-12 > .dropdown-menu li {
margin: 0;
padding: 0;
}


.btn.btn-xs {
font-size: 12px;
}
Expand Down Expand Up @@ -46,42 +78,51 @@ svg:not(:root) {
overflow: clip;
}

.list-group-item {
.annotation.list-group-item {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 0;
width: 100%;
}

.annotation {
background: #fffae6;
border-left: 5px solid #ff6600;
border-left: 5px solid #8eecfa;
}

.epoch-details {
padding-right: 100px;
display: flex;
width: 100%;
padding: 10px 0;
}

.epoch-action {
display: flex;
flex-direction: row;
justify-content: center;
justify-content: end;
align-items: center;
position: absolute;
right: 10px;
}

.epoch-tag {
padding: 5px;
padding: 10px;
background: #e7e4e4;
border-left: 5px solid #797878;
word-wrap: break-word;
width: 100%;
}

.epoch-tag p {
word-wrap: break-word;
width: 95%;
.line-height-14 {
line-height: 14px;
}

.margin-top-10 {
margin-top: 10px;
}

.flex-basis-45 {
flex-basis: 45%
}

.event-list .btn.btn-primary {
Expand Down Expand Up @@ -111,8 +152,9 @@ svg:not(:root) {

.btn-zoom {
margin: 0 auto 3px auto;
width: 50px;
width: 55px;
text-align: center;
text-wrap: unset;
}

.col-xs-title {
Expand All @@ -139,7 +181,7 @@ svg:not(:root) {
.electrode:hover circle {
stroke: #064785;
cursor: pointer;
fill: #E4EBF2
fill: #E4EBF2;
}

.electrode:hover text {
Expand Down Expand Up @@ -181,6 +223,10 @@ svg:not(:root) {
width: auto;
}

.cursor-default {
cursor: default;
}

/* Custom, iPhone Retina */
@media only screen and (min-width : 320px) {
.pagination-nav {
Expand Down
4 changes: 2 additions & 2 deletions modules/electrophysiology_browser/help/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Files can be downloaded containing only the recording signal, the events, or oth
- EEG: the file containing the session recording data.
- Electrode info (tsv): contains electrode locations.
- Channels info (tsv): channel status and filter settings.
- Events (tsv): events (both stimuli and responses) recorded during the session.
- Annotations (tsv): annotations (both stimuli and responses) recorded during the session.
- Events (tsv): events (both stimuli and responses) recorded during the session.

Loading