feat: cornerstone3D stack and volume viewports (#2787)
* feat: cs3d working stack viewport and tools (#19) * Squashed everything * fix weird react issue * fix eslint / prettier stuff * thumbnails work now with cpu rendering * feat: use new loadImageToCanvas in cs3d * make jump to measurement work * fix active thumbnail * fix measurement delete * fix window level presets * remove segmentation and sync groups for now * fix the dicom pdf and dicom video * fix cornerstone window assignment for cypress * apply review comments Co-authored-by: Erik <erik.sweed@gmail.com> * feat: cs3d tools and toolGroups (#20) * add more tools to work with cs3d mode * fix hotkeys * add stack manager usage for stach viewports * add image scrollbar * wip viewport overlay * fix toAnnotation schema for tools * fix the unnecessary size change that triggered resize * hanging protocol improvement to allow unmatched errors * study description matching for hanging protocol * fix the displaysetOptions to work * fix handle the active tool when a new viewport is added * fix separate toolGroups for mode * apply review comments * apply review comments * yarn lock * feat: overlay component (#21) * fix default displayset options * add viewport overlay * apply review comments * feat: loading and orientation indicators (#22) * add loading indicator * add orientation marker initial work * apply review comments * fix: orientation markers (#23) * finished the orientation markers * fix various broken cypress tests * apply review comments * update yarn lock * feat: re-working measurement tracking mode with cornerstone3d (#2805) * feat: cs3d working stack viewport and tools (#19) * Squashed everything * fix weird react issue * fix eslint / prettier stuff * thumbnails work now with cpu rendering * feat: use new loadImageToCanvas in cs3d * make jump to measurement work * fix active thumbnail * fix measurement delete * fix window level presets * remove segmentation and sync groups for now * fix the dicom pdf and dicom video * fix cornerstone window assignment for cypress * apply review comments Co-authored-by: Erik <erik.sweed@gmail.com> * feat: Add Measurement tracking mode with cs3D (#2789) * feat: first render for cornerstone3d tracked viewport * make tool active work * wip for SR extension * renamed dicom sr to cornerstone dicom sr * remove cornerstone from dicom pdf and video * move dicom sr logic to sr extension * feat: Add hydration for the length tool * fix SR display tool for length using cs3d * fix default config * fix: various bugs with sr viewport and tracking * fix promptying to continue tracking for when SR is created * feat: add keep trackign of unique identifiers * fix hydration for same imageIds * feat: Add SR toolGroup creation on modeEnter * feat: remove the need for separate mapper for SR hydration * add SR display for ellipse * handle hydration of elliptical ROI tool * remove cornerstone extension * add arrow mapping * feat: Add ArrowAnnotate SR display and hydration * apply review comments * apply review comments * move viewport labels to the viewportData * apply review comments * fix: integration cypress tests with cornerstone3D and add CINE tool (#2795) * fix: integration cypress tests with cornerstone3D * revert to addOrUpdate as it makes more sense * fix local drag and drop * fix tests * move dicomLoaderService to cornerstone extension * fix various import bugs * fix bug for local PT series * fix various unit tests * bump cs3d versions * add angle and magnify tool * bump dependencies to avoid broken peerDeps * feat: add initial work for capture using cs3d * feat: show annotations on the image capture * feat: add svg layer export * feat: Add CINE Tool * feat: remove unnecessary viewport rendering for cine state changes Co-authored-by: Erik Ziegler <erik.sweed@gmail.com> * docs: modify and improve documentation (#2800) * cleanup docs versionings * feat: Add all version explanations * version docs for 3.0 * wip for changing docs * wip for updated docs * add utility module documentation * fix demo with nohoisting of history * add slides and video to resources * apply review comments * fix: drag and drop SR into SR viewport (#2803) * update yarn lock Co-authored-by: Erik <erik.sweed@gmail.com> * update pathnames to match v3-stable * update the e2e pathname * fix: various bugs with regard to tracking workflow (#2811) * fix: various issues with measurement panel * fix: update default tool style for annotations * fix: annotatoin label getting removed * feat: Add backward compatibility for SR hydration with legacy cornerstone * fix: cursors and ellipse ROI max style * fix: ArrowAnnotate SRDisplay * apply review comments * bump package versions * fix: bugin rehydration of SR * fix: e2e tests * fix active viewport thickness and arrowTool ui * add readme for measurement tracking * use uploaded image for readme * add back images * try to fix e2e test * fix: window level presets hotkeys * Update README.md * update yarn lock * feat: volume api and TMTV mode (#2817) * feat: volumeAPI and TMTV mode * feat: use cs3d cache service to obtain viewportData * wip for volume api * wip: fusion viewport * feat: add blend mode option * wip for image scrollbar * fix drag and drop thumbnail * wip for image scrollbar for voluems * fix: element mismatch bug for scroll * feat: Add image scrollbar to volumes * feat: add syncGroups to volume api * feat: add tmtv mode initial setup * feat: add initial image options for the stack viewports * feat: Add custom load strategy for volume viewports via HP * apply review comments fix: Jump presets cs3d (#2812) * feat: Add JumpPreset to OHIF for Cornerstone3D * fix: accessing viewport service from servicesManager feat: volume API and TMTV mode (#2814) * fix: do not display overlays on mip viewports * feat: add optional disableCommands for toggle buttons * fix: toggleCrossharis * feat: config the crosshairs * feat: add PetSUV Panel for changing metadata * feat: initial work for the rectangleROIThreshold panel * wip: measurement service * roi threshold working * feat: Add displayText to segmentations * feat: add remove segmentation * feat: add csv export * feat: add RT export for annotations in tmtv mode * fix: fusion to use pt in tmtv mode and measuremet mappings * fix: various bugs * apply review comments * apply review comments * feat: add fusion color maps * add readme to tmtv mode * Update README.md * fix: try to fix build * fix unit tests * Update README.md * feat: add about to the panel * fix: changing strategy in roi panel * apply review comments * update package versions * wip for stackPrefetch * fix: cornerstone3d hydration and renaming (#2818) * update readme * renamed cornerstone extension * wip for renaming cornerstone3D variables * wip for renaming cornerstone3D variables * wip for fixing bugs for SR viewport * fix: jumpToMeasurement and initial label after hydration * fix: fileName capitalization * feat: use the new prefetch stack in the cs3d (#2820) * feat: use the new prefetch stack in the cs3d * use viewport scroll api for stack viewport * fix cine stop when scrollbar changes * feat: use new prefetch events * fix loading state to not show repeatedly * fix: various bugs for tmtv mode thresholding and new icons (#2823) * feat: make tmtv mode available in worklist * feat: add new icons for tmtv mode * feat: add fusion color icon * fix: parallel scale calculation * fix: bump Cornerstone to get large image support working * fix: Fix issues with CPU viewport flipping, including config files * fix: bump cornerstone to fix magnify tool * fix: Bump Cornerstone version to fix resetCamera issue in StackViewport * ci: Add _headers file to enable CORS headers for Netlify Drag/Drop deploys * fix: WADO-URI was not working. PET Metadata was coming from the wrong place. Fixed some minor React errors * feat(OHIF):Allow modes and extensions to be added after commpile time. (#2838) Also works with the compile time add that the existing cli uses, so that both build types work. Eric and I agreed this doesn't change existing functionality, but is almost entirely build issues/fixes. * bump: dependency versions to fix hydration bugs (#2848) * bump: dcmjs version to fix hydration bugs * try to fix tests * bump dependency versions Co-authored-by: Alireza <ar.sedghi@gmail.com> Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
This commit is contained in:
668 files changed
+41669
-13410
No files matched your search
@@ -0,0 +1,335 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_label: Overview
|
||||
---
|
||||
|
||||
# Deployment
|
||||
|
||||
The OHIF Viewer can be embedded in other web applications via it's [packaged
|
||||
script source][viewer-npm], or served up as a stand-alone PWA ([progressive web
|
||||
application][pwa-url]) by building and hosting a collection of static assets. In
|
||||
either case, you will need to configure your instance of the Viewer so that it
|
||||
can connect to your data source (the database or PACS that provides the data
|
||||
your Viewer will display).
|
||||
|
||||
## Overview
|
||||
|
||||
Our goal is to make deployment as simple and painless as possible; however,
|
||||
there is an inherent amount of complexity in configuring and deploying web
|
||||
applications. If you find yourself a little lost, please don't hesitate to
|
||||
[reach out for help](/help)
|
||||
|
||||
## Deployment Scenarios
|
||||
|
||||
### Embedded Viewer (deprecated)
|
||||
|
||||
`OHIF-v3` has deprecated deploying the viewer as an embedded viewer the number
|
||||
of underlying libraries that run web workers are increasing for OHIF. An example
|
||||
of these libraries is OHIF's 3D rendering functionality that is provided by
|
||||
`vtk-js`.
|
||||
|
||||
### Stand-alone Viewer
|
||||
|
||||
Deploying the OHIF Viewer as a stand-alone web application provides many
|
||||
benefits, but comes at the cost of time and complexity. Some benefits include:
|
||||
|
||||
_Today:_
|
||||
|
||||
- Leverage [extensions](../platform/extensions/index.md) and
|
||||
[modes](../platform/modes/index.md) to drop-in powerful new features
|
||||
- Add routes and customize the viewer's workflow
|
||||
- Finer control over styling and whitelabeling
|
||||
|
||||
_In the future:_
|
||||
|
||||
- The ability to package the viewer for [App Store distribution][app-store]
|
||||
- Leverage `service-workers` for offline support and speed benefits from caching
|
||||
|
||||
#### Hosted Static Assets
|
||||
|
||||
At the end of the day, a production OHIF Viewer instance is a collection of
|
||||
HTML, CSS, JS, Font Files, and Images. We "build" those files from our
|
||||
`source code` with configuration specific to our project. We then make those
|
||||
files publicly accessible by hosting them on a Web Server.
|
||||
|
||||
If you have not deployed a web application before, this may be a good time to
|
||||
[reach out for help](/help), as these steps assume prior web development and
|
||||
deployment experience.
|
||||
|
||||
##### Part 1 - Build Production Assets
|
||||
|
||||
"Building", or creating, the files you will need is the same regardless of the
|
||||
web host you choose. You can find detailed instructions on how to configure and
|
||||
build the OHIF Viewer in our
|
||||
["Build for Production" guide](./build-for-production.md).
|
||||
|
||||
##### Part 2 - Host Your App
|
||||
|
||||
There are a lot of [benefits to hosting static assets][host-static-assets] over
|
||||
dynamic content. You can find instructions on how to host your build's output
|
||||
via one of these guides:
|
||||
|
||||
_Drag-n-drop_
|
||||
|
||||
- [Netlify: Drop](./static-assets.md#netlify-drop)
|
||||
|
||||
_Easy_
|
||||
|
||||
- [Surge.sh](./static-assets.md#surgesh)
|
||||
- [GitHub Pages](./static-assets.md#github-pages)
|
||||
|
||||
_Advanced_
|
||||
|
||||
- [AWS S3 + Cloudfront](./static-assets.md#aws-s3--cloudfront)
|
||||
- [GCP + Cloudflare](./static-assets.md#gcp--cloudflare)
|
||||
- [Azure](./static-assets.md#azure)
|
||||
|
||||
## Data
|
||||
|
||||
The OHIF Viewer is able to connect to any data source that implements the [DICOM
|
||||
Web Standard][dicom-web-standard]. [DICOM Web][dicom-web] refers to RESTful
|
||||
DICOM Services -- a recently standardized set of guidelines for exchanging
|
||||
medical images and imaging metadata over the internet. Not all archives fully
|
||||
support it yet, but it is gaining wider adoption.
|
||||
|
||||
### Configure Connection
|
||||
|
||||
If you have an existing archive and intend to host the OHIF Viewer at the same
|
||||
domain name as your archive, then connecting the two is as simple as following
|
||||
the steps layed out in our
|
||||
[Configuration Essentials Guide](./../configuration/index.md).
|
||||
|
||||
#### What if I don't have an imaging archive?
|
||||
|
||||
We provide some guidance on configuring a local image archive in our
|
||||
[Data Source Essentials](./../configuration/index.md#set-up-a-local-DICOM-server)
|
||||
guide. Hosting an archive remotely is a little trickier. You can check out some
|
||||
of our [advanced recipes](#recipes) for modeled setups that may work for you.
|
||||
|
||||
#### What if I intend to host the OHIF Viewer at a different domain?
|
||||
|
||||
There are two important steps to making sure this setup works:
|
||||
|
||||
1. Your Image Archive needs to be exposed, in some way, to the open web. This
|
||||
can be directly, or through a `reverse proxy`, but the Viewer needs _some
|
||||
way_ to request its data.
|
||||
2. \* Your Image Archive needs to have appropriate CORS (Cross-Origin Resource
|
||||
Sharing) Headers
|
||||
|
||||
> \* Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional
|
||||
> HTTP headers to tell a browser to let a web application running at one origin
|
||||
> (domain) have permission to access selected resources from a server at a
|
||||
> different origin. - [MDN Web Docs: Web - Http - CORS][cors]
|
||||
|
||||
Most image archives do not provide either of these features "out of the box".
|
||||
It's common to use IIS, Nginx, or Apache to route incoming requests and append
|
||||
appropriate headers. You can find an example of this setup in our
|
||||
[Nginx + Image Archive Deployment Recipe](./nginx--image-archive.md).
|
||||
|
||||
#### What if my archive doesn't support DicomWeb?
|
||||
|
||||
It's possible to supply all Study data via JSON format, in the event you do not
|
||||
have a DicomWeb endpoint. You can host all of the relevant files on any web
|
||||
accessible server (Amazon S3, Azure Blob Storage, Local file server etc.)
|
||||
|
||||
This JSON is supplied via the '?url=' query parameter. It should reference an
|
||||
endpoint that returns **application/json** formatted text.
|
||||
|
||||
If you do not have an API, you can simply return a text file containing the JSON
|
||||
from any web server.
|
||||
|
||||
You tell the OHIF viewer to use JSON by using the `dicomjson` datasource and
|
||||
appending `'?url='` query to your mode's route:
|
||||
|
||||
e.g.
|
||||
`https://my-test-ohif-server/myMode/dicomjson?url=https://my-json-server/study-uid.json`
|
||||
|
||||
The returned JSON object must contain a single root object with a 'studies'
|
||||
array.
|
||||
|
||||
You can read more about using different data sources for mode's routes
|
||||
[here](../platform/modes/routes.md#route-path)
|
||||
|
||||
_Sample JSON format:_
|
||||
|
||||
```json
|
||||
{
|
||||
"studies": [
|
||||
{
|
||||
"StudyInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.78",
|
||||
"StudyDescription": "BRAIN SELLA",
|
||||
"StudyDate": "20010108",
|
||||
"StudyTime": "120022",
|
||||
"PatientName": "MISTER^MR",
|
||||
"PatientId": "832040",
|
||||
"series": [
|
||||
{
|
||||
"SeriesDescription": "SAG T-1",
|
||||
"SeriesInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.121",
|
||||
"SeriesNumber": 2,
|
||||
"SeriesDate": "20010108",
|
||||
"SeriesTime": "120318",
|
||||
"Modality": "MR",
|
||||
"instances": [
|
||||
{
|
||||
"metadata": {
|
||||
"Columns": 512,
|
||||
"Rows": 512,
|
||||
"InstanceNumber": 3,
|
||||
"AcquisitionNumber": 0,
|
||||
"PhotometricInterpretation": "MONOCHROME2",
|
||||
"BitsAllocated": 16,
|
||||
"BitsStored": 16,
|
||||
"PixelRepresentation": 1,
|
||||
"SamplesPerPixel": 1,
|
||||
"PixelSpacing": [0.390625, 0.390625],
|
||||
"HighBit": 15,
|
||||
"ImageOrientationPatient": [0, 1, 0, 0, 0, -1],
|
||||
"ImagePositionPatient": [11.6, -92.5, 98.099998],
|
||||
"FrameOfReferenceUID": "1.2.840.113619.2.5.1762583153.223134.978956938.470",
|
||||
"ImageType": ["ORIGINAL", "PRIMARY", "OTHER"],
|
||||
"Modality": "MR",
|
||||
"SOPInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.124",
|
||||
"SeriesInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.121",
|
||||
"StudyInstanceUID": "1.2.840.113619.2.5.1762583153.215519.978957063.78"
|
||||
},
|
||||
"url": "dicomweb://s3.amazonaws.com/lury/MRStudy/1.2.840.113619.2.5.1762583153.215519.978957063.124.dcm"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
More info on this JSON format can be found here
|
||||
[Issue #1500](https://github.com/OHIF/Viewers/issues/1500)
|
||||
|
||||
**Implementation Notes:**
|
||||
|
||||
<!-- 1. When hosting the viewer, you will also need to host a /viewer route on the server - or the browser may not be able to find the route. -->
|
||||
|
||||
1. For each instance url (dicom object) in the returned JSON, you must prefix
|
||||
the `url` with `dicomjson:` in order for the cornerstone image loader to
|
||||
retrieve it correctly. eg. `https://image-server/my-image.dcm` --->
|
||||
`dicomjson:https://image-server/my-image.dcm`
|
||||
2. The JSON format above is compatible with >= v3.7.8 of the application in `V2`
|
||||
version. Older versions of the viewer used a different JSON format. As of
|
||||
20/04/20 the public [https://viewer.ohif.org/] is a pre 3.0 version that does
|
||||
not support this format yet.
|
||||
3. The JSON format is case-sensitive. Please ensure you have matched casing with
|
||||
the naturalised Dicom format referenced in
|
||||
[Issue #1500](https://github.com/OHIF/Viewers/issues/1500).
|
||||
|
||||
_CORS Issues (Cross-Origin Resource Sharing)_
|
||||
|
||||
If you host a JSON API or Images on a different domain from the app itself,
|
||||
you will likely have CORS issues. This will also happen when testing from
|
||||
Localhost and reaching out to remote servers. Even if the domain is the same,
|
||||
different ports, subdomains or protocols (https vs http) will also cause CORS
|
||||
errors. You will to need add a configuration on each server hosting these assets
|
||||
to allow your App server origin.
|
||||
|
||||
For example:
|
||||
|
||||
Let's assume your application is hosted on `https://my-ohif-server.com`.
|
||||
|
||||
Your JSON API is hosted on `https://my-json-api.aws.com`
|
||||
|
||||
And your images are stored on Amazon S3 at `https://my-s3-bucket.aws.com`
|
||||
|
||||
When you first start your application, browsing to
|
||||
`https://my-ohif-server.com/myMode/dicomjson?url=https://my-json-api.aws.com/api/my-json-study-info.json`,
|
||||
you will likely get a CORS error in the browser console as it tries to connect
|
||||
to `https://my-json-api.aws.com`.
|
||||
|
||||
Adding a setting on the JSON server to allow the CORS origin =
|
||||
`https://my-ohif-server.com` should solve this.
|
||||
|
||||
Next, you will likely get a similar CORS error, as the browser tries to go to
|
||||
`https://my-s3-bucket.aws.com`. You will need to go to the S3 bucket
|
||||
configuration, and add a CORS setting to allow origin =
|
||||
`https://my-ohif-server.com`.
|
||||
|
||||
Essentially, whenever the application connects to a remote resource, you will
|
||||
need to add the applications url to the allowed CORS Origins on that resource.
|
||||
Adding an origin similar to https://localhost:3000 will also allow for local
|
||||
testing.
|
||||
|
||||
### Securing Your Data
|
||||
|
||||
Coming soon
|
||||
|
||||
<!--
|
||||
> Feeling lost? Securing your data is important, and it can be hard to tell if
|
||||
> you've gotten it right. Don't hesitate to work with professional auditors, or
|
||||
> [enlist help from experts](../help).
|
||||
|
||||
The OHIF Viewer can be configured to work with authorization servers that
|
||||
support one or more of the OpenID-Connect authorization flows. The Viewer finds
|
||||
it's OpenID-Connect settings on the `oidc` configuration key. You can set these
|
||||
values following the instructions laid out in the
|
||||
[Configuration Essentials Guide](./../configuration/index.md).
|
||||
|
||||
_Example OpenID-Connect Settings:_
|
||||
|
||||
```js
|
||||
window.config = {
|
||||
...
|
||||
oidc: [
|
||||
{
|
||||
// ~ REQUIRED
|
||||
// Authorization Server URL
|
||||
authority: 'http://127.0.0.1/auth/realms/ohif',
|
||||
client_id: 'ohif-viewer',
|
||||
redirect_uri: 'http://127.0.0.1/callback', // `OHIFStandaloneViewer.js`
|
||||
response_type: 'code', // "Authorization Code Flow"
|
||||
scope: 'openid', // email profile openid
|
||||
// ~ OPTIONAL
|
||||
post_logout_redirect_uri: '/logout-redirect.html',
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
You can find an example of this setup in our
|
||||
[User Account Control Deployment Recipe](./user-account-control.md).
|
||||
|
||||
#### Choosing a Flow for the Viewer
|
||||
|
||||
In general, we recommend using the "Authorization Code Flow" ( [see
|
||||
`response_type=code` here][code-flows]); however, the "Implicit Flow" ( [see
|
||||
`response_type=token` here][code-flows]) can work if additonal precautions are
|
||||
taken. If the flow you've chosen produces a JWT Token, it's validity can be used
|
||||
to secure access to your Image Archive as well.
|
||||
|
||||
-->
|
||||
|
||||
### Recipes
|
||||
|
||||
We've included a few recipes for common deployment scenarios. There are many,
|
||||
many possible configurations, so please don't feel limited to these setups.
|
||||
Please feel free to suggest or contribute your own recipes.
|
||||
|
||||
- [Build for Production](./build-for-production.md)
|
||||
- [Static](./static-assets.md)
|
||||
- [Nginx + Image Archive](./nginx--image-archive.md)
|
||||
- [User Account Control](./user-account-control.md)
|
||||
|
||||
<!--
|
||||
Links
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[viewer-npm]: https://www.npmjs.com/package/@ohif/viewer
|
||||
[pwa-url]: https://developers.google.com/web/progressive-web-apps/
|
||||
[static-assets-url]: https://www.maxcdn.com/one/visual-glossary/static-content/
|
||||
[app-store]: https://medium.freecodecamp.org/i-built-a-pwa-and-published-it-in-3-app-stores-heres-what-i-learned-7cb3f56daf9b
|
||||
[dicom-web-standard]: https://www.dicomstandard.org/dicomweb/
|
||||
[dicom-web]: https://en.wikipedia.org/wiki/DICOMweb
|
||||
[host-static-assets]: https://www.netlify.com/blog/2016/05/18/9-reasons-your-site-should-be-static/
|
||||
[cors]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
[code-flows]: https://medium.com/@darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660
|
||||
[code-sandbox]: https://codesandbox.io/s/viewer-script-tag-tprch
|
||||
<!-- prettier-ignore-end -->
|
||||
Reference in new issue
Block a user