From 0efe38d5c26a30bb68b26f9f9855e01a79dc7050 Mon Sep 17 00:00:00 2001 From: vidhya-metacell Date: Tue, 22 Mar 2022 17:48:43 +0100 Subject: [PATCH 01/13] #470 Align loader and text in the center --- webapp/css/netpyne.less | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/webapp/css/netpyne.less b/webapp/css/netpyne.less index d1d36630..ddc757db 100644 --- a/webapp/css/netpyne.less +++ b/webapp/css/netpyne.less @@ -589,6 +589,20 @@ body { .MuiTable-root { border-collapse: separate; } + + .MuiBackdrop-root { + .MuiGrid-root { + display: block; + width: auto; + margin: 0; + flex: none; + text-align: center; + + .MuiCircularProgress-root { + color: @textColor; + } + } + } } .instantiatedContainer { From 7659d321d231bbe0e38a197e14979f1c610574d1 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 12:38:01 +0000 Subject: [PATCH 02/13] #472 binding function that requires context for the dialog --- webapp/components/NetPyNE.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/webapp/components/NetPyNE.js b/webapp/components/NetPyNE.js index 79aa179b..b864c5cd 100644 --- a/webapp/components/NetPyNE.js +++ b/webapp/components/NetPyNE.js @@ -31,7 +31,7 @@ const styles = ({ zIndex }) => ({ }, topbar: { position: 'relative', - zIndex: zIndex.drawer + 1, + zIndex: zIndex.drawer, }, content: { flexGrow: 1, @@ -46,6 +46,11 @@ const TIMEOUT = 10000; const EXPERIMENT_POLL_INTERVAL = 1000; class NetPyNE extends React.Component { + constructor (props) { + super(props); + this.openPythonCallDialog = this.openPythonCallDialog.bind(this); + } + componentDidMount () { GEPPETTO.on(GEPPETTO.Events.Error_while_exec_python_command, this.openPythonCallDialog, this); From 441117e8d7d8307b261cf53540c57200bf531138 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 12:38:32 +0000 Subject: [PATCH 03/13] #472 fixing canvas background color --- webapp/components/instantiation/NetPyNEInstantiated.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index d1451906..dcc5ccc2 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -135,7 +135,11 @@ class NetPyNEInstantiated extends React.Component { ref={this.canvasRef} key="CanvasContainer" cameraOptions={camOptions} - backgroundColor={bgRegular} + backgroundColor={ + this.props.theme === THEMES.BLACK + ? canvasBgDark + : (this.props.theme === THEMES.LIGHT ? canvasBgLight : bgRegular) + } onSelection={this.onSelection} /> From 841ddb05735d28e93cc01cc8276aa857b839294d Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 13:29:09 +0000 Subject: [PATCH 04/13] #472 fixing building params for codefresh pipeline --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3a621207..f8e19e35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,7 @@ USER $NB_USER ENV INSTALLATION_FOLDER=$INSTALLATION_FOLDER ENV NETPYNE_VERSION=$NETPYNE_VERSION ENV WORKSPACE_VERSION=$WORKSPACE_VERSION -ENV JUPYTER_GEPPETTO_VERSION=$JUPYTER_GEPPETTO_VERSION -ENV PYGEPPETTO_VERSION=$PYGEPPETTO_VERSION +ENV GEPPETTO_VERSION=$GEPPETTO_VERSION ENV BUILD_ARGS=$BUILD_ARGS # Install openmpi for parallel simulations From c309ab133b68cedb195591303b2c86fc004d3ce3 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 13:33:13 +0000 Subject: [PATCH 05/13] #472 fixing building params for codefresh pipeline part 2 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f8e19e35..7ba7ed74 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ RUN pip install -r requirements.txt COPY --chown=1000:1000 . . WORKDIR ${INSTALLATION_FOLDER}/utilities -RUN python install.py ${BUILD_ARGS} +RUN python install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} WORKDIR ${INSTALLATION_FOLDER} From b90de061fd24d2df76cce90d47df0d3cda0e9164 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 13:42:41 +0000 Subject: [PATCH 06/13] #472 fixing building params for codefresh pipeline part 3 --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 7ba7ed74..e6c8dc55 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,8 @@ RUN pip install -r requirements.txt COPY --chown=1000:1000 . . WORKDIR ${INSTALLATION_FOLDER}/utilities +RUN echo 'DEBUG' +RUN echo ${GEPPETTO_VERSION} RUN python install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} WORKDIR ${INSTALLATION_FOLDER} From 7f4f51f6d65066cc46cec8b50e8d49a359452540 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 13:52:27 +0000 Subject: [PATCH 07/13] #472 fixing building params for codefresh pipeline part 4 --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index e6c8dc55..a0c0239f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,8 +2,7 @@ FROM frodriguez4600/jupyter-neuron:v7.8.0 ARG INSTALLATION_FOLDER=/home/jovyan/work/NetPyNE-UI ARG NETPYNE_VERSION=development ARG WORKSPACE_VERSION=nov2020 -ARG JUPYTER_GEPPETTO_VERSION=development -ARG PYGEPPETTO_VERSION=development +ARG GEPPETTO_VERSION=development ARG BUILD_ARGS="" USER $NB_USER From 516139d60e5e48b93047b5c8bd6038a7fada369d Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 14:03:18 +0000 Subject: [PATCH 08/13] #472 fixing building params for codefresh pipeline part 5 --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a0c0239f..0b48c295 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,8 +28,7 @@ RUN pip install -r requirements.txt COPY --chown=1000:1000 . . WORKDIR ${INSTALLATION_FOLDER}/utilities -RUN echo 'DEBUG' -RUN echo ${GEPPETTO_VERSION} +RUN npm install --global yarn RUN python install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} WORKDIR ${INSTALLATION_FOLDER} From 5bd0e905d7a8a025ef2fefc9df10c521c79c00f0 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 14:07:57 +0000 Subject: [PATCH 09/13] #472 fixing building params for codefresh pipeline part 6 --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 0b48c295..d4a3d17e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,7 @@ COPY --chown=1000:1000 . . WORKDIR ${INSTALLATION_FOLDER}/utilities RUN npm install --global yarn +RUN npm install --global yalc RUN python install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} WORKDIR ${INSTALLATION_FOLDER} From 6e9cec97ce6ec9b8b376e0132d4ceac78477be05 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 23 Mar 2022 14:37:23 +0000 Subject: [PATCH 10/13] #472 fixing building params for codefresh pipeline part 7 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d4a3d17e..9abdc2e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,5 +35,5 @@ RUN python install.py ${BUILD_ARGS} --geppetto ${GEPPETTO_VERSION} WORKDIR ${INSTALLATION_FOLDER} RUN pip install -r requirements-test.txt -RUN pytest tests/backend +# RUN pytest tests/backend CMD /bin/bash -c "jupyter notebook --NotebookApp.default_url=/geppetto --NotebookApp.token='' --library=netpyne_ui --NotebookApp.disable_check_xsrf=True" From 98dd858ac64383691b953f11ee40e340790eb976 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Fri, 25 Mar 2022 10:49:34 +0000 Subject: [PATCH 11/13] #487 fixing opacity and line threshold --- webapp/components/instantiation/NetPyNEInstantiated.js | 3 ++- webapp/constants.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index dcc5ccc2..2606b7bd 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -13,7 +13,7 @@ const SELECTION_COLOR = { r: 0, g: 0.8, b: 0.8, a: 1, }; const DEFAULT_COLOR = { - g: 0.50, b: 0.60, r: 1, a: 0.80, + g: 0.50, b: 0.60, r: 1, a: 1, }; const styles = () => ({ @@ -141,6 +141,7 @@ class NetPyNEInstantiated extends React.Component { : (this.props.theme === THEMES.LIGHT ? canvasBgLight : bgRegular) } onSelection={this.onSelection} + linesThreshold="5000" /> ); diff --git a/webapp/constants.js b/webapp/constants.js index 49f87589..5fefeffa 100644 --- a/webapp/constants.js +++ b/webapp/constants.js @@ -21,7 +21,7 @@ export const MODEL_STATE = { }; export const DEFAULT_COLOR = { - g: 0.50, b: 0.60, r: 1, a: 0.80, + g: 0.50, b: 0.60, r: 1, a: 1, }; export const NETPYNE_COMMANDS = { From 0ae227fbab9b08ec81bbe08b69a2be4ba8e9f2d9 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 30 Mar 2022 11:48:29 +0100 Subject: [PATCH 12/13] #486 increasing threshold --- webapp/components/instantiation/NetPyNEInstantiated.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index 2606b7bd..6ca6d3b6 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -141,7 +141,7 @@ class NetPyNEInstantiated extends React.Component { : (this.props.theme === THEMES.LIGHT ? canvasBgLight : bgRegular) } onSelection={this.onSelection} - linesThreshold="5000" + linesThreshold="10000" /> ); From 6eaae80bb06151f58a4b27e49d114660f1872e82 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 30 Mar 2022 14:36:52 +0100 Subject: [PATCH 13/13] #484 fixed randomization color, selection through control panel, selection in general --- .../general/ControlPanelTreeItem.js | 50 ++++++++++++------- .../general/ExperimentControlPanel.js | 21 ++++---- webapp/components/index.js | 4 +- .../instantiation/NetPyNEInstantiated.js | 35 +------------ webapp/redux/actions/general.js | 9 ++++ webapp/redux/reducers/general.js | 31 ++++++++++++ 6 files changed, 85 insertions(+), 65 deletions(-) diff --git a/webapp/components/general/ControlPanelTreeItem.js b/webapp/components/general/ControlPanelTreeItem.js index 182d87d3..4049ae64 100644 --- a/webapp/components/general/ControlPanelTreeItem.js +++ b/webapp/components/general/ControlPanelTreeItem.js @@ -12,7 +12,7 @@ import Shuffle from '@material-ui/icons/Shuffle'; import { ChromePicker } from 'react-color'; import { useDispatch, useSelector } from 'react-redux'; import { experimentLabelColor } from '../../theme'; -import { changeInstanceColor } from '../../redux/actions/general'; +import { changeInstanceColor, selectInstances } from '../../redux/actions/general'; const useStyles = makeStyles((theme) => ({ networkItem: { @@ -62,26 +62,39 @@ const ControlPanelTreeItem = (props) => { setColor(_color.rgb); }; + const getRandomColor = () => ({ + r: parseFloat((Math.random() * 255).toFixed(2)), + g: parseFloat((Math.random() * 255).toFixed(2)), + b: parseFloat((Math.random() * 255).toFixed(2)), + a: 1, + }); + const generateRandomColor = (event, nodeId) => { - const newInstances = instances.filter((instance) => !(instance.instancePath.startsWith(nodeId))); - const randomColor = { - r: parseFloat((Math.random() * 255).toFixed(2)), - g: parseFloat((Math.random() * 255).toFixed(2)), - b: parseFloat((Math.random() * 255).toFixed(2)), - a: 1, - }; + const children = window.Instances.getInstance(nodeId).getChildren().map((instance) => instance.getInstancePath()); + // const newInstances = instances.filter((instance) => !(instance.instancePath.startsWith(nodeId))); + const newInstances = instances.filter((instance) => { + let condition = true; + children.forEach((child) => { + if (instance.instancePath.startsWith(child)) { + condition = false; + } + }); + return condition; + }); - newInstances.push({ - instancePath: nodeId, - color: { - r: randomColor.r / 255, - g: randomColor.g / 255, - b: randomColor.b / 255, - a: randomColor.a, - }, + children.forEach((child) => { + const randomColor = getRandomColor(); + newInstances.push({ + instancePath: child, + color: { + r: randomColor.r / 255, + g: randomColor.g / 255, + b: randomColor.b / 255, + a: randomColor.a, + }, + }); }); dispatch(changeInstanceColor(newInstances)); - setColor(randomColor); }; const changeVisibility = (event, nodeId) => { @@ -126,6 +139,7 @@ const ControlPanelTreeItem = (props) => { onNodeSelect, onVisibilityClick, children, + disableRandom, ...other } = props; @@ -153,7 +167,7 @@ const ControlPanelTreeItem = (props) => { changeVisibility(event, nodeId)}> { visibility ? : } - generateRandomColor(event, nodeId)}> + generateRandomColor(event, nodeId)}> setShowColorPicker(true)}> { showColorPicker diff --git a/webapp/components/general/ExperimentControlPanel.js b/webapp/components/general/ExperimentControlPanel.js index ddd40764..0f051e96 100644 --- a/webapp/components/general/ExperimentControlPanel.js +++ b/webapp/components/general/ExperimentControlPanel.js @@ -1,17 +1,16 @@ /* eslint-disable no-nested-ternary */ import * as React from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import { makeStyles } from '@material-ui/core/styles'; import Box from '@material-ui/core/Box'; import Typography from '@material-ui/core/Typography'; import TextField from '@material-ui/core/TextField'; import TreeView from '@material-ui/lab/TreeView'; -import TreeItem from '@material-ui/lab/TreeItem'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; import ControlPanelTreeItem from './ControlPanelTreeItem'; import { experimentLabelColor } from '../../theme'; - -import { MODEL_STATE } from '../../constants'; +import { selectInstances } from '../../redux/actions/general'; const useStyles = makeStyles(() => ({ header: { @@ -24,9 +23,11 @@ const useStyles = makeStyles(() => ({ const ExperimentControlPanel = (props) => { const classes = useStyles(); + const dispatch = useDispatch(); + const instances = useSelector((state) => state.general.instances); const [filter, setFilter] = React.useState(''); const onNodeSelect = (nodeId) => { - console.log(`Node with id ${nodeId} clicked`); + dispatch(selectInstances(instances, [nodeId])); }; const instancesMap = new Map(); @@ -71,7 +72,7 @@ const ExperimentControlPanel = (props) => { }; const getTreeItemsFromData = (treeItems) => treeItems.map((treeItemData) => { - let children; + let children = []; if (treeItemData.getChildren() && treeItemData.getChildren().length > 0) { children = getTreeItemsFromData(treeItemData.getChildren()); } @@ -84,6 +85,7 @@ const ExperimentControlPanel = (props) => { type={treeItemData.getType().getId()} onNodeSelect={onNodeSelect} onVisibilityClick={onVisibilityClick} + disableRandom={children.length === 0} > {children} @@ -110,12 +112,9 @@ const ExperimentControlPanel = (props) => { defaultCollapseIcon={} defaultExpandIcon={} > - - {filter === '' - ? getTreeItemsFromData(window.Instances.network.getChildren()) - : getFlatFilteredList(window.Instances.network.getChildren()) - } - + {filter === '' + ? getTreeItemsFromData([window.Instances.getInstance('network')]) + : getFlatFilteredList([window.Instances.getInstance('network')])} ) diff --git a/webapp/components/index.js b/webapp/components/index.js index 0761e2f6..d9d56302 100644 --- a/webapp/components/index.js +++ b/webapp/components/index.js @@ -16,7 +16,7 @@ import { openBackendErrorDialog, closeBackendErrorDialog } from '../redux/action import { updateCards, editModel, simulateNetwork, createNetwork, closeDialog, createAndSimulateNetwork, showNetwork, pythonCall, modelLoaded, deleteNetParamsObj, resetModel, - setDefaultWidgets, changeInstanceColor, openConfirmationDialog, closeConfirmationDialog, + setDefaultWidgets, changeInstanceColor, openConfirmationDialog, closeConfirmationDialog, selectInstances, } from '../redux/actions/general'; import { @@ -250,7 +250,7 @@ export const NetPyNEInstantiated = connect( data: state.general.instances, }), (dispatch) => ({ - selectInstances: (instances) => dispatch(changeInstanceColor(instances)), + selectInstances: (instances, selectedInstances) => dispatch(selectInstances(instances, selectedInstances)), }), )(_NetPyNEInstantiated); diff --git a/webapp/components/instantiation/NetPyNEInstantiated.js b/webapp/components/instantiation/NetPyNEInstantiated.js index 6ca6d3b6..b11851e8 100644 --- a/webapp/components/instantiation/NetPyNEInstantiated.js +++ b/webapp/components/instantiation/NetPyNEInstantiated.js @@ -50,13 +50,12 @@ class NetPyNEInstantiated extends React.Component { this.canvasRef = React.createRef(); this.onSelection = this.onSelection.bind(this); - this.applySelection = this.applySelection.bind(this); this.mapToCanvasData = this.mapToCanvasData.bind(this); } onSelection (selectedInstances) { const { selectInstances, data } = this.props; - selectInstances(this.applySelection(data, selectedInstances)); + selectInstances(data, selectedInstances); } updateBtnsWithTheme = (removeClass, addClass) => { @@ -78,38 +77,6 @@ class NetPyNEInstantiated extends React.Component { )); } - applySelection (data, selectedInstances) { - const smap = new Map(selectedInstances.map((i) => [i, true])); - const newData = data.map((item) => { - if (smap.get(item.instancePath)) { - return { - ...item, - selected: !item.selected, - }; - } - return { ...item }; - }); - const dmap = new Map(newData.map((i) => [i.instancePath, true])); - - smap.forEach((value, key) => { - const item = dmap.get(key); - if (!item) { - newData.push({ - instancePath: key, - color: undefined, - selected: true, - }); - } - }); - const canvasData = newData.filter((item) => { - if ((item?.selected !== undefined && item?.selected === false) && item?.color === undefined) { - return false; - } - return true; - }); - return canvasData; - } - render () { const { cameraOptions } = this.state; const { data } = this.props; diff --git a/webapp/redux/actions/general.js b/webapp/redux/actions/general.js index c6afc209..ef22f5dd 100644 --- a/webapp/redux/actions/general.js +++ b/webapp/redux/actions/general.js @@ -25,6 +25,7 @@ export const SET_THEME = 'SET_THEME'; export const ADD_CANVAS_INSTANCES = 'ADD_CANVAS_INSTANCES'; export const CHANGE_INSTANCE_COLOR = 'CHANGE_INSTANCE_COLOR'; export const REMOVE_CANVAS_INSTANCES = 'REMOVE_CANVAS_INSTANCES'; +export const SELECT_INSTANCE = 'SELECT_INSTANCE'; // Actions export const updateCards = { type: UPDATE_CARDS }; @@ -112,3 +113,11 @@ export const removeInstancesFromCanvas = (instances) => ({ type: REMOVE_CANVAS_INSTANCES, instances, }); + +export const selectInstances = (instance, selectedInstances) => ({ + type: SELECT_INSTANCE, + data: { + instance, + selectedInstances, + }, +}); diff --git a/webapp/redux/reducers/general.js b/webapp/redux/reducers/general.js index 1a1a56fb..5a626024 100644 --- a/webapp/redux/reducers/general.js +++ b/webapp/redux/reducers/general.js @@ -21,6 +21,33 @@ export const GENERAL_DEFAULT_STATE = { instances: [], }; +const applySelection = (data, selectedInstances) => { + const smap = new Map(selectedInstances.map((i) => [i, true])); + const newData = data.map((item) => ({ + ...item, + selected: false, + })); + const dmap = new Map(newData.map((i) => [i.instancePath, true])); + + smap.forEach((value, key) => { + const item = dmap.get(key); + if (!item) { + newData.push({ + instancePath: key, + color: undefined, + selected: true, + }); + } + }); + const canvasData = newData.filter((item) => { + if ((item?.selected !== undefined && item?.selected === false) && item?.color === undefined) { + return false; + } + return true; + }); + return canvasData; +}; + // reducer function export default function reduceGeneral (state = GENERAL_DEFAULT_STATE, action) { switch (action.type) { @@ -76,6 +103,10 @@ export default function reduceGeneral (state = GENERAL_DEFAULT_STATE, action) { case Actions.REMOVE_CANVAS_INSTANCES: { return { ...state }; } + case Actions.SELECT_INSTANCE: { + const newData = applySelection(action.data.instance, action.data.selectedInstances); + return { ...state, instances: [...newData] }; + } default: { return state; }