Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

accessi

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

accessi - npm Package Compare versions

Comparing version
0.0.3
to
0.0.4
+1
-1
PKG-INFO
Metadata-Version: 2.1
Name: accessi
Version: 0.0.3
Version: 0.0.4
Summary: Library for Siemens Access-i MR Scanner Interface to integrate and control the MR Scanner.

@@ -5,0 +5,0 @@ Author-email: Martin Reinok <m.reinok@student.utwente.nl>

[project]
name = "accessi"
version = "0.0.3"
version = "0.0.4"
authors = [

@@ -5,0 +5,0 @@ { name="Martin Reinok", email="m.reinok@student.utwente.nl" },

Metadata-Version: 2.1
Name: accessi
Version: 0.0.3
Version: 0.0.4
Summary: Library for Siemens Access-i MR Scanner Interface to integrate and control the MR Scanner.

@@ -5,0 +5,0 @@ Author-email: Martin Reinok <m.reinok@student.utwente.nl>

@@ -5,3 +5,2 @@ """

"""
import asyncio
# TODO: TemplateSelection Service Not implemented.

@@ -18,9 +17,9 @@ # TODO: Patient Service Not implemented.

from typing import Literal
import numpy as np
import websockets
import requests
import urllib3
import math
import asyncio
import json
import ssl
import sys

@@ -53,3 +52,7 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

@staticmethod
def websocket_default_url():
return f"wss://{config.ip_address}:{config.websocket_port}/SRC?sessionId={config.session_id}"
class Remote:

@@ -88,3 +91,3 @@ """

Before any of the services described in this document can be used,
a RC must register providing a valid authentication key (provided by your point of contact at Siemens Healthineers),
an RC must register providing a valid authentication key (provided by your point of contact at Siemens Healthineers),
which also encodes the scope of functionality that can be used by the RC.

@@ -153,3 +156,3 @@ """

has the mastership with respect to controlling the workflow.
As soon as a RC releases the control, the MR host is automatically in charge.
As soon as an RC releases the control, the MR host is automatically in charge.
The RC can only retrieve the mastership if a patient is registered and no sequence is running or open.

@@ -423,3 +426,3 @@ """

@staticmethod
def set_slice_position_dcs(index=0, x=None, y=None, z=None, allow_side_effects=True):
def set_slice_position_dcs(x=None, y=None, z=None, allow_side_effects=True, index=0):
"""

@@ -435,3 +438,3 @@ Response example:

"allowSideEffects": allow_side_effects}
return send_request(url, data)
return send_request(url, data, "POST")

@@ -452,6 +455,4 @@ @staticmethod

@staticmethod
def set_slice_orientation_dcs(index=0, allow_side_effects=True,
normal: tuple = (0, 0, 0),
phase: tuple = (0, 0, 0),
read: tuple = (0, 0, 0)):
def set_slice_orientation_dcs(normal: tuple = (0, 0, 0), phase: tuple = (0, 0, 0), read: tuple = (0, 0, 0),
allow_side_effects=True, index=0):
"""

@@ -474,2 +475,36 @@ Response example:

@staticmethod
def set_slice_orientation_degrees(x_deg, y_deg, z_deg, allow_side_effects=True, index=0):
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "normalSet":{"x":0,"y":0,"z":-1.0},
- "phaseSet":{"x":0,"y":-1.0,"z":0},
- "readSet":{"x":-1.0,"y":0,"z":0}
Don't really understand how the math works
"""
# Convert degrees to radians
x_rad = np.radians(x_deg)
y_rad = np.radians(y_deg)
z_rad = np.radians(z_deg)
# Calculate the rotation matrices around each axis
Rx = np.array([[1, 0, 0], [0, np.cos(x_rad), -np.sin(x_rad)], [0, np.sin(x_rad), np.cos(x_rad)]])
Ry = np.array([[np.cos(y_rad), 0, np.sin(y_rad)], [0, 1, 0], [-np.sin(y_rad), 0, np.cos(y_rad)]])
Rz = np.array([[np.cos(z_rad), -np.sin(z_rad), 0], [np.sin(z_rad), np.cos(z_rad), 0], [0, 0, 1]])
# Combine the rotation matrices to get the overall rotation matrix
R = np.dot(Rz, np.dot(Ry, Rx))
# Extract the orientation vectors (normal, phase, read) from the rotation matrix
normal = R[:, 2] # Third column
phase = R[:, 1] # Second column
read = R[:, 0] # First column
# Normalize the vectors
normal /= np.linalg.norm(normal)
phase /= np.linalg.norm(phase)
read /= np.linalg.norm(read)
return ParameterStandard.set_slice_orientation_dcs(normal, phase, read, allow_side_effects, index)
@staticmethod
def get_slice_thickness():

