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.4
to
0.0.5
+1
-1
PKG-INFO
Metadata-Version: 2.1
Name: accessi
Version: 0.0.4
Version: 0.0.5
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.4"
version = "0.0.5"
authors = [

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

Homepage = "https://github.com/martinreinok/accessi-library"
Issues = "https://github.com/martinreinok/accessi-library/issues"
Issues = "https://github.com/martinreinok/accessi-library/issues"
Metadata-Version: 2.1
Name: accessi
Version: 0.0.4
Version: 0.0.5
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>

@@ -15,2 +15,3 @@ """

from types import SimpleNamespace
from math import atan2, degrees
from typing import Literal

@@ -468,3 +469,4 @@ import numpy as np

@staticmethod
def set_slice_orientation_degrees(x_deg, y_deg, z_deg, allow_side_effects=True, index=0):
def set_slice_orientation_pcs(normal: tuple = (0, 0, 0), phase: tuple = (0, 0, 0), read: tuple = (0, 0, 0),
allow_side_effects=True, index=0):
"""

@@ -476,29 +478,118 @@ Response example:

- "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)
url = f"{config.base_url()}/parameter/standard/setSliceOrientationPcs"
data = {"sessionId": config.session_id,
"index": index,
"normal": {"sag": float(normal[0]), "cor": float(normal[1]), "tra": float(normal[2])},
"phase": {"sag": float(phase[0]), "cor": float(phase[1]), "tra": float(phase[2])},
"read": {"sag": float(read[0]), "cor": float(read[1]), "tra": float(read[2])},
"allowSideEffects": allow_side_effects}
return send_request(url, data, "POST")
# 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]])
@staticmethod
def get_slice_orientation_pcs():
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "normal":{"x":0,"y":0,"z":-1.0},
- "phase":{"x":0,"y":-1.0,"z":0},
- "read":{"x":-1.0,"y":0,"z":0}
"""
url = f"{config.base_url()}/parameter/standard/getSliceOrientationPcs"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
# Combine the rotation matrices to get the overall rotation matrix
R = np.dot(Rz, np.dot(Ry, Rx))
@staticmethod
def get_number_of_slice_groups():
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value":2
"""
url = f"{config.base_url()}/parameter/standard/getNumberOfSliceGroups"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
# 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
@staticmethod
def get_number_of_slices():
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value":2
"""
url = f"{config.base_url()}/parameter/standard/getNumberOfSlices"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
# Normalize the vectors
normal /= np.linalg.norm(normal)
phase /= np.linalg.norm(phase)
read /= np.linalg.norm(read)
@staticmethod
def set_slice_orientation_degrees_dcs(roll_degrees, pitch_degrees, yaw_degrees, allow_side_effects=True, index=0):
"""
This math is not completely verified but seems to work.
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}
"""
rotation_matrix = ParameterStandard.euler_to_rotation_matrix((roll_degrees, pitch_degrees, yaw_degrees))
basis_vectors = np.eye(3)
rotated_vectors = np.dot(rotation_matrix, basis_vectors.T).T
normalized_vectors = rotated_vectors / np.linalg.norm(rotated_vectors, axis=1, keepdims=True)
for vector in normalized_vectors:
if vector[2] < 0: # Ensure the largest component is positive
vector *= -1
normal = np.array([rotation_matrix[0, 0], rotation_matrix[0, 1], rotation_matrix[0, 2]])
phase = np.array([rotation_matrix[1, 0], rotation_matrix[1, 1], rotation_matrix[1, 2]])
read = np.array([rotation_matrix[2, 0], rotation_matrix[2, 1], rotation_matrix[2, 2]])
# Set the slice orientation using the RAS coordinate system
return ParameterStandard.set_slice_orientation_dcs(normal, phase, read, allow_side_effects, index)
@staticmethod
def euler_to_rotation_matrix(angles=(0, 0, 0)):
phi, theta, psi = np.radians(angles)
R_x = np.array([[1, 0, 0],
[0, np.cos(phi), -np.sin(phi)],
[0, np.sin(phi), np.cos(phi)]])
R_y = np.array([[np.cos(theta), 0, np.sin(theta)],
[0, 1, 0],
[-np.sin(theta), 0, np.cos(theta)]])
R_z = np.array([[np.cos(psi), -np.sin(psi), 0],
[np.sin(psi), np.cos(psi), 0],
[0, 0, 1]])
return np.dot(R_z, np.dot(R_y, R_x))
@staticmethod
def get_slice_orientation_degrees_dcs():
"""
This math is not completely verified but seems to work.
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "normal":{180},
- "phase":{0},
- "read":{180}
"""
answer = ParameterStandard.get_slice_orientation_dcs()
if not answer.result.success:
return answer.result.reason
normal = np.array([answer.normal.x, answer.normal.y, answer.normal.z])
phase = np.array([answer.phase.x, answer.phase.y, answer.phase.z])
read = np.array([answer.read.x, answer.read.y, answer.read.z])
rotation_matrix = np.array([normal, phase, read])
theta = -np.arcsin(rotation_matrix[0, 2]) # pitch
psi = np.arctan2(rotation_matrix[0, 1], rotation_matrix[0, 0]) # yaw
phi = np.arctan2(rotation_matrix[1, 2], rotation_matrix[2, 2]) # roll
# Convert unit vectors to angles (in degrees)
answer.normal = np.degrees(phi)
answer.phase = np.degrees(theta)
answer.read = np.degrees(psi)
return answer
@staticmethod
def get_slice_thickness():

@@ -528,2 +619,16 @@ """

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

@@ -565,2 +670,65 @@ """

class Table:
"""
The table service was newly introduced in version 2 of the Access-i interface,
to reflect the new / changed table positioning modes that are available for the Numaris X Sola / Vida systems.
In contrast to Access-i version 1, the table positioning mode is set globally for the whole workflow,
i.e. not template-/protocol-specific. Therefore a dedicated service was introduced for this purpose.
"""
@staticmethod
def get_current_table_position():
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value":120
"""
url = f"{config.base_url()}/table/getCurrentTablePosition"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
@staticmethod
def get_table_positioning_mode():
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value":"fix"
"""
url = f"{config.base_url()}/table/getTablePositioningMode"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
@staticmethod
def set_table_positioning_mode(value: Literal["isoCenter", "localRange", "fix"] = "isoCenter"):
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value":"fix"
"""
url = f"{config.base_url()}/table/setTablePositioningMode"
data = {"sessionId": config.session_id, "value": value}
return send_request(url, data, "POST")
@staticmethod
def get_fix_table_position():
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"},
- "value":123
"""
url = f"{config.base_url()}/table/getFixTablePosition"
data = {"sessionId": config.session_id}
return send_request(url, data, "GET")
@staticmethod
def set_fix_table_position(value: int):
"""
Response example:
- "result":{"success":true,"reason":"ok","time":"20170608T143325.423"}
"""
url = f"{config.base_url()}/table/setFixTablePosition"
data = {"sessionId": config.session_id, "value": value}
return send_request(url, data, "POST")
class Image:

@@ -567,0 +735,0 @@ """