Skip to content

Commit

Permalink
[EEG Browser] Automate viz install process in npm postinstall script (#…
Browse files Browse the repository at this point in the history
…8263)

Integrate the EEG visualization postinstall step into npm-postinstall.js.
This simplifies the EEG vis setup by eliminating the need to edit the package.json file.

New steps to enable the EEG visualization:

- set the new config (GUI/useEEGBrowserVisualizationComponents) to on/off.
- make dev or npm install && npm run compile

This new config will be used later on the LORIS-MRI side to decide if eeg chunks should be generated or not.
  • Loading branch information
laemtl authored Dec 12, 2022
1 parent e8f26a9 commit 96a1d5d
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 105 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/loristest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on:
- push
- pull_request

env:
EEG_VIS_ENABLED: 'true'

jobs:
build:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions SQL/0000-00-03-ConfigTables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ INSERT INTO ConfigSettings (Name, Description, Visible, AllowMultiple, Label, Or
INSERT INTO ConfigSettings (Name, Description, Visible, AllowMultiple, DataType, Parent, Label, OrderNumber) SELECT 'css', 'CSS file used for rendering (default main.css)', 1, 0, 'text', ID, 'CSS file', 1 FROM ConfigSettings WHERE Name="gui";
INSERT INTO ConfigSettings (Name, Description, Visible, AllowMultiple, DataType, Parent, Label, OrderNumber) SELECT 'rowsPerPage', 'Number of table rows to display per page', 1, 0, 'text', ID, 'Table rows per page', 2 FROM ConfigSettings WHERE Name="gui";
INSERT INTO ConfigSettings (Name, Description, Visible, AllowMultiple, DataType, Parent, Label, OrderNumber) SELECT 'StudyDescription', 'Description of the Study', 1, 0, 'textarea', ID , 'Study Description', 2 FROM ConfigSettings WHERE Name="gui";
INSERT INTO ConfigSettings (Name, Description, Visible, AllowMultiple, DataType, Parent, Label, OrderNumber) SELECT 'useEEGBrowserVisualizationComponents', 'Whether to enable the visualization components on the EEG Browser module', 1, 0, 'boolean', ID, 'Enable the EEG Browser components', 4 FROM ConfigSettings WHERE Name="gui";


INSERT INTO ConfigSettings (Name, Description, Visible, AllowMultiple, Label, OrderNumber) VALUES ('www', 'Web address settings', 1, 0, 'WWW', 4);
Expand Down Expand Up @@ -215,6 +216,7 @@ INSERT INTO Config (ConfigID, Value) SELECT ID, "%MINCToolsPath%" FROM ConfigSet

INSERT INTO Config (ConfigID, Value) SELECT ID, "main.css" FROM ConfigSettings WHERE Name="css";
INSERT INTO Config (ConfigID, Value) SELECT ID, 25 FROM ConfigSettings WHERE Name="rowsPerPage";
INSERT INTO Config (ConfigID, Value) SELECT ID, 'false' FROM ConfigSettings WHERE Name="useEEGBrowserVisualizationComponents";

INSERT INTO Config (ConfigID, Value) SELECT ID, "localhost" FROM ConfigSettings WHERE Name="host";

Expand Down
27 changes: 27 additions & 0 deletions SQL/New_patches/2022-12-05-AddVizConfig.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-- Adds the option to toggle the EEG Browser visualization components (disabled by default).
INSERT INTO ConfigSettings
(
Name,
Description,
Visible,
AllowMultiple,
DataType,
Parent,
Label,
OrderNumber
)
SELECT
'useEEGBrowserVisualizationComponents',
'Whether to enable the visualization components on the EEG Browser module',
1,
0,
'boolean',
ID,
'Enable the EEG Browser components',
4
FROM
ConfigSettings
WHERE
Name="gui";

INSERT INTO Config (ConfigID, Value) SELECT ID, 'false' FROM ConfigSettings WHERE Name="useEEGBrowserVisualizationComponents";
12 changes: 3 additions & 9 deletions modules/electrophysiology_browser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,9 @@ electrode information, task event information, the actual recording) -- as well

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.

## <a name="installation-requirements-to-use-the-visualization-features"></a> Installation requirements to use the visualization features
The visualization component requires Protocol Buffers v3.0.0 or higher.
## Installation requirements to use the visualization features
The visualization components require Protocol Buffers v3.0.0 or higher.
For install instructions, you can refer to the Protocol Buffers GitHub page: https://github.com/protocolbuffers/protobuf

