diff --git a/examples/01_api_example.py b/examples/01_api_example.py new file mode 100644 index 0000000000000000000000000000000000000000..102cb52321d34bb071f804bb7262c5dad7005af6 --- /dev/null +++ b/examples/01_api_example.py @@ -0,0 +1,76 @@ +# Copyright 2023 Simon Wittl (Deggendorf Institute of Technology) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import matplotlib.pyplot as plt +from pathlib import Path + +from artist_pythonlib import API +from artist_pythonlib.hardware import XraySource, XrayDetector + + +def main(): + # Initialize the api. + artist_api = API() + + # Move and rotate source to initial position / orientation. + artist_api.rotate('S', alpha=0., beta=77, gamma=-12.) + artist_api.translate('S', x=10, y=-129, z=199.4) + + # Get the current position of the source: + source_position = artist_api.get_position('S') + source_orientation = artist_api.get_orientation('S') + + print(f'Source Position: {source_position}') + print(f'Source Orientation: {source_orientation}') + + # Create a source object and set the voltage + source = XraySource() + source.voltage_kv = 142. + source.exposure_ma = 10. + + print(f'Source Voltage: {source.voltage_kv} kV') + print(f'Source Exposure: {source.exposure_ma} mA') + print(f'Source Type: {source.source_type}') + + # Create a detector object and set the resolution + detector = XrayDetector() + detector.detector_resolution_mm = [0.1, 0.15] + detector.detector_count_px = [1000, 1000] + + print(f'Detector Resolution: {detector.detector_resolution_mm} mm') + print(f'Detector Pixel Count: {detector.detector_count_px} px') + + # Load .stl part + new_id = artist_api.load_part( + Path(r'C:\Program Files\BAM\aRTist 2.12\Data\Library\ExampleParts\Fun\Dog.stl'), # Plesas check where the aRTist software is installed. + 'Fe', + 'test_object') + + # Make a projection an visualize it in python + image = artist_api.get_image() + + # change material + artist_api.set_material(new_id, 'Al') + + plt.imshow(image) + plt.show() + + # Set visibility off + artist_api.set_visibility(new_id, False) + + # Delete part + artist_api.delete_part(new_id) + +if __name__ == '__main__': + main() diff --git a/examples/02_circular_trajectory.py b/examples/02_circular_trajectory.py new file mode 100644 index 0000000000000000000000000000000000000000..6e196ff2aa687f2d82b3bca5f57f800ec3800e73 --- /dev/null +++ b/examples/02_circular_trajectory.py @@ -0,0 +1,44 @@ +# Copyright 2023 Simon Wittl (Deggendorf Institute of Technology) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import annotations + +from pathlib import Path + +from artist_pythonlib import API, PROJECTIONGEOMETRIES +from artist_pythonlib.trajectory import circular_trajectory + + +NUMBER_OF_PROJECTIONS = 20 +SAVEFOLDER = Path('./workspace') / 'example_02' +SAVEFOLDER.mkdir(exist_ok=True) + + +def main(): + trajectory = circular_trajectory(500., 1000., NUMBER_OF_PROJECTIONS) + api = API() + + for i in range(NUMBER_OF_PROJECTIONS): + source, detector, rotation_matrix = trajectory[0][i], trajectory[1][i], trajectory[2][i] + + api.translate('S', *source) + api.translate('D', *detector) + api.rotate_from_rotation_matrix('S', rotation_matrix) + api.rotate_from_rotation_matrix('D', rotation_matrix) + + api.save_image(SAVEFOLDER / f'{i:03}.tif', save_projection_geometry=PROJECTIONGEOMETRIES.THD) + + +if __name__ == '__main__': + main() + \ No newline at end of file diff --git a/examples/03_get_spectrum.py b/examples/03_get_spectrum.py new file mode 100644 index 0000000000000000000000000000000000000000..358b8265d374d3f67d7e54910b9b820b26d5eb02 --- /dev/null +++ b/examples/03_get_spectrum.py @@ -0,0 +1,51 @@ +from artist_pythonlib import API +import numpy as np +from matplotlib import pyplot as plt +from xraydb import mu_elam + + +def scrap_spectrum(artist_spectrum: str): + try: + spectrum_dict = artist_spectrum.split('{# Avg:')[-1].split('Flux')[1] + spectrum_dict = spectrum_dict.replace('{', '') + spectrum_dict = spectrum_dict.replace('}', '') + spectrum_dict = spectrum_dict.replace('\t', ' ') + spectrum_dict = spectrum_dict.split(' ')[3:-1] + spectrum = np.array(spectrum_dict, np.float32) + return spectrum.reshape((-1, 2)) + except IndexError: + raise ValueError('Ploychromatic Source must be set in aRTist!') + + +def get_current_artist_spcectrum(api: API) -> np.ndarray: + return scrap_spectrum(api.rc.send('Engine::GetSpectrum')) + + +def main(): + api = API() + current_spectrum = get_current_artist_spcectrum(api) + energy_keV = current_spectrum[:, 0] + photons_n = current_spectrum[:, 1] + + plt.plot(energy_keV, photons_n) + plt.title('aRTist Source Spectrum') + plt.ylabel('Photons (n)') + plt.xlabel('Energy (keV)') + plt.show() + + energy = np.arange(500, 120000, 10) # energy in eV + + for elem in ('C', 'Cu', 'Au'): + mu = mu_elam(elem, energy) + plt.plot(energy / 1000., mu, label=elem) + + plt.title('X-ray Mass Attenuation') + plt.xlabel('Energy (keV)') + plt.ylabel(r'$\mu/\rho \rm\, (cm^2/gr)$') + plt.legend() + plt.yscale('log') + plt.xscale('log') + plt.show() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/examples/04_save_image.py b/examples/04_save_image.py new file mode 100644 index 0000000000000000000000000000000000000000..aa34c154b4c9ff27e199db3dd8a8f7a9028df678 --- /dev/null +++ b/examples/04_save_image.py @@ -0,0 +1,17 @@ +from artist_pythonlib import SAVEMODES, API +from artist_pythonlib.common_types import PROJECTIONGEOMETRIES +from pathlib import Path + +def main(): + # Initialize the api. + artist_api = API() + + # Save Folder + save_folder = Path('./workspace') + save_folder.mkdir(exist_ok=True) + + # Save image / Save images and load them is fastern than to send the images via the rc connection. + artist_api.save_image(save_folder / 'projection.tif', SAVEMODES.UINT16, save_projection_geometry=PROJECTIONGEOMETRIES.THD) + +if __name__ == '__main__': + main() \ No newline at end of file