userguide:thinknode
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
userguide:thinknode [2015/06/22 19:42] – [SOBP Dose Calculation] dbottomley | userguide:thinknode [2015/07/02 15:42] (current) – removed dpatenaude | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== thinknode™ Examples ====== | ||
- | These examples provide a starting point for issuing http connections and requests to the dosimetry app on the thinknode™ framework. They are provided as is, and are written in python and c++. Any further dependencies are listed along with the provided scripts. | ||
- | |||
- | ====== C++ ====== | ||
- | |||
- | A simple C++ project that handles posting immutable objects and calculation requests to thinknode™ framework. The //main()// function toggles on which task to perform. Below are the defined functions of the project as well as a link to download the file in its entirety. | ||
- | |||
- | Dependencies: | ||
- | * [[http:// | ||
- | * [[https:// | ||
- | |||
- | ===thinknode.cpp=== | ||
- | |||
- | * {{: | ||
- | |||
- | <code cpp> | ||
- | // Copyright (c) 2015 .decimal, Inc. All rights reserved. | ||
- | // Desc: | ||
- | |||
- | #include " | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | #define CURL_STATICLIB | ||
- | #include < | ||
- | |||
- | using namespace std; | ||
- | |||
- | // API configuration | ||
- | string basic_user = " | ||
- | string api_url = " | ||
- | string app_name = " | ||
- | string app_version = " | ||
- | |||
- | // Curl get request call back | ||
- | static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) | ||
- | ... | ||
- | |||
- | // Select a specific json tag into string | ||
- | string get_json_value(string json, string id, int num = 0) | ||
- | ... | ||
- | |||
- | // Curllib get http request | ||
- | string do_curl_get(string auth, string url) | ||
- | ... | ||
- | |||
- | // Curllib post http request | ||
- | string do_curl_post(string auth, string json, string url) | ||
- | ... | ||
- | |||
- | // Handles http request to get the user ID from the basic_user | ||
- | string get_user_token() | ||
- | ... | ||
- | |||
- | // Handles http request for realm id | ||
- | string get_realm_id(string token) | ||
- | ... | ||
- | |||
- | // Handles http request for context id | ||
- | string get_context_id(std:: | ||
- | ... | ||
- | |||
- | // API Authentication | ||
- | std:: | ||
- | ... | ||
- | |||
- | // Grab and post the specified calc request | ||
- | void post_calc_request() | ||
- | ... | ||
- | |||
- | // Grab and post sepcified object to the ISS | ||
- | void post_immutable_object() | ||
- | ... | ||
- | |||
- | int main(void) | ||
- | ... | ||
- | |||
- | </ | ||
- | |||
- | ===== C++: Immutable Storage ===== | ||
- | |||
- | |||
- | The below example is a function in the [[userguide: | ||
- | |||
- | |||
- | Dependencies: | ||
- | * {{: | ||
- | |||
- | <code cpp> | ||
- | void post_immutable_object() | ||
- | { | ||
- | // Immutable info | ||
- | string path = " | ||
- | string sjon_iss_file = " | ||
- | string obj_name = " | ||
- | |||
- | std:: | ||
- | |||
- | // Read local immutable json file | ||
- | std:: | ||
- | string str((std:: | ||
- | | ||
- | // Post object | ||
- | std::cout << " | ||
- | string authentication_string = " | ||
- | string res = do_curl_post( | ||
- | authentication_string, | ||
- | str, | ||
- | api_url + "/ | ||
- | std::cout << " | ||
- | } | ||
- | </ | ||
- | |||
- | **Returns: | ||
- | - The ID (in json) of the object stored in Immutable Storage. | ||
- | |||
- | ===== C++: Calculation Request ===== | ||
- | |||
- | The below example is a function in the [[userguide: | ||
- | |||
- | Dependencies: | ||
- | * {{: | ||
- | |||
- | <code cpp> | ||
- | void post_calc_request() | ||
- | { | ||
- | // Request info | ||
- | string path = " | ||
- | string sjon_iss_file = " | ||
- | |||
- | std:: | ||
- | |||
- | std:: | ||
- | string str((std:: | ||
- | | ||
- | string authentication_string = " | ||
- | // Get calculation id | ||
- | std::cout << " | ||
- | string calculation_id = get_json_value( | ||
- | do_curl_post(authentication_string, | ||
- | str, api_url + "/ | ||
- | " | ||
- | |||
- | // Get calculation Status - using long polling | ||
- | std::cout << " | ||
- | string calculation_status = get_json_value( | ||
- | do_curl_get(authentication_string, | ||
- | api_url + "/ | ||
- | " | ||
- | if (calculation_status.find(" | ||
- | { | ||
- | std::cout << " | ||
- | return; | ||
- | } | ||
- | |||
- | // Get calculation Result | ||
- | std::cout << " | ||
- | string calculation_result = do_curl_get( | ||
- | authentication_string, | ||
- | api_url + "/ | ||
- | |||
- | std::cout << " | ||
- | } | ||
- | </ | ||
- | |||
- | **Returns: | ||
- | - The calculation result (in json) of the API function called. | ||
- | ====== Python ====== | ||
- | |||
- | The provided python scripts and libraries are meant to be a foundation and starting point for using the astroid Dosimetry app on the thinknode™ framework. The provided scripts outline the basic usage of using ISS to store objects, constructing, | ||
- | |||
- | **Download: | ||
- | |||
- | ====thinknode.cfg==== | ||
- | |||
- | Configuration file for connecting to the Dosimetry app on the thinknode™ framework. This file is required by all scripts in the python astroid_script_library to authenticate and use the Dosimetry app. | ||
- | |||
- | * // | ||
- | * //api_url// being the connection string to the thinknode™ framework. | ||
- | * // | ||
- | * // | ||
- | |||
- | <code json thinknode.cfg> | ||
- | { | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | </ | ||
- | ===== Python: Immutable Storage ===== | ||
- | ==== Post Generic ISS Object ==== | ||
- | |||
- | The // | ||
- | |||
- | Dependencies: | ||
- | * thinknode.cfg | ||
- | * .decimal Python libraries | ||
- | * compute_aperture_creation_params.json (or any other prebuilt json file of a dosimetry object as described in the [[http:// | ||
- | |||
- | <code python post_iss_object_generic.py> | ||
- | # Copyright (c) 2015 .decimal, Inc. All rights reserved. | ||
- | # Desc: Post an immutable json object to the thinknode framework | ||
- | |||
- | from lib import thinknode_worker as thinknode | ||
- | from lib import decimal_logging as dl | ||
- | import requests | ||
- | import json | ||
- | |||
- | iss_dir = " | ||
- | json_iss_file = " | ||
- | obj_name = " | ||
- | |||
- | # Get IAM ids | ||
- | iam = thinknode.authenticate(thinknode.read_config(' | ||
- | |||
- | # App object to post to iss | ||
- | with open(iss_dir + '/' | ||
- | json_data = json.load(data_file) | ||
- | |||
- | # Post immutable object to ISS | ||
- | res = thinknode.post_immutable(iam, | ||
- | dl.data(" | ||
- | |||
- | </ | ||
- | |||
- | **Returns: | ||
- | - The ID (in json) of the object stored in Immutable Storage. | ||
- | ===== Python: Calculation Request ===== | ||
- | |||
- | ==== Generic Calc Request ==== | ||
- | |||
- | The // | ||
- | |||
- | Dependencies: | ||
- | * thinknode.cfg | ||
- | * .decimal Python libraries | ||
- | * compute_aperture.json (or any other prebuilt json file of a dosimetry object as described in the [[http:// | ||
- | |||
- | <code python post_calc_request_generic.py> | ||
- | # Copyright (c) 2015 .decimal, Inc. All rights reserved. | ||
- | # Desc: Post a json calculation request to the thinknode framework | ||
- | |||
- | from lib import thinknode_worker as thinknode | ||
- | from lib import decimal_logging as dl | ||
- | import requests | ||
- | import json | ||
- | |||
- | request_dir = " | ||
- | json_calc_file = " | ||
- | |||
- | # Get IAM ids | ||
- | iam = thinknode.authenticate(thinknode.read_config(' | ||
- | |||
- | # App calculation request | ||
- | with open(request_dir + '/' | ||
- | json_data = json.load(data_file) | ||
- | |||
- | # Send calc request and wait for answer | ||
- | res = thinknode.do_calculation(iam, | ||
- | dl.data(" | ||
- | </ | ||
- | |||
- | **Returns: | ||
- | - The calculation result (in json) of the API function called. | ||
- | |||
- | ==== SOBP Dose Calculation ==== | ||
- | The // | ||
- | |||
- | The // | ||
- | |||
- | The // | ||
- | |||
- | === Example === | ||
- | |||
- | Below is an abbreviated version of the // | ||
- | |||
- | * The // | ||
- | * The // | ||
- | * The // | ||
- | |||
- | Refer to the FIXME section for more information on the provided decimal libraries. | ||
- | |||
- | <code python> | ||
- | import json | ||
- | from lib import thinknode_worker as thinknode | ||
- | from lib import decimal_logging as dl | ||
- | from lib import dosimetry_types as dt | ||
- | |||
- | # Get IAM ids | ||
- | iam = thinknode.authenticate(thinknode.read_config(' | ||
- | |||
- | def make_grid(corner, | ||
- | ... | ||
- | |||
- | def make_water_phantom(corner, | ||
- | ... | ||
- | |||
- | def make_dose_points(pointCount): | ||
- | ... | ||
- | |||
- | def get_example_sobp_machine(id): | ||
- | ... | ||
- | |||
- | def make_layers(sad, | ||
- | ... | ||
- | |||
- | def make_target(): | ||
- | return \ | ||
- | thinknode.function(" | ||
- | [ | ||
- | thinknode.value([-32, | ||
- | thinknode.value([16, | ||
- | ]) | ||
- | |||
- | def make_view(): | ||
- | mv = dt.multiple_source_view() | ||
- | ds = {} | ||
- | ds[' | ||
- | ds[' | ||
- | mv.display_surface = ds | ||
- | mv.center = [0, 0, 0] | ||
- | mv.direction = [0, 1, 0] | ||
- | mv.distance = [2270, 2270] | ||
- | mv.up = [0, 0, 1] | ||
- | |||
- | return mv.out() | ||
- | |||
- | def compute_aperture(): | ||
- | ... | ||
- | |||
- | beam_geometry = \ | ||
- | ... | ||
- | |||
- | # Call compute_sobp_pb_dose2 | ||
- | dose_calc = \ | ||
- | thinknode.function(" | ||
- | [ | ||
- | make_water_phantom([-100, | ||
- | thinknode.value(make_dose_points(181)), | ||
- | beam_geometry, | ||
- | make_grid([-75, | ||
- | make_layers(2270.0, | ||
- | compute_aperture(), | ||
- | thinknode.value([proton_degr]) # degraders | ||
- | ]) | ||
- | | ||
- | # Perform calculation | ||
- | res = thinknode.do_calculation(iam, | ||
- | dl.data(" | ||
- | </ | ||
- | ====== Node.js ====== | ||
- | |||
- | The following section contains examples using node.js and (if applicable) the specified modules. These examples are for a high level approach to encoding and decoding the blob data that is part of the Dosimetry App calculation request. | ||
- | |||
- | **Base64 Blob Format** | ||
- | |||
- | The blob returned by a calculation request is formatted as such: | ||
- | |||
- | <code cpp> | ||
- | // value_type enum definitions | ||
- | // Nil = 0; | ||
- | // Boolean = 1; | ||
- | // Number = 2; | ||
- | // String = 3; | ||
- | // Blob = 4; | ||
- | // List = 5; | ||
- | // Record = 6; | ||
- | |||
- | // For value_types nil, boolean, number, string | ||
- | // <uint32 value_type enum (4 bytes)>< | ||
- | |||
- | // For value_types blob, list, record | ||
- | // <uint31 value_type enum (4 bytes)>< | ||
- | </ | ||
- | |||
- | ===== Node: Decrypt Base64 Blob Data ===== | ||
- | |||
- | The following example shows , using node.js, how to decode the base64 encoded data returned by a calculation request. | ||
- | |||
- | <code javascript> | ||
- | // The below base64string is a blob array with the values [ -25, -25, 25, -25, 25, 25, -25, 25 ] | ||
- | var b64string = " | ||
- | |||
- | // The below base64string is a number set to the value 25.1 | ||
- | //var b64string = " | ||
- | |||
- | var buf = new Buffer(b64string, | ||
- | |||
- | var zlib = require(' | ||
- | |||
- | function read_base_255_number(buf, | ||
- | var n = 0; | ||
- | var s = 0; | ||
- | while (offset < buf.length) { | ||
- | var digit = buf[offset]; | ||
- | var value = buf.readUInt8(offset); | ||
- | offset++; | ||
- | s++; | ||
- | if (digit.toString(16) === ' | ||
- | break; | ||
- | } | ||
- | n = n * 255; | ||
- | n += value; | ||
- | } | ||
- | return [s, n]; | ||
- | } | ||
- | |||
- | var size = read_base_255_number(buf, | ||
- | |||
- | zlib.unzip(buf.slice(4 + size[0]), function (err, data) { | ||
- | if (err) { | ||
- | throw err | ||
- | } | ||
- | var value_type = data.readUInt32LE(0); | ||
- | |||
- | // Number | ||
- | if (value_type === 2) { | ||
- | console.log(" | ||
- | } | ||
- | // Blob | ||
- | else if (value_type === 4) { | ||
- | // Read size here | ||
- | var values = []; | ||
- | for (var i = 12; i < data.length; | ||
- | values.push(data.readDoubleLE(i)); | ||
- | } | ||
- | console.log(values); | ||
- | } | ||
- | }); | ||
- | |||
- | </ | ||
- | |||
- | {{page> |
userguide/thinknode.1435002133.txt.gz · Last modified: 2021/07/29 18:19 (external edit)