In order to automatically generate the protoc compiled files, add the following block in `modules/electrophysiology_browser/jsx/react-series-data-viewer/package.json`:
```
"scripts": {
"postinstall": "protoc protocol-buffers/chunk.proto --js_out=import_style=commonjs,binary:./src/"
}
```
and run `make dev` or 'npm install && npm run compile' from the loris root directory.
To enable the visualization components, set the useEEGBrowserVisualizationComponents config (Configuration/GUI) to true and run `make dev` or 'npm install && npm run compile' from the loris root directory.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* global EEG_VIS_ENABLED */

/**
* This is the React class for the eeg_session.
*
Expand All @@ -16,12 +18,21 @@ import {SummaryPanel} from './components/electrophysiology_session_summary';
import {DownloadPanel} from './components/DownloadPanel';
import Sidebar from './components/Sidebar';
import SidebarContent from './components/SidebarContent';
import EEGLabSeriesProvider
from './react-series-data-viewer/src/eeglab/EEGLabSeriesProvider';
import SeriesRenderer
from './react-series-data-viewer/src/series/components/SeriesRenderer';
import EEGMontage
from './react-series-data-viewer/src/series/components/EEGMontage';

let EEGLabSeriesProvider;
let SeriesRenderer;
let EEGMontage;
if (EEG_VIS_ENABLED) {
EEGLabSeriesProvider = require(
'./react-series-data-viewer/src/eeglab/EEGLabSeriesProvider'
).default;
SeriesRenderer = require(
'./react-series-data-viewer/src/series/components/SeriesRenderer'
).default;
EEGMontage = require(
'./react-series-data-viewer/src/series/components/EEGMontage'
).default;
}

/**
* Electrophysiology Session View page
Expand Down Expand Up @@ -350,6 +361,7 @@ class ElectrophysiologySessionView extends Component {
title={this.state.database[i].file.name}
data={this.state.database[i].file.details}
>
{EEG_VIS_ENABLED &&
<div className="react-series-data-viewer-scoped col-xs-12">
<EEGLabSeriesProvider
chunksURL={
Expand Down Expand Up @@ -441,7 +453,7 @@ class ElectrophysiologySessionView extends Component {
</div>
</div>
</EEGLabSeriesProvider>
</div>
</div>}
</FilePanel>
</div>
);
Expand Down
88 changes: 76 additions & 12 deletions npm-postinstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,39 @@ const fs = require('fs');
const path = require('path');
const cp = require('child_process');

const submodules = [
'project',
'modules/electrophysiology_browser/jsx/react-series-data-viewer',
];

submodules.forEach((submodule) => {
// Check if the submodule is in modules/, and has an override
const submodulePath = submodule.split(path.sep);
/**
* Check if the path provided is a module and has an override
* in project. If so, returns the override path
* @param {string} p
* @return {string}
*/
const getPath = (p) => {
const pathParts = p.split(path.sep);

if (
submodulePath[0] === 'modules' &&
fs.existsSync(path.join(__dirname, 'project', 'modules', submodulePath[1]))
pathParts[0] === 'modules' &&
fs.existsSync(path.join(__dirname, 'project', 'modules', pathParts[1]))
) {
submodule = path.join('project', submodule);
return path.join('project', p);
}

submodule = path.join(__dirname, submodule);
return p;
};

/*
* ----------------------------------------
* Install npm packages in LORIS submodules
* ----------------------------------------
*/
const eegVisualization =
'modules/electrophysiology_browser/jsx/react-series-data-viewer';
const submodules = [
'project',
eegVisualization,
];