@@ -487,2 +522,14 @@ """

@staticmethod
def get_field_of_view_read():
"""
Unit:mm
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value": 400.0
"""
url = f"{config.base_url()}/parameter/standard/getFieldOfViewRead"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
@staticmethod
def set_slice_thickness(value, allow_side_effects=True):

@@ -499,3 +546,27 @@ """

@staticmethod
def get_base_resolution():
"""
Unit:mm
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value":128
"""
url = f"{config.base_url()}/parameter/standard/getBaseResolution"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
@staticmethod
def set_base_resolution(value, allow_side_effects=True):
"""
Unit:mm
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "valueSet":192
"""
url = f"{config.base_url()}/parameter/standard/setBaseResolution"
data = {"sessionId": config.session_id, "value": value, "allowSideEffects": allow_side_effects}
return send_request(url, data, "POST")
class Image:

@@ -677,19 +748,20 @@ """

async def connect_websocket(queue: asyncio.Queue, websocket_connected: asyncio.Event):
async def connect_websocket():
"""
Can use any asyncio queue
Connects to the websocket server and returns the connected websocket object.
Returns websockets.legacy.client.Connect object
"""
url = f"wss://{config.ip_address}:{config.websocket_port}/SRC?sessionId={config.session_id}"
if not config.ssl_verify:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
else:
raise SystemExit("SSL verification no supported yet")
async with websockets.connect(url, ssl=ssl_context) as websocket:
websocket_connected.set()
while True:
message = await websocket.recv()
decoded_message = handle_websocket_message(message)
await queue.put(decoded_message)
try:
url = config.websocket_default_url()
if not config.ssl_verify:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
else:
raise SystemExit("SSL verification not supported yet")
return websockets.connect(url, ssl=ssl_context)
except (websockets.ConnectionClosed, asyncio.TimeoutError) as e:
raise ConnectionError("Connection failed: " + str(e)) from e
except Exception as e:
raise e

@@ -696,0 +768,0 @@

@@ -175,38 +175,27 @@ """

async def demo_callback_function(queue: asyncio.Queue):
while True:
image_data = await queue.get()
while not queue.empty():
await queue.get()
if "imageStream" in image_data:
image_data = json.loads(json.dumps(image_data), object_hook=lambda d: SimpleNamespace(**d))
print(f"Websocket callback image dimensions: "
f"{image_data[2].value.image.dimensions.columns},"
f"{image_data[2].value.image.dimensions.rows} ")
async def main():
lifo_queue = LifoQueue()
# Run websocket
websocket_connected_event = asyncio.Event()
asyncio.create_task(Access.connect_websocket(lifo_queue, websocket_connected_event))
await websocket_connected_event.wait()
async with await Access.connect_websocket() as websocket:
# Connect the image service to websocket
websocket = Access.Image.connect_to_default_web_socket()
print(f"connect_to_default_web_socket: {websocket}")
assert websocket.result.success is True
# Connect the image service to websocket
websocket_connection = Access.Image.connect_to_default_web_socket()
print(f"connect_to_default_web_socket: {websocket_connection}")
assert websocket_connection.result.success is True
# Start template
output = Access.TemplateExecution.start(template_id).result.success
print(f"start: {output}")
assert output is True
# Start template
output = Access.TemplateExecution.start(template_id).result.success
print(f"start: {output}")
assert output is True
# Start image processing thread
asyncio.create_task(demo_callback_function(lifo_queue))
# Receive one image and quit
while True:
image_data = await websocket.recv()
if '"imageStream"' in image_data:
image_data = json.dumps(Access.handle_websocket_message(image_data))
image_data = json.loads(image_data, object_hook=lambda d: SimpleNamespace(**d))
print(f"Websocket callback image dimensions: "
f"{image_data[2].value.image.dimensions.columns},"
f"{image_data[2].value.image.dimensions.rows} ")
break
while True:
await asyncio.sleep(5)
"""

@@ -224,3 +213,3 @@ Done, cleanup

print("Running websocket for 5 seconds")
print("Running websocket for 1 image")
asyncio.run(main())