dosimetry:userguide:thinknode
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
dosimetry:userguide:thinknode [2015/07/02 15:34] – created dpatenaude | dosimetry:userguide:thinknode [2021/07/29 18:23] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== thinknode™ Examples ====== | ====== 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 | + | 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. 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. | + | ====== Python ====== |
- | Dependencies: | + | Please refer to the [[https:// |
- | * [[http:// | + | ===== Python: Overview ===== |
- | * [[https:// | + | |
- | ===thinknode.cpp=== | ||
- | * {{: | + | The provided python scripts and libraries are meant to be a foundation and starting point for using the astroid |
- | + | ||
- | <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 | + | |
**Download: | **Download: | ||
Line 179: | Line 16: | ||
====thinknode.cfg==== | ====thinknode.cfg==== | ||
- | There is a simple configuration file (thinknode.cfg) that is used to store user data for connecting to the Dosimetry | + | There is a simple configuration file (thinknode.cfg) that is used to store user data for connecting to the astroid |
* // | * // | ||
* //api_url// being the connection string to the thinknode™ framework. | * //api_url// being the connection string to the thinknode™ framework. | ||
- | * // | + | |
- | * // | + | |
+ | * // | ||
+ | * // | ||
+ | * // | ||
+ | * // | ||
<code json thinknode.cfg> | <code json thinknode.cfg> | ||
{ | { | ||
- | " | + | " |
- | " | + | " |
- | "app_name": " | + | "apps": |
- | " | + | { |
- | " | + | |
+ | | ||
+ | | ||
+ | " | ||
+ | }, | ||
+ | " | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | }, | ||
+ | " | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | }, | ||
+ | " | ||
+ | " | ||
} | } | ||
- | |||
</ | </ | ||
===== Python: Immutable Storage ===== | ===== Python: Immutable Storage ===== | ||
==== Post Generic ISS Object ==== | ==== Post Generic ISS Object ==== | ||
- | The // | + | The // |
Dependencies: | Dependencies: | ||
- | * [[userguide: | + | * [[dosimetry:userguide: |
- | * [[userguide: | + | * [[dosimetry:userguide: |
- | * compute_aperture_creation_params.json (or any other prebuilt json file of a dosimetry object as described in the [[http:// | + | * study.json (or any other prebuilt json file of a dosimetry object as described in the [[http:// |
<code python post_iss_object_generic.py> | <code python post_iss_object_generic.py> | ||
Line 211: | Line 68: | ||
from lib import thinknode_worker as thinknode | from lib import thinknode_worker as thinknode | ||
- | from lib import decimal_logging as dl | ||
import requests | import requests | ||
import json | import json | ||
iss_dir = " | iss_dir = " | ||
- | json_iss_file = "aperture_creation_params.json" | + | json_iss_file = "study.json" |
- | obj_name = "aperture_creation_params" | + | obj_name = "rt_study" |
# Get IAM ids | # Get IAM ids | ||
Line 227: | Line 83: | ||
# Post immutable object to ISS | # Post immutable object to ISS | ||
- | res = thinknode.post_immutable(iam, json_data, obj_name) | + | res = thinknode.post_immutable_named(iam, " |
- | dl.data(" | + | |
</ | </ | ||
Line 241: | Line 96: | ||
Dependencies: | Dependencies: | ||
- | * [[userguide: | + | * [[dosimetry:userguide: |
- | * [[userguide: | + | * [[dosimetry:userguide: |
- | * compute_aperture.json (or any other prebuilt json file of a dosimetry object as described in the [[http:// | + | * 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> | <code python post_calc_request_generic.py> | ||
# Copyright (c) 2015 .decimal, Inc. All rights reserved. | # Copyright (c) 2015 .decimal, Inc. All rights reserved. | ||
# Desc: Post a json calculation request to the thinknode framework | # 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 = " | request_dir = " | ||
Line 265: | Line 115: | ||
# Send calc request and wait for answer | # Send calc request and wait for answer | ||
- | res = thinknode.do_calculation(iam, | + | res = thinknode.do_calculation(iam, |
- | dl.data(" | + | dl.data(" |
</ | </ | ||
Line 280: | Line 130: | ||
Dependencies: | Dependencies: | ||
- | * [[userguide: | + | * [[dosimetry:userguide: |
- | * [[userguide: | + | * [[dosimetry:userguide: |
=== Example === | === Example === | ||
- | Below is an abbreviated version of the //post_calc_request_sobp_dose.py// file. The abbreviated sections are denoted as " | + | Below is an abbreviated version of the //post_calc_request_sobp_dose_with_shifter.py// file. The abbreviated sections are denoted as " |
- | In the below sample, the // | + | In the below sample, the // |
* Modules used and explanation: | * Modules used and explanation: | ||
- | * The // | ||
* The // | * The // | ||
+ | * The // | ||
* The // | * The // | ||
- | Refer to the [[userguide: | + | Refer to the [[dosimetry:userguide: |
<code python> | <code python> | ||
import json | import json | ||
from lib import thinknode_worker as thinknode | from lib import thinknode_worker as thinknode | ||
+ | from lib import dosimetry_worker as dosimetry | ||
from lib import decimal_logging as dl | from lib import decimal_logging as dl | ||
- | from lib import dosimetry_types as dt | ||
# Get IAM ids | # Get IAM ids | ||
iam = thinknode.authenticate(thinknode.read_config(' | iam = thinknode.authenticate(thinknode.read_config(' | ||
- | def make_grid(corner, size, spacing): | + | def make_dose_points(pointCount): |
... | ... | ||
- | def make_water_phantom(corner, size, spacing): | + | def make_layers(sad, range, mod): |
return \ | return \ | ||
- | thinknode.function(" | + | thinknode.function(iam[" |
[ | [ | ||
- | | + | |
- | thinknode.value(1), | + | thinknode.value(sad), |
- | thinknode.value(" | + | thinknode.value(range), |
+ | thinknode.value(mod) | ||
]) | ]) | ||
- | |||
- | def make_dose_points(pointCount): | ||
- | ... | ||
- | |||
- | def get_example_sobp_machine(id): | ||
- | ... | ||
- | |||
- | def make_layers(sad, | ||
- | ... | ||
def make_target(): | def make_target(): | ||
Line 332: | Line 174: | ||
thinknode.value([16, | 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(): | def compute_aperture(): | ||
- | | + | |
- | + | ||
- | # ap_params.targets.append(thinknode.reference(" | + | |
- | ap_params.targets.append(make_target()) | + | |
- | ap_params.target_margin = 20.0 | + | |
- | ap_params.view = make_view() | + | |
- | ap_params.mill_radius = 0.0 | + | |
- | ap_params.downstream_edge = 250.5 | + | |
- | + | ||
- | # Make aperture_creation_params | + | |
- | args = {} | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | args[" | + | |
- | + | ||
- | return \ | + | |
- | thinknode.function(" | + | |
- | [ | + | |
- | thinknode.structure_named_type(" | + | |
- | ]) | + | |
beam_geometry = \ | beam_geometry = \ | ||
... | ... | ||
+ | |||
+ | # Get degrader geometry as calculation result | ||
+ | degrade_geom = \ | ||
+ | thinknode.function(iam[" | ||
+ | [ | ||
+ | thinknode.value(18), | ||
+ | thinknode.value(" | ||
+ | thinknode.value(200) # downstream edge | ||
+ | ]) | ||
+ | res_geom = thinknode.do_calculation(iam, | ||
+ | degrader = \ | ||
+ | thinknode.function(iam[" | ||
+ | [ | ||
+ | thinknode.value(res_geom), | ||
+ | thinknode.reference(" | ||
+ | ]) | ||
+ | proton_degr = thinknode.do_calculation(iam, | ||
# Call compute_sobp_pb_dose2 | # Call compute_sobp_pb_dose2 | ||
Line 382: | Line 202: | ||
thinknode.function(" | thinknode.function(" | ||
[ | [ | ||
- | | + | |
thinknode.value(make_dose_points(181)), | thinknode.value(make_dose_points(181)), | ||
beam_geometry, | beam_geometry, | ||
- | make_grid([-75, | + | |
make_layers(2270.0, | make_layers(2270.0, | ||
compute_aperture(), | compute_aperture(), | ||
Line 392: | Line 212: | ||
| | ||
# Perform calculation | # Perform calculation | ||
- | res = thinknode.do_calculation(iam, | + | res = thinknode.do_calculation(iam, |
- | dl.data(" | + | dl.data(" |
</ | </ | ||
===== Python: decimal Libraries ===== | ===== Python: decimal Libraries ===== | ||
- | ==== dosimetry_types | + | ==== rt_types |
- | The //dosimetry_types// module is a reconstruction of dosimetry manifest | + | The //rt_types// module is a reconstruction of all astroid |
- | Each data type detailed in the [[http:// | + | Each data type detailed in the [[http:// |
+ | Below you will see a snippet from the rt_types module that shows the class for the //polyset// rt_type along with its default initialization, | ||
- | Below you will see as snippet from the dosimetiry_types module that shows the class for the // | + | <code python> |
- | * **Interdependence: | + | class polygon2(object): |
- | * **//out// function:** Each class' | + | |
+ | # | ||
+ | def __init__(self): | ||
+ | blob = blob_type() | ||
+ | self.vertices = blob.toStr() | ||
+ | |||
+ | def expand_data(self): | ||
+ | data = {} | ||
+ | data[' | ||
+ | return data | ||
+ | |||
+ | def from_json(self, | ||
+ | for k, v in jdict.items(): | ||
+ | if hasattr(self, | ||
+ | setattr(self, | ||
+ | |||
+ | class polyset(object): | ||
+ | |||
+ | # | ||
+ | def __init__(self): | ||
+ | self.polygons = [] | ||
+ | self.holes = [] | ||
+ | |||
+ | def expand_data(self): | ||
+ | data = {} | ||
+ | polygon = [] | ||
+ | for x in self.polygons: | ||
+ | s = polygon2() | ||
+ | s.from_json(x) | ||
+ | polygon.append(s.expand_data()) | ||
+ | data[' | ||
+ | hole = [] | ||
+ | for x in self.holes: | ||
+ | s = polygon2() | ||
+ | s.from_json(x) | ||
+ | hole.append(s.expand_data()) | ||
+ | data[' | ||
+ | return data | ||
+ | |||
+ | def from_json(self, | ||
+ | for k, v in jdict.items(): | ||
+ | if hasattr(self, | ||
+ | setattr(self, | ||
+ | </ | ||
+ | |||
+ | * **Interdependence: | ||
+ | * **//expand_data// function:** Each class' | ||
+ | * **// | ||
+ | |||
+ | Below is an example usage of getting a thinknode | ||
<code python> | <code python> | ||
- | class aperture_creation_params: | + | def dose_to_vtk(dose_id): |
+ | img_data = json.loads(thinknode.get_immutable(iam, | ||
- | # | + | img = rt_types.image_3d() |
- | def __init__(self): | + | img.from_json(img_data) |
- | self.targets = [] | + | |
- | self.target_margin = 0.0 | + | |
- | multiple_source_vie = multiple_source_view() | + | |
- | self.view | + | |
- | self.mill_radius = 0.0 | + | |
- | self.organs = [] | + | |
- | self.half_planes = [] | + | |
- | self.corner_planes = [] | + | |
- | self.centerlines = [] | + | |
- | self.overrides = [] | + | |
- | self.downstream_edge = 0.0 | + | |
- | | + | |
- | values = OrderedDict([(" | + | |
- | (" | + | |
- | (" | + | |
- | (" | + | |
- | (" | + | |
- | (" | + | |
- | (" | + | |
- | (" | + | |
- | (" | + | |
- | (" | + | |
- | ]) | + | |
- | return values | + | |
</ | </ | ||
==== thinknode_worker ==== | ==== thinknode_worker ==== | ||
- | The // | + | The // |
- | Refer to the [[https:// | + | Refer to the [[https:// |
<code python> | <code python> | ||
- | # Authenticate with thinknode and store necessary ids | + | # Authenticate with thinknode and store necessary ids. |
- | # Gets the realm_id, bucket_id, and context_id | + | # Gets the context id for each app detailed in the thinknode config |
+ | # Gets the app version (if non defined) for each app in the realm | ||
# param config: connection settings (url and unique basic user authentication) | # param config: connection settings (url and unique basic user authentication) | ||
def authenticate(config): | def authenticate(config): | ||
- | # Send calculation request to thinknode | + | # Send calculation request to thinknode |
+ | # calculation is performed again, the calculation | ||
+ | # does not have to be repeatedly pulled from thinknode. Saves one calculation time and bandwidth. | ||
+ | # note: see post_calculation if you just want the calculation ID and don't need to wait for the calculation to finish or get results | ||
# param config: connection settings (url, user token, and ids for context and realm) | # param config: connection settings (url, user token, and ids for context and realm) | ||
# param json_data: calculation request in json format | # param json_data: calculation request in json format | ||
- | # param return_data: | + | # param return_data: |
- | def do_calculation(config, | + | # param return_error: |
+ | def do_calculation(config, | ||
- | # Post immutable object to ISS | + | # Post immutable |
# param config: connection settings (url, user token, and ids for context and realm) | # param config: connection settings (url, user token, and ids for context and realm) | ||
+ | # param app_name: name of the app to use to get the context id from the iam config | ||
# param json_data: immutable object in json format | # param json_data: immutable object in json format | ||
# param obj_name: object name of app to post to | # param obj_name: object name of app to post to | ||
- | def post_immutable(config, json_data, obj_name): | + | def post_immutable_named(config, app_name, json_data, obj_name): |
+ | scope = '/ | ||
+ | return post_immutable(config, | ||
# Post immutable object to ISS | # Post immutable object to ISS | ||
# param config: connection settings (url, user token, and ids for context and realm) | # param config: connection settings (url, user token, and ids for context and realm) | ||
+ | # param app_name: name of the app to use to get the context id from the iam config | ||
# param obj_id: thinknode iss reference id for object to get | # param obj_id: thinknode iss reference id for object to get | ||
- | def get_immutable(config, | + | def get_immutable(config, app_name, obj_id): |
</ | </ | ||
- | ==== decimal_logging | + | ==== dosimetry_worker |
+ | The dosimetry_worker module provides high-level functions for building data types and calculation requests for common dosimetry tasks. This library is constantly growing as more routine tasks are programmed in python. | ||
- | The //decimal_logging// module | + | Refer to the [[https://github.com/dotdecimal/astroid-script-library|.decimal GitHub repository]] for the complete |
- | The following settings are available in the decimal_logging.py file: | + | - Aperture creation |
- | **display_timestamps: | + | - Dose comparison |
- | **display_types: | + | - Grid creation |
- | **log_file: ** sets the logfile name and location | + | - Image creation |
+ | - PBS Spot functions | ||
- | The following image shows the logging settings for each message type as: | ||
- | - Timestamps = //True//; Types = //True// | ||
- | - Timestamps = //False//; Types = //True// | ||
- | - Timestamps = //False//; Types = //False// | ||
- | {{ : | + | ==== vtk_worker |
- | ====== Node.js ====== | + | The VTK worker provides a means to write out common rt_types to a vtk file format ([[http:// |
- | 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. | + | Below is an example |
- | **Base64 Blob Format** | + | <code python> |
- | + | def dose_to_vtk(dose_id): | |
- | The blob returned by a calculation request is formatted as such: | + | img_data = json.loads(thinknode.get_immutable(iam, |
- | <code cpp> | + | img = rt_types.image_3d() |
- | // value_type enum definitions | + | |
- | // Nil = 0; | + | |
- | // Boolean = 1; | + | |
- | // Number = 2; | + | |
- | // String = 3; | + | |
- | // Blob = 4; | + | |
- | // List = 5; | + | |
- | // Record | + | |
- | // For value_types nil, boolean, number, string | + | vtk.write_vtk_image3('E:/dicom/dose.vtk' |
- | // <uint32 value_type enum (4 bytes)>< | + | |
- | + | ||
- | // For value_types blob, list, record | + | |
- | // <uint31 value_type enum (4 bytes)>< | + | |
</ | </ | ||
- | ===== Node: Decrypt Base64 Blob Data ===== | + | ==== decimal_logging |
- | The following example shows , using node.js, how to decode the base64 encoded data returned by a calculation request. | + | The // |
- | <code javascript> | + | The following settings are available in the decimal_logging.py file: |
- | // The below base64string is a blob array with the values [ -25, -25, 25, -25, 25, 25, -25, 25 ] | + | **display_timestamps: |
- | var b64string = " | + | **display_types: |
+ | **log_file: ** sets the logfile name and location | ||
- | // The below base64string is a number set to the value 25.1 | + | === Debugging === |
- | //var b64string | + | |
- | var buf = new Buffer(b64string, ' | + | When debugging, use the dl.debug() function and set the //isDebug// flag in the decimal_logging library to True. This toggles on the output for each of the dl.debug calls. By default we keep debugging off, but it can be turned on as needed. |
- | var zlib = require(' | + | === Other Flags === |
- | 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, | + | The following image shows the logging settings for each message type as: |
+ | - Timestamps | ||
+ | - Timestamps = //False//; Types = //True// | ||
+ | - Timestamps = //False//; Types = //False// | ||
- | zlib.unzip(buf.slice(4 + size[0]), function (err, data) { | + | {{ dosimetry: |
- | if (err) { | + | |
- | throw err | + | |
- | | + | |
- | var value_type = data.readUInt32LE(0); | + | |
- | // Number | + | === File Logging |
- | if (value_type | + | |
- | console.log(" | + | |
- | } | + | |
- | // Blob | + | |
- | else if (value_type | + | |
- | // Read size here | + | |
- | var values = []; | + | |
- | for (var i = 12; i < data.length; | + | |
- | values.push(data.readDoubleLE(i)); | + | |
- | } | + | |
- | console.log(values); | + | |
- | } | + | |
- | }); | + | |
- | </code> | + | The decimal_logging library also provides simple file logging. The //log_file// variable at the top of the library sets the log file. By using any of the following functions, you can easily log data to the specified file: |
+ | |||
+ | * log(message) | ||
+ | * log_debug_data(message, | ||
+ | * log_data(data) | ||
---- | ---- |
dosimetry/userguide/thinknode.1435851269.txt.gz · Last modified: 2021/07/29 18:21 (external edit)