submodules.forEach((submodule) => {
submodule = path.join(__dirname, getPath(submodule));

// ensure submodule has package.json
if (!fs.existsSync(path.join(submodule, 'package.json'))) return;
Expand Down Expand Up @@ -47,3 +63,51 @@ submodules.forEach((submodule) => {
);
});

/*
* ------------------------------------------------------------
* Check if useEEGBrowserVisualizationComponents is set to TRUE
* If so, compile the protobuf file to enable the components to load
* ------------------------------------------------------------
*/
const getConfig = cp.spawn('php', [
'tools/get_config.php',
'useEEGBrowserVisualizationComponents',
], {});

getConfig.stdout.on('data', (data) => {
const EEGVisEnabled = JSON.parse(data);
if (EEGVisEnabled === 'true') {
console.info('\n ----- \n >> '
+ 'EEG Browser visualization components enabled '
+ '\n -----'
);

const eegVizSubmodule = path.join(__dirname, getPath(eegVisualization));

const protoc = cp.spawn(
'protoc',
[
'protocol-buffers/chunk.proto',
'--js_out=import_style=commonjs,binary:./src/',
],
{
env: process.env,
cwd: eegVizSubmodule,
stdio: 'inherit',
}
);

protoc.on('error', (error) => {
console.error('ERROR: '
+ 'Make sure that protoc '
+ '(https://github.com/protocolbuffers/protobuf/releases/) '
+ 'is installed on your system '
);
console.error(error);
});
}
});

getConfig.on('error', (error) => {
console.error(error);
});
62 changes: 0 additions & 62 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"eslint-plugin-no-jquery": "^2.6.0",
"eslint-plugin-react": "^7.16.0",
"eslint-webpack-plugin": "2.1.0",
"null-loader": "^4.0.1",
"style-loader": "^1.1.3",
"terser-webpack-plugin": "^5.3.6",
"ts-loader": "^8.3.0",
Expand Down
1 change: 1 addition & 0 deletions raisinbread/RB_files/RB_Config.sql
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,6 @@ INSERT INTO `Config` (`ID`, `ConfigID`, `Value`) VALUES (117,117,'');
INSERT INTO `Config` (`ID`, `ConfigID`, `Value`) VALUES (118,118,'');
INSERT INTO `Config` (`ID`, `ConfigID`, `Value`) VALUES (119,119,'');
INSERT INTO `Config` (`ID`, `ConfigID`, `Value`) VALUES (120,120,'database_config.py');
INSERT INTO `Config` (`ID`, `ConfigID`, `Value`) VALUES (121,125,'false');
UNLOCK TABLES;
SET FOREIGN_KEY_CHECKS=1;
1 change: 1 addition & 0 deletions raisinbread/RB_files/RB_ConfigSettings.sql
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMult
INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMultiple`, `DataType`, `Parent`, `Label`, `OrderNumber`) VALUES (40,'css','CSS file used for rendering (default main.css)',1,0,'text',39,'CSS file',1);
INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMultiple`, `DataType`, `Parent`, `Label`, `OrderNumber`) VALUES (41,'rowsPerPage','Number of table rows to display per page',1,0,'text',39,'Table rows per page',2);
INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMultiple`, `DataType`, `Parent`, `Label`, `OrderNumber`) VALUES (42,'StudyDescription','Description of the Study',1,0,'textarea',39,'Study Description',2);
INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMultiple`, `DataType`, `Parent`, `Label`, `OrderNumber`) VALUES (125,'useEEGBrowserVisualizationComponents','Whether to enable the visualization components on the EEG Browser module',1,0,'boolean',39,'Enable the EEG Browser components',4);
INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMultiple`, `DataType`, `Parent`, `Label`, `OrderNumber`) VALUES (43,'www','Web address settings',1,0,NULL,NULL,'WWW',4);
INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMultiple`, `DataType`, `Parent`, `Label`, `OrderNumber`) VALUES (44,'host','Host',1,0,'text',43,'Host',1);
INSERT INTO `ConfigSettings` (`ID`, `Name`, `Description`, `Visible`, `AllowMultiple`, `DataType`, `Parent`, `Label`, `OrderNumber`) VALUES (46,'mantis_url','Bug tracker URL',0,0,'text',43,'Bug tracker URL',3);
Expand Down
20 changes: 20 additions & 0 deletions tools/get_config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env php
<?php declare(strict_types=1);
require_once __DIR__ . "/../vendor/autoload.php";
require_once __DIR__ . "/generic_includes.php";

/**
* This script is used to get configuration settings from LORIS db.
* "Usage: php get_config.php configName"
*
* @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3
*/

const MIN_NUMBER_OF_ARGS = 2;
if (count($argv) < MIN_NUMBER_OF_ARGS) {
throw new Exception('Missing config name');
}

$configName = $argv[1];
$configValue = $config->getSetting($configName);
echo json_encode($configValue, JSON_THROW_ON_ERROR);
Loading

0 comments on commit 96a1d5d

Please sign in to comment.