Real-time Medical Image Collaboration POC Made Easy with OHIF and Nun-db
Remotely controlling medical imaging visualization enables many use cases; for example, in education, the professor can ask all students to open the same study and manipulate the image from their computers at the lab, and all students can see it reflected immediately on their screens. Or, for example, in collaboration between two doctors while analyzing a patient case.
OHIF and Nun-db
OHIF (Open Health Imaging Foundation) is a widely used open-source platform for medical imaging visualization tools, and it has mature extension and event capabilities, making it simple to enable such use cases. Using Nun-db and its real-time data synchronization, we can easily implement such use cases using fully open-source solutions (both are licensed under MIT).
How it works?
Let’s make it happen
This tutorial is based on OHIF master version 3.7.0-beta.86, but it should work with any recent version since it does not rely on special new features.
Cloning OHIF
git clone git@github.com:OHIF/Viewers.git cd Viewers&&yarn install yarn start
Link the Nun-db library to the OHIF repo
Link the lib using the OHIF cli
tool.
yarn cli add-extension ohif-nun-db
Diff of the change
diff --git a/platform/app/pluginConfig.json b/platform/app/pluginConfig.json index 08a42deb0..47ce44fd4 100644 --- a/platform/app/pluginConfig.json +++ b/platform/app/pluginConfig.json @@ -51,6 +51,10 @@ "packageName": "@ohif/extension-cornerstone-dicom-rt", "default": false, "version": "3.0.0" + }, + { + "packageName": "ohif-nun-db", + "version": "1.2.4" } ], "modes": [
Amazing, we are almost there. Let’s configure OHIF to access the correct instance of Nun-db. in this first part, we will use the cloud-hosted Nun-db, and in the last part of the tutorial, we will show how to connect to a local running version.
For that you have to change the file platform/app/public/config/default.js
and add the Nun-db configuration to the end of the file.
Configuring OHIF to access Nun-db
window.config = { //.. Omitted for simplicity dataSources: [ //... Omitted for simplicity ], hotkeys: [ //... Omitted for simplicity ], nunDb: { url: 'wss://ws-staging.nundb.org', // Nun-db server address db: 'features-of-db',// Nun-db Db instance user: 'client', // Nun-db db user token: 'client-pwd',// Nun-db user token key: 'client-YOUR_NAME_HERE', // Replace this key to a unique one }, };
Diff of the config change
diff --git a/platform/app/public/config/default.js b/platform/app/public/config/default.js index 0001352..c98de30 100644 --- a/platform/app/public/config/default.js +++ b/platform/app/public/config/default.js @@ -230,4 +230,11 @@ window.config = { keys: ['9'], }, ], + nunDb: { + url: 'wss://ws-staging.nundb.org', + db: 'features-of-db', + user: 'client', + token: 'client-pwd', + key: 'client-YOUR_NAME_HERE', + }, };
Stop and restart your yarn start process.
# Kill old yarn start process yarn start
Change the YOUR_NAME_HERE
to a unique value (maybe use your GitHub name).
At this point, you should be able to see it working as expected; let’s test it. Open http://localhost:3000 at your machine browser and see it in action.
If you want to see an repo configured up to this point here it is, and here is the commit, with all changes you must have up to this point (You can ignore yarn.lock
changes).
From this point ahead is optional only if you want to run Nun-db locally or understand how this work and the limitation of this POC implementation.
Advance topics
Running your own Nun-db instance with docker
To execute this POC fully in your computer or infra, you will need to run your own Nun-db instance for that, the simplest form is using docker
, Next I am showing the command to get it running.
docker run --env NUN_USER=user-name --env NUN_PWD=user-pwd --env NUN_DBS_DIR="/data" --mount type=bind,source="/tmp",target=/data -it --rm -p 3013:3013 -p 3012:3012 -p 3014:3014 --name nun-test mateusfreira/nun-db
Next, we need to create the database and the user and set the proper permissions for this tutorial to work. This may sound complex, so if you want to understand deeper how to manipulate users in Nun-db, read this tutorial.
docker exec -it nun-test /bin/sh -c 'nun-db -u user-name -p user-pwd create-db -d features-ohif-db -t features-ohif-db-pwd&&nun-db -u user-name -p user-pwd exec "use features-of-db features-of-db-pwd; create-user client client-pwd;set-permissions client r *|rwx client-*;"'
You should see the following response if the command works as expected.
[2023-09-24T21:32:22.005972013Z nun_db] nundb starting! Response "valid auth\n;create-db success\n" [2023-09-24T21:32:22.328383888Z nun_db] nundb starting! Response "valid auth\n;empty;empty;empty"
Now, to connect to your local Nun-db instead of the Cloud Nun-db, you just have to change the URL to point to local. This change will be in the file platform/app/public/config/default.js
and the parameter nunDb.url
must be changed from wss://ws-staging.nundb.org
to ws://localhost:3012
(port 3012 is the default websocket port for Nun-db). If you are testing this in your internal network, make sure to change the localhost
to the machine’s network IP.
How does it work internally ? (If you want to replicate with different backends)
The main mechanism to enable this implementation are 2 cornerstone APIs.
- First one is the event
CAMERA_MODIFIED
Documentation here, that triggers on the HTML element when the viewport camera changes. We leverage that event to propagate in the network the same camera state using Nun-Dbs watch capabilities, in the code Here Here you can find we binding the event from the viewport and applying the value to Nun-db here. That will ensure that any change made in one client will be stored and therefore replicated to other connected clients. This process is shown in the Next image.
- On the other side, every time the key
${window.config.nunDb.key}-camera
changes we want to use the API setCamera to apply the same state in the other clients. We do that by watching the changes coming from Nun-db here, and apply it on the other side here after that you have torender
the viewport again we do that here.
There are other smaller details in the implementation to avoid infinite loops of change and also to sync currentImageIdIndex
, setting here and watching there.
Limitations
This was a proof of concept and by no means ready for production usage. Nevertheless, it shows the capabilities of Nun-db to quickly enable such use cases. Please email me if you need help replicating this; next, I am adding a few current implementation limitations.
- Works with a single viewport.
- Does not sync the series opening.
Update 1
- We also implemented tools to enable and disable the live sync and here you can find an example of how to add that to your hotkey bindings.
Future Work ideas
- Enable remote replication of Hanging Protocol.
- Remote replicate tool enabling (add a button to enable and disable the sync).
- Show the other actor’s mouse position.
- Add some visual indication that the sync is enabled.
Conclusion
In this tutorial, we aim to demonstrate how to connect OHIF to Nun-db to enable live sync use cases. Though simple to do, we also tried to show the means we used to create the POC and also make sure that if someone wants to replicate with different backends, they can use this as an example.
Important links
- Code Coverage for Rust Projects with GitHub Actions
- NunDb is now referenced in the Database of Databases
- Real-time Medical Image Collaboration POC Made Easy with OHIF and Nun-db
- How to create users with different permission levels in Nun-db
- Match vs Hashmap! Which one is faster in rust?
- Towards a More Secure Nun-db: Our Latest Security Enhancements
- Building a Trello-like React/Redux App with NunDB with offline and conflict resolution features
- Introduction to managing conflicts in NunDB
- Keepin up with Nun-db 2023
- The new storage engine of Nun-db
- Stop procrastinating and just fix your flaky tests, it may be catching nasty bugs
- An approach to hunt and fix non-reproducible bugs - Case study - Fixing a race conditions in Nun-db replication algorithm in rust
- NunDB the debug command
- Keeping up with Nun-db 2021
- Writing a prometheus exporter in rust from idea to grafana chart
- Integration tests in rust a multi-process test example
- Leader election in rust the journey towards implementing nun-db leader election
- How to make redux TodoMVC example a real-time multiuser app with nun-db in 10 steps
- A fast-to-sync/search and space-optimized replication algorithm written in rust, The Nun-db data replication model
- NunDb How to backup one or all databases
- How to create your simple version of google analytics real-time using Nun-db
- Migrating a chat bot feature from Firebase to Nun-db
- Keepin' up with NunDB
- Going live with NunDB