Yesterday I spent about eight hours building out the foundation for the SIIM 2015 Hackathon Grand Challenge. This foundation is a simple web based radiology focused EMR client that includes functionality such as patient search and the display of a patient's radiology reports with images. By providing such a foundation, it is hoped that hackers would have a baseline system to start hacking from rather than starting from scratch.
The SIIM Hackathon committee had already deployed a Spark FHIR server and DCM4CHEE v4 server into AWS and loaded both with synchronized data sets. A special thanks to Mark Kohli, Steve Langer, and Jason Hostettler for their work on the datasets and Mohannad Hussain for setting up the DCM4CHEE server. I also contributed the ImagingStudy resources to the FHIR dataset which were generated by converting the response from a WADO-RS Retrieve Metadata call using this tool.
I wanted to keep the learning curve for the baseline system to be low so hackers could get started quickly. To support this, I decided to keep the third party dependencies to a minimum. I ended up using only jQuery and bootstrap since most web developers are familiar with both. I ruled out other popular (and powerful) libraries such as Meteor (my favorite), Angular and KnockoutJS as these powerful libraries take some time to learn and not everyone knows them.
My first goal was to create an architecture spike to prove out that it would work and also lay down the foundational pieces that I could build on top of. I decided to begin with displaying a list of patients that I would obtain by querying the FHIR server. This turned out to be very easy and took about 30 minutes to get up and going. It basically involved making a query to the Patient resource filtered by the last name of the patients in our datasets and creating rows in a table from the results:
http://fhir.hackathon.siim.org/fhir/Patient?family=SIIM
Next up was creating a radiology centric patient view. The first thing I needed was to display the available reports for the user. This required querying the DiagnosticReport resource filtered by the ID for the selected Patient and creating rows in a table from the results:
http://fhir.hackathon.siim.org/fhir/DiagnosticReport?subject=Patient/siimjoe
This was up and running after another 30 minutes. After this, I needed to display the actual report the user clicked on in the list of reports. I hooked the click event on the table row and made a request for the associated DiagnosticReport by ID:
http://fhir.hackathon.siim.org/fhir/DiagnosticReport/2257132503242682
I grabbed the human readable form for the report from the data.text.div property. This is normally HTML so I used the jQuery parseHTML() function to parse it into DOM nodes that I could stick directly into DOM. This took yet another 30 minutes.
The last step is to display the images for the report. This required searching for ImagingStudy resources based on the accession number stored in selected the DiagnosticReport resource:
http://fhir.hackathon.siim.org/fhir/ImagingStudy?accession=2257132503242682
There may actually be multiple ImagingStudy resources for a given DiagnosticReport so some logic was required to pick the right one. I decided to pick the one with the fewest number of referenced SOP Instances assuming that the smallest one would contain the key images (rather than the entire study). Once I had the ImagingStudy, I decided to pick the first image in the first series and display it using cornerstone. I haven't built a WADO-RS based ImageLoader for cornerstone yet so I decided to use cornerstoneWADOImageLoader and load images via WADO-URI. 30 minutes later, I had an image displayed!
The spike took about 2 1/2 hours to complete and not only proved the concept but provided a great foundation to work from. I spent the rest of the day refactoring the code for readability and adding more functionality. If you are really interested in seeing how this was built, check out the commit log.
Showing posts with label WADO. Show all posts
Showing posts with label WADO. Show all posts
Tuesday, April 28, 2015
Thursday, September 11, 2014
WADO-RS Overview
WADO-RS was recently added to the DICOM standard in 2011 with Supplement 161. The RS stands for REST or RESTful and is generally easier to understand and work with than WS* Web Services. WADO-RS was mainly driven by the need to provide a way for clients to access multiple SOP Instances in one HTTP request which had been shown by the MINT project to offer significant performance gains.
One of the key concepts that WG27 took from the MINT project was the concept of bulk data. A bulk data item is a field in a DICOM SOP Instance that is typically very large - such as the Pixel Data field 7FE0,0010. To maximize performance, all fields for a study can be retrieved at once but bulk data fields are replaced with a URL that can be used to obtain the bulk data item via a separate request. This strategy enables clients to stream the pieces of the study they want, when they need them. This strategy is often used by image viewers to deliver images "on demand".
WADO-RS provides multiple ways to access SOP Instances to support a variety of use cases and scenarios:
One of the key concepts that WG27 took from the MINT project was the concept of bulk data. A bulk data item is a field in a DICOM SOP Instance that is typically very large - such as the Pixel Data field 7FE0,0010. To maximize performance, all fields for a study can be retrieved at once but bulk data fields are replaced with a URL that can be used to obtain the bulk data item via a separate request. This strategy enables clients to stream the pieces of the study they want, when they need them. This strategy is often used by image viewers to deliver images "on demand".
WADO-RS provides multiple ways to access SOP Instances to support a variety of use cases and scenarios:
- RS – RetrieveMetadata. This allows a client to retrieve all fields (except bulk data) for all SOP Instances in a study. It supports both XML and JSON responses. The JSON response is an array of objects, each of which contains all of the fields for each SOP instance in the study. The data in bulk data fields is replaced with a URL which can be used to get the actual bulk data separately. The XML response is a multi-part MIME message with each SOP Instance returned as a separate XML document and encoded as a single part.
- RS – RetrieveBulkdata. This is the mechanism to retrieve a single bulk data item as returned in the RS-RetrieveMetadata response. By default the bulk data is returned in little endian transfer syntax, but other transfer syntaxes can be requested (e.g. JPEG2000)
- RS - RetrieveFrames. This mechanism allows a client to get all image frames for a study, series or SOP Instance in one request. The frames are returned in a multi-part mime message with each frame encoded as single part. By default frames are returned in little endian transfer syntaxes but other transfer syntaxes can be requested (e.g. JPEG 2000).
- RS – RetrieveStudy. This allows a client to obtain all SOP Instances for a study in one request. Each SOP Instances is sent as a separate part in a multi-part MIME message with each SOP Instances as a DICOM P10 byte stream (application/dicom) encoded in a single part. You can also request just the bulk data items for a study and they are returned in a multi-part MIME message with each bulk data item as an individual part.
- RS – RetrieveSeries. Same as RS-RetrieveStudy but scoped to a series.
- RS – RetrieveInstance. Same as RS-RetrieveStudy but scoped to an individual SOP Instance
Tuesday, September 2, 2014
DICOM WADO and WADO-URI
The DICOM standard defines web service based functionality in PS 3.18. DICOM Working Group 27 (Web Technology for DICOM) oversees the standardization of web services. You can read more about WG 27 in the DICOM's strategy document and access its meeting notes.
The first web service mechanism standardized was called WADO (Web Access to DICOM Objects) which provides HTTP GET access to SOP Instances. WADO was added via Supplement 85 in 2003. WADO was recently renamed WADO-URI to avoid confusion with the new WADO-RS (RESTful) and WADO-WS (WS*) standards. This industry is still coming up to speed with this new terminology, so the term "WADO" generally refers to what is now called WADO-URI as WADO-RS and WADO-WS are not widely in use yet.
WADO-URI supports access to SOP Instances via HTTP GET. Built into HTTP is a mechanism to request data in a variety of formats (or MIME types). There are hundreds of MIME types defined, here are some of the more common MIME types that are behind the web pages you see when browsing the web:
- text/html - HTML documents
- text/css - CSS documents
- image/jpeg - JPEG images
- image/png - PNG images
Different types of SOP Instances can be returned as different MIME types. For example, a single frame image SOP Instance can be rendered as a image/jpeg but multi-frame image and structured report SOP Instances cannot. A structured report can be retrieved as an HTML document, but an image SOP Instance cannot.
DICOM also defined its own MIME type 'application/dicom' which refers to a DICOM P10 byte stream. By default, a requested SOP Instance should be returned in Explicit VR Little Endian transfer syntax. Other transfer syntaxes can be requested (e.g. JPEG 2000), but the server does not have to honor the request.
Here is an example of a WADO-URI URL that requests a SOP Instance rendered as a JPEG:
http://localhost:8080/wado?requestType=WADO&studyUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075541.1&seriesUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075541.2&objectUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075557.1
A few notes about this URL:
- You must know the StudyInstanceUID, SeriesInstanceUID and SOPInstanceUID. The QIDO-RS standard will allow you to query for these via a REST call, but it is new and very few systems that support it right now.
- The default MIME type is application/jpeg which returns a JPEG image the same size as the DICOM image with a server selected window/level value. Your web browser will display this rendered image if you paste the URL into it!
While rendered images are nice for integration with web based applications, there are three disadvantages:
- You need to re-render the image on the server if you need to adjust the window width or window center
- You don't have access to any other DICOM Fields (e.g. patient name, patient id, study description, etc)
- The image is not diagnostic due to encoding as a JPEG Lossy image (this can be avoided if the server supports rendering to the image/png MIME type)
To address these issues, you can request the SOP Instance as a DICOM P10 byte stream. To do this, you need to request that it be returned with the application/dicom MIME type using the contentType parameter. Here is an example of this for the same SOP Instance used above:
http://localhost:8080/wado?requestType=WADO&studyUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075541.1&seriesUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075541.2&objectUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075557.1&contentType=application%2Fdicom
Note that the '/' in 'application/dicom' is converted into %2F due to conform with URL encoding rules. Diagnostic viewers will typically use the application/dicom access method to avoid the three issues listed above with the image rendered mode. One drawback to the application/dicom access method is that the responses are typically much larger. An uncompressed 256x256 MRI image is 128K bytes while a JPEG rendered version may only be 3k!
Subscribe to:
Posts (Atom)