Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • roboct-public/xraytransformstudies/cyxtrax-object
1 result
Show changes
Commits on Source (10)
Showing
with 1069 additions and 0 deletions
*.egg-info
/build/
__pycache__
/temp/
\ No newline at end of file
image: ubuntu:latest
stages:
- code_embed
variables:
GIT_STRATEGY: clone
code_embedder:
stage: code_embed
script:
- echo "Personal a"
- cd code-embedder/
- poetry install --only main
- README_PATHS=$(find .. -maxdepth 1 -name "*.md" -print)
- poetry run python ./src/main.py --readme-paths $README_PATHS
- cd ..
- README_PATHS=$(find . -maxdepth 1 -name "*.md" -print)
- git add $README_PATHS
- git diff --staged
- export BRANCH_NAME="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-$CI_COMMIT_REF_NAME}"
- echo "branch name $BRANCH_NAME"
- git remote set-url origin "https://oauth2:${PERSONAL_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
- echo "https://oauth2:${PERSONAL_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
- if ! git diff --cached --exit-code; then
git commit -m "Apply Code Embedder";
git push origin HEAD:$BRANCH_NAME;
else
echo "No changes to commit";
fi
before_script:
- apt-get update && apt-get install -y curl git python3 python3-pip
- curl -sSL https://install.python-poetry.org | python3 -
- export PATH="$HOME/.local/bin:$PATH"
- git clone https://github.com/kvankova/code-embedder.git
- git config --global user.email $GITLAB_USER_EMAIL
- git config --global user.name $GITLAB_USER_NAME
only:
- merge_requests
\ No newline at end of file
3.10
# Object Placement
![](/temp/logo.svg)
## For Circular CT Trajectories using Local Cylindrical Xray Transforms / CyXTraX
To install just use uv.
```bash
uv venv
uv run scripts/01_circular_trajectory.py
```
## Examples
```python:../scripts/01_circular_trajectory.py:o:main
def main():
fod_mm = jnp.array([1000,])
fdd_mm = jnp.array([2000,])
alpha_rad = jnp.linspace(0, jnp.pi, 100).reshape((-1, 1))
source, orientation_source, detector, orientation_detector = circular_trajectory(fod_mm, fdd_mm, alpha_rad)
source, orientation_source, detector, orientation_detector = add_world_orign(
source, orientation_source, detector, orientation_detector, jnp.array([1, 2., -1.]), x_90_quat)
detector, orientation_detector = add_offset(detector, orientation_detector, jnp.array([1, 20., -1.]), zero_quat)
print(source.shape)
print(orientation_detector.shape)
api = API()
for i in range(source.shape[0]):
api.translate('S', source[i, 0], source[i, 1], source[i, 2])
api.translate('D', detector[i, 0], detector[i, 1], detector[i, 2])
api.rotate_from_quat('D', orientation_detector[i])
api.rotate_from_quat('S', orientation_source[i])
```
```python:../scripts/02_object_placment.py:o:main
def main():
files = list(FOLDER.glob('*.h5'))
map_path = files[0]
maps, points, mesh_object_list = load_atlas(map_path)
number_of_projection = 2000
obj_place = CircularTrajectoryOptimization(maps, points, number_of_projection=number_of_projection)
obj_place.alpha_x_deg.value = jnp.array([1.,])
grid_num = 128
angle_0 = 40
angle_1 = 180
grid_y = jnp.linspace(-angle_0, angle_0, grid_num, endpoint=True)
grid_z = jnp.linspace(-angle_1, angle_1, grid_num, endpoint=True)
grid_array = jnp.zeros((grid_num, grid_num, number_of_projection, maps.shape[2]))
for i in range(grid_num):
obj_place.alpha_x_deg.value = jnp.ones((grid_num, 1)) * grid_y[i]
obj_place.beta_y_deg.value = grid_z.reshape((-1, 1))
obj_place.origin.value = jnp.zeros((grid_num, 3))
return_array = obj_place()
grid_array = grid_array.at[i].set(return_array)
print(i)
print(grid_array.shape)
grid_array_std = jnp.std(grid_array, 2)
print(grid_array_std.shape)
grid_array_std = jnp.std(grid_array, 3)
print(grid_array_std.shape)
mean_std_grid = jnp.mean(jnp.std(grid_array, 2), 2)
plot_map(mean_std_grid, [angle_0, angle_1], TEMP_FOLDER, 'Mean STD')
mean_mean_grid = jnp.mean(jnp.mean(grid_array, 2), 2)
plot_map(mean_mean_grid, [angle_0, angle_1], TEMP_FOLDER, 'Mean')
std_std_grid = jnp.std(jnp.std(grid_array, 3), 2)
plot_map(std_std_grid, [angle_0, angle_1], TEMP_FOLDER, 'STD')
std_mean_grid = jnp.std(jnp.mean(grid_array, 3), 2)
plot_map(std_mean_grid, [angle_0, angle_1], TEMP_FOLDER, 'STD Mean')
```
![](/temp/meanstd_map.png)
\ No newline at end of file
[project]
name = "cyxtrax_object"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"artist_pythonlib ; sys_platform == 'windows'",
"cyxtrax",
"evosax>=0.1.6 ; sys_platform == 'linux'",
"flax>=0.10.1",
"jax>=0.4.35 ; sys_platform == 'windows'",
"jax[cuda12]>=0.4.35 ; sys_platform == 'linux'",
]
[tool.uv.sources]
cyxtrax = { git = "https://mygit.th-deg.de/roboct-public/xraytransformstudies/cyxtrax" }
artist-pythonlib = { git = "https://mygit.th-deg.de/roboct-public/artist-api" }
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
from cyxtrax_object import (
circular_trajectory,
add_world_orign,
zero_quat,
x_90_quat,
add_offset,
)
from jax import numpy as jnp
from artistlib import API
def main():
fod_mm = jnp.array(
[
1000,
]
)
fdd_mm = jnp.array(
[
2000,
]
)
alpha_rad = jnp.linspace(0, jnp.pi, 100).reshape((-1, 1))
source, orientation_source, detector, orientation_detector = circular_trajectory(
fod_mm, fdd_mm, alpha_rad
)
source, orientation_source, detector, orientation_detector = add_world_orign(
source,
orientation_source,
detector,
orientation_detector,
jnp.array([1, 2.0, -1.0]),
x_90_quat,
)
detector, orientation_detector = add_offset(
detector, orientation_detector, jnp.array([1, 20.0, -1.0]), zero_quat
)
print(source.shape)
print(orientation_detector.shape)
api = API()
for i in range(source.shape[0]):
api.translate("S", source[i, 0], source[i, 1], source[i, 2])
api.translate("D", detector[i, 0], detector[i, 1], detector[i, 2])
api.rotate_from_quat("D", orientation_detector[i])
api.rotate_from_quat("S", orientation_source[i])
if __name__ == "__main__":
main()
from cyxtrax_object import CircularTrajectoryOptimization, plot_map
from cyxtrax.io.load_maps import load_atlas
from pathlib import Path
from jax import numpy as jnp
FOLDER = Path(r"C:\data\xray_transform")
TEMP_FOLDER = Path("./temp/")
def main():
files = list(FOLDER.glob("*.h5"))
map_path = files[0]
maps, points, mesh_object_list = load_atlas(map_path)
number_of_projection = 2000
obj_place = CircularTrajectoryOptimization(
maps, points, number_of_projection=number_of_projection
)
obj_place.alpha_x_deg.value = jnp.array(
[
1.0,
]
)
grid_num = 128
angle_0 = 40
angle_1 = 180
grid_y = jnp.linspace(-angle_0, angle_0, grid_num, endpoint=True)
grid_z = jnp.linspace(-angle_1, angle_1, grid_num, endpoint=True)
grid_array = jnp.zeros((grid_num, grid_num, number_of_projection, maps.shape[2]))
for i in range(grid_num):
obj_place.alpha_x_deg.value = jnp.ones((grid_num, 1)) * grid_y[i]
obj_place.beta_y_deg.value = grid_z.reshape((-1, 1))
obj_place.origin.value = jnp.zeros((grid_num, 3))
return_array = obj_place()
grid_array = grid_array.at[i].set(return_array)
print(i)
print(grid_array.shape)
grid_array_std = jnp.std(grid_array, 2)
print(grid_array_std.shape)
grid_array_std = jnp.std(grid_array, 3)
print(grid_array_std.shape)
mean_std_grid = jnp.mean(jnp.std(grid_array, 2), 2)
plot_map(mean_std_grid, [angle_0, angle_1], TEMP_FOLDER, "Mean STD")
mean_mean_grid = jnp.mean(jnp.mean(grid_array, 2), 2)
plot_map(mean_mean_grid, [angle_0, angle_1], TEMP_FOLDER, "Mean")
std_std_grid = jnp.std(jnp.std(grid_array, 3), 2)
plot_map(std_std_grid, [angle_0, angle_1], TEMP_FOLDER, "STD")
std_mean_grid = jnp.std(jnp.mean(grid_array, 3), 2)
plot_map(std_mean_grid, [angle_0, angle_1], TEMP_FOLDER, "STD Mean")
if __name__ == "__main__":
main()
from cyxtrax_object import CircularTrajectoryOptimization
from CyXTraX.io.load_maps import load_atlas
from pathlib import Path
from jax import numpy as jnp, lax, random
from flax import nnx
from evosax import ParameterReshaper
from evosax.strategies.ars import ARS
from evosax import CMA_ES
MAP_FOLDER = Path(r"C:\data\XrayTransform")
TEMP_FOLDER = Path(r"./temp")
POP_SIZE = 100
ITERATIONS = 100
EPOCH = 25
def main():
files = list(MAP_FOLDER.glob("*.h5"))
map_path = files[0]
maps, points, mesh_object_list = load_atlas(map_path)
number_of_projection = 2000
obj_place = CircularTrajectoryOptimization(
maps, points, number_of_projection=number_of_projection, only_orientation=False
)
params = nnx.state(obj_place, nnx.Param)
print(params)
param_reshaper = ParameterReshaper(params)
strategy = ARS(popsize=100, num_dims=param_reshaper.total_params)
strategy = CMA_ES(popsize=100, num_dims=param_reshaper.total_params)
es_params = strategy.default_params
rng = random.PRNGKey(42)
state = strategy.initialize(rng, es_params)
def es_step(state_input, tmp):
rng, state = state_input
rng, rng_iter = random.split(rng)
x, state = strategy.ask(rng_iter, state, es_params)
weights = param_reshaper.reshape(x)
model = nnx.clone(obj_place)
nnx.update(model, weights)
fitness = model()
fitness = jnp.std(jnp.std(fitness, 1), 1)
state = strategy.tell(x, fitness, state, es_params)
return [rng, state], fitness[jnp.argmin(fitness)]
for i in range(ITERATIONS // EPOCH):
[rng, state], scan_out = lax.scan(es_step, [rng, state], [jnp.zeros(EPOCH)])
print(f"Best Member at Iteration {i * EPOCH}: {state.best_member}")
if __name__ == "__main__":
main()
from cyxtrax_object import (
circular_trajectory,
add_world_orign,
zero_quat,
x_90_quat,
add_offset,
)
from jax import numpy as jnp
from artistlib import API
from cyxtrax.simulation.artist_bridge import set_cone_mode
def main():
fod_mm = jnp.array(
[
1000,
]
)
fdd_mm = jnp.array(
[
2000,
]
)
alpha_rad = jnp.linspace(0, jnp.pi, 100).reshape((-1, 1))
source, orientation_source, detector, orientation_detector = circular_trajectory(
fod_mm, fdd_mm, alpha_rad
)
source, orientation_source, detector, orientation_detector = add_world_orign(
source,
orientation_source,
detector,
orientation_detector,
jnp.array([1, 2.0, -1.0]),
x_90_quat,
)
detector, orientation_detector = add_offset(
detector, orientation_detector, jnp.array([1, 20.0, -1.0]), zero_quat
)
print(source.shape)
print(orientation_detector.shape)
api = API()
set_cone_mode(api)
for i in range(source.shape[0]):
api.translate("S", source[i, 0], source[i, 1], source[i, 2])
api.translate("D", detector[i, 0], detector[i, 1], detector[i, 2])
api.rotate_from_quat("D", orientation_detector[i])
api.rotate_from_quat("S", orientation_source[i])
if __name__ == "__main__":
main()
[metadata]
name = cyxtrax_object
version = 0.1.0
description = A Python module to play with obeject orientation for circular trajectories using local cylindrical xray transform maps or atlases.
author = Simon Wittl
author_email = simon.wittl@th-deg.de / simonwittl@gmail.com
url = https://mygit.th-deg.de/roboct/xraytrafo
[options]
packages = find:
include_package_data = True # Ensures data files are included
zip_safe = False
install_requires =
CyXTraX
jaxlib
jax
chex
flax
\ No newline at end of file
from setuptools import setup
setup()
from .circular_trajectory import (
circular_trajectory,
add_world_orign,
add_offset,
add_origin,
)
from jax import numpy as jnp
from jax.scipy.spatial.transform import Rotation
from .object_placement import CircularTrajectoryOptimization
from .plot_png import plot_map
from .geometry_artist import set_geometry_at_index
zero_quat = jnp.array([0.0, 0.0, 0.0, 1.0])
z_90_quat = Rotation.from_euler("Z", 90.0, True).as_quat()
y_90_quat = Rotation.from_euler("Y", 90.0, True).as_quat()
x_90_quat = Rotation.from_euler("X", 90.0, True).as_quat()
def x_deg2quat(x):
return Rotation.from_euler("X", x, True).as_quat()
def y_deg2quat(x):
return Rotation.from_euler("Y", x, True).as_quat()
def z_deg2quat(x):
return Rotation.from_euler("Z", x, True).as_quat()
__all__ = [
"CircularTrajectoryOptimization",
"plot_map",
"set_geometry_at_index",
"add_origin",
"add_offset",
"add_world_orign",
"circular_trajectory",
]
from jax import numpy as jnp, vmap, jit
from jax.scipy.spatial.transform import Rotation
import chex
@jit
def as_quat(rot: Rotation) -> jnp.ndarray:
return rot.as_quat()
@jit
def pose(pos: chex.Array, rot: chex.Array):
chex.assert_shape(pos, (3,))
chex.assert_shape(rot, (4,))
matrix = jnp.eye(4)
matrix = matrix.at[:3, :3].set(Rotation.from_quat(rot).as_matrix())
matrix = matrix.at[:3, 3].set(pos)
return matrix
@jit
def pose_inv_rot(pos: chex.Array, rot: chex.Array):
chex.assert_shape(pos, (3,))
chex.assert_shape(rot, (4,))
matrix = jnp.eye(4)
matrix = matrix.at[:3, :3].set(Rotation.from_quat(rot).as_matrix().T)
matrix = matrix.at[:3, 3].set(pos)
return matrix
@jit
def pos_quat(pose: chex.Array):
chex.assert_shape(pose, (4, 4))
return pose[:3, 3], Rotation.from_matrix(pose[:3, :3]).as_quat()
@jit
def circular_trajectory(fod_mm: chex.Array, fdd_mm: chex.Array, alpha_rad: chex.Array):
chex.assert_shape(fod_mm, (1,))
chex.assert_shape(fdd_mm, (1,))
chex.assert_rank(alpha_rad, 2)
chex.assert_axis_dimension(alpha_rad, 1, 1)
source = jnp.eye(4)
detector = jnp.eye(4)
detector = detector.at[2, 3].set(fod_mm[0])
source = source.at[2, 3].set((fod_mm - fdd_mm)[0])
rotations = Rotation.from_euler("y", alpha_rad, degrees=False)
rotations_negative = Rotation.from_euler("y", alpha_rad + jnp.pi, degrees=False)
source = rotations.apply(source[:3, 3])
detector = rotations.apply(detector[:3, 3])
orientation_source = vmap(as_quat)(rotations)
orientation_detector = vmap(as_quat)(rotations_negative)
return source, orientation_source, detector, orientation_detector
@jit
def add_origin(
input_position: chex.Array,
input_quat: chex.Array,
origin_position: chex.Array,
origin_quat: chex.Array,
):
chex.assert_rank(input_position, 2)
chex.assert_rank(input_quat, 2)
chex.assert_rank(origin_position, 1)
chex.assert_rank(origin_quat, 1)
chex.assert_axis_dimension(input_position, 1, 3)
chex.assert_axis_dimension(input_quat, 1, 4)
chex.assert_axis_dimension(origin_position, 0, 3)
chex.assert_axis_dimension(origin_quat, 0, 4)
input_trafos = vmap(pose)(input_position, input_quat)
origin_trafo = pose(origin_position, origin_quat)
origin_trafo = jnp.expand_dims(origin_trafo, 0)
trafos = jnp.matmul(origin_trafo, input_trafos)
pos, ori = vmap(pos_quat)(trafos)
return pos, ori
@jit
def add_offset(
input_position: chex.Array,
input_quat: chex.Array,
origin_position: chex.Array,
origin_quat: chex.Array,
):
chex.assert_rank(input_position, 2)
chex.assert_rank(input_quat, 2)
chex.assert_rank(origin_position, 1)
chex.assert_rank(origin_quat, 1)
chex.assert_axis_dimension(input_position, 1, 3)
chex.assert_axis_dimension(input_quat, 1, 4)
chex.assert_axis_dimension(origin_position, 0, 3)
chex.assert_axis_dimension(origin_quat, 0, 4)
input_trafos = vmap(pose)(input_position, input_quat)
origin_trafo = pose_inv_rot(origin_position, origin_quat)
origin_trafo = jnp.expand_dims(origin_trafo, 0)
trafos = jnp.matmul(input_trafos, origin_trafo)
pos, ori = vmap(pos_quat)(trafos)
return pos, ori
@jit
def add_world_orign(
source_position,
source_quat,
detector_position,
detector_quat,
origin_position,
origin_quat,
):
source_position, source_quat = add_origin(
source_position, source_quat, origin_position, origin_quat
)
detector_position, detector_quat = add_origin(
detector_position, detector_quat, origin_position, origin_quat
)
return source_position, source_quat, detector_position, detector_quat
try:
from artist_pythonlib import API, SAVEMODES # type: ignore
except ModuleNotFoundError:
from warnings import warn
warn(
"The module `artistlib`is not installed. The simulation module is not 100\% usable! \nInstall: https://github.com/wittlsn/aRTist-PythonLib"
)
def API():
return None
utility = None
SAVEMODES = None
from pathlib import Path
def set_geometry_at_index(
source,
orientation_source,
detector,
orientation_detector,
index,
temp_projection: Path = None,
):
api = API()
api.translate("S", source[index, 0], source[index, 1], source[index, 2])
api.translate("D", detector[index, 0], detector[index, 1], detector[index, 2])
api.rotate_from_quat("D", orientation_detector[index])
api.rotate_from_quat("S", orientation_source[index])
if temp_projection is not None:
api.save_image(temp_projection, save_mode=SAVEMODES.FLOAT_TIFF)
from flax import nnx
from jax import numpy as jnp, vmap
import chex
from cyxtrax.mapping import map_source_2_cylinder
from cyxtrax_object import circular_trajectory, add_world_orign
from jax.scipy.spatial.transform import Rotation
x_90_quat = Rotation.from_euler("X", 90.0, True).as_quat()
class RayCalculator(nnx.Module):
def __init__(
self,
maps: chex.Array,
map_positions: chex.Array,
radius: float = 1000.0,
angle_discretisation: int = 2000,
pitch: float = jnp.pi,
) -> None:
chex.assert_rank(maps, 3)
chex.assert_rank(map_positions, 2)
chex.assert_axis_dimension(map_positions, 0, 3)
self.maps = maps
self.map_positions = map_positions
self.radius = radius
self.angle_discretisation = angle_discretisation
self.pitch = pitch
def __call__(self, source_positions):
ray_values = vmap(map_source_2_cylinder, (0, None, None, None, None, None))(
source_positions,
self.maps,
self.map_positions,
self.radius,
self.angle_discretisation,
self.pitch,
)
return ray_values[0]
class CircularTrajectoryOptimization(nnx.Module):
def __init__(
self,
maps,
map_positions,
radius: float = 1000,
angle_discretisation: int = 2000,
pitch: float = jnp.pi,
number_of_projection: int = 1000,
fod_mm: float = 1000,
fdd_mm: float = 2000.0,
gamma: float = jnp.pi * 2.0,
euler_conv: str = "YZ",
only_orientation: bool = False,
) -> None:
self.ray_calc = RayCalculator(
maps, map_positions, radius, angle_discretisation, pitch
)
self.alpha_x_deg = nnx.Param(jnp.zeros((1, 1)))
self.beta_y_deg = nnx.Param(jnp.zeros((1, 1)))
if only_orientation:
self.origin = nnx.Variable(jnp.zeros((1, 3)))
else:
self.origin = nnx.Param(jnp.zeros((1, 3)))
self.number_of_projections = number_of_projection
self.fod_mm = jnp.array(fod_mm).reshape((1,))
self.fdd_mm = jnp.array(fdd_mm).reshape((1,))
self.gamma = gamma
self.euler_conv = euler_conv
def __call__(self):
source, orientation_source, detector, orientation_detector = (
self.get_state_trajectory()
)
return vmap(self.ray_calc)(source)
def get_trajectory(self):
alpha_rad = jnp.linspace(0, self.gamma, self.number_of_projections).reshape(
(-1, 1)
)
return add_world_orign(
*circular_trajectory(self.fod_mm, self.fdd_mm, alpha_rad),
jnp.zeros((3,)),
x_90_quat,
)
def get_state_trajectory(self):
source, orientation_source, detector, orientation_detector = (
self.get_trajectory()
)
angles = jnp.concatenate(
(self.alpha_x_deg.value, self.beta_y_deg.value), axis=-1
)
origin_quat = Rotation.from_euler(self.euler_conv, angles, True).as_quat()
return vmap(add_world_orign, in_axes=(None, None, None, None, 0, 0))(
source,
orientation_source,
detector,
orientation_detector,
jnp.array(self.origin),
origin_quat,
)
from matplotlib import pyplot as plt
from pathlib import Path
def plot_map(map, angle_min: list, folder: Path, name: str):
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)
ax.imshow(map)
ax.set_xlabel(r"$\alpha$ / °")
ax.set_ylabel(r"$\beta$ / °")
ax.set_xticks([0, int(map.shape[0] // 2), int(map.shape[0]) - 1])
ax.set_xticklabels([f"-{angle_min[0]:2.2f}", "0.", f"{angle_min[0]:2.2f}"])
ax.set_yticks([0, int(map.shape[1] // 2), int(map.shape[1]) - 1])
ax.set_yticklabels([f"-{angle_min[1]:2.2f}", "0.", f"{angle_min[1]:2.2f}"])
ax.set_title(f"Map {name}")
name = name.replace(" ", "")
fig.savefig(folder / f"{name.lower()}_map.png")
temp/logo.png

46.6 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="100mm"
height="100mm"
viewBox="0 0 100 100"
version="1.1"
id="svg1"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
sodipodi:docname="logo.svg"
inkscape:export-filename="logo.png"
inkscape:export-xdpi="48.767998"
inkscape:export-ydpi="48.767998"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.1180205"
inkscape:cx="299.63672"
inkscape:cy="419.04419"
inkscape:window-width="3200"
inkscape:window-height="1711"
inkscape:window-x="3191"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<linearGradient
id="linearGradient1051"
inkscape:collect="always">
<stop
style="stop-color:#fea4bb;stop-opacity:1;"
offset="0"
id="stop1051" />
<stop
style="stop-color:#547bbf;stop-opacity:0.90588236;"
offset="0.5"
id="stop1054" />
<stop
style="stop-color:#058073;stop-opacity:0.8142361;"
offset="1"
id="stop1052" />
</linearGradient>
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Colorize"
id="filter15"
x="0"
y="0"
width="1"
height="1">
<feComposite
in2="SourceGraphic"
operator="arithmetic"
k1="1.15854"
k2="0"
result="composite1"
id="feComposite14" />
<feColorMatrix
in="composite1"
values="1"
type="saturate"
result="colormatrix1"
id="feColorMatrix14" />
<feFlood
flood-opacity="0.568627"
flood-color="rgb(240,249,98)"
result="flood1"
id="feFlood14" />
<feBlend
in="flood1"
in2="colormatrix1"
mode="multiply"
result="blend1"
id="feBlend14" />
<feBlend
in2="blend1"
mode="normal"
result="blend2"
id="feBlend15" />
<feColorMatrix
in="blend2"
values="1"
type="saturate"
result="colormatrix2"
id="feColorMatrix15" />
<feComposite
in="colormatrix2"
in2="SourceGraphic"
operator="in"
k2="1"
result="fbSourceGraphic"
id="feComposite15" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix16" />
<feComposite
id="feComposite16"
in2="fbSourceGraphic"
operator="arithmetic"
k1="1.15854"
k2="0"
result="composite1"
in="fbSourceGraphic" />
<feColorMatrix
id="feColorMatrix17"
in="composite1"
values="1"
type="saturate"
result="colormatrix1" />
<feFlood
id="feFlood17"
flood-opacity="0.568627"
flood-color="rgb(240,249,98)"
result="flood1" />
<feBlend
id="feBlend17"
in="flood1"
in2="colormatrix1"
mode="multiply"
result="blend1" />
<feBlend
id="feBlend18"
in2="blend1"
mode="normal"
result="blend2" />
<feColorMatrix
id="feColorMatrix18"
in="blend2"
values="1"
type="saturate"
result="colormatrix2" />
<feComposite
id="feComposite18"
in="colormatrix2"
in2="fbSourceGraphic"
operator="in"
k2="1"
result="composite2" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient1051"
id="radialGradient1052"
cx="60.41275"
cy="40.88699"
fx="60.41275"
fy="40.88699"
r="50"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.2665938,2.068853,-0.53765962,0.848932,-114.94789,-118.80839)" />
<filter
style="color-interpolation-filters:sRGB"
inkscape:label="Colorize"
id="filter15-3"
x="0"
y="0"
width="1"
height="1">
<feComposite
in2="SourceGraphic"
operator="arithmetic"
k1="1.15854"
k2="0"
result="composite1"
id="feComposite14-1"
k3="0"
k4="0" />
<feColorMatrix
in="composite1"
values="1"
type="saturate"
result="colormatrix1"
id="feColorMatrix14-3" />
<feFlood
flood-opacity="0.568627"
flood-color="rgb(240,249,98)"
result="flood1"
id="feFlood14-2" />
<feBlend
in="flood1"
in2="colormatrix1"
mode="multiply"
result="blend1"
id="feBlend14-2" />
<feBlend
in2="blend1"
mode="normal"
result="blend2"
id="feBlend15-0" />
<feColorMatrix
in="blend2"
values="1"
type="saturate"
result="colormatrix2"
id="feColorMatrix15-1" />
<feComposite
in="colormatrix2"
in2="SourceGraphic"
operator="in"
result="fbSourceGraphic"
id="feComposite15-4" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix16-7" />
<feComposite
id="feComposite16-0"
in2="fbSourceGraphic"
operator="arithmetic"
k1="1.15854"
k2="0"
result="composite1"
in="fbSourceGraphic"
k3="0"
k4="0" />
<feColorMatrix
id="feColorMatrix17-5"
in="composite1"
values="1"
type="saturate"
result="colormatrix1" />
<feFlood
id="feFlood17-5"
flood-opacity="0.568627"
flood-color="rgb(240,249,98)"
result="flood1" />
<feBlend
id="feBlend17-5"
in="flood1"
in2="colormatrix1"
mode="multiply"
result="blend1" />
<feBlend
id="feBlend18-3"
in2="blend1"
mode="normal"
result="blend2" />
<feColorMatrix
id="feColorMatrix18-6"
in="blend2"
values="1"
type="saturate"
result="colormatrix2" />
<feComposite
id="feComposite18-7"
in="colormatrix2"
in2="fbSourceGraphic"
operator="in"
result="composite2" />
</filter>
</defs>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#000000;stroke-width:0.264583;fill-opacity:0"
id="rect1"
width="100"
height="100"
x="0"
y="0"
inkscape:label="rect1" />
<rect
style="fill:url(#radialGradient1052);fill-opacity:1;stroke-width:0.264583;filter:url(#filter15)"
id="rect2"
width="100"
height="100"
x="0"
y="0" />
<text
xml:space="preserve"
style="font-size:25.4px;letter-spacing:2.64583px;fill:#1eb7be;fill-opacity:1;stroke-width:0.264583"
x="47.415554"
y="21.421324"
id="text9"><tspan
sodipodi:role="line"
id="tspan9"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25.4px;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';letter-spacing:2.64583px;fill:#ffffff;fill-opacity:1;stroke-width:0.264583"
x="47.415554"
y="21.421324">THD</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05556px;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';letter-spacing:2.38125px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke-width:0.264583"
x="2.3253708"
y="94.57032"
id="text10"><tspan
sodipodi:role="line"
id="tspan10"
style="font-size:7.05556px;letter-spacing:2.38125px;word-spacing:0px;stroke-width:0.264583"
x="2.3253708"
y="94.57032"
dx="0">TWIN ROBOTIC CT</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.7px;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke-width:0.264583"
x="50.820835"
y="49.816677"
id="text10-8"><tspan
sodipodi:role="line"
style="font-size:12.7px;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="50.820835"
y="49.816677"
id="tspan1">CyXTraX</tspan><tspan
sodipodi:role="line"
style="font-size:12.7px;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="50.820835"
y="65.691673"
id="tspan1054">Object</tspan><tspan
sodipodi:role="line"
style="font-size:12.7px;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;stroke-width:0.264583"
x="50.820835"
y="81.566673"
id="tspan2" /></text>
</g>
</svg>
temp/meanstd_map.png

16.2 KiB

Source diff could not be displayed: it is too large. Options to address this: view the blob.