Commit cfc24222 authored by Chris Coughlin's avatar Chris Coughlin

Added documentation on REST ROI finder

parent c725d3ef
......@@ -123,25 +123,29 @@ The purpose of the Sliding Window stage is to produce subsets of incoming data f
The Region Of Interest Detection stage is responsible for examining data for ROI. When the stage receives data, it is sent to a worker that runs an instance of Myriad’s ``ROIFinder`` class. The ROIFinder class’ ``isROI()`` method is called, and if the `ROIFinder` reports true the worker reports that a Region Of Interest was found within its data.
#### Internal ROI Finder
As of this writing this stage has only one option, used to configure the ``ROIFinder`` type and path. If the ``ROIFinder`` is “internal,” this refers to a Myriad model previously saved with [Myriad Trainer]( or [similar custom code]( When the stage is constructed / updated, this internal model is read from storage and an identical copy provided to each worker in the pool.
The other major type of ROIFinder is “external,” which is broken into three sub-types for convenience.
#### External ROI Finder
The second supported type of ROIFinder is “external,” which is broken into three sub-types for convenience.
#### Python
For Python scripts, Desktop will ask for the full path to a Python binary and then for the Python application. This will result in a path to the ``ROIFinder`` of the form ``/path/to/python /path/to/python_script [command line arguments]`` e.g.
````C:\Users\chris\Anaconda3\python.exe C:\Users\chris\PycharmProjects\myriad_datagen\ ````
For MATLAB scripts, Desktop will construct a command line that executes the script without displaying the MATLAB user interface e.g.
````E:\Apps\MATLAB\R2016a\bin\matlab.exe -nodisplay -nosplash -nodesktop -r "run('C:\Users\chris\nditoolbox.m);exit;" ````
#### General External
**General External**
For all other external scripts Desktop will ask for the full path and filename of the external application. Note that there is no functional difference between MATLAB, Python, or any other external ``ROIFinder`` - Desktop provides some convenient shortcuts for Python and MATLAB but otherwise they are identical to every other external process.
......@@ -160,6 +164,75 @@ Where the path is the path as shown in Desktop (including paths to Python, MATLA
> The worker then listens to the standard output of the external application. All lines that do **not** begin with ``myriad:`` are ignored; a line that begins with ``myriad:`` and contains ``true``, ``TRUE``, etc. is assumed to indicate a Region Of Interest was found in the data, i.e.````myriad: true```` for ROI and ````myriad: false```` for no ROI.
#### REST ROI Finder
The third type of ``ROIFinder`` supported in Desktop is “REST,” which is used to contact a [representational state transfer]( web service via Myriad's ``RESTROIFinder`` class. When a REST ``ROIFinder`` is selected, Desktop will open the ``Configure REST Client`` dialog from which the REST API endpoint and (optional) authentication credentials are entered.
![REST Client Dialog](img/restclient.png)
By default the ``RESTROIFinder`` sends a PUT request of the form
where ``[url]`` is the specified API URL and the data to be checked for ROI are [encoded]( and sent as the ``data`` parameter. ``RESTROIFinder`` expects the server to return a JSON object of the form
````{'isROI': boolean}````
where the ``isROI`` value should be ``true`` if the API classifies this data as containing an ROI and ``false`` otherwise. Basic authentication is supported by specifying a username and a password; if both fields are empty no authentication is used.
#### REST API Service Example
If you have access to Emphysic's [myriad_datagen]( project, the ```` file shows an example of a simple ROI service written in Python using the [Bottle]( web framework:
"""server - demonstrates running a REST-based API for making Region of Interest (ROI) calls for the Myriad
data reduction framework.
Chris R. Coughlin (Emphysic)
Copyright (C) 2016 Emphysic LLC. All rights reserved.
from service.bottle import route, run, request, response
from ml import cscan
import numpy as np
import argparse
import base64
import json
clf = cscan.load_model("cscan_demo")
@route('/api/isroi', method='POST')
def isroi():
Calls the model and returns whether the model predicts the input data contains a Region of Interest or not. Data
are expected as POST requests with Base64-encoded array e.g. calls of the form
POST host:port/api/isroi?data=WzIzLjM3OTY4MDI4NjA3ODc3NCw5LjQyNzQ3NzQzNDk1M...
:return: JSON object of the form {'isROI': boolean}
response.content_type = "application/json"
decoded_data = base64.b64decode(
data = json.loads(str(decoded_data, 'utf-8'))
arr = np.array(data)
prediction = np.asscalar(clf.predict(arr.reshape(1, -1))[0]) == 1
return {'isROI': prediction}
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost',
help='Specifies the IP address the server listens to (default localhost)')
parser.add_argument('--port', default=8080,
help='Specifies the port the server listens to (default 8080)')
args = parser.parse_args()
run(, port=args.port)
Note that the simple single-process server shown here is useful for development purposes, but a production server should be able to handle multiple simultaneous connections and may additionally require load balancing. If the number of ``RESTROIFinder`` requests overwhelms the server, you may begin to receive "connection refused" errors in the Desktop log.
### Reporting
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment