diff --git a/CMake/BuildConfigurations/All.cmake b/CMake/BuildConfigurations/All.cmake index 2bbbfaf858..6a3b24125e 100644 --- a/CMake/BuildConfigurations/All.cmake +++ b/CMake/BuildConfigurations/All.cmake @@ -1,51 +1,45 @@ set(MITK_CONFIG_PACKAGES ) set(_apple_package_excludes) set(_package_excludes ${_apple_package_excludes} OpenCL OpenMP SYSTEM_Boost Boost_LIBRARIES SYSTEM_PYTHON SUPERBUILD - BiophotonicsHardware_SpectroCam POLHEMUS_TRACKER - - US_DiPhAS_SDK - GALIL_HARDWARE - OPHIR_PYRO_HARDWARE - MICROBIRD_TRACKER MICROBIRD_TRACKER_INCLUDE_DIR MICROBIRD_TRACKER_LIB MICRON_TRACKER OPTITRACK_TRACKER SPACENAVIGATOR TOF_KINECT TOF_KINECTV2 TOF_MESASR4000 TOF_PMDCAMBOARD TOF_PMDCAMCUBE TOF_PMDO3 US_TELEMED_SDK videoInput WIIMOTE ) get_cmake_property(_cache_vars CACHE_VARIABLES) foreach(_cache_var ${_cache_vars}) string(REGEX REPLACE "MITK_USE_(.+)" "\\1" _package "${_cache_var}") if(_package AND NOT _package STREQUAL _cache_var) list(FIND _package_excludes ${_package} _index) if(_index EQUAL -1) list(APPEND MITK_CONFIG_PACKAGES ${_package}) endif() endif() endforeach() set(MITK_BUILD_ALL_APPS ON CACHE BOOL "Build all MITK applications" FORCE) set(MITK_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all MITK plugins" FORCE) set(MITK_BUILD_EXAMPLES ON CACHE BOOL "Build the MITK examples" FORCE) set(BLUEBERRY_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all BlueBerry plugins" FORCE) diff --git a/CMake/BuildConfigurations/camiPhotoacousticsSetup.cmake b/CMake/BuildConfigurations/camiPhotoacousticsSetup.cmake deleted file mode 100644 index 4a881e5fb6..0000000000 --- a/CMake/BuildConfigurations/camiPhotoacousticsSetup.cmake +++ /dev/null @@ -1,25 +0,0 @@ -message(STATUS "Configuring MITK Photoacoustics Setup Build") - -# Enable open cv and open igt link, which is a necessary configuration -set(MITK_USE_OpenCV ON CACHE BOOL "MITK Use OpenCV Library" FORCE) -set(MITK_USE_OpenIGTLink ON CACHE BOOL "MITK Use OpenIGTLink Library" FORCE) -set(MITK_USE_US_DiPhAS_SDK ON CACHE BOOL "Use DiPhAS SDK" FORCE) -set(MITK_US_DiPhAS_SDK_PATH "C:/Users/dkfz/Source/Repos/UltrasoundResearchPlatform_SDK/UltrasoundResearchPlatformSDK_Cpp/x64" CACHE PATH "DiPhAS SDK Path") - -set(MITK_USE_OPHIR_PYRO_HARDWARE ON CACHE BOOL "Use the Ophir sensor build-in in OPOTEK Phocus Mobile" FORCE) -set(MITK_OPHIR_API_PATH "C:/OphirCppWrapper" CACHE PATH "Ophir API Path") - -set(MITK_USE_GALIL_HARDWARE ON CACHE BOOL "Use hardware build-in in OPOTEK Phocus Mobile" FORCE) -set(MITK_GALIL_API_PATH "C:/Program Files (x86)/Galil/gclib" CACHE PATH "Galil API Path") - -# Enable default plugins and the navigation modules -set(MITK_CONFIG_PLUGINS - org.mitk.gui.qt.datamanager - org.mitk.gui.qt.stdmultiwidgeteditor - org.mitk.gui.qt.imagenavigator - org.mitk.gui.qt.properties - org.mitk.gui.qt.viewnavigator - org.mitk.gui.qt.ultrasound - org.mitk.gui.qt.lasercontrol -) - diff --git a/CMake/BuildConfigurations/camiPhotoacousticsWorkstation.cmake b/CMake/BuildConfigurations/camiPhotoacousticsWorkstation.cmake deleted file mode 100644 index 0b05599c4e..0000000000 --- a/CMake/BuildConfigurations/camiPhotoacousticsWorkstation.cmake +++ /dev/null @@ -1,22 +0,0 @@ -message(STATUS "Configuring MITK Photoacoustics Setup Build") - -# Enable open cv and open igt link, which is a necessary configuration -set(MITK_USE_OpenCV ON CACHE BOOL "MITK Use OpenCV Library" FORCE) -set(MITK_USE_OpenIGTLink ON CACHE BOOL "MITK Use OpenIGTLink Library" FORCE) - -set(MITK_USE_OpenCL ON CACHE BOOL "MITK Use OpenCL Library" FORCE) - -# Also enable plugins often used in photoacoustics -set(MITK_CONFIG_PLUGINS - org.mitk.gui.qt.datamanager - org.mitk.gui.qt.stdmultiwidgeteditor - org.mitk.gui.qt.imagenavigator - org.mitk.gui.qt.properties - org.mitk.gui.qt.viewnavigator - org.mitk.gui.qt.ultrasound - org.mitk.gui.qt.photoacoustics.imageprocessing - org.mitk.gui.qt.measurementtoolbox - org.mitk.gui.qt.pointsetinteraction -) - -set(BUILD_PhotoacousticBeamformingTool ON CACHE BOOL "Build commandline tools for Beamforming" FORCE) diff --git a/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox b/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox index 28d65a2336..a85370db75 100644 --- a/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox +++ b/Documentation/Doxygen/2-UserManual/MITKPluginManualsList.dox @@ -1,73 +1,71 @@ /** \page PluginListPage MITK Plugin Manuals The plugins and bundles provide much of the extended functionality of MITK. Each encapsulates a solution to a problem and associated features. This way one can easily assemble the necessary capabilites for a workflow without adding a lot of bloat, by combining plugins as needed. \subpage PluginListGeneralPage \subpage PluginListSpecificPage */ diff --git a/Documentation/Doxygen/2-UserManual/MITKPluginSpecificManualsList.dox b/Documentation/Doxygen/2-UserManual/MITKPluginSpecificManualsList.dox index 9f1a98ced2..a6e4f4d28f 100644 --- a/Documentation/Doxygen/2-UserManual/MITKPluginSpecificManualsList.dox +++ b/Documentation/Doxygen/2-UserManual/MITKPluginSpecificManualsList.dox @@ -1,36 +1,34 @@ /** \page PluginListSpecificPage List of Application-specific Plugins \li \subpage org_mitk_gui_qt_aicpregistration \li \subpage org_mitk_gui_qt_cest \li \subpage org_mitk_gui_qt_classificationsegmentation \li \subpage org_mitk_gui_qt_flowapplication \li \subpage org_mitk_views_cmdlinemodules \li \subpage org_mitk_views_pharmacokinetics_concentration_mri \li \subpage org_mitk_views_pharmacokinetics_mri \li \subpage org_mitk_views_pharmacokinetics_pet \li \subpage org_mitk_views_pharmacokinetics_simulation \li \subpage org_mitk_gui_qt_examples \li \subpage org_mitk_gui_qt_geometrytools \li \subpage org_mitk_gui_qt_igtexample \li \subpage org_mitk_gui_qt_igttracking \li \subpage org_mitk_views_igttrackingsemiautomaticmeasurement \li \subpage org_mitk_views_imagestatistics \li \subpage org_mitk_views_fit_demo \li \subpage org_mitk_views_fit_genericfitting \li \subpage org_mitk_views_fit_inspector \li \subpage org_mitkexamplesopencv \li \subpage org_mitk_gui_qt_overlaymanager \li \subpage org_mitk_gui_qt_mitkphenotyping \li \subpage org_mitk_gui_qt_preprocessing_resampling \li \subpage org_mitk_views_pharmacokinetics_curvedescriptor - \li \subpage org_mitk_views_photoacoustics_imageprocessing \li \subpage org_mitk_gui_qt_pharmacokinetics_simulation - \li \subpage org_mitk_gui_qt_photoacoustics_spectralunmixing \li \subpage org_surfacematerialeditor \li \subpage org_blueberry_ui_qt_objectinspector \li \subpage org_toftutorial \li \subpage org_mitk_gui_qt_ultrasound \li \subpage org_mitk_gui_qt_xnat */ diff --git a/Modules/Biophotonics/CMakeLists.txt b/Modules/Biophotonics/CMakeLists.txt deleted file mode 100644 index f45b05b564..0000000000 --- a/Modules/Biophotonics/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -MITK_CREATE_MODULE(mitkBiophotonics -) -if( MITK_USE_Python3 ) - ADD_SUBDIRECTORY(python) -endif() diff --git a/Modules/Biophotonics/python/iMC/mc/__init__.py b/Modules/Biophotonics/python/iMC/mc/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/mc/batches.py b/Modules/Biophotonics/python/iMC/mc/batches.py deleted file mode 100644 index 2706262dc6..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/batches.py +++ /dev/null @@ -1,375 +0,0 @@ -''' -Created on Oct 15, 2015 - -@author: wirkert -''' - -import numpy as np -from pandas import DataFrame -import pandas as pd - - -class AbstractBatch(object): - """summarizes a batch of simulated mc spectra""" - - def __init__(self): - self._nr_layers = 0 # internally keeps track of number of layers - my_index = pd.MultiIndex(levels=[[], []], - labels=[[], []]) - self.df = DataFrame(columns=my_index) - - def create_parameters(self, nr_samples): - """create the parameters for the batch, the simulation has - to create the resulting reflectances""" - pass - - def nr_elements(self): - return self.df.shape[0] - - -class GenericBatch(AbstractBatch): - """generic n-layer batch with each layer having the same oxygenation """ - - def __init__(self): - super(GenericBatch, self).__init__() - - def append_one_layer(self, saO2, nr_samples): - """helper function to create parameters for one layer""" - - # scales data to lie between maxi and mini instead of 0 and 1 - scale = lambda x, mini, maxi: x * (maxi - mini) + mini - # shortcut to random generator - gen = np.random.random_sample - gen_n = np.random.normal - - # create layer elements - self.df["layer" + str(self._nr_layers), "vhb"] = \ - scale(gen(nr_samples), 0, 1.) - self.df["layer" + str(self._nr_layers), "sao2"] = \ - saO2 - self.df["layer" + str(self._nr_layers), "a_mie"] = \ - np.clip(gen_n(loc=18.9, scale=10.2, size=nr_samples), - 0.1, np.inf) * 100 # to 1/m - self.df["layer" + str(self._nr_layers), "b_mie"] = \ - np.clip(gen_n(loc=1.286, scale=0.521, size=nr_samples), 0, np.inf) - self.df["layer" + str(self._nr_layers), "d"] = \ - scale(gen(nr_samples), 0, 1.) - self.df["layer" + str(self._nr_layers), "n"] = \ - scale(gen(nr_samples), 1.33, 1.54) - self.df["layer" + str(self._nr_layers), "g"] = \ - scale(gen(nr_samples), 0.8, 0.95) - self._nr_layers += 1 - - def create_parameters(self, nr_samples): - """Create generic three layer batch with a total diameter of 2mm. - saO2 is the same in all layers, but all other parameters vary randomly - within each layer""" - saO2 = np.random.random_sample(size=nr_samples) - - # create three layers with random samples - self.append_one_layer(saO2, nr_samples) - self.append_one_layer(saO2, nr_samples) - self.append_one_layer(saO2, nr_samples) - - # "normalize" d to 2mm - # first extract all layers from df - self.df - - layers = [l for l in self.df.columns.levels[0] if "layer" in l] - # summarize all ds - sum_d = 0 - for l in layers: - sum_d += self.df[l, "d"] - for l in layers: - self.df[l, "d"] = self.df[l, "d"] / sum_d * 2000. * 10 ** -6 - self.df[l, "d"] = np.clip(self.df[l, "d"], 25 * 10 ** -6, np.inf) - - return self.df - - -class GenericBatch(AbstractBatch): - """generic n-layer batch with each layer having the same oxygenation """ - - def __init__(self): - super(GenericBatch, self).__init__() - - def append_one_layer(self, saO2, nr_samples): - """helper function to create parameters for one layer""" - - # scales data to lie between maxi and mini instead of 0 and 1 - scale = lambda x, mini, maxi: x * (maxi - mini) + mini - # shortcut to random generator - gen = np.random.random_sample - gen_n = np.random.normal - - # create layer elements - self.df["layer" + str(self._nr_layers), "vhb"] = \ - scale(gen(nr_samples), 0, 1.) - self.df["layer" + str(self._nr_layers), "sao2"] = \ - saO2 - self.df["layer" + str(self._nr_layers), "a_mie"] = \ - np.clip(gen_n(loc=18.9, scale=10.2, size=nr_samples), - 0.1, np.inf) * 100 # to 1/m - self.df["layer" + str(self._nr_layers), "b_mie"] = \ - np.clip(gen_n(loc=1.286, scale=0.521, size=nr_samples), 0, np.inf) - self.df["layer" + str(self._nr_layers), "d"] = \ - scale(gen(nr_samples), 0, 1.) - self.df["layer" + str(self._nr_layers), "n"] = \ - scale(gen(nr_samples), 1.33, 1.54) - self.df["layer" + str(self._nr_layers), "g"] = \ - scale(gen(nr_samples), 0.8, 0.95) - self._nr_layers += 1 - - def create_parameters(self, nr_samples): - """Create generic three layer batch with a total diameter of 2mm. - saO2 is the same in all layers, but all other parameters vary randomly - within each layer""" - saO2 = np.random.random_sample(size=nr_samples) - - # create three layers with random samples - self.append_one_layer(saO2, nr_samples) - self.append_one_layer(saO2, nr_samples) - self.append_one_layer(saO2, nr_samples) - - # "normalize" d to 2mm - # first extract all layers from df - self.df - - layers = [l for l in self.df.columns.levels[0] if "layer" in l] - # summarize all ds - sum_d = 0 - for l in layers: - sum_d += self.df[l, "d"] - for l in layers: - self.df[l, "d"] = self.df[l, "d"] / sum_d * 2000. * 10 ** -6 - self.df[l, "d"] = np.clip(self.df[l, "d"], 25 * 10 ** -6, np.inf) - - return self.df - - -class LessGenericBatch(AbstractBatch): - """less generic three layer batch. This only varies blood volume fraction - w.r.t. the ColonMuscleBatch. Let's see if DA works in this case.""" - - def __init__(self): - super(LessGenericBatch, self).__init__() - - def append_one_layer(self, saO2, n, d_ranges, nr_samples): - """helper function to create parameters for one layer""" - - # scales data to lie between maxi and mini instead of 0 and 1 - scale = lambda x, mini, maxi: x * (maxi - mini) + mini - # shortcut to random generator - gen = np.random.random_sample - - # create as generic batch - super(LessGenericBatch, self).append_one_layer(saO2, nr_samples) - self._nr_layers -= 1 # we're not finished - - # but some changes in specific layer elements - # more specific layer thicknesses - self.df["layer" + str(self._nr_layers), "d"] = \ - scale(gen(nr_samples), d_ranges[0], d_ranges[1]) - # more specific n - self.df["layer" + str(self._nr_layers), "n"] = \ - n - - self._nr_layers += 1 - - def create_parameters(self, nr_samples): - """Create generic three layer batch with a total diameter of 2mm. - saO2 is the same in all layers, but all other parameters vary randomly - within each layer""" - saO2 = np.random.random_sample(size=nr_samples) - n = np.ones_like(saO2) - # create three layers with random samples - # muscle - self.append_one_layer(saO2, n * 1.36, (600.*10 ** -6, 1010.*10 ** -6), - nr_samples) - # submucosa - self.append_one_layer(saO2, n * 1.36, (415.*10 ** -6, 847.*10 ** -6), - nr_samples) - # mucosa - self.append_one_layer(saO2, n * 1.38, (395.*10 ** -6, 603.*10 ** -6), - nr_samples) - - return self.df - - -class ColonMuscleBatch(GenericBatch): - """three layer batch simulating colonic tissue""" - - def __init__(self): - super(ColonMuscleBatch, self).__init__() - - def append_one_layer(self, saO2, n, d_ranges, nr_samples): - """helper function to create parameters for one layer""" - - # scales data to lie between maxi and mini instead of 0 and 1 - scale = lambda x, mini, maxi: x * (maxi - mini) + mini - # shortcut to random generator - gen = np.random.random_sample - - # create as generic batch - super(ColonMuscleBatch, self).append_one_layer(saO2, nr_samples) - self._nr_layers -= 1 # we're not finished - - # but some changes in specific layer elements - # less blood - self.df["layer" + str(self._nr_layers), "vhb"] = \ - scale(gen(nr_samples), 0, 0.1) - # more specific layer thicknesses - self.df["layer" + str(self._nr_layers), "d"] = \ - scale(gen(nr_samples), d_ranges[0], d_ranges[1]) - # more specific n - self.df["layer" + str(self._nr_layers), "n"] = \ - n - - self._nr_layers += 1 - - def create_parameters(self, nr_samples): - """Create generic three layer batch with a total diameter of 2mm. - saO2 is the same in all layers, but all other parameters vary randomly - within each layer""" - saO2 = np.random.random_sample(size=nr_samples) - n = np.ones_like(saO2) - # create three layers with random samples - # muscle - self.append_one_layer(saO2, n * 1.36, (600.*10 ** -6, 1010.*10 ** -6), - nr_samples) - # submucosa - self.append_one_layer(saO2, n * 1.36, (415.*10 ** -6, 847.*10 ** -6), - nr_samples) - # mucosa - self.append_one_layer(saO2, n * 1.38, (395.*10 ** -6, 603.*10 ** -6), - nr_samples) - - return self.df - - -class GenericMeanScatteringBatch(GenericBatch): - """three layer batch simulating colonic tissue""" - - def __init__(self): - super(GenericMeanScatteringBatch, self).__init__() - - def append_one_layer(self, saO2, nr_samples): - """helper function to create parameters for one layer""" - - # create as generic batch - super(GenericMeanScatteringBatch, self).append_one_layer(saO2, - nr_samples) - self._nr_layers -= 1 # we're not finished - - # restrict exponential scattering to mean value for soft tissue. - self.df["layer" + str(self._nr_layers), "b_mie"] = 1.286 - - self._nr_layers += 1 - - -class ColonMuscleMeanScatteringBatch(ColonMuscleBatch): - """three layer batch simulating colonic tissue""" - - def __init__(self): - super(ColonMuscleMeanScatteringBatch, self).__init__() - - def append_one_layer(self, saO2, n, d_ranges, nr_samples): - """helper function to create parameters for one layer""" - - # create as generic batch - super(ColonMuscleMeanScatteringBatch, self).append_one_layer(saO2, - n, - d_ranges, - nr_samples) - self._nr_layers -= 1 # we're not finished - - # restrict exponential scattering to mean value for soft tissue. - self.df["layer" + str(self._nr_layers), "b_mie"] = 1.286 - - self._nr_layers += 1 - - -class VisualizationBatch(AbstractBatch): - """batch used for visualization of different spectra. Feel free to adapt - for your visualization purposes.""" - - def __init__(self): - super(VisualizationBatch, self).__init__() - - def append_one_layer(self, vhb, sao2, a_mie, b_mie, d, n, g, nr_samples): - """helper function to create parameters for one layer""" - - # create layer elements - self.df["layer" + str(self._nr_layers), "vhb"] = vhb - self.df["layer" + str(self._nr_layers), "sao2"] = sao2 - self.df["layer" + str(self._nr_layers), "a_mie"] = a_mie - self.df["layer" + str(self._nr_layers), "b_mie"] = b_mie - self.df["layer" + str(self._nr_layers), "d"] = d - self.df["layer" + str(self._nr_layers), "n"] = n - self.df["layer" + str(self._nr_layers), "g"] = g - self._nr_layers += 1 - - def create_parameters(self, nr_samples): - # bvf = np.linspace(0.0, .1, nr_samples) - # saO2 = np.linspace(0., 1., nr_samples) - # d = np.linspace(175, 735, nr_samples) * 10 ** -6 - # a_mie = np.linspace(5., 30., nr_samples) * 100 - # a_ray = np.linspace(0., 60., nr_samples) * 100 - # n = np.linspace(1.33, 1.54, nr_samples) - # g = np.linspace(0, 0.95, nr_samples) - # create three layers with random samples - self.append_one_layer([0.1, 0.02], [0.7, 0.1], 18.9*100., 1.286, - 500 * 10 ** -6, 1.38, 0.9, - nr_samples) - self.append_one_layer(0.04, 0.7, 18.9*100., 1.286, 500 * 10 ** -6, - 1.36, 0.9, - nr_samples) - self.append_one_layer(0.04, 0.7, 18.9*100., 1.286, 500 * 10 ** -6, - 1.36, 0.9, - nr_samples) - - return self.df - - -class IntralipidPhantomBatch(AbstractBatch): - """batch used for visualization of different spectra. Feel free to adapt - for your visualization purposes.""" - - def __init__(self): - super(IntralipidPhantomBatch, self).__init__() - - def append_one_layer(self, nr_samples): - """helper function to create parameters for one layer""" - - # scales data to lie between maxi and mini instead of 0 and 1 - scale = lambda x, mini, maxi: x * (maxi - mini) + mini - # shortcut to random generator - gen = np.random.random_sample - - # create layer elements - self.df["layer" + str(self._nr_layers), "vhb"] = \ - scale(gen(nr_samples), 0.001, 0.1) - self.df["layer" + str(self._nr_layers), "sao2"] = \ - scale(gen(nr_samples), 0., 1.) - self.df["layer" + str(self._nr_layers), "a_mie"] = \ - scale(gen(nr_samples), 5., 40.) * 100 # to 1/m - self.df["layer" + str(self._nr_layers), "b_mie"] = \ - scale(gen(nr_samples), 2.3, 2.4) - self.df["layer" + str(self._nr_layers), "d"] = \ - 2000.*10**-6 - self.df["layer" + str(self._nr_layers), "n"] = \ - scale(gen(nr_samples), 1.33, 1.54) - self.df["layer" + str(self._nr_layers), "g"] = \ - scale(gen(nr_samples), 0.8, 0.95) - self._nr_layers += 1 - - def create_parameters(self, nr_samples): - """Create intralipid batch with a total diameter of 2mm. - all other parameters vary randomly - within each layer to simulate the interlipid scattering/absorption - properties.""" - - # create three layers with random samples - self.append_one_layer(nr_samples) - - return self.df diff --git a/Modules/Biophotonics/python/iMC/mc/create_spectrum.py b/Modules/Biophotonics/python/iMC/mc/create_spectrum.py deleted file mode 100644 index 8d42ea197c..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/create_spectrum.py +++ /dev/null @@ -1,41 +0,0 @@ - -import logging -import time -import os - -from mc.sim import get_diffuse_reflectance - - -def create_spectrum(tissue_model, sim_wrapper, wavelengths): - """ - Create a whole spectrum from one instance (dataframe_row) using our - tissue model at wavelength wavelength. - - Args: - tissue_model: the model which should be used to generate the - spectrum - sim_wrapper: the simulation which should be used to generate the - reflectances - wavelengths: the wavelengths which shall be simulated - - Returns: the simulated reflectances - """ - start = time.time() - # map the _wavelengths array to reflectance list - - def wavelength_to_reflectance(wavelength): - # helper function to determine the reflectance for a given - # wavelength using the current model and simulation - tissue_model.set_wavelength(wavelength) - tissue_model.create_mci_file() - sim_wrapper.run_simulation() - simulation_path = os.path.split(sim_wrapper.mcml_executable)[0] - return get_diffuse_reflectance(os.path.join(simulation_path, - tissue_model. - get_mco_filename())) - reflectances = map(wavelength_to_reflectance, wavelengths) - end = time.time() - # success! - logging.info("successfully ran simulation in " + - "{:.2f}".format(end - start) + " seconds") - return reflectances diff --git a/Modules/Biophotonics/python/iMC/mc/data/beta_carotin.txt b/Modules/Biophotonics/python/iMC/mc/data/beta_carotin.txt deleted file mode 100644 index 902019d56c..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/data/beta_carotin.txt +++ /dev/null @@ -1,1924 +0,0 @@ -lambda beta carotin -##Wavelength (nm) Molar Extinction (cm-1/M) -219.74 860669 -219.99 866939 -220.24 873996 -220.49 887103 -220.74 901200 -220.99 914068 -221.24 931102 -221.49 952261 -221.74 984397 -221.99 1006831 -222.24 1032652 -222.49 1061135 -222.74 1081015 -222.99 1093144 -223.24 1101278 -223.49 1095590 -223.74 1087870 -223.99 1078610 -224.24 1055667 -224.49 1019649 -224.74 984279 -224.99 942523 -225.24 897948 -225.49 847468 -225.74 802920 -225.99 750521 -226.24 704257 -226.49 657528 -226.74 612102 -226.99 568332 -227.24 522203 -227.49 483550 -227.74 445839 -227.99 410272 -228.24 376479 -228.49 346892 -228.74 317864 -228.99 291931 -229.24 267330 -229.49 244432 -229.74 224462 -229.99 206460 -230.24 189372 -230.49 174797 -230.74 162312 -230.99 149431 -231.24 139576 -231.49 129411 -231.74 119268 -231.99 111778 -232.24 104297 -232.49 97028 -232.74 91749 -232.99 85840 -233.24 82466 -233.49 78359 -233.74 74179 -233.99 71819 -234.24 68531 -234.49 65721 -234.74 62361 -234.99 60073 -235.24 57992 -235.49 56889 -235.74 54353 -235.99 52961 -236.24 51795 -236.49 51443 -236.74 49052 -236.99 49363 -237.24 49200 -237.49 48552 -237.74 47755 -237.99 47755 -238.24 47872 -238.49 46494 -238.74 45877 -238.99 45503 -239.24 46845 -239.49 45570 -239.74 46489 -239.99 45822 -240.24 45151 -240.49 45629 -240.74 45232 -240.99 45426 -241.24 44949 -241.49 45723 -241.74 45863 -241.99 44908 -242.24 45165 -242.49 45219 -242.74 44710 -242.99 45597 -243.24 44814 -243.49 45192 -243.74 45250 -243.99 44863 -244.24 44926 -244.49 44841 -244.74 44660 -244.99 44359 -245.24 44796 -245.49 44260 -245.74 45746 -245.99 45404 -246.24 45917 -246.49 45759 -246.74 46012 -246.99 45386 -247.24 45372 -247.49 46291 -247.74 45656 -247.99 46417 -248.24 46989 -248.49 46750 -248.74 47615 -248.99 48034 -249.24 48313 -249.49 48295 -249.74 48777 -249.99 49601 -250.24 49817 -250.49 50290 -250.74 50169 -250.99 49971 -251.24 51047 -251.49 51475 -251.74 52313 -251.99 52551 -252.24 52416 -252.49 54020 -252.74 54168 -252.99 53988 -253.24 53583 -253.49 55038 -253.74 55213 -253.99 55308 -254.24 55155 -254.49 56299 -254.74 56546 -254.99 56470 -255.24 56546 -255.49 56929 -255.74 56641 -255.99 57726 -256.24 58510 -256.49 58433 -256.74 58609 -256.99 58830 -257.24 59411 -257.49 60199 -257.74 59785 -257.99 61920 -258.24 62595 -258.49 63109 -258.74 64541 -258.99 63901 -259.24 64662 -259.49 65284 -259.74 66779 -259.99 66365 -260.24 67946 -260.49 67734 -260.74 69689 -260.99 70594 -261.24 71004 -261.49 72387 -261.74 74004 -261.99 75368 -262.24 75283 -262.49 75864 -262.74 75738 -262.99 77503 -263.24 76265 -263.49 77116 -263.74 77976 -263.99 78476 -264.24 78827 -264.49 79215 -264.74 79841 -264.99 79246 -265.24 79341 -265.49 78886 -265.74 79652 -265.99 80958 -266.24 80696 -266.49 82030 -266.74 82214 -266.99 82201 -267.24 83273 -267.49 84101 -267.74 84790 -267.99 86502 -268.24 87196 -268.49 87479 -268.74 88029 -268.99 89853 -269.24 89641 -269.49 90925 -269.74 93334 -269.99 93983 -270.24 94415 -270.49 95136 -270.74 95951 -270.99 97046 -271.24 98482 -271.49 99924 -271.74 101248 -271.99 101460 -272.24 102617 -272.49 104198 -272.74 104572 -272.99 103621 -273.24 104112 -273.49 103928 -273.74 103185 -273.99 102324 -274.24 103414 -274.49 102270 -274.74 100802 -274.99 100099 -275.24 98856 -275.49 97528 -275.74 98050 -275.99 96253 -276.24 96469 -276.49 97104 -276.74 97212 -276.99 97663 -277.24 98329 -277.49 98235 -277.74 98523 -277.99 98942 -278.24 100099 -278.49 99757 -278.74 101550 -278.99 101649 -279.24 100933 -279.49 102689 -279.74 102865 -279.99 102743 -280.24 103266 -280.49 104220 -280.74 104018 -280.99 103748 -281.24 104797 -281.49 105247 -281.74 105878 -281.99 105954 -282.24 107324 -282.49 108333 -282.74 109679 -282.99 110400 -283.24 111179 -283.49 111332 -283.74 111499 -283.99 110323 -284.24 108968 -284.49 108432 -284.74 106148 -284.99 104653 -285.24 102905 -285.49 99717 -285.74 97735 -285.99 95681 -286.24 92771 -286.49 90096 -286.74 88344 -286.99 85795 -287.24 83975 -287.49 83147 -287.74 80728 -287.99 79206 -288.24 79071 -288.49 78386 -288.74 77503 -288.99 78206 -289.24 77125 -289.49 78053 -289.74 76715 -289.99 77215 -290.24 77035 -290.49 77913 -290.74 77071 -290.99 77715 -291.24 76454 -291.49 76783 -291.74 74440 -291.99 75175 -292.24 73260 -292.49 72198 -292.74 71828 -292.99 71576 -293.24 71725 -293.49 71535 -293.74 70918 -293.99 70319 -294.24 70306 -294.49 71035 -294.74 70603 -294.99 70896 -295.24 70797 -295.49 70783 -295.74 69067 -295.99 67986 -296.24 66658 -296.49 64874 -296.74 62600 -296.99 61176 -297.24 59316 -297.49 56191 -297.74 53763 -297.99 50912 -298.24 48412 -298.49 44381 -298.74 41994 -298.99 39296 -299.24 36734 -299.49 34342 -299.74 32923 -299.99 31887 -300.24 30667 -300.49 29343 -300.74 27352 -300.99 28383 -301.24 26834 -301.49 25902 -301.74 24852 -301.99 23951 -302.24 23591 -302.49 22627 -302.74 22717 -302.99 22136 -303.24 21889 -303.49 22100 -303.74 22961 -303.99 21911 -304.24 20664 -304.49 20551 -304.74 20934 -304.99 19150 -305.24 20736 -305.49 19983 -305.74 21087 -305.99 20245 -306.24 18448 -306.49 18254 -306.74 17547 -306.99 16808 -307.24 16777 -307.49 16434 -307.74 16232 -307.99 17605 -308.24 16551 -308.49 17214 -308.74 16664 -308.99 16218 -309.24 16601 -309.49 16939 -309.74 16205 -309.99 19488 -310.24 16412 -310.49 17713 -310.74 18520 -310.99 12223 -311.24 14417 -311.49 16669 -311.74 18119 -311.99 15633 -312.24 15871 -312.49 14016 -312.74 15961 -312.99 15457 -313.24 13570 -313.49 16808 -313.74 15669 -313.99 14421 -314.24 16033 -314.49 14642 -314.74 16385 -314.99 13471 -315.24 14871 -315.49 17218 -315.74 15943 -315.99 17722 -316.24 13056 -316.49 16376 -316.74 14218 -316.99 13444 -317.24 15043 -317.49 14808 -317.74 12493 -317.99 14142 -318.24 13034 -318.49 11939 -318.74 13980 -318.99 15398 -319.24 12804 -319.49 14115 -319.74 14277 -319.99 15561 -320.24 16313 -320.49 14525 -320.74 13642 -320.99 11989 -321.24 13939 -321.49 14367 -321.74 14759 -321.99 12133 -322.24 13624 -322.49 14430 -322.74 8715 -322.99 14687 -323.24 13741 -323.49 11989 -323.74 10408 -323.99 12457 -324.24 13241 -324.49 12881 -324.74 12376 -324.99 13309 -325.24 14390 -325.49 12120 -325.74 13155 -325.99 12120 -326.24 13552 -326.49 12597 -326.74 13300 -326.99 11822 -327.24 16074 -327.49 14097 -327.74 13498 -327.99 12624 -328.24 14426 -328.49 12291 -328.74 11822 -328.99 13106 -329.24 13863 -329.49 13056 -329.74 11061 -329.99 14421 -330.24 14417 -330.49 13083 -330.74 15079 -330.99 13691 -331.24 12201 -331.49 15858 -331.74 14128 -331.99 14903 -332.24 14727 -332.49 12435 -332.74 13052 -332.99 14660 -333.24 15223 -333.49 13520 -333.74 12002 -333.99 13655 -334.24 14056 -334.49 13705 -334.74 12313 -334.99 14272 -335.24 14295 -335.49 16786 -335.74 14813 -335.99 13565 -336.24 15128 -336.49 14200 -336.74 14241 -336.99 13975 -337.24 12165 -337.49 12854 -337.74 16070 -337.99 12939 -338.24 14484 -338.49 14727 -338.74 16151 -338.99 16245 -339.24 14529 -339.49 15313 -339.74 15655 -339.99 13791 -340.24 13822 -340.49 16466 -340.74 14390 -340.99 15889 -341.24 13714 -341.49 12903 -341.74 11899 -341.99 13854 -342.24 11629 -342.49 13813 -342.74 14853 -342.99 15475 -343.24 13944 -343.49 13637 -343.74 14529 -343.99 14056 -344.24 14466 -344.49 14957 -344.74 14079 -344.99 13953 -345.24 16088 -345.49 14678 -345.74 12854 -345.99 14944 -346.24 13219 -346.49 16070 -346.74 14556 -346.99 15281 -347.24 13998 -347.49 15043 -347.74 15038 -347.99 15565 -348.24 14723 -348.49 15164 -348.74 13660 -348.99 14002 -349.24 14480 -349.49 15579 -349.74 14678 -349.99 15786 -350.24 15880 -350.49 16146 -350.74 14390 -350.99 15020 -351.24 15007 -351.49 15502 -351.74 14209 -351.99 16236 -352.24 16880 -352.49 14142 -352.74 14709 -352.99 15254 -353.24 14678 -353.49 16052 -353.74 15038 -353.99 13822 -354.24 15281 -354.49 14601 -354.74 14588 -354.99 16583 -355.24 15187 -355.49 16678 -355.74 15232 -355.99 15380 -356.24 15466 -356.49 17695 -356.74 15534 -356.99 17934 -357.24 17358 -357.49 16344 -357.74 15511 -357.99 15781 -358.24 17137 -358.49 16813 -358.74 16587 -358.99 15664 -359.24 16673 -359.49 14529 -359.74 15412 -359.99 15412 -360.24 15714 -360.49 16862 -360.74 15723 -360.99 17907 -361.24 16574 -361.49 17502 -361.74 17295 -361.99 16673 -362.24 17141 -362.49 17795 -362.74 16178 -362.99 17646 -363.24 18047 -363.49 17975 -363.74 17389 -363.99 16786 -364.24 16745 -364.49 18614 -364.74 17331 -364.99 17686 -365.24 19191 -365.49 18857 -365.74 17056 -365.99 19529 -366.24 20862 -366.49 18862 -366.74 19281 -366.99 19776 -367.24 20452 -367.49 19727 -367.74 19623 -367.99 18574 -368.24 21010 -368.49 19911 -368.74 20812 -368.99 20028 -369.24 22623 -369.49 22425 -369.74 21695 -369.99 21609 -370.24 21308 -370.49 22456 -370.74 21591 -370.99 21555 -371.24 22578 -371.49 22956 -371.74 23033 -371.99 23641 -372.24 24204 -372.49 24150 -372.74 24123 -372.99 25019 -373.24 23528 -373.49 23469 -373.74 25523 -373.99 25361 -374.24 24298 -374.49 25068 -374.74 25244 -374.99 26555 -375.24 26762 -375.49 25352 -375.74 26244 -375.99 26451 -376.24 26654 -376.49 27352 -376.74 26591 -376.99 27451 -377.24 27424 -377.49 28518 -377.74 27892 -377.99 28577 -378.24 28338 -378.49 29059 -378.74 29298 -378.99 29928 -379.24 29253 -379.49 30090 -379.74 29847 -379.99 29757 -380.24 32072 -380.49 30329 -380.74 29325 -380.99 32432 -381.24 30365 -381.49 30424 -381.74 32013 -381.99 31068 -382.24 32824 -382.49 32959 -382.74 34991 -382.99 31968 -383.24 33045 -383.49 33599 -383.74 34049 -383.99 34923 -384.24 33482 -384.49 34774 -384.74 36216 -384.99 35004 -385.24 36008 -385.49 35981 -385.74 36450 -385.99 35626 -386.24 36828 -386.49 36954 -386.74 38242 -386.99 37833 -387.24 37616 -387.49 38977 -387.74 38472 -387.99 38454 -388.24 39576 -388.49 38796 -388.74 40656 -388.99 40003 -389.24 40733 -389.49 40107 -389.74 42683 -389.99 41850 -390.24 42098 -390.49 40931 -390.74 42791 -390.99 43976 -391.24 44219 -391.49 44246 -391.74 45836 -391.99 45904 -392.24 44570 -392.49 46881 -392.74 47948 -392.99 46849 -393.24 47448 -393.49 48187 -393.74 48863 -393.99 50925 -394.24 50723 -394.49 50916 -394.74 49691 -394.99 50151 -395.24 51164 -395.49 52340 -395.74 52096 -395.99 51624 -396.24 54218 -396.49 53326 -396.74 53754 -396.99 55420 -397.24 55465 -397.49 54529 -397.74 55632 -397.99 56407 -398.24 57528 -398.49 57091 -398.74 56961 -398.99 59213 -399.24 58726 -399.49 59208 -399.74 59109 -399.99 58312 -400.24 60258 -400.49 60744 -400.74 60505 -400.99 61185 -401.24 62154 -401.49 61483 -401.74 61023 -401.99 62302 -402.24 61348 -402.49 61676 -402.74 62717 -402.99 62919 -403.24 62879 -403.49 64248 -403.74 63455 -403.99 63627 -404.24 65315 -404.49 64874 -404.74 65644 -404.99 66126 -405.24 65203 -405.49 66360 -405.74 65117 -405.99 66631 -406.24 66333 -406.49 67063 -406.74 68004 -406.99 68117 -407.24 68063 -407.49 68108 -407.74 68747 -407.99 68189 -408.24 71153 -408.49 69270 -408.74 70999 -408.99 70135 -409.24 71612 -409.49 72414 -409.74 73071 -409.99 73202 -410.24 73179 -410.49 73873 -410.74 74963 -410.99 75463 -411.24 75206 -411.49 75805 -411.74 76260 -411.99 76634 -412.24 78287 -412.49 77485 -412.74 78656 -412.99 78692 -413.24 80233 -413.49 79859 -413.74 81250 -413.99 80426 -414.24 82710 -414.49 83723 -414.74 83723 -414.99 82223 -415.24 83354 -415.49 83633 -415.74 85885 -415.99 86389 -416.24 86750 -416.49 88132 -416.74 88398 -416.99 88259 -417.24 90065 -417.49 89979 -417.74 90416 -417.99 91672 -418.24 92141 -418.49 93294 -418.74 92389 -418.99 94789 -419.24 94744 -419.49 95321 -419.74 96519 -419.99 97374 -420.24 97712 -420.49 97825 -420.74 98014 -420.99 99496 -421.24 99347 -421.49 99527 -421.74 99527 -421.99 100442 -422.24 100955 -422.49 101784 -422.74 102153 -422.99 103176 -423.24 103428 -423.49 103626 -423.74 103468 -423.99 103338 -424.24 103757 -424.49 104738 -424.74 105297 -424.99 105923 -425.24 105756 -425.49 105819 -425.74 106126 -425.99 106094 -426.24 106166 -426.49 105085 -426.74 105711 -426.99 105774 -427.24 106162 -427.49 107071 -427.74 107080 -427.99 106824 -428.24 107193 -428.49 106770 -428.74 108269 -428.99 107216 -429.24 107855 -429.49 107589 -429.74 107445 -429.99 106824 -430.24 107324 -430.49 107711 -430.74 109035 -430.99 107571 -431.24 108634 -431.49 108661 -431.74 107621 -431.99 109040 -432.24 108008 -432.49 108801 -432.74 109179 -432.99 109801 -433.24 109459 -433.49 109341 -433.74 110170 -433.99 110003 -434.24 110116 -434.49 109801 -434.74 111197 -434.99 111436 -435.24 110805 -435.49 112053 -435.74 111643 -435.99 113197 -436.24 112742 -436.49 113008 -436.74 115215 -436.99 114129 -437.24 113994 -437.49 115435 -437.74 116111 -437.99 116147 -438.24 116593 -438.49 117701 -438.74 118205 -438.99 117944 -439.24 118453 -439.49 119908 -439.74 119529 -439.99 120966 -440.24 120948 -440.49 121295 -440.74 122556 -440.99 123367 -441.24 124087 -441.49 124380 -441.74 125105 -441.99 126781 -442.24 124200 -442.49 126961 -442.74 127037 -442.99 127835 -443.24 128785 -443.49 127609 -443.74 129172 -443.99 130510 -444.24 130758 -444.49 130731 -444.74 131604 -444.99 132086 -445.24 132609 -445.49 132721 -445.74 132582 -445.99 135095 -446.24 135649 -446.49 133969 -446.74 134676 -446.99 135383 -447.24 136428 -447.49 135964 -447.74 136752 -447.99 136270 -448.24 137604 -448.49 138288 -448.74 137329 -448.99 136698 -449.24 137464 -449.49 139171 -449.74 139342 -449.99 138730 -450.24 138243 -450.49 139356 -450.74 138590 -450.99 139500 -451.24 137541 -451.49 138509 -451.74 138342 -451.99 137401 -452.24 137887 -452.49 137820 -452.74 136518 -452.99 137572 -453.24 136653 -453.49 136000 -453.74 135915 -453.99 135550 -454.24 135437 -454.49 133577 -454.74 134036 -454.99 133122 -455.24 134000 -455.49 132424 -455.74 133253 -455.99 130983 -456.24 131816 -456.49 131920 -456.74 129028 -456.99 129478 -457.24 129087 -457.49 129015 -457.74 126893 -457.99 126808 -458.24 125736 -458.49 125065 -458.74 125335 -458.99 124367 -459.24 123227 -459.49 122187 -459.74 121966 -459.99 121173 -460.24 119818 -460.49 119651 -460.74 119435 -460.99 118336 -461.24 118070 -461.49 116665 -461.74 116818 -461.99 116273 -462.24 114805 -462.49 114057 -462.74 113998 -462.99 113535 -463.24 113904 -463.49 112882 -463.74 111368 -463.99 112332 -464.24 111233 -464.49 111436 -464.74 109504 -464.99 110148 -465.24 110386 -465.49 109990 -465.74 109431 -465.99 110161 -466.24 110139 -466.49 108369 -466.74 108981 -466.99 107995 -467.24 107450 -467.49 107445 -467.74 107661 -467.99 108432 -468.24 107621 -468.49 108796 -468.74 107517 -468.99 107607 -469.24 108378 -469.49 107977 -469.74 108251 -469.99 108427 -470.24 108792 -470.49 108900 -470.74 108157 -470.99 109283 -471.24 109350 -471.49 109805 -471.74 109094 -471.99 109197 -472.24 109319 -472.49 109058 -472.74 109940 -472.99 110148 -473.24 110472 -473.49 110071 -473.74 111864 -473.99 111409 -474.24 110747 -474.49 111733 -474.74 111134 -474.99 112395 -475.24 112972 -475.49 112566 -475.74 112521 -475.99 111765 -476.24 111747 -476.49 111792 -476.74 112778 -476.99 110404 -477.24 112314 -477.49 112476 -477.74 113111 -477.99 112368 -478.24 111850 -478.49 110445 -478.74 111517 -478.99 110711 -479.24 110828 -479.49 110382 -479.74 109873 -479.99 110769 -480.24 110166 -480.49 108936 -480.74 108427 -480.99 108409 -481.24 108837 -481.49 107270 -481.74 105716 -481.99 106765 -482.24 105491 -482.49 104711 -482.74 103712 -482.99 104356 -483.24 103198 -483.49 102941 -483.74 101518 -483.99 100162 -484.24 99802 -484.49 98491 -484.74 98960 -484.99 96757 -485.24 96248 -485.49 95622 -485.74 94663 -485.99 95114 -486.24 93803 -486.49 91772 -486.74 91551 -486.99 89497 -487.24 89529 -487.49 85826 -487.74 86646 -487.99 85047 -488.24 85115 -488.49 83304 -488.74 81021 -488.99 80611 -489.24 80399 -489.49 79075 -489.74 77318 -489.99 76107 -490.24 74945 -490.49 74323 -490.74 72553 -490.99 70999 -491.24 71265 -491.49 70590 -491.74 68027 -491.99 66887 -492.24 65180 -492.49 64514 -492.74 63618 -492.99 62996 -493.24 59983 -493.49 59379 -493.74 57789 -493.99 58560 -494.24 55605 -494.49 55024 -494.74 54200 -494.99 52736 -495.24 52376 -495.49 50371 -495.74 50218 -495.99 49926 -496.24 48696 -496.49 47142 -496.74 46525 -496.99 45332 -497.24 44390 -497.49 42030 -497.74 41454 -497.99 40458 -498.24 41260 -498.49 37598 -498.74 37044 -498.99 36337 -499.24 35968 -499.49 34621 -499.74 33729 -499.99 32662 -500.24 32135 -500.49 32657 -500.74 30180 -500.99 29933 -501.24 28100 -501.49 27982 -501.74 27437 -501.99 26257 -502.24 24960 -502.49 25203 -502.74 24942 -502.99 24686 -503.24 23118 -503.49 22375 -503.74 21353 -503.99 20673 -504.24 19871 -504.49 20407 -504.74 18155 -504.99 19186 -505.24 19596 -505.49 17912 -505.74 16619 -505.99 16867 -506.24 16880 -506.49 15628 -506.74 15205 -506.99 15434 -507.24 14736 -507.49 13628 -507.74 13016 -507.99 13286 -508.24 13223 -508.49 13417 -508.74 12363 -508.99 11259 -509.24 11800 -509.49 10606 -509.74 9760 -509.99 10985 -510.24 10440 -510.49 9751 -510.74 10277 -510.99 9890 -511.24 9287 -511.49 9683 -511.74 8845 -511.99 8039 -512.24 7296 -512.49 7192 -512.74 7215 -512.99 7994 -513.24 7449 -513.49 6850 -513.74 7003 -513.99 7147 -514.24 6652 -514.49 7490 -514.74 6341 -514.99 6539 -515.24 5129 -515.49 5084 -515.74 4206 -515.99 4963 -516.24 4859 -516.49 5557 -516.74 5490 -516.99 4585 -517.24 4828 -517.49 4278 -517.74 4301 -517.99 4350 -518.24 5098 -518.49 4562 -518.74 4062 -518.99 4589 -519.24 3778 -519.49 3220 -519.74 3639 -519.99 3386 -520.24 3319 -520.49 2850 -520.74 3823 -520.99 4305 -521.24 3666 -521.49 3400 -521.74 1900 -521.99 4188 -522.24 2418 -522.49 3350 -522.74 2116 -522.99 2670 -523.24 3585 -523.49 2535 -523.74 3355 -523.99 1621 -524.24 2661 -524.49 2306 -524.74 2441 -524.99 2026 -525.24 1990 -525.49 2706 -525.74 2319 -525.99 1806 -526.24 2026 -526.49 3058 -526.74 2233 -526.99 319 -527.24 1873 -527.49 2814 -527.74 2837 -527.99 1999 -528.24 1612 -528.49 2143 -528.74 1977 -528.99 3026 -529.24 1549 -529.49 1180 -529.74 1508 -529.99 2229 -530.24 2040 -530.49 824 -530.74 1607 -530.99 1562 -531.24 2260 -531.49 1157 -531.74 1193 -531.99 1810 -532.24 675 -532.49 1837 -532.74 801 -532.99 1801 -533.24 2405 -533.49 963 -533.74 743 -533.99 540 -534.24 1688 -534.49 1288 -534.74 1806 -534.99 454 -535.24 2053 -535.49 1603 -535.74 1896 -535.99 1184 -536.24 -67 -536.49 1423 -536.74 1697 -536.99 986 -537.24 653 -537.49 247 -537.74 157 -537.99 -405 -538.24 1022 -538.49 797 -538.74 1495 -538.99 2062 -539.24 999 -539.49 1634 -539.74 -229 -539.99 2143 -540.24 571 -540.49 1797 -540.74 1274 -540.99 909 -541.24 1355 -541.49 1391 -541.74 1567 -541.99 1157 -542.24 855 -542.49 571 -542.74 810 -542.99 1229 -543.24 1130 -543.49 1035 -543.74 1198 -543.99 571 -544.24 1279 -544.49 319 -544.74 1283 -544.99 702 -545.24 774 -545.49 0 -545.74 1265 -545.99 963 -546.24 -297 -546.49 819 -546.74 427 -546.99 1923 -547.24 495 -547.49 1238 -547.74 405 -547.99 1292 -548.24 882 -548.49 657 -548.74 567 -548.99 900 -549.24 1851 -549.49 1202 -549.74 1373 -549.99 1369 -550.24 1756 -550.49 1153 -550.74 851 -550.99 1675 -551.24 729 -551.49 1279 -551.74 806 -551.99 -495 -552.24 508 -552.49 544 -552.74 1013 -552.99 621 -553.24 229 -553.49 972 -553.74 1697 -553.99 234 -554.24 27 -554.49 1490 -554.74 369 -554.99 747 -555.24 1963 -555.49 585 -555.74 1756 -555.99 13 -556.24 1107 -556.49 -58 -556.74 783 -556.99 1490 -557.24 -337 -557.49 1860 -557.74 666 -557.99 459 -558.24 117 -558.49 977 -558.74 310 -558.99 1026 -559.24 -3 -559.49 1576 -559.74 900 -559.99 -1184 -560.24 774 -560.49 936 -560.74 360 -560.99 801 -561.24 -819 -561.49 1580 -561.74 63 -561.99 1112 -562.24 571 -562.49 833 -562.74 283 -562.99 -211 -563.24 1035 -563.49 252 -563.74 792 -563.99 -481 -564.24 288 -564.49 540 -564.74 31 -564.99 1585 -565.24 -94 -565.49 1427 -565.74 675 -565.99 1252 -566.24 1499 -566.49 -977 -566.74 648 -566.99 -198 -567.24 1549 -567.49 1089 -567.74 680 -567.99 -423 -568.24 198 -568.49 878 -568.74 189 -568.99 193 -569.24 576 -569.49 1022 -569.74 630 -569.99 653 -570.24 481 -570.49 270 -570.74 216 -570.99 1216 -571.24 873 -571.49 -756 -571.74 1589 -571.99 175 -572.24 909 -572.49 -499 -572.74 1134 -572.99 472 -573.24 1162 -573.49 1702 -573.74 36 -573.99 1026 -574.24 1130 -574.49 896 -574.74 1058 -574.99 972 -575.24 1107 -575.49 702 -575.74 1454 -575.99 1116 -576.24 1562 -576.49 707 -576.74 1130 -576.99 1576 -577.24 364 -577.49 18 -577.74 666 -577.99 175 -578.24 905 -578.49 364 -578.74 2161 -578.99 684 -579.24 1342 -579.49 130 -579.74 923 -579.99 833 -580.24 1116 -580.49 666 -580.74 27 -580.99 1189 -581.24 454 -581.49 139 -581.74 -414 -581.99 481 -582.24 2022 -582.49 743 -582.74 594 -582.99 657 -583.24 1026 -583.49 1630 -583.74 207 -583.99 319 -584.24 553 -584.49 1166 -584.74 716 -584.99 1107 -585.24 -72 -585.49 815 -585.74 1382 -585.99 1445 -586.24 860 -586.49 535 -586.74 819 -586.99 355 -587.24 400 -587.49 626 -587.74 -121 -587.99 1175 -588.24 1116 -588.49 788 -588.74 -198 -588.99 1490 -589.24 1279 -589.49 -499 -589.74 1049 -589.99 103 -590.24 481 -590.49 1153 -590.74 1396 -590.99 -193 -591.24 999 -591.49 364 -591.74 972 -591.99 891 -592.24 -31 -592.49 810 -592.74 1171 -592.99 626 -593.24 959 -593.49 1143 -593.74 297 -593.99 558 -594.24 -94 -594.49 918 -594.74 504 -594.99 1022 -595.24 626 -595.49 211 -595.74 490 -595.99 1391 -596.24 220 -596.49 617 -596.74 261 -596.99 346 -597.24 828 -597.49 162 -597.74 121 -597.99 36 -598.24 184 -598.49 1360 -598.74 1022 -598.99 630 -599.24 1116 -599.49 1819 -599.74 -45 -599.99 734 -600.24 522 -600.49 558 -600.74 887 -600.99 81 -601.24 1373 -601.49 297 -601.74 1427 -601.99 -603 -602.24 81 -602.49 1351 -602.74 891 -602.99 635 -603.24 963 -603.49 -247 -603.74 1058 -603.99 936 -604.24 1688 -604.49 -162 -604.74 1342 -604.99 680 -605.24 963 -605.49 567 -605.74 1171 -605.99 1238 -606.24 693 -606.49 1517 -606.74 526 -606.99 792 -607.24 436 -607.49 1508 -607.74 -328 -607.99 -144 -608.24 1567 -608.49 914 -608.74 702 -608.99 891 -609.24 535 -609.49 1261 -609.74 495 -609.99 1630 -610.24 486 -610.49 1116 -610.74 1274 -610.99 1130 -611.24 914 -611.49 1022 -611.74 1504 -611.99 441 -612.24 1216 -612.49 279 -612.74 729 -612.99 1693 -613.24 968 -613.49 1234 -613.74 851 -613.99 698 -614.24 873 -614.49 1040 -614.74 617 -614.99 684 -615.24 1472 -615.49 608 -615.74 779 -615.99 -139 -616.24 1851 -616.49 1391 -616.74 1540 -616.99 463 -617.24 1080 -617.49 450 -617.74 1058 -617.99 1067 -618.24 819 -618.49 783 -618.74 747 -618.99 603 -619.24 1454 -619.49 896 -619.74 1243 -619.99 1743 -620.24 535 -620.49 1607 -620.74 -198 -620.99 1026 -621.24 535 -621.49 54 -621.74 1121 -621.99 432 -622.24 1243 -622.49 846 -622.74 918 -622.99 662 -623.24 2058 -623.49 207 -623.74 508 -623.99 869 -624.24 -13 -624.49 1387 -624.74 950 -624.99 1779 -625.24 1017 -625.49 1369 -625.74 720 -625.99 346 -626.24 2076 -626.49 319 -626.74 1495 -626.99 1202 -627.24 1274 -627.49 2175 -627.74 743 -627.99 1977 -628.24 680 -628.49 1292 -628.74 1234 -628.99 1914 -629.24 626 -629.49 27 -629.74 1882 -629.99 535 -630.24 1495 -630.49 1171 -630.74 720 -630.99 571 -631.24 1049 -631.49 680 -631.74 788 -631.99 1981 -632.24 738 -632.49 801 -632.74 986 -632.99 837 -633.24 1265 -633.49 1481 -633.74 1896 -633.99 738 -634.24 990 -634.49 729 -634.74 968 -634.99 1684 -635.24 963 -635.49 2310 -635.74 743 -635.99 1071 -636.24 1247 -636.49 617 -636.74 2139 -636.99 1688 -637.24 1432 -637.49 1004 -637.74 788 -637.99 1234 -638.24 761 -638.49 806 -638.74 743 -638.99 1589 -639.24 1490 -639.49 2116 -639.74 1774 -639.99 936 -640.24 1612 -640.49 1193 -640.74 977 -640.99 720 -641.24 1238 -641.49 1657 -641.74 900 -641.99 1603 -642.24 761 -642.49 878 -642.74 599 -642.99 585 -643.24 1891 -643.49 1684 -643.74 2022 -643.99 1634 -644.24 873 -644.49 342 -644.74 1373 -644.99 346 -645.24 1774 -645.49 1107 -645.74 977 -645.99 1909 -646.24 468 -646.49 1171 -646.74 662 -646.99 1837 -647.24 274 -647.49 562 -647.74 932 -647.99 621 -648.24 648 -648.49 815 -648.74 1220 -648.99 1022 -649.24 1067 -649.49 828 -649.74 373 -649.99 553 -650.24 828 -650.49 1116 -650.74 1752 -650.99 297 -651.24 2085 -651.49 45 -651.74 1103 -651.99 562 -652.24 1234 -652.49 540 -652.74 581 -652.99 400 -653.24 1288 -653.49 644 -653.74 423 -653.99 1472 -654.24 490 -654.49 684 -654.74 1571 -654.99 1094 -655.24 535 -655.49 198 -655.74 454 -655.99 666 -656.24 445 -656.49 234 -656.74 544 -656.99 1594 -657.24 806 -657.49 941 -657.74 797 -657.99 914 -658.25 234 -658.5 819 -658.75 873 -659 36 -659.25 1481 -659.5 1306 -659.75 662 -660 454 -660.25 1013 -660.5 945 -660.75 -108 -661 1504 -661.25 472 -661.5 1004 -661.75 391 -662 -67 -662.25 648 -662.5 -139 -662.75 869 -663 306 -663.25 1400 -663.5 1116 -663.75 887 -664 1040 -664.25 391 -664.5 378 -664.75 -337 -665 666 -665.25 562 -665.5 112 -665.75 806 -666 544 -666.25 1508 -666.5 90 -666.75 211 -667 378 -667.25 -441 -667.5 540 -667.75 486 -668 562 -668.25 -36 -668.5 247 -668.75 423 -669 -486 -669.25 225 -669.5 918 -669.75 1049 -670 1409 -670.25 549 -670.5 477 -670.75 369 -671 283 -671.25 891 -671.5 171 -671.75 49 -672 387 -672.25 1008 -672.5 405 -672.75 67 -673 -175 -673.25 905 -673.5 -139 -673.75 558 -674 945 -674.25 959 -674.5 450 -674.75 508 -675 234 -675.25 297 -675.5 -13 -675.75 -49 -676 414 -676.25 382 -676.5 -103 -676.75 1013 -677 639 -677.25 513 -677.5 -58 -677.75 1661 -678 -153 -678.25 40 -678.5 130 -678.75 639 -679 941 -679.25 -477 -679.5 -108 -679.75 180 -680 472 -680.25 765 -680.5 -297 -680.75 1220 -681 684 -681.25 450 -681.5 234 -681.75 310 -682 -54 -682.25 279 -682.5 261 -682.75 499 -683 -135 -683.25 517 -683.5 -2 -683.75 94 -684 72 -684.25 680 -684.5 -108 -684.75 279 -685 513 -685.25 -328 -685.5 594 -685.75 126 -686 675 -686.25 103 -686.5 387 -686.75 927 -687 -310 -687.25 364 -687.5 306 -687.75 756 -688 810 -688.25 725 -688.5 54 -688.75 40 -689 720 -689.25 409 -689.5 657 -689.75 315 -690 599 -690.25 373 -690.5 -247 -690.75 490 -691 54 -691.25 540 -691.5 -126 -691.75 -549 -692 486 -692.25 788 -692.5 -234 -692.75 -162 -693 171 -693.25 409 -693.5 477 -693.75 -981 -694 157 -694.25 99 -694.5 1071 -694.75 -648 -695 -58 -695.25 477 -695.5 220 -695.75 211 -696 -171 -696.25 126 -696.5 666 -696.75 166 -697 743 -697.25 387 -697.5 -130 -697.75 716 -698 409 -698.25 4 -698.5 774 -698.75 1639 -699 252 -699.25 396 -699.5 -454 -699.75 -148 -700 1436 diff --git a/Modules/Biophotonics/python/iMC/mc/data/bilirubin.txt b/Modules/Biophotonics/python/iMC/mc/data/bilirubin.txt deleted file mode 100644 index 3ca6e8e1c0..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/data/bilirubin.txt +++ /dev/null @@ -1,1844 +0,0 @@ -# taken from http://omlc.org/spectra/PhotochemCAD/data/119-abs.txt -##Wavelength (nm) Molar Extinction (cm-1/M) -239.75 17208 -240 16074 -240.25 18576 -240.5 16910 -240.75 17810 -241 17784 -241.25 17734 -241.5 18617 -241.75 17737 -242 17532 -242.25 17582 -242.5 17609 -242.75 17141 -243 17102 -243.25 16666 -243.5 16594 -243.75 16111 -244 16576 -244.25 15964 -244.5 15470 -244.75 15805 -245 15304 -245.25 15243 -245.5 15230 -245.75 14725 -246 14481 -246.25 14588 -246.5 14454 -246.75 14002 -247 14152 -247.25 13951 -247.5 13735 -247.75 13755 -248 13531 -248.25 13231 -248.5 13354 -248.75 13226 -249 12855 -249.25 13256 -249.5 12851 -249.75 12557 -250 12254 -250.25 12287 -250.5 12174 -250.75 12231 -251 11840 -251.25 11772 -251.5 11575 -251.75 11246 -252 11231 -252.25 11165 -252.5 11021 -252.75 11034 -253 11068 -253.25 10789 -253.5 10691 -253.75 10568 -254 10477 -254.25 10341 -254.5 10346 -254.75 10029 -255 10164 -255.25 10055 -255.5 9970 -255.75 9865 -256 9945 -256.25 9764 -256.5 9632 -256.75 9781 -257 9670 -257.25 9526 -257.5 9223 -257.75 9096 -258 9220 -258.25 9312 -258.5 9145 -258.75 9138 -259 8955 -259.25 8984 -259.5 8862 -259.75 8933 -260 8891 -260.25 8896 -260.5 8816 -260.75 8984 -261 8774 -261.25 8840 -261.5 8737 -261.75 8679 -262 8719 -262.25 8874 -262.5 8777 -262.75 8685 -263 8627 -263.25 8732 -263.5 8527 -263.75 8572 -264 8650 -264.25 8812 -264.5 8614 -264.75 8601 -265 8612 -265.25 8688 -265.5 8513 -265.75 8498 -266 8698 -266.25 8554 -266.5 8479 -266.75 8449 -267 8560 -267.25 8544 -267.5 8536 -267.75 8448 -268 8470 -268.25 8574 -268.5 8519 -268.75 8580 -269 8518 -269.25 8460 -269.5 8514 -269.75 8616 -270 8620 -270.25 8681 -270.5 8436 -270.75 8509 -271 8573 -271.25 8526 -271.5 8474 -271.75 8543 -272 8591 -272.25 8515 -272.5 8537 -272.75 8695 -273 8550 -273.25 8547 -273.5 8596 -273.75 8545 -274 8435 -274.25 8695 -274.5 8471 -274.75 8560 -275 8727 -275.25 8631 -275.5 8652 -275.75 8360 -276 8625 -276.25 8456 -276.5 8639 -276.75 8632 -277 8473 -277.25 8521 -277.5 8589 -277.75 8557 -278 8627 -278.25 8344 -278.5 8597 -278.75 8561 -279 8646 -279.25 8452 -279.5 8527 -279.75 8426 -280 8634 -280.25 8461 -280.5 8496 -280.75 8525 -281 8383 -281.25 8515 -281.5 8307 -281.75 8411 -282 8374 -282.25 8663 -282.5 8398 -282.75 8418 -283 8501 -283.25 8565 -283.5 8227 -283.75 8286 -284 8582 -284.25 8334 -284.5 8305 -284.75 8220 -285 8313 -285.25 8211 -285.5 8302 -285.75 8226 -286 8234 -286.25 8471 -286.5 8205 -286.75 8313 -287 8258 -287.25 8237 -287.5 8234 -287.75 8210 -288 8104 -288.25 8203 -288.5 8269 -288.75 8138 -289 8030 -289.25 8063 -289.5 8104 -289.75 8119 -290 7874 -290.25 7970 -290.5 8081 -290.75 8068 -291 8115 -291.25 7943 -291.5 7911 -291.75 7808 -292 7876 -292.25 7947 -292.5 7832 -292.75 8024 -293 7867 -293.25 7657 -293.5 7798 -293.75 7739 -294 7745 -294.25 7622 -294.5 7718 -294.75 7922 -295 7810 -295.25 7709 -295.5 7784 -295.75 7745 -296 7644 -296.25 7642 -296.5 7512 -296.75 7609 -297 7791 -297.25 7664 -297.5 7414 -297.75 7515 -298 7596 -298.25 7627 -298.5 7578 -298.75 7628 -299 7569 -299.25 7374 -299.5 7429 -299.75 7468 -300 7370 -300.25 7448 -300.5 7331 -300.75 7592 -301 7374 -301.25 7214 -301.5 7484 -301.75 7449 -302 7282 -302.25 7230 -302.5 7328 -302.75 7071 -303 7348 -303.25 7135 -303.5 7224 -303.75 7300 -304 7399 -304.25 7224 -304.5 7244 -304.75 7208 -305 7085 -305.25 7036 -305.5 7257 -305.75 7153 -306 6989 -306.25 6795 -306.5 7012 -306.75 6993 -307 7047 -307.25 7085 -307.5 6900 -307.75 6823 -308 6737 -308.25 6897 -308.5 6852 -308.75 7083 -309 6903 -309.25 6895 -309.5 6826 -309.75 6820 -310 6811 -310.25 6907 -310.5 6804 -310.75 6522 -311 6559 -311.25 6618 -311.5 6688 -311.75 6701 -312 6632 -312.25 6548 -312.5 6667 -312.75 6580 -313 6519 -313.25 6607 -313.5 6338 -313.75 6559 -314 6529 -314.25 6385 -314.5 6425 -314.75 6346 -315 6458 -315.25 6318 -315.5 6260 -315.75 6212 -316 6277 -316.25 6176 -316.5 6219 -316.75 6363 -317 6160 -317.25 6304 -317.5 6070 -317.75 6201 -318 6177 -318.25 6108 -318.5 6033 -318.75 5911 -319 5864 -319.25 5951 -319.5 5995 -319.75 5901 -320 6010 -320.25 5815 -320.5 5753 -320.75 5996 -321 5886 -321.25 5830 -321.5 5816 -321.75 5627 -322 5870 -322.25 5621 -322.5 5559 -322.75 5697 -323 5679 -323.25 5544 -323.5 5478 -323.75 5637 -324 5690 -324.25 5486 -324.5 5325 -324.75 5452 -325 5328 -325.25 5432 -325.5 5564 -325.75 5209 -326 5194 -326.25 5150 -326.5 5252 -326.75 5311 -327 5056 -327.25 5097 -327.5 5312 -327.75 5208 -328 5030 -328.25 4895 -328.5 5167 -328.75 5078 -329 4928 -329.25 5029 -329.5 4921 -329.75 4866 -330 4851 -330.25 4971 -330.5 4965 -330.75 4756 -331 4830 -331.25 4924 -331.5 4578 -331.75 4746 -332 4801 -332.25 4654 -332.5 4736 -332.75 4795 -333 4822 -333.25 4698 -333.5 4701 -333.75 4652 -334 4351 -334.25 4609 -334.5 4523 -334.75 4423 -335 4573 -335.25 4883 -335.5 4723 -335.75 4337 -336 4560 -336.25 4593 -336.5 4807 -336.75 4531 -337 4442 -337.25 4470 -337.5 4425 -337.75 4531 -338 4267 -338.25 4399 -338.5 4248 -338.75 4383 -339 4350 -339.25 4346 -339.5 4390 -339.75 4632 -340 4394 -340.25 4330 -340.5 4231 -340.75 4441 -341 4371 -341.25 4360 -341.5 4383 -341.75 4538 -342 4197 -342.25 4176 -342.5 4356 -342.75 4335 -343 4234 -343.25 4170 -343.5 4184 -343.75 4384 -344 4472 -344.25 4256 -344.5 4466 -344.75 4355 -345 4351 -345.25 4556 -345.5 4298 -345.75 4225 -346 4508 -346.25 4502 -346.5 4557 -346.75 4384 -347 4371 -347.25 4533 -347.5 4385 -347.75 4628 -348 4396 -348.25 4668 -348.5 4687 -348.75 4254 -349 4565 -349.25 4804 -349.5 4687 -349.75 4724 -350 4639 -350.25 4570 -350.5 4544 -350.75 4738 -351 4801 -351.25 4728 -351.5 4914 -351.75 4843 -352 4826 -352.25 4962 -352.5 5069 -352.75 4863 -353 4951 -353.25 5046 -353.5 5156 -353.75 5211 -354 5139 -354.25 4968 -354.5 5138 -354.75 5196 -355 5241 -355.25 5325 -355.5 5324 -355.75 5280 -356 5180 -356.25 5445 -356.5 5225 -356.75 5468 -357 5401 -357.25 5586 -357.5 5684 -357.75 5657 -358 5600 -358.25 5847 -358.5 5801 -358.75 5667 -359 5802 -359.25 5822 -359.5 5899 -359.75 6019 -360 5936 -360.25 5993 -360.5 6071 -360.75 6071 -361 6135 -361.25 6222 -361.5 6196 -361.75 6219 -362 6386 -362.25 6342 -362.5 6462 -362.75 6449 -363 6670 -363.25 6545 -363.5 6722 -363.75 6663 -364 6678 -364.25 6709 -364.5 6865 -364.75 6765 -365 6972 -365.25 6997 -365.5 6991 -365.75 7078 -366 7225 -366.25 7159 -366.5 7295 -366.75 7440 -367 7392 -367.25 7443 -367.5 7485 -367.75 7604 -368 7718 -368.25 7726 -368.5 7732 -368.75 7787 -369 8029 -369.25 7979 -369.5 8120 -369.75 8211 -370 8189 -370.25 8371 -370.5 8318 -370.75 8419 -371 8399 -371.25 8576 -371.5 8579 -371.75 8714 -372 8934 -372.25 8884 -372.5 8952 -372.75 8892 -373 9054 -373.25 9118 -373.5 9234 -373.75 9307 -374 9389 -374.25 9520 -374.5 9382 -374.75 9615 -375 9685 -375.25 9807 -375.5 9809 -375.75 10012 -376 9949 -376.25 10165 -376.5 10160 -376.75 10361 -377 10418 -377.25 10527 -377.5 10587 -377.75 10720 -378 10795 -378.25 10832 -378.5 10931 -378.75 11099 -379 11352 -379.25 11250 -379.5 11380 -379.75 11488 -380 11551 -380.25 11693 -380.5 11781 -380.75 12018 -381 12026 -381.25 12158 -381.5 12153 -381.75 12321 -382 12376 -382.25 12542 -382.5 12561 -382.75 12914 -383 12831 -383.25 13004 -383.5 13033 -383.75 13120 -384 13339 -384.25 13526 -384.5 13534 -384.75 13639 -385 13778 -385.25 13924 -385.5 14011 -385.75 14125 -386 14245 -386.25 14357 -386.5 14611 -386.75 14578 -387 14794 -387.25 14943 -387.5 15004 -387.75 15132 -388 15217 -388.25 15346 -388.5 15625 -388.75 15701 -389 15763 -389.25 15872 -389.5 16082 -389.75 16198 -390 16334 -390.25 16618 -390.5 16750 -390.75 16922 -391 16897 -391.25 17153 -391.5 17363 -391.75 17306 -392 17508 -392.25 17645 -392.5 17947 -392.75 18077 -393 18306 -393.25 18360 -393.5 18564 -393.75 18681 -394 18947 -394.25 19077 -394.5 19257 -394.75 19386 -395 19603 -395.25 19819 -395.5 19840 -395.75 20018 -396 20306 -396.25 20537 -396.5 20696 -396.75 20890 -397 21025 -397.25 21099 -397.5 21508 -397.75 21590 -398 21695 -398.25 22046 -398.5 22099 -398.75 22208 -399 22456 -399.25 22739 -399.5 22910 -399.75 23068 -400 23223 -400.25 23332 -400.5 23529 -400.75 23716 -401 23938 -401.25 24060 -401.5 24153 -401.75 24483 -402 24617 -402.25 24823 -402.5 24967 -402.75 25185 -403 25435 -403.25 25604 -403.5 25578 -403.75 25931 -404 26126 -404.25 26394 -404.5 26468 -404.75 26635 -405 26737 -405.25 27056 -405.5 27230 -405.75 27451 -406 27857 -406.25 27866 -406.5 28176 -406.75 28139 -407 28467 -407.25 28640 -407.5 28746 -407.75 29143 -408 29168 -408.25 29527 -408.5 29637 -408.75 29858 -409 30049 -409.25 30302 -409.5 30569 -409.75 30645 -410 30831 -410.25 30924 -410.5 31204 -410.75 31548 -411 31698 -411.25 31887 -411.5 32216 -411.75 32411 -412 32610 -412.25 32535 -412.5 32945 -412.75 32846 -413 33200 -413.25 33433 -413.5 33480 -413.75 33777 -414 34095 -414.25 34190 -414.5 34531 -414.75 34834 -415 34903 -415.25 35085 -415.5 35414 -415.75 35564 -416 35706 -416.25 35778 -416.5 36112 -416.75 36431 -417 36596 -417.25 36893 -417.5 37139 -417.75 37287 -418 37558 -418.25 37587 -418.5 37957 -418.75 38212 -419 38475 -419.25 38640 -419.5 38902 -419.75 39044 -420 39293 -420.25 39645 -420.5 39675 -420.75 39886 -421 40236 -421.25 40299 -421.5 40898 -421.75 40977 -422 41146 -422.25 41209 -422.5 41438 -422.75 41659 -423 42024 -423.25 41937 -423.5 42254 -423.75 42509 -424 42569 -424.25 42830 -424.5 43004 -424.75 43220 -425 43491 -425.25 43775 -425.5 43958 -425.75 44066 -426 44106 -426.25 44366 -426.5 44656 -426.75 44818 -427 44920 -427.25 45175 -427.5 45289 -427.75 45205 -428 45653 -428.25 45663 -428.5 46031 -428.75 45880 -429 46284 -429.25 46275 -429.5 46321 -429.75 46875 -430 46801 -430.25 47034 -430.5 47183 -430.75 47159 -431 47497 -431.25 47738 -431.5 47623 -431.75 47944 -432 48068 -432.25 48045 -432.5 48481 -432.75 48552 -433 48455 -433.25 48794 -433.5 48981 -433.75 48824 -434 49361 -434.25 49335 -434.5 49562 -434.75 49363 -435 49796 -435.25 49830 -435.5 50195 -435.75 50058 -436 50080 -436.25 50471 -436.5 50242 -436.75 50212 -437 50999 -437.25 50705 -437.5 50718 -437.75 51066 -438 51272 -438.25 51313 -438.5 51585 -438.75 51472 -439 51653 -439.25 51846 -439.5 51777 -439.75 51924 -440 52109 -440.25 52208 -440.5 52280 -440.75 52293 -441 52356 -441.25 52457 -441.5 52557 -441.75 52914 -442 53001 -442.25 52673 -442.5 52891 -442.75 52803 -443 53133 -443.25 52993 -443.5 53312 -443.75 53499 -444 53570 -444.25 53376 -444.5 53727 -444.75 53590 -445 53466 -445.25 53330 -445.5 53550 -445.75 53855 -446 53945 -446.25 54100 -446.5 53803 -446.75 54042 -447 53727 -447.25 54205 -447.5 54320 -447.75 54323 -448 54336 -448.25 54364 -448.5 54198 -448.75 54445 -449 54593 -449.25 54669 -449.5 54570 -449.75 54814 -450 54889 -450.25 55016 -450.5 54631 -450.75 55023 -451 54904 -451.25 55003 -451.5 54709 -451.75 54692 -452 54913 -452.25 54882 -452.5 54780 -452.75 54816 -453 54985 -453.25 54709 -453.5 54940 -453.75 54965 -454 54944 -454.25 54897 -454.5 54881 -454.75 54860 -455 54838 -455.25 54970 -455.5 54914 -455.75 54792 -456 54852 -456.25 54810 -456.5 54653 -456.75 54691 -457 54697 -457.25 54499 -457.5 54411 -457.75 54379 -458 54456 -458.25 54476 -458.5 54507 -458.75 54318 -459 54179 -459.25 54368 -459.5 53982 -459.75 53776 -460 53869 -460.25 53863 -460.5 53765 -460.75 53687 -461 53612 -461.25 53421 -461.5 53163 -461.75 53220 -462 53073 -462.25 52805 -462.5 52643 -462.75 52655 -463 52297 -463.25 52346 -463.5 52125 -463.75 52124 -464 51893 -464.25 51713 -464.5 51601 -464.75 51196 -465 51182 -465.25 50770 -465.5 50676 -465.75 50469 -466 50213 -466.25 50146 -466.5 49932 -466.75 49547 -467 49358 -467.25 49033 -467.5 48863 -467.75 48688 -468 48330 -468.25 48011 -468.5 47847 -468.75 47529 -469 47213 -469.25 47164 -469.5 46779 -469.75 46505 -470 46188 -470.25 45749 -470.5 45325 -470.75 45059 -471 44709 -471.25 44313 -471.5 44104 -471.75 43981 -472 43437 -472.25 43051 -472.5 42721 -472.75 42370 -473 41989 -473.25 41733 -473.5 41243 -473.75 40789 -474 40495 -474.25 39942 -474.5 39694 -474.75 39259 -475 38765 -475.25 38218 -475.5 37894 -475.75 37467 -476 36981 -476.25 36510 -476.5 36003 -476.75 35534 -477 35156 -477.25 34646 -477.5 34092 -477.75 33757 -478 33338 -478.25 32856 -478.5 32487 -478.75 31972 -479 31378 -479.25 30972 -479.5 30621 -479.75 30125 -480 29636 -480.25 29219 -480.5 28809 -480.75 28426 -481 27950 -481.25 27596 -481.5 27063 -481.75 26732 -482 26271 -482.25 25872 -482.5 25391 -482.75 24929 -483 24544 -483.25 24180 -483.5 23794 -483.75 23353 -484 22833 -484.25 22532 -484.5 22123 -484.75 21593 -485 21333 -485.25 20952 -485.5 20411 -485.75 20085 -486 19771 -486.25 19386 -486.5 18940 -486.75 18564 -487 18211 -487.25 17827 -487.5 17433 -487.75 17152 -488 16794 -488.25 16455 -488.5 16035 -488.75 15691 -489 15367 -489.25 14995 -489.5 14678 -489.75 14362 -490 14025 -490.25 13750 -490.5 13415 -490.75 13103 -491 12797 -491.25 12457 -491.5 12191 -491.75 11964 -492 11835 -492.25 11548 -492.5 11298 -492.75 11013 -493 10718 -493.25 10489 -493.5 10199 -493.75 9944 -494 9634 -494.25 9399 -494.5 9098 -494.75 8913 -495 8611 -495.25 8326 -495.5 8195 -495.75 7887 -496 7707 -496.25 7520 -496.5 7320 -496.75 7033 -497 6821 -497.25 6602 -497.5 6485 -497.75 6171 -498 6090 -498.25 5889 -498.5 5721 -498.75 5508 -499 5400 -499.25 5182 -499.5 5068 -499.75 4893 -500 4767 -500.25 4534 -500.5 4461 -500.75 4285 -501 4204 -501.25 4053 -501.5 3875 -501.75 3753 -502 3654 -502.25 3487 -502.5 3412 -502.75 3333 -503 3151 -503.25 3151 -503.5 3037 -503.75 2899 -504 2794 -504.25 2746 -504.5 2654 -504.75 2530 -505 2503 -505.25 2359 -505.5 2327 -505.75 2211 -506 2144 -506.25 2030 -506.5 2033 -506.75 2005 -507 1863 -507.25 1858 -507.5 1718 -507.75 1776 -508 1702 -508.25 1587 -508.5 1611 -508.75 1561 -509 1466 -509.25 1385 -509.5 1383 -509.75 1374 -510 1299 -510.25 1314 -510.5 1200 -510.75 1148 -511 1116 -511.25 1032 -511.5 1108 -511.75 995 -512 966 -512.25 941 -512.5 920 -512.75 908 -513 846 -513.25 848 -513.5 846 -513.75 737 -514 782 -514.25 724 -514.5 716 -514.75 704 -515 624 -515.25 616 -515.5 574 -515.75 602 -516 582 -516.25 547 -516.5 506 -516.75 525 -517 485 -517.25 488 -517.5 487 -517.75 431 -518 396 -518.25 411 -518.5 418 -518.75 365 -519 401 -519.25 361 -519.5 375 -519.75 346 -520 340 -520.25 326 -520.5 357 -520.75 292 -521 306 -521.25 270 -521.5 273 -521.75 251 -522 212 -522.25 253 -522.5 285 -522.75 233 -523 251 -523.25 247 -523.5 236 -523.75 235 -524 214 -524.25 188 -524.5 212 -524.75 201 -525 214 -525.25 169 -525.5 136 -525.75 182 -526 222 -526.25 147 -526.5 164 -526.75 133 -527 191 -527.25 176 -527.5 141 -527.75 156 -528 208 -528.25 179 -528.5 117 -528.75 116 -529 152 -529.25 121 -529.5 153 -529.75 178 -530 129 -530.25 102 -530.5 163 -530.75 118 -531 130 -531.25 82 -531.5 83 -531.75 99 -532 126 -532.25 153 -532.5 70 -532.75 109 -533 101 -533.25 72 -533.5 72 -533.75 114 -534 68 -534.25 71 -534.5 90 -534.75 177 -535 107 -535.25 107 -535.5 80 -535.75 92 -536 121 -536.25 37 -536.5 15 -536.75 54 -537 120 -537.25 104 -537.5 59 -537.75 40 -538 81 -538.25 126 -538.5 102 -538.75 80 -539 66 -539.25 65 -539.5 32 -539.75 83 -540 66 -540.25 64 -540.5 92 -540.75 84 -541 58 -541.25 72 -541.5 14 -541.75 78 -542 9 -542.25 71 -542.5 40 -542.75 118 -543 57 -543.25 100 -543.5 89 -543.75 64 -544 61 -544.25 86 -544.5 68 -544.75 76 -545 46 -545.25 85 -545.5 71 -545.75 61 -546 31 -546.25 68 -546.5 84 -546.75 68 -547 45 -547.25 94 -547.5 125 -547.75 33 -548 104 -548.25 70 -548.5 59 -548.75 33 -549 21 -549.25 1 -549.5 55 -549.75 41 -550 61 -550.25 75 -550.5 71 -550.75 81 -551 34 -551.25 63 -551.5 68 -551.75 56 -552 27 -552.25 61 -552.5 69 -552.75 45 -553 71 -553.25 90 -553.5 55 -553.75 105 -554 20 -554.25 47 -554.5 21 -554.75 10 -555 57 -555.25 77 -555.5 20 -555.75 56 -556 60 -556.25 105 -556.5 15 -556.75 8 -557 -8 -557.25 69 -557.5 18 -557.75 47 -558 6 -558.25 42 -558.5 27 -558.75 39 -559 12 -559.25 20 -559.5 41 -559.75 9 -560 52 -560.25 67 -560.5 39 -560.75 72 -561 40 -561.25 52 -561.5 73 -561.75 39 -562 -4 -562.25 72 -562.5 64 -562.75 52 -563 109 -563.25 12 -563.5 49 -563.75 -25 -564 9 -564.25 35 -564.5 59 -564.75 78 -565 15 -565.25 27 -565.5 52 -565.75 98 -566 10 -566.25 -3 -566.5 40 -566.75 -2 -567 16 -567.25 64 -567.5 82 -567.75 19 -568 28 -568.25 37 -568.5 6 -568.75 64 -569 35 -569.25 19 -569.5 18 -569.75 -33 -570 45 -570.25 -6 -570.5 19 -570.75 12 -571 9 -571.25 -6 -571.5 -1 -571.75 3 -572 47 -572.25 39 -572.5 16 -572.75 33 -573 10 -573.25 32 -573.5 18 -573.75 29 -574 68 -574.25 52 -574.5 9 -574.75 21 -575 34 -575.25 24 -575.5 7 -575.75 -63 -576 24 -576.25 32 -576.5 54 -576.75 19 -577 13 -577.25 11 -577.5 59 -577.75 31 -578 78 -578.25 -16 -578.5 39 -578.75 -12 -579 13 -579.25 21 -579.5 77 -579.75 25 -580 2 -580.25 -3 -580.5 -6 -580.75 0 -581 24 -581.25 -27 -581.5 29 -581.75 -11 -582 17 -582.25 -18 -582.5 -10 -582.75 51 -583 27 -583.25 -5 -583.5 17 -583.75 -66 -584 0 -584.25 19 -584.5 21 -584.75 20 -585 -21 -585.25 -8 -585.5 49 -585.75 -12 -586 4 -586.25 60 -586.5 29 -586.75 16 -587 54 -587.25 -10 -587.5 15 -587.75 -22 -588 -39 -588.25 15 -588.5 46 -588.75 29 -589 -31 -589.25 44 -589.5 -37 -589.75 12 -590 56 -590.25 51 -590.5 44 -590.75 22 -591 46 -591.25 -2 -591.5 59 -591.75 27 -592 77 -592.25 38 -592.5 74 -592.75 56 -593 -8 -593.25 0 -593.5 25 -593.75 54 -594 18 -594.25 110 -594.5 17 -594.75 -16 -595 10 -595.25 -71 -595.5 -25 -595.75 57 -596 5 -596.25 -29 -596.5 52 -596.75 37 -597 30 -597.25 24 -597.5 85 -597.75 28 -598 36 -598.25 2 -598.5 -48 -598.75 67 -599 -31 -599.25 8 -599.5 56 -599.75 71 -600 58 -600.25 40 -600.5 -8 -600.75 5 -601 17 -601.25 8 -601.5 73 -601.75 91 -602 42 -602.25 2 -602.5 64 -602.75 -16 -603 22 -603.25 55 -603.5 -33 -603.75 6 -604 -2 -604.25 -12 -604.5 71 -604.75 24 -605 53 -605.25 8 -605.5 28 -605.75 37 -606 29 -606.25 -16 -606.5 59 -606.75 11 -607 37 -607.25 8 -607.5 -6 -607.75 -12 -608 25 -608.25 69 -608.5 78 -608.75 64 -609 18 -609.25 7 -609.5 37 -609.75 81 -610 54 -610.25 2 -610.5 29 -610.75 2 -611 -1 -611.25 21 -611.5 48 -611.75 -5 -612 32 -612.25 2 -612.5 39 -612.75 12 -613 12 -613.25 -9 -613.5 50 -613.75 6 -614 0 -614.25 79 -614.5 19 -614.75 20 -615 85 -615.25 -10 -615.5 29 -615.75 36 -616 84 -616.25 31 -616.5 14 -616.75 4 -617 84 -617.25 -14 -617.5 46 -617.75 24 -618 -3 -618.25 -3 -618.5 0 -618.75 -23 -619 -20 -619.25 69 -619.5 30 -619.75 24 -620 -2 -620.25 89 -620.5 -31 -620.75 3 -621 62 -621.25 27 -621.5 29 -621.75 46 -622 54 -622.25 -19 -622.5 48 -622.75 4 -623 51 -623.25 -26 -623.5 69 -623.75 -97 -624 64 -624.25 -31 -624.5 78 -624.75 -17 -625 28 -625.25 -42 -625.5 77 -625.75 57 -626 15 -626.25 40 -626.5 -65 -626.75 -14 -627 77 -627.25 -7 -627.5 36 -627.75 2 -628 15 -628.25 -23 -628.5 13 -628.75 14 -629 47 -629.25 -70 -629.5 -54 -629.75 33 -630 28 -630.25 42 -630.5 -13 -630.75 -13 -631 29 -631.25 51 -631.5 59 -631.75 44 -632 -29 -632.25 51 -632.5 26 -632.75 71 -633 54 -633.25 60 -633.5 29 -633.75 90 -634 0 -634.25 11 -634.5 15 -634.75 13 -635 32 -635.25 75 -635.5 78 -635.75 -24 -636 13 -636.25 47 -636.5 -18 -636.75 -10 -637 0 -637.25 0 -637.5 29 -637.75 32 -638 -9 -638.25 -19 -638.5 5 -638.75 61 -639 36 -639.25 11 -639.5 27 -639.75 56 -640 4 -640.25 43 -640.5 15 -640.75 -59 -641 -19 -641.25 76 -641.5 32 -641.75 -21 -642 -35 -642.25 39 -642.5 20 -642.75 39 -643 -22 -643.25 -29 -643.5 -12 -643.75 17 -644 -3 -644.25 32 -644.5 54 -644.75 -25 -645 -26 -645.25 11 -645.5 91 -645.75 -3 -646 -24 -646.25 -56 -646.5 -49 -646.75 -47 -647 93 -647.25 36 -647.5 0 -647.75 86 -648 34 -648.25 34 -648.5 -23 -648.75 25 -649 -25 -649.25 -49 -649.5 -35 -649.75 78 -650 86 -650.25 -25 -650.5 -16 -650.75 77 -651 -16 -651.25 35 -651.5 3 -651.75 -19 -652 8 -652.25 19 -652.5 -30 -652.75 -23 -653 5 -653.25 23 -653.5 79 -653.75 6 -654 -46 -654.25 -15 -654.5 -17 -654.75 60 -655 78 -655.25 -25 -655.5 51 -655.75 -48 -656 53 -656.25 93 -656.5 54 -656.75 -45 -657 14 -657.25 98 -657.5 -2 -657.75 42 -658 -13 -658.25 52 -658.5 59 -658.75 74 -659 -3 -659.25 54 -659.5 60 -659.75 -27 -660 30 -660.25 25 -660.5 -6 -660.75 8 -661 24 -661.25 67 -661.5 5 -661.75 46 -662 24 -662.25 -33 -662.5 26 -662.75 106 -663 -18 -663.25 62 -663.5 37 -663.75 81 -664 37 -664.25 104 -664.5 17 -664.75 110 -665 -21 -665.25 74 -665.5 51 -665.75 35 -666 -78 -666.25 49 -666.5 43 -666.75 42 -667 55 -667.25 65 -667.5 48 -667.75 -49 -668 48 -668.25 86 -668.5 68 -668.75 2 -669 31 -669.25 -21 -669.5 16 -669.75 26 -670 87 -670.25 181 -670.5 87 -670.75 44 -671 107 -671.25 43 -671.5 88 -671.75 28 -672 13 -672.25 73 -672.5 7 -672.75 76 -673 44 -673.25 80 -673.5 14 -673.75 12 -674 32 -674.25 11 -674.5 5 -674.75 -23 -675 -18 -675.25 12 -675.5 -56 -675.75 -7 -676 47 -676.25 33 -676.5 0 -676.75 58 -677 158 -677.25 46 -677.5 64 -677.75 17 -678 30 -678.25 -80 -678.5 21 -678.75 -21 -679 -1 -679.25 5 -679.5 86 -679.75 36 -680 -20 -680.25 -34 -680.5 53 -680.75 6 -681 21 -681.25 41 -681.5 59 -681.75 39 -682 51 -682.25 8 -682.5 46 -682.75 43 -683 11 -683.25 11 -683.5 -19 -683.75 8 -684 15 -684.25 -16 -684.5 33 -684.75 32 -685 -36 -685.25 32 -685.5 11 -685.75 25 -686 49 -686.25 -53 -686.5 0 -686.75 -11 -687 -6 -687.25 -22 -687.5 8 -687.75 -18 -688 45 -688.25 -41 -688.5 17 -688.75 11 -689 32 -689.25 -40 -689.5 54 -689.75 34 -690 35 -690.25 50 -690.5 19 -690.75 -58 -691 -59 -691.25 70 -691.5 -55 -691.75 8 -692 21 -692.25 8 -692.5 40 -692.75 -27 -693 -41 -693.25 11 -693.5 21 -693.75 -24 -694 48 -694.25 13 -694.5 24 -694.75 -16 -695 -9 -695.25 0 -695.5 3 -695.75 16 -696 -3 -696.25 70 -696.5 31 -696.75 -48 -697 -6 -697.25 52 -697.5 12 -697.75 44 -698 50 -698.25 -7 -698.5 4 -698.75 -4 -699 8 -699.25 35 -699.5 -61 -699.75 -32 -700 103 diff --git a/Modules/Biophotonics/python/iMC/mc/data/colon_default.mci b/Modules/Biophotonics/python/iMC/mc/data/colon_default.mci deleted file mode 100644 index 9017b775cb..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/data/colon_default.mci +++ /dev/null @@ -1,14 +0,0 @@ -1.0 # file version -1 # number of runs - -temp.mco A # output filename, ASCII/Binary -1000000 # No. of photons -0.002 2 # dz, dr -500 1 1 # No. of dz, dr & da. - -2 # No. of layers -# n mua mus g d # One line for each layer -1.0 # n for medium above. -1.380 1.78741 20.00000 0.000 0.050 -1.380 1.78741 20.00000 0.000 0.050 -1.0 # n for medium below. diff --git a/Modules/Biophotonics/python/iMC/mc/data/correct.mci b/Modules/Biophotonics/python/iMC/mc/data/correct.mci deleted file mode 100644 index 3548fe2f84..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/data/correct.mci +++ /dev/null @@ -1,15 +0,0 @@ -1.0 # file version -1 # number of runs - -temp.mco A # output filename, ASCII/Binary -1000000 # No. of photons -0.002 2 # dz, dr -500 1 1 # No. of dz, dr & da. - -3 # No. of layers -# n mua mus g d # One line for each layer -1.0 # n for medium above. -1.000 0.02100 0.03200 4.300 540.000 -1.000 0.01000 0.01000 1.000 100.000 -100.100 1.01100 1.02100 103.100 10410.000 -1.0 # n for medium below. diff --git a/Modules/Biophotonics/python/iMC/mc/data/haemoglobin.txt b/Modules/Biophotonics/python/iMC/mc/data/haemoglobin.txt deleted file mode 100644 index b5e87f7035..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/data/haemoglobin.txt +++ /dev/null @@ -1,378 +0,0 @@ -lambda Hb02 Hb -nm cm-1/M cm-1/M -250 106112 112736 -252 105552 112736 -254 107660 112736 -256 109788 113824 -258 112944 115040 -260 116376 116296 -262 120188 117564 -264 124412 118876 -266 128696 120208 -268 133064 121544 -270 136068 122880 -272 137232 123096 -274 138408 121952 -276 137424 120808 -278 135820 119840 -280 131936 118872 -282 127720 117628 -284 122280 114820 -286 116508 112008 -288 108484 107140 -290 104752 98364 -292 98936 91636 -294 88136 85820 -296 79316 77100 -298 70884 69444 -300 65972 64440 -302 63208 61300 -304 61952 58828 -306 62352 56908 -308 62856 57620 -310 63352 59156 -312 65972 62248 -314 69016 65344 -316 72404 68312 -318 75536 71208 -320 78752 74508 -322 82256 78284 -324 85972 82060 -326 89796 85592 -328 93768 88516 -330 97512 90856 -332 100964 93192 -334 103504 95532 -336 104968 99792 -338 106452 104476 -340 107884 108472 -342 109060 110996 -344 110092 113524 -346 109032 116052 -348 107984 118752 -350 106576 122092 -352 105040 125436 -354 103696 128776 -356 101568 132120 -358 97828 133632 -360 94744 134940 -362 92248 136044 -364 89836 136972 -366 88484 137900 -368 87512 138856 -370 88176 139968 -372 91592 141084 -374 95140 142196 -376 98936 143312 -378 103432 144424 -380 109564 145232 -382 116968 145232 -384 125420 148668 -386 135132 153908 -388 148100 159544 -390 167748 167780 -392 189740 180004 -394 212060 191540 -396 231612 202124 -398 248404 212712 -400 266232 223296 -402 284224 236188 -404 308716 253368 -406 354208 270548 -408 422320 287356 -410 466840 303956 -412 500200 321344 -414 524280 342596 -416 521880 363848 -418 515520 385680 -420 480360 407560 -422 431880 429880 -424 376236 461200 -426 326032 481840 -428 283112 500840 -430 246072 528600 -432 214120 552160 -434 165332 552160 -436 132820 547040 -438 119140 501560 -440 102580 413280 -442 92780 363240 -444 81444 282724 -446 76324 237224 -448 67044 173320 -450 62816 103292 -452 58864 62640 -454 53552 36170 -456 49496 30698.8 -458 47496 25886.4 -460 44480 23388.8 -462 41320 20891.2 -464 39807.2 19260.8 -466 37073.2 18142.4 -468 34870.8 17025.6 -470 33209.2 16156.4 -472 31620 15310 -474 30113.6 15048.4 -476 28850.8 14792.8 -478 27718 14657.2 -480 26629.2 14550 -482 25701.6 14881.2 -484 25180.4 15212.4 -486 24669.6 15543.6 -488 24174.8 15898 -490 23684.4 16684 -492 23086.8 17469.6 -494 22457.6 18255.6 -496 21850.4 19041.2 -498 21260 19891.2 -500 20932.8 20862 -502 20596.4 21832.8 -504 20418 22803.6 -506 19946 23774.4 -508 19996 24745.2 -510 20035.2 25773.6 -512 20150.4 26936.8 -514 20429.2 28100 -516 21001.6 29263.2 -518 22509.6 30426.4 -520 24202.4 31589.6 -522 26450.4 32851.2 -524 29269.2 34397.6 -526 32496.4 35944 -528 35990 37490 -530 39956.8 39036.4 -532 43876 40584 -534 46924 42088 -536 49752 43592 -538 51712 45092 -540 53236 46592 -542 53292 48148 -544 52096 49708 -546 49868 51268 -548 46660 52496 -550 43016 53412 -552 39675.2 54080 -554 36815.2 54520 -556 34476.8 54540 -558 33456 54164 -560 32613.2 53788 -562 32620 52276 -564 33915.6 50572 -566 36495.2 48828 -568 40172 46948 -570 44496 45072 -572 49172 43340 -574 53308 41716 -576 55540 40092 -578 54728 38467.6 -580 50104 37020 -582 43304 35676.4 -584 34639.6 34332.8 -586 26600.4 32851.6 -588 19763.2 31075.2 -590 14400.8 28324.4 -592 10468.4 25470 -594 7678.8 22574.8 -596 5683.6 19800 -598 4504.4 17058.4 -600 3200 14677.2 -602 2664 13622.4 -604 2128 12567.6 -606 1789.2 11513.2 -608 1647.6 10477.6 -610 1506 9443.6 -612 1364.4 8591.2 -614 1222.8 7762 -616 1110 7344.8 -618 1026 6927.2 -620 942 6509.6 -622 858 6193.2 -624 774 5906.8 -626 707.6 5620 -628 658.8 5366.8 -630 610 5148.8 -632 561.2 4930.8 -634 512.4 4730.8 -636 478.8 4602.4 -638 460.4 4473.6 -640 442 4345.2 -642 423.6 4216.8 -644 405.2 4088.4 -646 390.4 3965.08 -648 379.2 3857.6 -650 368 3750.12 -652 356.8 3642.64 -654 345.6 3535.16 -656 335.2 3427.68 -658 325.6 3320.2 -660 319.6 3226.56 -662 314 3140.28 -664 308.4 3053.96 -666 302.8 2967.68 -668 298 2881.4 -670 294 2795.12 -672 290 2708.84 -674 285.6 2627.64 -676 282 2554.4 -678 279.2 2481.16 -680 277.6 2407.92 -682 276 2334.68 -684 274.4 2261.48 -686 272.8 2188.24 -688 274.4 2115 -690 276 2051.96 -692 277.6 2000.48 -694 279.2 1949.04 -696 282 1897.56 -698 286 1846.08 -700 290 1794.28 -702 294 1741 -704 298 1687.76 -706 302.8 1634.48 -708 308.4 1583.52 -710 314 1540.48 -712 319.6 1497.4 -714 325.2 1454.36 -716 332 1411.32 -718 340 1368.28 -720 348 1325.88 -722 356 1285.16 -724 364 1244.44 -726 372.4 1203.68 -728 381.2 1152.8 -730 390 1102.2 -732 398.8 1102.2 -734 407.6 1102.2 -736 418.8 1101.76 -738 432.4 1100.48 -740 446 1115.88 -742 459.6 1161.64 -744 473.2 1207.4 -746 487.6 1266.04 -748 502.8 1333.24 -750 518 1405.24 -752 533.2 1515.32 -754 548.4 1541.76 -756 562 1560.48 -758 574 1560.48 -760 586 1548.52 -762 598 1508.44 -764 610 1459.56 -766 622.8 1410.52 -768 636.4 1361.32 -770 650 1311.88 -772 663.6 1262.44 -774 677.2 1213 -776 689.2 1163.56 -778 699.6 1114.8 -780 710 1075.44 -782 720.4 1036.08 -784 730.8 996.72 -786 740 957.36 -788 748 921.8 -790 756 890.8 -792 764 859.8 -794 772 828.8 -796 786.4 802.96 -798 807.2 782.36 -800 816 761.72 -802 828 743.84 -804 836 737.08 -806 844 730.28 -808 856 723.52 -810 864 717.08 -812 872 711.84 -814 880 706.6 -816 887.2 701.32 -818 901.6 696.08 -820 916 693.76 -822 930.4 693.6 -824 944.8 693.48 -826 956.4 693.32 -828 965.2 693.2 -830 974 693.04 -832 982.8 692.92 -834 991.6 692.76 -836 1001.2 692.64 -838 1011.6 692.48 -840 1022 692.36 -842 1032.4 692.2 -844 1042.8 691.96 -846 1050 691.76 -848 1054 691.52 -850 1058 691.32 -852 1062 691.08 -854 1066 690.88 -856 1072.8 690.64 -858 1082.4 692.44 -860 1092 694.32 -862 1101.6 696.2 -864 1111.2 698.04 -866 1118.4 699.92 -868 1123.2 701.8 -870 1128 705.84 -872 1132.8 709.96 -874 1137.6 714.08 -876 1142.8 718.2 -878 1148.4 722.32 -880 1154 726.44 -882 1159.6 729.84 -884 1165.2 733.2 -886 1170 736.6 -888 1174 739.96 -890 1178 743.6 -892 1182 747.24 -894 1186 750.88 -896 1190 754.52 -898 1194 758.16 -900 1198 761.84 -902 1202 765.04 -904 1206 767.44 -906 1209.2 769.8 -908 1211.6 772.16 -910 1214 774.56 -912 1216.4 776.92 -914 1218.8 778.4 -916 1220.8 778.04 -918 1222.4 777.72 -920 1224 777.36 -922 1225.6 777.04 -924 1227.2 776.64 -926 1226.8 772.36 -928 1224.4 768.08 -930 1222 763.84 -932 1219.6 752.28 -934 1217.2 737.56 -936 1215.6 722.88 -938 1214.8 708.16 -940 1214 693.44 -942 1213.2 678.72 -944 1212.4 660.52 -946 1210.4 641.08 -948 1207.2 621.64 -950 1204 602.24 -952 1200.8 583.4 -954 1197.6 568.92 -956 1194 554.48 -958 1190 540.04 -960 1186 525.56 -962 1182 511.12 -964 1178 495.36 -966 1173.2 473.32 -968 1167.6 451.32 -970 1162 429.32 -972 1156.4 415.28 -974 1150.8 402.28 -976 1144 389.288 -978 1136 374.944 -980 1128 359.656 -982 1120 344.372 -984 1112 329.084 -986 1102.4 313.796 -988 1091.2 298.508 -990 1080 283.22 -992 1068.8 267.932 -994 1057.6 252.648 -996 1046.4 237.36 -998 1035.2 222.072 -1000 1024 206.784 \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/mc/dfmanipulations.py b/Modules/Biophotonics/python/iMC/mc/dfmanipulations.py deleted file mode 100644 index 6bb2c76258..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/dfmanipulations.py +++ /dev/null @@ -1,45 +0,0 @@ -''' -Created on Oct 19, 2015 - -@author: wirkert -''' - -from scipy.interpolate import interp1d -import pandas as pd - - -def fold_by_sliding_average(df, window_size): - """take a batch and apply a sliding average with given window size to - the reflectances. - window_size is elements to the left and to the right. - There will be some boundary effect on the edges.""" - # next line does the folding. - df.reflectances = pd.rolling_mean(df.reflectances.T, window_size, - center=True).T - # let's get rid of NaN columns which are created at the boundaries - df.dropna(axis="columns", inplace=True) - return df - - -def switch_reflectances(df, new_wavelengths, new_reflectances): - df.drop(df["reflectances"].columns, axis=1, level=1, inplace=True) - for i, nw in enumerate(new_wavelengths): - df["reflectances", nw] = new_reflectances[:, i] - return df - - -def interpolate_wavelengths(df, new_wavelengths): - """ interpolate image data to fit new_wavelengths. Current implementation - performs simple linear interpolation. Neither existing nor new _wavelengths - need to be sorted. """ - # build an interpolator using the inormation provided by the dataframes - # reflectance column - interpolator = interp1d(df.reflectances.columns.astype(float), - df.reflectances.as_matrix(), assume_sorted=False, - bounds_error=False) - # use this to create new reflectances - new_reflectances = interpolator(new_wavelengths) - # build a new dataframe out of this information and set the original df - # to the new information. This seems hacky, can't it be done easier? - switch_reflectances(df, new_wavelengths, new_reflectances) - return df diff --git a/Modules/Biophotonics/python/iMC/mc/factories.py b/Modules/Biophotonics/python/iMC/mc/factories.py deleted file mode 100644 index dd6c317f9c..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/factories.py +++ /dev/null @@ -1,115 +0,0 @@ -''' -Created on Oct 15, 2015 - -@author: wirkert -''' - -from mc.tissuemodels import AbstractTissue, GenericTissue, PhantomTissue -from mc.batches import AbstractBatch -from mc.batches import GenericBatch, LessGenericBatch, GenericMeanScatteringBatch -from mc.batches import ColonMuscleBatch, ColonMuscleMeanScatteringBatch -from mc.batches import VisualizationBatch, IntralipidPhantomBatch - - -class AbstractMcFactory(object): - ''' - Monte Carlo Factory. - Will create fitting models and batches, dependent on your task - ''' - - def create_tissue_model(self): - return AbstractTissue() - - def create_batch_to_simulate(self): - return AbstractBatch() - - def __init__(self): - ''' - Constructor - ''' - - -class GenericMcFactory(AbstractMcFactory): - - def create_tissue_model(self): - return GenericTissue() - - def create_batch_to_simulate(self): - return GenericBatch() - - def __init__(self): - ''' - Constructor - ''' - - -class LessGenericMcFactory(GenericMcFactory): - - def create_batch_to_simulate(self): - return LessGenericBatch() - - def __init__(self): - ''' - Constructor - ''' - - -class ColonMuscleMcFactory(GenericMcFactory): - - def create_batch_to_simulate(self): - return ColonMuscleBatch() - - def __init__(self): - ''' - Constructor - ''' - - -class GenericMeanScatteringFactory(GenericMcFactory): - - def create_batch_to_simulate(self): - return GenericMeanScatteringBatch() - - def __init__(self): - ''' - Constructor - ''' - - -class ColonMuscleMeanScatteringFactory(GenericMcFactory): - - def create_batch_to_simulate(self): - return ColonMuscleMeanScatteringBatch() - - def __init__(self): - ''' - Constructor - ''' - - -class VisualizationMcFactory(AbstractMcFactory): - - def create_tissue_model(self): - return GenericTissue() - - def create_batch_to_simulate(self): - return VisualizationBatch() - - def __init__(self): - ''' - Constructor - ''' - - -class PhantomFactory(AbstractMcFactory): - - def create_tissue_model(self): - return PhantomTissue() - - def create_batch_to_simulate(self): - return IntralipidPhantomBatch() - - def __init__(self): - ''' - Constructor - ''' diff --git a/Modules/Biophotonics/python/iMC/mc/plot.py b/Modules/Biophotonics/python/iMC/mc/plot.py deleted file mode 100644 index 2706a15c2b..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/plot.py +++ /dev/null @@ -1,43 +0,0 @@ -''' -Created on Oct 16, 2015 - -@author: wirkert -''' - - -import numpy as np -import matplotlib.pyplot as plt - - -class PlotFunctor(object): - """helping functor necessary because we need to save color for plotting""" - - def __init__(self, axes, wavelengths, nr_plot_elements): - self.axes = axes - self.sortedIndices = sorted(range(len(wavelengths)), - key=lambda k: wavelengths[k]) - self.sortedWavelenghts = wavelengths[self.sortedIndices] - self.nr_plot_elements = nr_plot_elements - self.i = 0 - - - def __call__(self, r): - pass - # set color so it slowly moves from blue to red - plt_color = (1. / float(self.nr_plot_elements) * self.i, - 0., - 1. - (1. / float(self.nr_plot_elements) * self.i)) - self.axes.plot(self.sortedWavelenghts, r[self.sortedIndices], "-o", - color=plt_color) - self.i += 1 - return self.i - -def plot(batch, axes=None): - if axes is None: - axes = plt.gca() - - f = PlotFunctor(axes, batch._wavelengths, batch.reflectances.shape[0]) - - np.apply_along_axis(f, - axis=1, - arr=batch.reflectances) diff --git a/Modules/Biophotonics/python/iMC/mc/sim.py b/Modules/Biophotonics/python/iMC/mc/sim.py deleted file mode 100644 index f629a25d99..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/sim.py +++ /dev/null @@ -1,211 +0,0 @@ -''' -Created on Sep 8, 2015 - -This file contains methods which wrap the mcml simulation so it can be -conveniently called from python. One example for a mcml simulation would be -gpumcml: -https://code.google.com/p/gpumcml/ - -@author: wirkert -''' - -import os -import contextlib -import logging - -import subprocess32 - -""" helper method to change to the correct path and back again """ -@contextlib.contextmanager -def cd(newPath): - savedPath = os.getcwd() - os.chdir(newPath) - yield - os.chdir(savedPath) - - -class MciWrapper(object): - ''' - this class provides a wrapper to the mcml monte carlo file. - Its purpose is to create a .mci file which the mcml simulation can use to - create the simulation - ''' - - def set_mci_filename(self, mci_filename): - self.mci_filename = mci_filename - - def set_mco_filename(self, mco_filename): - """path of the mco file. - This can be either a path relative to the mcml executable - or an absolute path. - BUG: it seems that it can only be relative file name - """ - self.mco_filename = mco_filename - - def set_nr_photons(self, nr_photons): - self.nr_photons = nr_photons - - def add_layer(self, n=None, ua=None, us=None, g=None, d=None): - """adds a layer below the currently existing ones. - - Arguments: - n: Refraction index of medium - ua: absorption coefficient [1/m] - us: scattering coefficient [1/m] - g: anisotropy factor - d: thickness of layer [m] - """ - if n is None: - n = 1. - if ua is None: - ua = 0. - if us is None: - us = 0. - if g is None: - g = 1. - if d is None: - d = 500.*10 ** -6 - self.layers.append([n, ua, us, g, d]) - - def set_layer(self, layer_nr, n, ua, us, g, d): - """set a layer with a specific layer_nr (stariting with layer_nr 0). - Note that the layer must already exist, otherwise an error will occure - """ - self.layers[layer_nr] = [n, ua, us, g, d] - - def set_file_version(self, file_version): - self.file_version = file_version - - def set_nr_runs(self, nr_runs): - self.nr_runs = nr_runs - - def set_dz_dr(self, dz, dr): - self.dz = dz - self.dr = dr - - def set_nr_dz_dr_da(self, nr_dz, nr_dr, nr_da): - self.nr_dz = nr_dz - self.nr_dr = nr_dr - self.nr_da = nr_da - - def set_n_medium_above(self, n_above): - self.n_above = n_above - - def set_n_medium_below(self, n_below): - self.n_below = n_below - - def create_mci_file(self): - """this method creates the mci file at the location self.mci_filename""" - open(self.mci_filename, 'a').close() - f = open(self.mci_filename, 'w') - # write general information - f.write(str(self.file_version) + " # file version\n") - f.write(str(self.nr_runs) + " # number of runs\n\n") - # write the data for run - f.write(self.mco_filename + " A # output filename, ASCII/Binary\n") - f.write(str(self.nr_photons) + " # No. of photons\n") - f.write(repr(self.dz) + " " + repr(self.dr) + " # dz, dr\n") - f.write(repr(self.nr_dz) + " " + - repr(self.nr_dr) + " " + - repr(self.nr_da) + " # No. of dz, dr & da.\n\n") - # write layer information - f.write(str(len(self.layers)) + " # No. of layers\n") - f.write("# n mua mus g d # One line for each layer\n") - f.write(repr(self.n_above) + " # n for medium above.\n") - for layer in self.layers: - - # factors (/100.; *100.) to convert to mcml expected units: - f.write("%.3f" % layer[0] + " " + # n - "%.5f" % (layer[1] / 100.) + " " + # ua - "%.5f" % (layer[2] / 100.) + " " + # us - "%.3f" % layer[3] + " " + # g - "%.3f" % (layer[4] * 100.) + "\n") # d - f.write(repr(self.n_below) + " # n for medium below.\n") - f.close() - if not os.path.isfile(self.mci_filename): - raise IOError("input file for monte carlo simulation not " + - "succesfully created") - - def __init__(self): - # set standard parameters - self.file_version = 1.0 - self.nr_photons = 10**6 - self.nr_runs = 1 - self.dz = 0.002 - self.dr = 2 - self.nr_dz = 500 - self.nr_dr = 1 - self.nr_da = 1 - self.n_above = 1.0 - self.n_below = 1.0 - # initialize to 0 layers - self.layers = [] - - -class SimWrapper(object): - - def set_mci_filename(self, mci_filename): - """the full path to the input file. E.g. ./data/my.mci - """ - self.mci_filename = mci_filename - - def set_mcml_executable(self, mcml_executable): - """ the full path of the excutable. E.g. ./mcml/mcml.exe""" - self.mcml_executable = mcml_executable - - def run_simulation(self): - """this method runs a monte carlo simulation""" - mcml_path, mcml_file = os.path.split(self.mcml_executable) - abs_mci_filename = os.path.abspath(self.mci_filename) - # note: the -A option makes gpumcml much faster, but is not available - # in original mcml. Maybe a switch should be introduced here - args = ("./" + mcml_file, "-A", abs_mci_filename) - # switch to folder where mcml resides in and execute it. - with cd(mcml_path): - try: - popen = subprocess32.Popen(args, stdout=subprocess32.PIPE) - popen.wait(timeout=100) - except: - logging.error("couldn't run simulation") - # popen.kill() - - def __init__(self): - pass - - -def get_diffuse_reflectance(mco_filename): - """ - extract reflectance from mco file. - Attention: mco_filename specifies full path. - - Returns: the reflectance - """ - with open(mco_filename) as myFile: - for line in myFile: - if "Diffuse reflectance" in line: - return float(line.split(' ', 1)[0]) - - -def get_specular_reflectance(mco_filename): - """ - extract reflectance from mco file. - Attention: mco_filename specifies full path. - - Returns: the reflectance - """ - with open(mco_filename) as myFile: - for line in myFile: - if "Specular reflectance" in line: - return float(line.split(' ', 1)[0]) - - -def get_total_reflectance(mco_filename): - """ - extract reflectance from mco file. - Attention: mco_filename specifies full path. - - Returns: the reflectance - """ - return get_diffuse_reflectance(mco_filename) + \ - get_specular_reflectance(mco_filename) - diff --git a/Modules/Biophotonics/python/iMC/mc/test/__init__.py b/Modules/Biophotonics/python/iMC/mc/test/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/mc/test/test_dfmanipulations.py b/Modules/Biophotonics/python/iMC/mc/test/test_dfmanipulations.py deleted file mode 100644 index 7e62886813..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/test/test_dfmanipulations.py +++ /dev/null @@ -1,78 +0,0 @@ -''' -Created on Oct 19, 2015 - -@author: wirkert -''' -import unittest - -import numpy as np -from pandas.util.testing import assert_frame_equal - -from mc.batches import ColonMuscleBatch -import mc.dfmanipulations as dfmani - -class Test(unittest.TestCase): - - def setUp(self): - # create a colon batch with 2 samples - self.test_batch = ColonMuscleBatch() - self.test_batch.create_parameters(2) - - # artificially add 10 fake "reflectances" to this batch - # at 10 fake "wavelengths" - WAVELENGHTS = np.linspace(450, 720, 10) - reflectance1 = np.arange(0, 30, 3) - reflectance2 = np.arange(30, 60, 3) - for w in WAVELENGHTS: - self.test_batch.df["reflectances", w] = np.NAN - for r1, r2, w in zip(reflectance1, reflectance2, WAVELENGHTS): - self.test_batch.df["reflectances", w][0] = r1 - self.test_batch.df["reflectances", w][1] = r2 - - # shortcut to dataframe that we are interested in: - self.df = self.test_batch.df - - def test_sliding_average(self): - # by test design folding should not alter elements (only at boundaries, - # which are excluded by array slicing: - expected_elements = self.df.reflectances.iloc[:, 1:-1].copy() - dfmani.fold_by_sliding_average(self.df, 3) - - assert_frame_equal(self.df.reflectances, expected_elements) - - def test_interpolation(self): - new_wavelengths = [465, 615, 555] - - dfmani.interpolate_wavelengths(self.df, new_wavelengths) - - expected = np.array([[1.5, 16.5, 10.5], [31.5, 46.5, 40.5]]) - np.testing.assert_almost_equal(self.df.reflectances.as_matrix(), - expected, - err_msg="test if interpolation " + - "works fine on batches") - - def test_select_n(self): - """ this is less a test and more a showing of how to select n elements - from a dataframe.""" - # draw one sample. Look into documentation for sample to see all the - # options. Sample is quite powerfull. - self.df = self.df.sample(1) - self.assertEqual(self.df.shape[0], 1, - "one sample selected") - - def test_sortout_bands(self): - """ this is less a test and more a showing of how to sortout specific - bands from a dataframe """ - # drop the 510 and 720 nm band - band_names_to_sortout = [510, 720] - self.df.drop(band_names_to_sortout, axis=1, level=1, inplace=True) - - df_r = self.df["reflectances"] - self.assertTrue(not (510 in df_r.columns)) - self.assertTrue(not 720 in df_r.columns) - self.assertTrue(690 in df_r.columns) - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.testName'] - unittest.main() diff --git a/Modules/Biophotonics/python/iMC/mc/test/test_sim.py b/Modules/Biophotonics/python/iMC/mc/test/test_sim.py deleted file mode 100644 index 313341c081..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/test/test_sim.py +++ /dev/null @@ -1,125 +0,0 @@ -''' -Created on Sep 8, 2015 - -@author: wirkert -''' -import unittest -import filecmp -import os - -from mc.sim import MciWrapper, SimWrapper, \ - get_total_reflectance, get_diffuse_reflectance - - -path_to_gpumcml = "/home/wirkert/workspace/monteCarlo/gpumcml/" + \ - "fast-gpumcml/gpumcml.sm_20" -skip_gpu_tests = not os.path.exists(path_to_gpumcml) - - -class Test(unittest.TestCase): - - def setUp(self): - self.mci_filename = "temp.mci" - self.mco_filename = "temp.mco" - # create a mci_wrapper which shall create a mci file - self.mci_wrapper = MciWrapper() - self.mci_wrapper.set_mci_filename(self.mci_filename) - self.mci_wrapper.set_mco_filename(self.mco_filename) - self.mci_wrapper.set_nr_photons(10 ** 6) - self.mci_wrapper.add_layer(1.0, 2.1, 3.2, 4.3, 5.4) - self.mci_wrapper.add_layer(6.5, 7.8, 8.9, 9.10, 10.11) - self.mci_wrapper.add_layer(100.1001, 101.10001, 102.100001, - 103.1000001, 104.10000001) - self.mci_wrapper.set_layer(1, 1, 1, 1, 1, 1) - # expected mci file - self.correct_mci_filename = "./mc/data/correct.mci" - # path to the externaly installed mcml simulation. This is machine - # dependent. Thus tests depending on the execution of mcml will only - # be performed if this file exists. - # Should the file be located somewhere else on your computer, - # change this path to your actual location. - - def tearDown(self): - os.remove(self.mci_filename) - mcml_path, mcml_file = os.path.split(path_to_gpumcml) - created_mco_file = mcml_path + "/" + self.mco_filename - if os.path.isfile(created_mco_file): - os.remove(created_mco_file) - - def test_mci_wrapper(self): - self.mci_wrapper.create_mci_file() - self.assertTrue(os.path.isfile(self.mci_filename), - "mci file was created") - self.assertTrue(filecmp.cmp(self.mci_filename, - self.correct_mci_filename, shallow=False), - "the written mci file is the same as the stored " + - "reference file") - - @unittest.skipIf(skip_gpu_tests, "skip if gpumcml not installed") - def test_sim_wrapper(self): - mcml_path, mcml_file = os.path.split(path_to_gpumcml) - if os.path.isfile(path_to_gpumcml): - self.mci_wrapper.create_mci_file() - sim_wrapper = SimWrapper() - sim_wrapper.set_mci_filename(self.mci_filename) - sim_wrapper.set_mcml_executable(path_to_gpumcml) - sim_wrapper.run_simulation() - self.assertTrue(os.path.isfile(os.path.join(mcml_path, - self.mco_filename)), - "mco file was created") - - @unittest.skipIf(skip_gpu_tests, "skip if gpumcml not installed") - def test_mci_wrapper_book_example(self): - """see if our result matches the one from - Biomedical Optics - Principles and Imaging - page 55 (Table 3.1)""" - # create a book_p55_mci which shall create a mci file - book_p55_mci = MciWrapper() - book_p55_mci.set_mci_filename(self.mci_filename) - book_p55_mci.set_mco_filename(self.mco_filename) - book_p55_mci.set_nr_photons(10**6) - book_p55_mci.add_layer(1, 1000, 9000, 0.75, 0.0002) - - mcml_path, mcml_file = os.path.split(path_to_gpumcml) - if os.path.isfile(path_to_gpumcml): - book_p55_mci.create_mci_file() - sim_wrapper = SimWrapper() - sim_wrapper.set_mci_filename(self.mci_filename) - sim_wrapper.set_mcml_executable(path_to_gpumcml) - sim_wrapper.run_simulation() - self.assertTrue(os.path.isfile(mcml_path + "/" + self.mco_filename), - "mco file was created") - refl = get_diffuse_reflectance(os.path.join(mcml_path, - self.mco_filename)) - self.assertAlmostEqual(refl, 0.09734, 3, - "correct reflectance determined " + - "according to book table 3.1") - - @unittest.skipIf(skip_gpu_tests, "skip if gpumcml not installed") - def test_mci_wrapper_book_example_2(self): - """see if our result matches the one from - Biomedical Optics - Principles and Imaging - page 56 (Table 3.2)""" - # create a book_p56_mci which shall create a mci file - book_p56_mci = MciWrapper() - book_p56_mci.set_mci_filename(self.mci_filename) - book_p56_mci.set_mco_filename(self.mco_filename) - book_p56_mci.set_nr_photons(10**6) - book_p56_mci.add_layer(1.5, 1000, 9000, 0., 1) - - mcml_path, mcml_file = os.path.split(path_to_gpumcml) - if os.path.isfile(path_to_gpumcml): - book_p56_mci.create_mci_file() - sim_wrapper = SimWrapper() - sim_wrapper.set_mci_filename(self.mci_filename) - sim_wrapper.set_mcml_executable(path_to_gpumcml) - sim_wrapper.run_simulation() - self.assertTrue(os.path.isfile(mcml_path + "/" + self.mco_filename), - "mco file was created") - refl = get_total_reflectance(os.path.join(mcml_path, - self.mco_filename)) - self.assertAlmostEqual(refl, 0.26, delta=0.01, - msg="correct reflectance determined " + - "according to book table 3.2") diff --git a/Modules/Biophotonics/python/iMC/mc/test/test_tissuemodels.py b/Modules/Biophotonics/python/iMC/mc/test/test_tissuemodels.py deleted file mode 100644 index bd708c2fe7..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/test/test_tissuemodels.py +++ /dev/null @@ -1,50 +0,0 @@ -''' -Created on Sep 9, 2015 - -@author: wirkert -''' - -import unittest -import filecmp -import os - -from mc.tissuemodels import GenericTissue - -this_dir, this_filename = os.path.split(__file__) -DATA_PATH = os.path.join(this_dir, "..", "data") - - -class TestTissueModels(unittest.TestCase): - - def setUp(self): - self.mci_filename = "temp.mci" - self.mco_filename = "temp.mco" - # in this file we stored the expected result created from the - # "old" implementation of our algorithm: - self.correct_mci_filename = os.path.join(DATA_PATH, "colon_default.mci") - - def tearDown(self): - os.remove(self.mci_filename) - - def test_tissue_model(self): - # create nice colon model - tissue = GenericTissue(nr_layers=2) - tissue.set_mci_filename(self.mci_filename) - tissue.set_mco_filename(self.mco_filename) - tissue.wavelength = 500. * 10 ** -9 - # just use the default parameters for this test - # now create the simulation file - tissue.create_mci_file() - # and assert its correct - self.assertTrue(os.path.isfile(self.mci_filename), - "mci file was created") - self.assertTrue(filecmp.cmp(self.mci_filename, - self.correct_mci_filename, - shallow=False), - "the written mci file is the same as the stored " + - "reference file") - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.testName'] - unittest.main() diff --git a/Modules/Biophotonics/python/iMC/mc/test/test_ua.py b/Modules/Biophotonics/python/iMC/mc/test/test_ua.py deleted file mode 100644 index d29f2f5f4c..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/test/test_ua.py +++ /dev/null @@ -1,40 +0,0 @@ -''' -Created on Sep 8, 2015 - -@author: wirkert -''' - -import unittest - -from mc.usuag import Ua - -class test_ua(unittest.TestCase): - - def setUp(self): - self.ua_l2 = Ua() - self.ua532 = self.ua_l2(532.*10 ** -9) / 100. - self.ua800 = self.ua_l2(800.*10 ** -9) / 100. - - def test_uA532(self): - self.assertTrue(3. < self.ua532 < 4., "test if calculated ua_l2 takes " + - "reasonable values " + - "(according to \"Determination of optical" + - " properties of normal and adenomatous human colon " + - "tissues in vitro using integrating sphere " + - "techniques\")") - - def test_uA800(self): - self.assertTrue(0.05 < self.ua800 < 0.15, "test if calculated ua_l2 " + - "takes reasonable values " + - "(according to \"Differences in" + - " optical properties between healthy and " + - "pathological human colon tissues using a Ti:sapphire" + - " laser: an in vitro study using the Monte Carlo " + - "inversion technique\")") - - def test_saO2_makes_difference(self): - self.ua_l2.saO2 = 1.0 - self.assertNotAlmostEqual(self.ua532, - self.ua_l2(532.*10 ** -9) / 100., - msg="changing oxygenation changes result") - diff --git a/Modules/Biophotonics/python/iMC/mc/test/test_usg.py b/Modules/Biophotonics/python/iMC/mc/test/test_usg.py deleted file mode 100644 index 2af36b493c..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/test/test_usg.py +++ /dev/null @@ -1,26 +0,0 @@ -''' -Created on Oct 23, 2015 - -@author: wirkert -''' -import unittest - -from mc.usuag import UsgJacques - - -class TestUs(unittest.TestCase): - - def setUp(self): - self.usg = UsgJacques() - - def test_no_rayleigh_high_wavelengths(self): - self.usg.a_ray = 2.*100 - self.usg.a_mie = 20.*100 - w = 500. * 10 ** -9 - print self.usg(w)[0] / 100. - # todo write test - - -if __name__ == "__main__": - # import sys;sys.argv = ['', 'Test.testName'] - unittest.main() diff --git a/Modules/Biophotonics/python/iMC/mc/tissuemodels.py b/Modules/Biophotonics/python/iMC/mc/tissuemodels.py deleted file mode 100644 index f6a31821c1..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/tissuemodels.py +++ /dev/null @@ -1,149 +0,0 @@ -''' -Created on Sep 9, 2015 - -@author: wirkert -''' - -import numpy as np - -from mc.sim import MciWrapper -from mc.usuag import Ua, UsgJacques, UsgIntralipid - - -class AbstractTissue(object): - ''' - Initializes a abstract tissue model" - ''' - - def set_nr_photons(self, nr_photons): - self._mci_wrapper.set_nr_photons(nr_photons) - - def set_mci_filename(self, mci_filename): - self._mci_wrapper.set_mci_filename(mci_filename) - - def set_mco_filename(self, mco_filename): - self._mci_wrapper.set_mco_filename(mco_filename) - - def get_mco_filename(self): - return self._mci_wrapper.mco_filename - - def set_wavelength(self, wavelength): - self.wavelength = wavelength - - def create_mci_file(self): - # set layers - for i, ua in enumerate(self.uas): - self._mci_wrapper.set_layer(i, # layer nr - self.ns[i], # refraction index - self.uas[i](self.wavelength), # ua - self.usgs[i](self.wavelength)[0], # us - self.usgs[i](self.wavelength)[1], # g - self.ds[i]) # d - # now that the layers have been updated: create file - self._mci_wrapper.create_mci_file() - - def __str__(self): - """ Overwrite this method! - print the current model""" - model_string = "" - return model_string - - def __init__(self, ns, uas, usgs, ds): - self._mci_wrapper = MciWrapper() - - self.wavelength = 500.*10**9 # standard wavelength, should be set. - self.uas = uas - self.usgs = usgs - self.ds = ds - self.ns = ns - # initially create layers. these will be overwritten as soon - # as create_mci_file is called. - for i in enumerate(uas): - self._mci_wrapper.add_layer() - - -class GenericTissue(AbstractTissue): - ''' - Initializes a 3-layer generic tissue model - ''' - - def set_dataframe_row(self, df_row): - """take one example (one row) of a created batch and set the tissue to - resemble the structure specified by this row - - Args: - df_row: one row of a dataframe created by a batch.""" - layers = [l for l in df_row.index.levels[0] if "layer" in l] - for i, l in enumerate(layers): - self.set_layer(i, - df_row[l, "vhb"], - df_row[l, "sao2"], - df_row[l, "a_mie"], - df_row[l, "b_mie"], - df_row[l, "d"], - df_row[l, "n"], - df_row[l, "g"]) - - def set_layer(self, layer_nr=0, - bvf=None, saO2=None, a_mie=None, b_mie=None, d=None, - n=None, g=None): - """Helper function to set one layer.""" - if bvf is None: - bvf = 0.02 - if saO2 is None: - saO2 = 0.7 - if a_mie is None: - a_mie = 10. * 100 - if d is None: - d = 500. * 10 ** -6 - if b_mie is None: - b_mie = 1.286 - if n is None: - n = 1.38 - if g is None: - g = 0. - # build obejct for absorption coefficient determination - self.uas[layer_nr].bvf = bvf - self.uas[layer_nr].saO2 = saO2 - # and one for scattering coefficient - self.usgs[layer_nr].a_mie = a_mie - self.usgs[layer_nr].a_ray = 0. - self.usgs[layer_nr].b_mie = b_mie - self.usgs[layer_nr].g = g - self.ds[layer_nr] = d - self.ns[layer_nr] = n - - def __str__(self): - """print the current model""" - model_string = "" - for i, ua in enumerate(self.uas): - layer_string = "layer " + str(i) + \ - " - vhb: " + "%.1f" % (self.uas[i].bvf * 100.) + \ - "%; sao2: " + "%.1f" % (self.uas[i].saO2 * 100.) + \ - "%; a_mie: " + "%.2f" % (self.usgs[i].a_mie / 100.) + \ - "cm^-1; a_ray: " + "%.2f" % (self.usgs[i].a_ray / 100.) + \ - "cm^-1; b_mie: " + "%.3f" % self.usgs[i].b_mie + \ - "; d: " + "%.0f" % (self.ds[i] * 10 ** 6) + "um" + \ - "; n: " + "%.2f" % (self.ns[i]) + \ - "; g: " + "%.2f" % self.usgs[i].g + "\n" - model_string += layer_string - return model_string - - def __init__(self, nr_layers=3): - uas = [] - usgs = [] - for i in range(nr_layers): - uas.append(Ua()) - usgs.append(UsgJacques()) - ds = np.ones(nr_layers, dtype=float) * 500.*10 ** -6 - ns = np.ones(nr_layers, dtype=float) * 1.38 - super(GenericTissue, self).__init__(ns, uas, usgs, ds) - - -class PhantomTissue(GenericTissue): - - def __init__(self, nr_layers=1): - super(PhantomTissue, self).__init__(nr_layers=1) - self.usgs = [UsgIntralipid()] - - diff --git a/Modules/Biophotonics/python/iMC/mc/usuag.py b/Modules/Biophotonics/python/iMC/mc/usuag.py deleted file mode 100644 index d60d8173f6..0000000000 --- a/Modules/Biophotonics/python/iMC/mc/usuag.py +++ /dev/null @@ -1,217 +0,0 @@ -''' -Created on Sep 8, 2015 - -@author: wirkert -''' - -import math -import os - -import numpy as np -from scipy.interpolate import interp1d - - -this_dir, this_filename = os.path.split(__file__) -DATA_PATH = os.path.join(this_dir, "data") - -def get_haemoglobin_extinction_coefficients(reference_filename=None): - """ - helper method to get reference data for eHbO2 and eHb from Scott Prahls - reference file: - http://omlc.org/spectra/hemoglobin/summary.html - """ - if reference_filename is None: - reference_filename = os.path.join(DATA_PATH, "haemoglobin.txt") - # table with wavelength at 1st row, - # HbO2 molar extinction coefficient [cm**-1/(moles/l)] at 2nd row, - # Hb molar extinction coefficient [cm**-1/(moles/l)] at 3rd row - haemoLUT = np.loadtxt(reference_filename, skiprows=2) - # we calculate everything in [m] instead of [nm] and [1/cm] - haemoLUT[:, 0] = haemoLUT[:, 0] * 10 ** -9 - haemoLUT[:, 1:] = haemoLUT[:, 1:] * 10 ** 2 - # get the data into an interpolation map for oxy and deoxy haemoglobin - eHbO2 = interp1d(haemoLUT[:, 0], haemoLUT[:, 1]) - eHb = interp1d(haemoLUT[:, 0], haemoLUT[:, 2]) - return eHbO2, eHb - - -def get_beta_carotin_extinction_coefficients(reference_filename=None): - """ - Reference data taken from - http://omlc.org/spectra/PhotochemCAD/data/041-abs.txt - """ - if reference_filename is None: - reference_filename = os.path.join(DATA_PATH, "beta_carotin.txt") - # table with wavelength at 1st row, - # beta carotin molar extinction coefficient [cm**-1/(M)] - betaLUT = np.loadtxt(reference_filename, skiprows=2) - # we calculate everything in [m] instead of [nm] and [1/cm] - betaLUT[:, 0] = betaLUT[:, 0] * 10 ** -9 - betaLUT[:, 1:] = betaLUT[:, 1:] * 10 ** 2 - # get the data into an interpolation map - eBc = interp1d(betaLUT[:, 0], betaLUT[:, 1], bounds_error=False, - fill_value=0.) - return eBc - - -def get_bilirubin_extinction_coefficients(reference_filename=None): - """ - Reference data taken from - http://omlc.org/spectra/PhotochemCAD/data/041-abs.txt - """ - if reference_filename is None: - reference_filename = os.path.join(DATA_PATH, "bilirubin.txt") - # table with wavelength at 1st row, - # beta carotin molar extinction coefficient [cm**-1/(M)] - biliLUT = np.loadtxt(reference_filename, skiprows=2) - # we calculate everything in [m] instead of [nm] and [1/cm] - biliLUT[:, 0] = biliLUT[:, 0] * 10 ** -9 - biliLUT[:, 1:] = biliLUT[:, 1:] * 10 ** 2 - # get the data into an interpolation map - eBili = interp1d(biliLUT[:, 0], biliLUT[:, 1], bounds_error=False, - fill_value=0.) - return eBili - - -class Ua(object): - - def __init__(self): - self.bvf = 0.02 # % - self.cHb = 120. # g*Hb/l - self.saO2 = 0. # % - self.eHbO2, self.eHb = \ - get_haemoglobin_extinction_coefficients() - - self.cBetaCarotinUgProDl = 0. # 2000. - # g / l - self.cBili = 0. # 1.23 * 10 ** -2 - self.eBc = get_beta_carotin_extinction_coefficients() - self.eBili = get_bilirubin_extinction_coefficients() - - - def __call__(self, wavelength): - """ determine ua [1/m] as combination of - Haemoglobin extinction coefficients. - For more on this equation, please refer to - http://omlc.org/spectra/hemoglobin/ - """ - ua_haemoglobin = math.log(10) * self.cHb * \ - (self.saO2 * self.eHbO2(wavelength) + - (1 - self.saO2) * self.eHb(wavelength)) \ - / 64500. * self.bvf - ua_bilirubin = math.log(10) * self.cBili / 574.65 * \ - self.eBili(wavelength) - # second line is to convert from ug/dl to g/ mole - ua_beta_carotin = math.log(10) * self.cBetaCarotinUgProDl / \ - 536.8726 * 10 ** -5 * \ - self.eBc(wavelength) - - return ua_haemoglobin + ua_bilirubin + ua_beta_carotin - - -class UaMuscle(): - """helper class for setting ua in muscle layer. - for ua_sm in the muscle layer we don't use mie theory but the - approximation presented in - Rowe et al. - "Modelling and validation of spectral reflectance for the colon" - calculated to retrieve an absorption of 11.2 cm-1 at 515nm - """ - def __init__(self): - self.ua = Ua() - - def __call__(self, wavelength): - A = 1.7923385088285804 - self.ua.bvf = 0.1 * A - self.ua.saO2 = 0.7 - self.ua.cHb = 120. - return self.ua(wavelength) - - -class UsgJacques(object): - - def __init__(self): - """ - To be set externally: - - a': - """ - self.a_ray = 0. * 100. - self.a_mie = 20. * 100. - self.b_mie = 1.286 - self.g = 0. - - def __call__(self, wavelength): - """ - Calculate the scattering parameters relevant for monte carlo simulation. - - Uses equation (2) from: Optical properties of biological tissues: - a Review - - Args - ____ - wavelength: - wavelength of the incident light [m] - - Returns: - ____ - (us, g) - scattering coefficient us [1/m] and anisotropy factor g - """ - norm_wavelength = (wavelength / (500 * 10 ** -9)) - - us_ray = self.a_ray * norm_wavelength ** (-4) - us_mie = self.a_mie * norm_wavelength ** (-self.b_mie) - - us_prime = (us_ray + us_mie) # * 100. to convert to m^-1 - # actually we calculated the reduced scattering coefficent, so - # assume g is 0 - us = us_prime / (1 - self.g) - - return us, self.g - - -class UsGMuscle(object): - """helper object for setting us in muscle layer. - for us in the muscle layer we don't use mie theory but the - approximation presented in - Rowe et al. - "Modelling and validation of spectral reflectance for the colon" - """ - - def __init__(self): - pass - - - def __call__(self, wavelength): - us = 168.52 * (wavelength * 10 ** 9) ** -0.332 / (1. - 0.96) * 100. - g = 0.96 - return us, g - - -class UsgIntralipid(object): - """helper object for setting us and g in intralipid - We use the formulas from - http://omlc.org/spectra/intralipid/ to calculate - """ - - def __init__(self): - self.a_ray = 0. * 100. - self.a_mie = 20. * 100. - self.b_mie = 2.33 - self.g = 0.85 - - def __call__(self, wavelength): - - norm_wavelength = (wavelength / (500 * 10 ** -9)) - - us_ray = self.a_ray * norm_wavelength ** (-4) - us_mie = self.a_mie * norm_wavelength ** (-self.b_mie) - - us_prime = (us_ray + us_mie) # * 100. to convert to m^-1 - - g = 2.25 * (wavelength * 10**9)**-0.155 - - us = us_prime / (1 - g) - - return us, g diff --git a/Modules/Biophotonics/python/iMC/msi/__init__.py b/Modules/Biophotonics/python/iMC/msi/__init__.py deleted file mode 100644 index 0e9a801a5f..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 14 15:54:35 2015 - -@author: wirkert -""" - diff --git a/Modules/Biophotonics/python/iMC/msi/data/Transmission_15-49-35-978_filter700nm.txt b/Modules/Biophotonics/python/iMC/msi/data/Transmission_15-49-35-978_filter700nm.txt deleted file mode 100755 index 5f619b446a..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/data/Transmission_15-49-35-978_filter700nm.txt +++ /dev/null @@ -1,2064 +0,0 @@ -Data from Transmission_15-49-35-978.txt Node - -Date: Mon Jun 01 15:49:35 CEST 2015 -User: thomaskirchnerbackup -Spectrometer: HR+C3363 -Autoset integration time: false -Trigger mode: 0 -Integration Time (sec): 1.600000E-2 -Scans to average: 1 -Electric dark correction enabled: true -Nonlinearity correction enabled: false -Boxcar width: 0 -XAxis mode: Wavelengths -Stop averaging: false -Number of Pixels in Spectrum: 2048 ->>>>>Begin Spectral Data<<<<< -187.255 70.50 -187.731 70.51 -188.206 70.51 -188.682 -0 -189.158 303.75 -189.634 135.85 -190.109 109.35 -190.585 9.89 -191.061 5400 -191.536 -476.47 -192.012 17100 -192.488 -54 -192.963 46.61 -193.439 -211.22 -193.914 114.18 -194.389 225 -194.865 137.65 -195.34 270 -195.816 -8100 -196.291 407.81 -196.766 -276.92 -197.242 51.43 -197.717 591.43 -198.192 -140.63 -198.667 135 -199.142 161.8 -199.618 -990 -200.093 139.75 -200.568 2.79 -201.043 -794.12 -201.518 101.61 -201.993 -50.4 -202.468 -3.35 -202.943 90 -203.418 -252.34 -203.893 -42.35 -204.368 112.5 -204.842 100.41 -205.317 331.58 -205.792 -203.77 -206.267 -900 -206.741 43.55 -207.216 -488.57 -207.691 69.74 -208.165 33.51 -208.64 276.92 -209.115 135 -209.589 33.51 -210.064 100.49 -210.538 -10800 -211.013 -0 -211.487 -144 -211.962 0 -212.436 185.05 -212.91 172.6 -213.385 14.33 -213.859 103.85 -214.333 96.43 -214.808 -582.35 -215.282 12600 -215.756 39.01 -216.23 -24.11 -216.704 -380.77 -217.178 40.15 -217.653 264.71 -218.127 11700 -218.601 -93.6 -219.075 81.82 -219.549 -14400 -220.023 308.22 -220.496 22.84 -220.97 -29.14 -221.444 -121.35 -221.918 -38.63 -222.392 28.72 -222.866 1800 -223.339 102.27 -223.813 106.21 -224.287 63.22 -224.76 -203.77 -225.234 -1042.11 -225.708 -38.79 -226.181 5.92 -226.655 94.41 -227.128 -138.46 -227.602 -43.9 -228.075 -26.21 -228.549 623.08 -229.022 56.25 -229.496 -25.23 -229.969 46.61 -230.442 119.58 -230.916 270 -231.389 26.87 -231.862 -787.5 -232.335 -0 -232.809 431.51 -233.282 -203.23 -233.755 14.06 -234.228 134.16 -234.701 -101.12 -235.174 76.34 -235.647 70.39 -236.12 43.71 -236.593 -32.37 -237.066 190.68 -237.539 210.28 -238.012 210.94 -238.485 14.34 -238.958 57.94 -239.43 308.57 -239.903 -55.1 -240.376 168.75 -240.849 321.43 -241.321 360 -241.794 -7.09 -242.267 -110.2 -242.739 30.58 -243.212 -31.03 -243.684 5.29 -244.157 -39.13 -244.629 9.57 -245.102 -1136.84 -245.574 -152.83 -246.047 -18.48 -246.519 0 -246.992 27.95 -247.464 -38.03 -247.936 8.74 -248.408 -371.74 -248.881 90 -249.353 2.51 -249.825 72.69 -250.297 157.98 -250.769 340.54 -251.242 -18.37 -251.714 -25.1 -252.186 163.64 -252.658 -668.57 -253.13 43.09 -253.602 -105.88 -254.074 29.89 -254.546 78.88 -255.017 22.31 -255.489 43.69 -255.961 27.36 -256.433 23.68 -256.905 -87.38 -257.377 29.03 -257.848 101.61 -258.32 -232.26 -258.792 -23.14 -259.263 225 -259.735 67.16 -260.206 -562.5 -260.678 450 -261.15 -16200 -261.621 104.13 -262.093 -100.93 -262.564 33.75 -263.035 119.74 -263.507 128.57 -263.978 43.71 -264.449 810 -264.921 72.97 -265.392 63 -265.863 474.55 -266.335 65.77 -266.806 26.03 -267.277 56.25 -267.748 -3600 -268.219 43.49 -268.69 64.29 -269.161 -411.43 -269.632 -41.12 -270.103 50.28 -270.574 43.9 -271.045 -373.58 -271.516 -15.08 -271.987 64.75 -272.458 60.27 -272.929 59.21 -273.4 -63.38 -273.87 741.18 -274.341 6.92 -274.812 -112.5 -275.282 12.16 -275.753 38.3 -276.224 124.14 -276.694 -578.57 -277.165 -33.96 -277.636 234.78 -278.106 3.86 -278.577 -48.65 -279.047 29.61 -279.517 -22.84 -279.988 -87.31 -280.458 11.16 -280.929 -10800 -281.399 -265.91 -281.869 -55.9 -282.34 246.58 -282.81 -37.76 -283.28 -388.64 -283.75 60.45 -284.22 -14.36 -284.691 -257.14 -285.161 102.27 -285.631 20.07 -286.101 168.75 -286.571 116.52 -287.041 67.92 -287.511 19.42 -287.981 -173.08 -288.451 84.37 -288.921 69.23 -289.39 -3.72 -289.86 0 -290.33 7.17 -290.8 21.6 -291.27 31500 -291.739 -102.27 -292.209 52.94 -292.679 20.22 -293.148 112.5 -293.618 49.54 -294.088 87.91 -294.557 55.45 -295.027 114.89 -295.496 900 -295.966 12.05 -296.435 -59.21 -296.904 331.58 -297.374 178.02 -297.843 -220.41 -298.313 -246.77 -298.782 450 -299.251 128.57 -299.72 11.25 -300.19 23.14 -300.659 44.55 -301.128 69.23 -301.597 -58.24 -302.066 -25.35 -302.535 19.78 -303.004 -60.67 -303.473 86.3 -303.942 293.48 -304.411 1125 -304.88 12.23 -305.349 -21.18 -305.818 121.62 -306.287 215.22 -306.756 -11.84 -307.225 60.34 -307.693 29.51 -308.162 37.89 -308.631 -37.76 -309.1 17.82 -309.568 68.82 -310.037 59.58 -310.506 81.38 -310.974 21.18 -311.443 105.08 -311.911 -8.85 -312.38 -115.2 -312.848 37.67 -313.317 63.38 -313.785 109.35 -314.254 21.11 -314.722 -43.2 -315.19 245.45 -315.659 -81.82 -316.127 258.9 -316.595 -16.77 -317.063 476.47 -317.532 -33.75 -318 63.53 -318.468 11.16 -318.936 101.61 -319.404 48.91 -319.872 0 -320.34 44.72 -320.808 -26.87 -321.276 71.05 -321.744 -92.52 -322.212 53.31 -322.68 16200 -323.148 -715.91 -323.616 214.68 -324.083 107.52 -324.551 3.14 -325.019 15.95 -325.487 -209.48 -325.954 11.18 -326.422 -18.6 -326.89 -101.61 -327.357 288 -327.825 120.47 -328.292 85.04 -328.76 -65.67 -329.228 -45.69 -329.695 -35.53 -330.162 -303.75 -330.63 0 -331.097 0 -331.565 41.54 -332.032 0 -332.499 -86.17 -332.967 52.43 -333.434 41.54 -333.901 246.77 -334.368 12.05 -334.835 83.01 -335.303 101.41 -335.77 -25.9 -336.237 296.34 -336.704 19.1 -337.171 -47.37 -337.638 -80.9 -338.105 27.41 -338.572 62.23 -339.039 -50.7 -339.506 64.73 -339.973 0 -340.439 -172.8 -340.906 -100.49 -341.373 -26.39 -341.84 34.24 -342.307 1440 -342.773 41.31 -343.24 6.54 -343.707 48.18 -344.173 -21.69 -344.64 -52.65 -345.106 12.23 -345.573 68.3 -346.039 -12.16 -346.506 33.4 -346.972 -20.66 -347.439 60.7 -347.905 13.35 -348.372 -1.5 -348.838 22.62 -349.304 58.7 -349.77 -16.32 -350.237 -14.32 -350.703 -42.57 -351.169 16.71 -351.635 10.62 -352.102 5.62 -352.568 -12.53 -353.034 7.15 -353.5 -6.18 -353.966 -37.23 -354.432 1.27 -354.898 17.31 -355.364 -65.77 -355.83 -25.55 -356.296 -26.71 -356.762 -7.26 -357.227 2.74 -357.693 9.59 -358.159 3.23 -358.625 -9.59 -359.09 -10.49 -359.556 7.01 -360.022 9.83 -360.488 9.76 -360.953 -9.1 -361.419 -7.91 -361.884 4.83 -362.35 4.13 -362.815 -0.86 -363.281 10.41 -363.746 -1.98 -364.212 -5.27 -364.677 0 -365.143 12.01 -365.608 0 -366.073 -9.66 -366.539 -1.3 -367.004 6.13 -367.469 13.65 -367.934 -8.58 -368.399 4.52 -368.865 0 -369.33 -4.49 -369.795 -10.07 -370.26 3.41 -370.725 -1.21 -371.19 6.18 -371.655 13.9 -372.12 8.63 -372.585 -7.93 -373.05 -1.84 -373.515 -3.98 -373.979 5.92 -374.444 2.8 -374.909 -7.58 -375.374 -0.98 -375.839 10.89 -376.303 4.17 -376.768 8.22 -377.233 0.44 -377.697 15.92 -378.162 -15.93 -378.626 -3.97 -379.091 -1.29 -379.556 -0.49 -380.02 -6.48 -380.485 -7.32 -380.949 0 -381.413 -2.81 -381.878 2.27 -382.342 -0.38 -382.806 4 -383.271 0.75 -383.735 5.76 -384.199 8 -384.663 5.29 -385.128 2.28 -385.592 2.08 -386.056 -5.6 -386.52 5.33 -386.984 6.92 -387.448 -4.68 -387.912 -8.79 -388.376 -0.71 -388.84 0.93 -389.304 2.74 -389.768 -3.72 -390.232 0.93 -390.696 2.48 -391.16 0 -391.623 -0.89 -392.087 4.05 -392.551 0.51 -393.015 2.94 -393.478 5.03 -393.942 7.63 -394.406 0.73 -394.869 0.47 -395.333 0.52 -395.796 2.78 -396.26 0.51 -396.723 -4.75 -397.187 0 -397.65 0.25 -398.114 2.78 -398.577 -1.45 -399.041 -6.15 -399.504 0 -399.967 1.95 -400.43 2.06 -400.894 -2.95 -401.357 -1.1 -401.82 -1.52 -402.283 2.15 -402.746 -0.86 -403.21 0.95 -403.673 0.42 -404.136 -3.42 -404.599 -1.46 -405.062 -0.79 -405.525 0.59 -405.988 3.17 -406.451 1.14 -406.913 -0.74 -407.376 -2.42 -407.839 3.43 -408.302 2.36 -408.765 1.76 -409.228 0.53 -409.69 -2.5 -410.153 -0.49 -410.616 1.49 -411.078 4.88 -411.541 1.27 -412.004 1.97 -412.466 -1.29 -412.929 -2.17 -413.391 -0.76 -413.854 -1.06 -414.316 0 -414.778 0.3 -415.241 -1.03 -415.703 -0.43 -416.166 0.29 -416.628 -3.02 -417.09 0.71 -417.552 -1.7 -418.015 -0.28 -418.477 -1.05 -418.939 1.9 -419.401 -0.13 -419.863 -1.23 -420.325 1.69 -420.787 0.39 -421.25 0.26 -421.712 -2.89 -422.174 -0.94 -422.635 1.26 -423.097 2.28 -423.559 -0.13 -424.021 2.43 -424.483 -1.65 -424.945 -2.66 -425.407 1.11 -425.868 1.76 -426.33 0.91 -426.792 1.99 -427.254 -1.2 -427.715 -0.59 -428.177 0.68 -428.638 2.35 -429.1 -1.49 -429.562 -0.67 -430.023 -1.57 -430.485 -0.85 -430.946 -0.87 -431.407 2.02 -431.869 -0.51 -432.33 0.61 -432.792 1.65 -433.253 -0.81 -433.714 -3.13 -434.175 0 -434.637 -1.85 -435.098 1.75 -435.559 1.45 -436.02 0 -436.481 -1.51 -436.942 -0.09 -437.404 0.26 -437.865 0.94 -438.326 -0.89 -438.787 -0.44 -439.248 0.51 -439.709 1.08 -440.169 0.57 -440.63 0.17 -441.091 -1.89 -441.552 0.97 -442.013 -1.9 -442.474 -2.27 -442.934 1.11 -443.395 0.81 -443.856 -0.38 -444.316 0.23 -444.777 0.55 -445.238 0.52 -445.698 0.29 -446.159 -0.53 -446.619 0.9 -447.08 2.23 -447.54 -1.09 -448.001 0.89 -448.461 0.51 -448.921 0.66 -449.382 -0.15 -449.842 0 -450.302 -2.32 -450.763 -1.75 -451.223 0.14 -451.683 0.15 -452.143 -0.58 -452.604 0.76 -453.064 -0.49 -453.524 -2.23 -453.984 0 -454.444 -0.07 -454.904 0.47 -455.364 -1.87 -455.824 0.59 -456.284 0.74 -456.744 -0.19 -457.204 -2.07 -457.664 0 -458.123 0.12 -458.583 -0.62 -459.043 -0.74 -459.503 0.18 -459.963 -0.42 -460.422 0.23 -460.882 1.68 -461.342 -0.62 -461.801 -0.45 -462.261 -1.45 -462.72 -0.44 -463.18 0.75 -463.639 -0.21 -464.099 -1.98 -464.558 -0.4 -465.018 -0.1 -465.477 -1.16 -465.936 -0.53 -466.396 0.38 -466.855 -0.38 -467.314 -0.09 -467.774 0 -468.233 -1.23 -468.692 -0.66 -469.151 -1.29 -469.61 -0.79 -470.07 -0.16 -470.529 -0.16 -470.988 0.47 -471.447 0.63 -471.906 0.31 -472.365 -0.44 -472.824 -0.44 -473.283 0 -473.742 0.14 -474.2 -0.03 -474.659 0.03 -475.118 0.07 -475.577 -0.33 -476.036 0.35 -476.494 0.16 -476.953 -0.18 -477.412 0.59 -477.87 -0.55 -478.329 -0.61 -478.788 0.64 -479.246 0.22 -479.705 -0.19 -480.163 -0.21 -480.622 -0.52 -481.08 -0.95 -481.539 -0.32 -481.997 0.19 -482.455 -0.15 -482.914 -0.24 -483.372 -0.36 -483.83 0.05 -484.289 -0.07 -484.747 -0.42 -485.205 -0.18 -485.663 0.02 -486.122 -0.17 -486.58 -0.1 -487.038 -0.25 -487.496 -0.14 -487.954 0.02 -488.412 0.02 -488.87 0.33 -489.328 0.19 -489.786 -0.1 -490.244 0.08 -490.702 -0.21 -491.159 -0.11 -491.617 0.11 -492.075 0.13 -492.533 0.34 -492.991 0.18 -493.448 0.23 -493.906 0.23 -494.364 0.31 -494.821 -0.12 -495.279 0.32 -495.737 0.13 -496.194 0.02 -496.652 0.21 -497.109 0.08 -497.567 -0.23 -498.024 -0.14 -498.481 -0.08 -498.939 0.11 -499.396 -0.06 -499.854 -0.14 -500.311 0.26 -500.768 0.27 -501.225 0.42 -501.683 0.29 -502.14 -0.3 -502.597 -0.22 -503.054 -0.04 -503.511 0.3 -503.968 -0.63 -504.425 -0.24 -504.882 0.19 -505.339 -0.26 -505.796 0.13 -506.253 0 -506.71 0.18 -507.167 0.08 -507.624 0.14 -508.081 0.05 -508.538 0.05 -508.995 -0.15 -509.451 0.04 -509.908 0.2 -510.365 -0.07 -510.821 -0.07 -511.278 -0.16 -511.735 0.03 -512.191 -0.29 -512.648 -0.17 -513.104 0.23 -513.561 0 -514.017 -0.24 -514.474 -0.01 -514.93 0.31 -515.387 0.02 -515.843 0.16 -516.299 -0.07 -516.756 0.12 -517.212 -0.02 -517.668 0.13 -518.125 0.08 -518.581 0.18 -519.037 0.09 -519.493 -0.1 -519.949 0.16 -520.405 0.13 -520.861 0.13 -521.317 0.16 -521.773 -0.02 -522.229 -0.11 -522.685 0.09 -523.141 0.48 -523.597 0.28 -524.053 0.14 -524.509 0.29 -524.965 -0.08 -525.421 -0.02 -525.876 -0.17 -526.332 0.01 -526.788 0.03 -527.244 -0.04 -527.699 -0.1 -528.155 0.05 -528.61 0.03 -529.066 0 -529.522 -0.07 -529.977 -0.14 -530.433 -0.05 -530.888 0.03 -531.344 0.08 -531.799 0.29 -532.254 -0.03 -532.71 -0.08 -533.165 -0.16 -533.62 -0.26 -534.076 -0.3 -534.531 0.03 -534.986 0.1 -535.441 -0.14 -535.897 -0.03 -536.352 0.1 -536.807 0.02 -537.262 0.27 -537.717 -0.1 -538.172 0 -538.627 0.07 -539.082 0.38 -539.537 -0.27 -539.992 -0.1 -540.447 0.04 -540.902 -0.08 -541.356 -0.16 -541.811 0.04 -542.266 0 -542.721 0.05 -543.176 -0.01 -543.63 0.09 -544.085 0.17 -544.54 -0.04 -544.994 -0.05 -545.449 0.08 -545.903 0.01 -546.358 -0.03 -546.812 -0.12 -547.267 -0.12 -547.721 -0.13 -548.176 -0.04 -548.63 0.08 -549.085 -0.07 -549.539 -0.11 -549.993 0.11 -550.448 -0.08 -550.902 -0.01 -551.356 -0.01 -551.81 -0.08 -552.264 -0.14 -552.719 0.13 -553.173 0.1 -553.627 -0.07 -554.081 0.03 -554.535 0.11 -554.989 -0.04 -555.443 0.04 -555.897 0.08 -556.351 0.12 -556.805 -0.06 -557.259 -0.23 -557.712 -0.03 -558.166 0.05 -558.62 0.15 -559.074 -0.31 -559.528 -0.14 -559.981 0.09 -560.435 0.09 -560.889 0.09 -561.342 -0.06 -561.796 0.25 -562.25 -0.1 -562.703 0.15 -563.157 -0.09 -563.61 0.01 -564.064 -0.16 -564.517 -0.14 -564.97 -0.19 -565.424 -0.04 -565.877 -0.2 -566.331 -0.01 -566.784 0.13 -567.237 0.04 -567.69 0.14 -568.144 0.17 -568.597 -0.04 -569.05 -0.07 -569.503 -0.04 -569.956 -0.11 -570.409 0 -570.862 0.06 -571.315 -0.04 -571.768 0.21 -572.221 0.07 -572.674 -0.07 -573.127 0.2 -573.58 -0.02 -574.033 0.08 -574.486 0 -574.939 0.07 -575.392 -0.08 -575.844 0.04 -576.297 0.05 -576.75 -0.15 -577.202 -0.05 -577.655 0.08 -578.108 -0.12 -578.56 -0.1 -579.013 -0.11 -579.465 0.23 -579.918 0.02 -580.37 0.21 -580.823 0.34 -581.275 0.18 -581.728 0.02 -582.18 -0.06 -582.632 0.14 -583.085 -0.13 -583.537 0.06 -583.989 0.02 -584.442 -0.05 -584.894 -0.02 -585.346 -0.03 -585.798 0.08 -586.25 0.05 -586.702 -0.05 -587.155 0.05 -587.607 0.02 -588.059 0.17 -588.511 0.01 -588.963 0.08 -589.415 -0.03 -589.866 0.05 -590.318 0.03 -590.77 0.02 -591.222 -0.02 -591.674 0.06 -592.126 0 -592.577 0.09 -593.029 -0.1 -593.481 0.04 -593.932 0 -594.384 -0.02 -594.836 -0.05 -595.287 0.02 -595.739 -0.11 -596.19 -0.02 -596.642 0.11 -597.093 0.15 -597.545 0.07 -597.996 -0.06 -598.448 0.02 -598.899 -0.04 -599.35 -0.07 -599.802 -0.01 -600.253 0.02 -600.704 -0.06 -601.155 -0.15 -601.607 -0.12 -602.058 -0.11 -602.509 -0.01 -602.96 -0.06 -603.411 0.11 -603.862 0.08 -604.313 0.2 -604.764 -0.06 -605.215 0.02 -605.666 -0.07 -606.117 -0.06 -606.568 0.11 -607.019 -0.13 -607.47 -0.02 -607.921 -0.12 -608.371 -0.23 -608.822 0.02 -609.273 0.06 -609.724 0.13 -610.174 0.08 -610.625 0.11 -611.076 0.06 -611.526 -0.06 -611.977 -0.06 -612.427 -0.02 -612.878 0.08 -613.328 0.01 -613.779 0.04 -614.229 0.05 -614.68 -0.07 -615.13 -0.06 -615.58 -0.15 -616.031 0.01 -616.481 0 -616.931 -0.15 -617.382 -0.12 -617.832 0.01 -618.282 0.17 -618.732 -0.02 -619.182 -0.07 -619.632 -0.28 -620.083 -0.04 -620.533 -0.14 -620.983 0.08 -621.433 0.05 -621.883 0.09 -622.333 0.05 -622.783 -0.11 -623.232 -0.11 -623.682 0.13 -624.132 0.09 -624.582 -0.01 -625.032 -0.08 -625.481 0.11 -625.931 -0.02 -626.381 0.02 -626.831 0 -627.28 0.08 -627.73 0.15 -628.179 -0.16 -628.629 0.02 -629.079 0.14 -629.528 0.08 -629.978 -0.13 -630.427 -0.15 -630.876 0.16 -631.326 0.04 -631.775 0.04 -632.225 0.09 -632.674 -0.07 -633.123 -0.12 -633.573 -0.03 -634.022 -0.05 -634.471 0.13 -634.92 0.17 -635.369 0.01 -635.818 0.01 -636.268 -0.14 -636.717 0.02 -637.166 0.11 -637.615 0.08 -638.064 -0.04 -638.513 -0.13 -638.962 -0.01 -639.411 0.14 -639.859 0.1 -640.308 -0.04 -640.757 0.15 -641.206 0.04 -641.655 -0.14 -642.103 0.01 -642.552 0.04 -643.001 0.07 -643.45 -0.04 -643.898 0.11 -644.347 0 -644.795 0.17 -645.244 0 -645.692 -0.03 -646.141 -0.03 -646.589 -0.07 -647.038 0.18 -647.486 0.03 -647.935 0.08 -648.383 0.11 -648.831 -0.06 -649.28 -0.03 -649.728 0.03 -650.176 -0.05 -650.625 -0.01 -651.073 0.07 -651.521 -0.04 -651.969 0.07 -652.417 0 -652.865 0.04 -653.313 -0.09 -653.761 -0.01 -654.209 0.11 -654.657 0.12 -655.105 0.16 -655.553 -0.13 -656.001 -0.06 -656.449 -0.04 -656.897 -0.06 -657.345 0.12 -657.793 0.06 -658.24 0.03 -658.688 -0.02 -659.136 0.05 -659.584 -0.09 -660.031 -0.05 -660.479 0.11 -660.926 0.17 -661.374 -0.04 -661.822 0.11 -662.269 0.03 -662.717 -0.09 -663.164 0.02 -663.611 0.12 -664.059 0.11 -664.506 0.08 -664.954 -0.03 -665.401 0.05 -665.848 -0.04 -666.296 0.02 -666.743 0.02 -667.19 0.13 -667.637 -0.07 -668.084 -0.06 -668.532 -0.11 -668.979 -0.1 -669.426 -0.03 -669.873 -0.02 -670.32 0.25 -670.767 -0.01 -671.214 -0.02 -671.661 0.22 -672.108 0.21 -672.555 0.14 -673.002 0.23 -673.448 0.15 -673.895 0.16 -674.342 0.04 -674.789 0.17 -675.235 0.12 -675.682 0.19 -676.129 0.03 -676.576 0.37 -677.022 0.15 -677.469 0.16 -677.915 -0.05 -678.362 0.24 -678.808 0.33 -679.255 0.2 -679.701 0.22 -680.148 0.21 -680.594 0.07 -681.041 0.21 -681.487 0.21 -681.933 0.36 -682.38 0.29 -682.826 0.5 -683.272 0.48 -683.718 0.49 -684.165 0.79 -684.611 1.09 -685.057 1.31 -685.503 1.83 -685.949 3.15 -686.395 4.55 -686.841 7.27 -687.287 11.74 -687.733 19.13 -688.179 29.95 -688.625 44.29 -689.071 56.79 -689.517 66.46 -689.963 72.42 -690.408 73.42 -690.854 75.79 -691.3 76.21 -691.746 77.76 -692.191 77.99 -692.637 79.37 -693.083 80.64 -693.528 83.42 -693.974 85.5 -694.419 85.33 -694.865 87.07 -695.311 86.82 -695.756 85.95 -696.201 85.16 -696.647 82.87 -697.092 82.21 -697.538 82.19 -697.983 82.97 -698.428 82.35 -698.874 82.57 -699.319 83.05 -699.764 83.78 -700.209 83.92 -700.655 84.64 -701.1 84.21 -701.545 84.33 -701.99 84.34 -702.435 85.04 -702.88 84.41 -703.325 86.05 -703.77 87.18 -704.215 88.7 -704.66 88.74 -705.105 88.61 -705.55 85.02 -705.995 79.77 -706.44 69.94 -706.884 58.82 -707.329 46.78 -707.774 35.81 -708.219 27.19 -708.663 19.34 -709.108 14.29 -709.553 10.15 -709.997 7.17 -710.442 5.26 -710.886 3.41 -711.331 2.8 -711.775 2.18 -712.22 1.45 -712.664 1.32 -713.109 0.94 -713.553 0.72 -713.998 0.73 -714.442 0.43 -714.886 0.27 -715.331 0.25 -715.775 0.54 -716.219 0.14 -716.663 0.47 -717.107 0.19 -717.552 0.09 -717.996 0.24 -718.44 0.14 -718.884 0.23 -719.328 0.27 -719.772 0.13 -720.216 0.17 -720.66 0.2 -721.104 0.08 -721.548 -0.05 -721.992 0.1 -722.436 0.08 -722.879 0.07 -723.323 0.4 -723.767 0.21 -724.211 0.08 -724.654 0.21 -725.098 0.06 -725.542 -0.13 -725.985 -0.12 -726.429 -0.12 -726.873 0.03 -727.316 0.06 -727.76 0.11 -728.203 0.08 -728.647 -0.01 -729.09 0.05 -729.534 0.09 -729.977 -0.01 -730.42 0.11 -730.864 0.11 -731.307 -0.07 -731.75 -0.11 -732.194 0.02 -732.637 0.01 -733.08 0.28 -733.523 0.24 -733.966 0 -734.41 -0.16 -734.853 0.03 -735.296 -0.11 -735.739 -0.07 -736.182 0.16 -736.625 0.21 -737.068 0.3 -737.511 -0.04 -737.954 -0.09 -738.396 0.19 -738.839 -0.24 -739.282 -0.08 -739.725 -0.15 -740.168 0.16 -740.61 -0.02 -741.053 -0.16 -741.496 0.01 -741.939 0.01 -742.381 0.01 -742.824 -0.13 -743.266 0.1 -743.709 0.27 -744.151 0.05 -744.594 -0.23 -745.036 -0.19 -745.479 0.08 -745.921 -0.12 -746.364 -0.12 -746.806 -0.17 -747.248 0.23 -747.691 0.32 -748.133 -0.11 -748.575 0.12 -749.017 0.06 -749.46 -0.01 -749.902 -0.21 -750.344 0.2 -750.786 -0.33 -751.228 -0.01 -751.67 0.01 -752.112 0.06 -752.554 0.18 -752.996 -0.05 -753.438 0.16 -753.88 -0.27 -754.322 -0.16 -754.764 0.19 -755.206 0.18 -755.648 0.06 -756.09 0.2 -756.531 -0.06 -756.973 0.31 -757.415 0.35 -757.856 -0.08 -758.298 0.32 -758.74 -0.02 -759.181 0.24 -759.623 0.04 -760.065 0.02 -760.506 -0.07 -760.948 -0.06 -761.389 -0.15 -761.83 0.12 -762.272 0.23 -762.713 0.32 -763.155 -0.19 -763.596 -0.45 -764.037 -0.04 -764.479 0.09 -764.92 0.01 -765.361 0.1 -765.802 0.22 -766.243 -0.03 -766.685 0.18 -767.126 -0.05 -767.567 0.53 -768.008 0.1 -768.449 0 -768.89 -0.1 -769.331 0.01 -769.772 -0.26 -770.213 0.14 -770.654 0 -771.095 -0.24 -771.535 0.05 -771.976 0.05 -772.417 0.03 -772.858 0.29 -773.299 -0.08 -773.739 0.01 -774.18 0.25 -774.621 0.39 -775.061 -0.04 -775.502 0.4 -775.942 0.41 -776.383 0.15 -776.824 0 -777.264 0.43 -777.705 0.43 -778.145 -0.07 -778.585 -0.08 -779.026 -0.27 -779.466 -0.03 -779.906 0.4 -780.347 0.03 -780.787 0.01 -781.227 -0.01 -781.668 -0.1 -782.108 0.46 -782.548 0.21 -782.988 0.59 -783.428 0 -783.868 -0.2 -784.308 -0.07 -784.748 -0.01 -785.188 0 -785.628 -0.22 -786.068 0.48 -786.508 0.28 -786.948 0.18 -787.388 -0.16 -787.828 -0.18 -788.268 -0.03 -788.708 0.23 -789.147 0.19 -789.587 0.38 -790.027 0.25 -790.467 0 -790.906 -0.18 -791.346 -0.03 -791.785 0.06 -792.225 -0.57 -792.665 0.2 -793.104 -0.11 -793.544 -0.2 -793.983 0.11 -794.422 0.3 -794.862 -0.11 -795.301 0.38 -795.741 -0.38 -796.18 0.06 -796.619 -0.11 -797.059 -0.1 -797.498 0.11 -797.937 0.08 -798.376 0 -798.815 0.43 -799.255 0.38 -799.694 0.08 -800.133 -0.05 -800.572 -0.49 -801.011 -0.2 -801.45 -0.03 -801.889 -0.03 -802.328 0.24 -802.767 -0.09 -803.206 0.55 -803.645 -0.31 -804.083 0.14 -804.522 0.3 -804.961 0.12 -805.4 -0.36 -805.839 0.14 -806.277 0.14 -806.716 -0.04 -807.155 0.16 -807.593 -0.3 -808.032 0.12 -808.471 -0.18 -808.909 0.29 -809.348 0.45 -809.786 0.09 -810.225 -0.23 -810.663 0.18 -811.101 0.23 -811.54 0.51 -811.978 0 -812.417 0.04 -812.855 0.2 -813.293 0.17 -813.731 -0.09 -814.17 -0.19 -814.608 0.06 -815.046 0.21 -815.484 -0.04 -815.922 -0.04 -816.36 0.1 -816.798 0.02 -817.236 0.35 -817.674 -0.09 -818.112 0 -818.55 0.2 -818.988 -0.08 -819.426 -0.36 -819.864 0 -820.302 0.18 -820.74 -0.22 -821.178 0.12 -821.615 0.1 -822.053 -0.1 -822.491 -0.18 -822.929 0.18 -823.366 0.25 -823.804 0.17 -824.241 0.39 -824.679 0.19 -825.117 0 -825.554 -0.1 -825.992 0.29 -826.429 -0.33 -826.867 0.23 -827.304 0 -827.741 0.34 -828.179 0.58 -828.616 0.11 -829.053 -0.11 -829.491 0.31 -829.928 0.29 -830.365 -0.22 -830.802 -0.13 -831.24 -0.57 -831.677 0.15 -832.114 -0.37 -832.551 0.02 -832.988 0.22 -833.425 0 -833.862 -0.45 -834.299 0.04 -834.736 -0.14 -835.173 -0.09 -835.61 -0.33 -836.047 -0.07 -836.484 0.19 -836.92 0.12 -837.357 -0.09 -837.794 0.35 -838.231 -0.31 -838.668 0.32 -839.104 -0.34 -839.541 0.2 -839.978 0.19 -840.414 -0.25 -840.851 0.1 -841.287 -0.17 -841.724 0.27 -842.16 -0.37 -842.597 -0.27 -843.033 0.3 -843.47 0.55 -843.906 -0.48 -844.342 -0.36 -844.779 -0.38 -845.215 0.66 -845.651 -0.55 -846.088 -0.36 -846.524 -0.03 -846.96 0.34 -847.396 -0.05 -847.832 -0.34 -848.269 0.24 -848.705 -0.71 -849.141 -0.21 -849.577 -0.03 -850.013 0.21 -850.449 -0.03 -850.885 0.08 -851.321 0.64 -851.757 0.68 -852.192 -0.3 -852.628 0.58 -853.064 0.36 -853.5 0.22 -853.936 -0.14 -854.372 0.25 -854.807 0.42 -855.243 0.23 -855.679 -0.06 -856.114 -0.38 -856.55 0.15 -856.985 0.29 -857.421 0.43 -857.857 0.48 -858.292 0.36 -858.728 0.72 -859.163 -0.12 -859.598 0.39 -860.034 0.59 -860.469 0.12 -860.905 -0.24 -861.34 0.9 -861.775 -0.12 -862.21 -0.55 -862.646 -0.24 -863.081 0.09 -863.516 0.62 -863.951 -0.84 -864.386 -0.25 -864.821 0.54 -865.257 0.06 -865.692 -0.03 -866.127 0.06 -866.562 -0.1 -866.997 0.46 -867.432 -0.36 -867.866 -0.3 -868.301 0.27 -868.736 0.48 -869.171 0.07 -869.606 0.03 -870.041 0.77 -870.475 -0.03 -870.91 -0.17 -871.345 0.44 -871.779 0.17 -872.214 -0.53 -872.649 0.14 -873.083 0.11 -873.518 0.04 -873.952 0.07 -874.387 -0.53 -874.821 -0.32 -875.256 -0.14 -875.69 -0.48 -876.125 -0.75 -876.559 0.11 -876.993 1.02 -877.428 -0.11 -877.862 0.22 -878.296 0.68 -878.731 -0.51 -879.165 0.43 -879.599 -1.17 -880.033 -0.11 -880.467 0.07 -880.901 0.56 -881.336 0.19 -881.77 0.8 -882.204 1.04 -882.638 -0.27 -883.072 -0.44 -883.506 0.08 -883.939 0.27 -884.373 0.2 -884.807 -0.12 -885.241 0.6 -885.675 0.28 -886.109 0.19 -886.542 0.87 -886.976 1.75 -887.41 -0.41 -887.844 0.72 -888.277 -0.61 -888.711 0.72 -889.144 0.04 -889.578 0.29 -890.012 0 -890.445 0.21 -890.879 -0.79 -891.312 0.21 -891.745 0.39 -892.179 0.34 -892.612 -0.92 -893.046 0.26 -893.479 0.9 -893.912 -0.49 -894.345 -0.31 -894.779 -0.39 -895.212 0.17 -895.645 0.84 -896.078 -0.18 -896.511 0 -896.945 0 -897.378 -0.09 -897.811 -0.91 -898.244 0.49 -898.677 0.19 -899.11 -0.8 -899.543 -0.09 -899.976 0.65 -900.409 -0.29 -900.841 -0.67 -901.274 -0.24 -901.707 1.15 -902.14 -0.5 -902.573 0.34 -903.005 0.5 -903.438 0.86 -903.871 -0.5 -904.303 -0.1 -904.736 -0.36 -905.169 0.71 -905.601 -0.62 -906.034 0.52 -906.466 -0.11 -906.899 0.89 -907.331 -0.46 -907.764 1.2 -908.196 0.05 -908.629 1.16 -909.061 0.16 -909.493 1.59 -909.926 1.5 -910.358 1.49 -910.79 -0.11 -911.222 2.14 -911.655 0.61 -912.087 -0.18 -912.519 -0.17 -912.951 0.53 -913.383 0.35 -913.815 -0.53 -914.247 -0.24 -914.679 2 -915.111 0.9 -915.543 -1.49 -915.975 -1.89 -916.407 0.55 -916.839 1 -917.271 -0.81 -917.703 -0.7 -918.134 0.19 -918.566 -0.82 -918.998 -0.58 -919.43 0.45 -919.861 0.06 -920.293 -0.13 -920.725 -0.39 -921.156 -0.26 -921.588 0.2 -922.019 0.07 -922.451 0.2 -922.882 0.49 -923.314 0 -923.745 -0.49 -924.177 0.42 -924.608 0.14 -925.039 0.63 -925.471 -3.04 -925.902 0.79 -926.333 -0.29 -926.765 0.52 -927.196 1.22 -927.627 0.36 -928.058 1.38 -928.489 1.27 -928.921 2.33 -929.352 -2.11 -929.783 -1.35 -930.214 -2.41 -930.645 0 -931.076 -0.77 -931.507 1.16 -931.938 1.15 -932.369 0.23 -932.8 -0.39 -933.23 0.16 -933.661 0.88 -934.092 1.68 -934.523 0.16 -934.954 0.41 -935.384 1.2 -935.815 -0.33 -936.246 0.81 -936.676 1.8 -937.107 -1.17 -937.538 -1.4 -937.968 1.54 -938.399 1.7 -938.829 -2.14 -939.26 -0.78 -939.69 -0.53 -940.121 -1.11 -940.551 -2.13 -940.981 0.61 -941.412 -1.23 -941.842 -0.44 -942.272 -0.45 -942.703 -2.33 -943.133 0.18 -943.563 -1.75 -943.993 -2.54 -944.423 0.27 -944.854 -0.85 -945.284 -1.04 -945.714 -0.47 -946.144 0.55 -946.574 0.58 -947.004 0.57 -947.434 1.08 -947.864 1.43 -948.294 0.6 -948.724 -0.42 -949.153 1.04 -949.583 0.82 -950.013 0.11 -950.443 0.11 -950.873 0.92 -951.302 1.37 -951.732 0.43 -952.162 -0.94 -952.591 -1.46 -953.021 2.59 -953.451 -2.59 -953.88 -1.14 -954.31 -0.23 -954.739 -0.12 -955.169 -2.41 -955.598 -1.05 -956.028 0.81 -956.457 -1.19 -956.886 -1.07 -957.316 2.25 -957.745 1.26 -958.174 0.63 -958.604 1.33 -959.033 -1.53 -959.462 -1.52 -959.891 -3.42 -960.321 0 -960.75 2.76 -961.179 3.52 -961.608 -2.31 -962.037 -2.28 -962.466 0.57 -962.895 0.14 -963.324 -0.96 -963.753 1.14 -964.182 0 -964.611 -0.43 -965.04 -4.87 -965.469 2.85 -965.897 -0.29 -966.326 -0.46 -966.755 -0.46 -967.184 2.18 -967.612 1.86 -968.041 -3.15 -968.47 -5.56 -968.898 1.3 -969.327 1.63 -969.756 3.69 -970.184 -0.5 -970.613 -0.16 -971.041 -3.54 -971.47 0.7 -971.898 -0.52 -972.327 1.9 -972.755 0.69 -973.183 -1.22 -973.612 -3.38 -974.04 3.44 -974.468 -2.12 -974.897 -1.66 -975.325 3.9 -975.753 1.33 -976.181 3.11 -976.609 0 -977.037 -2.63 -977.466 -0.81 -977.894 0.81 -978.322 -1.76 -978.75 0.19 -979.178 -0.98 -979.606 -1.1 -980.034 -3.35 -980.462 -1.11 -980.889 6.78 -981.317 -3.81 -981.745 -6.38 -982.173 -0.44 -982.601 1.75 -983.028 3.07 -983.456 3.13 -983.884 -2.93 -984.312 5.23 -984.739 0.25 -985.167 -0.24 -985.594 3.59 -986.022 3.31 -986.45 -7.18 -986.877 0.76 -987.305 0.26 -987.732 -6.62 -988.159 -5.36 -988.587 3.67 -989.014 1.57 -989.442 -2.17 -989.869 -6.23 -990.296 -2.88 -990.724 0.96 -991.151 -1.39 -991.578 -2.61 -992.005 0 -992.432 3.35 -992.859 -9.57 -993.287 4.06 -993.714 -0.94 -994.141 9.31 -994.568 -5.5 -994.995 4.01 -995.422 6.11 -995.849 10.28 -996.276 -0.35 -996.703 4.97 -997.129 2.86 -997.556 5.1 -997.983 0.34 -998.41 4.91 -998.837 4.97 -999.263 -1.38 -999.69 -3.33 -1000.117 -6.12 -1000.543 3.92 -1000.97 -9.06 -1001.397 -1.9 -1001.823 1.28 -1002.25 -2.51 -1002.676 -6.06 -1003.103 -1.61 -1003.529 -6.3 -1003.956 -1.49 -1004.382 0 -1004.809 0.36 -1005.235 3.54 -1005.661 6.18 -1006.088 -5.62 -1006.514 -1.94 -1006.94 -11.56 -1007.366 -3.57 -1007.793 -0.37 -1008.219 -7.33 -1008.645 -5.68 -1009.071 0.42 -1009.497 -11.95 -1009.923 4.68 -1010.349 2.5 -1010.775 4.38 -1011.201 -0.37 -1011.627 0.83 -1012.053 1.3 -1012.479 -6.09 -1012.905 -8.7 -1013.331 4.39 -1013.757 -2.78 -1014.182 -4.7 -1014.608 -5.59 -1015.034 2.86 -1015.46 7.87 -1015.885 2.81 -1016.311 14.54 -1016.737 2.86 -1017.162 1.02 -1017.588 -6.08 -1018.013 -10.6 -1018.439 5.79 -1018.865 3.54 -1019.29 -6.29 -1019.715 -6.88 -1020.141 1.56 -1020.566 -0.58 -1020.992 0.55 -1021.417 2.12 -1021.842 14.08 -1022.268 8.29 -1022.693 0.55 -1023.118 -13.02 -1023.543 4.47 -1023.969 -0.69 -1024.394 0 -1024.819 3.49 -1025.244 -3.87 -1025.669 -20.01 -1026.094 -7.1 -1026.519 7.23 -1026.944 3.64 -1027.369 9.1 -1027.794 7.98 -1028.219 11.93 -1028.644 15.23 -1029.069 -9.57 -1029.494 2.11 -1029.918 9.82 -1030.343 2.82 -1030.768 3.45 -1031.193 -7.7 -1031.617 13.55 -1032.042 -12.28 -1032.467 -13.25 -1032.891 9.24 -1033.316 0.84 -1033.741 -7.04 -1034.165 20.32 -1034.59 31.57 -1035.014 3.97 -1035.439 -6.09 -1035.863 12.65 -1036.288 3.28 -1036.712 2.02 -1037.136 3 -1037.561 -2.94 -1037.985 -6.86 -1038.409 9.1 -1038.834 3.37 -1039.258 12.76 -1039.682 12.08 -1040.106 32.3 -1040.53 -1.87 -1040.954 -24.08 -1041.379 3.85 -1041.803 -1.93 -1042.227 -20.24 -1042.651 15.72 -1043.075 17.92 -1043.499 -5.06 -1043.923 -10.36 -1044.346 -12.13 -1044.77 24.82 -1045.194 -21.95 -1045.618 3.58 -1046.042 16.51 -1046.466 -6.67 -1046.889 20.48 -1047.313 -6.99 -1047.737 15.57 -1048.16 12.78 -1048.584 -26.61 -1049.008 13.94 -1049.431 -13.27 -1049.855 4.12 -1050.278 10.99 -1050.702 20.35 -1051.125 21.65 -1051.549 -1.59 -1051.972 8.34 -1052.396 8.35 -1052.819 2.71 -1053.242 5.37 -1053.666 -20.87 -1054.089 13.2 -1054.512 8.08 -1054.936 -42.45 -1055.359 -22.08 -1055.782 -20.04 -1056.205 6.86 -1056.628 -56.12 -1057.051 -5.14 -1057.475 -5.18 -1057.898 -29.62 -1058.321 -37.82 -1058.744 -18.49 -1059.167 -1.39 -1059.59 -22.43 -1060.012 12.52 -1060.435 -2 -1060.858 17.13 -1061.281 -54.48 -1061.704 -23.87 -1062.127 -2.33 -1062.549 -8.36 -1062.972 8.35 -1063.395 -8.79 -1063.818 0 -1064.24 7.29 -1064.663 -12.27 -1065.086 -17.55 -1065.508 20.67 -1065.931 28.65 -1066.353 -75.74 -1066.776 -62.38 -1067.198 29.03 -1067.621 10.9 -1068.043 -6.16 -1068.465 -7.71 -1068.888 66.86 -1069.31 26.9 -1069.732 12.16 -1070.155 3.14 -1070.577 31.19 -1070.999 -55.31 -1071.421 27.58 -1071.844 0 -1072.266 50.94 -1072.688 -51.92 -1073.11 -12.3 -1073.532 12.16 -1073.954 -56.25 -1074.376 -34.18 -1074.798 27.11 -1075.22 66.89 -1075.642 43.03 -1076.064 -56.57 -1076.486 -16.73 -1076.908 10.76 -1077.33 40.22 -1077.751 342 -1078.173 50.2 -1078.595 40.15 -1079.017 -112.5 -1079.438 -3.35 -1079.86 14.62 -1080.282 42.49 -1080.703 -85.34 -1081.125 -35.5 -1081.546 79.79 -1081.968 -6.92 -1082.39 -192.86 -1082.811 7.16 -1083.232 -13.38 -1083.654 -86.17 -1084.075 -115.2 -1084.497 39.13 -1084.918 51.51 -1085.339 116.38 -1085.761 38.85 -1086.182 -132.17 -1086.603 37.67 -1087.024 -67.16 -1087.446 -194.78 -1087.867 105.88 -1088.288 60.45 -1088.709 -93.1 -1089.13 40.91 -1089.551 5.59 -1089.972 165.79 -1090.393 194.59 -1090.814 9.64 -1091.235 -135.85 -1091.656 120.9 -1092.077 229.09 -1092.498 22.66 -1092.919 89.74 -1093.34 -90 -1093.76 -8.74 -1094.181 -50.94 -1094.602 113.59 -1095.023 151.4 -1095.443 -110.2 -1095.864 267.57 -1096.285 165.31 -1096.705 -109.35 -1097.126 -100.8 -1097.546 52.43 -1097.967 104.85 -1098.387 -152.11 -1098.808 229.09 -1099.228 169.41 -1099.649 68.13 -1100.069 8.6 -1100.49 -36 -1100.91 18.27 -1101.33 201.72 -1101.751 60.34 -1102.171 33.54 -1102.591 13.71 -1103.011 -67.29 -1103.431 3.72 -1103.852 68.13 diff --git a/Modules/Biophotonics/python/iMC/msi/data/testMsi.nrrd b/Modules/Biophotonics/python/iMC/msi/data/testMsi.nrrd deleted file mode 100644 index 82708c6160..0000000000 Binary files a/Modules/Biophotonics/python/iMC/msi/data/testMsi.nrrd and /dev/null differ diff --git a/Modules/Biophotonics/python/iMC/msi/imgmani.py b/Modules/Biophotonics/python/iMC/msi/imgmani.py deleted file mode 100644 index ceb06a581b..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/imgmani.py +++ /dev/null @@ -1,66 +0,0 @@ -''' -Created on Aug 28, 2015 - -@author: wirkert -''' - -import numpy as np - - -def collapse_image(img): - """ helper method which transorms the n x m x nrWavelengths image to a - (n*m) x nrWavelength image. - - note that this function doesn't take an object of class Msi but - msi.get_image() """ - return img.reshape(-1, img.shape[-1]) - - -def remove_masked_elements(img): - """ helper method which removes masked pixels. - Note that by applying this method, the img loses it's shape.""" - collapsed_image = collapse_image(img) - # if one reflectance is masked msis are defined to have all refl. - # masked. Thus we can just have a look at the first column - one_column = collapsed_image[:, 0] - if (isinstance(one_column, np.ma.masked_array)): - masked_elems = np.where(one_column.mask) - collapsed_image = np.delete(collapsed_image, masked_elems, 0) - return collapsed_image - - -def select_n_reflectances(img, n): - """ randomly select n reflectances from image. - The output is of shape n x nr_wavelengths """ - collapsed_image = collapse_image(img) - perms = np.random.permutation(collapsed_image.shape[0]) - first_n_perms = perms[0:n] - return collapsed_image[first_n_perms, :] - - -def get_bands(img, bands): - """get the bands bands (np.array) from the multispectral image. - Example: image is 2048x2048x8. get_bands(img, [0,3] will return - img[:,:,[0,3]]. The advantage of this function is that the image does not - need to be 2d + wavelength.""" - original_shape = img.shape - collapsed_image = collapse_image(img) - img_bands = collapsed_image[ :, bands] - new_nr_bands = 1 - if hasattr(bands, "__len__"): - new_nr_bands = len(bands) - new_shape = original_shape[:-1] + (new_nr_bands,) - return np.reshape(img_bands, new_shape) - - -def sortout_bands(img, bands): - """delete bands bands (np.array) from the multispectral image. - Example: image is 2048x2048x8. sortout_bands(img, [0,3] will return - img[:,:,[1,2,4,5,6,7]]. The advantage of this function is that the image does not - need to be 2d + wavelength. - - TODO SW: Test""" - all_bands = np.arange(img.shape[-1]) - bands_to_get = np.setdiff1d(all_bands, bands) - return get_bands(img, bands_to_get) - diff --git a/Modules/Biophotonics/python/iMC/msi/io/__init__.py b/Modules/Biophotonics/python/iMC/msi/io/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/msi/io/msireader.py b/Modules/Biophotonics/python/iMC/msi/io/msireader.py deleted file mode 100644 index 6bb7413ad8..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/msireader.py +++ /dev/null @@ -1,22 +0,0 @@ -''' -Created on Aug 25, 2015 - -@author: wirkert -''' - -import pickle - -class MsiReader(object): - ''' - The MsiReader reads the Msi from the serialized python object. - This is the prefered way of reading an Msi. - ''' - - def __init__(self): - pass - - def read(self, filename_to_read): - msi_file = open(filename_to_read, 'r') - msi = pickle.load(msi_file) - msi_file.close() - return msi diff --git a/Modules/Biophotonics/python/iMC/msi/io/msiwriter.py b/Modules/Biophotonics/python/iMC/msi/io/msiwriter.py deleted file mode 100644 index 815c465a54..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/msiwriter.py +++ /dev/null @@ -1,25 +0,0 @@ -''' -Created on Aug 25, 2015 - -@author: wirkert -''' - -import pickle - -from writer import Writer - -class MsiWriter(Writer): - ''' - The MsiReader writing the Msi as a serialized python object. - ''' - - def __init__(self, msiToWrite): - """ - initialize the write with a specific multi spectral image (class Msi) - """ - self.msiToWrite = msiToWrite - - def write (self, uri): - f = open(uri, 'w') - pickle.dump(self.msiToWrite, f) - f.close() diff --git a/Modules/Biophotonics/python/iMC/msi/io/nrrdreader.py b/Modules/Biophotonics/python/iMC/msi/io/nrrdreader.py deleted file mode 100644 index 637ac7ab43..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/nrrdreader.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 10 16:29:20 2015 - -@author: wirkert -""" - -import logging -import numpy as np - -import SimpleITK as sitk - -from msi.io.reader import Reader -from msi.msi import Msi - - -class NrrdReader(Reader): - - def __init__(self): - pass - - def read(self, fileToRead): - """ read the nrrd image. - TODO: properties are not correctly extracted from nrrd.""" - - image = None - - try: - reader = sitk.ImageFileReader() - reader.SetFileName(fileToRead) - - image = reader.Execute() - image = sitk.GetArrayFromImage(image) - - except RuntimeError as re: - # image could not be read - logging.warning("image " + fileToRead + - " could not be loaded: " + - str(re)) - # rethrow exception after logging - raise - - # if image is too low dimensional singleton dimensions - # are added when saving. Done because sitk can only handle dimensions - # 2,3,4. This removes these singleton dimensions again. - squeezed_image = np.squeeze(image) - msi = Msi(squeezed_image) - return msi diff --git a/Modules/Biophotonics/python/iMC/msi/io/nrrdwriter.py b/Modules/Biophotonics/python/iMC/msi/io/nrrdwriter.py deleted file mode 100644 index a07694a0e0..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/nrrdwriter.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 13 09:48:18 2015 - -@author: wirkert -""" - -import logging -import numpy as np - -import SimpleITK as sitk - -from msi.io.writer import Writer - - -class NrrdWriter(Writer): - - def __init__(self, msiToWrite): - """ - initialize the write with a specific multi spectral image (class Msi) - """ - self.msiToWrite = msiToWrite - - def write(self, uri): - """ - write the msi image to the specified uri - """ - img_to_write = self.msiToWrite.get_image() - - # sitk can only write images of dimension 2,3,4. This hack is - # to fake 1d images as being 2d. 1d images e.g. occure after taking - # the mean of an image. - if len(img_to_write.shape) == 1: - img_to_write = np.reshape(img_to_write, (1, 1, img_to_write.shape[0])) - - img = sitk.GetImageFromArray(img_to_write, isVector=True) - sitk.WriteImage(img, uri) - logging.info("written file " + uri + " to disk") - return None diff --git a/Modules/Biophotonics/python/iMC/msi/io/pngreader.py b/Modules/Biophotonics/python/iMC/msi/io/pngreader.py deleted file mode 100644 index 48ee12e81e..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/pngreader.py +++ /dev/null @@ -1,58 +0,0 @@ -''' -Created on Sep 28, 2015 - -@author: wirkert -''' - - -import os -import itertools - -# PIL always rescales the image, thus PIL and skimage (which uses PIL) cannot -# be used -import png -import numpy as np - -from msi.io.reader import Reader -from msi.msi import Msi - - -class PngReader(Reader): - """ - Assumes bitdepth 16bit. - TODO SW: document and test""" - - def __init__(self): - pass - - - def read(self, fileToRead): - """ read the msi from pngs. - The fileToRead is a string prefix, all files starting with this - prefix will be summarized to one msi""" - - path, file_prefix = os.path.split(fileToRead) - files = os.listdir(path) - files_to_read = [os.path.join(path, f) for f in files - if f.startswith(file_prefix)] - files_to_read.sort() - image_array = [toImage(f) - for f in files_to_read] - image = reduce(lambda x, y: np.dstack((x, y)), image_array) - - msi = Msi(image) - return msi - - -def toImage(f): - reader = png.Reader(f) - column_count, row_count, pngdata, params = reader.asDirect() - plane_count = params['planes'] - image_2d = np.vstack(itertools.imap(np.uint16, pngdata)) - # this is needed for rgb images. probably better would be a mean in case - # we convert "real" rgb data. This is just for rgb images which - # contain the same values for r,g and b for every pixel. - image_3d = np.reshape(image_2d, - (row_count, column_count, plane_count)) - return image_3d[:, :, 0] - diff --git a/Modules/Biophotonics/python/iMC/msi/io/reader.py b/Modules/Biophotonics/python/iMC/msi/io/reader.py deleted file mode 100644 index 99d6b678c3..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/reader.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 7 13:39:16 2015 - -@author: wirkert -""" - - -class Reader: - """ - Abstract reader base class - """ - - def __init__(self): - pass - - def read(self, fileToRead): - return None - diff --git a/Modules/Biophotonics/python/iMC/msi/io/spectrometerreader.py b/Modules/Biophotonics/python/iMC/msi/io/spectrometerreader.py deleted file mode 100644 index b182201d7a..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/spectrometerreader.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 7 12:04:18 2015 - -@author: wirkert -""" - -import numpy as np -from msi.io.reader import Reader -from msi.msi import Msi - - -class SpectrometerReader(Reader): - - def __init__(self): - pass - - def read(self, file_to_read): - # our spectrometer like to follow german standards in files, we need - # to switch to english ones - transformed="" - replacements = {',': '.', '\r\n': ''} - with open(file_to_read) as infile: - for line in infile: - for src, target in replacements.iteritems(): - line = line.replace(src, target) - transformed = "\n".join([transformed, line]) - - for num, line in enumerate(transformed.splitlines(), 1): - if ">>>>>Begin" in line: - break - - for num_end, line in enumerate(transformed.splitlines(), 1): - if ">>>>>End" in line: - num_end -= 1 - break - string_only_spectrum = "\n".join(transformed.splitlines()[num:num_end]) - data_vector = np.fromstring(string_only_spectrum, - sep="\t").reshape(-1, 2) - msi = Msi(data_vector[:, 1], - {'wavelengths': data_vector[:, 0] * 10 ** -9}) - return msi - diff --git a/Modules/Biophotonics/python/iMC/msi/io/tiffreader.py b/Modules/Biophotonics/python/iMC/msi/io/tiffreader.py deleted file mode 100644 index fdc7bae5fb..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/tiffreader.py +++ /dev/null @@ -1,100 +0,0 @@ -''' -Created on Sep 28, 2015 - -@author: wirkert -''' - - -import os - -import Image -import scipy -import numpy as np - -from msi.io.reader import Reader -from msi.msi import Msi - - -def sort_by_filter(s1, s2): - ''' - Sorting function which takes two strings and sorts them lexigraphically by - the last character before the file extension. - - say: - - blabla_w2_F0.tiff < blabla_w0_F1.tiff - - This is done to sort by the filter index, which is always written as the - last thing by the tiff writer. - ''' - s1_prefix = os.path.splitext(s1)[0] - s2_prefix = os.path.splitext(s2)[0] - - result = 0 - if s1_prefix < s2_prefix: - result = 1 - elif s1_prefix > s2_prefix: - result = -1 - - return result - - -class TiffReader(Reader): - """ - AAATTTEEENTION: Some big bug hiding somewhere here, ordering of files - is corrupted, no time now to fix. TODO SW - - Assumes bitdepth 16bit on a 12bit camera. - TODO SW: document and test""" - - # static member to globally set resizing for all images read by the reader - # 1.0 for no resizing - RESIZE_FACTOR = 1.0 - - def __init__(self, shift_bits=4): - self.shift_bits = shift_bits - - def read(self, file_to_read, resize_factor=None, - sorting_function=sort_by_filter): - """ read the msi from tiffs. - The fileToRead is a string prefix, all files starting with this - prefix will be summarized to one msi. they will be sorted as specified - in the sorting_function - - Args: - sorting_function: the function which defines the sorting of the - strings that match the prefix. Pass none if normal - lexicographical sorting is wished - file_to_read: the prefix of the tiff file which shall be read - """ - - if resize_factor is None: - resize_factor = TiffReader.RESIZE_FACTOR - - path, file_prefix = os.path.split(file_to_read) - files = os.listdir(path) - files_to_read = [os.path.join(path, f) for f in files - if file_prefix[2:] in f] - files_to_read.sort(cmp=sorting_function) - image_array = [self.to_image(f, resize_factor=resize_factor) - for f in files_to_read] - image = reduce(lambda x, y: np.dstack((x, y)), image_array) - - msi = Msi(image) - return msi - - def to_image(self, f, resize_factor): - im = Image.open(f) - im_array = np.array(im) - - im_array >>= self.shift_bits - - if do_resize(resize_factor): - im_array = scipy.misc.imresize(im_array, resize_factor, - interp="bilinear", mode="F") - - return im_array.astype('float') - - -def do_resize(resize_factor): - return not np.isclose(resize_factor, 1.0) and (resize_factor is not None) diff --git a/Modules/Biophotonics/python/iMC/msi/io/tiffringreader.py b/Modules/Biophotonics/python/iMC/msi/io/tiffringreader.py deleted file mode 100644 index b0bf6177b9..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/tiffringreader.py +++ /dev/null @@ -1,100 +0,0 @@ -''' -Created on Nov 2, 2015 - -@author: wirkert -''' - -import os -import logging - -import Image -import scipy -import numpy as np - -from msi.io.reader import Reader -from msi.msi import Msi - - -class TiffRingReader(Reader): - ''' - TODO SW: document and test - ''' - - # static member to globally set resizing for all images read by the reader - # 1.0 for no resizing - RESIZE_FACTOR = 1.0 - - def __init__(self, shift_bits=4): - self.shift_bits = shift_bits - - def read(self, fileToRead, n, resize_factor=None, - segmentation=None): - """ read the msi from tiffs. - The fileToRead is the first file to read, - then n files will be read to one msi from a - sorted file list - - segmentation: tiff filename of the segmentation. If none, it will be - tried to get a segmentation from npy files with filenames like the - tiff files + _seg.tiff. If this fails, no segmentation will be - assumed - """ - - if resize_factor is None: - resize_factor = TiffRingReader.RESIZE_FACTOR - - path, file_name = os.path.split(fileToRead) - files = os.listdir(path) - files_in_folder = [os.path.join(path, f) for f in files if - os.path.isfile(os.path.join(path, f)) and - f.endswith('.tiff')] - - files_in_folder.sort() - position = files_in_folder.index(fileToRead) - # take n images from found position - image_array = [self.to_image(f, resize_factor) - for f in files_in_folder[position:position + n]] - image = reduce(lambda x, y: np.dstack((x, y)), image_array) - - # in case of 1 dimensional image: add a fake last dimension, since - # we always assume the last dimension to be the wavelength domain. - # TODO SW: Test this and implement for other readers - if n is 1: - image = np.expand_dims(image, -1) - - msi = Msi(image) - - # we pass an explicic image as segmentation - if segmentation is not None: - segmentation = self.to_image(segmentation, resize_factor) - else: # otherwise: search for numpy segmentations - try: - segmentation_array = [to_segmentation(f) - for f in - files_in_folder[position:position + n]] - if do_resize(resize_factor): - segmentation = reduce(lambda x, y: x & y, segmentation_array) - segmentation = scipy.misc.imresize(segmentation, resize_factor, - interp="bilinear") - except: - logging.info("didn't find segmentation for all images") - return msi, segmentation - - def to_image(self, f, resize_factor): - im = Image.open(f) - im_array = np.array(im) - im_array >>= self.shift_bits - - if do_resize(resize_factor): - im_array= scipy.misc.imresize(im_array, resize_factor, - interp="bilinear", mode="F") - return im_array.astype('float') - - -def to_segmentation(f): - seg = np.load(f + ".seg.npy") - return seg - - -def do_resize(resize_factor): - return not np.isclose(resize_factor, 1.0) and (resize_factor is not None) diff --git a/Modules/Biophotonics/python/iMC/msi/io/tiffwriter.py b/Modules/Biophotonics/python/iMC/msi/io/tiffwriter.py deleted file mode 100644 index 36506aa850..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/tiffwriter.py +++ /dev/null @@ -1,72 +0,0 @@ - - -import logging - -import numpy as np -from libtiff import TIFF - -from msi.io.writer import Writer - - -class TiffWriter(Writer): - """ - The tiff write will store nr_wavelength tiff files for one msi - """ - - def __init__(self, msi_to_write, convert_to_nm=True, scale_to_16_bit=False): - """ - initialize the write with a specific multi spectral image (class Msi) - """ - self.msi_to_write = msi_to_write - self.convert_to_nm = convert_to_nm - self.scale_to_16_bit = scale_to_16_bit - - def write(self, uri_prefix): - """ - write the msi image to the specified uri_prefix - - Args: - uri_prefix: the prefix off the uri. E.g. C:\example the image - write will automatically extend this prefix path to include the - wavelengths information and add a suffix. Your final - file may look similar to: C:\example_w_470nm_F0.tiff - convert_to_nm: if the wavelengths are saved in m they are hard to - write as string. Thus they can be automatically expanded to nm. - """ - img_to_write = self.msi_to_write.get_image() - - max_image_value = np.max(img_to_write) - - if self.scale_to_16_bit: - img_to_write *= 2**16 / max_image_value - - nr_wavelengths = self.msi_to_write.get_wavelengths().size - for wavelength_index in np.arange(nr_wavelengths): - full_uri = self._build_full_uri(uri_prefix, wavelength_index) - self._write_single_image(full_uri, - img_to_write[:, :, wavelength_index]) - - logging.info("written file " + full_uri + " to disk") - return None - - @staticmethod - def _write_single_image(full_uri, image_array): - """ - internally used method to write single tiff image - """ - tiff = TIFF.open(full_uri, mode='w') - tiff.write_image(image_array.astype('uint16'), write_rgb=False) - tiff.close() - - def _build_full_uri(self, uri_prefix, wavelength_index): - """ - Helper method to build full path of one image - Returns: full uri containing the desired properties. - """ - wavelength = self.msi_to_write.get_wavelengths()[wavelength_index] - if self.convert_to_nm: - wavelength *= 10**9 - full_uri = uri_prefix + "_w_" + str(wavelength) +\ - "_F" + str(wavelength_index) + ".tiff" - - return full_uri diff --git a/Modules/Biophotonics/python/iMC/msi/io/writer.py b/Modules/Biophotonics/python/iMC/msi/io/writer.py deleted file mode 100644 index 9342ff00fe..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/io/writer.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 13 09:47:31 2015 - -@author: wirkert -""" - - -class Writer(): - """ - Abstract writer base class - """ - - def __init__(self): - pass - - def write(self, fileToWrite): - return None \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/msi/msi.py b/Modules/Biophotonics/python/iMC/msi/msi.py deleted file mode 100644 index 5638d44ad7..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/msi.py +++ /dev/null @@ -1,128 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 6 18:21:36 2015 - -@author: wirkert -""" - -import numpy as np - - -class Msi(): - """ a multi spectral image stack consisting of: - - image: a rows x columns x nrWavelengths dimensional array - properties: additional, application dependent properties - """ - - def __init__(self, image=None, properties=None): - if image is None: - image = np.array([]) - if properties is None: - properties = {} - self._image = image - self._properties = properties - self._assure_basic_properties() - - self._test_image() - - def get_image(self): - return self._image - - def set_image(self, image, wavelengths=None): - """ - Put a new image into this msi - Args: - image: the rows x columns x nrWavelengths dimensional array - np.array. - wavelengths: a np.array of size nrWavelengths. If the number of - wavelengths hasn't change this is not needed. - """ - self._image = image - if wavelengths is not None: - self.set_wavelengths(wavelengths) - self._assure_basic_properties() - self._test_image() - - def get_wavelengths(self): - """ shortcut to get the wavelengths property - The wavelengths are given in [m] units and need not be sorted. """ - if 'wavelengths' not in self.get_properties(): - return None - return self._properties['wavelengths'] - - def set_wavelengths(self, wavelengths): - """ shortcut to set the wavelengths property """ - w_prop = {"wavelengths":wavelengths} - self.add_property(w_prop) - self._test_image() - - def get_properties(self): - return self._properties - - def add_property(self, newProperty): - """ add a new property(ies) to the existing properties """ - self._properties.update(newProperty) - self._test_image() - - def set_mask(self, mask): - """" applies a masked to the Msi. After this call, the image is of - type MaskedArray. If the image was already masked, the existing - masked will be "or ed" with the new mask. mask is a boolean array of - the same shape as self.get_image() - - Args: - mask: a mask of the same size as the image. 1s stand for pixels - masked out, 0s for pixels not masked.""" - if not isinstance(self.get_image(), np.ma.MaskedArray): - self.set_image(np.ma.masked_array(self.get_image(), mask, - fill_value=999999)) - else: - self.get_image()[mask] = np.ma.masked - - def __eq__(self, other): - """ - overrite the == operator - Two Msi s are the same if they contain the same image and properties. - Note: properties not implemented yet! - """ - if isinstance(other, Msi): - samesame = np.array_equal(other.get_image(), self.get_image()) - return samesame - return NotImplemented - - def __ne__(self, other): - """ != operator implemented by inverting to ==""" - result = self.__eq__(other) - if result is NotImplemented: - return result - return not result - - def _assure_basic_properties(self): - """ - helper method to automatically add the basic properties: - wavelength - to the msi if not added explicicly. basic wavelengths will just be - integers from 0 to 1 - """ - if self._image.size > 0 and ( - ("wavelengths" not in self._properties.keys() or - self._properties["wavelengths"].size == 0)): - self._properties["wavelengths"] = np.arange(self._image.shape[-1]) - if self._image.size == 0 and "wavelengths" not in self._properties.keys(): - self._properties["wavelengths"] = np.array([]) - - def _test_image(self): - """ - helper method which tests for the integrity of the msi. - E.g. the number of wavelengths must match the number of bands. - """ - # either both image and wavelength property are empty - if self._image.size == 0 and len(self._properties["wavelengths"]) != 0: - raise RuntimeError("dimension of image and wavelength mismatch: " + - "image size is zero, but wavelengths are set") - # or both are same - elif self._image.shape[-1] != len(self._properties["wavelengths"]): - raise RuntimeError("dimension of image and wavelength mismatch: " + - "image size and wavelenths do not match") - diff --git a/Modules/Biophotonics/python/iMC/msi/msimanipulations.py b/Modules/Biophotonics/python/iMC/msi/msimanipulations.py deleted file mode 100644 index 9169fa35c1..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/msimanipulations.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 13 13:42:00 2015 - -@author: wirkert -""" - -import logging -import copy -import numpy as np - -from scipy.interpolate import interp1d - -from imgmani import collapse_image -import imgmani -from msi import Msi - - -''' -The msi manipulations module includes usefull convenience operations on msis. - -E.g. calculate_mean_spectrum to calculate the average spectrum on all the image -data or interpolate_wavelengths to change to a different wavelenght set by -simple interpolation. - -All methods take a msi and change it in place. They also return the same msi -object for convenience (can e.g. be used to chain msi manipulations). -''' - - -def apply_segmentation(msi, segmentation): - """ applies a segmentation to an msi. - - If the msi has imaging data of n x m x nr_wavelengths the segmentation - has to be a numpy array of n x m size. pixelvalues with values different - than zero will be included in the segmentation. - By applying the segmentation, not segmented elements will be np.ma.masked. - - Alternatively, one can input a msi with the mentioned n x m numpy array - in from of a msi as segmentation (for convenience to be able to use the - same reader for msis and segmentations) - """ - if (isinstance(segmentation, Msi)): - # expects just an image, but if a Msi is passed it's also ok - segmentation = segmentation.get_image() - segmentation = np.squeeze(segmentation) - mask = (0 == segmentation) - # mask needs to be expanded to cover all wavlengths - wholeMask = np.zeros_like(msi.get_image(), dtype="bool") - # doesn't seem elegant - for i in range(wholeMask.shape[-1]): - wholeMask[:, :, i] = mask - - msi.set_mask(wholeMask) - return msi - - -def calculate_mean_spectrum(msi): - """ reduce this image to only its mean spectrum. - If the msi.get_image() is a masked array these values will be ignored when - calculating the mean spectrum """ - # reshape to collapse all but last dimension (which contains reflectances) - collapsedImage = collapse_image(msi.get_image()) - msi.set_image(np.mean(collapsedImage, axis=0)) - # returns the same msi. - return msi - - -def interpolate_wavelengths(msi, newWavelengths): - """ interpolate image data to fit newWavelengths. Current implementation - performs simple linear interpolation. Neither existing nor new wavelengths - need to be sorted. """ - interpolator = interp1d(msi.get_wavelengths(), msi.get_image(), assume_sorted=False) - msi.set_image(interpolator(newWavelengths), wavelengths=newWavelengths) - return msi - - -def normalize_integration_times(msi): - """ divides by integration times """ - if ('integration times' not in msi.get_properties()): - logging.warn("warning: trying to normalize integration times for " - "image without the integration time property") - return msi - - original_shape = msi.get_image().shape - collapsed_image = collapse_image(msi.get_image()) - collapsed_image = collapsed_image / msi.get_properties()['integration times'] - msi.set_image(collapsed_image.reshape(original_shape)) - - msi.add_property({'integration times': - np.ones_like(msi.get_properties()['integration times'])}) - return msi - - -def dark_correction(msi, dark): - """" subtract dark current from multi spectral image. - - The dark msi should either be of the same shape - as msi or 1xnr_wavelengths (see tests).""" - msi.set_image(msi.get_image() - dark.get_image()) - return msi - - -def flatfield_correction(msi, flatfield): - """ divide by flatfield to remove dependencies on light source form and - imaging system. - - The flatfield msi should either be of the same shape - as msi or 1xnr_wavelengths (see tests).""" - # we copy the flatfield to ensure it is unchanged by the normalization - flatfield_copy = copy.copy(flatfield) - normalize_integration_times(flatfield_copy) - normalize_integration_times(msi) - - msi.set_image(msi.get_image() / flatfield_copy.get_image()) - return msi - - -def image_correction(msi, flatfield, dark): - """ do the usual image correction: - msi = ((msi - dark) / integration_time) / ((flatfield - dark) / integration_time) - this function changes only the msi, flatfield and dark image - are left unchanged. - """ - # we need a copy of flatfield since otherwise the dark correction - # changes the flatfield - dark_correction(msi, dark) - flatfield_copy = copy.copy(flatfield) - dark_correction(flatfield_copy, dark) - flatfield_correction(msi, flatfield_copy) - return msi - - -def get_bands(msi, bands): - """ - TODO SW: document and test - """ - msi.set_image(imgmani.get_bands(msi.get_image(), bands)) - if msi.get_wavelengths() is not None: - msi.set_wavelengths(msi.get_wavelengths()[bands]) - return msi - diff --git a/Modules/Biophotonics/python/iMC/msi/normalize.py b/Modules/Biophotonics/python/iMC/msi/normalize.py deleted file mode 100644 index 880bbffed4..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/normalize.py +++ /dev/null @@ -1,53 +0,0 @@ - -import numpy as np -from sklearn.preprocessing import Normalizer - - -from imgmani import collapse_image - - -class Normalize(): - - def __init__(self): - pass - - def normalize(self, msi): - pass - - -class NormalizeIQ(Normalize): - """Normalize by image quotient""" - def __init__(self, iqBand=None): - if iqBand is None: - iqBand = 0 - self.iqBand = iqBand - - def normalize(self, msi): - # todo: guard if iqBand is outside of image dimension - original_shape = msi.get_image().shape - collapsed_image = collapse_image(msi.get_image()) - iqDimension = collapsed_image[ :, self.iqBand] - normalized_image = collapsed_image / iqDimension[:, None] - msi.set_image(np.reshape(normalized_image, original_shape)) - - -class NormalizeMean(Normalize): - """Normalize by image mean""" - def __init__(self): - pass - - def normalize(self, msi, norm="l1"): - original_shape = msi.get_image().shape - collapsed_image = collapse_image(msi.get_image()) - # temporarily save mask, since scipy normalizer removes mask - is_masked_array = isinstance(msi.get_image(), np.ma.MaskedArray) - if is_masked_array: - mask = msi.get_image().mask - normalizer = Normalizer(norm=norm) - normalized_image = normalizer.transform(collapsed_image) - if is_masked_array: - normalized_image = np.ma.MaskedArray(normalized_image, mask=mask) - msi.set_image(np.reshape(normalized_image, original_shape)) - - -standard_normalizer = NormalizeMean() diff --git a/Modules/Biophotonics/python/iMC/msi/plot.py b/Modules/Biophotonics/python/iMC/msi/plot.py deleted file mode 100644 index 0ae653b2ce..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/plot.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 13 11:13:31 2015 - -@author: wirkert -""" - -import copy -import logging - -import numpy as np -import matplotlib.pyplot as plt -from mpl_toolkits.axes_grid1 import make_axes_locatable - -import imgmani -import msimanipulations as msimani - -def plot(msi, axes=None, color=None): - """ - create a plot for the Msi with x axes being the wavelengths and - y-axes being the corresponding image values (e.g. reflectances, absorptions) - Takes image masks into account: - doesn't plot a spectrum containing masked elements - """ - if axes is None: - axes = plt.gca() - - sortedIndices = sorted(range(len(msi.get_wavelengths())), - key=lambda k: msi.get_wavelengths()[k]) - sortedWavelenghts = msi.get_wavelengths()[sortedIndices] - # reshape to collapse all but last dimension (which contains reflectances) - collapsedImage = imgmani.collapse_image(msi.get_image()) - # todo: simply use np.ma.compress_rows - - # print "filtered ", filteredImage.shape - i = 0 - for i in range(collapsedImage.shape[0]): - if (collapsedImage[i, 0] is not np.ma.masked): - axes.plot(sortedWavelenghts, - collapsedImage[i, :][sortedIndices], "-o", color=color) - - -def plot_images(msi): - """plot the images as a 2d image array, one image for - each wavelength.""" - nr_wavelengths = msi.get_image().shape[-1] - f, axarr = plt.subplots(1, nr_wavelengths) - for i, a in enumerate(axarr): - one_band_image = imgmani.get_bands(msi.get_image(), i) - im = a.imshow(np.squeeze(one_band_image)) - a.set_title("band nr " + str(i), fontsize=5) - divider_dsp = make_axes_locatable(a) - cax_dsp = divider_dsp.append_axes("right", size="10%", pad=0.1) - cbar = plt.colorbar(im, cax=cax_dsp) - cbar.ax.tick_params(labelsize=5) - a.xaxis.set_visible(False) - a.yaxis.set_visible(False) - - -def plotMeanError(msi, axes=None): - """ - create a plot for the Msi with x axes being the wavelengths and - y-axes being the corresponding mean image values - (e.g. reflectances, absorptions). Plots also standard deviation bands - Takes image masks into account: - doesn't plot a spectrum containing masked elements - """ - if axes is None: - axes = plt.gca() - # sort the wavelengths - sortedIndices = sorted(range(len(msi.get_wavelengths())), - key=lambda k: msi.get_wavelengths()[k]) - sortedWavelenghts = msi.get_wavelengths()[sortedIndices] - # copy the msi, since it will be altered (mean will be built) - msi_copy = copy.deepcopy(msi) - image = msi_copy.get_image() - image = imgmani.collapse_image(image) - std_curve = np.ma.std(image, axis=0) - msimani.calculate_mean_spectrum(msi_copy) - # calculate std - logging.info("percentual std: " + - str(std_curve / msi_copy.get_image() * 100.)) - # plot as errorbar - axes.errorbar(sortedWavelenghts, msi_copy.get_image()[sortedIndices], - yerr=std_curve, fmt='-o') diff --git a/Modules/Biophotonics/python/iMC/msi/test/__init__.py b/Modules/Biophotonics/python/iMC/msi/test/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/msi/test/helpers.py b/Modules/Biophotonics/python/iMC/msi/test/helpers.py deleted file mode 100644 index 4565f7e63a..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/helpers.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 13 09:53:52 2015 - -@author: wirkert -""" - -import numpy as np -from msi.msi import Msi - - -def getFakeMsi(): - - # build a fake multispectral image with 5 dimensions. - image = np.concatenate((np.ones((5, 5, 1)), - np.ones((5, 5, 1)) * 2, - np.ones((5, 5, 1)) * 3, - np.ones((5, 5, 1)) * 4, - np.ones((5, 5, 1)) * 5), - axis=-1) - msi = Msi(image) - - msi.set_wavelengths(np.array([5, 4, 3, 2, 1])) - - return msi diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_imgmani.py b/Modules/Biophotonics/python/iMC/msi/test/test_imgmani.py deleted file mode 100644 index c6960958ca..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_imgmani.py +++ /dev/null @@ -1,96 +0,0 @@ -''' -Created on Aug 28, 2015 - -@author: wirkert -''' -import unittest -import numpy as np - -import msi.msimanipulations as msimani -import msi.imgmani as imgmani -import msi.test.helpers as helpers -from msi.imgmani import remove_masked_elements, select_n_reflectances - - -class TestImgMani(unittest.TestCase): - - def setUp(self): - self.msi = helpers.getFakeMsi() - # set one pixel to special values - self.specialValue = np.arange(self.msi.get_image().shape[-1]) * 2 - self.msi.get_image()[2, 2, :] = self.specialValue - # create a segmentation which sets all elements to invalid but the - # one pixel with the special value - self.segmentation = np.zeros(self.msi.get_image().shape[0:-1]) - self.segmentation[2, 2] = 1 - # apply this segmentation to the msi - msimani.apply_segmentation(self.msi, self.segmentation) - self.image = self.msi.get_image() - - def tearDown(self): - self.msi = None - self.specialValue = None - self.segmentation = None - self.image = None - - def test_collapse_image(self): - image = self.image - newShapedImage = imgmani.collapse_image(image) - - self.assertEqual(newShapedImage.shape, - (image.shape[0] * image.shape[1], image.shape[2]), - "collapsed image has correct shape") - np.testing.assert_equal(newShapedImage[2 * 5 + 2, :], - self.msi.get_image()[2, 2, :], - "values have been correctly transformed") - - def test_collapse_image_retains_data(self): - newShapedImage = imgmani.collapse_image(self.image) - self.msi.get_image()[2, 2, 0] = 5000. - - self.assertEqual(newShapedImage[2 * 5 + 2, 0], 5000., - "collapse_image does not copy data") - - def test_remove_masked_elements(self): - value = self.msi.get_image()[2, 2, :] - image_without_masked = remove_masked_elements(self.image) - np.testing.assert_array_equal(image_without_masked[0, :], value, - "mask correctly removed") - self.assertEqual(image_without_masked.shape, - (1, self.image.shape[-1]), - "shape of image without mask correct") - - def test_select_n_reflectances_selects(self): - n = 10 - new_image = select_n_reflectances(self.image, n) - self.assertEqual(new_image.shape, (n, self.image.shape[-1]), - "correct shape after selection") - - def test_select_n_reflectances_permutes(self): - image_shape = self.image.shape - new_first_layer = np.random.random_sample(image_shape[0:-1]) - self.image[:, :, 0] = new_first_layer - shuffled_image = select_n_reflectances(self.image, - image_shape[0] * image_shape[1]) - # restore_shape - shuffled_image = np.reshape(shuffled_image, image_shape) - self.assertFalse(np.allclose(shuffled_image[:, :, 0], - new_first_layer), - "image has been shuffled") - - def test_get_bands_from_int(self): - new_image_bands = imgmani.get_bands(self.image, 2) - self.assertEqual(new_image_bands.shape, (5, 5, 1), - "new image has correct shape") - self.assertEqual(new_image_bands[2, 2, :], self.specialValue[2], - "new image has correct values") - - def test_get_bands_from_array(self): - new_image_bands = imgmani.get_bands(self.image, np.array([0, 1, 2])) - self.assertEqual(new_image_bands.shape, (5, 5, 3), - "new image has correct shape") - np.testing.assert_allclose(new_image_bands[2, 2, :], - self.specialValue[:3], - err_msg="new image has correct values") - - diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_msi.py b/Modules/Biophotonics/python/iMC/msi/test/test_msi.py deleted file mode 100644 index 128a0691df..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_msi.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Mar 27 19:12:40 2015 - -@author: wirkert -""" - -import unittest -import numpy as np - -from msi.msi import Msi -from msi.test import helpers - - -class TestMsi(unittest.TestCase): - - def setUp(self): - self.msi = helpers.getFakeMsi() - - def tearDown(self): - pass - - def test_create(self): - self.assertTrue(True, "Created msi during setup") - - def test_add_property(self): - self.msi.add_property({'test':np.array([1, 2, 3])}) - self.assertTrue(np.array_equal(self.msi.get_properties()['test'], - np.array([1, 2, 3])), "property successfully added to msi") - - def test_properties_not_shared(self): - msi1 = Msi() - msi2 = Msi() - msi1.add_property({"integration time": np.array([1, 2, 3])}) - - self.assertTrue('integration time' not in msi2.get_properties()) - - def test_add_dummy_wavelengths_automatically(self): - msi_no_wavelengths_set = Msi() - msi_no_wavelengths_set.set_image(self.msi.get_image()) - - nr_wavelengths = msi_no_wavelengths_set.get_image().shape[-1] - - np.testing.assert_equal(msi_no_wavelengths_set.get_wavelengths(), - np.arange(nr_wavelengths), - "correct dummy wavelength values set") - - - - diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_msimanipulations.py b/Modules/Biophotonics/python/iMC/msi/test/test_msimanipulations.py deleted file mode 100644 index 9b895a6cf4..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_msimanipulations.py +++ /dev/null @@ -1,203 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 13 13:52:23 2015 - -@author: wirkert -""" - - -import unittest -import copy -import numpy as np - -from msi.test import helpers -import msi.msimanipulations as mani - - -class TestMsiManipulations(unittest.TestCase): - - def setUp(self): - self.msi = helpers.getFakeMsi() - self.specialmsi = helpers.getFakeMsi() - - # set one pixel to special values - self.specialValue = np.arange(self.specialmsi.get_image().shape[-1]) * 2 - self.specialmsi.get_image()[2, 2, :] = self.specialValue - - # create a segmentation which sets all elements to invalid but the - # one pixel with the special value - self.segmentation = np.zeros(self.specialmsi.get_image().shape[0:-1]) - self.segmentation[2, 2] = 1 - - def tearDown(self): - pass - - def test_apply_segmentation(self): - - mani.apply_segmentation(self.specialmsi, self.segmentation) - - validImageEntries = self.specialmsi.get_image() \ - [~self.specialmsi.get_image().mask] - - np.testing.assert_equal(validImageEntries, self.specialValue, - "image has been correctly segmented") - - def test_calculate_mean_spectrum(self): - - mani.calculate_mean_spectrum(self.specialmsi) - - np.testing.assert_equal(np.array([0.96, 2., 3.04, 4.08, 5.12]), - self.specialmsi.get_image(), - "mean spectrum is correctly calculated on image with " + - "no mask applied") - - def test_calculate_mean_spectrum_masked_image(self): - - mani.apply_segmentation(self.specialmsi, self.segmentation) - mani.calculate_mean_spectrum(self.specialmsi) - - np.testing.assert_equal(self.specialValue, self.specialmsi.get_image(), - "mean spectrum is correctly calculated on image with " + - "mask applied") - - def test_interpolate(self): - # create not sorted new wavelengths - newWavelengths = np.array([4.0, 2.5, 3.5, 1.5]) - mani.interpolate_wavelengths(self.msi, newWavelengths) - - np.testing.assert_equal(newWavelengths, self.msi.get_wavelengths(), - "wavelengths correctly updated") - # check if first image pixel was correctly calculated - # (hopefully true for all then) - np.testing.assert_equal(np.array([2.0, 3.5, 2.5, 4.5]), - self.msi.get_image()[0, 0, :], - "image elements correctly interpolated") - - def test_normalize_integration_times(self): - old_shape = self.msi.get_image().shape - integration_times = np.array([1., 2., 3., 4., 5.]) - self.msi.add_property({'integration times': integration_times}) - mani.normalize_integration_times(self.msi) - - np.testing.assert_equal(self.msi.get_image()[1, 3, :], - np.ones_like(integration_times), - "normalized integration times") - np.testing.assert_equal(self.msi.get_properties()['integration times'], - np.ones_like(integration_times), - "integration time property set to ones") - self.assertEqual(self.msi.get_image().shape, old_shape, - "shape did not change from normalizing") - - def test_normalize_integration_times_none_given(self): - msi_copy = copy.deepcopy(self.msi) - mani.normalize_integration_times(msi_copy) - np.testing.assert_equal(msi_copy.get_image(), self.msi.get_image(), - "nothing change by normalizing without" + \ - "integration times given") - - def test_dark_correction(self): - desired_image_data = copy.copy(self.msi.get_image()) - desired_image_data -= 1 - - dark = copy.copy(self.msi) - dark.set_image(np.ones_like(dark.get_image())) - - mani.dark_correction(self.msi, dark) - - np.testing.assert_equal(self.msi.get_image(), - desired_image_data, - "dark image correctly accounted for") - np.testing.assert_equal(dark.get_image(), - np.ones_like(dark.get_image()), - "dark image unchanged by dark correction") - - def test_dark_correction_with_single_value(self): - desired_image_data = copy.copy(self.specialmsi.get_image()) - desired_image_data -= 1 - - dark = copy.copy(self.specialmsi) - dark.set_image(np.ones_like(dark.get_image())) - mani.calculate_mean_spectrum(dark) - - mani.dark_correction(self.specialmsi, dark) - - np.testing.assert_equal(self.specialmsi.get_image(), - desired_image_data, - "dark image correctly accounted for from singular dark value") - np.testing.assert_equal(dark.get_image(), - np.ones_like(dark.get_image()), - "dark image unchanged by dark correction") - - def test_flatfield_correction(self): - desired_image_data = np.ones_like(self.specialmsi.get_image()) - desired_image_data[2, 2, 0] = np.nan - - mani.flatfield_correction(self.specialmsi, self.specialmsi) - - np.testing.assert_equal(self.specialmsi.get_image(), - desired_image_data, - "correct image by itself should lead to only 1s ") - - def test_flatfield_correction_differing_integration_times(self): - MSI_INTEGRATION_TIME = 3.0 - FLATFIELD_INTEGRATION_TIME = 2.0 - desired_image_data = np.ones_like(self.specialmsi.get_image()) * \ - FLATFIELD_INTEGRATION_TIME / MSI_INTEGRATION_TIME - desired_image_data[2, 2, 0] = np.nan - self.specialmsi.add_property({"integration times": - np.ones_like( - self.specialmsi.get_image()[0, 0, :]) - * MSI_INTEGRATION_TIME}) - flatfield = copy.deepcopy(self.specialmsi) - flatfield.add_property({"integration times": - np.ones_like( - flatfield.get_image()[0, 0, :]) - * FLATFIELD_INTEGRATION_TIME}) - # for testing if flatfield does not changed by correction we copy it - flatfield_copy = copy.deepcopy(flatfield) - - mani.flatfield_correction(self.specialmsi, flatfield_copy) - - np.testing.assert_almost_equal(self.specialmsi.get_image(), - desired_image_data, 15, - "corrected image is a division of integration times") - np.testing.assert_equal(flatfield.get_image(), - flatfield_copy.get_image(), - "flatfield doesn't change by correction") - - def test_flatfield_correction_with_single_value(self): - desired_image_data = np.ones_like(self.msi.get_image()) - flatfield = copy.copy(self.msi) - mani.calculate_mean_spectrum(flatfield) - unchanged_flatfield = copy.deepcopy(flatfield) - - mani.flatfield_correction(self.msi, flatfield) - - np.testing.assert_equal(self.msi.get_image(), - desired_image_data, - "flatfield correctly accounted for from singular reference value") - np.testing.assert_equal(flatfield, unchanged_flatfield, - "flatfield not changed by algorithm") - - def test_image_correction(self): - dark = copy.copy(self.msi) - dark.set_image(np.ones_like(dark.get_image()) * 0.5) - flatfield = copy.copy(self.msi) - flatfield_copy = copy.deepcopy(flatfield) - dark_copy = copy.deepcopy(dark) - - mani.image_correction(self.msi, flatfield, dark) - - np.testing.assert_equal(flatfield.get_image(), - flatfield_copy.get_image(), - "image correction didn't change flatfield") - np.testing.assert_equal(dark.get_image(), dark_copy.get_image(), - "image correction didn't change dark image") - np.testing.assert_almost_equal(self.msi.get_image(), - np.ones_like(self.msi.get_image()), - 15, "image correctly corrected :-)") - - - - - diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_msireaderwriter.py b/Modules/Biophotonics/python/iMC/msi/test/test_msireaderwriter.py deleted file mode 100644 index a3bed221b0..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_msireaderwriter.py +++ /dev/null @@ -1,40 +0,0 @@ -''' -Created on Aug 25, 2015 - -@author: wirkert -''' -import unittest -import os -import numpy as np - -import msi.test.helpers as helpers -from msi.io.msiwriter import MsiWriter -from msi.io.msireader import MsiReader - - -class Test(unittest.TestCase): - - def setUp(self): - self.msi = helpers.getFakeMsi() - self.test_file_path = "test_msi.msi" - - def tearDown(self): - # remove the hopefully written file - os.remove(self.test_file_path) - - def test_read_and_write(self): - reader = MsiReader() - writer = MsiWriter(self.msi) - writer.write(self.test_file_path) - read_msi = reader.read(self.test_file_path) - - np.testing.assert_array_equal(self.msi.get_image(), - read_msi.get_image(), - "data array of msi stays same" + - "after read and write") - np.testing.assert_array_equal( - self.msi.get_properties()["wavelengths"], - read_msi.get_properties()["wavelengths"], - "properties of msi stay same after read and write") - - diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_normalize.py b/Modules/Biophotonics/python/iMC/msi/test/test_normalize.py deleted file mode 100644 index 72f2a844c6..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_normalize.py +++ /dev/null @@ -1,74 +0,0 @@ -''' -Created on Aug 20, 2015 - -@author: wirkert -''' -import unittest -import numpy as np - -import msi.normalize as norm -import msi.test.helpers as helpers - - -class TestNormalize(unittest.TestCase): - - def setUp(self): - self.specialmsi = helpers.getFakeMsi() - # set one pixel to special values - self.specialValue = np.arange(self.specialmsi.get_image().shape[-1]) * 2 - self.specialmsi.get_image()[2, 2, :] = self.specialValue - - def tearDown(self): - pass - - def test_normalizeIQ(self): - original_shape = self.specialmsi.get_image().shape # shape should stay - # value 4.0 is in band 3 - desired_matrix = self.specialmsi.get_image() / 4.0 - # except for special value, where it is 8 - desired_matrix[2, 2, :] = self.specialmsi.get_image()[2, 2, :] / 6.0 - # the same after normalization - iq_normalizer = norm.NormalizeIQ(3) - iq_normalizer.normalize(self.specialmsi) - - self.assertEqual(self.specialmsi.get_image().shape, original_shape, - "shape not changed by normalization") - np.testing.assert_equal(self.specialmsi.get_image(), - desired_matrix, - "msi correctly normalized by iq") - - def test_normalizeMean(self): - original_shape = self.specialmsi.get_image().shape # shape should stay - desired_matrix = self.specialmsi.get_image() / 15.0 - desired_matrix[2, 2, :] = self.specialmsi.get_image()[2, 2, :] / 20.0 - # the same after normalization - mean_normalizer = norm.NormalizeMean() - mean_normalizer.normalize(self.specialmsi) - - self.assertEqual(self.specialmsi.get_image().shape, original_shape, - "shape not changed by normalization") - np.testing.assert_equal(self.specialmsi.get_image(), - desired_matrix, - "msi correctly normalized by mean") - - def test_normalizeMean_with_masked_elemnets(self): - original_shape = self.specialmsi.get_image().shape # shape should stay - # set mask so it masks the special value - mask = np.zeros_like(self.specialmsi.get_image()) - mask [2, 2, :] = 1 - mask = mask.astype(bool) - masked_msi_image = np.ma.MaskedArray(self.specialmsi.get_image(), - mask=mask) - self.specialmsi.set_image(masked_msi_image) - desired_matrix = masked_msi_image / 15.0 - # the same after normalization - mean_normalizer = norm.NormalizeMean() - mean_normalizer.normalize(self.specialmsi) - - self.assertEqual(self.specialmsi.get_image().shape, original_shape, - "shape not changed by normalization") - np.testing.assert_equal(self.specialmsi.get_image(), - desired_matrix, - "msi correctly normalized by mean") - np.testing.assert_equal(mask, self.specialmsi.get_image().mask) - diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_nrrdreader.py b/Modules/Biophotonics/python/iMC/msi/test/test_nrrdreader.py deleted file mode 100644 index da5083a125..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_nrrdreader.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 10 16:43:31 2015 - -@author: wirkert -""" - -import unittest -from msi.io.nrrdreader import NrrdReader -import numpy as np - - -class TestNrrdReader(unittest.TestCase): - - def setUp(self): - self.nrrdReader = NrrdReader() - self.msi = self.nrrdReader.read('./msi/data/testMsi.nrrd') - - def test_read_does_not_crash(self): - # if we got this far, at least an image was read. - self.assertTrue(len(self.msi.get_image().shape) == 3, - "read image has correct basic shape dimensions") - self.assertTrue(self.msi.get_image().shape[-1] == 5, - "read image has correct number of image stacks") - self.assertTrue(np.array_equal(self.msi.get_image()[2, 2, :], - np.array([1, 2, 3, 4, 5])), - "read image contains correct data") - - def test_read_non_existing_image_returns_exception(self): - with self.assertRaises(RuntimeError): - self.nrrdReader.read("./msi/data/asdf.nrrd") diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_nrrdwriter.py b/Modules/Biophotonics/python/iMC/msi/test/test_nrrdwriter.py deleted file mode 100644 index c442b76159..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_nrrdwriter.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Aug 13 09:52:47 2015 - -@author: wirkert -""" - -import unittest -import os -import numpy as np - -import msi.msimanipulations as msimani -from msi.io.nrrdreader import NrrdReader -from msi.io.nrrdwriter import NrrdWriter -from msi.test import helpers - - -class TestNrrdWriter(unittest.TestCase): - - def setUp(self): - # setup file and the path where it shall be written to - self.msi = helpers.getFakeMsi() - self.fileUriToWrite = "testfile.nrrd" - - def tearDown(self): - # remove the hopefully written file - os.remove(self.fileUriToWrite) - - def test_imageWriterCreatesFile(self): - writer = NrrdWriter(self.msi) - writer.write(self.fileUriToWrite) - self.assertTrue(os.path.isfile(self.fileUriToWrite), - "file was written to disk") - - def test_imageWriterCreatesCorrectFile(self): - - writer = NrrdWriter(self.msi) - writer.write(self.fileUriToWrite) - - reader = NrrdReader() - msi = reader.read(self.fileUriToWrite) - self.assertTrue(msi == helpers.getFakeMsi(), - "image correctly written and read") - - def test_write_one_d_image_works(self): - writer = NrrdWriter(self.msi) - msimani.calculate_mean_spectrum(self.msi) - writer.write(self.fileUriToWrite) - - reader = NrrdReader() - msi = reader.read(self.fileUriToWrite) - np.testing.assert_array_equal(msi.get_image(), - np.array([1, 2, 3, 4, 5]), - "1d image correctly written and read") diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_spectrometerreader.py b/Modules/Biophotonics/python/iMC/msi/test/test_spectrometerreader.py deleted file mode 100644 index b993a434bf..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_spectrometerreader.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 7 18:02:08 2015 - -@author: wirkert -""" - -import unittest - -from msi.io.spectrometerreader import SpectrometerReader - - -class TestSpectrometer(unittest.TestCase): - - def setUp(self): - self.exampleFileName = "./msi/data/Transmission_15-49-35-978_filter700nm.txt" - self.reader = SpectrometerReader() - - def tearDown(self): - pass - - def test_create(self): - self.assertTrue(True, "Created empty reader during setup") - - def test_read_spectrum(self): - msi = self.reader.read(self.exampleFileName) - - self.assertAlmostEqual(msi.get_image()[0], - 70.50, - msg="first spectral element is read correctly") - self.assertAlmostEqual(msi.get_image()[-1], - 68.13, - msg="last sprectral element is read correctly") - self.assertTrue(msi.get_image().size == 2048, - "correct number of elements read") - - def test_read_wavelengths(self): - msi = self.reader.read(self.exampleFileName) - - self.assertAlmostEqual(msi.get_wavelengths()[0], - 187.255 * 10 ** -9, - msg="first wavelength element is read correctly") - self.assertAlmostEqual(msi.get_wavelengths()[-1], - 1103.852 * 10 ** -9, - msg="last wavelength element is read correctly") - self.assertTrue(msi.get_wavelengths().size == 2048, - "correct number of elements read") diff --git a/Modules/Biophotonics/python/iMC/msi/test/test_tiffwriter.py b/Modules/Biophotonics/python/iMC/msi/test/test_tiffwriter.py deleted file mode 100644 index a2e880b80c..0000000000 --- a/Modules/Biophotonics/python/iMC/msi/test/test_tiffwriter.py +++ /dev/null @@ -1,40 +0,0 @@ - -import unittest -import os - -from msi.io.tiffwriter import TiffWriter -from msi.io.tiffreader import TiffReader -from msi.test import helpers - - -class TestTiffWriter(unittest.TestCase): - - def setUp(self): - # setup file and the path where it shall be written to - self.msi = helpers.getFakeMsi() - self.msi.set_image(self.msi.get_image()) - self.fileUriToWrite = os.path.join(os.getcwd(), "testfiles") - - def tearDown(self): - # remove the hopefully written files - folder, file_prefix = os.path.split(self.fileUriToWrite) - image_files = [f for f in os.listdir(folder) if - os.path.isfile(os.path.join(folder, f))] - image_files = [f for f in image_files if f.startswith(file_prefix)] - # expand to full path - image_files = [os.path.join(folder, f) for f in image_files] - for f in image_files: - os.remove(f) - - def test_imageWriterCreatesFile(self): - writer = TiffWriter(self.msi, convert_to_nm=False) - writer.write(self.fileUriToWrite) - - def test_imageWriterCreatesCorrectFile(self): - writer = TiffWriter(self.msi, convert_to_nm=False) - writer.write(self.fileUriToWrite) - - reader = TiffReader(shift_bits=0) - msi = reader.read(self.fileUriToWrite) - self.assertTrue(msi == helpers.getFakeMsi(), - "image correctly written and read") diff --git a/Modules/Biophotonics/python/iMC/regression/__init__.py b/Modules/Biophotonics/python/iMC/regression/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/regression/domain_adaptation.py b/Modules/Biophotonics/python/iMC/regression/domain_adaptation.py deleted file mode 100644 index 316f378aa9..0000000000 --- a/Modules/Biophotonics/python/iMC/regression/domain_adaptation.py +++ /dev/null @@ -1,88 +0,0 @@ -''' -Created on Oct 20, 2015 - -@author: wirkert -''' - -import numpy as np -from sklearn.cross_validation import KFold -from sklearn.grid_search import GridSearchCV -from sklearn.linear_model.logistic import LogisticRegressionCV -from sklearn.ensemble.forest import RandomForestClassifier - - -def prepare_data_for_weights_estimation(X_s, X_t): - nr_s = X_s.shape[0] - nr_t = X_t.shape[0] - source_labels = np.zeros(nr_s) - target_labels = np.ones(nr_t) - X_all = np.concatenate((X_s, X_t)) - all_labels = np.concatenate((source_labels, target_labels)) - return X_all, all_labels - - -def estimate_weights_random_forests(X_s, X_t, X_w): - - X_all, all_labels = prepare_data_for_weights_estimation(X_s, X_t) - # train logistic regression - kf = KFold(X_all.shape[0], 10, shuffle=True) - param_grid_rf = [ - {"n_estimators": np.array([500]), - "max_depth": np.array([6]), - # "max_features": np.array([1, 2, 4, 8, 16]), - "min_samples_leaf": np.array([100])}] - rf = GridSearchCV(RandomForestClassifier(50, max_depth=10, - class_weight="auto", n_jobs=-1), - param_grid_rf, cv=kf, n_jobs=-1) - rf = RandomForestClassifier(100, max_depth=6, min_samples_leaf=200, - class_weight="auto", n_jobs=-1) - rf.fit(X_all, all_labels) - # print "best parameters for rf weights determination: ", rf.best_estimator_ - probas = rf.predict_proba(X_w) - weights = probas[:, 1] / probas[:, 0] - return weights - - -def estimate_weights_logistic_regresssion(X_s, X_t): - """ estimate a logistic regressor to predict the probability of a sample - to be generated by one class or the other. - If one class is over or under represented weights will be adapted. - - Parameters: - X_s: samples from the source domain - X_t: samples from the target domain - - Returns: - weigths for X_s """ - X_all, all_labels = prepare_data_for_weights_estimation(X_s, X_t) - - kf = KFold(X_all.shape[0], 10, shuffle=True) - best_lr = LogisticRegressionCV(class_weight="auto", - Cs=np.logspace(4, 8, 10), - fit_intercept=False) - best_lr.fit(X_all, all_labels) - - weights = X_s.shape[0] / X_t.shape[0] * np.exp(np.dot(X_s, best_lr.coef_.T) - + best_lr.intercept_) - return weights - - -def resample(X, y, w, nr_samples=None): - """bootstrapping: resample with replacement according to weights - - Returns: - (X_new, w_new): the chosen samples and the new weights. - by design these new weights are all equal to 1.""" - if (nr_samples is None): - nr_samples = X.shape[0] - w = w / np.sum(w) # normalize - # create index array with samples to draw: - total_nr_samples = X.shape[0] # nr total samples - chosen_samples = np.random.choice(total_nr_samples, - size=nr_samples, - replace=True, p=np.squeeze(w)) - if y.ndim == 1: - y_chosen = y[chosen_samples] - else: - y_chosen = y[chosen_samples, :] - return X[chosen_samples, :], y_chosen, np.ones(nr_samples) diff --git a/Modules/Biophotonics/python/iMC/regression/estimation.py b/Modules/Biophotonics/python/iMC/regression/estimation.py deleted file mode 100644 index 7b84e88974..0000000000 --- a/Modules/Biophotonics/python/iMC/regression/estimation.py +++ /dev/null @@ -1,130 +0,0 @@ - - -""" - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -""" -''' -Created on Oct 21, 2015 - -@author: wirkert -''' - -import math -import logging -import time - -import tensorflow as tf -import numpy as np -import SimpleITK as sitk - -from regression.tensorflow_estimator import multilayer_perceptron, cnn -import msi.imgmani as imgmani - - -def SAMDistance(x, y): - return math.acos(np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))) - - -def estimate_image(msi, regressor): - """given an Msi and an regressor estimate the parmaeters for this image - - Paramters: - msi: multi spectral image - regressor: regressor, must implement the predict method""" - - # estimate parameters - collapsed_msi = imgmani.collapse_image(msi.get_image()) - # in case of nan values: set to 0 - collapsed_msi[np.isnan(collapsed_msi)] = 0. - collapsed_msi[np.isinf(collapsed_msi)] = 0. - - start = time.time() - estimated_parameters = regressor.predict(collapsed_msi) - end = time.time() - estimation_time = end - start - logging.info("time necessary for estimating image parameters: " + - str(estimation_time) + "s") - # restore shape - feature_dimension = 1 - if len(estimated_parameters.shape) > 1: - feature_dimension = estimated_parameters.shape[-1] - - estimated_paramters_as_image = np.reshape( - estimated_parameters, (msi.get_image().shape[0], - msi.get_image().shape[1], - feature_dimension)) - # save as sitk nrrd. - sitk_img = sitk.GetImageFromArray(estimated_paramters_as_image, - isVector=True) - return sitk_img, estimation_time - - -def estimate_image_tensorflow(msi, model_checkpoint_dir): - # estimate parameters - collapsed_msi = imgmani.collapse_image(msi.get_image()) - # in case of nan values: set to 0 - collapsed_msi[np.isnan(collapsed_msi)] = 0. - collapsed_msi[np.isinf(collapsed_msi)] = 0. - - - tf.reset_default_graph() - - keep_prob = tf.placeholder("float") - nr_wavelengths = len(msi.get_wavelengths()) - x = tf.placeholder("float", [None, nr_wavelengths, 1, 1]) - - x_test_image = np.reshape(msi.get_image(), [-1, nr_wavelengths, 1, 1]) - - # Construct the desired model - # pred, regularizers = multilayer_perceptron(x, nr_wavelengths, 100, 1, - # keep_prob) - pred = cnn(x, 1, keep_prob) - - # Initializing the variables - init = tf.initialize_all_variables() - - saver = tf.train.Saver() - - with tf.Session() as sess: - sess.run(tf.initialize_all_variables()) - # restore model: - ckpt = tf.train.get_checkpoint_state(model_checkpoint_dir) - - if ckpt and ckpt.model_checkpoint_path: - saver.restore(sess, ckpt.model_checkpoint_path) - - start = time.time() - estimated_parameters = pred.eval({x: x_test_image, - keep_prob:1.0}) - end = time.time() - estimation_time = end - start - logging.info("time necessary for estimating image parameters: " + - str(estimation_time) + "s") - # restore shape - feature_dimension = 1 - if len(estimated_parameters.shape) > 1: - feature_dimension = estimated_parameters.shape[-1] - - estimated_paramters_as_image = np.reshape( - estimated_parameters, (msi.get_image().shape[0], - msi.get_image().shape[1], - feature_dimension)) - # save as sitk nrrd. - sitk_img = sitk.GetImageFromArray(estimated_paramters_as_image, - isVector=True) - - return sitk_img, estimation_time - - -def standard_score(estimator, X, y): - """our standard scoring method is the median absolute error""" - return np.median(np.abs(estimator.predict(X) - y)) - diff --git a/Modules/Biophotonics/python/iMC/regression/linear.py b/Modules/Biophotonics/python/iMC/regression/linear.py deleted file mode 100644 index dcd96977a7..0000000000 --- a/Modules/Biophotonics/python/iMC/regression/linear.py +++ /dev/null @@ -1,95 +0,0 @@ -''' -Created on Oct 19, 2015 - -@author: wirkert -''' - -import numpy as np -from scipy.interpolate import interp1d - -from mc.usuag import get_haemoglobin_extinction_coefficients - -class LinearSaO2Unmixing(object): - ''' - classdocs - ''' - - def __init__(self): - # oxygenated haemoglobin extinction coefficients - eHb02 = 0 - eHb = 0 - - # oxygenated haemoglobin extinction coefficients - eHbO2 = np.array([34772.8, - 27840.93333, - 23748.8 , - 21550.8 , - 21723.46667, - 28064.8 , - 39131.73333, - 45402.93333, - 42955.06667, - 40041.73333, - 42404.4 , - 36333.6 , - 22568.26667, - 6368.933333, - 1882.666667, - 1019.333333, - 664.6666667, - 473.3333333, - 376.5333333, - 327.2 , - 297.0666667],) - # deoxygenated haemoglobin extinction coefficients - eHb = [18031.73333 , - 15796.8 , - 17365.33333 , - 21106.53333 , - 26075.06667 , - 32133.2 , - 39072.66667 , - 46346.8 , - 51264 , - 50757.33333 , - 45293.33333 , - 36805.46667 , - 26673.86667 , - 17481.73333 , - 10210.13333 , - 7034 , - 5334.533333 , - 4414.706667 , - 3773.96 , - 3257.266667 , - 2809.866667] - nr_total_wavelengths = len(eHb) - # to account for scattering losses we allow a constant offset - scattering = np.ones(nr_total_wavelengths) - # put eHbO2, eHb and scattering term in one measurement matrix - self.H = np.vstack((eHbO2, eHb, scattering)).T - self.lsq_solution_matrix = np.dot(np.linalg.inv(np.dot(self.H.T, - self.H)), - self.H.T) - - - def fit(self, X, y, weights=None): - """only implemented to fit to the standard sklearn framework.""" - pass - - def predict(self, X): - """predict like in sklearn: - - Parameters: - X: nrsamples x nr_features matrix of samples to predict for - regression - - Returns: - y: array of shape [nr_samples] with values for predicted - oxygenation """ - # do least squares estimation - oxy_test, deoxy, s = np.dot(self.lsq_solution_matrix, X.T) - # calculate oxygenation = oxygenated blood / total blood - saO2 = oxy_test / (oxy_test + deoxy) - - return np.clip(saO2, 0., 1.) diff --git a/Modules/Biophotonics/python/iMC/regression/preprocessing.py b/Modules/Biophotonics/python/iMC/regression/preprocessing.py deleted file mode 100644 index 494f7a82db..0000000000 --- a/Modules/Biophotonics/python/iMC/regression/preprocessing.py +++ /dev/null @@ -1,94 +0,0 @@ -''' -Created on Oct 26, 2015 - -@author: wirkert -''' - -import numpy as np -import pandas as pd -from sklearn.preprocessing import Normalizer - - -def preprocess2(df, nr_samples=None, snr=None, movement_noise_sigma=None, - magnification=None, bands_to_sortout=None): - - # first set 0 reflectances to nan - df["reflectances"] = df["reflectances"].replace(to_replace=0., - value=np.nan) - # remove nan - df.dropna(inplace=True) - - # extract nr_samples samples from data - if nr_samples is not None: - df = df.sample(nr_samples) - - # get reflectance and oxygenation - X = df.reflectances - if bands_to_sortout is not None and bands_to_sortout.size > 0: - X.drop(X.columns[bands_to_sortout], axis=1, inplace=True) - snr = np.delete(snr, bands_to_sortout) - X = X.values - y = df.layer0[["sao2", "vhb"]] - - # do data magnification - if magnification is not None: - X_temp = X - y_temp = y - for i in range(magnification - 1): - X = np.vstack((X, X_temp)) - y = pd.concat([y, y_temp]) - - # add noise to reflectances - camera_noise = 0. - if snr is not None: - sigmas = X / snr - noises = np.random.normal(loc=0., scale=1, size=X.shape) - camera_noise = sigmas*noises - - movement_noise = 0. - if movement_noise_sigma is not None: - nr_bands = X.shape[1] - nr_samples = X.shape[0] - # we assume no correlation between neighboring bands - CORRELATION_COEFFICIENT = 0.0 - movement_variance = movement_noise_sigma ** 2 - movement_variances = np.ones(nr_bands) * movement_variance - movement_covariances = np.ones(nr_bands-1) * CORRELATION_COEFFICIENT * \ - movement_variance - movement_covariance_matrix = np.diag(movement_variances) + \ - np.diag(movement_covariances, -1) + \ - np.diag(movement_covariances, 1) - # percentual sample errors - sample_errors_p = np.random.multivariate_normal(mean=np.zeros(nr_bands), - cov=movement_covariance_matrix, - size=nr_samples) - # errors w.r.t. the curve height. - movement_noise = X * sample_errors_p - - X += camera_noise + movement_noise - - X = np.clip(X, 0.00001, 1.) - # do normalizations - X = normalize(X) - return X, y - - -def preprocess(batch, nr_samples=None, snr=None, movement_noise_sigma=None, - magnification=None, bands_to_sortout=None): - X, y = preprocess2(batch, nr_samples, snr, movement_noise_sigma, - magnification, bands_to_sortout) - - return X, y["sao2"] - - -def normalize(X): - # normalize reflectances - normalizer = Normalizer(norm='l1') - X = normalizer.transform(X) - # reflectances to absorption - absorptions = -np.log(X) - X = absorptions - # get rid of sorted out bands - normalizer = Normalizer(norm='l2') - X = normalizer.transform(X) - return X diff --git a/Modules/Biophotonics/python/iMC/regression/tensorflow_dataset.py b/Modules/Biophotonics/python/iMC/regression/tensorflow_dataset.py deleted file mode 100644 index 4bc2065aac..0000000000 --- a/Modules/Biophotonics/python/iMC/regression/tensorflow_dataset.py +++ /dev/null @@ -1,83 +0,0 @@ -"""Functions for downloading and reading ipcai data.""" -from __future__ import print_function - -import os - -import numpy -import pandas as pd - -from regression.preprocessing import preprocess - - -class DataSet(object): - def __init__(self, images, labels, fake_data=False): - if fake_data: - self._num_examples = 10000 - else: - assert images.shape[0] == labels.shape[0], ( - "images.shape: %s labels.shape: %s" % (images.shape, - labels.shape)) - self._num_examples = images.shape[0] - images = images.astype(numpy.float32) - self._images = images - self._labels = labels - if self._labels.ndim == 1: - self._labels = self._labels[:, numpy.newaxis] - self._epochs_completed = 0 - self._index_in_epoch = 0 - - @property - def images(self): - return self._images - - @property - def labels(self): - return self._labels - - @property - def num_examples(self): - return self._num_examples - - @property - def epochs_completed(self): - return self._epochs_completed - - def next_batch(self, batch_size, fake_data=False): - """Return the next `batch_size` examples from this data set.""" - if fake_data: - fake_image = [1.0 for _ in xrange(784)] - fake_label = 0 - return [fake_image for _ in xrange(batch_size)], [ - fake_label for _ in xrange(batch_size)] - start = self._index_in_epoch - self._index_in_epoch += batch_size - if self._index_in_epoch > self._num_examples: - # Finished epoch - self._epochs_completed += 1 - # Shuffle the data - perm = numpy.arange(self._num_examples) - numpy.random.shuffle(perm) - self._images = self._images[perm] - self._labels = self._labels[perm] - - # Start next epoch - start = 0 - self._index_in_epoch = batch_size - assert batch_size <= self._num_examples - end = self._index_in_epoch - return self._images[start:end], self._labels[start:end] - - -def read_data_set(dataframe_filename, fake_data=False): - - if fake_data: - data_set = DataSet([], [], fake_data=True) - return data_set - - df_data_set = pd.read_csv(os.path.join(dir, dataframe_filename), - header=[0, 1]) - - data_set_images, data_set_labels = preprocess(df_data_set, snr=10.) - data_set_labels = data_set_labels.values - data_set = DataSet(data_set_images, data_set_labels) - return data_set diff --git a/Modules/Biophotonics/python/iMC/regression/tensorflow_estimator.py b/Modules/Biophotonics/python/iMC/regression/tensorflow_estimator.py deleted file mode 100644 index b5025563ec..0000000000 --- a/Modules/Biophotonics/python/iMC/regression/tensorflow_estimator.py +++ /dev/null @@ -1,88 +0,0 @@ - - -import tensorflow as tf - - -def weight_variable(shape): - initial = tf.truncated_normal(shape, stddev=0.1) - return tf.Variable(initial) - - -def bias_variable(shape): - initial = tf.constant(0.1, shape=shape) - return tf.Variable(initial) - - -def conv2d(x, W, padding='SAME'): - return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding=padding) - - -def max_pool1d(x, poolsize=2): - return tf.nn.max_pool(x, ksize=[1, poolsize, 1, 1], - strides=[1, poolsize, 1, 1], padding='SAME') - - -def add_cnn_layer(input, n_inputs, n_outputs, kernel_size, padding='SAME'): - #w = weight_variable([n_inputs, n_outputs]) - #b = bias_variable([n_outputs]) - W = weight_variable([kernel_size, 1, n_inputs, n_outputs]) - b = bias_variable([n_outputs]) - # Hidden layer with RELU activation - #new_layer = tf.nn.relu(tf.add(tf.matmul(input, w), b)) - h_conv = tf.nn.relu(conv2d(input, W, padding=padding) + b) - # Add dropout regularization - #new_layer_with_dropout = tf.nn.dropout(new_layer, keep_prob) - h_pool = max_pool1d(h_conv) - return h_pool, W - - -def add_fully_connected_layer(_X, n_inputs, n_outputs, keep_prob): - W = weight_variable([n_inputs, n_outputs]) - b = bias_variable([n_outputs]) - # Hidden layer with RELU activation - new_layer = tf.nn.relu(tf.add(tf.matmul(_X, W), b)) - # Add dropout regularization - new_layer_with_dropout = tf.nn.dropout(new_layer, keep_prob) - - return new_layer_with_dropout, W - - -# this is my exemplary convolutional network -def cnn(_X, n_classes, keep_prob): - # two convolutional layers - layer_1, _ = add_cnn_layer(_X, 1, 32, 3, padding='VALID') - layer_2, _ = add_cnn_layer(layer_1, 32, 32, 2, padding='VALID') - # flatten last one to be able to apply it to fully connected layer - final_number_of_dimensions = 1*32 - layer_2_flat = tf.reshape(layer_2, [-1, final_number_of_dimensions]) - - # fully connected layer to bring information together - fc_dim = 5 - h_fc1_drop, _ = add_fully_connected_layer(layer_2_flat, - final_number_of_dimensions, - fc_dim, keep_prob) - - # return linear output layer - W_fc2 = weight_variable([fc_dim, n_classes]) - b_fc2 = bias_variable([n_classes]) - return tf.matmul(h_fc1_drop, W_fc2) + b_fc2 - - -# and this is the simpler multilayer perceptron -def multilayer_perceptron(x, n_bands, n_hidden, n_classes, keep_prob): - flattend_input = tf.reshape(x, [-1, n_bands]) - layer_1, W_1 = add_fully_connected_layer(flattend_input, n_bands, n_hidden, - keep_prob) - layer_2, W_2 = add_fully_connected_layer(layer_1, n_hidden, n_hidden, - keep_prob) - last_hidden_layer, W_3 = add_fully_connected_layer(layer_2, n_hidden, n_hidden, - keep_prob) - - W_out = weight_variable([n_hidden, n_classes]) - b_out = bias_variable([n_classes]) - - regularizers = (tf.nn.l2_loss(W_1) + tf.nn.l2_loss(W_2) + - tf.nn.l2_loss(W_3) + tf.nn.l2_loss(W_out)) - - return tf.matmul(last_hidden_layer, W_out) + b_out, regularizers - diff --git a/Modules/Biophotonics/python/iMC/scripts/basic_checks/__init__.py b/Modules/Biophotonics/python/iMC/scripts/basic_checks/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/scripts/basic_checks/script_evaluate_color_checkerboard.py b/Modules/Biophotonics/python/iMC/scripts/basic_checks/script_evaluate_color_checkerboard.py deleted file mode 100644 index fcf5bea72e..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/basic_checks/script_evaluate_color_checkerboard.py +++ /dev/null @@ -1,266 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 14 11:09:18 2015 - -@author: wirkert -""" - - -import Image -import ImageEnhance -import logging -import datetime -import copy - -from scipy.interpolate import interp1d -from sklearn.preprocessing import normalize -from sklearn.metrics import r2_score - -from msi.io.nrrdreader import NrrdReader -import msi.normalize as norm -from ipcai2016.tasks_common import * -import commons -from ipcai2016 import tasks_mc -import msi.plot as msiplot -from msi.io.spectrometerreader import SpectrometerReader -from msi.normalize import standard_normalizer -from msi.io.tiffringreader import TiffRingReader - -TiffRingReader.RESIZE_FACTOR = 0.5 - -sc = commons.ScriptCommons() - -sc.add_dir("COLORCHECKER_DATA", - os.path.join(sc.get_dir("DATA_FOLDER"), "colorchecker_laparoscope")) - -sc.add_dir("COLORCHECKER_RESULTS", - os.path.join(sc.get_dir("RESULTS_FOLDER"), - "colorchecker_laparoscope")) - -sc.add_dir("FLAT_FOLDER", - os.path.join(sc.get_dir("DATA_FOLDER"), - "colorchecker_laparoscope_flatfield")) - -sc.add_dir("SPECTROMETER_REFERENCE_DATA", - os.path.join(sc.get_dir("DATA_FOLDER"), - "spectrometer_reflectance_new")) - -sc.add_dir("FILTER_TRANSMISSIONS", - os.path.join(sc.get_dir("DATA_FOLDER"), - "filter_transmissions")) - - -class CheckColorCheckerBoards(luigi.Task): - image_name = luigi.Parameter() - - def requires(self): - return Flatfield(flatfield_folder=sc.get_full_dir("FLAT_FOLDER")), \ - SingleMultispectralImage(image=self.image_name), \ - Dark(dark_folder=sc.get_full_dir("DARK_FOLDER")), \ - SpectrometerToSpectrocam(spectrometer_measurement= - os.path.join(sc.get_full_dir("SPECTROMETER_REFERENCE_DATA"), - os.path.split(self.image_name)[1][0:8] + ".txt")) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("COLORCHECKER_RESULTS"), - os.path.split(self.image_name)[1] + - "_" + "_color_check" + ".png")) - - def run(self): - - print "... read data" - - segmentation_file = os.path.join( - sc.get_full_dir("COLORCHECKER_DATA"), "seg.tiff") - segmentation_file2 = os.path.join( - sc.get_full_dir("COLORCHECKER_DATA"), "seg2.tiff") - - nrrd_reader = NrrdReader() - tiff_ring_reader = TiffRingReader() - # read the flatfield - flat = nrrd_reader.read(self.input()[0].path) - dark = nrrd_reader.read(self.input()[2].path) - # read the msi - nr_filters = len(sc.other["RECORDED_WAVELENGTHS"]) - msi, segmentation = tiff_ring_reader.read(self.input()[1].path, - nr_filters, - segmentation=segmentation_file) - msi_copy = copy.deepcopy(msi) # copy to be able to apply both - # segmentations - msimani.apply_segmentation(msi, segmentation) - msi2, segmentation2 = tiff_ring_reader.read(self.input()[1].path, - nr_filters, - segmentation=segmentation_file2) - msimani.apply_segmentation(msi2, segmentation2) - - msimani.apply_segmentation(msi_copy, segmentation + segmentation2) - - # read the spectrometer measurement - msi_spectrometer = nrrd_reader.read(self.input()[3].path) - - # correct by flatfield and dark image - #msimani.image_correction(msi, flat, dark) - #msimani.image_correction(msi2, flat, dark) - #msimani.image_correction(msi_copy, flat, dark) - msimani.dark_correction(msi, dark) - msimani.dark_correction(msi2, dark) - msimani.dark_correction(msi_copy, dark) - - # create artificial rgb - rgb_image = msi_copy.get_image()[:, :, [2, 3, 1]] - rgb_image /= np.max(rgb_image) - rgb_image *= 255. - - # preprocess the image - # sortout unwanted bands - print "... apply normalizations" - # normalize to get rid of lighting intensity - norm.standard_normalizer.normalize(msi) - norm.standard_normalizer.normalize(msi2) - - print "... plot" - - # plot of the rgb image - rgb_image = rgb_image.astype(np.uint8) - im = Image.fromarray(rgb_image, 'RGB') - enh_brightness = ImageEnhance.Brightness(im) - im = enh_brightness.enhance(2.) - plotted_image = np.array(im) - - plt.figure() - f, (ax_rgb, ax_spectra) = plt.subplots(1, 2) - plot_image(plotted_image, ax_rgb, title="false rgb") - - msiplot.plotMeanError(msi, ax_spectra) - msiplot.plotMeanError(msi2, ax_spectra) - - standard_normalizer.normalize(msi_spectrometer) - msiplot.plot(msi_spectrometer, ax_spectra) - - mean_spectrometer = msi_spectrometer.get_image() - mean_msi = msimani.calculate_mean_spectrum(msi).get_image() - mean_msi2 = msimani.calculate_mean_spectrum(msi2).get_image() - r2_msi = r2_score(mean_spectrometer, mean_msi) - r2_msi2 = r2_score(mean_spectrometer, mean_msi2) - - ax_spectra.legend(["spectrocam 1 r2: " + str(r2_msi), - "spectrocam 2 r2: " + str(r2_msi2), "spectrometer"], - bbox_to_anchor=(0., 1.02, 1., .102), loc=3, - ncol=2, mode="expand", borderaxespad=0., - fontsize=5) - - plt.savefig(self.output().path, - dpi=250, bbox_inches='tight') - - -class CameraQEFile(luigi.Task): - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("DATA_FOLDER"), - "camera_quantum_efficiency.csv")) - - -class SpectrometerToSpectrocam(luigi.Task): - - spectrometer_measurement = luigi.Parameter() - - def requires(self): - # all wavelengths must have been measured for transmission and stored in - # wavelength.txt files (e.g. 470.txt) - filenames = ((sc.other["RECORDED_WAVELENGTHS"] * 10**9).astype(int)).astype(str) - filenames = map(lambda name: tasks_mc.FilterTransmission(os.path.join(sc.get_full_dir("FILTER_TRANSMISSIONS"), - name) + ".txt"), - filenames) - - return tasks_mc.SpectrometerFile(self.spectrometer_measurement), \ - filenames, CameraQEFile() - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - os.path.split(self.spectrometer_measurement)[1] + - "_spectrocam.nrrd")) - - def run(self): - # load spectrometer measurement - spectrometer_reader = SpectrometerReader() - spectrometer_msi = spectrometer_reader.read(self.input()[0].path) - - # the wavelengths recorded by the spectrometer - spectrometer_wavelengths = spectrometer_msi.get_wavelengths() - - spectrometer_white = spectrometer_reader.read(os.path.join( - sc.get_full_dir("DATA_FOLDER"), "spectrometer_whitebalance", - "white_IL_1_OO_20ms.txt")) - spectrometer_dark = spectrometer_reader.read(os.path.join( - sc.get_full_dir("DATA_FOLDER"), "spectrometer_whitebalance", - "dark_1_OO_20ms.txt")) - msimani.dark_correction(spectrometer_white, spectrometer_dark) - white_interpolator = interp1d(spectrometer_white.get_wavelengths(), - spectrometer_white.get_image(), - bounds_error=False, fill_value=0.) - white_interpolated = white_interpolator(spectrometer_wavelengths) - - camera_qe = pd.read_csv(self.input()[2].path) - camera_qe_interpolator = interp1d(camera_qe["wavelengths"] * 10**-9, - camera_qe["quantum efficiency"], - bounds_error=False, - fill_value=0.) - camera_qe_interpolated = \ - camera_qe_interpolator(spectrometer_wavelengths) - - # camera batch creation: - new_reflectances = [] - for band in self.input()[1]: - df_filter = pd.read_csv(band.path) - interpolator = interp1d(df_filter["wavelengths"], - df_filter["reflectances"], - assume_sorted=False, bounds_error=False) - # use this to create new reflectances - interpolated_filter = interpolator(spectrometer_wavelengths) - # if a wavelength cannot be interpolated, set it to 0 - interpolated_filter = np.nan_to_num(interpolated_filter) - # account for cameras quantum efficiency - interpolated_filter *= camera_qe_interpolated * white_interpolated - # normalize band response - #normalize(interpolated_filter.reshape(1, -1), norm='l1', copy=False) - folded_reflectance = np.dot(spectrometer_msi.get_image(), - interpolated_filter) - new_reflectances.append(folded_reflectance) - plt.plot(interpolated_filter) - new_reflectances = np.array(new_reflectances).T - spectrometer_msi.set_image(new_reflectances, - wavelengths=sc.other["RECORDED_WAVELENGTHS"]) - - # write it - nrrd_writer = NrrdWriter(spectrometer_msi) - nrrd_writer.write(self.output().path) - -if __name__ == '__main__': - - # create a folder for the results if necessary - sc.set_root("/media/wirkert/data/Data/2020_Current_Works/") - sc.create_folders() - - # root folder there the data lies - logging.basicConfig(filename=os.path.join(sc.get_full_dir("LOG_FOLDER"), - "color_checker" + - str(datetime.datetime.now()) + - '.log'), level=logging.INFO) - luigi.interface.setup_interface_logging() - ch = logging.StreamHandler() - ch.setLevel(logging.INFO) - logger = logging.getLogger() - logger.addHandler(ch) - - sch = luigi.scheduler.CentralPlannerScheduler() - w = luigi.worker.Worker(scheduler=sch) - - files = get_image_files_from_folder(sc.get_full_dir("COLORCHECKER_DATA"), - suffix="F0.tiff", fullpath=True) - - for f in files: - main_task = CheckColorCheckerBoards(image_name=f) - w.add(main_task) - - w.run() - diff --git a/Modules/Biophotonics/python/iMC/scripts/commons.py b/Modules/Biophotonics/python/iMC/scripts/commons.py deleted file mode 100644 index 48e060132c..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/commons.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -This file contains a singleton class which manages the paths set for evaluating -the scripts. - -Also it contains some utility methods. -""" - -import os - -import numpy as np - - -class ScriptCommons(object): - """ - The commonly shared paths to the data/log/results... folders. - + additional commonly available data as recorded wavelengths - this is a singleton pattern copied from - http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Singleton.html - """ - - class __ScriptCommons_Singleton: - - def __init__(self): - - self.root = os.path.join("..", "..") - - self.dirs = {"LOG_FOLDER": "log", - "DATA_FOLDER": "data", - "RESULTS_FOLDER": "results"} - - self.dirs["FLAT_FOLDER"] = os.path.join(self.dirs["DATA_FOLDER"], - "flatfields") - self.dirs["DARK_FOLDER"] = os.path.join(self.dirs["DATA_FOLDER"], - "dark") - - self.dirs["INTERMEDIATES_FOLDER"] = os.path.join( - self.dirs["RESULTS_FOLDER"], "intermediate") - - self.dirs["MC_DATA_FOLDER"] = os.path.join( - self.dirs["INTERMEDIATES_FOLDER"], "mc_data") - - self.other = {"RECORDED_WAVELENGTHS": np.array([580, 470, - 660, 560, - 480, 511, - 600, 700]) - * 10 ** -9} - - def create_folders(self): - """ - Create all folders listed in self.folders if not existing - """ - for f in self.dirs: - create_folder_if_necessary(self.get_full_dir(f)) - - def set_root(self, root): - self.root = root - - def get_root(self): - return self.root - - def add_dir(self, key, new_dir): - """ - Add/replace a directory to the singletons list. - Directories can be returned with get_dir and with their full path by - calling get_full_dir - - :param key: the key under which it shall be retrievable - :param new_dir: the directory to add to the list - """ - self.dirs[key] = new_dir - - def get_dir(self, key): - return self.dirs[key] - - def get_full_dir(self, key): - return os.path.join(self.get_root(), self.get_dir(key)) - - instance = None - - def __new__(cls): # __new__ always a classmethod - if not ScriptCommons.instance: - ScriptCommons.instance = ScriptCommons.__ScriptCommons_Singleton() - return ScriptCommons.instance - - def __getattr__(self, name): - return getattr(self.instance, name) - - def __setattr__(self, name): - return setattr(self.instance, name) - - -def create_folder_if_necessary(folder): - """ - :param folder: create the folder folder if necessary (not already existing) - """ - if not os.path.exists(folder): - os.makedirs(folder) diff --git a/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/__init__.py b/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/domain_adaptation_paths.py b/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/domain_adaptation_paths.py deleted file mode 100644 index 23660eb1f1..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/domain_adaptation_paths.py +++ /dev/null @@ -1,18 +0,0 @@ - - -import os - -ROOT_FOLDER = "/media/wirkert/data/Data/2016_03_Domain_Adaptation" -LOG_FOLDER = os.path.join(ROOT_FOLDER, "log") -DATA_FOLDER = os.path.join(ROOT_FOLDER, "data") -RESULTS_FOLDER = os.path.join(ROOT_FOLDER, "results") -INTERMEDIATES_FOLDER = os.path.join(RESULTS_FOLDER, "intermediate") -MC_DATA_FOLDER = os.path.join(INTERMEDIATES_FOLDER, "mc_data") - - -def create_folder_if_necessary(folder): - if not os.path.exists(folder): - os.makedirs(folder) - -create_folder_if_necessary(INTERMEDIATES_FOLDER) -create_folder_if_necessary(LOG_FOLDER) diff --git a/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/script_analyze_da_in_silico.py b/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/script_analyze_da_in_silico.py deleted file mode 100644 index f8d486e90a..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/domain_adaptation/script_analyze_da_in_silico.py +++ /dev/null @@ -1,364 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 14 11:09:18 2015 - -@author: wirkert -""" - -import os -import logging -import datetime - -import numpy as np -import pandas as pd -import luigi -import matplotlib.pyplot as plt -import seaborn as sns - -from regression.preprocessing import preprocess -import domain_adaptation_paths as sp -from ipcai2016 import tasks_mc -from ipcai2016.script_analyze_ipcai_in_silico import w_standard, noise_levels, \ - evaluate_data, standard_plotting, NoisePlot -# additionally we need the weights estimation functionality -from regression.domain_adaptation import estimate_weights_random_forests - - -class WeightedBatch(luigi.Task): - which_source = luigi.Parameter() - which_target = luigi.Parameter() - noise = luigi.FloatParameter() - - def requires(self): - return tasks_mc.CameraBatch(self.which_source), \ - tasks_mc.CameraBatch(self.which_target) - - def output(self): - return luigi.LocalTarget(os.path.join(sp.ROOT_FOLDER, - sp.RESULTS_FOLDER, - "adapted_" + - self.which_source + - "_with_" + self.which_target + - "_noise_" + str(self.noise) + - ".txt")) - - def run(self): - # get data - df_source = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_target = pd.read_csv(self.input()[1].path, header=[0, 1]) - - # first extract X_source and X_target, preprocessed at standard noise - # level - X_source, y_source = preprocess(df_source, w_percent=w_standard) - X_target, y_target = preprocess(df_target, w_percent=w_standard) - - # train a classifier to determine probability for specific class - weights = estimate_weights_random_forests(X_source, X_target, X_source) - # add weight to dataframe - df_source["weights"] = weights - - # finally save the dataframe with the added weights - df_source.to_csv(self.output().path, index=False) - - -class DaNoisePlot(luigi.Task): - """ - Very similar to NoisePlot in IPCAI in silico evaluation but with - weighted data coming in. - """ - which_train = luigi.Parameter() - which_test = luigi.Parameter() - - def requires(self): - # for each noise level we need to create the weights - NecessaryBatches = map(lambda noise: WeightedBatch(self.which_train, - self.which_test, - noise), - noise_levels) - return NecessaryBatches(self.which_train, self.which_test), \ - tasks_mc.CameraBatch(self.which_test) - - def output(self): - return luigi.LocalTarget(os.path.join(sp.ROOT_FOLDER, - sp.RESULTS_FOLDER, - sp.FINALS_FOLDER, - "noise_da_plot_train_" + - self.which_train + - "_test_" + self.which_test + - ".png")) - - def run(self): - # get data - df_train = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_test = pd.read_csv(self.input()[1].path, header=[0, 1]) - - df = evaluate_data(df_train, noise_levels, df_test, noise_levels) - standard_plotting(df) - - # finally save the figure - plt.savefig(self.output().path, dpi=500, - bbox_inches='tight') - - -class GeneratingDistributionPlot(luigi.Task): - which_source = luigi.Parameter() - which_target = luigi.Parameter() - - def requires(self): - return WeightedBatch(self.which_source, self.which_target), \ - tasks_mc.CameraBatch(self.which_target) - - def output(self): - return luigi.LocalTarget(os.path.join(sp.ROOT_FOLDER, - sp.RESULTS_FOLDER, - sp.FINALS_FOLDER, - "generating_distribution_" + - self.which_source + - "_adapted_to_" + - self.which_target + - ".png")) - - def run(self): - # get data - df_source = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_target = pd.read_csv(self.input()[1].path, header=[0, 1]) - - # create dataframe suited for plotting - # we do a weighted sampling with replacement to be able to create some - # plots there the data distribution is visible. - nr_samples = 100 - # first data weighted by domain adaptation - df_source_adapted = df_source["layer0"].copy() - df_source_adapted["weights"] = df_source["weights"] - df_source_adapted["data"] = "adapted" - df_source_adapted = df_source_adapted.sample(n=nr_samples, replace=True, - weights="weights") - # now original source data - df_source = df_source["layer0"].copy() - df_source["weights"] = 1 # we set the weights here to 1 - df_source["data"] = "source" - df_source = df_source.sample(n=nr_samples, replace=True, - weights="weights") - # now the target data - df_target = df_target["layer0"] - df_target["weights"] = 1 - df_target["data"] = "target" - df_target = df_target.sample(n=nr_samples, replace=True, - weights="weights") - # now merge all three dataframes to the dataframe used for the plotting - df = pd.concat([df_source, df_source_adapted, df_target]) - # since we already sampled we can get rid of weights - df.drop("weights", axis=1, inplace=True) - # d to um - df["d"] *= 10**6 - # vhb and sao2 to % - df["vhb"] *= 100 - df["sao2"] *= 100 - - # do some serious plotting - g = sns.pairplot(df, vars=["vhb", "sao2", "d"], - hue="data", markers=["o", "s", "D"]) - - # tidy up plot - g.add_legend() - - # finally save the figure - plt.savefig(self.output().path, dpi=500, - bbox_inches='tight') - - -class WeightDistributionPlot(luigi.Task): - which_source = luigi.Parameter() - which_target = luigi.Parameter() - - def requires(self): - return WeightedBatch(self.which_source, self.which_target) - - def output(self): - return luigi.LocalTarget(os.path.join(sp.ROOT_FOLDER, - sp.RESULTS_FOLDER, - sp.FINALS_FOLDER, - "weight_distribution_" + - self.which_source + - "_adapted_to_" + - self.which_target + - ".png")) - - def run(self): - # get data - df_source = pd.read_csv(self.input().path, header=[0, 1]) - - df_source["weights"].plot.hist(bins=100) - plt.axvline(x=1, ymin=0, ymax=df_source.shape[0]) - # TODO: add cumsum on top - - # finally save the figure - plt.savefig(self.output().path, dpi=500, - bbox_inches='tight') - - -class FeatureDistributionPlot(luigi.Task): - which_source = luigi.Parameter() - which_target = luigi.Parameter() - - def requires(self): - return WeightedBatch(self.which_source, self.which_target), \ - tasks_mc.CameraBatch(self.which_target) - - def output(self): - return luigi.LocalTarget(os.path.join(sp.ROOT_FOLDER, - sp.RESULTS_FOLDER, - sp.FINALS_FOLDER, - "feature_distribution_" + - self.which_source + - "_adapted_to_" + - self.which_target + - ".png")) - - def run(self): - # get data - df_source = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_target = pd.read_csv(self.input()[1].path, header=[0, 1]) - - df_f_source = format_dataframe_for_distribution_plotting(df_source) - df_f_target = format_dataframe_for_distribution_plotting(df_target) - df_f_adapted = format_dataframe_for_distribution_plotting(df_source, - weights=df_source["weights"].values.squeeze()) - - # build a combined df - df_f_source["data"] = "source" - df_f_target["data"] = "target" - df_f_adapted["data"] = "adapted" - df = pd.concat([df_f_source, df_f_target, df_f_adapted]) - - # do the plotting - grid = sns.FacetGrid(df, col="w", hue="data", col_wrap=3, size=1.5) - grid.map(plt.plot, "bins", "frequency") - - # tidy up plot - grid.fig.tight_layout(w_pad=1) - grid.add_legend() - grid.set(xticks=(0, 1)) - - # finally save the figure - plt.savefig(self.output().path, dpi=500) - - -class DAvNormalPlot(luigi.Task): - which_train = luigi.Parameter() - which_test = luigi.Parameter() - which_train_no_covariance_shift = luigi.Parameter() - - def requires(self): - return WeightedBatch(self.which_train, self.which_test), \ - tasks_mc.CameraBatch(self.which_test), \ - tasks_mc.CameraBatch(self.which_train_no_covariance_shift) - - def output(self): - return luigi.LocalTarget(os.path.join(sp.ROOT_FOLDER, - sp.RESULTS_FOLDER, - sp.FINALS_FOLDER, - "da_v_normal_train_" + - self.which_train + - "_test_" + self.which_test + - ".png")) - - def run(self): - # get data - df_train = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_test = pd.read_csv(self.input()[1].path, header=[0, 1]) - df_train_no_covariance_shift = pd.read_csv(self.input()[2].path, - header=[0, 1]) - - evaluation_setups = [EvaluationStruct("Proposed", rf)] - # evaluate the different methods - df_adapted = evaluate_data(df_train, noise_levels, - df_test, noise_levels, - evaluation_setups=evaluation_setups) - df_adapted["data"] = "adapted" - df_no_adaptation = evaluate_data( - df_train.drop("weights", axis=1), noise_levels, - df_test, noise_levels, - evaluation_setups=evaluation_setups) - df_no_adaptation["data"] = "source" - df_no_covariance_shift = evaluate_data( - df_train_no_covariance_shift, noise_levels, - df_test, noise_levels, - evaluation_setups=evaluation_setups) - df_no_covariance_shift["data"] = "target" - df = pd.concat([df_adapted, df_no_adaptation, df_no_covariance_shift]) - - # plot it - sns.boxplot(data=df, x="noise added [sigma %]", y="Errors", hue="data", - hue_order=["source", "adapted", "target"], fliersize=0) - # tidy up plot - plt.ylim((0, 40)) - plt.legend(loc='upper left') - - # finally save the figure - plt.savefig(self.output().path, dpi=500) - - -def format_dataframe_for_distribution_plotting(df, weights=None): - if weights is None: - weights = np.ones(df.shape[0]) - - bins = np.arange(0, 1, 0.01) - - # we're only interested in reflectance information - df_formatted = df.loc[:, "reflectances"] - # to [nm] for plotting - df_formatted.rename(columns=lambda x: float(x)*10**9, inplace=True) - - # transform data to a histogram - df_formatted = df_formatted.apply(lambda x: - pd.Series(np.histogram(x, bins=bins, - weights=weights, - normed=True)[0]), - axis=0) - # convert to long form using bins as identifier - df_formatted["bins"] = bins[1:] - df_formatted = pd.melt(df_formatted, id_vars=["bins"], - var_name="w", value_name="frequency") - - return df_formatted - - -if __name__ == '__main__': - logging.basicConfig(filename=os.path.join(sp.LOG_FOLDER, - "da_in_silico_plots" + - str(datetime.datetime.now()) + - '.log'), - level=logging.INFO) - ch = logging.StreamHandler() - ch.setLevel(logging.INFO) - logger = logging.getLogger() - logger.addHandler(ch) - luigi.interface.setup_interface_logging() - - source_domain = "ipcai_revision_generic" - target_domain = "ipcai_revision_colon_test" - - sch = luigi.scheduler.CentralPlannerScheduler() - w = luigi.worker.Worker(scheduler=sch) - # check how the graph looks with same domains for training and testing - w.add(DaNoisePlot(which_train="ipcai_revision_colon_train", - which_test="ipcai_revision_colon_test")) - # check how the graph looks without domain adaptation - w.add(NoisePlot(which_train=source_domain, which_test=target_domain)) - # Set a different testing domain to evaluate domain sensitivity - w.add(DaNoisePlot(which_train=source_domain, which_test=target_domain)) - - w.add(WeightDistributionPlot(which_source=source_domain, - which_target=target_domain)) - w.add(FeatureDistributionPlot(which_source=source_domain, - which_target=target_domain)) - # also plot distributions for equal domains to check for errors in data - w.add(FeatureDistributionPlot(which_source="ipcai_revision_colon_mean_scattering_train", - which_target="ipcai_revision_colon_mean_scattering_test")) - # plot how the generating model data (e.g. sao2 and vhb) is distributed - w.add(GeneratingDistributionPlot(which_source=source_domain, - which_target=target_domain)) - w.add(DAvNormalPlot(which_train=source_domain, which_test=target_domain, - which_train_no_covariance_shift="ipcai_revision_colon_train")) - w.run() diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/__init__.py b/Modules/Biophotonics/python/iMC/scripts/ipcai2016/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_silico.py b/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_silico.py deleted file mode 100644 index 0db37b69f9..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_silico.py +++ /dev/null @@ -1,335 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 14 11:09:18 2015 - -@author: wirkert -""" - -import os -import logging -import datetime -from collections import namedtuple - -import matplotlib -import numpy as np -import pandas as pd -from pandas import DataFrame -import luigi -import matplotlib.pyplot as plt -from sklearn.ensemble.forest import RandomForestRegressor - -import tasks_mc -from regression.preprocessing import preprocess, preprocess2 -from regression.linear import LinearSaO2Unmixing - -import commons - -sc = commons.ScriptCommons() - -sc.add_dir("IN_SILICO_RESULTS_PATH", os.path.join(sc.get_dir("RESULTS_FOLDER"), - "in_silico")) - -sc.other["RECORDED_WAVELENGTHS"] = np.arange(470, 680, 10) * 10 ** -9 - -w_standard = 10. # for this evaluation we add 10% noise - -font = {'family' : 'normal', - 'size' : 20} - -matplotlib.rc('font', **font) - - -# setup standard random forest -rf = RandomForestRegressor(10, min_samples_leaf=10, max_depth=9, n_jobs=-1) -EvaluationStruct = namedtuple("EvaluationStruct", - "name regressor") -# standard evaluation setup -standard_evaluation_setups = [EvaluationStruct("Linear Beer-Lambert", - LinearSaO2Unmixing()) - , EvaluationStruct("Proposed", rf)] - -# color palette -my_colors = ["red", "green"] - -# standard noise levels -noise_levels = np.array([1,2,3,4,5,6,7,8,9,10, - 15,20,30,40,50,100,150,200]).astype("float") - - -class TrainingSamplePlot(luigi.Task): - which_train = luigi.Parameter() - which_test = luigi.Parameter() - - def requires(self): - return tasks_mc.CameraBatch(self.which_train), \ - tasks_mc.CameraBatch(self.which_test) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("IN_SILICO_RESULTS_PATH"), - "sample_plot_train_" + - self.which_train + - "_test_" + self.which_test + - ".pdf")) - - def run(self): - # get data - df_train = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_test = pd.read_csv(self.input()[1].path, header=[0, 1]) - - # for this plot we write a custom evaluation function as it is built - # a little different - - # create a new dataframe which will hold all the generated errors - df = pd.DataFrame() - - nr_training_samples = np.arange(10, 15010, 50).astype(int) - # not very pythonic, don't care - for n in nr_training_samples: - X_test, y_test = preprocess(df_test, snr=w_standard) - # only take n samples for training - X_train, y_train = preprocess(df_train, nr_samples=n, - snr=w_standard) - - regressor = rf - regressor.fit(X_train, y_train) - y_pred = regressor.predict(X_test) - # save results to a dataframe - errors = np.abs(y_pred - y_test) - errors = errors.reshape(len(errors), 1) - current_df = DataFrame(errors * 100, - columns=["Errors"]) - current_df["Method"] = "Proposed" - current_df["Number Samples"] = n / 10**3. - df = pd.concat([df, current_df], ignore_index=True) - logging.info( - "Finished training classifier with {0} samples".format( - str(n))) - - df = df.groupby("Number Samples").describe() - # get the error description in the rows: - df = df.unstack(-1) - # get rid of multiindex by dropping "Error" level - df.columns = df.columns.droplevel(0) - - plt.figure() - plt.plot(df.index, df["50%"], color="green") - - # tidy up the plot - plt.xlabel("number of training samples / 1000") - plt.ylabel("absolute error [%]") - plt.ylim((0, 20)) - plt.xlim((0, 15)) - plt.grid() - - # finally save the figure - plt.savefig(self.output().path, mode="pdf", dpi=500, - bbox_inches='tight') - - -class VhbPlot(luigi.Task): - which_train = luigi.Parameter() - which_test = luigi.Parameter() - - def requires(self): - return tasks_mc.CameraBatch(self.which_train), \ - tasks_mc.CameraBatch(self.which_test) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("IN_SILICO_RESULTS_PATH"), - "vhb_noise_plot_train_" + - self.which_train + - "_test_" + self.which_test + - ".pdf")) - - @staticmethod - def preprocess_vhb(batch, nr_samples=None, snr=None, - magnification=None, bands_to_sortout=None): - """ For evaluating vhb we extract labels for vhb instead of sao2""" - X, y = preprocess2(batch, nr_samples, snr, - magnification, bands_to_sortout) - - return X, y["vhb"].values - - def run(self): - # get data - df_train = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_test = pd.read_csv(self.input()[1].path, header=[0, 1]) - - # for vhb we only evaluate the proposed method since the linear - # beer-lambert is not applicable - evaluation_setups = [EvaluationStruct("Proposed", rf)] - df = evaluate_data(df_train, noise_levels, df_test, noise_levels, - evaluation_setups=evaluation_setups, - preprocessing=self.preprocess_vhb) - standard_plotting(df, color_palette=["green"], - xytext_position=(2, 3)) - plt.ylim((0, 4)) - - # finally save the figure - plt.savefig(self.output().path, dpi=500, - bbox_inches='tight') - - -class NoisePlot(luigi.Task): - which_train = luigi.Parameter() - which_test = luigi.Parameter() - - def requires(self): - return tasks_mc.CameraBatch(self.which_train), \ - tasks_mc.CameraBatch(self.which_test) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("IN_SILICO_RESULTS_PATH"), - "noise_plot_train_" + - self.which_train + - "_test_" + self.which_test + - ".pdf")) - - def run(self): - # get data - df_train = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_test = pd.read_csv(self.input()[1].path, header=[0, 1]) - - df = evaluate_data(df_train, noise_levels, df_test, noise_levels) - standard_plotting(df) - - # finally save the figure - plt.savefig(self.output().path, mode="pdf", dpi=500, - bbox_inches='tight') - - -class WrongNoisePlot(luigi.Task): - which_train = luigi.Parameter() - which_test = luigi.Parameter() - train_snr = luigi.FloatParameter() - - def requires(self): - return tasks_mc.CameraBatch(self.which_train), \ - tasks_mc.CameraBatch(self.which_test) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("IN_SILICO_RESULTS_PATH"), - str(self.train_snr) + - "_wrong_noise_plot_train_" + - self.which_train + - "_test_" + self.which_test + - ".pdf")) - - def run(self): - # get data - df_train = pd.read_csv(self.input()[0].path, header=[0, 1]) - df_test = pd.read_csv(self.input()[1].path, header=[0, 1]) - - # do same as in NoisePlot but with standard noise input - df = evaluate_data(df_train, - np.ones_like(noise_levels) * self.train_snr, - df_test, noise_levels) - standard_plotting(df) - - # finally save the figure - plt.savefig(self.output().path, mode="pdf", dpi=500, - bbox_inches='tight') - - -def evaluate_data(df_train, w_train, df_test, w_test, - evaluation_setups=None, preprocessing=None): - """ Our standard method to evaluate the data. It will fill a DataFrame df - which saves the errors for each evaluated setup""" - if evaluation_setups is None: - evaluation_setups = standard_evaluation_setups - if preprocessing is None: - preprocessing = preprocess - if ("weights" in df_train) and df_train["weights"].size > 0: - weights = df_train["weights"].as_matrix().squeeze() - else: - weights = np.ones(df_train.shape[0]) - - # create a new dataframe which will hold all the generated errors - df = pd.DataFrame() - for one_w_train, one_w_test in zip(w_train, w_test): - # setup testing function - X_test, y_test = preprocessing(df_test, snr=one_w_test) - # extract noisy data - X_train, y_train = preprocessing(df_train, snr=one_w_train) - for e in evaluation_setups: - regressor = e.regressor - regressor.fit(X_train, y_train, weights) - y_pred = regressor.predict(X_test) - # save results to a dataframe - errors = np.abs(y_pred - y_test) - errors = errors.reshape(len(errors), 1) - current_df = DataFrame(errors * 100, - columns=["Errors"]) - current_df["Method"] = e.name - current_df["SNR"] = int(one_w_test) - df = pd.concat([df, current_df], ignore_index=True) - - return df - - -def standard_plotting(df, color_palette=None, xytext_position=None): - if color_palette is None: - color_palette = my_colors - if xytext_position is None: - xytext_position = (2, 15) - - plt.figure() - - # group it by method and noise level and get description on the errors - df_statistics = df.groupby(['Method', 'SNR']).describe() - # get the error description in the rows: - df_statistics = df_statistics.unstack(-1) - # get rid of multiindex by dropping "Error" level - df_statistics.columns = df_statistics.columns.droplevel(0) - - # iterate over methods to plot linegraphs with error tube - # probably this can be done nicer, but no idea how exactly - - for color, method in zip( - color_palette, df_statistics.index.get_level_values("Method").unique()): - df_method = df_statistics.loc[method] - plt.plot(df_method.index, df_method["50%"], - color=color, label=method) - plt.fill_between(df_method.index, df_method["25%"], df_method["75%"], - facecolor=color, edgecolor=color, - alpha=0.5) - # tidy up the plot - plt.ylim((0, 40)) - plt.gca().set_xticks(np.arange(0, 200, 10), minor=True) - plt.xlabel("SNR") - plt.ylabel("absolute error [%]") - plt.grid() - plt.legend() - - -if __name__ == '__main__': - - sc.set_root("/media/wirkert/data/Data/2016_02_02_IPCAI/") - sc.create_folders() - - logging.basicConfig(filename=os.path.join(sc.get_full_dir("LOG_FOLDER"), - "in_silico_plots_" + - str(datetime.datetime.now()) + - '.log'), - level=logging.INFO) - ch = logging.StreamHandler() - ch.setLevel(logging.INFO) - logger = logging.getLogger() - logger.addHandler(ch) - luigi.interface.setup_interface_logging() - - train = "ipcai_revision_colon_mean_scattering_train" - test = "ipcai_revision_colon_mean_scattering_test" - - sch = luigi.scheduler.CentralPlannerScheduler() - w = luigi.worker.Worker(scheduler=sch) - w.add(TrainingSamplePlot(which_train=train, which_test=test)) - w.add(NoisePlot(which_train=train, which_test=test)) - w.add(WrongNoisePlot(which_train=train, which_test=test, train_snr=10.)) - w.add(WrongNoisePlot(which_train=train, which_test=test, train_snr=50.)) - w.add(WrongNoisePlot(which_train=train, which_test=test, train_snr=200.)) - # Set a different testing domain to evaluate domain sensitivity - w.add(NoisePlot(which_train=train, - which_test="ipcai_revision_generic_mean_scattering_test")) - w.add(VhbPlot(which_train=train, which_test=test)) - w.run() diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_vivo_liver.py b/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_vivo_liver.py deleted file mode 100644 index 2f547afe3f..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_vivo_liver.py +++ /dev/null @@ -1,294 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 14 11:09:18 2015 - -@author: wirkert -""" - - -import Image -import ImageEnhance -import logging -import datetime - -import SimpleITK as sitk -import matplotlib - -from msi.io.nrrdreader import NrrdReader -import msi.normalize as norm -from regression.estimation import estimate_image -from tasks_common import * -import commons -from msi.io.tiffringreader import TiffRingReader - -TiffRingReader.RESIZE_FACTOR = 0.5 - -sc = commons.ScriptCommons() - -sc.add_dir("LIVER_DATA", - os.path.join(sc.get_dir("DATA_FOLDER"), "liver_images")) -sc.add_dir("LIVER_RESULTS", os.path.join(sc.get_dir("RESULTS_FOLDER"), "liver")) - -sc.add_dir("FILTER_TRANSMISSIONS", - os.path.join(sc.get_dir("DATA_FOLDER"), - "filter_transmissions")) - -font = {'family' : 'normal', - 'size' : 30} -matplotlib.rc('font', **font) - - -class ResultsFile(luigi.Task): - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("LIVER_RESULTS"), - "results.csv")) - - -class OxyAndVhbOverTimeTask(luigi.Task): - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("LIVER_RESULTS"), - "liver_oxy_over_time.pdf")) - - def requires(self): - return ResultsFile() - - def run(self): - df = pd.read_csv(self.input().path, index_col=0) - # determine times from start: - image_name_strings = df["image name"].values - time_strings = map(lambda s: s[ - s.find("2014-08-03_")+11:s.find("2014-08-03_")+19], - image_name_strings) - time_in_s = map(lambda s: int(s[0:2]) * 3600 + - int(s[3:5]) * 60 + - int(s[6:]), time_strings) - df["time since drug delivery [s]"] = np.array(time_in_s) - time_in_s[0] - - # print oxy over time as scatterplot. - ax = df.plot.scatter(x="time since drug delivery [s]", - y="oxygenation mean [%]", - s=100, alpha=0.5, - fontsize=30) - ax.set_xlim((-1, 70)) - - plt.axvline(x=0, ymin=0, ymax=1, linewidth=2) - plt.axvline(x=56, ymin=0, ymax=1, linewidth=2) - ax.annotate('drug delivery', xy=(0, ax.get_ylim()[1]), - xycoords='data', xytext=(0, 0), - fontsize=30, - textcoords='offset points') - ax.annotate('porcine death', xy=(56, ax.get_ylim()[1]), - xycoords='data', xytext=(-100, 0), - fontsize=30, - textcoords='offset points') - ax.yaxis.label.set_size(30) - ax.xaxis.label.set_size(30) - plt.grid() - - df.to_csv(self.input().path) - - # create and save vhb plot - plt.savefig(self.output().path, - dpi=250, bbox_inches='tight', mode="pdf") - - # print vhb over time as scatterplot. - ax = df.plot.scatter(x="time since drug delivery [s]", - y="blood volume fraction mean [%]", - s=100, alpha=0.5, - fontsize=30) - ax.set_xlim((-1, 70)) - - plt.axvline(x=0, ymin=0, ymax=1, linewidth=2) - plt.axvline(x=56, ymin=0, ymax=1, linewidth=2) - ax.annotate('drug delivery', xy=(0, ax.get_ylim()[1]), - xycoords='data', xytext=(0, 0), - fontsize=30, - textcoords='offset points') - ax.annotate('porcine death', xy=(56, ax.get_ylim()[1]), - xycoords='data', xytext=(-100, 0), - fontsize=30, - textcoords='offset points') - ax.yaxis.label.set_size(30) - ax.xaxis.label.set_size(30) - plt.grid() - - plt.savefig(self.output().path + "_vhb_mean.pdf", - dpi=250, bbox_inches='tight', mode="pdf") - - -class IPCAICreateOxyImageTask(luigi.Task): - image_name = luigi.Parameter() - df_prefix = luigi.Parameter() - - def requires(self): - return IPCAITrainRegressor(df_prefix=self.df_prefix), \ - Flatfield(flatfield_folder=sc.get_full_dir("FLAT_FOLDER")), \ - SingleMultispectralImage(image=os.path.join( - sc.get_full_dir("LIVER_DATA"), self.image_name)), \ - Dark(dark_folder=sc.get_full_dir("DARK_FOLDER")) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("LIVER_RESULTS"), - self.image_name + "_" + - self.df_prefix + - "_oxy_summary" + ".png")) - - def run(self): - nrrd_reader = NrrdReader() - tiff_ring_reader = TiffRingReader() - # read the flatfield - flat = nrrd_reader.read(self.input()[1].path) - dark = nrrd_reader.read(self.input()[3].path) - # read the msi - nr_filters = len(sc.other["RECORDED_WAVELENGTHS"]) - msi, segmentation = tiff_ring_reader.read(self.input()[2].path, - nr_filters) - - # only take into account not saturated pixels. - segmentation = np.max(msi.get_image(), axis=-1) < 2000. - - # read the regressor - e_file = open(self.input()[0].path, 'r') - e = pickle.load(e_file) - - # correct image setup - position_filter_nr_in_string = self.image_name.find(" 2014") - 1 - filter_nr = int(self.image_name[ - position_filter_nr_in_string:position_filter_nr_in_string+1]) - original_order = np.arange(nr_filters) - new_image_order = np.concatenate(( - original_order[nr_filters - filter_nr:], - original_order[:nr_filters - filter_nr])) - # resort msi to restore original order - msimani.get_bands(msi, new_image_order) - # correct by flatfield - msimani.image_correction(msi, flat, dark) - - # create artificial rgb - rgb_image = msi.get_image()[:, :, [2, 3, 1]] - rgb_image /= np.max(rgb_image) - rgb_image *= 255. - - # preprocess the image - # sortout unwanted bands - print "1" - # zero values would lead to infinity logarithm, thus clip. - msi.set_image(np.clip(msi.get_image(), 0.00001, 2. ** 64)) - # normalize to get rid of lighting intensity - norm.standard_normalizer.normalize(msi) - # transform to absorption - msi.set_image(-np.log(msi.get_image())) - # normalize by l2 for stability - norm.standard_normalizer.normalize(msi, "l2") - print "2" - # estimate - sitk_image, time = estimate_image(msi, e) - image = sitk.GetArrayFromImage(sitk_image) - - plt.figure() - print "3" - rgb_image = rgb_image.astype(np.uint8) - im = Image.fromarray(rgb_image, 'RGB') - enh_brightness = ImageEnhance.Brightness(im) - im = enh_brightness.enhance(5.) - plotted_image = np.array(im) - top_left_axis = plt.gca() - top_left_axis.imshow(plotted_image, interpolation='nearest') - top_left_axis.xaxis.set_visible(False) - top_left_axis.yaxis.set_visible(False) - - plt.set_cmap("jet") - print "4" - # plot parametric maps - # first oxygenation - plt.figure() - oxy_image = image[:, :, 0] - segmentation[0, 0] = 1 - segmentation[0, 1] = 1 - oxy_image = np.ma.masked_array(oxy_image, ~segmentation) - oxy_image[np.isnan(oxy_image)] = 0. - oxy_image[np.isinf(oxy_image)] = 0. - oxy_mean = np.mean(oxy_image) - oxy_image[0, 0] = 0.0 - oxy_image[0, 1] = 1. - plot_image(oxy_image[:, :], plt.gca()) - plt.savefig(self.output().path, - dpi=250, bbox_inches='tight') - # second blood volume fraction - plt.figure() - vhb_image = image[:, :, 1] - vhb_image = np.ma.masked_array(vhb_image, ~segmentation) - vhb_image[np.isnan(vhb_image)] = 0. - vhb_image[np.isinf(vhb_image)] = 0. - vhb_image[0, 0] = 0.0 - vhb_image[0, 1] = 0.1 - vhb_image = np.clip(vhb_image, 0.0, 0.1) - vhb_mean = np.mean(vhb_image) - plot_image(vhb_image, plt.gca()) - plt.savefig(self.output().path + "vhb.png", - dpi=250, bbox_inches='tight') - - # store results summary in dataframe - df_image_results = pd.DataFrame(data=np.expand_dims([self.image_name, - oxy_mean * 100., - vhb_mean * 100., - time], 0), - columns=["image name", - "oxygenation mean [%]", - "blood volume fraction mean [%]", - "time to estimate"]) - - results_file = os.path.join(sc.get_full_dir("LIVER_RESULTS"), - "results.csv") - if os.path.isfile(results_file): - df_results = pd.read_csv(results_file, index_col=0) - df_results = pd.concat((df_results, df_image_results)).reset_index( - drop=True - ) - else: - df_results = df_image_results - - df_results.to_csv(results_file) - - print "5" - plt.close("all") - - -if __name__ == '__main__': - - # create a folder for the results if necessary - sc.set_root("/media/wirkert/data/Data/2016_02_02_IPCAI/") - sc.create_folders() - - # root folder there the data lies - logging.basicConfig(filename=os.path.join(sc.get_full_dir("LOG_FOLDER"), - "liver" + - str(datetime.datetime.now()) + - '.log'), level=logging.INFO) - luigi.interface.setup_interface_logging() - ch = logging.StreamHandler() - ch.setLevel(logging.INFO) - logger = logging.getLogger() - logger.addHandler(ch) - - sch = luigi.scheduler.CentralPlannerScheduler() - w = luigi.worker.Worker(scheduler=sch) - - onlyfiles = get_image_files_from_folder(sc.get_full_dir("LIVER_DATA")) - - first_invivo_image_files = filter(lambda image_name: "0 2014" in image_name, - onlyfiles) - - for f in first_invivo_image_files: - main_task = IPCAICreateOxyImageTask(image_name=f, - df_prefix="ipcai_revision_colon_mean_scattering_train") - w.add(main_task) - - w.run() - - oxygenation_over_time_task = OxyAndVhbOverTimeTask() - w.add(oxygenation_over_time_task) - w.run() - diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_vivo_small_bowel.py b/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_vivo_small_bowel.py deleted file mode 100644 index 6ce3da2895..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_analyze_ipcai_in_vivo_small_bowel.py +++ /dev/null @@ -1,276 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 14 11:09:18 2015 - -@author: wirkert -""" - -import Image -import ImageEnhance -import logging -import datetime - -import SimpleITK as sitk -import matplotlib - -from msi.io.nrrdreader import NrrdReader -import msi.normalize as norm -from regression.estimation import estimate_image -from tasks_common import * -import commons -from msi.io.tiffringreader import TiffRingReader - -TiffRingReader.RESIZE_FACTOR = 0.5 - -sc = commons.ScriptCommons() - - -sc.add_dir("SMALL_BOWEL_DATA", - os.path.join(sc.get_dir("DATA_FOLDER"), "small_bowel_images")) - -sc.add_dir("SMALL_BOWEL_RESULT", os.path.join(sc.get_dir("RESULTS_FOLDER"), - "small_bowel")) - -sc.add_dir("FILTER_TRANSMISSIONS", - os.path.join(sc.get_dir("DATA_FOLDER"), - "filter_transmissions")) - -font = {'family' : 'normal', - 'size' : 25} -matplotlib.rc('font', **font) - - -class ResultsFile(luigi.Task): - - def output(self): - return luigi.LocalTarget(os.path.join( - sc.get_full_dir("SMALL_BOWEL_RESULT"), "results.csv")) - - -class OxyOverTimeTask(luigi.Task): - - def output(self): - return luigi.LocalTarget(os.path.join( - sc.get_full_dir("SMALL_BOWEL_RESULT"), - "colon_oxy_over_time.pdf")) - - def requires(self): - return ResultsFile() - - def run(self): - df = pd.read_csv(self.input().path, index_col=0) - - # determine times from start: - image_name_strings = df["image name"].values - time_strings = map(lambda s: s[ - s.find("2015-10-08_")+11:s.find("2015-10-08_")+19], - image_name_strings) - time_in_s = map(lambda s: int(s[0:2]) * 3600 + - int(s[3:5]) * 60 + - int(s[6:]), time_strings) - df["time since first frame [s]"] = np.array(time_in_s) - time_in_s[0] - df["time since applying first clip [s]"] = df["time since first frame [s]"] - 4 - # print oxy over time as scatterplot. - plt.figure() - ax = df.plot.scatter(x="time since applying first clip [s]", - y="oxygenation mean [%]", fontsize=30, - s=50, alpha=0.5) - ax.set_xlim((-5, 600)) - - plt.axvline(x=0, ymin=0, ymax=1, linewidth=2) - plt.axvline(x=39, ymin=0, ymax=1, linewidth=2) - plt.axvline(x=100, ymin=0, ymax=1, linewidth=2) - plt.axvline(x=124, ymin=0, ymax=1, linewidth=2) - ax.annotate('1', xy=(0, ax.get_ylim()[1]), - fontsize=18, - color="blue", - xycoords='data', xytext=(-5, 0), - textcoords='offset points') - ax.annotate('2', xy=(39, ax.get_ylim()[1]), - fontsize=18, - color="blue", - xycoords='data', xytext=(-5, 0), - textcoords='offset points') - ax.annotate('3', xy=(100, ax.get_ylim()[1]), - fontsize=18, - color="blue", - xycoords='data', xytext=(-5, 0), - textcoords='offset points') - ax.annotate('4', xy=(124, ax.get_ylim()[1]), - fontsize=18, - color="blue", - xycoords='data', xytext=(-5, 0), - textcoords='offset points') - - plt.grid() - - df.to_csv(self.input().path) - - # save - plt.savefig(self.output().path, - dpi=250, bbox_inches='tight', mode="pdf") - - -def plot_image(image, axis): - im2 = axis.imshow(image, interpolation='nearest', alpha=1.0) - # axis.set_title(title, fontsize=5) - # divider = make_axes_locatable(axis) - # cax = divider.append_axes("right", size="10%", pad=0.05) - # cbar = plt.colorbar(im2, cax=cax) - # cbar.ax.tick_params(labelsize=5) - axis.xaxis.set_visible(False) - - -class IPCAICreateOxyImageTask(luigi.Task): - image_name = luigi.Parameter() - df_prefix = luigi.Parameter() - - def requires(self): - return IPCAITrainRegressor(df_prefix=self.df_prefix), \ - Flatfield(flatfield_folder=sc.get_full_dir("FLAT_FOLDER")), \ - SingleMultispectralImage(image=self.image_name), \ - Dark(dark_folder=sc.get_full_dir("DARK_FOLDER")) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("SMALL_BOWEL_RESULT"), - os.path.split(self.image_name)[1] + - "_" + self.df_prefix + - "_summary" + ".png")) - - def run(self): - nrrd_reader = NrrdReader() - tiff_ring_reader = TiffRingReader() - # read the flatfield - flat = nrrd_reader.read(self.input()[1].path) - dark = nrrd_reader.read(self.input()[3].path) - # read the msi - nr_filters = len(sc.other["RECORDED_WAVELENGTHS"]) - msi, segmentation = tiff_ring_reader.read(self.input()[2].path, - nr_filters) - # only take into account not saturated pixels. - segmentation = np.logical_and(segmentation, - (np.max(msi.get_image(), - axis=-1) < 1000.)) - - # read the regressor - e_file = open(self.input()[0].path, 'r') - e = pickle.load(e_file) - - # correct image setup - filter_nr = int(self.image_name[-6:-5]) - original_order = np.arange(nr_filters) - new_image_order = np.concatenate(( - original_order[nr_filters - filter_nr:], - original_order[:nr_filters - filter_nr])) - # resort msi to restore original order - msimani.get_bands(msi, new_image_order) - # correct by flatfield - msimani.image_correction(msi, flat, dark) - - # create artificial rgb - rgb_image = msi.get_image()[:, :, [2, 3, 1]] - rgb_image /= np.max(rgb_image) - rgb_image *= 255. - - # preprocess the image - # sortout unwanted bands - print "1" - # zero values would lead to infinity logarithm, thus clip. - msi.set_image(np.clip(msi.get_image(), 0.00001, 2. ** 64)) - # normalize to get rid of lighting intensity - norm.standard_normalizer.normalize(msi) - # transform to absorption - msi.set_image(-np.log(msi.get_image())) - # normalize by l2 for stability - norm.standard_normalizer.normalize(msi, "l2") - print "2" - # estimate - sitk_image, time = estimate_image(msi, e) - image = sitk.GetArrayFromImage(sitk_image) - - plt.figure() - print "3" - rgb_image = rgb_image.astype(np.uint8) - im = Image.fromarray(rgb_image, 'RGB') - enh_brightness = ImageEnhance.Brightness(im) - im = enh_brightness.enhance(10.) - plotted_image = np.array(im) - top_left_axis = plt.gca() - top_left_axis.imshow(plotted_image, interpolation='nearest') - top_left_axis.xaxis.set_visible(False) - top_left_axis.yaxis.set_visible(False) - - plt.set_cmap("jet") - print "4" - # plot parametric maps - segmentation[0, 0] = 1 - segmentation[0, 1] = 1 - oxy_image = np.ma.masked_array(image[:, :, 0], ~segmentation) - oxy_image[np.isnan(oxy_image)] = 0. - oxy_image[np.isinf(oxy_image)] = 0. - oxy_mean = np.mean(oxy_image) - oxy_image[0, 0] = 0.0 - oxy_image[0, 1] = 1. - - plot_image(oxy_image[:, :], plt.gca()) - - df_image_results = pd.DataFrame(data=np.expand_dims([self.image_name, - oxy_mean * 100., - time], 0), - columns=["image name", - "oxygenation mean [%]", - "time to estimate"]) - - results_file = os.path.join(sc.get_full_dir("SMALL_BOWEL_RESULT"), - "results.csv") - if os.path.isfile(results_file): - df_results = pd.read_csv(results_file, index_col=0) - df_results = pd.concat((df_results, df_image_results)).reset_index( - drop=True - ) - else: - df_results = df_image_results - - df_results.to_csv(results_file) - - plt.savefig(self.output().path, - dpi=250, bbox_inches='tight') - plt.close("all") - - -if __name__ == '__main__': - - # create a folder for the results if necessary - sc.set_root("/media/wirkert/data/Data/2016_02_02_IPCAI/") - sc.create_folders() - - # root folder there the data lies - logging.basicConfig(filename=os.path.join(sc.get_full_dir("LOG_FOLDER"), - "small_bowel_images" + - str(datetime.datetime.now()) + - '.log'), - level=logging.INFO) - luigi.interface.setup_interface_logging() - ch = logging.StreamHandler() - ch.setLevel(logging.INFO) - logger = logging.getLogger() - logger.addHandler(ch) - - sch = luigi.scheduler.CentralPlannerScheduler() - w = luigi.worker.Worker(scheduler=sch) - - - # determine files to process - files = get_image_files_from_folder(sc.get_full_dir("SMALL_BOWEL_DATA"), - suffix="F0.tiff", fullpath=True) - - for f in files: - main_task = IPCAICreateOxyImageTask(image_name=f, - df_prefix="ipcai_revision_colon_mean_scattering_te") - w.add(main_task) - w.run() - - oxygenation_over_time_task = OxyOverTimeTask() - w.add(oxygenation_over_time_task) - w.run() - diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_calculate_spectra.py b/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_calculate_spectra.py deleted file mode 100644 index 5ceb764c33..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/script_calculate_spectra.py +++ /dev/null @@ -1,123 +0,0 @@ -''' -Created on Sep 9, 2015 - -@author: wirkert -''' - - -import logging -import datetime -import os -import time - -import numpy as np -import luigi - -import commons -import mc.factories as mcfac -from mc.sim import SimWrapper -from mc.create_spectrum import create_spectrum - -# parameter setting -NR_BATCHES = 100 -NR_ELEMENTS_IN_BATCH = 1000 -# the wavelengths to be simulated -WAVELENGHTS = np.arange(450, 720, 2) * 10 ** -9 -NR_PHOTONS = 10 ** 6 - -# experiment configuration -MCI_FILENAME = "./temp.mci" -MCO_FILENAME = "temp.mco" -# this path definitly needs to be adapted by you -PATH_TO_MCML = "/home/wirkert/workspace/monteCarlo/gpumcml/fast-gpumcml/" -EXEC_MCML = "gpumcml.sm_20" - - -sc = commons.ScriptCommons() - - -class CreateSpectraTask(luigi.Task): - df_prefix = luigi.Parameter() - batch_nr = luigi.IntParameter() - nr_samples = luigi.IntParameter() - factory = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("MC_DATA_FOLDER"), - self.df_prefix + "_" + - str(self.batch_nr) + ".txt")) - - def run(self): - start = time.time() - # setup simulation wrapper - sim_wrapper = SimWrapper() - sim_wrapper.set_mci_filename(MCI_FILENAME) - sim_wrapper.set_mcml_executable(os.path.join(PATH_TO_MCML, EXEC_MCML)) - # setup model - tissue_model = self.factory.create_tissue_model() - tissue_model.set_mci_filename(sim_wrapper.mci_filename) - tissue_model.set_mco_filename(MCO_FILENAME) - tissue_model.set_nr_photons(NR_PHOTONS) - # setup array in which data shall be stored - batch = self.factory.create_batch_to_simulate() - batch.create_parameters(self.nr_samples) - # dataframe created by batch: - df = batch.df - # add reflectance column to dataframe - for w in WAVELENGHTS: - df["reflectances", w] = np.NAN - - # for each instance of our tissue model - for i in range(df.shape[0]): - # set the desired element in the dataframe to be simulated - tissue_model.set_dataframe_row(df.loc[i, :]) - logging.info("running simulation " + str(i) + " for\n" + - str(tissue_model)) - reflectances = create_spectrum(tissue_model, sim_wrapper, - WAVELENGHTS) - # store in dataframe - for r, w in zip(reflectances, WAVELENGHTS): - df["reflectances", w][i] = r - - # clean up temporarily created files - os.remove(MCI_FILENAME) - created_mco_file = os.path.join(PATH_TO_MCML, MCO_FILENAME) - if os.path.isfile(created_mco_file): - os.remove(created_mco_file) - # save the created output - f = open(self.output().path, 'w') - df.to_csv(f) - - end = time.time() - logging.info("time for creating batch of mc data: %.f s" % - (end - start)) - - -if __name__ == '__main__': - - # create a folder for the results if necessary - sc.set_root("/media/wirkert/data/Data/2016_02_02_IPCAI/") - sc.create_folders() - - logging.basicConfig(filename=os.path.join(sc.get_full_dir("LOG_FOLDER"), - "calculate_spectra" + - str(datetime.datetime.now()) + - '.log'), - level=logging.INFO) - ch = logging.StreamHandler() - ch.setLevel(logging.INFO) - logger = logging.getLogger() - logger.addHandler(ch) - luigi.interface.setup_interface_logging() - - sch = luigi.scheduler.CentralPlannerScheduler() - w = luigi.worker.Worker(scheduler=sch) - BATCH_NUMBERS = np.arange(0, NR_BATCHES, 1) - for i in BATCH_NUMBERS: - colon_task = CreateSpectraTask("ipcai_revision_generic_mean_scattering", - i, - NR_ELEMENTS_IN_BATCH, - mcfac.GenericMeanScatteringFactory()) - w.add(colon_task) - w.run() - diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/tasks_common.py b/Modules/Biophotonics/python/iMC/scripts/ipcai2016/tasks_common.py deleted file mode 100644 index 7df698175c..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/tasks_common.py +++ /dev/null @@ -1,166 +0,0 @@ - -import os -import pickle - -import numpy as np -import pandas as pd -import luigi -from sklearn.ensemble.forest import RandomForestRegressor -import matplotlib.pylab as plt -from mpl_toolkits.axes_grid1 import make_axes_locatable - -import tasks_mc -import commons -from msi.msi import Msi -from msi.io.nrrdwriter import NrrdWriter -import msi.msimanipulations as msimani -from regression.preprocessing import preprocess2 -from msi.io.tiffringreader import TiffRingReader - -sc = commons.ScriptCommons() - -""" -Collection of functions and luigi.Task s which are used by more than one script -""" - - -def get_image_files_from_folder(folder, - prefix="", suffix=".tiff", fullpath=False): - # small helper function to get all the image files in a folder - # it will only return files which end with suffix. - # if fullpath==True it will return the full path of the file, otherwise - # only the filename - # get all filenames - image_files = [f for f in os.listdir(folder) if - os.path.isfile(os.path.join(folder, f))] - image_files.sort() - image_files = [f for f in image_files if f.endswith(suffix)] - image_files = [f for f in image_files if f.startswith(prefix)] - if fullpath: # expand to full path if wished - image_files = [os.path.join(folder, f) for f in image_files] - return image_files - - -def plot_image(image, axis=None, title=None, cmap=None): - if axis is None: - axis = plt.gca() - if cmap is None: - im = axis.imshow(image, interpolation='nearest', alpha=1.0) - else: - im = axis.imshow(image, interpolation='nearest', alpha=1.0, - cmap=cmap) - divider = make_axes_locatable(axis) - cax = divider.append_axes("right", size="20%", pad=0.05) - cbar = plt.colorbar(im, cax=cax) - - axis.xaxis.set_visible(False) - axis.yaxis.set_visible(False) - if title is not None: - axis.set_title(title) - - -class IPCAITrainRegressor(luigi.Task): - df_prefix = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - "reg_small_bowel_" + - self.df_prefix)) - - def requires(self): - return tasks_mc.SpectroCamBatch(self.df_prefix) - - def run(self): - # extract data from the batch - df_train = pd.read_csv(self.input().path, header=[0, 1]) - - X, y = preprocess2(df_train, snr=10.) - # train regressor - reg = RandomForestRegressor(10, min_samples_leaf=10, max_depth=9, - n_jobs=-1) - # reg = KNeighborsRegressor(algorithm="auto") - # reg = LinearRegression() - # reg = sklearn.svm.SVR(kernel="rbf", degree=3, C=100., gamma=10.) - # reg = LinearSaO2Unmixing() - reg.fit(X, y.values) - # reg = LinearSaO2Unmixing() - # save regressor - regressor_file = self.output().open('w') - pickle.dump(reg, regressor_file) - regressor_file.close() - - -class SingleMultispectralImage(luigi.Task): - - image = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(self.image) - - -class Flatfield(luigi.Task): - - flatfield_folder = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - "flatfield.nrrd")) - - def run(self): - tiff_ring_reader = TiffRingReader() - nr_filters = len(sc.other["RECORDED_WAVELENGTHS"]) - - # analyze all the first image files - image_files = get_image_files_from_folder(self.flatfield_folder) - image_files = filter(lambda image_name: "F0" in image_name, image_files) - - # helper function to take maximum of two images - def maximum_of_two_images(image_1, image_name_2): - image_2 = tiff_ring_reader.read(os.path.join(self.flatfield_folder, - image_name_2), - nr_filters)[0].get_image() - return np.maximum(image_1, image_2) - - # now reduce to maximum of all the single images - flat_maximum = reduce(lambda x, y: maximum_of_two_images(x, y), - image_files, 0) - msi = Msi(image=flat_maximum) - msi.set_wavelengths(sc.other["RECORDED_WAVELENGTHS"]) - - # write flatfield as nrrd - writer = NrrdWriter(msi) - writer.write(self.output().path) - - -class Dark(luigi.Task): - dark_folder = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - "dark" + - ".nrrd")) - - def run(self): - tiff_ring_reader = TiffRingReader() - nr_filters = len(sc.other["RECORDED_WAVELENGTHS"]) - - # analyze all the first image files - image_files = get_image_files_from_folder(self.dark_folder, - suffix="F0.tiff") - - # returns the mean dark image vector of all inputted dark image - # overly complicated TODO SW: make this simple code readable. - dark_means = map(lambda image_name: - msimani.calculate_mean_spectrum( - tiff_ring_reader.read(os.path.join(self.dark_folder, image_name), - nr_filters)[0]), - image_files) - dark_means_sum = reduce(lambda x, y: x+y.get_image(), dark_means, 0) - final_dark_mean = dark_means_sum / len(dark_means) - - msi = Msi(image=final_dark_mean) - msi.set_wavelengths(sc.other["RECORDED_WAVELENGTHS"]) - - # write flatfield as nrrd - writer = NrrdWriter(msi) - writer.write(self.output().path) diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/tasks_mc.py b/Modules/Biophotonics/python/iMC/scripts/ipcai2016/tasks_mc.py deleted file mode 100644 index c3771dfd9d..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai2016/tasks_mc.py +++ /dev/null @@ -1,155 +0,0 @@ -''' -Created on Sep 10, 2015 - -@author: wirkert -''' - - - -import os - -import pandas as pd -import numpy as np -import luigi -from scipy.interpolate import interp1d -from sklearn.preprocessing import normalize - -import commons -import mc.dfmanipulations as dfmani -from msi.io.spectrometerreader import SpectrometerReader - -sc = commons.ScriptCommons() - - -class SpectrometerFile(luigi.Task): - input_file = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(self.input_file) - - -class FilterTransmission(luigi.Task): - input_file = luigi.Parameter() - - def requires(self): - return SpectrometerFile(self.input_file) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - "processed_transmission" + os.path.split(self.input_file)[1])) - - def run(self): - reader = SpectrometerReader() - filter_transmission = reader.read(self.input().path) - # filter high and low _wavelengths - wavelengths = filter_transmission.get_wavelengths() - fi_image = filter_transmission.get_image() - fi_image[wavelengths < 450 * 10 ** -9] = 0.0 - fi_image[wavelengths > 720 * 10 ** -9] = 0.0 - # filter elements farther away than +- 30nm - file_name = os.path.split(self.input_file)[1] - name_to_float = float(os.path.splitext(file_name)[0]) - fi_image[wavelengths < (name_to_float - 30) * 10 ** -9] = 0.0 - fi_image[wavelengths > (name_to_float + 30) * 10 ** -9] = 0.0 - # elements < 0 are set to 0. - fi_image[fi_image < 0.0] = 0.0 - - # write it to a dataframe - df = pd.DataFrame() - df["wavelengths"] = wavelengths - df["reflectances"] = fi_image - df.to_csv(self.output().path, index=False) - - -class JoinBatches(luigi.Task): - df_prefix = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - self.df_prefix + "_" + - "all" + ".txt")) - - def run(self): - # get all files in the search path - files = [f for f in os.listdir(sc.get_full_dir("MC_DATA_FOLDER")) - if os.path.isfile(os.path.join(sc.get_full_dir("MC_DATA_FOLDER"), f))] - # from these get only those who start with correct batch prefix - df_file_names = [os.path.join(sc.get_full_dir("MC_DATA_FOLDER"), f) - for f in files if f.startswith(self.df_prefix)] - # load these files - dfs = [pd.read_csv(f, header=[0, 1]) for f in df_file_names] - # now join them to one batch - joined_df = pd.concat(dfs, ignore_index=True) - # write it - joined_df.to_csv(self.output().path, index=False) - - -class CameraBatch(luigi.Task): - """takes a batch of reference data and converts it to the spectra - processed by a camera with the specified wavelengths assuming a 10nm FWHM""" - df_prefix = luigi.Parameter() - - def requires(self): - return JoinBatches(self.df_prefix) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - self.df_prefix + - "_all_virtual_camera.txt")) - - def run(self): - # load dataframe - df = pd.read_csv(self.input().path, header=[0, 1]) - # camera batch creation: - dfmani.fold_by_sliding_average(df, 6) - dfmani.interpolate_wavelengths(df, sc.other["RECORDED_WAVELENGTHS"]) - # write it - df.to_csv(self.output().path, index=False) - - -class SpectroCamBatch(luigi.Task): - """ - Same as CameraBatch in purpose but adapts the batch to our very specific - SpectroCam set-up. - """ - df_prefix = luigi.Parameter() - - def requires(self): - # all wavelengths must have been measured for transmission and stored in - # wavelength.txt files (e.g. 470.txt) - filenames = ((sc.other["RECORDED_WAVELENGTHS"] * 10**9).astype(int)).astype(str) - filenames = map(lambda name: FilterTransmission(os.path.join(sc.get_full_dir("FILTER_TRANSMISSIONS"), - name + - ".txt")), - filenames) - - return JoinBatches(self.df_prefix), filenames - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("INTERMEDIATES_FOLDER"), - self.df_prefix + - "_all_spectrocam.txt")) - - def run(self): - # load dataframe - df = pd.read_csv(self.input()[0].path, header=[0, 1]) - # camera batch creation: - new_reflectances = [] - for band in self.input()[1]: - df_filter = pd.read_csv(band.path) - interpolator = interp1d(df_filter["wavelengths"], - df_filter["reflectances"], - assume_sorted=False, bounds_error=False) - # use this to create new reflectances - interpolated_filter = interpolator(df["reflectances"]. - columns.astype(float)) - # normalize band response - normalize(interpolated_filter.reshape(1, -1), norm='l1', copy=False) - folded_reflectance = np.dot(df["reflectances"].values, - interpolated_filter) - new_reflectances.append(folded_reflectance) - new_reflectances = np.array(new_reflectances).T - dfmani.switch_reflectances(df, sc.other["RECORDED_WAVELENGTHS"], - new_reflectances) - # write it - df.to_csv(self.output().path, index=False) diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/__init__.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_image_hdf5.h5_list.txt b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_image_hdf5.h5_list.txt deleted file mode 100644 index 1a0f78a1b1..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_image_hdf5.h5_list.txt +++ /dev/null @@ -1 +0,0 @@ -ipcai_image_hdf5.h5 \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_solver.prototxt b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_solver.prototxt deleted file mode 100644 index d76ba8c7f1..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_solver.prototxt +++ /dev/null @@ -1,24 +0,0 @@ -# The train/test net protocol buffer definition -train_net: "ipcai_train.prototxt" -test_net: "ipcai_test.prototxt" -# test_iter specifies how many forward passes the test should carry out. -# In the case of MNIST, we have test batch size 100 and 100 test iterations, -# covering the full 10,000 testing images. -test_iter: 100 -# Carry out testing every 500 training iterations. -test_interval: 500 -# The base learning rate, momentum and the weight decay of the network. -base_lr: 0.01 -momentum: 0.0 -weight_decay: 0.0005 -# The learning rate policy -lr_policy: "inv" -gamma: 0.0001 -power: 0.75 -# Display every 100 iterations -display: 1000 -# The maximum number of iterations -max_iter: 10000 -# snapshot intermediate results -snapshot: 5000 -snapshot_prefix: "snapshot" diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test.prototxt b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test.prototxt deleted file mode 100644 index 72534d20a0..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test.prototxt +++ /dev/null @@ -1,77 +0,0 @@ -layer { - name: "data" - type: "HDF5Data" - top: "data" - top: "label" - hdf5_data_param { - source: "ipcai_test_hdf5.h5_list.txt" - batch_size: 50 - } -} -layer { - name: "fc1" - type: "InnerProduct" - bottom: "data" - top: "fc1" - inner_product_param { - num_output: 25 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "relu1" - type: "ReLU" - bottom: "fc1" - top: "fc1" -} -layer { - name: "fc2" - type: "InnerProduct" - bottom: "fc1" - top: "fc2" - inner_product_param { - num_output: 25 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "relu2" - type: "ReLU" - bottom: "fc2" - top: "fc2" -} -layer { - name: "score" - type: "InnerProduct" - bottom: "fc2" - top: "score" - inner_product_param { - num_output: 1 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "loss" - type: "EuclideanLoss" - bottom: "score" - bottom: "label" - top: "loss" -} diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test_hdf5.h5_list.txt b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test_hdf5.h5_list.txt deleted file mode 100644 index 691abad4da..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test_hdf5.h5_list.txt +++ /dev/null @@ -1 +0,0 @@ -ipcai_test_hdf5.h5 \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test_image.prototxt b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test_image.prototxt deleted file mode 100644 index 6bc1620c4f..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_test_image.prototxt +++ /dev/null @@ -1,70 +0,0 @@ - -layer { - name: "data" - type: "HDF5Data" - top: "data" - hdf5_data_param { - source: "ipcai_image_hdf5.h5_list.txt" - batch_size: 1263612 - } -} -layer { - name: "fc1" - type: "InnerProduct" - bottom: "data" - top: "fc1" - inner_product_param { - num_output: 25 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "relu1" - type: "ReLU" - bottom: "fc1" - top: "fc1" -} -layer { - name: "fc2" - type: "InnerProduct" - bottom: "fc1" - top: "fc2" - inner_product_param { - num_output: 25 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "relu2" - type: "ReLU" - bottom: "fc2" - top: "fc2" -} -layer { - name: "score" - type: "InnerProduct" - bottom: "fc2" - top: "score" - inner_product_param { - num_output: 1 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_train.prototxt b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_train.prototxt deleted file mode 100644 index d79b65aa90..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_train.prototxt +++ /dev/null @@ -1,77 +0,0 @@ -layer { - name: "data" - type: "HDF5Data" - top: "data" - top: "label" - hdf5_data_param { - source: "ipcai_train_hdf5.h5_list.txt" - batch_size: 100 - } -} -layer { - name: "fc1" - type: "InnerProduct" - bottom: "data" - top: "fc1" - inner_product_param { - num_output: 25 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "relu1" - type: "ReLU" - bottom: "fc1" - top: "fc1" -} -layer { - name: "fc2" - type: "InnerProduct" - bottom: "fc1" - top: "fc2" - inner_product_param { - num_output: 25 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "relu2" - type: "ReLU" - bottom: "fc2" - top: "fc2" -} -layer { - name: "score" - type: "InnerProduct" - bottom: "fc2" - top: "score" - inner_product_param { - num_output: 1 - weight_filler { - type: "xavier" - } - bias_filler { - type: "constant" - value: 0.1 - } - } -} -layer { - name: "loss" - type: "EuclideanLoss" - bottom: "score" - bottom: "label" - top: "loss" -} diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_train_hdf5.h5_list.txt b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_train_hdf5.h5_list.txt deleted file mode 100644 index d4b8316827..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/ipcai_train_hdf5.h5_list.txt +++ /dev/null @@ -1 +0,0 @@ -ipcai_train_hdf5.h5 \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_create_hdf5_database.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_create_hdf5_database.py deleted file mode 100644 index 3c416e3446..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_create_hdf5_database.py +++ /dev/null @@ -1,29 +0,0 @@ -import h5py, os -import pandas as pd - -from regression.preprocessing import preprocess - - -def create_hdf5(path_to_simulation_results, hdf5_name): - - df = pd.read_csv(path_to_simulation_results, header=[0, 1]) - - X, y = preprocess(df, snr=10.) - y = y.values - - with h5py.File(hdf5_name,'w') as H: - H.create_dataset('data', data=X ) # note the name X given to the dataset! - H.create_dataset('label', data=y ) # note the name y given to the dataset! - with open(hdf5_name + '_list.txt','w') as L: - L.write(hdf5_name) # list all h5 files you are going to use - - -data_root = "/media/wirkert/data/Data/2016_02_02_IPCAI/results/intermediate" - -TRAIN_IMAGES = os.path.join(data_root, - "ipcai_revision_colon_mean_scattering_train_all_spectrocam.txt") -TEST_IMAGES = os.path.join(data_root, - "ipcai_revision_colon_mean_scattering_test_all_spectrocam.txt") - -create_hdf5(TRAIN_IMAGES, "ipcai_train_hdf5.h5") -create_hdf5(TEST_IMAGES, "ipcai_test_hdf5.h5") diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_create_lmdb_database.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_create_lmdb_database.py deleted file mode 100644 index ad0160c8ce..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_create_lmdb_database.py +++ /dev/null @@ -1,52 +0,0 @@ - -import os - -import pandas as pd -import lmdb -import caffe - -from regression.preprocessing import preprocess - - -def create_lmdb(path_to_simulation_results, lmdb_name): - - df = pd.read_csv(path_to_simulation_results, header=[0, 1]) - - X, y = preprocess(df, snr=10.) - y = y.values * 1000 - - # We need to prepare the database for the size. We'll set it 10 times - # greater than what we theoretically need. There is little drawback to - # setting this too big. If you still run into problem after raising - # this, you might want to try saving fewer entries in a single - # transaction. - map_size = X.nbytes * 10 - - env = lmdb.open(lmdb_name, map_size=map_size) - - with env.begin(write=True) as txn: - # txn is a Transaction object - for i in range(X.shape[0]): - datum = caffe.proto.caffe_pb2.Datum() - datum.channels = X.shape[1] - datum.height = 1 - datum.width = 1 - datum.data = X[i].tobytes() # or .tostring() if numpy < 1.9 - datum.label = int(y[i]) - str_id = '{:08}'.format(i) - - # The encode is only essential in Python 3 - txn.put(str_id.encode('ascii'), datum.SerializeToString()) - - -data_root = "/media/wirkert/data/Data/2016_02_02_IPCAI/results/intermediate" - -TRAIN_IMAGES = os.path.join(data_root, - "ipcai_revision_colon_mean_scattering_train_all_spectrocam.txt") -TEST_IMAGES = os.path.join(data_root, - "ipcai_revision_colon_mean_scattering_test_all_spectrocam.txt") - -create_lmdb(TRAIN_IMAGES, "ipcai_train_lmdb") -create_lmdb(TEST_IMAGES, "ipcai_test_lmdb") - - diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_test_pretrained_model.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_test_pretrained_model.py deleted file mode 100644 index 688ad933ec..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_test_pretrained_model.py +++ /dev/null @@ -1,26 +0,0 @@ - -import time - -import caffe - -from ipcai2016.tasks_common import plot_image - -model_def = 'ipcai_test_image.prototxt' -model_weights = 'snapshot_iter_100000.caffemodel' - -net = caffe.Net(model_def, # defines the structure of the model - model_weights, # contains the trained weights - caffe.TEST) # use test mode (e.g., don't perform dropout) - -### perform classification - -start = time.time() -output = net.forward() -end = time.time() -estimation_time = end - start - -print "time necessary for estimating image parameters: " + str(estimation_time) + "s" - -image = output['score'].reshape(1029,1228) - -plot_image(image) \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_train_caffe.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_train_caffe.py deleted file mode 100644 index c269272502..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_caffe/script_train_caffe.py +++ /dev/null @@ -1,83 +0,0 @@ -from pylab import * - -import caffe -from caffe import layers as L, params as P - - -def ipcai(database, batch_size): - # our version of LeNet: a series of linear and simple nonlinear transformations - n = caffe.NetSpec() - - n.data, n.label = L.HDF5Data(batch_size=batch_size, source=database, ntop=2) - - n.fc1 = L.InnerProduct(n.data, num_output=25, weight_filler=dict(type='xavier'), - bias_filler=dict(type='constant', value=0.1)) - n.relu1 = L.ReLU(n.fc1, in_place=True) - n.fc2 = L.InnerProduct(n.relu1, num_output=25, weight_filler=dict(type='xavier'), - bias_filler=dict(type='constant', value=0.1)) - n.relu2 = L.ReLU(n.fc2, in_place=True) - n.score = L.InnerProduct(n.relu2, num_output=1, weight_filler=dict(type='xavier'), - bias_filler=dict(type='constant', value=0.1)) - n.loss = L.EuclideanLoss(n.score, n.label) - - return n.to_proto() - -with open('ipcai_train.prototxt', 'w') as f: - f.write(str(ipcai('ipcai_train_hdf5.h5_list.txt', 100))) - -with open('ipcai_test.prototxt', 'w') as f: - f.write(str(ipcai('ipcai_test_hdf5.h5_list.txt', 50))) - -caffe.set_device(0) -caffe.set_mode_gpu() - -### load the solver and create train and test nets -solver = None # ignore this workaround for lmdb data (can't instantiate two solvers on the same data) -solver = caffe.SGDSolver('ipcai_solver.prototxt') - -# each output is (batch size, feature dim, spatial dim) -print [(k, v.data.shape) for k, v in solver.net.blobs.items()] - -# just print the weight sizes (we'll omit the biases) -print [(k, v[0].data.shape) for k, v in solver.net.params.items()] - -solver.net.forward() # train net -print solver.test_nets[0].forward() # test net (there can be more than one) - -niter = 100000 -test_interval = 1000 -# losses will also be stored in the log -train_loss = zeros(niter) -test_acc = zeros(int(np.ceil(niter / test_interval))) -output = zeros((niter, 8, 10)) - -# the main solver loop -for it in range(niter): - solver.step(1) # SGD by Caffe - - # store the train loss - train_loss[it] = solver.net.blobs['loss'].data - - # store the output on the first test batch - # (start the forward pass at fc1 to avoid loading new data) - solver.test_nets[0].forward(start='fc1') - output[it] = solver.test_nets[0].blobs['score'].data[:8] - - # run a full test every so often - # (Caffe can also do this for us and write to a log, but we show here - # how to do it directly in Python, where more complicated things are easier.) - if it % test_interval == 0: - print 'Iteration', it, 'testing...' - mean = 0. - for i in range(100): - solver.test_nets[0].forward() - mean += np.sum(np.abs(np.squeeze(solver.test_nets[0].blobs['score'].data) - - solver.test_nets[0].blobs['label'].data)) - mean = mean / 5000 - test_acc[it // test_interval] = mean * 100. # % - -print "final testing accuracy: ", test_acc[-1] - - -print solver.test_nets[0].blobs['score'].data -print solver.test_nets[0].blobs['label'].data \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/__init__.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/input_data.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/input_data.py deleted file mode 100644 index d1d0d28e2b..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/input_data.py +++ /dev/null @@ -1,144 +0,0 @@ -"""Functions for downloading and reading MNIST data.""" -from __future__ import print_function -import gzip -import os -import urllib -import numpy -SOURCE_URL = 'http://yann.lecun.com/exdb/mnist/' -def maybe_download(filename, work_directory): - """Download the data from Yann's website, unless it's already here.""" - if not os.path.exists(work_directory): - os.mkdir(work_directory) - filepath = os.path.join(work_directory, filename) - if not os.path.exists(filepath): - filepath, _ = urllib.urlretrieve(SOURCE_URL + filename, filepath) - statinfo = os.stat(filepath) - print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.') - return filepath -def _read32(bytestream): - dt = numpy.dtype(numpy.uint32).newbyteorder('>') - return numpy.frombuffer(bytestream.read(4), dtype=dt) -def extract_images(filename): - """Extract the images into a 4D uint8 numpy array [index, y, x, depth].""" - print('Extracting', filename) - with gzip.open(filename) as bytestream: - magic = _read32(bytestream) - if magic != 2051: - raise ValueError( - 'Invalid magic number %d in MNIST image file: %s' % - (magic, filename)) - num_images = _read32(bytestream) - rows = _read32(bytestream) - cols = _read32(bytestream) - buf = bytestream.read(rows * cols * num_images) - data = numpy.frombuffer(buf, dtype=numpy.uint8) - data = data.reshape(num_images, rows, cols, 1) - return data -def dense_to_one_hot(labels_dense, num_classes=10): - """Convert class labels from scalars to one-hot vectors.""" - num_labels = labels_dense.shape[0] - index_offset = numpy.arange(num_labels) * num_classes - labels_one_hot = numpy.zeros((num_labels, num_classes)) - labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1 - return labels_one_hot -def extract_labels(filename, one_hot=False): - """Extract the labels into a 1D uint8 numpy array [index].""" - print('Extracting', filename) - with gzip.open(filename) as bytestream: - magic = _read32(bytestream) - if magic != 2049: - raise ValueError( - 'Invalid magic number %d in MNIST label file: %s' % - (magic, filename)) - num_items = _read32(bytestream) - buf = bytestream.read(num_items) - labels = numpy.frombuffer(buf, dtype=numpy.uint8) - if one_hot: - return dense_to_one_hot(labels) - return labels -class DataSet(object): - def __init__(self, images, labels, fake_data=False): - if fake_data: - self._num_examples = 10000 - else: - assert images.shape[0] == labels.shape[0], ( - "images.shape: %s labels.shape: %s" % (images.shape, - labels.shape)) - self._num_examples = images.shape[0] - # Convert shape from [num examples, rows, columns, depth] - # to [num examples, rows*columns] (assuming depth == 1) - assert images.shape[3] == 1 - images = images.reshape(images.shape[0], - images.shape[1] * images.shape[2]) - # Convert from [0, 255] -> [0.0, 1.0]. - images = images.astype(numpy.float32) - images = numpy.multiply(images, 1.0 / 255.0) - self._images = images - self._labels = labels - self._epochs_completed = 0 - self._index_in_epoch = 0 - @property - def images(self): - return self._images - @property - def labels(self): - return self._labels - @property - def num_examples(self): - return self._num_examples - @property - def epochs_completed(self): - return self._epochs_completed - def next_batch(self, batch_size, fake_data=False): - """Return the next `batch_size` examples from this data set.""" - if fake_data: - fake_image = [1.0 for _ in xrange(784)] - fake_label = 0 - return [fake_image for _ in xrange(batch_size)], [ - fake_label for _ in xrange(batch_size)] - start = self._index_in_epoch - self._index_in_epoch += batch_size - if self._index_in_epoch > self._num_examples: - # Finished epoch - self._epochs_completed += 1 - # Shuffle the data - perm = numpy.arange(self._num_examples) - numpy.random.shuffle(perm) - self._images = self._images[perm] - self._labels = self._labels[perm] - # Start next epoch - start = 0 - self._index_in_epoch = batch_size - assert batch_size <= self._num_examples - end = self._index_in_epoch - return self._images[start:end], self._labels[start:end] -def read_data_sets(train_dir, fake_data=False, one_hot=False): - class DataSets(object): - pass - data_sets = DataSets() - if fake_data: - data_sets.train = DataSet([], [], fake_data=True) - data_sets.validation = DataSet([], [], fake_data=True) - data_sets.test = DataSet([], [], fake_data=True) - return data_sets - TRAIN_IMAGES = 'train-images-idx3-ubyte.gz' - TRAIN_LABELS = 'train-labels-idx1-ubyte.gz' - TEST_IMAGES = 't10k-images-idx3-ubyte.gz' - TEST_LABELS = 't10k-labels-idx1-ubyte.gz' - VALIDATION_SIZE = 5000 - local_file = maybe_download(TRAIN_IMAGES, train_dir) - train_images = extract_images(local_file) - local_file = maybe_download(TRAIN_LABELS, train_dir) - train_labels = extract_labels(local_file, one_hot=one_hot) - local_file = maybe_download(TEST_IMAGES, train_dir) - test_images = extract_images(local_file) - local_file = maybe_download(TEST_LABELS, train_dir) - test_labels = extract_labels(local_file, one_hot=one_hot) - validation_images = train_images[:VALIDATION_SIZE] - validation_labels = train_labels[:VALIDATION_SIZE] - train_images = train_images[VALIDATION_SIZE:] - train_labels = train_labels[VALIDATION_SIZE:] - data_sets.train = DataSet(train_images, train_labels) - data_sets.validation = DataSet(validation_images, validation_labels) - data_sets.test = DataSet(test_images, test_labels) - return data_sets \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/input_ipcai_data.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/input_ipcai_data.py deleted file mode 100644 index 65429d72ad..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/input_ipcai_data.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Functions for downloading and reading ipcai data.""" -from __future__ import print_function - -import os - -import numpy -import pandas as pd - -from regression.preprocessing import preprocess - - -class DataSet(object): - def __init__(self, images, labels, fake_data=False): - if fake_data: - self._num_examples = 10000 - else: - assert images.shape[0] == labels.shape[0], ( - "images.shape: %s labels.shape: %s" % (images.shape, - labels.shape)) - self._num_examples = images.shape[0] - images = images.astype(numpy.float32) - self._images = images - self._labels = labels - if self._labels.ndim == 1: - self._labels = self._labels[:, numpy.newaxis] - self._epochs_completed = 0 - self._index_in_epoch = 0 - - @property - def images(self): - return self._images - - @property - def labels(self): - return self._labels - - @property - def num_examples(self): - return self._num_examples - - @property - def epochs_completed(self): - return self._epochs_completed - - def next_batch(self, batch_size, fake_data=False): - """Return the next `batch_size` examples from this data set.""" - if fake_data: - fake_image = [1.0 for _ in xrange(784)] - fake_label = 0 - return [fake_image for _ in xrange(batch_size)], [ - fake_label for _ in xrange(batch_size)] - start = self._index_in_epoch - self._index_in_epoch += batch_size - if self._index_in_epoch > self._num_examples: - # Finished epoch - self._epochs_completed += 1 - # Shuffle the data - perm = numpy.arange(self._num_examples) - numpy.random.shuffle(perm) - self._images = self._images[perm] - self._labels = self._labels[perm] - - # Start next epoch - start = 0 - self._index_in_epoch = batch_size - assert batch_size <= self._num_examples - end = self._index_in_epoch - return self._images[start:end], self._labels[start:end] - - -def read_data_sets(dir, fake_data=False): - - class DataSets(object): - pass - data_sets = DataSets() - if fake_data: - data_sets.train = DataSet([], [], fake_data=True) - data_sets.validation = DataSet([], [], fake_data=True) - data_sets.test = DataSet([], [], fake_data=True) - return data_sets - - TRAIN_IMAGES = "ipcai_revision_colon_mean_scattering_train_all_spectrocam.txt" - TEST_IMAGES = "ipcai_revision_colon_mean_scattering_test_all_spectrocam.txt" - - df_train = pd.read_csv(os.path.join(dir, TRAIN_IMAGES), header=[0, 1]) - df_test = pd.read_csv(os.path.join(dir, TEST_IMAGES), header=[0, 1]) - - train_images, train_labels = preprocess(df_train, snr=10.) - test_images, test_labels = preprocess(df_test, snr=10.) - - train_labels = train_labels.values - test_labels = test_labels.values - - VALIDATION_SIZE = 1 - - validation_images = train_images[:VALIDATION_SIZE] - validation_labels = train_labels[:VALIDATION_SIZE] - train_images = train_images[VALIDATION_SIZE:] - train_labels = train_labels[VALIDATION_SIZE:] - data_sets.train = DataSet(train_images, train_labels) - data_sets.validation = DataSet(validation_images, validation_labels) - data_sets.test = DataSet(test_images, test_labels) - return data_sets \ No newline at end of file diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/script_train_tensorflow_model.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/script_train_tensorflow_model.py deleted file mode 100644 index ee85401f73..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_tensorflow/script_train_tensorflow_model.py +++ /dev/null @@ -1,270 +0,0 @@ - -import Image -import ImageEnhance -import logging -import datetime - -import SimpleITK as sitk -import tensorflow as tf - -from regression.tensorflow_estimator import multilayer_perceptron, cnn -from regression.tensorflow_dataset import read_data_set -from ipcai2016.tasks_common import * -import commons -from msi.io.nrrdreader import NrrdReader -import msi.normalize as norm -from regression.estimation import estimate_image_tensorflow - -sc = commons.ScriptCommons() -sc.set_root("/media/wirkert/data/Data/2016_02_02_IPCAI/") -sc.create_folders() - -ipcai_dir = sc.get_full_dir("INTERMEDIATES_FOLDER") - -sc.add_dir("SMALL_BOWEL_DATA", - os.path.join(sc.get_dir("DATA_FOLDER"), "small_bowel_images")) - -sc.add_dir("TENSORFLOW_DATA", - os.path.join(sc.get_dir("INTERMEDIATES_FOLDER"), "TensorflowModels")) - -sc.add_dir("SMALL_BOWEL_RESULT", os.path.join(sc.get_dir("RESULTS_FOLDER"), - "small_bowel_tensorflow")) - -sc.add_dir("FILTER_TRANSMISSIONS", - os.path.join(sc.get_dir("DATA_FOLDER"), - "filter_transmissions")) - - - -def plot_image(image, axis): - im2 = axis.imshow(image, interpolation='nearest', alpha=1.0) - axis.xaxis.set_visible(False) - - -class TensorFlowCreateOxyImageTask(luigi.Task): - image_name = luigi.Parameter() - df_prefix = luigi.Parameter() - df_test_prefix = luigi.Parameter() - - def requires(self): - return TensorflowTrainRegressor(df_prefix=self.df_prefix, - df_test_prefix=self.df_test_prefix), \ - Flatfield(flatfield_folder=sc.get_full_dir("FLAT_FOLDER")), \ - SingleMultispectralImage(image=self.image_name), \ - Dark(dark_folder=sc.get_full_dir("DARK_FOLDER")) - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("SMALL_BOWEL_RESULT"), - os.path.split(self.image_name)[1] + - "_" + self.df_prefix + - "_summary" + ".png")) - - - def run(self): - nrrd_reader = NrrdReader() - tiff_ring_reader = TiffRingReader() - # read the flatfield - flat = nrrd_reader.read(self.input()[1].path) - dark = nrrd_reader.read(self.input()[3].path) - # read the msi - nr_filters = len(sc.other["RECORDED_WAVELENGTHS"]) - msi, segmentation = tiff_ring_reader.read(self.input()[2].path, - nr_filters, resize_factor=0.5) - # only take into account not saturated pixels. - segmentation = np.logical_and(segmentation, - (np.max(msi.get_image(), - axis=-1) < 1000.)) - - # correct image setup - filter_nr = int(self.image_name[-6:-5]) - original_order = np.arange(nr_filters) - new_image_order = np.concatenate(( - original_order[nr_filters - filter_nr:], - original_order[:nr_filters - filter_nr])) - # resort msi to restore original order - msimani.get_bands(msi, new_image_order) - # correct by flatfield - msimani.image_correction(msi, flat, dark) - - # create artificial rgb - rgb_image = msi.get_image()[:, :, [2, 3, 1]] - rgb_image /= np.max(rgb_image) - rgb_image *= 255. - - # preprocess the image - # sortout unwanted bands - print "1" - # zero values would lead to infinity logarithm, thus clip. - msi.set_image(np.clip(msi.get_image(), 0.00001, 2. ** 64)) - # normalize to get rid of lighting intensity - norm.standard_normalizer.normalize(msi) - # transform to absorption - msi.set_image(-np.log(msi.get_image())) - # normalize by l2 for stability - norm.standard_normalizer.normalize(msi, "l2") - print "2" - # estimate - path = sc.get_full_dir("TENSORFLOW_DATA") - sitk_image, time = estimate_image_tensorflow(msi, path) - image = sitk.GetArrayFromImage(sitk_image) - - plt.figure() - print "3" - rgb_image = rgb_image.astype(np.uint8) - im = Image.fromarray(rgb_image, 'RGB') - enh_brightness = ImageEnhance.Brightness(im) - im = enh_brightness.enhance(10.) - plotted_image = np.array(im) - top_left_axis = plt.gca() - top_left_axis.imshow(plotted_image, interpolation='nearest') - top_left_axis.xaxis.set_visible(False) - top_left_axis.yaxis.set_visible(False) - - plt.set_cmap("jet") - print "4" - # plot parametric maps - segmentation[0, 0] = 1 - segmentation[0, 1] = 1 - oxy_image = np.ma.masked_array(image[:, :], ~segmentation) - oxy_image[np.isnan(oxy_image)] = 0. - oxy_image[np.isinf(oxy_image)] = 0. - oxy_mean = np.mean(oxy_image) - oxy_image[0, 0] = 0.0 - oxy_image[0, 1] = 1. - - plot_image(oxy_image[:, :], plt.gca()) - - df_image_results = pd.DataFrame(data=np.expand_dims([self.image_name, - oxy_mean * 100., - time], 0), - columns=["image name", - "oxygenation mean [%]", - "time to estimate"]) - - results_file = os.path.join(sc.get_full_dir("SMALL_BOWEL_RESULT"), - "results.csv") - if os.path.isfile(results_file): - df_results = pd.read_csv(results_file, index_col=0) - df_results = pd.concat((df_results, df_image_results)).reset_index( - drop=True - ) - else: - df_results = df_image_results - - df_results.to_csv(results_file) - - plt.savefig(self.output().path, - dpi=250, bbox_inches='tight') - plt.close("all") - - -class TensorflowTrainRegressor(luigi.Task): - df_prefix = luigi.Parameter() - df_test_prefix = luigi.Parameter() - - def output(self): - return luigi.LocalTarget(os.path.join(sc.get_full_dir("TENSORFLOW_DATA"), - "model.ckpt")) - - def requires(self): - return tasks_mc.SpectroCamBatch(self.df_prefix), \ - tasks_mc.SpectroCamBatch(self.df_test_prefix) - - def run(self): - # extract data from the batch - tensorflow_dataset = read_data_set(self.input()[0].path) - test_dataset = read_data_set(self.input()[1].path) - - # train regressor - # Construct the desired model - - # Network Parameters - nr_filters = len(sc.other["RECORDED_WAVELENGTHS"]) - x = tf.placeholder("float", [None, nr_filters, 1, 1]) - # Construct the desired model - keep_prob = tf.placeholder("float") - # pred, regularizers = multilayer_perceptron(x, nr_filters, 100, 1, - # keep_prob) - pred = cnn(x, 1, keep_prob) - # define parameters - learning_rate = 0.0001 - training_epochs = 300 - batch_size = 100 - display_step = 1 - - # Define loss and optimizer - - y = tf.placeholder("float", [None, 1]) - cost = tf.reduce_mean(tf.square(pred - y)) - optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) - - # Initializing the variables - init = tf.initialize_all_variables() - - saver = tf.train.Saver() # defaults to saving all variables - - # Launch the graph - with tf.Session() as sess: - sess.run(init) - - # Training cycle - for epoch in range(training_epochs): - avg_cost = 0. - total_batch = int(tensorflow_dataset.num_examples/batch_size) - # Loop over all batches - for i in range(total_batch): - batch_xs, batch_ys = tensorflow_dataset.next_batch(batch_size) - # Fit training using batch data - x_image = np.reshape(batch_xs, [-1, nr_filters, 1, 1]) - sess.run(optimizer, feed_dict={x: x_image, y: batch_ys, - keep_prob: 0.75}) - # Compute average loss - avg_cost += sess.run(cost, feed_dict={x: x_image, y: batch_ys, - keep_prob: 1.0})/total_batch - # Display logs per epoch step - if epoch % display_step == 0: - print "Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost) - - # Test model - accuracy = tf.reduce_mean(tf.cast(tf.abs(pred-y), "float")) - x_test_image = np.reshape(test_dataset.images, [-1, nr_filters, 1, 1]) - print "Mean testing error:", accuracy.eval({x: x_test_image, - y: test_dataset.labels, - keep_prob:1.0}) - - print "Optimization Finished!" - saver.save(sess, self.output().path) - - -if __name__ == '__main__': - - # create a folder for the results if necessary - sc.set_root("/media/wirkert/data/Data/2016_02_02_IPCAI/") - sc.create_folders() - - # root folder there the data lies - logging.basicConfig(filename=os.path.join(sc.get_full_dir("LOG_FOLDER"), - "small_bowel_images" + - str(datetime.datetime.now()) + - '.log'), - level=logging.INFO) - luigi.interface.setup_interface_logging() - ch = logging.StreamHandler() - ch.setLevel(logging.INFO) - logger = logging.getLogger() - logger.addHandler(ch) - - sch = luigi.scheduler.CentralPlannerScheduler() - w = luigi.worker.Worker(scheduler=sch) - - # determine files to process - files = get_image_files_from_folder(sc.get_full_dir("SMALL_BOWEL_DATA"), - suffix="F0.tiff", fullpath=True) - - for f in files: - main_task = TensorFlowCreateOxyImageTask(image_name=f, - df_prefix="ipcai_revision_colon_mean_scattering_train", - df_test_prefix="ipcai_revision_colon_mean_scattering_test") - w.add(main_task) - w.run() - diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/__init__.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/input_icai_data.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/input_icai_data.py deleted file mode 100644 index 4aaf742da7..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/input_icai_data.py +++ /dev/null @@ -1,110 +0,0 @@ -""" -This tutorial introduces logistic regression using Theano and stochastic -gradient descent. - -Logistic regression is a probabilistic, linear classifier. It is parametrized -by a weight matrix :math:`W` and a bias vector :math:`b`. Classification is -done by projecting data points onto a set of hyperplanes, the distance to -which is used to determine a class membership probability. - -Mathematically, this can be written as: - -.. math:: - P(Y=i|x, W,b) &= softmax_i(W x + b) \\ - &= \frac {e^{W_i x + b_i}} {\sum_j e^{W_j x + b_j}} - - -The output of the model or prediction is then done by taking the argmax of -the vector whose i'th element is P(Y=i|x). - -.. math:: - - y_{pred} = argmax_i P(Y=i|x,W,b) - - -This tutorial presents a stochastic gradient descent optimization method -suitable for large datasets. - - -References: - - - textbooks: "Pattern Recognition and Machine Learning" - - Christopher M. Bishop, section 4.3.2 - -""" - -from __future__ import print_function - -import os - -import numpy -import pandas as pd -import numpy as np - -import theano -import theano.tensor as T - -from regression.preprocessing import preprocess - -__docformat__ = 'restructedtext en' - - -def create_dataset(path_to_simulation_results): - - df = pd.read_csv(path_to_simulation_results, header=[0, 1]) - - X, y = preprocess(df, snr=10.) - y = y.values - return X, y - - - -def load_data(data_root): - ''' Loads the dataset - - :type dataset: string - :param dataset: the path to the dataset (here MNIST) - ''' - - TRAIN_IMAGES = os.path.join(data_root, - "ipcai_revision_colon_mean_scattering_train_all_spectrocam.txt") - TEST_IMAGES = os.path.join(data_root, - "ipcai_revision_colon_mean_scattering_test_all_spectrocam.txt") - - train_set = create_dataset(TRAIN_IMAGES) - valid_set = create_dataset(TEST_IMAGES) - test_set = (np.load("sample_image.npy"), np.array([0])) - - def shared_dataset(data_xy, borrow=True): - """ Function that loads the dataset into shared variables - - The reason we store our dataset in shared variables is to allow - Theano to copy it into the GPU memory (when code is run on GPU). - Since copying data into the GPU is slow, copying a minibatch everytime - is needed (the default behaviour if the data is not in a shared - variable) would lead to a large decrease in performance. - """ - data_x, data_y = data_xy - shared_x = theano.shared(numpy.asarray(data_x, - dtype=theano.config.floatX), - borrow=borrow) - shared_y = theano.shared(numpy.asarray(data_y, - dtype=theano.config.floatX), - borrow=borrow) - # When storing data on the GPU it has to be stored as floats - # therefore we will store the labels as ``floatX`` as well - # (``shared_y`` does exactly that). But during our computations - # we need them as ints (we use labels as index, and if they are - # floats it doesn't make sense) therefore instead of returning - # ``shared_y`` we will have to cast it to int. This little hack - # lets ous get around this issue - return shared_x, shared_y - - test_set_x, test_set_y = shared_dataset(test_set, 0) - valid_set_x, valid_set_y = shared_dataset(valid_set) - train_set_x, train_set_y = shared_dataset(train_set) - - rval = [(train_set_x, train_set_y), (valid_set_x, valid_set_y), - (test_set_x, test_set_y)] - return rval - diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/logistic_sgd.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/logistic_sgd.py deleted file mode 100644 index 6ef9f732b3..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/logistic_sgd.py +++ /dev/null @@ -1,176 +0,0 @@ -""" -This tutorial introduces logistic regression using Theano and stochastic -gradient descent. - -Logistic regression is a probabilistic, linear classifier. It is parametrized -by a weight matrix :math:`W` and a bias vector :math:`b`. Classification is -done by projecting data points onto a set of hyperplanes, the distance to -which is used to determine a class membership probability. - -Mathematically, this can be written as: - -.. math:: - P(Y=i|x, W,b) &= softmax_i(W x + b) \\ - &= \frac {e^{W_i x + b_i}} {\sum_j e^{W_j x + b_j}} - - -The output of the model or prediction is then done by taking the argmax of -the vector whose i'th element is P(Y=i|x). - -.. math:: - - y_{pred} = argmax_i P(Y=i|x,W,b) - - -This tutorial presents a stochastic gradient descent optimization method -suitable for large datasets. - - -References: - - - textbooks: "Pattern Recognition and Machine Learning" - - Christopher M. Bishop, section 4.3.2 - -""" - -from __future__ import print_function - -import numpy - -import theano -import theano.tensor as T - - -__docformat__ = 'restructedtext en' - - -class LogisticRegression(object): - """Multi-class Logistic Regression Class - - The logistic regression is fully described by a weight matrix :math:`W` - and bias vector :math:`b`. Classification is done by projecting data - points onto a set of hyperplanes, the distance to which is used to - determine a class membership probability. - """ - - def __init__(self, input, n_in, n_out): - """ Initialize the parameters of the logistic regression - - :type input: theano.tensor.TensorType - :param input: symbolic variable that describes the input of the - architecture (one minibatch) - - :type n_in: int - :param n_in: number of input units, the dimension of the space in - which the datapoints lie - - :type n_out: int - :param n_out: number of output units, the dimension of the space in - which the labels lie - - """ - # start-snippet-1 - # initialize with 0 the weights W as a matrix of shape (n_in, n_out) - self.W = theano.shared( - value=numpy.zeros( - (n_in, n_out), - dtype=theano.config.floatX - ), - name='W', - borrow=True - ) - # initialize the biases b as a vector of n_out 0s - self.b = theano.shared( - value=numpy.zeros( - (n_out,), - dtype=theano.config.floatX - ), - name='b', - borrow=True - ) - - # symbolic expression for computing the matrix of class-membership - # probabilities - # Where: - # W is a matrix where column-k represent the separation hyperplane for - # class-k - # x is a matrix where row-j represents input training sample-j - # b is a vector where element-k represent the free parameter of - # hyperplane-k - #self.p_y_given_x = T.nnet.softmax(T.dot(input, self.W) + self.b) - self.p_y_given_x = T.max(T.dot(input, self.W) + self.b, axis = 1) - - - # symbolic description of how to compute prediction as class whose - # probability is maximal - self.y_pred = self.p_y_given_x - #self.y_pred = self.p_y_given_x - # end-snippet-1 - - # parameters of the model - self.params = [self.W, self.b] - - # keep track of model input - self.input = input - - def negative_log_likelihood(self, y): - """Return the mean of the negative log-likelihood of the prediction - of this model under a given target distribution. - - .. math:: - - \frac{1}{|\mathcal{D}|} \mathcal{L} (\theta=\{W,b\}, \mathcal{D}) = - \frac{1}{|\mathcal{D}|} \sum_{i=0}^{|\mathcal{D}|} - \log(P(Y=y^{(i)}|x^{(i)}, W,b)) \\ - \ell (\theta=\{W,b\}, \mathcal{D}) - - :type y: theano.tensor.TensorType - :param y: corresponds to a vector that gives for each example the - correct label - - Note: we use the mean instead of the sum so that - the learning rate is less dependent on the batch size - """ - # start-snippet-2 - # y.shape[0] is (symbolically) the number of rows in y, i.e., - # number of examples (call it n) in the minibatch - # T.arange(y.shape[0]) is a symbolic vector which will contain - # [0,1,2,... n-1] T.log(self.p_y_given_x) is a matrix of - # Log-Probabilities (call it LP) with one row per example and - # one column per class LP[T.arange(y.shape[0]),y] is a vector - # v containing [LP[0,y[0]], LP[1,y[1]], LP[2,y[2]], ..., - # LP[n-1,y[n-1]]] and T.mean(LP[T.arange(y.shape[0]),y]) is - # the mean (across minibatch examples) of the elements in v, - # i.e., the mean log-likelihood across the minibatch. - theano.printing.Print('p_y_given_x')(self.p_y_given_x) - theano.printing.Print('y')(y) - return T.mean(T.square(self.p_y_given_x - y)) - #return -T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]), y]) - # end-snippet-2 - - def errors(self, y): - """Return a float representing the number of errors in the minibatch - over the total number of examples of the minibatch ; zero one - loss over the size of the minibatch - - :type y: theano.tensor.TensorType - :param y: corresponds to a vector that gives for each example the - correct label - """ - - # check if y has same dimension of y_pred - if y.ndim != self.y_pred.ndim: - raise TypeError( - 'y should have the same shape as self.y_pred', - ('y', y.type, 'y_pred', self.y_pred.type) - ) - # check if y is of the correct datatype - if y.dtype.startswith('float'): - # the T.neq operator returns a vector of 0s and 1s, where 1 - # represents a mistake in prediction - return T.mean(T.abs_(self.y_pred - y)) - else: - raise NotImplementedError() - - - diff --git a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/script_train_theano_model.py b/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/script_train_theano_model.py deleted file mode 100644 index 32c2a7045e..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/ipcai_to_theano/script_train_theano_model.py +++ /dev/null @@ -1,445 +0,0 @@ - - -""" -This tutorial introduces the multilayer perceptron using Theano. - - A multilayer perceptron is a logistic regressor where -instead of feeding the input to the logistic regression you insert a -intermediate layer, called the hidden layer, that has a nonlinear -activation function (usually tanh or sigmoid) . One can use many such -hidden layers making the architecture deep. The tutorial will also tackle -the problem of MNIST digit classification. - -.. math:: - - f(x) = G( b^{(2)} + W^{(2)}( s( b^{(1)} + W^{(1)} x))), - -References: - - - textbooks: "Pattern Recognition and Machine Learning" - - Christopher M. Bishop, section 5 - -""" - -from __future__ import print_function - -import os -import sys -import timeit -import time - -import numpy -import numpy as np -import matplotlib.pylab as plt -import theano -import theano.tensor as T - - -from logistic_sgd import LogisticRegression -from input_icai_data import load_data -from ipcai2016.tasks_common import plot_image - -#theano.config.compute_test_value = 'warn' -#theano.config.mode = "FAST_COMPILE" -#theano.config.exception_verbosity='high' - -__docformat__ = 'restructedtext en' - - -# start-snippet-1 -class HiddenLayer(object): - def __init__(self, rng, input, n_in, n_out, W=None, b=None, - activation=T.tanh): - """ - Typical hidden layer of a MLP: units are fully-connected and have - sigmoidal activation function. Weight matrix W is of shape (n_in,n_out) - and the bias vector b is of shape (n_out,). - - NOTE : The nonlinearity used here is tanh - - Hidden unit activation is given by: tanh(dot(input,W) + b) - - :type rng: numpy.random.RandomState - :param rng: a random number generator used to initialize weights - - :type input: theano.tensor.dmatrix - :param input: a symbolic tensor of shape (n_examples, n_in) - - :type n_in: int - :param n_in: dimensionality of input - - :type n_out: int - :param n_out: number of hidden units - - :type activation: theano.Op or function - :param activation: Non linearity to be applied in the hidden - layer - """ - self.input = input - # end-snippet-1 - - # `W` is initialized with `W_values` which is uniformely sampled - # from sqrt(-6./(n_in+n_hidden)) and sqrt(6./(n_in+n_hidden)) - # for tanh activation function - # the output of uniform if converted using asarray to dtype - # theano.config.floatX so that the code is runable on GPU - # Note : optimal initialization of weights is dependent on the - # activation function used (among other things). - # For example, results presented in [Xavier10] suggest that you - # should use 4 times larger initial weights for sigmoid - # compared to tanh - # We have no info for other function, so we use the same as - # tanh. - if W is None: - W_values = numpy.asarray( - rng.uniform( - low=-numpy.sqrt(6. / (n_in + n_out)), - high=numpy.sqrt(6. / (n_in + n_out)), - size=(n_in, n_out) - ), - dtype=theano.config.floatX - ) - if activation == theano.tensor.nnet.sigmoid: - W_values *= 4 - - W = theano.shared(value=W_values, name='W', borrow=True) - - if b is None: - b_values = 0.1+numpy.zeros((n_out,), dtype=theano.config.floatX) - b = theano.shared(value=b_values, name='b', borrow=True) - - self.W = W - self.b = b - - lin_output = T.dot(input, self.W) + self.b - self.output = ( - lin_output if activation is None - else activation(lin_output) - ) - # parameters of the model - self.params = [self.W, self.b] - - -# start-snippet-2 -class MLP(object): - """Multi-Layer Perceptron Class - - A multilayer perceptron is a feedforward artificial neural network model - that has one layer or more of hidden units and nonlinear activations. - Intermediate layers usually have as activation function tanh or the - sigmoid function (defined here by a ``HiddenLayer`` class) while the - top layer is a softmax layer (defined here by a ``LogisticRegression`` - class). - """ - - def __init__(self, rng, input, n_in, n_hidden, n_out): - """Initialize the parameters for the multilayer perceptron - - :type rng: numpy.random.RandomState - :param rng: a random number generator used to initialize weights - - :type input: theano.tensor.TensorType - :param input: symbolic variable that describes the input of the - architecture (one minibatch) - - :type n_in: int - :param n_in: number of input units, the dimension of the space in - which the datapoints lie - - :type n_hidden: int - :param n_hidden: number of hidden units - - :type n_out: int - :param n_out: number of output units, the dimension of the space in - which the labels lie - - """ - - # Since we are dealing with a one hidden layer MLP, this will translate - # into a HiddenLayer with a tanh activation function connected to the - # LogisticRegression layer; the activation function can be replaced by - # sigmoid or any other nonlinear function - self.hiddenLayer1 = HiddenLayer( - rng=rng, - input=input, - n_in=n_in, - n_out=n_hidden, - activation=T.nnet.relu - ) - - self.hiddenLayer2 = HiddenLayer( - rng=rng, - input=self.hiddenLayer1.output, - n_in=n_hidden, - n_out=n_hidden, - activation=T.nnet.relu - ) - - # The logistic regression layer gets as input the hidden units - # of the hidden layer - self.logRegressionLayer = LogisticRegression( - input=self.hiddenLayer2.output, - n_in=n_hidden, - n_out=n_out - ) - # end-snippet-2 start-snippet-3 - # L1 norm ; one regularization option is to enforce L1 norm to - # be small - self.L1 = ( - abs(self.hiddenLayer1.W).sum() - + abs(self.hiddenLayer2.W).sum() - + abs(self.logRegressionLayer.W).sum() - ) - - # square of L2 norm ; one regularization option is to enforce - # square of L2 norm to be small - self.L2_sqr = ( - (self.hiddenLayer1.W ** 2).sum() - + (self.hiddenLayer2.W ** 2).sum() - + (self.logRegressionLayer.W ** 2).sum() - ) - - # negative log likelihood of the MLP is given by the negative - # log likelihood of the output of the model, computed in the - # logistic regression layer - self.negative_log_likelihood = ( - self.logRegressionLayer.negative_log_likelihood - ) - # same holds for the function computing the number of errors - self.errors = self.logRegressionLayer.errors - - self.y_pred = self.logRegressionLayer.y_pred - - # the parameters of the model are the parameters of the two layer it is - # made out of - self.params = self.hiddenLayer1.params +\ - self.hiddenLayer2.params +\ - self.logRegressionLayer.params - # end-snippet-3 - - # keep track of model input - self.input = input - - -def test_mlp(learning_rate=0.001, L1_reg=0.0001, L2_reg=0.0001, n_epochs=1000, - dataset="/media/wirkert/data/Data/2016_02_02_IPCAI/results/intermediate", - batch_size=20, n_hidden=25, - do_timing_test=False): - """ - Demonstrate stochastic gradient descent optimization for a multilayer - perceptron - - This is demonstrated on MNIST. - - :type learning_rate: float - :param learning_rate: learning rate used (factor for the stochastic - gradient - - :type L1_reg: float - :param L1_reg: L1-norm's weight when added to the cost (see - regularization) - - :type L2_reg: float - :param L2_reg: L2-norm's weight when added to the cost (see - regularization) - - :type n_epochs: int - :param n_epochs: maximal number of epochs to run the optimizer - - :type dataset: string - :param dataset: the path of the MNIST dataset file from - http://www.iro.umontreal.ca/~lisa/deep/data/mnist/mnist.pkl.gz - - - """ - - datasets = load_data(dataset) - - train_set_x, train_set_y = datasets[0] - valid_set_x, valid_set_y = datasets[1] - test_set_x, test_set_y = datasets[2] - - # compute number of minibatches for training and validation - n_train_batches = train_set_x.get_value(borrow=True).shape[0] // batch_size - n_valid_batches = valid_set_x.get_value(borrow=True).shape[0] // batch_size - - ###################### - # BUILD ACTUAL MODEL # - ###################### - print('... building the model') - - # allocate symbolic variables for the data - index = T.lscalar() # index to a [mini]batch - x = T.matrix('x') # the data is presented as rasterized images - x.tag.test_value = np.zeros((5000, 8)).astype('float32') - y = T.vector('y') # the labels are presented as 1D vector of - # [int] labels - y.tag.test_value = np.ones(5000).astype('float32') - - rng = numpy.random.RandomState(1234) - - # construct the MLP class - classifier = MLP( - rng=rng, - input=x, - n_in=8, - n_hidden=n_hidden, - n_out=1 - ) - - # start-snippet-4 - # the cost we minimize during training is the negative log likelihood of - # the model plus the regularization terms (L1 and L2); cost is expressed - # here symbolically - cost = ( - classifier.negative_log_likelihood(y) - + L1_reg * classifier.L1 - + L2_reg * classifier.L2_sqr - ) - # end-snippet-4 - - # compiling a Theano function that computes the mistakes that are made - # by the model on a minibatch - test_model = theano.function( - inputs=[], - outputs=classifier.y_pred, - givens={ - x: test_set_x - } - ) - - validate_model = theano.function( - inputs=[index], - outputs=classifier.errors(y), - givens={ - x: valid_set_x[index * batch_size:(index + 1) * batch_size], - y: valid_set_y[index * batch_size:(index + 1) * batch_size] - } - ) - - # start-snippet-5 - # compute the gradient of cost with respect to theta (sorted in params) - # the resulting gradients will be stored in a list gparams - gparams = [T.grad(cost, param) for param in classifier.params] - - # specify how to update the parameters of the model as a list of - # (variable, update expression) pairs - - # given two lists of the same length, A = [a1, a2, a3, a4] and - # B = [b1, b2, b3, b4], zip generates a list C of same size, where each - # element is a pair formed from the two lists : - # C = [(a1, b1), (a2, b2), (a3, b3), (a4, b4)] - updates = [ - (param, param - learning_rate * gparam) - for param, gparam in zip(classifier.params, gparams) - ] - - # compiling a Theano function `train_model` that returns the cost, but - # in the same time updates the parameter of the model based on the rules - # defined in `updates` - train_model = theano.function( - inputs=[index], - outputs=cost, - updates=updates, - givens={ - x: train_set_x[index * batch_size: (index + 1) * batch_size], - y: train_set_y[index * batch_size: (index + 1) * batch_size] - } - ) - # end-snippet-5 - - ############### - # TRAIN MODEL # - ############### - print('... training') - - # early-stopping parameters - patience = 10000 # look as this many examples regardless - patience_increase = 2 # wait this much longer when a new best is - # found - improvement_threshold = 0.995 # a relative improvement of this much is - # considered significant - validation_frequency = min(n_train_batches, patience // 2) - # go through this many - # minibatche before checking the network - # on the validation set; in this case we - # check every epoch - - best_validation_loss = numpy.inf - best_iter = 0 - test_score = 0. - start_time = timeit.default_timer() - - epoch = 0 - done_looping = False - - while (epoch < n_epochs):# and (not done_looping): - epoch = epoch + 1 - for minibatch_index in range(n_train_batches): - - minibatch_avg_cost = train_model(minibatch_index) - # iteration number - iter = (epoch - 1) * n_train_batches + minibatch_index - - if (iter + 1) % validation_frequency == 0: - # compute zero-one loss on validation set - validation_losses = [validate_model(i) for i - in range(n_valid_batches)] - this_validation_loss = numpy.mean(validation_losses) - - print( - 'epoch %i, minibatch %i/%i, validation error %f %%' % - ( - epoch, - minibatch_index + 1, - n_train_batches, - this_validation_loss * 100. - ) - ) - - # if we got the best validation score until now - if this_validation_loss < best_validation_loss: - #improve patience if loss improvement is good enough - if ( - this_validation_loss < best_validation_loss * - improvement_threshold - ): - patience = max(patience, iter * patience_increase) - - best_validation_loss = this_validation_loss - best_iter = iter - - if do_timing_test: - # test it on the test set - start = time.time() - test_predictions = test_model() - end = time.time() - estimation_time = end - start - print("time necessary for estimating image parameters: " + - str(estimation_time) + "s") - print(test_predictions.shape) - - if patience <= iter: - done_looping = True - #break - - end_time = timeit.default_timer() - print(('Optimization complete. Best validation score of %f %% ' - 'obtained at iteration %i, with test performance %f %%') % - (best_validation_loss * 100., best_iter + 1, test_score * 100.)) - print(('The code for file ' + - os.path.split(__file__)[1] + - ' ran for %.2fm' % ((end_time - start_time) / 60.)), file=sys.stderr) - - test_predictions = test_model() - image = test_predictions.reshape(1029,1228) - image[0, 0] = 0.0 - image[0, 1] = 1. - image = np.clip(image, 0., 1.) - plot_image(image) - plt.savefig("sample_image.png", - dpi=250, bbox_inches='tight') - -if __name__ == '__main__': - test_mlp() - diff --git a/Modules/Biophotonics/python/iMC/scripts/spielewiese/__init__.py b/Modules/Biophotonics/python/iMC/scripts/spielewiese/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/Modules/Biophotonics/python/iMC/scripts/spielewiese/monte_carlo_single_photon.py b/Modules/Biophotonics/python/iMC/scripts/spielewiese/monte_carlo_single_photon.py deleted file mode 100644 index 05f0afc7dd..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/spielewiese/monte_carlo_single_photon.py +++ /dev/null @@ -1,203 +0,0 @@ -from collections import OrderedDict -import numpy as np - -import theano -from theano.ifelse import ifelse -import theano.tensor as T -import theano.tensor.inplace as inplace -#from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams -from theano.tensor.shared_randomstreams import RandomStreams -import time - - -#theano.config.compute_test_value = 'warn' -#theano.config.exception_verbosity='high' -#theano.config.profile=True -#theano.config.mode = "FAST_RUN" -#theano.config.mode = "FAST_COMPILE" -#theano.config.scan.allow_gc =True -#theano.config.scan.allow_output_prealloc =False -#theano.optimizer_excluding="more_mem" - -# initializing -rng = RandomStreams(seed=234) -photons = 10**6 -SHELL_MAX = 101 - - -mu_a = T.scalar('mu_a') -# provide Theano with a default test-value -mu_a.tag.test_value = 2. -mu_s = T.scalar('mu_s') -mu_s.tag.test_value = 20. -microns_per_shell = T.scalar('microns_per_shell') -microns_per_shell.tag.test_value = 50. - -albedo = mu_s / (mu_s + mu_a) -shells_per_mfp = 1e4/microns_per_shell/(mu_a+mu_s) - -heat = theano.shared(np.zeros(SHELL_MAX, dtype=theano.config.floatX)) - -x = T.scalar('x') -x.tag.test_value = 0 - -y = T.scalar('y') -y.tag.test_value = 0 - -z = T.scalar('z') -z.tag.test_value = 0 - -u = T.scalar('u') -u.tag.test_value = 0 - -v = T.scalar('v') -v.tag.test_value = 0 - -w = T.scalar('w') -w.tag.test_value = 1 - -weight = T.scalar('weight') -weight.tag.test_value = 1 - - -def one_run(my_x, my_y, my_z, - my_u, my_v, my_w, - my_weight, - my_heat, my_albedo, my_microns_per_shell): - - # move - random = rng.uniform(low=0.00003, high=1.) - t = -T.log(random) - - x_moved = my_x + my_u*t - y_moved = my_y + my_v*t - z_moved = my_z + my_w*t - - # absorb - shell = T.cast(T.sqrt(T.sqr(x_moved) + T.sqr(y_moved) + T.sqr(z_moved)) - * my_microns_per_shell, 'int32') - shell = T.clip(shell, 0, SHELL_MAX-1) - - new_weight = my_weight * my_albedo - - # new direction - xi1 = rng.uniform(low=-1., high=1.) - xi2 = rng.uniform(low=-1., high=1.) - xi_norm = T.sqrt(T.sqr(xi1) + T.sqr(xi2)) - - t_xi = rng.uniform(low=0.000000001, high=1.) - - # rescale xi12 to fit t_xi as norm - xi1 = xi1/xi_norm * T.sqr(t_xi) - xi2 = xi2/xi_norm * T.sqr(t_xi) - - u_new_direction = 2. * t_xi - 1. - v_new_direction = xi1 * T.sqrt((1. - T.sqr(u_new_direction)) / t_xi) - w_new_direction = xi2 * T.sqrt((1. - T.sqr(u_new_direction)) / t_xi) - - # roulette - weight_for_starting_roulette = 0.001 - CHANCE = 0.1 - partakes_roulette = T.switch(T.lt(new_weight, weight_for_starting_roulette), - 1, - 0) - roulette = rng.uniform(low=0., high=1.) - loses_roulette = T.gt(roulette, CHANCE) - # if roulette decides to terminate the photon: set weight to 0 - weight_after_roulette = ifelse(T.and_(partakes_roulette, loses_roulette), - 0., - new_weight) - # if partakes in roulette but does not get terminated - weight_after_roulette = ifelse(T.and_(partakes_roulette, T.invert(loses_roulette)), - weight_after_roulette / CHANCE, - weight_after_roulette) - - new_heat = (1.0 - my_albedo) * my_weight - heat_i = my_heat[shell] - - return (x_moved, y_moved, z_moved,\ - u_new_direction, v_new_direction, w_new_direction,\ - weight_after_roulette),\ - OrderedDict({my_heat: T.inc_subtensor(heat_i, new_heat)}) - - -# one_photon_results, one_photon_updates = theano.scan(fn=one_run, -# outputs_info=[T.zeros_like(x), -# T.zeros_like(y), -# T.zeros_like(z), -# T.zeros_like(u), -# T.zeros_like(v), -# T.ones_like(w), -# T.ones_like(weight)], -# non_sequences=[heat, -# albedo, -# microns_per_shell], -# n_steps=100, -# strict=True) -# -# final_one_photon_heat_result = one_photon_updates[heat] - -# heat_for_one_photon = theano.function(inputs=[x, y, z, -# u, v, w, -# weight, -# mu_a, mu_s, microns_per_shell], -# outputs=final_one_photon_heat_result, -# updates=one_photon_updates) - - -def all_runs(my_x, my_y, my_z, - my_u, my_v, my_w, - my_weight, - my_heat, - my_albedo, my_microns_per_shell): - my_one_photon_results, my_one_photon_updates = theano.scan(fn=one_run, - outputs_info=[T.zeros_like(my_x), - T.zeros_like(my_y), - T.zeros_like(my_z), - T.zeros_like(my_u), - T.zeros_like(my_v), - T.ones_like(my_w), - T.ones_like(my_weight)], - non_sequences=[my_heat, - my_albedo, - my_microns_per_shell], - n_steps=10, - strict=True) - return {my_heat: my_one_photon_updates[my_heat]} - - -all_photon_results, all_photon_updates = theano.scan(fn=all_runs, - outputs_info=None, - non_sequences=[x, y, z, - u, v, w, - weight, - heat, - albedo, microns_per_shell], - n_steps=10, - strict=True) - - -heat_for_all_photons = theano.function(inputs=[x, y, z, - u, v, w, - weight, - mu_a, mu_s, microns_per_shell], - outputs=all_photon_updates[heat], - updates=all_photon_updates) - - - - - -start = time.time() - -print("start simulation") - -print(heat_for_all_photons(0., 0., 0., - 0., 0., 1., - 1., - 2., 20., 50.)) - -end = time.time() -print("end simulation after: " + str(end - start) + " seconds") - - diff --git a/Modules/Biophotonics/python/iMC/scripts/spielewiese/spielewiese.py b/Modules/Biophotonics/python/iMC/scripts/spielewiese/spielewiese.py deleted file mode 100644 index 871864547f..0000000000 --- a/Modules/Biophotonics/python/iMC/scripts/spielewiese/spielewiese.py +++ /dev/null @@ -1,130 +0,0 @@ -from collections import OrderedDict -import numpy as np - -import theano -import theano.tensor as T -from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams -#from theano.tensor.shared_randomstreams import RandomStreams -import time - -#theano.config.compute_test_value = 'warn' -#theano.config.exception_verbosity='high' -# initializing -rng = RandomStreams(seed=234) -photons = 10**6 -SHELL_MAX = 101 - -mu_a = T.scalar('mu_a') -# provide Theano with a default test-value -mu_a.tag.test_value = 2. -mu_s = T.scalar('mu_s') -mu_s.tag.test_value = 20. -microns_per_shell = T.scalar('microns_per_shell') -microns_per_shell.tag.test_value = 50. - -albedo = mu_s / (mu_s + mu_a) -shells_per_mfp = 1e4/microns_per_shell/(mu_a+mu_s) - - - - -finished = theano.shared(np.array(0, dtype='int8')) - -xyz = theano.shared(np.zeros((photons,3), dtype=theano.config.floatX)) - -uvw_np = np.zeros((photons,3), dtype=theano.config.floatX) -uvw_np[:,2] = 1. # w = 1 -uvw = theano.shared(uvw_np) - -#weights_np = np.ones((photons,1), dtype=theano.config.floatX) -weight = theano.shared(np.ones((photons,1), dtype=theano.config.floatX)) - -heat_np = np.zeros((SHELL_MAX,1), dtype=theano.config.floatX) -heat = theano.shared(heat_np) - - - - - - - - -# while sum alive > 0 - -def l2_norm_along_columns(A): - A_normed = T.sqrt(T.sum(T.sqr(A), axis=1)) - A_normed = A_normed.reshape((photons, 1)) - return A_normed - -# move -random = rng.uniform((photons,1), low=0.00003, high=1.) -t = -T.log(random) -t = T.addbroadcast(t, 1) - -xyz_moved = xyz + uvw*t -#theano.printing.Print('xyz_moved')(xyz_moved) - -# absorb -shells = T.cast(l2_norm_along_columns(xyz_moved) * shells_per_mfp, - 'int32') -shells = T.clip(shells, 0, SHELL_MAX-1) -new_heats = (1.0 - albedo) * weight -new_weight = weight * albedo -theano.printing.Print('shells')(shells) - -# new direction -xi12 = rng.uniform((photons,2), low=-1., high=1.) -xi_norm = l2_norm_along_columns(xi12) - -t_xi = rng.uniform((photons,1), low=0.000000001, high=1.) -t_xi = T.addbroadcast(t_xi, 1) - -# rescale xi12 to fit t_xi as norm -xi12 = xi12/xi_norm * T.sqr(t_xi) - -u_new_direction = 2. * t_xi - 1. -vw_new_direction = xi12 * T.sqrt((1. - T.sqr(u_new_direction)) / t_xi) -uvw_new_direction = T.concatenate([u_new_direction, vw_new_direction], axis=1) - -#theano.printing.Print('t_xi')(t_xi) -#theano.printing.Print('vw')(vw_new_direction) -#theano.printing.Print('uvw')(uvw_new_direction) -# roulette -weight_for_starting_roulette = 0.001 -CHANCE = 0.1 -partakes_roulette = T.switch(T.lt(new_weight, weight_for_starting_roulette), - 1, - 0) -roulette = rng.uniform((photons,1), low=0., high=1.) -loses_roulette = T.gt(roulette, CHANCE) -# if roulette decides to ter+minate the photon: set weight to 0 -weight_after_roulette = T.switch(T.and_(partakes_roulette, loses_roulette), - 0., - new_weight) -# if partakes in roulette but does not get terminated -weight_after_roulette = T.switch(T.and_(partakes_roulette, T.invert(loses_roulette)), - weight_after_roulette / CHANCE, - weight_after_roulette) -#theano.printing.Print('new weight')(new_weight) -#theano.printing.Print('partakes_roulette')(partakes_roulette) -#theano.printing.Print('loses_roulette')(loses_roulette) -#theano.printing.Print('weight_after_roulette')(weight_after_roulette) - - -one_cycle = theano.function(inputs=[mu_a, mu_s, microns_per_shell], - outputs=[shells, new_heats], - updates=OrderedDict({xyz: xyz_moved, uvw: uvw_new_direction, - weight: weight_after_roulette, - finished: T.allclose(weight, 0.)})) - - -start = time.time() -print("start simulation") - -while not finished.get_value(): - new_shells, new_heats = one_cycle(2, 20, 50) - -end = time.time() -print("end simulation after: " + str(end - start) + " seconds") - - diff --git a/Modules/Biophotonics/python/iMC/setup.py b/Modules/Biophotonics/python/iMC/setup.py deleted file mode 100644 index 9e04fc9ca8..0000000000 --- a/Modules/Biophotonics/python/iMC/setup.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Aug 7 18:41:50 2015 - -@author: wirkert -""" - -from setuptools import setup, find_packages - -setup(name='MITK-MSI', - version='0.1', - description='Multi spectral imaging (MSI) utilities', - author='Sebastian Wirkert', - author_email='s.wirkert@dkfz-heidelberg.de', - license='BSD', - packages=find_packages(exclude=['test*']), - package_dir={}, - package_data={'data': ['*.txt', '*.mci', '*.nrrd']}, - install_requires=['numpy>=1.10.2', 'scipy', 'scikit-learn>=0.17', - 'SimpleITK>=0.9.0', 'subprocess32', - 'pypng', 'pandas>0.17', 'libtiff'], - entry_points={} # for scripts, add later - ) diff --git a/Modules/Biophotonics/python/iMC/tox.ini b/Modules/Biophotonics/python/iMC/tox.ini deleted file mode 100644 index 51e0c9f594..0000000000 --- a/Modules/Biophotonics/python/iMC/tox.ini +++ /dev/null @@ -1,9 +0,0 @@ -# content of: tox.ini , put in same dir as setup.py -[tox] -envlist = py27 -[testenv] -deps=discover # install pytest in the venvs -install_command=pip install -f http://www.simpleitk.org/SimpleITK/resources/software.html --trusted-host www.simpleitk.org {opts} {packages} -#changedir=tests -commands=discover - diff --git a/Modules/Biophotonics/python/iMC/tutorials/Monte Carlo Spectra Generation - Basic tutorial.ipynb b/Modules/Biophotonics/python/iMC/tutorials/Monte Carlo Spectra Generation - Basic tutorial.ipynb deleted file mode 100644 index e5ea2b6e52..0000000000 --- a/Modules/Biophotonics/python/iMC/tutorials/Monte Carlo Spectra Generation - Basic tutorial.ipynb +++ /dev/null @@ -1,1018 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Creating and manipulating monte carlo spectra using MITK-MSI\n", - "\n", - "In this tutorial we will learn how to\n", - "1. create reflectance spectra from examplary tissues\n", - "2. how to analyse and visualize the created spectra\n", - "3. how to manipulate them\n", - "\n", - "The MITK-MSI software provides a wrapper to the popular MCML approach to simulate how light travels through tissue. This wrapper can be found in mc/sim.py.\n", - "In this tutorial we will utilize our tissue model which uses this wrapper to create the reflectance spectra.\n", - "\n", - "As a prerequisit, you need a MCML monte carlo simulation which uses the format specified [here](http://omlc.org/software/mc/).\n", - "I tested this software with the GPU accelerated version which can be found [here](https://code.google.com/archive/p/gpumcml/)." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "# 1.1 create spectra - setup simulation environment\n", - "\n", - "# some necessary imports\n", - "import logging\n", - "import numpy as np\n", - "import os\n", - "# everything related to the simulation wrapper\n", - "from mc import sim\n", - "# the factories create batches (tissue samples) and suited tissue models\n", - "from mc import factories\n", - "# function which runs simulations for each wavelength\n", - "from mc.create_spectrum import create_spectrum\n", - "\n", - "# Where does your monte carlo simulation executable resides in?\n", - "MCML_EXECUTABLE = \"/home/wirkert/workspace/monteCarlo/gpumcml/fast-gpumcml/gpumcml.sm_20\"\n", - "# The MCML needs a simulation input file, where shall it be created?\n", - "MCI_FILENAME = \"./temp.mci\"\n", - "# filename of the file with the simulation results. Due to a bug in GPUMCML will always\n", - "# be created in the same folder as the MCML executable\n", - "MCO_FILENAME = \"temp.mco\"\n", - "# The wavelengths for which we want to run our simulation\n", - "WAVELENGTHS = np.arange(450, 720, 2) * 10 ** -9\n", - "\n", - "# we want to create standard colonic tissue as specified in the IPCAI 2016 publication\n", - "# \"Robust Near Real-Time Estimation of Physiological Parameters from Megapixel\n", - "# Multispectral Images with Inverse Monte Carlo and Random Forest Regression\"\n", - "factory = factories.ColonMuscleMeanScatteringFactory()\n", - "# if you want to create data from the generic tissue mentioned in the paper, choose:\n", - "#factory = factories.GenericMeanScatteringFactory()\n", - "\n", - "# create a simulation wrapper\n", - "# the simulation wrapper wraps the mcml executable in python code\n", - "sim_wrapper = sim.SimWrapper()\n", - "# our simulation needs to know where the input file for the simulation\n", - "# shall resign (will be automatically created)\n", - "sim_wrapper.set_mci_filename(MCI_FILENAME)\n", - "# also it needs to know where the simulation executable shall lie in\n", - "sim_wrapper.set_mcml_executable(MCML_EXECUTABLE)\n", - "\n", - "# create the tissue model\n", - "# it is responsible for writing the simulation input file\n", - "tissue_model = factory.create_tissue_model()\n", - "# tell it where the input file shall lie in\n", - "tissue_model.set_mci_filename(sim_wrapper.mci_filename)\n", - "# also set the output filename\n", - "tissue_model.set_mco_filename(MCO_FILENAME)\n", - "# tell it how much photons shall be simulated. Will be set to 10**6 by standard,\n", - "# this is just an example\n", - "tissue_model.set_nr_photons(10**6)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
layer0layer1layer2
vhbsao2a_mieb_miedngvhbsao2a_mie...dngvhbsao2a_mieb_miedng
00.0037800.4475832425.9008821.2860.0009071.360.8726260.0689850.447583912.591151...0.0005031.360.9487000.0344270.4475833150.4940321.2860.0004541.380.804610
10.0211980.1844103022.1165321.2860.0007821.360.9302680.0638040.18441010.000000...0.0007351.360.8306010.0282470.1844103101.2614991.2860.0004301.380.813056
20.0520960.3074451171.3227581.2860.0008971.360.9249330.0210530.3074451433.788625...0.0007381.360.8073480.0066140.3074451002.5369011.2860.0004851.380.943837
30.0767990.4713041599.0386711.2860.0008781.360.9006370.0845040.4713043228.771326...0.0006051.360.9052220.0436740.4713041810.1143031.2860.0005041.380.868953
40.0531230.1081373524.4808851.2860.0010011.360.8334340.0953820.1081371988.134950...0.0006431.360.9209400.0312010.1081371731.7512831.2860.0005421.380.906191
50.0091470.866703372.7547991.2860.0009431.360.8412740.0949150.8667031660.695761...0.0005051.360.8569690.0092740.8667031991.3905631.2860.0004391.380.813544
60.0829030.2060322314.4154111.2860.0006631.360.8844920.0386080.206032459.458466...0.0005731.360.8505740.0637460.2060322728.8206781.2860.0004941.380.801766
70.0407190.2009561858.9101211.2860.0007721.360.8845160.0039300.2009563564.807750...0.0007661.360.9037640.0472570.2009561429.5744071.2860.0004681.380.849055
80.0288100.7296361751.8182481.2860.0008861.360.8133910.0074770.7296361388.286116...0.0008131.360.9141250.0929930.7296364001.4466131.2860.0005041.380.844552
90.0897580.6653973768.7091881.2860.0008001.360.8367110.0156480.6653971298.629577...0.0006201.360.9279040.0480230.6653973015.2893861.2860.0004271.380.893833
\n", - "

10 rows × 21 columns

\n", - "
" - ], - "text/plain": [ - " layer0 layer1 \\\n", - " vhb sao2 a_mie b_mie d n g vhb \n", - "0 0.003780 0.447583 2425.900882 1.286 0.000907 1.36 0.872626 0.068985 \n", - "1 0.021198 0.184410 3022.116532 1.286 0.000782 1.36 0.930268 0.063804 \n", - "2 0.052096 0.307445 1171.322758 1.286 0.000897 1.36 0.924933 0.021053 \n", - "3 0.076799 0.471304 1599.038671 1.286 0.000878 1.36 0.900637 0.084504 \n", - "4 0.053123 0.108137 3524.480885 1.286 0.001001 1.36 0.833434 0.095382 \n", - "5 0.009147 0.866703 372.754799 1.286 0.000943 1.36 0.841274 0.094915 \n", - "6 0.082903 0.206032 2314.415411 1.286 0.000663 1.36 0.884492 0.038608 \n", - "7 0.040719 0.200956 1858.910121 1.286 0.000772 1.36 0.884516 0.003930 \n", - "8 0.028810 0.729636 1751.818248 1.286 0.000886 1.36 0.813391 0.007477 \n", - "9 0.089758 0.665397 3768.709188 1.286 0.000800 1.36 0.836711 0.015648 \n", - "\n", - " ... layer2 \\\n", - " sao2 a_mie ... d n g vhb \n", - "0 0.447583 912.591151 ... 0.000503 1.36 0.948700 0.034427 \n", - "1 0.184410 10.000000 ... 0.000735 1.36 0.830601 0.028247 \n", - "2 0.307445 1433.788625 ... 0.000738 1.36 0.807348 0.006614 \n", - "3 0.471304 3228.771326 ... 0.000605 1.36 0.905222 0.043674 \n", - "4 0.108137 1988.134950 ... 0.000643 1.36 0.920940 0.031201 \n", - "5 0.866703 1660.695761 ... 0.000505 1.36 0.856969 0.009274 \n", - "6 0.206032 459.458466 ... 0.000573 1.36 0.850574 0.063746 \n", - "7 0.200956 3564.807750 ... 0.000766 1.36 0.903764 0.047257 \n", - "8 0.729636 1388.286116 ... 0.000813 1.36 0.914125 0.092993 \n", - "9 0.665397 1298.629577 ... 0.000620 1.36 0.927904 0.048023 \n", - "\n", - " \n", - " sao2 a_mie b_mie d n g \n", - "0 0.447583 3150.494032 1.286 0.000454 1.38 0.804610 \n", - "1 0.184410 3101.261499 1.286 0.000430 1.38 0.813056 \n", - "2 0.307445 1002.536901 1.286 0.000485 1.38 0.943837 \n", - "3 0.471304 1810.114303 1.286 0.000504 1.38 0.868953 \n", - "4 0.108137 1731.751283 1.286 0.000542 1.38 0.906191 \n", - "5 0.866703 1991.390563 1.286 0.000439 1.38 0.813544 \n", - "6 0.206032 2728.820678 1.286 0.000494 1.38 0.801766 \n", - "7 0.200956 1429.574407 1.286 0.000468 1.38 0.849055 \n", - "8 0.729636 4001.446613 1.286 0.000504 1.38 0.844552 \n", - "9 0.665397 3015.289386 1.286 0.000427 1.38 0.893833 \n", - "\n", - "[10 rows x 21 columns]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 1.2 create spectra - create tissue samples for simulation\n", - "\n", - "# setup batch with tissue instances which should be simulated\n", - "batch = factory.create_batch_to_simulate()\n", - "# we want to simulate ten tissue instances in this example\n", - "nr_samples = 10\n", - "df = batch.create_parameters(10)\n", - "\n", - "# lets have a look at the dataframe. Each row corresponds to one tissue instance,\n", - "# each tissue instance is defined by various layers, which all have certain parameters\n", - "# like e.g. oxygenation (here sao2)\n", - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
4.5e-074.52e-074.54e-074.56e-074.58e-074.6e-074.62e-074.64e-074.66e-074.68e-07...7e-077.02e-077.04e-077.06e-077.08e-077.1e-077.12e-077.14e-077.16e-077.18e-07
00.3186160.3469430.3712540.3798780.3855570.3890870.3948770.3977620.4010030.404130...0.4947310.4951620.4950680.4954260.4954470.4950080.4950810.4950930.4946230.494477
10.1402660.1896400.2435540.2597920.2755930.2848330.2963580.3023110.3088770.314986...0.4464260.4471380.4486750.4494690.4502970.4514850.4518860.4517670.4520540.452514
20.0217470.0351540.0562930.0651130.0736100.0807250.0889400.0945650.1008130.107133...0.3781550.3791120.3799530.3810480.3822710.3826990.3841090.3847810.3858160.386681
30.0219310.0319950.0459550.0517710.0569900.0616940.0676900.0713280.0760240.080335...0.4224780.4247930.4259650.4280110.4294140.4303710.4321060.4335270.4337730.435063
40.0692870.1071740.1597940.1774210.1961230.2080050.2219370.2313520.2392310.247642...0.4771400.4783930.4811330.4831720.4851440.4867610.4882540.4902850.4917000.492445
50.0456060.0513120.0585810.0627280.0653590.0689120.0734840.0759510.0801960.084404...0.3826210.3819220.3814710.3814510.3804810.3805680.3798410.3793170.3787140.378075
60.0273930.0446680.0708600.0810270.0912480.0985350.1074260.1125430.1184450.123929...0.3713010.3731900.3750970.3773240.3791270.3805240.3824810.3836580.3854440.386918
70.0489080.0788570.1249280.1422370.1596210.1722800.1868360.1968700.2060290.216111...0.4945830.4963940.4973510.4982170.4990100.4994520.5014810.5016000.5023150.503171
80.0867910.1051410.1258770.1359230.1430730.1511150.1602390.1656310.1738780.180887...0.5160760.5163510.5173030.5170440.5167270.5166640.5154350.5152280.5153230.514933
90.0563380.0714790.0890410.0970410.1033080.1094470.1168740.1209010.1278040.133711...0.5066700.5068890.5078580.5081430.5083510.5082180.5090400.5095760.5085060.508549
\n", - "

10 rows × 135 columns

\n", - "
" - ], - "text/plain": [ - " 4.500000e-07 4.520000e-07 4.540000e-07 4.560000e-07 4.580000e-07 \\\n", - "0 0.318616 0.346943 0.371254 0.379878 0.385557 \n", - "1 0.140266 0.189640 0.243554 0.259792 0.275593 \n", - "2 0.021747 0.035154 0.056293 0.065113 0.073610 \n", - "3 0.021931 0.031995 0.045955 0.051771 0.056990 \n", - "4 0.069287 0.107174 0.159794 0.177421 0.196123 \n", - "5 0.045606 0.051312 0.058581 0.062728 0.065359 \n", - "6 0.027393 0.044668 0.070860 0.081027 0.091248 \n", - "7 0.048908 0.078857 0.124928 0.142237 0.159621 \n", - "8 0.086791 0.105141 0.125877 0.135923 0.143073 \n", - "9 0.056338 0.071479 0.089041 0.097041 0.103308 \n", - "\n", - " 4.600000e-07 4.620000e-07 4.640000e-07 4.660000e-07 4.680000e-07 \\\n", - "0 0.389087 0.394877 0.397762 0.401003 0.404130 \n", - "1 0.284833 0.296358 0.302311 0.308877 0.314986 \n", - "2 0.080725 0.088940 0.094565 0.100813 0.107133 \n", - "3 0.061694 0.067690 0.071328 0.076024 0.080335 \n", - "4 0.208005 0.221937 0.231352 0.239231 0.247642 \n", - "5 0.068912 0.073484 0.075951 0.080196 0.084404 \n", - "6 0.098535 0.107426 0.112543 0.118445 0.123929 \n", - "7 0.172280 0.186836 0.196870 0.206029 0.216111 \n", - "8 0.151115 0.160239 0.165631 0.173878 0.180887 \n", - "9 0.109447 0.116874 0.120901 0.127804 0.133711 \n", - "\n", - " ... 7.000000e-07 7.020000e-07 7.040000e-07 7.060000e-07 \\\n", - "0 ... 0.494731 0.495162 0.495068 0.495426 \n", - "1 ... 0.446426 0.447138 0.448675 0.449469 \n", - "2 ... 0.378155 0.379112 0.379953 0.381048 \n", - "3 ... 0.422478 0.424793 0.425965 0.428011 \n", - "4 ... 0.477140 0.478393 0.481133 0.483172 \n", - "5 ... 0.382621 0.381922 0.381471 0.381451 \n", - "6 ... 0.371301 0.373190 0.375097 0.377324 \n", - "7 ... 0.494583 0.496394 0.497351 0.498217 \n", - "8 ... 0.516076 0.516351 0.517303 0.517044 \n", - "9 ... 0.506670 0.506889 0.507858 0.508143 \n", - "\n", - " 7.080000e-07 7.100000e-07 7.120000e-07 7.140000e-07 7.160000e-07 \\\n", - "0 0.495447 0.495008 0.495081 0.495093 0.494623 \n", - "1 0.450297 0.451485 0.451886 0.451767 0.452054 \n", - "2 0.382271 0.382699 0.384109 0.384781 0.385816 \n", - "3 0.429414 0.430371 0.432106 0.433527 0.433773 \n", - "4 0.485144 0.486761 0.488254 0.490285 0.491700 \n", - "5 0.380481 0.380568 0.379841 0.379317 0.378714 \n", - "6 0.379127 0.380524 0.382481 0.383658 0.385444 \n", - "7 0.499010 0.499452 0.501481 0.501600 0.502315 \n", - "8 0.516727 0.516664 0.515435 0.515228 0.515323 \n", - "9 0.508351 0.508218 0.509040 0.509576 0.508506 \n", - "\n", - " 7.180000e-07 \n", - "0 0.494477 \n", - "1 0.452514 \n", - "2 0.386681 \n", - "3 0.435063 \n", - "4 0.492445 \n", - "5 0.378075 \n", - "6 0.386918 \n", - "7 0.503171 \n", - "8 0.514933 \n", - "9 0.508549 \n", - "\n", - "[10 rows x 135 columns]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 1.3 create spectra - run simulation\n", - "\n", - "# add reflectance column to dataframe\n", - "for w in WAVELENGTHS:\n", - " df[\"reflectances\", w] = np.NAN # the reflectances have not been calculated yet, thus set no nan\n", - "\n", - "# for each instance in our batch\n", - "for i in range(df.shape[0]):\n", - " # set the desired element in the dataframe to be simulated\n", - " tissue_model.set_dataframe_row(df.loc[i, :])\n", - " logging.info(\"running simulation \" + str(i) + \" for\\n\" +\n", - " str(tissue_model))\n", - " reflectances = create_spectrum(tissue_model, sim_wrapper, WAVELENGTHS)\n", - " # store in dataframe\n", - " for r, w in zip(reflectances, WAVELENGTHS):\n", - " df[\"reflectances\", w][i] = r\n", - " \n", - "# clean up temporarily created files\n", - "os.remove(MCI_FILENAME)\n", - "created_mco_file = os.path.join(os.path.split(MCML_EXECUTABLE)[0], MCO_FILENAME)\n", - "if os.path.isfile(created_mco_file):\n", - " os.remove(created_mco_file)\n", - "\n", - "# Hooray, finished,\n", - "# now our dataframe also contains reflectances for each tissue instance:\n", - "df[\"reflectances\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbkAAAEPCAYAAADfx7pAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXd4FFXXwH+T3htphBZ6R3oRBBQVQewigo3XgqKv72fH\nrij2hooFsaCooFIEkSIIgQChhVADoQUS0usmm7rlfH9cWiAJKZs+v+eZZzMzd+7cu7vZM+eepokI\nOjo6Ojo6jRG7uh6Ajo6Ojo5OTaELOR0dHR2dRosu5HR0dHR0Gi26kNPR0dHRabToQk5HR0dHp9Gi\nCzkdHR0dnUZLjQs5TdOu0zTtkKZphzVNm1ZGm5GapkVpmrZf07T1NT0mHR0dHZ2mgVaTcXKaptkB\nh4FRQCKwA7hTRA6d18Yb2AJcKyIJmqb5i0h6jQ1KR0dHR6fJUNOa3EDgiIicFBETsAC46YI2k4BF\nIpIAoAs4HR0dHR1bUdNCrgUQf97+qdPHzqcT4Kdp2npN03ZomnZPDY9JR0dHR6eJ4FDXA0CNoS9w\nFeAORGiaFiEiR+t2WDo6Ojo6DZ2aFnIJQOvz9luePnY+p4B0ESkECjVN2whcBpQQcpqm6Uk2dXR0\ndKqAiGh1PYa6oqaXK3cAHTRNa6NpmhNwJ7DsgjZLgWGaptlrmuYGDAIOltaZiDTJ7bXXXqvzMejz\n1ueuz7thzr2pU6OanIhYNE37L/APSqB+JyIHNU17WJ2Wb0TkkKZpq4G9gAX4RkSia3JcDY0TJ07U\n9RDqhKY6b2i6c2+q84amPfeapMZtciKyCuh8wbHZF+x/CHxY02PR0dHR0Wla6BlPGgCTJ0+u6yHU\nCU113tB0595U5w1Ne+41SY0Gg9sSTdOkoYxVR0dHp76gaRqiO57o1GfCwsLqegh1QlOdNzTduTfV\neUPTnntNogs5HR0dHZ1Gi75cqaOjo9OI0ZcrdXR0dHR0Gim6kGsANNW1+qY6b2i6c2+q84amPfea\nRBdyOjo6OjqNFt0mp6Ojo9OI0W1yOjo6Ojo6jRRdyDUAmupafVOdNzTduTfVeUPtz93V1TVZ0zRp\nDJurq2tyWfOsD/XkdHR0dHRqmcLCwqDGYgLSNC2ozHMNZZK6TU5HR0en8pRlk2tMv6nl2R315Uod\nHR0dnUaLLuQaAE3VTtFU5w1Nd+5Ndd7QtOdek+hCTkdHR0en0aLb5HR0dHQaMbpNTkdHR0dHp56R\nlZXFLbfcgoeHB23btmX+/PlV6kcXcg2AprpW31TnDU137k113tC0514ajz76KC4uLqSlpfHzzz8z\ndepUDh48WOl+dCGno6Ojo1OvyM/PZ/HixcyYMQNXV1eGDh3KTTfdxLx58yrdl26T09HR0WnENESb\n3O7duxk2bBhGo/HssY8//pgNGzawdOnSi9qXZ5PTM57o6Ojo6FyEZqOUzlWRo0ajES8vrxLHvLy8\nyM3NrXRf+nJlA6CprtU31XlD0517U5031L+5i9hmqwoeHh7k5OSUOGYwGPD09Kx0X7qQ09HR0dGp\nV3Tq1Amz2cyxY8fOHtuzZw/du3evdF+6TU5HR0enEdMQbXIAkyZNQtM05syZw65du7jhhhvYsmUL\nXbt2vaitbpPT0dHRsTEiQnZhNsWWYrycvXCyd+JUzimOZx0nLT+NQnMhZquZQPdAQjxD8HTyxGw1\no2kaLb1a4uHkUWbfJouJxNxE7O3scXFwwdXBFRcHF+zt7GtxhnXLF198wf33309gYCD+/v58/fXX\npQq4S6Frcg2AsLAwRo4cWdfDqHWa6ryh6c69ruadb8onKTeJJGPS2desgiwKzYXkmfJIyE0gzhBH\ndmE2VrFisphIy0/Dyd4JZ3tncotzKbYU09yjOe392hPoHoirgyv2dvakGFNIyE0grzgPBzsHrGLl\nVM4p3J3cCfEMwdfFFy9nL5L2J+Hc3plkYzLxOfEEugciIhSaCykwF1BoLsROs8PFwQUXBxeaezTn\nsuDL6B7QHS9nLyUENXvMVjNWseLp7ImXsxfXd7q+QWpylUHX5HR0dBo9VrGSlJtEnCEOY7GRAnMB\nBaaCi16zCrNIzE0sIdCKzEU092xOc4/mZ199XXzxdPYkyCOI4W2G09q7NT4uPthr9tjb2RPoHoib\no1uJ+9tpFXNzEBGSjckkG5PJLswmpyiHGGsMQ4YNIdA9kLa+bXGyd7roGrPVfFboxRvi2ZOyh4Np\nBzmZfZJCSyFWseKgqZ91o8mIodBguze4gVLjmpymadcBM1FOLt+JyHsXnB8BLAWOnz60WERmlNJP\no3nq0NHRqRoiwqmcU2w9tZWtp7ayK3kX6fnpGAoNpOal4uPiQ2vv1ng5e+Hq6Iqrg+vZVzdHN1wd\nXPFx8blIoPm4+KDZyme+tjGZIDkZEhPB0RG6dAG3c8K3odrkKkN5mlyNCjlN0+yAw8AoIBHYAdwp\nIofOazMCeFpEbrxEX43mA9HR0SmbQnMhe5L3sC91H/tT95NsTMYqVvJN+UQlR2G2mhnccjCDWwym\nf0h/gjyC8Hb2JsA9oIRmVW8pKID8fCgshKKii1+Tk+HoUYiNBaNRtc3PV9cVFoK9PTg5QV6eEmzZ\n2RAYCM2bq/NHj0KzZkrgWa1ocXFNWsjV9HLlQOCIiJw8PZAFwE3AoQvaNdBHqNpBt880PRrz3PNN\n+exM3Em8IR6LWCi2FJOYm0icIY7N4ZuJ842jc7POZ+1Ng1oMwt7OHid7Jy4LuoxQn9D6qXXl5cH+\n/bB3L6SkgNUKFgvk5oLBAPHxEB0N6eng7g7OzuDicvY1rKiIkQEBEBAAHTvC4MHg5QWurmpzc1Nt\nLRalvbm6QosWqr39eQ4pFgucOqXur2nQtm3dvSf1gJoWci2A+PP2T6EE34UM0TRtN5AAPCsi0TU8\nLh0dnVogrziP2OxY9qbsJSI+gohTEUSnRdMjsAft/drjYOeAo50jIZ4hDGoxiJ79evLQbQ/Vf43M\naIQTJ9S2YwesWQN79qilwl69ICRECR47OyWIunWD225Tr61bq+MXEhYGlXywKSqCyG1KvppMkJUF\ncXH2xMW1IS4O4uJsMNcGTk0vV94GjBaRKaf37wYGisj/zmvjAVhFJF/TtDHApyLSqZS+Go1qraPT\nGBERTmSfYFPcJlYfW836E+vJLMikjXcbugV0Y0jLIQxpNYR+zfvh6uha18OtOGYzHD4M+/bB1q1K\nGB0+DG3aqK1XL7jmGhg2TGlmNkYEMjLU6uXJk+rvrCzYuRPWroUOHcDXV61OenurIbVurbZWraB3\n76Ztk6tpTS4BaH3efsvTx84iIsbz/l6padqXmqb5iUjmhZ1NnjyZ0NBQAHx8fOjdu/fZJZ0zKXH0\nfX1f36+9/eEjhvNXzF+8Ne8tDqYdxKuLF4NbDiY0K5T3O7zPxBsmYqfZqfYmGNZ6WL0a/9n99esh\nLo6RRUUQGUnYhg2QmspIsxkKCwkLCIB27Rg5Zgx8+SVheXng4FCyv61bqzUekwlcXEYSFQUbN4aR\nlAS5uSOJjQWRMJo3h+7dRxIQALm5YbRvD19+OZLAwJL9hYWFMXfuXLZv5+zvZVOmpjU5eyAG5XiS\nBGwHJorIwfPaBIlIyum/BwK/i0hoKX01mqeOyhLWiO0z5dFU5w31f+6ZBZn8uu9XZm2fhaezJ08N\nfopR7UYR6B5YrX5rbd5FRbBrF0REwJYtEB6ubF7Dh0P//tCnD6aWbYnPdOd4ijupWY5kZCjfD1Cm\nLldXZVorLFTLgsnJ58xgRUVK28rJUWa0M86ORqPqw9393H5WlvIdycoKw8VlJM7O6pzFopTIwkLV\n75n7eniAj4+6v9WqNhH16uICfn7qvIuL8k/57Tddk6sxRMSiadp/gX84F0JwUNO0h9Vp+Qa4XdO0\nqYAJKAAm1OSYdHR0qs7BtIO8sfENVhxZwdiOY/l63NeMaDOifjqCnIclPpGkxRHkrN6C1/4IApP2\nkOzdmePBl3Oi+S3sufxDtiaHcnINmFYoAZOXp0xrbdtCUJByWDwjrKxWJayMRiXEWrVSq5UODurc\nGcF2ZmkxKwvS0pQ/isGgVj5DQtTSYteuEBqqrrn2WnXdGT+TM387Op67b26u6q+oSJn2NO2MiU/I\nO1xA9gYDhbty4FghWnoRv9XRe15f0DOe6OjoXJLE3ESmh01n8aHFPHv5szzU9yF8XX1r7f4ikJkJ\nMTHKQTElRWk5RUWQlKScCfPywNVFaGE+ifep/TRLOUjXwl0MtkbgjpE9bkNIbTeEvF5DMHYdgIu/\nSqtlNoOnJ7Rvr4SOi4sSGp6eShOqCFlZsGGDGtuhQ8rB8vBh5SQZEKCcJJs3VwKta1cYOFD1X733\nRMg/mE/2hmwMGw1kb8gGDXxG+OA91BuX9i64tHLBo4dHg9TkvvjiC+bOncu+ffuYNGkS33//fZlt\n6yxOzpbU9w9ER6cxkpGfwXub3+PbXd/yQJ8HeOGKF/Bz9bNJ3yJKq0lJObclJ5fcP/+4iwt06qQc\nFENClHbj5AStPTLpmfovwfvW4L1jDXZFBRR26Y1jz6449r8My6DLoWNHXFxtp20mJsL27cqxMixM\naWaXXw6XXQadO0OPHsofxZZ+KCKCcY8RwwYl0AzhBuw97ZVQG+6NzwgfXNq6XKRVN9Rg8D///BM7\nOztWr15NQUGBLuQaM/XdPlNTNNV5Q93PPbcol5lbZ/Lptk+5vdvtvDz8ZVp6taxyf/HxyvS1davS\nxo4cUcecnNRSYFAQBAeD2RxG374jzx47/5ybG2q9budO1dn+/RAVpTq74grl4XjNNUoK2nD5tLhY\nRQds2aJMeBERSmscOBAGDFDLlFdcUX2BVtpnbsm3kPVvFhnLM8hYnoG9mz0+V/kowXaFNy6tLn3T\nhirkzvDKK6+QkJBQZSGn567U0dE5i1WszImcw2thr3F1u6vZ+uBWOvh1qNC1IkqAbdqk/Di2b1c2\nqZwctVx3+eUwZAhceaVaxmvTpkT2KaCMULH8fPj3X/jrL7X5+qpO+veH//xHvZ7x1rABKSnnhNmW\nLUqOtmunxj9mDLzxhhp/TZkhrWYrGcszSP4+meywbDz7e9JsXDNaPd0Kt071PH6wHqJrcjo6OgDs\nT93Pw8sfBuDLsV9yWfBlpbbLz1dCbM0aOH4642xhoVq6c3c/p9kMGaI0ME9PpeVUWiicOAFvvgl/\n/AH9+sENN6itY8eqT/ICRJQdLSzsnGDLzFTJRoYMUdugQUpI1xQiQuGJQnK25pCzNYe0RWm4tHEh\n5OEQmt3YDEcfx2r1X1VNTptuGykur1Xvd1vX5HR0dKqFiDBr+yze2PgGb175JlP6Tbkom/7x4/D3\n37BihdLUevdWK4OTJiknDQcHmD1beRlWYyDnMoisXQuLFsHUqerm/v7VmuP5t4iNhc2blaBevVod\nHzVKaZAvvqiSlthVrJhAlTDnmMndkauE2jYl2DQHDa/BXngN9qLXil549Cq71lxtUV3hVF/QhVwD\noK7tM3VFU5031N7cDYUGHlj2AMezjhPxQMTZpUkRFUa2YAEsX668B8eOhQcfVMe8vW00ALNZqYTL\nlsHy5YQVFDBy2DClPh08qBIP2wCDAebNgy+/VH8PHaqWH594Qnk71nQEhIiQHZZN4leJZK7KxOMy\nDzwHeRJ0bxAdv+iIc0tnNmzYQI+RPWp2IE0QXcjp6DRRIhMjuWPhHVzX/jp+vvVnXBxcyMyE775T\nm8mkNLV586BvXxtqN1archZZuFCpfyEhcPvtStglJSl7WzURgd27YdUqWLcOtm1T9rSvvlLx3jUt\n1My552lrpzU2R39HQqaG0HlOZxy89Z/eS2GxWDCZTFgsFsxmM0VFRTg4OGBvX7nq6LpNTkeniSEi\nfL3za14Ne5VZY2ZxXasJrF+vNLZFi+DGG+GRR5RdymbCwGyGP/+EOXOUi6Wfn1rvnDoV+vSpdvfZ\n2RAZqarM7N+v/FMcHGDcOLUUOXy4DbXPMihOKSb191RS56di3GvEo7eHWoIcpJYhnVs610nQfEP1\nrpw+fTrTp08v8Z699tprvPrqqxe11UMIdHR0AOU9+dTqp1gZs4YJ/MnGJR2JjFQOFtdeC/fco1z2\nbUZ8PPz8s9LYWraExx9XUscGNrbMTCU3Fy5UNrY+fZRPSqdOcN11KlatNjS2tIVppM5PJWd7Dv43\n+BM4KRDfUb7YOdWgYa8SNFQhVxl0IdfAaaq2qaY6b6iZuReaC7l70T3sikkj6+sl3HC1L7ffrhQq\nV1sWBcjLg8WL4ccflWFv/HhlzBsw4JKXXmre6emwZIkSbFu3qrGPH6/shdXNIFIZihKLOPXZKZLm\nJOF9hTdBdwXR7Ppm2LtVbintfGrq+97UhZy+MKyj0wQ4mHaQW3+dRNrBLvQ8upr1Ec60aWPDG1it\nsHGjEmx//qm8OqZMUWuf1YySFlFhch98oATbddcpmbl48blEx7WBKctE2qI00v5II2dbDsH3BtNv\nZz9c2zagskFNEF2T09Fp5Ly/bjavhb2Mw8a3eXf8g0ydqtnOicRigV9+genTlcS57z646y4VIFdN\nCgqUbe2TT5TN7YUXlH/KhQHkNU1BbAGnZp4iZV4KvqN8CRgfgN9YPxw8GoaOoGtyOjo6jRKjUbj+\no1fZlLmQ+5w28dGSzvjaMqfyunXwf/+nIqV/+EFFgFfTCGY2q25//RWWLlXJTJ58UhXVrqRTXfXG\nYTST/mc6KT+mkBuVS/MHmzNg3wCcW9gus0ptYLFa6noIdY4u5BoATdU21VTnDdWf+8qVwvhvn8Gx\n079se2Qj/bsG2G5wBgM8+6zyz//sM7jppmoJt8JCWL9eaW0LFoTRvv1IJk2Cd95Rmftri/zD+WSs\nyCBzRSY5ETl4D/Om+YPN6XFTD+xdal7ClveZW8VKijGF2OxY9qfuZ1/KPuJz4jEUGTAWG7HT7HCw\nc8BkMZFTlHN2KzAX1Pi46zu6kNPRaWQsWwaTvnqHVteEs2XqetuWxNm6FSZMUEFn+/dXK9/VkSPw\n+ecqDq9nT+XuP3Mm3Huv7YZ7KQpiC0j6Jom0hWlY8i00G9uMkKkhdF/YHQev2v95tIqVQ+mH2BK/\nhe0J2zmedZyThpPEG+LxcvYi1CeU7oHd6RnYkyvbXomPiw8eTh6ICGarGQc7B7xdvPFy9sLL2Qt3\nR3fsXqsfXp51hW6T09FpRCxZAg++uA/rvVex77GoalUOKIGICgN49VX49lvlUFIFMjKUw8hvv6ma\naw8+CI8+qqILapPsjdnEvRtHznblQBJ0bxAel3nUaBxbal4q0WnRHEg9wIG0A0SnRZNZkImTvRN2\nmh0peSkk5SbR0qslQ1sPZXCLwXTw60Abnza09m6Nm2PVjJG6TU5HR6dR8NNP8Ow0M0HT/sOTV7xt\nOwFnMMBjj6kUIps3VylBcmIivPuu0trOxICPHWvj0IVLIBYhc3Umce/FUXSqiNYvtKb7ou7Yu9pm\nKdIqVk5kn2Bvyl5OZp8koyCD1LxUDqUf4kDaAcxWM90DutM9oDvdArpxa9db8Xfzx2QxYRELwR7B\nNPdojrNDw7L71Xd0IdcAaKq2qaY6b6j83D/+WC313f3FR+wx+vBg3wdtM5AtW5S35OjRqnZOJVwb\nLRaV3f/XX5WG+Z//qKrZ5QWb18RnXpxaTNL3SSTNTsKhmQMt/68lgRMDsXOo/DJeWl4a2xO2sy91\nH/aaPR5OHiQZk4g4FcH2hO14OXvRK6gX7Xza0cytGT0De3J7t9vpHtCdYI/gcjXFsLAwQkeGVmOm\nOqWhCzkdnQbOG28oQTJ3+SHuWPUBO6fsrP6ym4hyKnn7bfjmG+VcUkFOnVKXfPedchyZNAneessm\nUQUVRkQwbDKQ+FUiGSsyCLg1gG6/d8NrQMVtiBarhT0pe9h4ciNbT21le8J2MgsyGdBiAL2DegNw\nPOs4fq5+PDHoCQa1HIS/m22qJTR1iouLefTRR1m7di1ZWVm0b9+et99+m+uuu67Sfek2OR2dBsy7\n78LcubBuvYXbV1zBXT3v4rGBj1Wv0/x8ePhh5ViyeDG0bXvJS5KSlMv/kiWqUs5dd6n8l927V28o\nlcFqspK3Pw/DRgOJcxIRsxDySAjB9wXj6Ft+TbacopwS9rIDaQfYkbCDII8gRrYZyZBWQxjUYhAd\nm3W8qAxRfUJEKLJaMVgs7DUa2W008lybNg3OJpefn8+HH37If/7zH1q1asXff//NxIkT2b9/P61b\nt76ovW6T09FphHzyifIB2bABfjvxGY72jkwdMLV6nRqNcP31qjLA5s3lLk+mpqoEJ0uWqKo4Y8Yo\nR5JFi8CjlsqhWYutpC9LP1tF26WtC14Dvej4WUd8rvS5SKO1ipWjmUfZmbiTXUm72J+6nwNpB8gs\nyKSrf1e6B3anm383rmp7FX2b9yXEM6R2JlIFLCJE5eYSlp3NttxctufkEF9UhKOm4WlvT3d3d/rU\n1gdhY9zc3EokYr7++utp27YtkZGRpQq58tA1uQZAU7VNNdV5w6Xn/sUX8OGHSsAVexxl8LeD2frg\n1rP14KrEGQHXvr2SnuWkRVm3TiVzHj0a7rhDVcdxtoG/REU/c+N+I8nfJZPySwru3d0Jvj8Y/5v9\ncfAs+dxuFSsR8RH8dfgvtiVsY1fSLnxdfOkf0p9+zfvRM6gn3QK6EeoTWucaWnlzN5rNRBqN7MrN\n5XBBAUfy84k0GglxcuJKHx+GeHsz0NOTti4uOFzwuTUG78qUlBTatm3L7t276dSp00XndU1OR6cR\n8e238N57SsC1aiVc98tjTBs6rfoCbuxY5Tk5Z06ZAs5kUva12bOVN+c111T9llUhKyyLk9NPkn8k\nn+DJwfTZ0ge3DkrbNBYbiU+L50T2Cfal7mNPyh7Wx66nmVszbulyC88PfZ5+If0ahN3MZLWyPy+P\nvzMyWJaRwYG8PHp5eNDPw4Pubm7c7O9PL3d3mtviyaIsbBVOUU1Bajabufvuu5k8eXKpAu5S6Jqc\njk4D4qef4MUXVYaQjh1hUfQiXgt7jaiHo3C0L9/uVCYVFHBRUXD//apY9w8/qBXN2kAsQsbyDOI/\njqcwoZC8h/OIHBBJXF4c8TnxxBniiDPEUWAuoJVXK9r4tKFHQA8uC76My1tdTqdmlf9hrG2sImwx\nGFiQmkq4wcCRggJaOztznZ8fN/r7M8zbG6cqJhxtyJqciDBx4kSMRiNLly4ts2CqXmpHR6cR8Ntv\n8MQTKiN/t25Kc+n2RTfm3TKPEaEjqtbpGQHXqZNyiSzlh1QE3n8fPvpIVQK4996ar9MGKut/8vfJ\nxH8eT65XLmuHr2VO8Bx6hPRgcMvBtPFuQyvvVrT2bk0rr1b4u/nXSVHSyiIixBYWsjUnh91GI9F5\neewyGmnm6MidgYFc5+dHNzc3XG2UrLMhC7n777+fuLg4VqxYgZOTU5nt9OXKBk5TtU011XnDxXNf\nskTlQv7nHyXgAGZsnMHwNsOrLuAKC1VoQMeOZQq44mLlaLl3r9LkWrSo2q0qSlhYGAMCB3Bi5glS\nFqQQ0yuG78d+T4vhLbij+x3Edoi1bZqyWsBoNrMzN5eInBwicnLYmpODk6Yx2MuLvp6ePBQSQg93\nd+K3bWOkTesfNWweeeQRDh06xNq1a8sVcJdCF3I6OvWcZcuUO/7KldCrlzq2N2Uv30V9x95H9lat\nU7MZJk5UFbrLEHApKcqpxM9PlYqrqdptxZZi/tn7D9t+3obxDyPZWdksH7Acw9sGxg0bx9oua/F2\n8a6Zm9cAxVYrmw0GVmdmsiYri0P5+fTy8GCIlxf3BAXxZceOtCylxl58HYy1vhIXF8c333yDi4sL\nQaezB2iaxuzZs5k4cWKl+tKXKytIQYHaLBaV5ejIEYiNVflpW7ZUW4sWtZumSKfxs3y5soP9/fe5\nwtpmq5kh3w3h4X4PVy2ziQg88MC54LZSnpIjIpSAu+8+FWxuq/pzxmIjG05sYO3xtexN3YvLHheG\n/DOE/kf7Y+ptovk9zWl5Z0v8ffxxsGs4z+DHCgpYlZnJ6sxMNmRn09nNjev8/LjW15cBXl4426yA\nX+VpyMuVFUVfrqwCKSnq///ff1XKvpMnVciQvT14ekKHDipG1mhUGR5OnYKEBPW0GxysjPMdOiiP\n7Guuqd0KxjqNgxUrlID7669zAg5g5taZeDp58kCfB6rW8TvvwL59KudWKQLuhx9g2jSVseSGG6p2\nizOYLCZOZJ9g48mNLD60mI0nN9I/pD+3Zd/GDb/cgEOKA82fbE7ovaE4+lXRcaaOSCwq4ouEBH5P\nS8NosTDa15eJgYF837kz/tVYXtOxMSJSoxtwHXAIOAxMK6fdAMAE3FrGealJzGaRTZtEXn9dZOhQ\nEW9vkTvvFPnpJ5H9+0VMpkv3YbWKpKaK7Nsn8u+/Ip98InLVVSKeniJjx4p89ZVIXFzlx7Z+/frK\nX9QIaKrzFhF57731EhAgEhFR8viRjCPS7L1mcjTjaNU6XrxYpGVLkYSEUk9/9JFImzYihw5VrXur\n1SpRSVHywtoXpNsX3cTpTSdpO7OtjP99vMzfN19SY1Jl3237JCI0QpJ/SRaLyVLi+obwmUfl5Mi9\n0dHiEx4uj8XESFROjlit1mr3W1NzP/3bWeu/qbVJWXMUkZrV5DRNswNmAaOARGCHpmlLReRQKe3e\nBVbX5HhKw2CA779Xda08PFRw6yuvwIgRUMqyebloGgQEqA3gqquUN1x2NqxerZ7IX35ZJagdPVpt\nw4frS5w6JfnnH5UycsUKGDy45LkX/32Rp4c8TXu/9pXveM8emDJFGfcu8P8Xgddeg99/h/BwaNWq\nYl2arWZ2J+9mc9xmNserzdnemTu638Hcm+bSK6gXzg7O5MfkE/9RPDELY2j5REu6zutqs+z/tYHB\nbGZlRgZzkpI4lJ/P4y1a8EmHDvg5NiztsylSozY5TdMGA6+JyJjT+8+jJO57F7T7P6AYpc0tF5HF\npfQlthxrcrLK2j5nDlx7rfJcu/AHpSawWGDXLiX0Vq9WS6FDhpwTet262c7+odPwyMiAzp3hzz9h\n2LCS5/ZSnwfaAAAgAElEQVSl7OOaeddw7H/HcHeq5Pq3wQD9+ikD26RJJU6ZzaqmW2Skkn+BgZfu\nLjotmnc2vcOfh/6kjXcbhrYaytDWQxnaaijtfNuddeU3bDUQ/348hk0GQh4NocVjLXAKaBhLeRYR\nlmdk8HViIpsMBoZ7ezMxMJA7AgOrHLNWF+g2uZqlBSWdhk4BA89voGlaCHCziFypaVqJczVBbKyK\n9VmwQP2vR0ZCaGhN3/Uc9vbKvjJggNLqDAaVIumff+CrryAtDXr3Vna8//4XfHxqb2w6dc/MmXDr\nrRcLOIDXN7zOs5c/W3kBJ6Lq3Fx33UUCLj8f7rwTioqUic7Ts/yuDqYd5NWwV9l4ciNPDHqCmf83\nk2ZuzUreziqkL08n/v14ik4V0fLp05qbe8PQ3LJNJr5PTmZWQgIBjo483qIFv3frhqeD7sLQEKkP\nn9pMYNp5+2VGc06ePJnQ0xLJx8eH3r17n40lCgsLAyhz/+uvw1i0CHbtGsmUKfDtt2H4+UFoaMWu\nr8n9W24BX98wJkyAnj1HsmsXfPRRGB98AE8/PZJevcLOCru6GF9d7e/evZsnnnii3oynpveNRvjq\nq5Fs3w4zZ84s8f3+dvG3rF+/nnmfzat8/598Qlh0NDzyCOqsOm8wwLvvjqRjR7jnnjAiI0u/XkT4\nfsn3LIpexE7nnTx7+bPc73M/rhbXswIuLCwMsQrdkrtxcsZJokxRBEwM4OZXb8bOwa7C4z1zrLbf\n/3/Xr+dAXh6HOnVifmoqfY4e5Rl/fx4dN65W7m/L73tYWBhz584FOPt72aQpy1hniw0YDKw6b/95\nLnA+AY6f3mKBXCAZuLGUvqpkkNyxQ2TIEGVMf+89kaysKnVTJ8TEiEyeLOLuvl5uuUXkr78q5gDT\nWGgITgi25I03RO67T/194dxvXnCzfBLxSeU7DQ8XCQwUiY0tcfj4cZFOnUSef145TJXGscxj8sDS\nByT4w2Bp/2l7eenflySroOQ/kNVqlaLkIklbliY7+uyQnQN3SsY/GVV2xKjtz/xIXp48eeSIBG3a\nJL22b5c3YmPlVGFhrY7hDLrjSdUpa44iUuNCzh44CrQBnIDdQNdy2v+ADb0r//xTxN9f5McfG7Zw\nMBhEvvlGZPBgkebNRaZNq7r3m079JCdHJCBAPdhcyKG0QxL4QaDkF+dXrtOUFOVJuXx5icPJyerw\nZ5+VfllWQZY8teopafZeM5keNr1UT05TrkliHomRjV4bJdwvXCKHRkrKHyk28TKsaSxWq6xIT5cx\ne/aI/6ZNMu3oUTmcl1fXw6oxmrqQq9HlShGxaJr2X+AfwA74TkQOapr28OlBfXPhJba4r8kEH3+s\nChuvXAn9+9ui17rDywseekhtBw+qOKYRI1RFlPvvV0G7l7Kl6NRvZs2Cq69WKSQv5PPtn/NQ34dw\ndayEG67FoiqX3nuvCtY8jdWqSuTcdx88/njJS0SE3w/8zpOrn2Rcp3Hsf3Q/wR4Xl/M2bDFw8N6D\n+Fzhw6DDg3AKahiOJNkmE3OTk/kiMRFPe3seb9GCRd272yxHpE49pSzpV982KvDUYbGI/PyzSLt2\nItdcI3LiRKUeBuotpS1jFBeLLF0qctNNKqZv8mQVz9eYaCrLlVlZasXhfO38zNyzCrLE911fScgp\nPa6tTD7+WGTEiIuWMN5+W2TYsItXNiITI2XMz2Okx5c9ZEvcllK7tFqscuKtE7IpaJOkLk6t3Hgq\nSE185vtyc+WRmBjxCQ+XOw8ckM3Z2RdpnFarWUymHCksTJS8vCOSm7tbcnJ2idF4UAoK4sRiKbb5\nuC7EZnPPzpbEVatk8VNPyXNXXNFgNbm7775bgoODxcvLS9q1ayczZswos21Zc5Sa1uRqE6NRPbgm\nJqpMDY09r6+jI9x4o9pSUlSs31VXKW1g+nSVbUWnYfDJJzBunAoduJDvo75nTMcxlatQnZenCs6t\nWQPneQSGh8Onn8LOnecO70vZxwv/vsDu5N08e/mzTB0wFSf7izWz4tRiDt5zEGu+lX47++HSspJB\npJdAxIrFkkdRUTIGw1ZMphSKi1MoLk7GYjGe18aAyZSF2ZyN2ZyF2WxAxAxYEbGWeC2yWiiymrGK\nlds0uFMTtHQrpjQrG8+2O4MVOzs37O09sLd3x97eHbDDai3EYjFiMqXh5BSMo6MfyjfO7nSYhIa9\nvTuOjv44ODRDO1141dHRH3f3Xri7d8fe3gNNc8De3hN7e/dSKyVYrebKvFkqx+CRI7BjB6YdOzh8\n+DD74uLYnJjI2qIiUuzsGBIQwOAG/EPwwgsvMGfOHFxcXDh8+DDDhw+nf//+jB49ulL9NIrcladO\nqfRDffsqN3ynhrF6YnNyc9WP2MyZamnzpZdUgLtO/SU9XQm3nTtVmrjzsVgtdPi8A7/d/hsDW1Qi\nuub991VszG+/nT109ChccQXMnaviMc1WM+9vfp9Ptn7Cq8Nf5aF+D+HiULrgygrL4uDdBwm+N5jQ\nN0Kxcyg/RkzESkHBcfLzD2AyZWA2GzCbDVgshtN/KwGlhJUSWBaLEXt7Nxwc/HByCsLJKfjsq729\nB0qwaDg4eOPg4IODg+/pzQtNczwtXOzJMpv5JSWNH1JSCXFy4cGQFtzgH4iTnQNKMNmd96pxxplb\n0+zLLdNjtZooKorHbM4GzmhCVkCwWPIwmdIwmTJPH4Pi4hSMxj3k5x/EYslHxITFkgsIjo6BODoG\n4OQUiNVaQH7+YYqLk7Gzc8XJKRBHx0D1WuyKlpsHOTk4pBbgesiI6940LFnZHC7W2GT2YK3RiS3J\n2bTw96dn584MGDKEa269ld59+mBnZ3d6bg0/Ti4mJoarr76apUuX0rdv34vON+rclenp6p936lR4\n9tnaqXNVX/H0VLF3DzwAzz0HXbvCCy+oECk9q0r95P33lU31QgEHsCxmGcEewZUTcLm5qvDb+vVn\nD2VmKrPca68pAXci+wR3LrwTT2dPIqdE0tq7daldiQhxb8eRMCuBLnO74Dfa74LzVoqK4ikoOEZB\nwVGMxr0YjbvJy9uLg4Mv7u49cXIKwN7eGwcHb5ydW+Hu3uMCIeVzevNC06puG4vMzeXzU6dYmpHB\nLf7+zOvZhb42NFTb2Tni6tqu2v1YLHkUF6dhMqViKkpBy8zBLcse5yPZWGIPYUqOpjjjGKa8KEyB\nLkhQABb/AHYW27E+vZitmSaiD4GfnyO9ezsycrDwRG8NT88cHB3jcHIqxskphqNHzzwoXGxTbUg8\n9thjzJ07l+LiYj7//PNSBdylaNCanMWi6j1edpn6sWishFWxrtq2bfDWW0pLeOYZeOwxcHa2/fhq\niqrOu6Fw6pT67u7Zo6pYnE9YWBivn3idR/o/wp097qx4p++8o4q/zZ8PqHpw116rnK8+/BBWHlnJ\nf5b+h2cvf5anhjxVpvZiNVmJeTCG/EP59FjcA+cW6otjNhvJzFxBRsYKMjNXoWl2uLp2wNW1A+7u\nvfDwuAwPj8tOL+tVnsp85kazmT/T0/kiMZHEoiIebdGCB4KD619yZBHIyoIDB2DLFvWPGRMDx4+D\nr6+yLXTsSJidHSOvvRY6dKC4dWs2RkWxcOFClixZQlBQENdccw2jRo1i0KBBNGvW7LzuBYsll+Li\npNNLvGqZ98zWtev3VdLktPNiF6s1/Wr+D4sIGzdu5LbbbmPlypUMOD9b+WkarSb3+uvqn/jtt+t6\nJPWTQYNULbK9e5WGN2uW+g28446mrfHWF15+WRUkvVDAARzNPMrRzKPc1vW2ineYk6MMfBs2AOq3\n9aGHVD24d9618Nr6N/gu6jv+GP8HV7S5osxuzLlmDtx+ADsnO3qv742dq0ZGxgqSk+eSmbkaL68h\n+PvfQGjoqzbRbiqDiLAmK4s5SUn8k5nJ5d7eTGvVihv8/bGv6y91Wtq5GlzR0arK7P79Koegm5sq\nTjt0KEyYoJZZ2rUrYU9IXrCAr9LTWfXzz4SFhdGlSxduu+02IiIiaNeu7PdZ0zQcHLxwcPDCza0U\nwy7fV2k61RVOtkLTNEaMGMH48eOZP39+qUKu3OsbqiYXEQHjxyvTw+maejqXYP16lTC6Uyf49lvw\nbjh1KBsdUVEwZgwcPqxCRC7k/qX308GvAy9e8WLFO33rLRVj8vPPAMyYoR5yFq5I56FVd1FkLmLB\n7QtKDQs4g9loZu91e3Hr4ka7WcGkps8jIeFz7O09CAl5hICA23B0bFbm9TXJhuxsXo6NJa24mKdb\nteLWgACa1WWC5Px82LFDOfgsX67qcXXurNaeO3eGPn2gZ09VaPKCJZT8/HzCw8PZtm0bBw4cICoq\nCoPBwOjRoxkzZgzXXHMN/v7+NhlmY7DJATz00EMEBQUxY8aMi86Vp8k1WCH3zDPqx+HVV+twUA2Q\nwkJ4+mmVHPr335Wzjk7tIqK8YG+/XdmSLyQtL41Oszpx5PEj+LtV8IfOYFDLXps3Q6dOLF+ucp++\nPX8dz2+dzKSek5hx1YxyC5FaCizsu34fDr1ScH70b1JSf8bX92patvw/vLwuL9cxoyY5UVDA08eO\nEWU0Mj00lElBQbWvtZnNaqlx61Y4dEhpaAcOKCF25ZXKPXbwYJWcthSys7PZtGkTW7duZcuWLezY\nsYM+ffowdOhQevToQc+ePenRo8dZZxFb0hCFXFpaGuvWrWPcuHG4urqyZs0aJkyYwJo1ayq9XFnR\nGLUg4Dtg5en9bsADFbnWVhsXxHT06CGydWuZYRONipqIHfrtN5Vh44svyk7rVNc01ji5v/8W6dKl\n7Cw8b254U8bOGFu5TqdPF7nnHhFRn2fffia56oVPJXRmqPxz9J9LXm7KMcmOh76RzT+OkE3h/nLs\n2PNSUFCF4ofV5PzPPLWoSKYdPSrNwsPlzdhYKTCba3cwGRkiv/wiMnGiiK+vSN++Ik88odIPhYeL\nXCJLysmTJ+Wrr76S0aNHi6enp1x99dXy8ssvy/LlyyUnJ+ei9npar3OkpaXJiBEjxNfXV3x8fGTA\ngAGybNmyMtuXNUepRJzcXFTKrZdO7x8Gfjst+GqdhAQVD9fQM5nUJXfcobS48eNV9vk5c/Tly9rA\nbFarEB98UCKE7SwiwuzI2bze9fWKd5qdrdL7REQAsHmLhYPxKYzvv5ul4/bh4VR+HElWzAH2/fMI\n2rh42vV9keDm92BvX3fuuCnFxXwYH893SUncGRhIVP/+tKpscceqYDYrLW3lSrX8GBWlAm7HjVMf\nWIsW5V5eWFjIxo0bWbVqFatWrSItLY3Ro0fz4IMPsnDhQjz0eJ4K4+/vXyJpd7UoS/pJSYm/4/Rr\n1HnHdlfkWlttnPfU8cMPIuPHV+X5QOdCCgpEpk4Vad9eJDKyrkfT+Pn6a5Erryxbez6ZfVKCPgiq\nXA7I6dPPZXYWka4j9krHuz8Ts6V8zcdszpPo9c/I+qXesve3F8RsLqj4PWuApMJCefLIEfEND5f/\nHj4s8QU1PB6LRWTDBpGHHxbp1k3ExUX9IzzyiFK38yuWK3Tnzp3y4IMPire3twwdOlTefPNN2bFj\nh1gslktfXAvQADW5ylLWHKUSmlyepmnNOJ1b8nQxVINtxGzlWb1axfvoVB8XF/jySxU3PHq0SpRx\n//11ParGSW6u8gj++++yvVu3J2xnYIuBFbd/GY3KbTY8HIAf1q/j0I4+HF1wJ/Z2pduHRIT09KUc\n3vd/mCM60nXIJoJu7FGFGdmGxKIi3o+L46eUFO4NCmL/gAGE1FSsS2qqWrr45x/1Q+Ljo1IlTZ2q\nPLIqGFCan5/PggUL+Prrr0lNTWXKlCkcOnSI4OCGHZfWKClL+klJid8X2IwSbJtRy5W9KnKtrTZO\nP3WYzSLNmonE1b65oM6oLdtUTIwqSTRrVq3c7pI0Npvcyy+L3Htv+W2e/edZeXPDmxWf+8cfi9x+\nu4iIxGbFituIz2XCg6fKbJ6XFyO7d4+WLWs6y8YrPxXDVkMFR297soqL5bmjR8UvPFyePHJEEgsL\nbfuZm80iUVEiX34pcvfdSkvz8REZN07k009FoqMr1V1KSorMnTtXxo8fL76+vjJu3Dj5+++/xWwj\nW6Fuk6s6Zc1RKqrJicguTdNGAJ1ReXBiRMRka4FbEaKiIDAQWrWqi7s3bjp1UmEGV12lPAD/+9+6\nHlHj4dgxlXIuKqr8dtsTtvPCsBfgVAU6LSpS2U2WLaPIXMQtP06G3St554eLtRGLJY+TJ2eQmDiH\nQMuT5N77An1W9sPjstq3ExVZrXyRkMC7cXHc5O/P3gEDaHFac4upbuciyutx3jwVSuHlBZdfrmxr\nL7wAXbpAJTwYExMTmTt3LsuWLePQoUOMGjWKcePG8dlnn+laW0OhLOknJSX+Y4DPefu+wKMVudZW\nG6efOmbMUA5OOjVHbKyq5DBtmnoY1qkeVqvItdeKfPBB+e3MFrN4vO0hGfkZFet4zhzVsYhMXT5V\nut7xq9x778W2vNTUhbJlSyuJjr5bck7GyuaQzZK+Mr2y06g2FqtVfk5OljZbtsgNe/fKAaOx+p1a\nrSIHDihtbcIEkeBgkdat1Zf3wIEqdWkymWTt2rUyYcIE8fHxkSlTpsiaNWuksI6KqVYXmrgmV1EB\nc5GTCec5odTGduYDGT5cZMUKW79FOheSmipy1VXqNzSjgr+5OqXzyy8il12myiOVx/6U/dLhsw4V\n69RkEunQQWT9elmwb4G0e6+3NPO3lCi6arEUSUzMo7J1ayfJytooliKLRF4eKbFvxlZ5LlVlTUaG\n9NmxQwbu3CkbsrIufUF5WCwiGzeKPPqoSFCQSNu2qtbUDz+okudViIkxm82ybt06eeSRRyQwMFD6\n9esnn3zyiWRVd6z1AF3IVUzA7ON04PjpfXvgQEWutdUGSEGBiLu7SG5ujbxP9Za6sk2ZTCJPPaVi\nulJSav/+jcEml5GhlIuKxHR+v+t7mbRokohUYO4//SRyxRWSnJMkgR8EytRp8XLXXedOFxUlS2Tk\nUNm790YxmbLFarbKgbsOyN4b94rVUjuBkUUWi8xPTpahkZHSPiJCfk+5dOXwMudttYrs2CHy9NOq\nrHmPHiJvvSVy5Ei1xpiRkSEvvviiBAUFSd++feWdd96Ro0cvroReG+g2uapTnpCrqHflKuA3TdNm\nn95/+PSxWmXnTpXyTQ83qR0cHJTJx8NDZehYtw5slGmoyfDSS3DrrSqP6KXYnrCdgSEVqDhgNsMb\nb8A33/D4qv8xseMUfn2/JRs3njltYM+ea2nWbBxt274JVo2D9x2kOLmYnst6otnVbLYQEWFxejpP\nHD1KR1dXnmrVihubNcOhKtk8jh6FH3+EBQtUWfOJE1UcW4/qeYPGxcXx/fffM2vWLG699VbCw8Pp\n2LFjtfrUqaeUJf2kpMS3A6YCC09vDwP2FbnWVhsgb7+t2+PqAqtV5PnnRfr0EUmvfVNOg2XXLrWa\nlplZsfZ9Z/ctsyp3CebOFRk+XBbu/0M6f95Z3nm/WCZMUKcslkKJihophw//V6xW61kNLmpUlJjz\nat7AerKgQG7et0+6bNsmG6u61JeZKbJsmciYMapk+hNPiGzfXu3UPJmZmfLNN9/I8OHDxc/PTx5+\n+GE5Uk1NsCFAE9fkak1IVXcDZMwYkUWLbP7+6FQAq1XZ8rt1EzlVtoe6zmmsVpGhQ1UGqIqQX5wv\nrjNcJb/4EgHIJpNI+/aS/vdCaf5hc9kYu1nathXZtk3EarXI/v13yP79t4vVahar2SrRd0fXioCL\nzc+XKYcOiW94uLx2/LgUViYQ2moV2bRJZMoUZV/z9BQZMULku+8qHJBdFgUFBfLHH3/IzTffLF5e\nXnL77bfLkiVLGqwTSVVo6ELu8OHD4uLiIvecTltXGuUJuQqtH2iaNlTTtDWaph3WNO24pmmxmqYd\nt6lKWQG2bIFhw2r7rnWPzdLbVANNg3ffhXvvVUVqjx6t+XvWh3lXlV9+UR7+FQ2s3528my7+XXB1\nVO7/Zc59/nykZQtuSfmUqf2nYth/Of7+MGCAcPTokxQXJ9Olyzyw2nFo8iGKkorouawn9m5VL0ha\nHnkWCy8eP07/yEgCHB05PHAgr7dti3NFliZPnVKlEjp2VDWB2rYl7LXXVJqysDD15lWx2m9SUhJP\nPvkkISEhfPXVV9xwww3ExcXxxx9/cPPNN+NcDwsrNuTve03y3//+l4EDK1E4+AIqapP7DngSiAQs\nVb5bNQkOVjFydUm+KZ/YrFj2pOwhOi2a7gHdGd1hNH6uVSsS2dCYNk3VeRw6FGbPhptvrusR1T/S\n0lRl9sWLy0xKfxERpyIY1KIChrtZs5g7riVujnm8NPwlrh+r4hnj4z8gO3sdvXuHY2/vwsm3T1IY\nX0ivFb1qTMCFZWVx36FDDPP2Zm9Fs5QUFcFff8F336nioXfcAb/+CgMGqCepsLBKxbFdSHR0NN98\n8w0//fQT9913H3v27KGVHlTbYFmwYAG+vr5069aNo1V9si5LxZOSau22irSryQ2QBx6ohs5bRaJT\no+X19a9L7697i9c7XuL8prN0/KyjjP99vLyy7hW54dcbxPNtT7nqx6tkwb4FUmQuqv1B1gERESKh\noSKPPy5S1DSmXCEsFmVKev75yl13/S/Xy2/7fyu/0c6dkhcSIKEftZK0vDQ5fFhVkjhxYr5s2dJa\nCgriRUTEZDDJJv9NkhdTfpb86rAiPV0CNm2SVRWNL4mJEXnmGTXgkSOVd+glsvhXlPT0dPn888+l\nf//+EhISItOmTZPExESb9N0YoIEuVxoMBunUqZMkJCTI66+/XuXlyopqcus1TfsAWAwUnScgd1VN\ntFaNK8ouZmwzRITFBxez/Mhywk6EYbKYGN9tPLPGzKJ7YHe8nb0vyitYaC5kWcwyZkfO5n+r/scN\nnW5gTIcxXNP+GrycS6mI2QgYPBh27YL//AdGjYJFi+pey64PzJwJWVnK+bGimCwmwuPC+eGmH8pt\nl/3JO3zRK48Fd/yFv5s/b30Jd9+dxKlTj3PZZf/i4qJKjCd8kYDvaF/cOrlVZyplsjQ9nSkxMSzr\n0YPB5ZWuKCqCJUuUyh8dDZMnq3p3NvBiNJlMrFixgh9//JF169YxduxYZsyYwdVXX419RdVnnXIJ\n08Js0s9IGVml61599VUeeughQkJCqjeAsqSflJT460vZ1lXkWlttgBw7Vr0ng0txIuuEXPPTNdLn\n6z7y1Y6vJDo1unLZ4EXkSMYR+STiE7l23rXi866PTFk2RfYk76nWuOpzvJjFIvLKKyrJxM6dtu27\nPs+7NHbsUIrK8eOVu27TyU3S++veJY5dOHdD8knJdrWTn//5SO0bRJo1s8iiRYMkNXXJ2XamXJNs\nCtgkxmgbZBMphTkJCRK0aZNEllIP7Szna22jRqnihRVU9y/1maekpMgLL7wgAQEBMmzYMJkzZ45k\nZ2dXYgb1Fz1O7hxRUVHSvXt3MZ0uulgdTa5OlyArswE1WtxzbtRcafZeM3kn/B0xWcqoZllJknKT\n5I2wNyTkoxC5af5NEp1auYSwZ2gIP/a//65+0158UZXvsQUNYd5nSE9Xy7cLF1b+2ulh0+Xp1U+X\nOHb+3C1Wi8y5r6dsH97+7LH33y+Wa69dLbGxb5a47uR7J2X/hP2VH8QlsFqt8urx49I+IkJiSltm\nLCwUmT9fLUUGBoo891yVArXL+swPHz4s//vf/8TX11emTp0qhw8frnTf9R1dyJ1j5syZ4uHhIc2b\nN5fg4GDx8PAQV1dX6devX6ntbSLkgOuB54BXz2wVvdYWW019IHnFeTL5z8nSZVYX2Zeyr0buUWAq\nkA82fyD+7/vL4yselwJT3dbtqikSE0Vuu02kUycV6lFPymnVOGazSn/27LNVu374D8Nl5ZGVZZ5/\nM+wNiQ12laJ1a0REpLDQKkFBGfL778+VWGkw5ZhkU9Amyd1n25RAxRaLTD54UAbs3CkpF2pk6emq\nnl1goNLafv/dZkZaq9Uqq1evltGjR4u/v78899xzkpCQYJO+mxINUcgVFBRISkrK2e2ZZ56R8ePH\nS0YZNuBqCznga+AnIB54DZXm67uKXGurrSY+kIScBOn1VS+5e/HdkltU87nCMvIz5NbfbpV+s/tJ\nbFZsjd+vrvj7b5F+/UR69Woawu6ll1QhVFMVFgCMRUZxf8tdjEWlLy/+ffhvuX1qMynu2vlsMPRH\nH62QgQMjxGwueU3s67Fy4K6qJSUuC4PJJNfu3i3j9u4V4/nZugsKVO0gX1+RBx6odNma8jCbzbJs\n2TIZOHCgdO3aVX744QcpqOkCqo2YhijkLqTGlyuBvRe8egDhFbnWVputP5CY9BgJnRkq74S/U2m7\nW3WwWq3y0ZaPJPCDQJkTOeeS1ZtFGtay3RmsVpG//jon7BYurHxFg4Yw7zlzVPxyVXN7rjyyUq74\n/oqLjq9fv16OZByRgPcDJO36K0U+/1xERDIy/pW2bQ/K8uUlb1iUUiThfuGSf6x6wdPnk1FcLH12\n7JBHYmLEdP6TyoYNSl2/9VaR+Hib3e/IkSNyxx13SPPmzWXAgAHy+++/15vq2rWBvlxZdcoTchX1\nriw4/ZqvaVoIkAE0r8iFmqZdB8xEpQb7TkTeu+D8jcCbgBUVg/eciKyr4LiqxK6kXVz/6/W8ddVb\n3N+ndstga5rGU0OeYmToSB5f+Thf7fyKz677jKGth9bqOGoaTYNx4+D661Ul7Bkz4H//U0WYb7oJ\nundXRZkvhdkMsbFgMEBhIRQUqNe8PEhOVvHEVquqhdexIzg7q5JiZzY7OwgNhZYty67GXVWWLIFX\nX4UNG6ruWfrv8X+5ut3VFx03FBqY8ssUPur5DP5vvwO/LMFqNfHjjwtwd/+AsWNLejWefPskQZOC\ncG1XteDpC8k1mxmzdy+jfH15v1075VFsMKhAyb/+gs8/V0k5bUB8fDxvvPEGS5Ys4dprr+Xff/+l\na8xXDTwAACAASURBVNeuNulbR0dTQvASjTTtFeBzYBTwBSDAtyLyyiWus0NVER8FJAI7gDtF5NB5\nbdxEJP/03z2BJSLSoZS+pCJjvRTbTm3jxgU38vX1X3NL11uq3V91EBF+3fcr09ZOY2ToSN67+j1a\neLWo0zHVJNHRqpbl2rVw6JBK/Ny1q9ratYOAACX4jh+HvXvVFh0NQUEqAN3V9dzm5qaSA7RooYRX\nTIzKwmIyqf0zm8WihGRuroo3njgRbrsN/KoZu//PP3D33bBqFfTtW/V++szuw6wxs0o85BSaC7n6\np6sZ2moo723zhPh4mD2bU6c+5eabR/Lkk724665zErvgRAGR/SIZGD0QpyCn6kxL9WexMGbvXrq6\nu/Nlx45KwP35p4o6v/56eO+9ij2hlENeXh5Llizh119/JSIigqlTp/LMM8/gV90PRuciNE1DRC56\nxLPVb2p9oKw5AhVernQ+/2/A+/xj5Vw3GFh53v7zwLRy2g8BtpZxrtoq7aaTmyTg/QD5K+avavdl\nS3KLcuXFtS+K33t+MmPDjEbrmHI+VqtIXJzI6tUiM2eqHLx33SUydqzIY4+JzJ6tAs7L81SvDFlZ\nIkuWiIwfL+LlJTJunMivv4pUpW7nt9+qxMvh4dUbU05hjri95XZRAoFJiybJhD8miKW4SJWViYqS\n4uJ0mT17tLRuXXRRXbqDDxyU4y9XMm6hDMxWq9y0d69MOnBALFZrSW+iDRuq3X9qaqq88sor4u/v\nL2PHjpWff/5Zcpta7axahia+XFlRIberIsdKaXMb8M15+3cDn5XS7mbgIJAFDCyjr2q9CX/F/CX+\n7/uX68VW1xzLPCY3L7hZ2s5sK8tjlp893hBsUzVBTc3bYBD58UeR0aNV2MP06RWrFFBYqDzj27eX\nEsVJq8q64+vk8u8uL3EsKilKWn7cUlavXS3y558igweLiEhMzGMyevQu+fTTkn3kx+ZLuF+4FGdc\noiJrBbBarfJoTIxcvXu3FFksIkuXKq/Jl16qdlxIXl6evP766+Ln5ydTpkwpMwSgqX7XRXSbXHUo\nT8iVa5PTNC0YaAG4aprWBzijDnoBNkunICJ/An9qmjYMmAd0Lq3d5MmTCQ0NBcDHx4fevXszcuRI\n4Fxy09L250TOYdq305hx1Qyu63DdJdvX5f6SCUtYe3wtd398N8NaD+PXp3+tV+Orzf3du3fXSP9e\nXtC6dRjPPw/Nm4/k3XehVaswunSBsWNHMnw4iITh6Kjai8Dbb4fx5ZfQv/9IIiLgwIEwEhOrN55f\n9/7KoM6DSpz/yfATj/Z/lOjIaJx+/pmRTzxBUVES8+b9Q0TErSxaRIn2zec3J+SREDbv3Vzt92d+\nSgpb27UjvEcPttx5J2zYwMilS2Hw4Cq/30OHDmXevHlMmzaNnj17EhkZSWhoKGFhYSQkJFzU/gz1\n4ftX2/u2+r6HhYUxd+5cgLO/l02asqSfEo7ch8pukgus41y2k6XAreVdK+eWK1edt1/ucuXpNseA\nZqUcr5KEn79vvrSd2VYOpzes4NGM/Ay5cf6N0v+b/nIss4ZTvehIaqoqYfbii0p58vERuekmVfEl\nKEhVR1+1yrb3vGn+TbJg34JzYzCmis+7PpKWlyZy8KC6cWGhxMa+IRMmbJBXXil5fcHJAgn3C5ei\ntOrHpc1OSJA2W7bIKYNB5PrrVQLOahQPNBgM8uWXX0qbNm1k1KhRsmnTpmqPUadq0MQ1uYouV95W\nkXalXGcPHAXaAE7AbqDrBW3an/d3X+BYGX1VeuK5RbnS4v/ZO++wKK4ujL9LUVAB6YioKGJv2DVR\nUWOP7TOJMbHExGiM0dhjTGJJjBpL7LHX2Luxi0oRkA4KAgoqKL33trvzfn+MIggLC4KC8HueeWBm\nbjszsGfvvaesr69cIsoKiCAI3HB3Aw3XGPL0g1KE0qim1ERGigE8bGxEK/my9jIRBIEm60wYkhiS\ne+1Phz/59fmvxZMffiB//ZVyuZQXL7anrq60gJvCw+8fMvin4Dcey6HISNZ3cmJwUpK4WTlmDAts\n/CmBVCrl1atXOW7cOOro6HD06NF0dq6c/3vvE9VKTjlltRJA3TznugBWKFl3MICHAIIALHpxbRqA\nqS9+XwjAD4AXgDsAOitop8SC/3zzZ44/O77E9Soa209uZ+ONjfndxe+YklVGlhiVgPd5fyYkMYTG\na41zfTRzZDmsv74+fSJ9yORk2tapQ4aFMSbmNKdM2c/vvstfP+NxBu/o32F29JvN4s7FxNDEyYkP\n4uLI4cPJ0aNLrODCwsK4cOFC1qtXj127duXWrVsZGxtbqvG8z++8OKr35EpPUUpO2cRNQ0gm5Vni\nTAQwVJmKJK+RbE7SkuTqF9d2ktz14vc1JNuQ7EiyF0kPJcdUJI8THmOX5y789dFfxReu4LQwbAGv\naV7Ilmej7fa2uPH4xrseUjVviGu4K7qZdcvNaHEu8Bya6jVFe5P2wKFDQKdOQP36CArah7NnP8e8\nefnrP1n8BGazzVDDqPQuA16pqfj20SNcNDREqwEDRD+N48cBdXWl6oeHh2P69Olo27YtcnJycOvW\nLbi6umLGjBkwMDAo9biqqaZMUaT9mF/j30d+NwJNAA+UqVtWB0rwrUMQBH589GOuurNK6TqVhWtB\n19hoQyNOPj+ZCRlKmARWUyGZe20u/3T4M/e8596ePON/Rjxp3Zq0t2damj9nzfqFY8bkj/qRdDeJ\nTvWdKEsvYQiZPIRnZbGBszNPOTmRpqbk2rUlWpM9ceIEjYyMuHDhQsbExJR6HNWUP6ikM7k+ffpQ\nQ0ODWlparFOnDlu0aKGwrCIZWYLlyp8AOAL45sXhCDEySYVUctvdt7PDjg7MkmYpXacykZKVwu8v\nfc/66+vz8qPL73o41ZSCD/Z+wFtPbpEk3cPd2XBDQzH7RUwMqaNDyuX09f2OpqaJdHN7VU8QBHp+\n4MmIfaVPCpopk7GLhwf/uHqVNDAQ468pSUZGBidOnEhLS0u65R1YNRWWyqrkrK2tuW/fPqXKFqXk\nlFqupBiKawWAli+OP0iuKYOJZJnjF+OH32x/w/Exx1FTrea7Hk6Z8Lp5tVZNLWwbtg1H/ncE0y5N\nw1LbpRAovJvBlSOvy/2+IJVL4R3ljc6mnQEAW9y2YEaXGVBTUQM8PIBOnXDj5hkcP040bVobXbq8\nqht3Lg7yVDlMJpqUuv/5jx/DLCICv3z9NXDlihh/TQkiIyPRp08fSKVSeHt7o0vegZUR7+s7V4aq\nLLsiRP31Zii7JweIztrXSM4HcEcikWi9ce9lTKY0E5+f/hxrPlqD5gaFutq9V/Qx7wOPbz1gG2KL\nEcdGIC4j7l0PqRoluB99H43rNoZ2TW1Ep0Xjv4f/YUrHKeJNDw+gc2eEh5/BwYN/4vffX+2PCTkC\nnvz0BBbrLCBRLV0gzpMxMbj67Bn2LVgAyZ07gJKKytvbG926dcPIkSNx5MgR1K5du1T9V1NNSfj5\n559hZGSEXr16wd7evlRtKBWgWSKRfAtgKgA9ABYQHcR3QIxJWWHY4bEDTfWa4qsOX73roZQpLx0+\nC8O4jjFuTbyFX27/gnbb22Hr0K34X8uyCZz7rilK7sqMa7grupt1BwDs9NyJT1t9Cj3NFzEb3d0h\n+2I0vJ1V0bZtLfTp86pexI4IaDbVhN6A0sV3DM7IwAx/f1z75RfUPXECsLBQqt7Zs2cxbdo0bN++\nHZ988kmp+laW9/WdK0NFk93Ormwimltbl242tmbNGrRq1Qo1atTAsWPHMHz4cNy7dw+NGzcuWUOK\n1jGZf+3WB6Kfm3eea77K1C2rA8WsH8sFOS02WVRan7iywOmZE5ttacZxp8cxMTPxXQ+nGgVMPDeR\nuzx2MVOayXrr6r1K1isIpIkJH1xZQH39ZPrmyeGbk5hDR0NHpt4vXZzHTJmMHZycuHXiRKX34ARB\n4MqVK2lmZkZ3d/dS9VvNuweVdE/udQYPHsytW7cWek+RjFR2Tw5ANsmclycSiUQNYiaCCsONxzeg\nXVM79xtyeUESmU8yEXs2FqErQ5HimlKu/QHKr9X3bNATPtN8oKepB6udVnB+7ly+Aytn3tc9Cpcw\nF3Qz64a9XnvRybQT2hi1EW9ERIAyGVYfNYGVlQPatHlV59nKZ9AfoY86beuUqs85vr6wdHbG9506\nKbUHl52djUmTJuHMmTNwcXFB586dS9VvSXlf37kyVGXZleFFpoES11M2n5y9RCJZDDGG5QAA3wO4\nWOLeypFt7tswo8uMXL+jsoIkMgIzkHA1AUkOSUhxSoGKhgrqdKgDzaaa8B/nD3UjdZjNNoPhGEOo\nqJdkm7Ps0VTXxNahWzHw4UD878T/sLjXYszsOrPMn0s1pSMxMxERqRFoqtsUw44Ow5nPzry66e4O\nmVUrnDs/BXv2eOVezgjKQOS+SHS5XzpDj+NPnsAmKAiemZmQzJ9fbPnY2FiMGjUKpqamcHBwQK1a\nZRamtppqlCI5ORmurq7o06cP1NTUcPz4cdy5cwebN28ueWOKpnjMP61VAfAtgFMATr/4XaJM3bI6\nUMTU+knCE+r/pc/0nHSlp77Fkfk8k09+fcK75nfp3MCZgVMDGX08mpnP80djF2QCY87F0KuPF53N\nnBmyKoQ5cW8eEb4seJr4lG3+acPvLn7HHFnFGFNV51rQNVofsOZOj50c9O+g/DcXL+bDz8exRYun\nuZcEQaDPQB+Grg0tVX8P4+JocOkSvZYsUcoPLjQ0lM2aNePixYurVFbu9xlUwuXK2NhYdunShdra\n2tTV1WWPHj1469YtheUVyUhSuaSpFYGiEvwttFkIgQLWDVz3xv0I2QIeTX+EuPNxMP7SGPWm1EPt\ndrWVmgml+qQifFM44s7HwfAzQ5j9aIbard6tFVpKdgq+OPMFsmRZOPXpKehq6r7T8VR1ltstR5o0\nDaf9T+Pw6MP5M8IPGoQ9Gl3gavQ/7N4tZmKNOR2DkGUh6OzducSrBJkZGehx8SK+e/oU3y1cKKZJ\nL4KHDx9i4MCBmDNnDmbPnl1i2aqpmFT1pKlF/tVLJBJfiURyX9FRPsMtGZnSTOz32Y/pnae/cVvy\nTDl8R/pCnipH95DusNxiiTrt6yi91KfVQQst9rdA18CuqGlaEz79fHBv4D3EX4l/I3+PN1mr166p\njQufX0B74/bovrc7HsU/KnVbb5v3cY/CNdwVmdJMNK7bOL+CIwEPD5wO6YkBA2rDzs4OsjQZHs95\njGbbmpV8GVwmw+x9+9AiORnT5s0rVsF5enqib9++WLp06TtVcO/jO1eWqix7eVLcntynADLfxkBK\ny3G/4+havyss9JQzh1aEPF0O3xG+qGFSAy0OtoCKWun31moY14D5UnM0XNQQMSdiEDw3GHrX9dB0\nY9N3sjemqqKK9YPWo6VhS/Ta3wvHxhxDv8b93vo4qjok4RbuBt8YXxz939H8N588gaChAYegXjg+\nsAZ8fCLx9NenqNu3Lur2qVvivs7t2QPbevXgMXgwJMXEorSxscEXX3yB3bt3Y9SoUSXuq5pqKjSK\n1jFfzDy8Xvz8t6hyb+NAIevHgiCw486ObxzaSpoipVdvL/pP8qcgK+OcKhTNvz27ezLw28Byab8k\n2D61pfFaY+5w3/FOx1EVCYoPou5q3YJ7cSR57Bgju/dlmzai30DC7QQ61XcqVcZvITmZ7fbv55V7\n94ote+TIERoZGdHBwaHE/VRTOUAl3JMrKYpkpBIuBDUkEskXAHpKJJL/vX6Un+pVDtdwVyRlJeVm\n+y4NsmQZ7g+6j1rNa6HFvhaljiRRFOp11dHuRjtkBmUiYEIAhJx3F4LL2twajl87YoPLBsy+Nhsy\nQfbOxlLVcAh1QKYsEyv6rSh4884duKq2xAcfREOWLEPg5EA0390c6nrKZQTIy7WjRwEtLQxu27bI\nchs2bMBPP/2EW7duoVevXiXup5pqKgPFKbnvAPQCUBfA8NcO5QLelSPb3Lfh+87fQ0VSuqVFeZYc\n94fcR52OddBsRzNIVMpvKVFNSw1tr7SFkCXg/pD7kCUrr1zKeq2+qV5TuExxgX+sP0YcG4HkrOQy\nbb+seN/2KPZ570NT3aa5MSvzYWuLk3HW6N9fDcFzgxHULgj6Q/RL3kl6OlYLAn4yN1e4NE4SixYt\nwq5du+Do6Ig2eR3y3jHv2zsvCVVZ9vKkSO1A0pHkdIgZBya/dnz9lsZYKDHpMbj06BImW00uVX2S\nCPo+CDXr14TlFkulFRwJ+PgAv/0mpvwaNAj4+Wfg/HkgpRi/cFVNVbQ+1Rq1W9WGdy9vZIVllWrs\nZUFdjbq48uUVNNFtgp77euJZ8rN3NpaqQGp2KlzDXbHggwUFb0ZFgZGRuBA6CL3a10fsmVjU/65+\nqfq5e/gwnpmZ4TMrK4VlNmzYgCtXrsDR0RGNGjUqVT/VVFNZUHYKdFwikfwqkUh2AYBEIrGUSCTv\ndCZ368kt9DXv+yrmXwmJ2B6BVPdUNN/fXCljkJwc4PBhoHNnYNQoICsL2LgR+OEHQFMT+OcfoH59\nwNoa2LoViIkpvB2JqgRNNzeF8QRjePf0RppfWrF9l1dMOzUVNWwduhVTrKag9/7eFc7ysqLF8nsT\n1jmvA0l80qqQ2I/29oiy7ArLFg8gu6kB/Y/10X9oKcLCpqXhr9RUzDc2hpoCa8r//vsP69evx6VL\nl6CvX4qZYjnzPr3zklKVZS9PlI14sg+AJ4CeL87DITqGXyqPQSlDSFIILPUsS1U3ySEJIctDYOVk\nBbU6xT+CixeBmTPFeLbLlwNDh+a3yB4+XPyZng7cvg2cOAH8+ivQowfwxReiUtTKk7NBIpGg4YKG\nqGlWE/f63UOr462g2+/d+a/N6TEHOho6sD5gjWvjr6Gdcbt3Npb3kcTMRGx02YjmBs1RS72Q6CG2\ntnBUs0LPLqGIO6UJs9lmpeonYNs2uLRti6MKQnB5e3vjm2++weXLl9GwYcNS9VFNNZUNZWdyFhTz\nx0kBgGQGgHcaJyokKQTmdc1LXC8jOAMPPnuAlv+2RK2mRYcrCg0FRo8G5s0D9u4Fbt0Sw/4pcjmq\nXVtUeIcPA+HhwMSJwMmTQIMGwL59BcsbjzNGq5Ot4P+FP8K3hSv0pXsba/VfW32NTYM3YcC/A3D3\n+d1y708Z3pc9inXO69DSsCV6N+xdeAFbWxyJsEa/nkSaTxp0B+mWXPbwcKxJT8cPpqaopapa4HZQ\nUBCGDRuGHTt2oGvXriUX4i3xvrzz0lCVZS9PlFVyORKJRBMvgjJLJBILANnlNiolCEkOQaO6JdtP\nkCZI4TvMF42XN4beQMXLnElJwE8/AR07AlZWwP37QP8Srh7Vrg2MGyfOAl1cgNWrgTlzANlr9ia6\n1rro6NwRETsi8HDKQwjZ787y8tPWn+LAyAMYcXwEbj65+c7G8T4Rkx6DHZ47YFTbqPDg4REREGLj\ncDuuO9qlmUJvmB5UNQoqqeJ4vnIlLvTqhRmtWxfSRQQGDRqE5cuXY8yYMaURo5pq3gnHjx9Hq1at\nUKdOHVhaWsLJyankjSjyLeArXwoJgIkA7AHEAjgCIASAdXF1y/LAaz4dzbY044OYB0r7UQgygd79\nvRk0N6jIchERZKNG5Ndfk+HhSjdfLAkJ5IABZP/+ZHR0wfvSVCl9x/jSs7sns8Kzyq7jUmAfYk/D\nNYa8EXzjnY7jfWDG5RmceWUmzTeaMyA2oGCBw4f5tOMQ9up1jZ59PBl7PrbknXh7c878+Zz7oOD/\nQ3x8PFu3bs1Vq1aVYvTVvA+gkvrJ3bhxg+bm5nRzcyNJRkREMCIiotCyimQkqXSAZl8A+gCGQXQd\nMFCmXlkeeV+IIAjUWKHBtOw0pR9YyKoQevX2KtIZOz2d7NKF/P13pZstEVIpuXgxWb8+WZjvrSAX\n+PT3p3Sq78Rkl+TyGYSSOIQ40GCNAV2eu7zTcVRm7kfdp+EaQwbEBLDu6rqUC4UEPP7mG+7psJi/\n/HSId+reoSxTVuJ+4j//nLo2NnyemT94eFpaGrt378758+dTUCI4czXvJ5VVyfXs2ZP79u1TqmxR\nSk7Z5UovAE1IXiZ5iWRcyeeMZUd0ejS0amihdg3lgh+nuKcg7O8wtDzcUqGztyAAkyYBzZqJRiPl\ngZoa8OefwO7dwKefAn/9Jfb7EomKBOa/maPZtmbwHe6LJPskAO9mrb5Xo17YP3I/RhwfgQcxD956\n/0Dl3qMgidnXZ2NJnyUISghC1/pdC/XnpK0t/n02GB/oqeZbqlRa9oAA/FO3LkaZmMBMQyP3ck5O\nDsaMGYOWLVtizZo1lSbVUmV+529KVZb9dQRBgIeHB2JiYmBpaYmGDRti5syZyM4u+S6ZskquG4C7\nEonk8YvgzL7vMkBzSYxOZGkyBHwZAMttltBooKGw3JIlQEQEsGcPUN6fB0OGAO7uom/dyJFAQsKr\ne0lZSQjrFobUXam4Pfk24m69u+8THzf7GOsHrsfAwwMRGBf4zsZRGbnw8AKi0qLwXefv4Bruim71\nuxUs9OwZ5IkpeKjWAIa2JjD6zKjE/WSvX49to0djXuPG+a4vX74c6urq2LVrV6VRcNVULCQSSZkc\npSE6OhpSqRRnzpyBk5MTfHx84O3tjRUrCokWVAzKuhAMKnHL5UhJlFzY32HQ6qwFo08Vf4D8+y9w\n9KhoIKKhWA+WCVmyLAQnBCMoLQhfb0nC8dMZaDwlHC36eSA4wxM58hw0rtsYtdRr4dm3zxBnHwcT\nTROYPzVHC4MW6N2oN3o17AU9TT2oqqhCQ02j1BFflGF8u/GQC3L0P9QftybeQguDFuXW1+tUVr+h\nxMxEzLk+Bzs/3gk1FTW4hLlgTvc5BQva2iLYrDO6mvsg644BdM+9ciNRSvbnz3EsKQnt9fTQuvar\nVY3IyEjs2LEDPj4+UFNT9l+8YlBZ33lZUNFkpwJr77eBpqYmAGDWrFkwMhI/u+fOnYs///wTf/zx\nR4naUuo/gGRoCcdYriir5GSpMoRvDYeVo+LoD46OoouArS1gVPIv0gUgiecpz+ES5gKvSC8ExgXi\nUfwjJGUlIUOagSxZFszrmsNS3xL6mvpo0as2jMyNcWXvj5j/ZUf8MssEKnmir8S6xMJukh0wHYhq\nFYXzgeexwGYBUrNTIVCArqYuFvRcgKmdphbug1UGTOowCQDeiaKrbMgEGcaeHotRzUdhoMVACBTg\nHuGOrvULMdu3s8P17C74wCIR+jrNS2xVyQ0b8PfEiVjXpEm+6ytWrMBXX32FBg0avIko1VTzzqhb\nty7MzPL7i5Z6RULRZl1FO5Bnk3TaxWnc5rat2M3I0DWh9Bvrp/B+XBxZrx559WqxTSkkS5rFvV57\nOfr4aHbe1ZmGawxptNaII46N4O92v/PUg1P0jfZleEo4EzMTKZVLC20nOJi0siLHjCGTkvLfu3b4\nGl0sXRj8UzAFeX4DAs8IT44+PprGa4258MZC+kUrlvdNOehzkKbrTekf419ufeTF1tb2rfRTlsy+\nOpsDDg3Ifc8PYh7QYpNFoWWFho3YUdOdNz47yNgL+a0qi5U9MpI3rK3Zxskpn1HJ48ePqa+vz9jY\nUlhpVgAq4zsvK8pLdlRSw5MlS5awa9eujImJYUJCAnv16sWlS5cWWlaRjCSVXq6sUIQkhWB4s+FF\nlpFnyhG2IQztrimO3jFrFjB2LDC4FEkMcuQ52OSyCRtcNqCdcTtMaj8JjXUbo6FOQ9SrU6/E3zos\nLABnZ2DuXDEm5unTQIcO4r2a9WvCytkKfiP8EDA+AC32t4BKTXGJsmO9jjg79iwC4wJxwOcABh0e\nBOM6xpjYbiLGtR0Ho9plMD19wcT2EyGBBB/9+xFsJtiglWGrMmv7fWCf9z5cDroM1ymuUFMR/7Vc\nwlzQzayQ/binT5GdmgW5ZQY0bptB92AJI9788Qf+nj4dcxs3zve3tmTJEsycORMGBgZvIko11bxz\nfvvtN8TFxaFZs2bQ1NTE2LFjsXjx4pI3pEj7ldUBYDCAQACPAPxUyP0vANx7cTgCaKugnVyt3XxL\n82JnLGFbw3h/xH2F98+dI5s2Fd0GSsrd53fZeltrDj0ylPejFPdRWo4cIQ0MyP/+y39dliGj7/98\n6dXHizlxhecZk8lltHlswwlnJ7Du6rr87fZvzJZll+n4Dt87TJN1JnQLcyvTdiszjqGONFxjWGCW\nO+XCFG522Vywwt69dG40krOmrKf/+BLOjIOC6NK9O80cHZkpe+Vy4OHhQRMTE6akpJRGhGreU1BJ\nZ3IlQZGMpJJ+cqU9IFpvBgNoBEAdgA+AFq+V6Q5Ah68UoouCtkiKPnKaKzSZmp2qUGBZmozOZs5M\ndi3c1+zlMuWdOyV7kClZKZx1ZRZN1pnwmO+xcvU9cnERx7j5tc9HQSYweH4wnRs5M8Wj6A+ziJQI\nDj86nO22t6N3pHeZju9C4IVqh/EXhCaFst66eoUm7229rTXdw90LXJd/OZ5zam/mqblzCixVFsvY\nsfzo3DnuzBOtQBAE9unThzt37izx+Kt5v6lWcuWr5LoDuJrnfFFhs7k89+sCeK7gHkkyKjWKBmsM\nihT46fKnCvfiBIEcOZKcO1e5h/eSK4+usOGGhpx0bhLj0uNKVrmUPH5MtmhBjhljS9lrPsLRp6Lp\naODIiH2FRwB4iSAIPOhzkIZrDLnMdhlzZCXPNK0IhxAHGq014nb37eWi8CvD/kxiZiLbb2/PtU5r\nC9xLykxi7T9rF3zmgsAsw/oc0OgmHYatoDyroJO4Qtk9PWnbrx8tnJ2ZI39V79y5c2zTpg2l0sL3\nfCsLleGdlxfVe3KlpyglV3625yL1ATzPcx724poipgC4WlSDxVlWZodnI2xTGJqsblLo/X/+AcLC\ngJUri+rlFbHpsfjy7JeYcWUG9gzfgwOjDkC/1ttJUdKkibhPFxwMjBkjZjl4idEnRuhwpwNCoMYQ\nDQAAIABJREFU/wzF0yVPX/7RFkAikWBi+4nwnuYNtwg3dN3TFdFp0WUyvl6NeuHO5DvY5r4NX134\nChnSjDJpt7KQnJWMQYcHwdrcGvN6zCtw3zXcFZ1MO0Fd9bXs3sHByMog6n/oDsPWfXL3V4uFBBcu\nxC/z5mFZ48ZQfxEpPCcnBwsWLMDff/9d6VwGqqmmvKkw/xESiaQvgMkAPlRU5quvvkJarTSkx6Zj\nY/pGdOjQIde35GW0AOMDxjCdagrXEFcgBPnuBwcDy5ZZ4+5d4O5dsfzr9fOeOz9zxqaYTZjYbiK2\ntdoG9efqgAUUli+vczc3awwfboeOHQEHB2sYG7+639O5J3yH+8LB1QEN5jdAvwH9Cm0vyCsI8+vN\nx3Wj65hwbgIWmS2CikSlTMbn8o0LRv01Cu0d2sN2mS3MtM3KTP6XvM3nrcz5lRtXsMBmAfr27YsN\ngzbA3t6+QPmjPkfRo02PAvV52xZb5C1goHUCZl/+UGj7L6/l69/NDZk6OkjS10e9gADYBQbC2toa\n27dvh76+PtTV1fPVrUjPq/pcufOXvEl7dnZ2OHDgAADA3NwcVR5FU7yyOCAuV17Lc17ociWAdgCC\nIKb0UdQWSXL1ndWcf31+oVPWVJ9UOpk4UZpccMkmM5Ns2ZL899/ip76CIHClw0rWX1+fzs+ci6/w\nFhAEculS0tyc9H/NTkGWLqPvKF969fZidmzRRiZSuZS99vXiSoeVZTw+gX85/kWzv83oEe5Rpm1X\nNCJTI9lxZ0dOvzS98HiULxj07yCeDzhf4Hri4M85T3sLHf4eoHynMhnZrh0/sLHhsaio3MtpaWk0\nMTHhvXv3SiRDNVUHVC9XlivuAJpKJJJGEomkBoDPAfyXt4BEImkI4AyACSQfF9dgSJLiFDsRuyNg\n+r0p1LQLTlCXLAHatAHGjy+6/Rx5Diaen4izgWfhOsUVPRr0KG5I5Y6dnR0kEmDZMvGwtgZu5smE\no1pLFa3PtIbOBzrw6uaF9AfpCloSs4EfHXMUG103wulZKdJWKEAikWDhBwuxefBmDD4yGJtcNkEu\nyN+ozde/3VYEHsY9RM+9PTGq+ShsG7pNYbQZgQJcwwv5+yGh6miHnJYa0DNVuGhRUPYjR+DYujWi\n6tTBJ4aGuZe3bt2K3r17o1279yPRbUV852+Lqix7uaJI+5XVAdFi8iHEmdqiF9emAZj64vfdAOIh\nBoH2BuCmoB2S5ODDg3nx4cUCmlyeI6ejoSMzHmcUuOfsTJqYkDExRX8bSM9J55DDQzji2Ahm5BRs\n513x+oa0ra0oz8aN4gwvL5H/RtLR0JFxl4o2jvkv8D823NCQ8RnxZTtYkoGxgeyzvw877+r8Rlad\nFckIQRAE7vPaR8M1htzvvb/Y8n7RfmyyqUnBGwEBjFBvyI0/fcaEcCeF9fPJnplJNmjAYXZ23JHH\nojIpKYmGhob0f31qX4mpSO/8bVNteFJ6FMlIlrN1ZVkeL19I8y3N6RvtW0DIuEtx9OzpWeB6RgbZ\nvDl5+nTRDykxM5Ef7vuQE85OUBiVpCLx5AnZti05eTKZ9Vr6uSTnJDrVc+Kzdc+KtHqcfXU2Rxwb\nUS6WkYIgcK/XXhquMeSCGwtKlBaponE/6j4H/juQVjus6BPpo1Sd3Z67+eWZLwtcj/vjHx5Vm8Cb\nV+tQLlfSf3HNGt6bMoX1nJzy+cUtW7aMEydOVK6NaqosVV3JlfdyZZkiF+QISQpBE92ClpPRh6Nh\nPN64wPVt24BWrUTrREVEp0Wj78G+sDKxwoFRB3KjVVRkGjcWLS+Tk8Xly8jIV/d0euigo0tHRB2K\nQtDMIFAo3PJy9UerEZ4Sji1uW8p8fBKJBF9bfQ2/7/0QnhqONtvb4OSDky//uSo84Snh2OSyCZ12\ndcLQo0PRv3F/uE5xRXuT9krVv/v8LnqYFVzqjj91G5F1WkCndluoqNQovqGEBGDNGvz1zTeYbWYG\nDVUxvmVUVBS2bNmCJUuWlEiuaqqpcijSfhXtAMBnSc9Yb129Alpcmiylg7ZDgSggWVliglLvIlbM\nQhJDaLnZkktuL6mwiSWLWsaQy8nly0kzM9LLK/89aZKUXn286PeZX6G+WCQZHB9MgzUGSs9QSsvN\nxzdptcOKXXZ14dWgq0UabLykPJeuBEHgs6RnvP3kNk/6neQ/bv/wd7vfOevKLPbc25O6q3U54ewE\n3gi+QZm85IlMW25tSc+I11YWBIEJqobcPnwFg4MXFFk/V/Z58/hw/nwaODoyKY8P3KRJk7hgQdFt\nVEaqlyvLHlTCmVydOnWopaVFLS0t1qlTh6qqqpw1a5bC8opkJCtZ7MrHiY9hoWdR4HrcuTjUta4L\ndf38/khHjwKtW7+KAfk6oUmh6HOgD37s9iPm9CgkFUolQEVFNKpp2RIYNEhMGzToRWIkNR01tLvW\nDgHjA3B/yH20Pt0a6nr5n5GFngX++ugvTL4wGa5TXAv6dJUR/Zv0h8dUDxz3O47FtxZj+uXpmGI1\nBZOtJsNUy7Rc+nxJUlYS7oTewb3oe3iW/AxPk57iXtQ9AEBLw5YwrGUIg1oGMKhlgMa6jTHEcgj6\nNe6HGqpKzLQKIS4jDmEpYWhnnN8YJOGOH5LkWmjznTO0tacU31BICLB/P363scGPenrQeeEDd/fu\nXdjY2CAwsDrHXzXvJ6mpqbm/p6eno169evjss89K15gi7VfRDgDc47mHk85NKqDFvft7M/pEdL5r\ncrnoMnDzZuGaPzwlnBabLLjx7kaF3w4qG3fukMbG5P79+a8LMoFB84LoYunC9IcFg3UKgsAhh4dw\nud3ytzNQkh7hHpx2cRp1V+tyxLERPOl3ktFp0cVXVIL4jHieDzjP2Vdn02qHFeusrMOPDn3ERTaL\nuMN9B688usKw5LBym7mfCzjHQf8OKnDdvt9aXlb/knfu6DIrK7L4hsaMof+aNTR0dGTyi1mcTCZj\np06dePjw4bIedjXvKaiEM7m8HDhwgBYWhWfyeIkiGVkZZ3Kv78dlhWYhzScN+iPyRyG5fBnQ1AT6\n9SvYTlxGHD469BG+sfoGP3b/sTyH/Fb58EPA3h4YOBBITQVmzhSvS1QlaLquKWq1qAXvXt5odbwV\ndPu+inovkUiwa/guWO20wsjmI5Xed3oTOpl2QifTTlg3cB1O+J3AgXsH8O3Fb1FPqx5aGrREE90m\nMK5tDFUVVahKVKGjoQNdDV3UVKuJ9Jx0ZEgzkC5NR3pOeu7PpKwkuIa74kniE/Ro0APWjayxdehW\ndDbtXOpZWWlwCHVA70a9C95wtIekVy+oqTmjZk2Tohu5dg3w9sbvS5dijrY2tF/M4nbv3g1NTU18\n8cUX5TDyaqqpeBw6dAgTJ04sdX0JK4khgEQi4WenPsOIZiPwZbsvc6+H/B6CnOgcNNvWLPcaKX7g\nz5wJfP55/nZy5DkY8O8AdKvfDWsGrHlbw38j8ka+UIbQUKB/f+Cbb4Cff85/L9E2Ef7j/NF4RWOY\nTsm/TLjPex92eu7E3W/ulmu2cUXIBTn8YvwQlBCExwmP4XXXC/Xb1YdMkCElOwUJmQnIlmejtnpt\n1K5RG7XUaqF2jdq551o1tETlWa+QUFpvkc67OmPj4I34sOErP7jnt5NQu78F4mx+g8zUHa1aHVHc\nQFYW7CwsYLh3L/ppaSG4Wzdoqanh+fPn6NixI+zs7NC6deu3IMnbp6R/6+8T5SW7RCIByQK5vyQS\nCYv6/C9tjtLXeRMVExoaiqZNmyI4OBiNGhXuHw0olhGoQGG9lOFxQv49OQpE1IEotD6V/x/+yhXR\n6vDTTwu2MfvabGjX1Mbqj1aX93DfGY0aAQ4OwIABQGwssG6duHcHALp9dWF1xwq+H/siIzADFn9Z\nQKIq/m181eEr7PLchcP3D2Ni+9J/cyotqiqqaG/SPncmaSerfB94qdmpCIwLRBfTLvmuX/neGUNq\nGkEw84N2nWICDKxZAzRpgp9MTbFQVxdaamogiWnTpuHHH398bxVcNRWLijD/+ffff/Hhhx8WqeCK\nRdE6ZkU7AFB3tS5j0l55dCfcTqBbW7d8eytyueg/dr5gNCVud9/OlltbMjmr8BQ87xsJCWSfPuSn\nn4r+xHnJScihdz9v3v/4PqUpr6z2XJ670HS9aZGpjKpRzLWga+y9v3e+a2kBadyo8huDh82iq2sr\npqQU9OfMJSOD1NHhjYAAWty9y6wXmQYOHjzIDh06MCen7LJIVFM1QCXek2vWrBkPHDhQbDlFMrKy\n7cnJBBkMar3KeBy1PwomX5vky4x87BhQuzYwYsSregIFLLdbjv0++3Fr4i1o19R+C4OVAeHhwNOn\nwLNngCAANWoA6ur5f9aoId5LTgZSUoCcHEAuB3R0xBThFhalXjfQ1QWuXwe++kqc1V24AOjpiffU\nddXR7lo7BP0QBO8PvNH2YltoNNJAN7Nu6N+4P1bdWYU/+/9Zds+jiuAQ6oDeDfPvx9n/HI1OEgeY\nfT0dEdn7ULt2ESG4bGwg69gRc1NTscbCAjVVVBAVFYUFCxbg2rVr+YIwV1PN+4yzszMiIiLwySef\nvFE7lUrJWehZ5Co0WYoM8RfjYbH+1fJlTo5oTr9v3yu9kJqdii/PfonErES4f+sO4zoFHcbfCKkU\nuHMHcHISFVpIiPgzIgIwMgLMzcX1QzU1cYBSqfgz7+8SiajUtLSAmjUBVVUgPh5YsABITYWdqSms\nu3QBrKyAIUMAS0ulFV/NmsCRI8CiRUDPnsDVq6IjOQCoqKug2Y5mCNsYBq8eXmh9tjV0uutgVf9V\naLejHb7p+E2hjvdvi8q4P+PwzAFLer9y0M4KzcKZqzn4R8UDaZ1qoE5CJ6gUFWzg/HnsmzwZqj4+\nGN25M0ji+++/x5QpU2BlZfUWJHi3VMZ3XlZUZdkL49ChQxgzZgxq1679Ru1UKiWX9wM30SYR2j20\nUcPwldXcsWPixKdPH/GcJKZcnAIdDR2c/ux02VrY+fkBGzYA58+Lid/69wd69ADGjRO1SIMGooZ5\nU2JiXk1PXV3F/ZqaNYGGDYE6dYBmzYBp04DmzRU2oaIiVmvUSDTIuXIFaP/CgFIikaDBnAbQtNSE\n3wg/WG6zRP1P62Nu97lYYLMAZz478+YyVBGyZFnwjvTOF5T58ZIQZEmCIGvfGSmCD3R0eipuQCaD\ncOkSlk+ejCWpqZBIJDh16hQCAgJw9OjRtyBBNdVUHHbs2FE2DSlax6xoBwAuuPEqwkPomlAGzQnK\nty77wQfkuXOvznd57GK77e2YKX1tQ+pNcHYmhw8XHdL+/JN8/rzs2lYGQSAfPBCjNP/3H/nzz6SR\nETlgAHniRMHNt9c4eVIcuptbwXup98RURTGnY5iRk0Hzjea8/eR2+cjxHmIfYs+uu7vmnqd4pnBd\nXT8eNZxFrlhBH58BjI39r4gG7OkyYgRbu7qSJGNjY2liYkJn54qR7qmaygkq8Z6csiiSkaxkAZp3\nuO/IFerh9Id8vvmVggkIED+8X+7L+0X70WCNAQNiA97w8VFULDduiFYcjRqRW7eKBgIVhcxMMVFe\n//6knh75449knmj1r3PxImloKDqPv06KVwodjRwZdzmOpx6cYrvt7SpFwOqKwG+3f+PCGwtJig72\nXr29OKRDBuPrtaLgepcODtrMzi4iFcacOfztwAEuDA6mIAgcOXIk586d+5ZGX837SlVXcpUqQHNe\n94Gsp1nQaKyRe75vHzBpkmjPkZyVjE9PfYq1A9aihUGLN+vUwwP46CPghx9Ex7OgIGDGDNHT/C1R\nbJ4pDQ0xUd7Nm4C3t7j/16YN8OOP4t7ga3z8sbhPN3p0/rx0AKBlpYW2/7VF4FeB6P2wN3Q1dLHb\nc3fZCVMCKlt+rUuPLuHjZh8DEEPNRcRIEPokDrpZUUhvroEaNYxRo4Zh4ZVJ4Px5XGnSBEP19fHD\nDz8gIiICq1ateosSvHsq2zsvS6qy7OVJ5VJyunmUXEgWNMxFJSeVAocOAV9/LVpgfn7mc/Rr3A9f\ndfiq9J2lpwPTp4tmmp99Ju7BTZggatGKTMOGomOcv39+ZZc3TQFEa8szZ4AvvhCjw+RFu5s22l1t\nh+AfgvFLwi9YarcUUWlRb1GIykdYShhCk0PRo0EP5MTl4PG8x3Ds2gw/dbwJSf9+SEl3g7Z2Ef5x\nvr6I1NbGE4kEagEBOHLkCE6cOIEaNd5epJZqqnkfqVRKroFOAwDiEmteJXf5smhw2Lw5sODGAsgE\nGTYO3lj6jlxcxKjOmZlAQIBo2PEOlVupLK5MTID160Vlp6ICtGsHHDyYz8Ozd2/g4kXxy8HFi/mr\na3XSQkfnjtDZo4MxCWMw68qsNxOiFFQmS7PLjy5jSNMhkGRJ4PuxL/TGGuHw7VoYoXYFGDoUKSl3\ni1ZyZ87g6qRJ6K+tjYnjx+PAgQNo/NIMtgpRmd55WVOVZS9PKpWSe5nnLScqB6paqlCrI57v3Suu\nJG5x3YIrwVdw8pOTpcsJJ5UCv/0GjBwJrF4NHDggmva/hlwuh5eXF7Zv347Lly8jPj7+TcQqX0xM\nRCtQGxtR6Y0eLfrkvaBbN+DSJfH52djkr6rRSANWTlaY5DYJbj5uOH///FsefOXhUtAlDLUYCv/P\n/VGreS0E9GiMxvVzUNfdBhgyBMnJzootK0ng2DFc7tQJDX19YWBggFGjRr1dAaqp5j2lUim5l2SF\nvNqPCw8XXdSkrQ5hrfNaXB9/HbqausW0UAhBQaILgJcX4OOTL8tqZGQkNm/ejG+++Qa9evWCvr4+\nxo8fDzc3N2zcuBFNmjRB8+bN8dVXX2HHjh24d+8e5HJ5WYlbNmv1HToA7u6i0hs4EEhKyr3VpQtw\n9qy4dOngkL+auq46ul7pit9jf8d3R79DXFjcm49FSSrLHkWGNAP2IfZosrYJhGwBzXc3x44dEvxq\n7Qg0awapvjpycqJQu7aCcFxeXsgBcEsiQeCpU5gyZUqlkb2sqapyA1Vb9vKkciq5p6+WKg8eBDqN\nP4cld37C9fHXYV7XvOQN2tiIDmRffSVOa+rVQ1ZWFk6dOoVhw4ahVatW8Pb2Rvfu3bFixQoEBQXB\n398f+/fvh42NDRISEnD69Gn07NkTrq6uGDt2LHR1ddG/f3/8+uuvuHLlCmQyWZk+g1JRsyawfbs4\nfXtN0X34IXD8OPDJJ8C9e/mrqdRUwYRdE2Bd0xrTFk5DxqOMtzzwio3NQxu0iG+BWkm10OZ8G7h6\nqsDPD+ibeRkYNgwpKS7Q0uoCiUS18AaOH4fj1KlokpkJZ3t7jB079u0KUE017zOKzC4r2oE85q4h\nK0IY/FMw5XKyYfvH1PlTnx7hHiW3OxUEctMm0sSEtLcnSWZkZHDevHnU19dnv379eOjQIaalpZW4\n6bi4OF6+fJm//voru3btyvbt21ccfydBIGfNIrt2JVNS8t06cULMpv70acFqCRkJNPnDhP+0/4eJ\nDolvZ6wVHGmqlGOmjuH87+ZTni2nIJDdupGHDpFs3px0d+fjx4v55MlvhTcgl5NmZpx29y6HLF7M\nyZMnv9XxV/P+gyruQvDOlZeyR94XEjglkOE7wnnrtpy1vu/DNY5rS/5UZDLxg75169xP9EePHrF9\n+/YcO3YsQ0JCSt6mAgRB4NGjR2lqasqJEyfy8ePHZdb2GwyKnDKF7NevgAP55s1ks2ZkTCEuXacf\nnGazv5rxtsltPt/8vNwSj1YGchJy6N7dnUa/GTEwOpAkefQo2akTKX8YJH55ksvp7d2XcXFXCm/E\nwYEZVlbUdXCgRbNmdHR0fIsSVFMVqKxKLiwsjMOHD6eenh7r1avHH374gfIXActfpyglVymXKzOf\nZkLDXAOLzvwDo3o5mNtjTgkbyBTz8Ny/Dzg6AubmOHPmDHr27Ilvv/0Wx44dKzq1gyAAt2+LVpfD\nhwN9+wKDBgFz5wL794t7X+npucUlEgnGjRuHgIAAmJubo0uXLpg6dSqePHmi1HDLZa1eIgF27AD0\n9cWke3mWU2fOFLckP/44nxgAgP+1/B9aNWqF69uuI2pfFALGB0CWWj5LsRV5jyI7Khs+fX0Q+GEg\nTOuborlRc2RmijFC//4bULl6GRg6FAIEpKZ6QFu7e+ENHTuGC9Omoenjx1BXUUHPnqJxSkWWvTyp\nqnIDVVv2wpg1axb09fURFRUFHx8f2Nvb459//ilxO5VSyWU9zUKQZjQ86izDsbH7oaqiYK+j0MpZ\nwKhRYvT/a9eQU6sW5syZg/nz5+PKlSuYMWNGvqwG+QgOFq0vGzcWFVqzZsDUqWJU6FmzRKOO27eB\nb78FDAyApk3Fvn77DQgMhLa2NpYvX45Hjx7B0NAQXbt2xbhx4+Dt7V02D6akqKoChw8DGRmiPHn4\n80+gdWvxu4BU+uq6RCLBP0P/waGnh5B0LAkqmirwsPJAimvKWx78KxIyE3Dj8Q2surMKk85PQs+9\nPdFrfy+scFgB78iyf7YJNxPg2ckTRp8awbaXLb5sKybxXb0a6NxZdM3AZXE/Lj3dDzVrmkFdvRBj\nqJwc4PRpHGjfHur//YepU6cq/turppoqhp+fH8aOHQt1dXUYGRlh8ODBePDgQckbUjTFq2gHXkyt\nBZlAuxp2HLN5Cc2/+7Fk89/sbHLYMDHBmlTKiIgI9uzZkx9//DHj4+MLryOVigEfe/cWY0TOnk16\nexffl1RK+vuTp06RCxeKcbRGjxZjab1Y4ktOTubatWtZv359DhgwgDdv3nw3y3+JiWSLFuT27QVE\nGDaMHD9e3DrKy43gGzRdb8qo1CjGnI6ho5Ejnyx9QnlW4csJZc3tJ7c5++pstvmnDeusrMM++/tw\n3vV53OO5h/Yh9rwWdI2zr85mww0NOe70OMZnKHi/JUCWKePjRY/pZOrEhJsJzJRmUne1LsOSw+jt\nLb7i8HCKify0tcmUFIaFbWVAwNeFN3j6NMOGDaPO2bPU1dVlUlLSG4+xmmpeB5V0uXLWrFmcMGEC\nMzIyGBYWxjZt2vDChQuFllUkIyvjnlxmaCadTJ1ovKwNv/y5BPsX4eHkkCHkqFFkTg7d3NxoZmbG\nZcuWFb7Om5ZGrl9PmpmJCu7UqVeBMUtDWpq42dW8OWlpSf7xB/li3y8rK4v79u1j8+bN2adPH7q4\nuJS+n9ISFCQG/7x1K9/l9HSyVy/y++9zdXMuv9z6hR8d+ogyuYxZYVn0HeVLl2YuTLiZUG7DjEuP\n4+enP6flZkv+6fAnXcNcKZPLFJZPz0nn7KuzabrelNeCrpW63/jr8XRp6kLf0b7MjsomKe5P9jvY\nj9nZZPv2ZG5ux717yf/9jyTp5/cZIyMPFN7okCFcde4cO0ybxlmzZpV6bNVUUxSlVXJYhjI5SktC\nQgKtrKyopqZGFRWVIo2y3isll2iXyLMDzlLz13rcvUeJWYNUSq5bR+rrk4sXk9nZPHHiBA0MDHjm\nzJmC5eVyUbkZGZGffEJ6FpHFuTQIAuniQk6fLgZT7ttX/HRMTaVUKuXu3btZv359fvLJJ3z48CEF\nQeDNm1eYmRnC9PRAZmWFMScnnmlpfoyN/Y+xsReYkxNXNmO7fVuU++HDfJeTkkRjikWL8heXyqXs\nf7A/p1+anjsDjb0QS+dGznzw5YNcZVBabG1tc38XBIFn/M/QdL0pZ1+dzfSc9JK19dSWJutMuM1t\nW4nqpXin8P7H93m38V3GXc7/nEcdH8W9Xnu5dKk44839EjBwIHniBAVBoKOjETMynhZs+PlzCrq6\ntLS1ZV0DAwYF5c+okVf2qkRVlZssP9kr60yuS5cuXLVqFaVSKRMSEjhy5EguXLiw0LLvlZKLPBDJ\n2TNn0/jr7+ngUMxTksvJL78UZ2IvFMa6detoZmZG78KWHBMTyaFDxanLgwfFNF4GZGaKS6HDhlGu\nr82k+UP57PZ0uruP5vffG1NHR8KRI1X4++/qdHY2o4tLUzo51aODgw5dXJrz3r0h9PEZSAcHLbq5\ntaG//yQ+e7aeiYl2lMlKmV5o1y7RtDIh/2wsNlY0RF2yJP+MLjkrmR13duSS20tyr8nSZAxeGExH\nA0c+3/Sc8uzSLWG+/KcPjg/mkMND2GpbK9qH2JeqLZJ8nPCYzbc059xrcykXFI8pJz6HUUej6Dva\nl04mTny+8TllmflniwkZCdRepU0bhyQaGpJhYS9uxMSIS5VpaUxLC6Czc8PCO/njD9795RcaLVrE\n4cOHF7hdVT/sq6rcZLWSy0tsbCwlEglT8rg4nT9/nm3bti20/Hul5J4sfcI2S9tQu/0tRkYW86Tm\nzhWTzGVkMCcnhzNmzGDr1q357NmzgmXv3yebNhXT1LzJsqQSCIKcmZkhjI4+yaCgOfT07E57O026\nXzblwz/0GTlOnykbZjDskTN//HEm9fT0uGTJknwvPC9yuZTJye4MD9/NR49m0sOjK+3ta9Pbuy+f\nP9/M7Oyokg1w9mzyo4/EWXAeoqNFRffrr/kVXXRaNC03W3Kt09p8e4qp91N5b8g93jW/y8gDkZRL\nS6bs5IKcm1w2Uf8vfa5xXMMc2Zu/l/iMeH6w9wNOuzgt31hzEnIYvjuc3v286aDlwPvD7zN8Rzhl\naYUvhW68u5Ejj3zCxo3JfAsC27eTn39OkgwP30F//4mFCCYnGzfmVHt7Glla8ubNm28sVzXVKKIy\nKjmSrF+/PtesWUOZTMbExESOHj2a48ePL7TsO1VyAAYDCATwCMBPhdxvDsAZQBaAuUW0Q5K0+dqG\nusv1WFtLWmCPKB9//SV+IsfH89mzZ+zRoweHDRvGxMRCnJiPHSMNDMScbGWITJbOlBRvRkUd49On\ny/jgwed0d7eivX0tOjnV4/37wxkSspIJCbcplaa+qujtLc5AjY3Jv//m08BAjh8/nsbGxtyyZQuz\ns4tfBpRKkxkbe4H+/uPp4KDD+/dHMjX1nnIDl0rFJbf58wvciokh27YVbWnyPv+QxBCUk8kGAAAg\nAElEQVS23taaUy5MYbYs//gSHRLp1ceLd5vcFRVHpuI9tJc8T37Ofgf7sceeHgyKDyq2fElIyUph\njz09OGXnFD6a+4genT3oUMeBvmN8GXM6hrKMoseXkJFAo7VGHDLpPqdNe+2mtXVu5t4HD8YxImJv\nwQZu3WJGp06svWwZO3TuXKV9DaspfyqrknN1deWHH37IunXr0tDQkGPHjmVMYc67fIdKDqKLQjCA\nRgDUAfgAaPFaGQMAnQD8oYySm/vlXA5ePYEdOyp4MoJALlsmzsqeP6eHhweNjY25atWqggYmcjm5\nYAHZuLFyFpMKu5QzLc2PkZEH+ejRj/TxGUhn54a0t9egq2tr+vqO4ePHvzAy8hCTk90olSppRXf/\nPjlyJG0NDMhdu+jt5sZBgwbRwsKCp0+fVvrDUSZL5/PnG+noaEx///HMyVHCMCQujjQ3Fw1uXiM2\nluzeXbS6zKtvU7JSOPr4aH6w9wM+Tijo8J7kmMR7w+7RqZ4TQ9eGUppSeDLWm49v0mSdCb/e+HWZ\nJmzNic9h7IVYPvrxEa83us7WP7bm5OWTmeCQUCKr0DnX5vCDVVPZqpVomJNLeDhZty6ZmUlBEOjk\nZMqMjOCCDYwZw8P797OWuTmvX79eaB9VddmuqspNVi9XvgnvUsl1B3A1z/miwmZzL+4tVUbJtZnW\nhnPW/cexYwuRVC4nf/iB7NCBjIpiQkICzc3NefLkyYJlpVJy4kRxOTOu5IYbgiAwMdGeDx/OoJOT\nKe/ebUI/v7EMDf2LcXGXmZERTEEofsaiDLbbtomRSZo2JY8do83162zXrh0//PDDElliSqUpfPjw\ne7q5tWd2dnTxFTw9Rbt4f/8Ct9LTyZEjxWTksbGvrssFOdc6raX+X/pccnsJM3IKZlBP8U6h31g/\n3tG/w4CvAxh7MZayTBnTc9K53G45TdaZ8NaTW2XyT58Zksln65/Rs4cnHbQc6DPQhyErQpjmn8bE\nzER22tmJ867PU/oLw8O4h6y9XJ+mltEMfl1/rV8v/k2RTE8PopNT/YLthoaSenpss3w5m3frprDf\nqvphX1XlJquV3JvwLpXcGAC78pyPB7BZQdlilZz/Q3/WXViXi3/L5q+/viZlTg45bpxoNJKUREEQ\nOGLECM6ePbvgE8nMFF0JBg9+7at48chkaQwP30k3tzZ0dW3JkJA/mZ4eWKI2Ss3Nm2SXLmSHDpQd\nPMhd27bRzMyMH330EW/fvq3UB7UgCHzy5Fe6urZgVlZYseW5f7+oXPNqshfIZOKypYkJefp0/nvP\nkp7x05Ofst66evzd7nfGpBVcZsgMyeSzDc9o38+e0/tNp8EvBhy8djAf3XtEQV66JTxBEJj+MJ2h\nf4XSo4sHHQ0cGTglkPHX4gs1gInPiGeHHR24yGZRsc9PLsjZdtVQ6gz9i0Gvr6DK5aJryIuwXBER\ne/jgwRcFG1m0iE/nz6eKqSmvv+auUU015UFVV3IS8X75IJFIxgAYRHLqi/PxALqSLJCBUyKRLAWQ\nSvJvBW1x4Z6FeH73OZBxFEOGiIm6AYgROz75RIzgcfIkoKmJdevW4dSpU7hz507+7MppaWIUEj09\nMdqHkpmXMzNDEBGxDZGR+6Gj8wHMzGYhqWYPBGRm4klmJqKlUggkCIAABBKaKiowq1kTDTQ0YKmp\niUYaGlB904gWpJgpYcsWwMcHOd9+iyOmpli1aRPMzc2xbt06tGvXrthmQkNXIzJyD9q3vwlNTfOi\nCy9eDNjZAbduAZqaBW47OwOTJwNWVsDWrWKwl5f4xfhho8tGnPY/jW5m3TCwyUC0MWqDLFkW4jPj\ncfHRRdx+ehuDGwzG1NSpML5ujFTPVMiSZNC00ISarpp41BV/quuqQ62uGlR1VMFsQp4mhyxVBnmq\nHNJ4KZJskyBkCdD/WB+Gnxqibp+6UFEvOrBPXEYcBh0eBEs9S+wavgvaNbULlMnOJrovm42AFHd4\nzrRF6xY18xe4eVOMGnPvHiCRICBgAnR0esHUdOqrMpmZQKNGGDFlCrzs7BDm7Fz0c6+mmjJAIpGA\nZIEPHolEwvL8/H+bKJIRAEqRWbREhANomOfc7MW1UrF1y1Z8rPEx7jxbBiOjumjQoAOse/QAhg6F\nXY0awNy5sNbUxOnTp7F69Wps3bo1V8HZ2dkBKSmwXrkSaNMGduPGAc7Oudl4X8aNe/28W7dGCA1d\nARub09DTG4yuQx1wLrUO9py8itgcf3Tr3RtNNDWR6eUFFQBNevSACoCnd+8iksQzKys8i4mBr5MT\nkmQytP7gA3TW0oK2ry8aaWjg84EDYaCuDnt7+0L7t7a2zhfTztraGhg+HHZaWkBYGKxv3sTkPXvQ\nYMwYXJRIMGDAAAwfPhxDhgyBvr6+QvmePu2O2NgIkH3Qvr0N3NwiFPaPFStgN2AAMHgwrG1tARWV\nfPd79gQ2b7bD3r1A27bW2LYN0NN7dX/PiD0YpTEKXpFeCEoIwrXH15ARlAFNNU2MHzEe+0fuh4+L\nDwCgzXdtAAA3/7sJJzsnTBs2DdJEKRxcHSBPlaNLzS7IDs+G8yNnqKiroEezHlCtowr3RHeoaqli\nyLkhqN22Nuzt7RGJSFirF/1+ra2tYVDLACubrMRWt63ovKsz9o7YC9kTGSQSCaytrREYCHw4cyKy\nDFwQuMEd5iY1C7b3++9A//6wFv/ZcPv2NVhYDICpKV71d+UKWnXsiMs7d+LXZctgZ2en8P1s3LgR\nHTp0KPbv8307f3mtooznbZ77+Phg9uzZb9yenZ0dDhw4AAAwNzdHlUfRFK8sDgCqeGV4UgOi4UlL\nBWWXAphXRFu0WGzB5zvCqK39YhtNEMgJE8gxY3LjTt24cYOGhob08fHJP599+lS0tpw3r2DojkJI\nTnajv/8E3rmjxwdBP3NriC+7e3pS/84dTg0M5K2EBMpKaBWXJpPRJTmZW54/5yR/f3b39KTunTvU\ncXBgFw8PfvngAVeFhPBKXByj81h0FLtWf/8+OXw4aWzMxJ9/5oIffqCenh6XL19ebJqgiIi9dHIy\nZVpaQNF9ZGWJ/obz5hVZzNFRXLX7/PNCVzhLxLvYnzly/wibb2nOJhub8LO9c9lo5jdUm96VRr+3\nYHRq4ZZdDAsjdXVz0xalpHjQxcUy//KnIJDt23Pw//5H0xfRUIqiqu5NVVW5yeo9uTdBkYws7z05\nsW8MBvAQQBCARS+uTQMw9cXvxgCeA0gCkADgGYA6hbTDGZ/NYNDlZOrpvZBs5UoxFMeLfTUfHx8a\nGhrS4XUvcUdHceNo06ZiFVxioj09/9/emcdVWeV//PNFkE1F2VUERCUTzS1zmUwd17RtrLRs2mwq\nHfvlNGlpU+q0l5VNNU3ZYtpm6lhTllvuiCsuLKKggMoiIIhwWS53+fz+eB4REQFluXDveb9ez+te\nnufc85zvPZf7ved7vkv0HxgVFcIdiS/zifhd9Nq+nffHx3Pt2bMsu0Kph7pwtqyMUfn5/DIjg39P\nSuLIgwfZdscOhu/ezb8cPcoVWVnMN9XCyzA+npw6lfTzY/Lrr3PypEns2LEjlyxZQrP5yk4wGRlL\nGBUVzJKSk9X3n5urpSX78MNqmxUVkc88Q7Zvr5WeaYC3rN4oKyMTE8lffyXff5+cMYO8eaiVbp2j\nGTDpn5z09n+4/uh2GozV/FiYP1/LYKNz4sQLPHGiUnqYNWsY360bndu25dIqHHkUioZCKbkGVnL1\ndQDgSv+V3LrBxIEDqRU5DQoqTzVhNBrZu3dvflWeQFDnt980D8G1a6t9kwyGOMbE3MaoqBAuT/iQ\nfffuZpddu/j2yZPMrkVcWn1jtlp5qLCQ/zp9muMOH2ar7ds58uBBfpaezryagtUPHdIKog4dyl1L\nlnDw4MHs06cPN1Xj6HDq1CLu3h1es9dlcrKmvfRYsOqIjNQKiEZEkMuXXxZb3ugUFGgfm0WLNANA\nRATZsqUWKTF6tJafc9EicsMG8vz5WnZaXKy9HzEx5af27OnO8+f3XmxjtdJ6000c2KcPfZ5++qot\nAApFXVBKrgkosNocALgrbBe//FKLz+LkyeS/L+YhfPnllzl+/PhLTURHjmgKrpqK3CUlp5mQMJWR\nkX78+cg/ef2u7Rx16BDX5+bS0kS+jLZs2cIis5mrsrN5d2wsW2/fzkHR0Xw2KYnrcnOr/tI0m7Xs\nG4GBtE6axBUffMDOnTvztttu45ErrCSSk1/ivn39Lg1Mr4p9+7T3dfXqGsdutWq/L26+WdMFzz9/\nWWrMK1JX801SEvnee5rpNDyc9PDQlO706eRnn5EHDmhW2Drxzjuap66OwXCEUVFBl34O16/nV+3b\n0ys8nO/UsmCuo5rtHFVuUpkr64LdKLmYO2M4dy751vO5pJdXeX7FmJgY+vr68vTp0xelzsvTNoeW\nLKnyTbFYTDx16h3u2OHDPQnPcnT0Nvbbt48br1Ryx4ZU/vAXmc3ckpfHV1NT2X/fPoZERfGVlBSm\nVfWNXVioVTzw9mbpk0/ynfnz6evry+nTpzMr69JVm9VqZULCYzx8eDwtNQVhR0drGVm++67Wchw5\nom3p+ftrkR5ffll19fELXNU/fV4eDb9u5aHZ3/CXEe/ynfbv8BGv1Zx/dyyXfmVlbGwDrCQLCjRh\nYmPLT6WmvsrExAoVBaxWnr7xRnq3acO2S5bwfC0H4ahf9o4qN6mUXF2oTsk1aAhBfSIiTH4pGc8l\ndMacVh+hvzEK+O47mM1mDBo0CNOmTcNf/vIXrbHRqJW17tkTWLTosr4KCvYjMfEJODm3w1r3f+D9\ns65YEBqKaR061N3F3wYcKCzEZ5mZ+CE7G7d4eeGx9u0x1tsbLZ0quM7n5ACvvw4sW4bc2bPxckYG\nvv3uO8yePRszZ86Em5sbAMBqNSE29na4uYUgPPyT6ot4xsVpFdGnT9fCDCrerxrKyrSaokuXAlu2\nAKGhwJAhQJcu2nN3dy0apPLh5KR54Z+NzYTX7/+FW0oCPHNS0f58ArzKchDndAOKfYPh2TkAwcFA\n+5JkSHwc4OwMTJ2qxTkEBFz7G12ZV14Bjh4Fvv22/NT+/f3Rtet7aNt2GACAmzZh3B13IHvqVNz1\n7LOYr7zdFI1Mcw0hOHr0KGbMmIHo6Gj4+/vj7bffxl133VVl2+pCCGy+QqvtAYBZK7IYEUEWde+r\nbZyQfPPNNzlq1KiL5iGTSfO2nDjxsp/uJlMhk5L+xsjIAG48/m92iYrivXFxTK+zzappUGgy8fOM\nDN584EC5F+jhwkqmx2PHtJxcI0bw2KZNvOuuuxgSEnJJmjCTqYD79vVlcnLliPsqSEvTbJFjx16T\nO2VZmWZN/uADzVnlT3/Syv6NGaNlUxk+XFv1jRhcwhe6rWCU93gaWrbl/l4Pc/s9/+Kef/yP8f9N\nYM4Zc9U+RVardoPHHtPKLb32mpYMoK7k5mr9VYgKLy5OYWSk38VMNxYLPwwKYs+wMHpv2cJzDZz4\nW6GoCjTDlZzZbGZ4eDjff/99Wq1Wbt68mZ6enpeVpLrAlWRkczNXpu81cIj7AVqDg0mzmQkJCfT1\n9WVKSoomqcVCPvyw9g1ZQXEVFh5iUtLfGRkZwJj4Bzk9PoohUVFccw3pvGzBtZgxUktK+GpqKtvv\n3Mmxhw5xY27uxR8CZjP55pval/Rbb3HLxo2MiIjgmDFjeEzfMDMas7lnTw+mpr5W883Kyi6mPvn2\n21qFaNSGLVu2kMePa6nafHy01GbLlmkFaK+F48c1LXohJ+e1jtNqJadMucSjkiRTU9/g0aOPl/+9\n9fnn6e/iwonr1nF+cvJV3cJRzXaOKjepzJUViYuLY+vWrS85N2bMGM6bN6/K9naj5Nb+ZuGqDv9H\nzptHs9nMQYMG8d8VnE84bx45ZEj5l6DRmM3Y2LsZFdWJyckvcnvmXobt2sXHEhJYYGtXv6ugLh/+\nUouFX2Rk8Po9e9hn3z5+e+bMRUeV48e11GY9erBs506+++679PHx4dy5c2kwGFhamsHdu7vy1KlF\ntbvZnj1aiexRo8itW69diVgs5LZt3DJ8uFYd4h//KK+iXi9s3kzecIMW93ctibnffpvs10/zrNSx\nWs2MigpmQcF+kmRqfDwDnZy49P336bNjR80esZVw1C97R5WbVEquIlUpudGjR3PiFWJM7UbJvTa3\nkAZ3HzIlhatWreKgQYMuVhb49VeyY0fyzBlarVZmZa3kzp2BPH78OSYW5vLeuDh22LmTP1bn6WDH\nWKxWrjl7ln+IjmavvXu5/oKDjdWqlRry9yfnz2d6aiqnTJnC4OBgrlq1isXFqYyKCmF6+ie1u5HJ\nRH78Mdm9O9mjh+aTn55eu9fGxmrul8HBWj2fRYvKA6zrHbOZ/PRTTe5Zs2q/Oly3TnMTrVSTMCfn\nJ0ZHDyJJZmdn8wZ/fy7q25f3x8dzwQVLg0JhA65ZyWlJBOt+XAMmk4ldunThwoULaTKZuH79erZs\n2ZLjxo27KhnJZuZ48lH3D/CndtvQIWoVpk2bhuuuuw7PPPMMkJICDBoErF6N/AgzkpPnwmIpRHj4\nJ/iqMASvpKbi7506YWZQEDxbtLC1KDaFJH46exbPJSfjeg8PfNytG4Lc3ICMDOCxx4D8fGDlSmw9\nfhwzZsxAUFAQFi6cDYPhEYSFvY7AwIdqeyMt3+XSpcDPPwMREUC/fkDXrlpyS6NR8yLJzgYyM4Fd\nu4C8PGDKFOCBB4Ba5N+sF7KztZyTO3cCr74K3Hef5uVSlTzffKO1Xb0aGDr0ksuHD49GQMDDKCu7\nBWNuuQV3Z2fjtoMHcW9uLo4NHOjwnzuF7WiujidxcXF46qmnEB8fjxtvvBF+fn5wdXXFZ599dllb\nu3E8OeHUhblrdpIku3XrpqXuKi6maeANTF82mfv3D+SuXZ2Zmfk1zRYTn01K4vV79jC1PhwNbEhD\nmDGMFgv/mZJC38hIfpqeru3XWSzkG29oe2ubN7OsrKzchDlr1uP8/feA2q/oKlJaqgXLvfuuto81\nebK2d/rkk+RLL2nxjlu3XpYapVFNV5s3k4MHaxHin36qrSrNZm2FFxur7cH16EEevrzwrMGQwMhI\nf8bEHGCnjh35Xtu2tK5axcHR0VySkXFNw3FUs52jyk0qc2VNDBkyhIsXL67y2pVkJNngCZrrlUIX\nH4SNH4y0tDTk5eWhZ88IZL49AsnzjsGrUxhCO7yEdu3GotAKTEk4hnSjEZF9+8LbxcXWQ29ytHRy\nwrzQUEz09cXUY8ewPDsbn113HbrMmQMMGABMmQKXqVPx93nzcN9992HWrFl49NEWePjhefjzn08g\nPPxNiNQuZACursC4cdpRj5jNBhQVHUZRURyKixNRWpoMi6UEpBkuLj5o2/YWtG07Ap6ePWrubMQI\nbTW3di3w/ffAwoVAWpp2LTRUG/u+fYCHx2Uvzcj4GNHRQ/DKK2OwKCAAf37gAfwwdChKT53CQ4GB\n9SqzQuEoxMbGIjw8HBaLBR9//DHOnDmDRx555Kr7aV7myqHLMWP7ZHz99ddYvfp7vPREEngmDeET\nNqG1/xAAwI78fDx09CjGtmuHRV27wl2ZiWrEQuL9tDS8cfIkXggJwcygILTIygKefFIzBS9dCvTt\ni8jISLz00lwcP74f06f3wrPPboSrq1ejjtVkysOZM0tx5swSlJQch6dnT3h69oKHRzjc3LqgRYtW\nEGmBsrIM5OdvQ17eBnh6Xo/Q0Ffg5TXo6m5mMGhKrZr4v3PnkvDEE70QHR2A1YNvRp+sLJxfswY3\nHDyIpd27Y3i7dnWUWKGoG83VXPncc8/h888/h9lsxtChQ/Hhhx8iLCysyrZ2Y6785CPNI/KhhyZz\n1jPtmPoXD1rjtWwTFquVC1JSGLhzJ3+ua/p7ByWpqIjDDhzgwP37GWcwaE4py5ZpKbwWLNBCBUhu\n3LiO/fsHsFOnlvzii3dY1gjxXwZDPBMSHuP27V6Mj3+A585to8VS830tljKmpy9mVFQnxsbeTaPx\nTL2NafPmzQwObsXbbuvBvAULyIgIWnNzeU9cHP9a29xlCkUDAzsxV1bHlWQkm5l35aFDZFnZOQYG\nunDDP/uQc+eSJHPLynjr4cMceuAAM+wksLsijblPYbFa+Z+0NPpGRvLllBSt6kJamhZq0K+fls6L\npMVi4fLlT7NPHxf6+7fhnDmzeaKWeRlry+bNm5mXt4WHD09gZKQ/U1IW1JxA+gqYzSU8cWIuIyMD\nmJX1Q53GdeTIEU6aNIkdO/px4cIAmr/+QvMIPX2a/0lLY++9e1lSTdWH2uCoe1OOKjep9uTqQnVK\nrpabKk2D667Lxdq1I2GxuGDksgLg7rtxtKgIA6Kjcb2HBzb17o32rq41d6S4Ik4imNaxIw70749d\nBQW4MToa+1u3Bn77Dfi//wPGjweefhpOhYWYPPlf2LEjGosX90VKyicYMKA3Ro36I1asWIHi4uJr\nHoPVakJW1vdITHwSiYnT4Ot7BwYNSkVo6Hy0bOl/TX22aOGGsLDX0avX/5CaOh/x8ZNQVpZT69db\nLBZs2rQJU6ZMwbBhw9CnTy98/XUbPNLpPrSY9QLw22845OWFl1JTsSIiAm7KTK5QNAma1Z7c7t1d\nsXlzV8RFOuHbuDhsO3QIk44cwVthYXikfXtbD9HuIIlvsrIw+8QJjPfxweudOyPQYADmzNHCAubO\nBaZNA9zckJ8fiePHX8eaNZHYuLEdYmNzMWzYCNx+++247bbb0OFCiexqKC1NQ3b2cqSnfwg3t87o\n1OlZ+PhMqL2DSy2xWEqQmjoPWVnfoGvX9+HnN6nKHJ35+fnYtm0bNm7ciJ9++gn+/v548MEH8eij\nDyIj42+wHotBz7+dB9avR0pICIYePIj3unbFJP9rU8QKRUPQXPfkrobq9uSalZLLyPgcs2Ztxoii\nInTv1w93jxyJ73r0wEi1ud+gnDeb8erJk1iSmYnZwcH4W1AQXOPjgRdfBA4eBGbO1JIfe3ujpOQE\nMjIWIzl5JaKizmPv3naIijqDsLDOGDr0ZgwYMBB9+/ZCcHA7kAUoLj6KoqI45OdvQXHxUfj63oEO\nHf6KNm0G1Nv4SSI/Px/Z2dmXHKdOReP48Z+Qny8oLQ2B0egEo9GIgoICZGdnQ0QwZMgQjBo1ChMm\nTEBERATM5kLEH7oDTgkn0GOhO1r8+juyAgJw88GD+FtQEGZ07Fhv41Yo6gOl5JqJkCLC4uJidOrU\nCQcDA/HQRx/h0e7dHcJFe+vWrRg+fLith4Gk4mLMOnECcUVFeDMsDHf7+cFp/37gww+BX34B7rxT\nC+T+4x9BJycUFyfg3LmNOHt2B6KiIhETU4AjR8qQlGRFXh4RFOSKLl180b17F3TvPgBdu45Ehw6d\n0KZNG7i7u2P37t0YMGAAysrKAGgfZCcnp/JVl9FoRElJSflhMBiQmJiII0eOICUlpVyZ5eTkwMPD\nA/7+/pcdfn6+cHGJh8m0Et7eEQgOfgTt2w9DYGAgPD09y+9FEnk5vyD58Ay02Z6HbucfgdOrbyDb\nzQ1jY2Jwp48PFnTuXG/vdVOZ88bGUeUGGk52R1dyzSpO7scff0T/Hj1w2mpFqqsr7ldmoUalm4cH\n/terF37Py8MLKSl4+eRJvBQSgolffQXns2e1kjNz5wLp6ZAJE+A5bhw8Rz2MoKCZ6NPn0r6Ki4uR\nmJiIhIQEJCQkICoqGf/97zvIzMyEwWAoV1yenp5wcXG58CEGSVitVgCAq6sr3N3d4e7uDg8PD3h4\neKBLly7o2bMn7rzzTgQEBOiKTMuUUB0WyyKcObMMaWlvITf3TZhMg9CqVT8AVphzUpCbvho8dxYh\nO0Lh9+hGyJAhOFFSgrEHDmBKQIAqoaNQNFGa1UpuxIgRmN6pE74aPRq3jxiBaco0ZDNIYl1eHl49\neRInS0sxtX17PBwYiC7u7kBSkhZUvW4dEBmppegaO1YrGnfjjYBXPcTWGY3A2bNanbzsbO2x8nHh\nfEmJVsTOZLr42KqVNg4vL6Bt2/LnbOuFIt9CFLZKQ6FHBpxOpcM534JW7W+Gz4TXIH37AQB+z8vD\nQ0ePYn5oKJ6sxX6jQmErrrTKcXd3P1NaWlqPBRZth5ubW1ZJSUmVZr1mpeT8/Pzwy+DBmDhzJk4M\nG6Y82JoIsQYDFmdmYkV2Nto5O+NWHx/c6u2NW7y84GYyATt2AOvXA3v2aHt43t5a8dKAAMDfX3ts\n0wYwmzUFZDZrR1mZpsxKS4HcXCAnB8zJQW5pKVK8vJAdEoKzHTqgyMcHTp6eYOvWyPL2RpqXF3I9\nPGB0dYXJxQVtnJ3h4+KCDq6uuM7TE9d5eCDcYkErgwE4f/7ikZ+vPRqNgIsL4OamKebevQHdbBlj\nMGBOcjKOFRfjo27dcKuPj43ffYWieqoNlHYAmpWSe+aee5AyZAhumTgRz4SE2HpIjUZz2aewkjho\nMGBtbi7W5uUhtqgIA9u0QW9PT/Rq1QrBrq4IbNEC7XNy4JWTA8nOBrKytMNgAFxcYHF2RqanJ055\neGDdyZNo1a8fTrm54ZSHB065uCBVBBBBmIcHAlu2hK+LC1q1aAErCQIIaNkSnVxd4eviAlcnJ7QQ\nQYHZjFyTCWlGI46VlCCxuBhJJSVo5+yM6z080MPTExGenojw8ECEpyfaVUgDZ7ZakWY0YlN+PpZk\nZuJ4SQnmhoRgeocOl1Zer2eay5zXN44qN9D4e3KOQrPakwsF8HPPnvg2KMjWQ1FUgZMI+rdujf6t\nW+PF0FDkmkzYU1CAGIMBG/LykG40IrOsDGfKylBGwt/PD/TzQ2mPHjBarSi1WmEmEdCyJYJdXeHm\n7o4b+/dHuJsbRrm6ItjNDSFubvB2dq7S5f9qsJJIMxqRUFyM+KIi7C0owJLMTMQXF0MAuDs5wUUE\nOSYTAlq2xIDWrfFccDBu9faGSwMqN4VCUb80q5Vc+x9/xA9Dh2KoMhE1e4otFih5ClgAAAmTSURB\nVGSXlUFE4ObkBFf9saWTE5zqqMDqAkkUWCwosVhQpitcV6XUFM0YtZJrRkxq0UIpODvBo0ULhLq7\n23oYlyEi8HJ2hpdzs/rXUCgUV6BZ/UR9bcwYWw/BJmzdutXWQ7AJjio34LiyO6rcgGPL3pA0KyXn\nqfJSKhQKheIqaFZ7cs1lrAqFQtFUcPQ9uWa1klMoFAqF4mpocCUnIuNE5KiIJIrI81do84GIJInI\nIRHpU1UbR8ZRbfWOKjfguLI7qtyAY8vekDSokhOtRspHAMYCiABwv4h0r9TmVgBdSHYD8CSATxpy\nTM2RQ4cO2XoINsFR5QYcV3ZHlRtwbNkbkoZeyd0EIInkSZImAMsB3FmpzZ0AlgEAyT0AvETELvKp\n1Rf5+fm2HoJNcFS5AceV3VHlBhxb9oakoZVcRwCnK/ydpp+rrk16FW0UCoVCobhqlONJMyA1NdXW\nQ7AJjio34LiyO6rcgGPL3pA0aAiBiAwCsIDkOP3vOQBI8q0KbT4BsIXkD/rfRwEMI5lVqS8VP6BQ\nKBTXgCOHEDR07qJ9ALqKSAiATAD3Abi/UpufAcwA8IOuFPMrKzjAsSdJoVAoFNdGgyo5khYReQrA\nBmim0S9IJojIk9plLib5m4iMF5HjAIoAPNqQY1IoFAqF49BsMp4oFAqFQnG1NEnHExFxEpEDIvJz\nFdeGiUi+fv2AiLxoizHWNyKSKiKHReSgiOy9Qhu7DJqvSXY7nnMvEVkpIgkiEi8iA6toY69zXq3s\n9jjnIhKuf8YP6I/nReTpKtrZ5ZzbiqZaT2QmgCMA2lzh+naSdzTieBoDK4DhJM9VdbFi0Lz+hfAJ\ngEGNOcAGpFrZdexxzv8F4DeS94qIMwCPihftfM6rlV3HruacZCKAvkB5oow0AD9WbGPnc24TmtxK\nTkSCAIwH8Hl1zRppOI2JoPr5sOeg+Zpkv9DGbhCRNgCGklwCACTNJAsqNbPLOa+l7ICdzXklRgE4\nQfJ0pfN2Oee2pMkpOQCLAMwGUN1m4WB9Kf+riPRopHE1NASwUUT2icjjVVy356D5mmQH7G/OOwM4\nKyJLdPPVYhGpXEXWXue8NrID9jfnFZkM4PsqztvrnNuMJqXkRGQCgCySh6D9iqvql1w0gGCSfaDl\nxfypEYfYkPyBZD9oq9gZInKzrQfUiNQkuz3OuTOAfgD+rcteDGCObYfUaNRGdnuccwCAiLgAuAPA\nSluPxRFoUkoOwB8A3CEiydB+5YwQkWUVG5A0kCzWn68F4CIi3o0/1PqFZKb+mAPNTn9TpSbpADpV\n+DtIP9fsqUl2O53zNACnSe7X/14F7Yu/IvY65zXKbqdzfoFbAUTrn/fK2Ouc24wmpeRIvkAymGQY\ntMDxzSQfqtimon1aRG6CFgaR18hDrVdExENEWunPPQGMARBXqdnPAB7S21wxaL65URvZ7XHO9bk7\nLSLh+qmR0JytKmKXc14b2e1xzitwP6o2VQJ2Oue2pKl6V15CxeBxAPeIyHQAJgAl0GzbzZ0AAD/q\nqcucAXxLcoODBM3XKDvsc84B4GkA3+rmq2QAjzrInAM1yA47nXMR8YDmdPJEhXOOMuc2QQWDKxQK\nhcJuaVLmSoVCoVAo6hOl5BQKhUJhtyglp1AoFAq7RSk5hUKhUNgtSskpFAqFDRCRL0QkS0Ri6qGv\n4ZWSP5eIiN3k/awLyrtSoVAobICe2ccAYBnJG+qx33YAkgAEkSytr36bK2olp1DoiMgWEamcdaSu\nfXrp8V4X/h4mIr9cY1/zRSRNRBZc5eu+EZFcEZl4LfdVNAwkIwFcUnlDRMJEZK2ex3VbhYD5q+Ee\nAGuVgtNQSk6haFjaAfhrpXN1MZ+8R3LB1byA5J8B/K8O91Q0HosBPEVyALRE9f+5hj7uw5Uzqjgc\nSskpmjQiMktEntKfLxKRTfrzESLytf78YxHZKyKxIjJfPzdWRFZU6Kd8BSUiY0QkSkT2i8gPehaK\nyvcdXVUbEUkRkQUiEi1aoddw/byviGzQx/CZaIVgvQG8ASBM3yt5S+++tVwsGPp1hXu+KSJxeub9\nt2vx3swXka9EZLs+rokislBEYkTkNxFpUbH51bzvisZHT2s3BMBKETkI4FNoGYEgIn/SP1sxFY5Y\nEVlbqY9AAD0BrG/s8TdVlJJTNHV2ABiqP+8PwFP/8h4KYLt+/gWSNwHoDWC4iPQE8DuAm+RiCZfJ\nAL4TER8A/wAwkuSN0LLd/73iDfU2L1bTJptkf2gFLWfp5+YD2ESyF7SEwxeS7M6BVjesH8nn9XN9\noKW16gGgi4gM0RXiXSR76pn3X63l+xMGYDi0OmTfANio7++UAphQyz4UTQMnAOf0z0pf/egJACR/\nJNmL5A0Vjl4kb63UxyQAP5K0NPromyhKySmaOtEA+otIawBGALsADICm5Hbobe4TkWgAB6Epjh76\nP/k6ALfrSnECtOS3g/Q2O/Vfyw8BCK50z5raXKjmHA0gVH9+M4DlAEByPSrttVRiL8lMal5fh/Q+\nzgMoEZHPReRP0PI11oa1JK0AYqE5km3Qz8dWGJui6VJeUoxkIYAUEbmn/KLI1TqkVJf82SFpFgma\nFY4LSbOIpAJ4BMBOADEARgDoQvKoiIQCeBZAf5IFIrIEgJv+8h8APAVN4ewjWSQiAmADyQequW1N\nbYz6owVX/h+qzjxorPDcAsCZpEW0bPsjAdyrj3tkNX1c0hdJioipwnlrNWNTNAFE5Dtoq3AfETkF\nzRrwAIBPRORFaPO3HNpnvjb9hUDzqNzWMCNunqh/AkVzYAc0s+Cj0MrwLAJwoRZZG2hu2IWilWe5\nFcAW/do2AF8CeBz6KgvAbgAfiUgXkif0vbaOJJMq3K82bSqzE5pJ9G0RGQOgrX6+EEDrmgTU7+FJ\ncp2I7AJwvKbXVNXNNbxGYSNITrnCpcomyNr2dxKX1qJTQJkrFc2DHQACAewimQ3NlLcdAEjGQDP5\nJUDbk4q88CLdjLcGwDj9ESTPQlsVfi8ihwFEAbjuwktq26YK/glgtB7YezeAMwAK9RpoO3VHgbeq\neN2F/toAWKPfbzuAZ2rzxlyhL4VCoaOCwRWKekBEWgKw6GbHQQA+JlnfMXfzARhIvnsNr10C4BeS\nq+tzTApFU0eZKxWK+iEYwAoRcYK2T/Z4A9zDAOBxEWl9NbFyIvINgMEAVjbAmBSKJo1aySkUCoXC\nblF7cgqFQqGwW5SSUygUCoXdopScQqFQKOwWpeQUCoVCYbcoJadQKBQKu0UpOYVCoVDYLf8PXF7/\nwooZFMEAAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# 2.1 analyse spectra - plot reflectances\n", - "\n", - "# the usual settings for plotting in ipython notebooks\n", - "import matplotlib.pylab as plt\n", - "%matplotlib inline\n", - "\n", - "# let's have a look at our reflectances\n", - "df[\"reflectances\"].T.plot(kind=\"line\")\n", - "plt.ylabel(\"reflectance\")\n", - "plt.xlabel(\"wavelengths [m]\")\n", - "# put legend outside of plot\n", - "plt.gca().legend(loc='center left', bbox_to_anchor=(1, 0.5))\n", - "plt.grid()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# 2.1 analyse spectra - show distribution of blood volume fraction (vhb) and sao2\n", - "\n", - "# now we need some special pandas functions\n", - "import pandas as pd\n", - "\n", - "# we're interested in the distribution of vhb and sao2 in the first layer (layer0)\n", - "df_vhb_sao2 = df[\"layer0\"][[\"vhb\", \"sao2\"]]\n", - "# plot a scatter matrix showing the distribution of vhb and sao2.\n", - "# of course, with this little data this does not really make sense,\n", - "# however it is a useful tool for analysis if much data is available\n", - "pd.tools.plotting.scatter_matrix(df_vhb_sao2, alpha=0.75, figsize=(6, 6))\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\nYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# 3.1 manipulate spectra - apply sliding average\n", - "# in 3.1 and 3.2 we will adapt the generated spectra to an imaginary imaging system\n", - "# This system has filters with 20nm bandwith (taken care of in 3.1)\n", - "# and takes multispectral images in 10nm steps (taken care of in 3.2)\n", - "\n", - "# the module mc.dfmanipulations was written to provide some basic,\n", - "# often needed manipulations of the calculated spectra\n", - "# all dmfmanipulations are performed inplace, however, the df is also returned.\n", - "import mc.dfmanipulations as dfmani\n", - "\n", - "# first copy to not lose our original data\n", - "df2 = df.copy()\n", - "# We apply a sliding average to our data. This is usefull if \n", - "# we want to see e.g. how the reflectance was recorded by bands with a certain width\n", - "# a sliding average of 11 will take the five left and five right of the current reflectance\n", - "# and average. Because we take 2nm steps of reflectance in our simulation this means\n", - "# a 20nm window.\n", - "dfmani.fold_by_sliding_average(df2, 11)\n", - "\n", - "# lets again plot the reflectances\n", - "df2[\"reflectances\"].T.plot(kind=\"line\")\n", - "plt.ylabel(\"reflectance\")\n", - "plt.xlabel(\"wavelengths [m]\")\n", - "# put legend outside of plot\n", - "plt.gca().legend(loc='center left', bbox_to_anchor=(1, 0.5))\n", - "plt.grid()\n", - "# we can see that the bump at 560nm is \"smoother\"" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# 3.2 manipulate spectra - select certain wavelenghts\n", - "\n", - "# our imaginary imaging system takes images in 10nm steps from 470 to 660nm\n", - "imaging_system_wavelengths = np.arange(470, 670, 10) * 10**-9\n", - "\n", - "df3 = df2.copy()\n", - "dfmani.interpolate_wavelengths(df3, imaging_system_wavelengths)\n", - "\n", - "# let's look at the newly created reflectances\n", - "df3[\"reflectances\"].T.plot(kind=\"line\", marker='o')\n", - "plt.ylabel(\"reflectance\")\n", - "plt.xlabel(\"wavelengths [m]\")\n", - "# put legend outside of plot\n", - "plt.gca().legend(loc='center left', bbox_to_anchor=(1, 0.5))\n", - "plt.grid()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# that's it, folks. If you want, you can save the created dataframe easily to csv:\n", - "df.to_csv(\"results.csv\", index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/Modules/Biophotonics/python/iMC/tutorials/README.txt b/Modules/Biophotonics/python/iMC/tutorials/README.txt deleted file mode 100644 index f6fb2aa8d9..0000000000 --- a/Modules/Biophotonics/python/iMC/tutorials/README.txt +++ /dev/null @@ -1,6 +0,0 @@ -The tutorials are not fletched out, since I want to discuss the general direction first. -I propose IPhython notebooks, as e.g. Google does for the Caffe framework: -http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb - -I added a tutorial for the monte carlo spectra generation to show how this could look like. - diff --git a/Modules/Biophotonics/python/iMC_ipcai_jcars_save/iMC/tox.ini b/Modules/Biophotonics/python/iMC_ipcai_jcars_save/iMC/tox.ini deleted file mode 100644 index 51e0c9f594..0000000000 --- a/Modules/Biophotonics/python/iMC_ipcai_jcars_save/iMC/tox.ini +++ /dev/null @@ -1,9 +0,0 @@ -# content of: tox.ini , put in same dir as setup.py -[tox] -envlist = py27 -[testenv] -deps=discover # install pytest in the venvs -install_command=pip install -f http://www.simpleitk.org/SimpleITK/resources/software.html --trusted-host www.simpleitk.org {opts} {packages} -#changedir=tests -commands=discover - diff --git a/Modules/BiophotonicsHardware/CMakeLists.txt b/Modules/BiophotonicsHardware/CMakeLists.txt deleted file mode 100644 index 29137eaf7c..0000000000 --- a/Modules/BiophotonicsHardware/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -#MITK_CREATE_MODULE( -# INCLUDE_DIRS ${MITK_BIN_DIR} -# INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} -# DEPENDS MitkOpenCVVideoSupport -# EXPORT_DEFINE MITK_TOFHARDWARE_EXPORT -# ADDITIONAL_LIBS ${ADDITIONAL_LIBS} -#) - - - -#Set Subfolder according to moduls -set( biophotonicsHardware_module_dir - SpectroCam -) - -# add_subdirectories for each module -foreach(biophotonicsHardware_module_dir ${biophotonicsHardware_module_dir}) - add_subdirectory(${biophotonicsHardware_module_dir}) -endforeach() - - - - -#IF(BUILD_TESTING) -# add_subdirectory(Testing) -#ENDIF(BUILD_TESTING) diff --git a/Modules/BiophotonicsHardware/SpectroCam/CMakeLists.txt b/Modules/BiophotonicsHardware/SpectroCam/CMakeLists.txt deleted file mode 100644 index 98b72e720f..0000000000 --- a/Modules/BiophotonicsHardware/SpectroCam/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -#Begin SpectroCam hardware -OPTION(MITK_USE_BiophotonicsHardware_SpectroCam "Enable support for SpectroCam camera" OFF) - -IF(MITK_USE_BiophotonicsHardware_SpectroCam) - #Find SpectroCam SDK - FIND_LIBRARY(MITK_SpectroCam_LIB SpectroCam DOC "SpectroCam access library." HINTS "C:\\Program Files (x86)\\Ocean Thin Films\\SpectroCam SDK\\Stage\\64-Bit") - FIND_PATH(MITK_SpectroCam_INCLUDE_DIR ISpectroCam.h DOC "Include directory of SpectroCam camera." HINTS "C:\\Program Files (x86)\\Ocean Thin Films\\SpectroCam SDK\\Include") - - #Find Jai SDK - FIND_LIBRARY(MITK_JAI_LIB Jai_Factory DOC "SpectroCam access library." HINTS "C:\\Program Files\\JAI\\SDK\\library\\CPP\\lib\\Win64_x64" "C:\\Programme\\JAI\\SDK\\library\\CPP\\lib\\Win64_x64") - FIND_PATH(MITK_JAI_INCLUDE_DIR Jai_Factory.h DOC "Include directory of SpectroCam camera." HINTS "C:\\Program Files\\JAI\\SDK\\library\\CPP\\include" "C:\\Programme\\JAI\\SDK\\library\\CPP\\include") - - SET(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${MITK_SpectroCam_LIB} ${MITK_JAI_LIB}) - SET(INCLUDE_DIRS_INTERNAL ${INCLUDE_DIRS_INTERNAL} ${MITK_SpectroCam_INCLUDE_DIR} ${MITK_JAI_INCLUDE_DIR}) - - -MITK_CREATE_MODULE( - INCLUDE_DIRS ${MITK_BIN_DIR} - PUBLIC ${INCLUDE_DIRS_INTERNAL} - ADDITIONAL_LIBS ${ADDITIONAL_LIBS} - DEPENDS MitkCore MitkOpenCVVideoSupport - PACKAGE_DEPENDS OpenCV ITK|ITKIOImageBase -# PUBLIC ${ADDITIONAL_LIBS} -) - - -Message("SpectroCam Module generated") - -ENDIF(MITK_USE_BiophotonicsHardware_SpectroCam) -#End SpectroCam Hardware diff --git a/Modules/BiophotonicsHardware/SpectroCam/files.cmake b/Modules/BiophotonicsHardware/SpectroCam/files.cmake deleted file mode 100644 index 18d1e3c5bb..0000000000 --- a/Modules/BiophotonicsHardware/SpectroCam/files.cmake +++ /dev/null @@ -1,8 +0,0 @@ -IF(MITK_USE_BiophotonicsHardware_SpectroCam) -set(CPP_FILES -mitkSpectroCamController.cpp - -) - - -ENDIF(MITK_USE_BiophotonicsHardware_SpectroCam) \ No newline at end of file diff --git a/Modules/BiophotonicsHardware/SpectroCam/mitkSpectroCamController.cpp b/Modules/BiophotonicsHardware/SpectroCam/mitkSpectroCamController.cpp deleted file mode 100644 index 96360e0b5f..0000000000 --- a/Modules/BiophotonicsHardware/SpectroCam/mitkSpectroCamController.cpp +++ /dev/null @@ -1,745 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include "mitkSpectroCamController.h" -#include "mitkLogMacros.h" -#include -#include - - -#include -#include -#include -#include - -//OpenCv includes -#include -#include -#include -#include - -// itk includes -#include -#include - -//Spectrocam includes -#include -#include - - - -using namespace std; -using namespace cv; - - -namespace mitk { - - - typedef itk::VectorImage CompositeCameraImageType; - - /** - Here basically all of the implementation for the Spectrocam Controller is located. - This pimpl implementation is necessary because of the additional JAI and SpectroCam libraries, which should be totally hidden - to external modules/plugins. - + due to the c - nature of the Spectrocam callback mechanism we need some global variable sharing which is not nice and should - be hidden from users. - */ - class SpectroCamController_pimpl - { - public: - SpectroCamController_pimpl(); - ~SpectroCamController_pimpl(); - - bool Ini(); - int OpenCameraConnection(); - int CloseCameraConnection(); - bool isCameraRunning(); - - - void SetCurrentImageAsWhiteBalance(); - - mitk::Image::Pointer GetCurrentImage(); - - CompositeCameraImageType::Pointer m_CompositeItkImage_1; - CompositeCameraImageType::Pointer m_CompositeItkImage_2; - mitk::Image::Pointer m_CompositeMitkImage; - - cv::Mat m_CurrentStackSmall; - cv::Mat m_CurrentTransformedStack; - cv::Mat m_FlatfieldSmall; - cv::Mat m_LLSQSolutionSmall; - - const int m_FullWidth; - const int m_FullHeight; - - const int m_SmallWidth; - const int m_SmallHeight; - - bool m_ShowOxygenation; - - // for image double buffer swap - bool m_Image1Selected; - - std::string mode; - std::string model; - - private: - - void InitializeItkImage(mitk::CompositeCameraImageType::Pointer& compositeImage); - - bool m_IsCameraRunning; - - unsigned m_NumRecordedImages; - - ISpectroCam* spectroCam; //SpectroCam var - - STREAM_HANDLE m_hDS; // Handle to the data stream - - uint32_t m_iValidBuffers; // Number of buffers allocated to image acquisition - BUF_HANDLE m_pAquBufferID; // Handles for all the image buffers - HANDLE m_hEventKill; // Event used for speeding up the termination of image capture - - - //Vars for Ini from file - FastModeSettings fastSettings; - SequenceModeSettings seqSettings; - IndexModeSettings indexSettings; - - void SaveCameraStreamToDisk(); - }; - -} - - -// Implementation - -static mitk::SpectroCamController_pimpl* my_SpectroCamController; - -mitk::Image::Pointer mitk::SpectroCamController_pimpl::GetCurrentImage() -{ - mitk::CompositeCameraImageType::Pointer selectedImage; - - // TODO SW: semaphore here so it cannot interfere with callback readout of m_Image1Selected - if (this->m_Image1Selected) - { - this->m_Image1Selected = !this->m_Image1Selected; - selectedImage = this->m_CompositeItkImage_1; - } - else - { - this->m_Image1Selected = !this->m_Image1Selected; - selectedImage = this->m_CompositeItkImage_2; - } - - this->m_CompositeMitkImage = mitk::Image::New(); - MITK_INFO << "Image created"; - this->m_CompositeMitkImage->InitializeByItk(selectedImage); - MITK_INFO << "Initialized image by ITK"; - this->m_CompositeMitkImage->SetVolume(selectedImage->GetBufferPointer()); - MITK_INFO << "Copied data"; - - - return m_CompositeMitkImage; -} - -static cv::Mat createLLSQSolutionFromHMatrix() -{ - //Create the H-Matrix - // Ox DOx //Lookup values at http://omlc.org/spectra/hemoglobin/summary.html - float H[8][4]= {{50104 , 37020. , 405, 1.}, //Filter0 = 580nm +- 10 - {33209.2 , 16156.4 , 785., 1.}, //Filter1 = 470nm +- 10 - {319.6 , 3226.56 , 280., 1.}, //Filter2 = 660nm +- 10 - {32613.2 , 53788 , 495., 1.}, //Filter3 = 560nm +- 10 - {26629.2 , 14550 , 760., 1.}, //Filter4 = 480nm +- 12,5 - {20035.2 , 25773.6 , 665., 1.}, //Filter5 = 511nm +- 10 ->took 510nm - {3200 , 14677.2 , 380., 1.}, //Filter6 = 600nm +- 10 - {290 , 1794.28 , 220., 1.}}; //Filter7 = 700nm - - //Create the hMatrix - cv::Mat hMatrix = cv::Mat(8, 4, CV_32F, &H ); //cv::Mat(rows, cols, type, fill with) - - cv::Mat transH; - transpose(hMatrix,transH); - cv::Mat mulImage = transH * hMatrix; - cv::Mat invImage = mulImage.inv(); - cv::Mat HCompononentsForLLSQ = invImage * transH; - - return HCompononentsForLLSQ; -} - -mitk::SpectroCamController_pimpl::SpectroCamController_pimpl() - :m_hDS(nullptr), - m_NumRecordedImages(1), - m_IsCameraRunning(false), - m_SmallWidth(614), - m_SmallHeight(514), - m_FullWidth(2456), - m_FullHeight(2058), - m_Image1Selected(true), - m_ShowOxygenation(false) -{ - my_SpectroCamController = this; - m_CurrentStackSmall = cv::Mat(8, m_SmallWidth * m_SmallHeight, CV_32F, cv::Scalar(0)); - m_FlatfieldSmall = cv::Mat(8, m_SmallWidth * m_SmallHeight, CV_32F, cv::Scalar(1)); - m_CurrentTransformedStack = cv::Mat(8, m_SmallWidth * m_SmallHeight, CV_32F, cv::Scalar(1)); - - - m_LLSQSolutionSmall = createLLSQSolutionFromHMatrix(); - - -} - -void mitk::SpectroCamController_pimpl::SetCurrentImageAsWhiteBalance() -{ - // deep copy of current image stack - m_FlatfieldSmall = m_CurrentStackSmall.clone(); - - cv::namedWindow("Oxygenation Estimate", WINDOW_AUTOSIZE); - m_ShowOxygenation = true; -} - - - -mitk::SpectroCamController_pimpl::~SpectroCamController_pimpl() -{ -} - - - - - -void mitk::SpectroCamController_pimpl::SaveCameraStreamToDisk() -{ - /* - //=================================Save Images to HDD================================= - imagesRecoreded=0; - - //If Rec is pressed -> Save Images to Harddrive - if (rec == true) //On pressing the Rec-Button we wan to save x Stacks with 8 images each - { - //Save Image - saveImage(in); //std::cout<< "save no."<< imagesRecoreded<< std::endl; - //Icrement counter - imagesRecoreded++; - - if (imagesRecoreded >= (NumberOfStacksToBeRecorded*8) ) //If number of images is bigger or equal to the the Image Stack we want to tecord, untoggle the rec button and reset the counter! - { - imagesRecoreded=0; - rec=false; - ReCButtonControl_Pointer->EnableWindow(TRUE); - } - } - */ -} - - - -//Initialize Camera Controller -bool mitk::SpectroCamController_pimpl::Ini() -{ - //===============Get Ini from File=============== - //Get model from file std::string CChildWindowSampleDlg::getModelNameFromIni() - std::ifstream fin("C:\\ModeSettings.txt"); //Set File to read - std::ofstream fout("C:\\ModeSettingsCheck.txt"); //Set output - const int bufferSize = 1000; - char buffer[bufferSize]; - - if (fin.fail()) - { - MITK_INFO << "Failed opening file ModeSettings.txt!" << endl ; - } - - fin.getline(buffer, bufferSize); - fin.getline(buffer, bufferSize); - model = buffer; - - - //Get mode from file - //Skipping model, getting mode - for (int i = 0; i < 3; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - - mode = buffer; - - // [FastModeExposure] - for (int i = 0; i < 2; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - - fin >> fastSettings.exposure; - fout << fastSettings.exposure << endl;; - - // [FastModeGain] - for (int i = 0; i < 3; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - - fin >> fastSettings.gain; - fout << fastSettings.gain << endl; - - // [SequenceModeExposures] - for (int i = 0; i < 3; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - - for (int i = 0; i < NUMBER_FILTERS; ++i) - { - fin >> seqSettings.exposures[i]; - fout << seqSettings.exposures[i] << endl; - } - - // [SequenceModeGains] - for (int i = 0; i < 3; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - - for (int i = 0; i < NUMBER_FILTERS; ++i) - { - fin >> seqSettings.gains[i]; - fout << seqSettings.gains[i] << endl; - } - - // [IndexModeExposures] - for (int i = 0; i < 3; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - - for (int i = 0; i < NUMBER_FILTERS; ++i) - { - fin >> indexSettings.exposures[i]; - fout << indexSettings.exposures[i] << endl; - } - - // [IndexModeGains] - for (int i = 0; i < 3; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - for (int i = 0; i < NUMBER_FILTERS; ++i) - { - fin >> indexSettings.gains[i]; - fout << indexSettings.gains[i] << endl; - } - - // [IndexModeNumberFilterIterations] - for (int i = 0; i < 3; ++i) - { - fin.getline(buffer, bufferSize); - fout << buffer << endl; - } - - for (int i = 0; i < NUMBER_FILTERS; ++i) - { - fin >> indexSettings.numFilterIterations[i]; - fout << indexSettings.numFilterIterations[i] << endl; - } - - //After reading files -> close stream - fin.close(); - fout.close(); - - return 0; - -} - -void mitk::SpectroCamController_pimpl::InitializeItkImage(mitk::CompositeCameraImageType::Pointer& compositeImage) -{ - if (compositeImage.IsNull()) - { - - MITK_INFO << "initializing itk::Composite Image"; - mitk::CompositeCameraImageType::RegionType region; - mitk::CompositeCameraImageType::RegionType::SizeType size; - mitk::CompositeCameraImageType::RegionType::IndexType index; - mitk::CompositeCameraImageType::SpacingType spacing; - size.Fill( 1 ); - size[0] = this->m_FullWidth; - size[1] = this->m_FullHeight; - index.Fill(0); - spacing.Fill(1); - region.SetSize(size); - region.SetIndex(index); - - compositeImage = mitk::CompositeCameraImageType::New(); - compositeImage->SetRegions(region); - compositeImage->SetSpacing(spacing); - compositeImage->SetNumberOfComponentsPerPixel(NUMBER_FILTERS); - compositeImage->Allocate(); - } -} - -/** -* this c callback function is where the magic happens. -* it is called every time a new image has arrived from the SpectroCam. -*/ -static void DisplayCameraStream(SpectroCamImage image) -{ - - MITK_INFO << "image callback call"; - try - { - if (image.m_FilterNum < 0 || image.m_FilterNum >= NUMBER_FILTERS) - { - std::cout << "Filter number out of range.\n"<< std::endl; - } - else - { - // Allocate the buffer to hold converted the image. (We only want to do this once for performance reasons) - if (image.m_pAcqImage->pImageBuffer == nullptr) - { - if (J_Image_Malloc(image.m_pAcqImage, image.m_pAcqImage) != J_ST_SUCCESS) - { - return; - } - } - - - //============= Get data from spectrocam to opencv - - // TODO SW: probably we can get around this memcopy by simply setting data pointer? Not sure. - cv::Mat data = cv::Mat( image.m_pAcqImage->iSizeY, image.m_pAcqImage->iSizeX, CV_16U); - memcpy( data.datastart , image.m_pAcqImage->pImageBuffer , image.m_pAcqImage->iImageSize); //Copy Image from JAI-Format to OCV´s IplImage - - - //============= From opencv to mitk::Image (VectorImage) - - mitk::CompositeCameraImageType::Pointer selectedImage; - - if (my_SpectroCamController->m_Image1Selected) - { - selectedImage = my_SpectroCamController->m_CompositeItkImage_1; - } - else - { - selectedImage = my_SpectroCamController->m_CompositeItkImage_2; - } - - itk::ImageRegionIterator imageIterator(selectedImage, selectedImage->GetLargestPossibleRegion()); - - MatConstIterator_ it, end; - it = data.begin(); - end = data.end(); - - - while(!imageIterator.IsAtEnd()) - { - mitk::CompositeCameraImageType::PixelType compositePixel = imageIterator.Get(); - - compositePixel[image.m_FilterNum] = *it; - - ++it; - ++imageIterator; - } - - //both matrix and itk image shall reach end at the same time. - assert(it == end); - - - //============= Display image as opencv window == - - cv::Mat display; - cv::resize(data, display, cvSize(my_SpectroCamController->m_SmallWidth, my_SpectroCamController->m_SmallHeight) ); //do some resizeing for faster display - - display *= 16; // image is only 12 bit large, but datatype is 16 bit. Expand to full range for displaying by multiplying by 2^4. - - - - //Display Image - cv::imshow("Display window", display); //Display image - //MITK_INFO << "pixel 100,100" << display.at(0,100); - - - //============= TODO: live oxygenation estimation - - if (my_SpectroCamController->m_ShowOxygenation) - { - cv::Range slice[2]; - slice[0] = cv::Range( image.m_FilterNum, image.m_FilterNum+1 ); - slice[1] = cv::Range::all(); - - cv::Mat currentSlice = my_SpectroCamController->m_CurrentStackSmall(slice); - - cv::Mat currentImageF32; - display.convertTo(currentImageF32, CV_32F); - - currentImageF32 = currentImageF32.reshape(0, 1); - currentImageF32.copyTo(currentSlice); - - cv::Mat currentWorkingSlice = currentSlice.clone(); - - cv::Mat currentFlatfieldSlice = my_SpectroCamController->m_FlatfieldSmall(slice); - MITK_INFO << "flat current: " << currentFlatfieldSlice.at(0,100); - - - MITK_INFO << "raw measured pixel value: " << currentWorkingSlice.at(0,100); - - cv::divide(currentWorkingSlice, currentFlatfieldSlice, currentWorkingSlice); - MITK_INFO << "corrected by flatfield pixel: " << currentWorkingSlice.at(0,100); - - cv::log(currentWorkingSlice, currentWorkingSlice); - currentWorkingSlice = -0.43429 * currentWorkingSlice; - MITK_INFO << "to absorption: " << currentWorkingSlice.at(0,100); - - currentWorkingSlice.copyTo(my_SpectroCamController->m_CurrentTransformedStack(slice) ); - - //MITK_INFO << "slice 0: " << my_SpectroCamController->m_CurrentTransformedStack.at(0,100);; - - cv::Mat currentEstimate = my_SpectroCamController->m_LLSQSolutionSmall * my_SpectroCamController->m_CurrentTransformedStack; - cv::Range oxyHemo[2]; - oxyHemo[0] = cv::Range(0,1); - oxyHemo[1] = cv::Range::all(); - - cv::Range deOxyHemo[2]; - deOxyHemo[0] = cv::Range(1,2); - deOxyHemo[1] = cv::Range::all(); - - cv::Mat saO2 = currentEstimate(oxyHemo) / (currentEstimate(oxyHemo) + currentEstimate(deOxyHemo)); - - cv::Mat saO2Image = saO2.reshape(0, my_SpectroCamController->m_SmallHeight); - MITK_INFO << "saO2, 200 200: " << saO2Image.at(200,200); - - cv::threshold(saO2Image, saO2Image, 1., 1., cv::THRESH_TRUNC); - cv::threshold(saO2Image, saO2Image, 0., 0., cv::THRESH_TOZERO); - - saO2Image = saO2Image * 637.;// 255.; - - cv::Mat SaO2IntImage; - saO2Image.convertTo(SaO2IntImage, CV_8U); - // MITK_INFO << saO2Image.at(0,100); - - cv::Mat colorImage; - cv::applyColorMap(SaO2IntImage, colorImage, COLORMAP_JET); - cv::imshow("Oxygenation Estimate", colorImage); //Display image - } - - - cv::waitKey(1); - } - - }//try - - catch (std::exception &e) { - MITK_INFO << e.what(); - } -} - - - -int mitk::SpectroCamController_pimpl::OpenCameraConnection() -{ - //=====================OpenFactoryAndCamera===================== - //Create Factory and cam based on //BOOL OpenFactoryAndCamera(); // Open factory and search for cameras. Open first camera - spectroCam = CreateSpectroCam(&DisplayCameraStream, nullptr, 0); - MITK_INFO << "Camera " << model << " is running in: " << mode << "-mode" << endl; - - - - //=====================Open Streams===================== - J_STATUS_TYPE status = spectroCam->initialize(model.c_str(), (std::string("C:\\") + model + "\\").c_str()); - - if (status != J_ST_SUCCESS) - { - MITK_INFO << "Could not initialize camera!" << endl; - } - - // initialize VectorImage - this->InitializeItkImage(this->m_CompositeItkImage_1); - this->InitializeItkImage(this->m_CompositeItkImage_2); - - - - //=====================Open Streams===================== - if (mode == "Fast") - { - status = status | spectroCam->start(fastSettings); - } - - else if (mode == "Sequence") - { - status = status | spectroCam->start(seqSettings); - } - - else if (mode == "IndexFast") - { - indexSettings.filterModeSpeed = IndexModeSettings::INDEX_FAST; - status = status | spectroCam->start(indexSettings); - } - - else if (mode == "IndexSlow") - { - indexSettings.filterModeSpeed = IndexModeSettings::INDEX_SLOW; - status = status | spectroCam->start(indexSettings); - } - - else if (mode == "IndexTriggered") - { - indexSettings.filterModeSpeed = IndexModeSettings::INDEX_TRIGGERED; - status = status | spectroCam->start(indexSettings); - } - - else - { - status = status | spectroCam->start(fastSettings); - } - - MITK_INFO << "status flag: " << status; - - if (status == J_ST_SUCCESS) - { - m_IsCameraRunning = true; - } - - - cv::namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display. - - return status; -} - -bool mitk::SpectroCamController_pimpl::isCameraRunning() -{ - return m_IsCameraRunning; -} - - - -//Method to close down connections -int mitk::SpectroCamController_pimpl::CloseCameraConnection() -{ - - // On click -> Stop acquisition - J_STATUS_TYPE retval = 0; - CAM_HANDLE hCam = spectroCam->GetCameraHandle(); - - // Stop Acquision - if (hCam) - { - retval = retval | J_Camera_ExecuteCommand(hCam, (int8_t*) NODE_NAME_ACQSTOP); - } - - - MITK_INFO << "execute acqstop command"; - - - // Close stream (this frees all allocated buffers) - // Stop the image acquisition engine - J_DataStream_StopAcquisition(m_hDS, ACQ_STOP_FLAG_KILL); - - - MITK_INFO << "execute stop aqui"; - - // UnPrepare Buffers (this removed the buffers from the acquisition engine and frees buffers) - { - void *pPrivate; - void *pBuffer; - - // Flush Queues - J_DataStream_FlushQueue(m_hDS, ACQ_QUEUE_INPUT_TO_OUTPUT); - J_DataStream_FlushQueue(m_hDS, ACQ_QUEUE_OUTPUT_DISCARD); - - // Remove the frame buffer from the Acquisition engine. - J_DataStream_RevokeBuffer(m_hDS, m_pAquBufferID, &pBuffer , &pPrivate); - - m_pAquBufferID = 0; - - m_iValidBuffers = 0; - } - - MITK_INFO << "unprepared buffers"; - - - // Close Stream - if(m_hDS) - { - J_DataStream_Close(m_hDS); - m_hDS = nullptr; - } - - - MITK_INFO << "closed stream"; - - //===================Close Factory and destroy Cam===================== - //void CloseFactoryAndCamera(); // Close camera and factory to clean up - retval = retval | spectroCam->stop(); - - - MITK_INFO << "stopped camera"; - - //BOOL TerminateStreamThread(void); // Terminate the image acquisition thread - if (spectroCam) - { - //DestroySpectroCam(spectroCam); //Destroy SpectroCam-Objekt - } - - MITK_INFO << "destroyed spectrocam"; - - if (J_ST_SUCCESS == retval) - { - m_IsCameraRunning = false; - } - - return retval; -} - - -mitk::SpectroCamController::SpectroCamController() -{ - m_SpectroCamController_pimpl = new SpectroCamController_pimpl(); -} - -mitk::SpectroCamController::~SpectroCamController() -{ - delete m_SpectroCamController_pimpl; -} - -int mitk::SpectroCamController::OpenCameraConnection() -{ - return m_SpectroCamController_pimpl->OpenCameraConnection(); -} - -int mitk::SpectroCamController::CloseCameraConnection() -{ - return m_SpectroCamController_pimpl->CloseCameraConnection(); -} - -bool mitk::SpectroCamController::Ini() -{ - return m_SpectroCamController_pimpl->Ini(); -} - -bool mitk::SpectroCamController::isCameraRunning() -{ - return m_SpectroCamController_pimpl->isCameraRunning(); -} - - -mitk::Image::Pointer mitk::SpectroCamController::GetCurrentImage() -{ - return m_SpectroCamController_pimpl->GetCurrentImage(); -} - -void mitk::SpectroCamController::SetCurrentImageAsWhiteBalance() -{ - m_SpectroCamController_pimpl->SetCurrentImageAsWhiteBalance(); -} diff --git a/Modules/BiophotonicsHardware/SpectroCam/mitkSpectroCamController.h b/Modules/BiophotonicsHardware/SpectroCam/mitkSpectroCamController.h deleted file mode 100644 index 3a755e08d4..0000000000 --- a/Modules/BiophotonicsHardware/SpectroCam/mitkSpectroCamController.h +++ /dev/null @@ -1,55 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#ifndef mitkSpectroCamController_h -#define mitkSpectroCamController_h - -#include - - -#include -#include - -namespace mitk -{ - // forward declaration of the implementation for the SpectroCam - class SpectroCamController_pimpl; - - /** - * @brief Controller for Pixelteq SpectroCam - * - * - * @ingroup BiophotonicsHardware - */ - class MITKSPECTROCAM_EXPORT SpectroCamController - { - public: - SpectroCamController(); - ~SpectroCamController(); - - bool Ini(); - int OpenCameraConnection(); - int CloseCameraConnection(); - bool isCameraRunning(); - - /** - Returns the current image stack. Is of VectorType, unsigned short - */ - mitk::Image::Pointer GetCurrentImage(); - - void SetCurrentImageAsWhiteBalance(); - - private: - SpectroCamController_pimpl* m_SpectroCamController_pimpl; - }; - -} -#endif diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index e9a5d07801..c36c213269 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,85 +1,81 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(MITK_MODULES Core CommandLine CoreCmdApps AppUtil LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOM DICOMQI DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction SceneSerialization Gizmo GraphAlgorithms Multilabel Chart ImageStatistics ContourModel SurfaceInterpolation Segmentation QtWidgets QtWidgetsExt ImageStatisticsUI SegmentationUI MatchPointRegistration MatchPointRegistrationUI Classification OpenIGTLink IGTBase IGT CameraCalibration OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI - PhotoacousticsHardware - PhotoacousticsAlgorithms - PhotoacousticsLib US USUI DICOMUI Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI RT RTUI IOExt XNAT TubeGraph - BiophotonicsHardware BoundingShape RenderWindowManager RenderWindowManagerUI SemanticRelations SemanticRelationsUI CEST BasicImageProcessing ModelFit ModelFitUI Pharmacokinetics PharmacokineticsUI DICOMPM REST RESTService DICOMweb ) if(MITK_ENABLE_PIC_READER) list(APPEND MITK_MODULES IpPicSupportIO) endif() diff --git a/Modules/PhotoacousticsAlgorithms/CMakeLists.txt b/Modules/PhotoacousticsAlgorithms/CMakeLists.txt deleted file mode 100644 index e503966264..0000000000 --- a/Modules/PhotoacousticsAlgorithms/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -set(dependencies_list MitkCore MitkAlgorithmsExt MitkOpenCVVideoSupport) - -IF(MITK_USE_OpenCL) - add_definitions(-DPHOTOACOUSTICS_USE_GPU) - set(dependencies_list ${dependencies_list} MitkOpenCL) - message("Using OpenCL in PhotoacousticAlgorithms") -ENDIF(MITK_USE_OpenCL) - -MITK_CREATE_MODULE( - DEPENDS ${dependencies_list} - #AUTOLOAD_WITH MitkCore - INCLUDE_DIRS PUBLIC include - INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} - PACKAGE_DEPENDS ITK|ITKFFT+ITKImageCompose+ITKImageIntensity OpenCV tinyxml2|tinyxml2 -) - -if(TARGET ${MODULE_TARGET}) - target_link_libraries(${MODULE_TARGET} - PRIVATE tinyxml2::tinyxml2 - ) -endif() - -add_subdirectory(test) -add_subdirectory(MitkPABeamformingTool) -add_subdirectory(MitkPAResampleCropTool) diff --git a/Modules/PhotoacousticsAlgorithms/Documentation/doxygen/PAModule.dox b/Modules/PhotoacousticsAlgorithms/Documentation/doxygen/PAModule.dox deleted file mode 100644 index 9cbcf6d54a..0000000000 --- a/Modules/PhotoacousticsAlgorithms/Documentation/doxygen/PAModule.dox +++ /dev/null @@ -1,45 +0,0 @@ -/** -\page PAModulePage Photoacoustic Algorithms Module - -\tableofcontents - -\section PAModulePageOverview Overview - -The Photoacoustic Algorithms Module provides a set of filters for beamforming and post-processing of photoacoustic and ultrasound data. -The main features are: -
    -
  • Management of all filters through a single class PhotoacousticImage -
  • Beamforming of ultrasound and photoacoustic image data. -
      -
    • Beamforming using the DAS and DMAS Algorithms. -
    • Optional real-time beamforming capabilities by the usage of openCL GPU computing -
    -
  • Post/Pre-Processing of any kind of images. -
      -
    • Crop Filter for removing artefacts in upper and lower edge of the image. -
    • Multiple B-Mode Filter implementations with resampling and logarithmic filter. -
    • Bandpass Filter -
    -
- -To use the GPU capabilities of this module, openCL needs to be activated in CMAKE. The custom build option "camiPhotoacousticsWorkstation" activates all needed CMAKE options, as well as openCL. -To build the project using openCL, the openCL libraries provided by your graphic card vendor need to be installed. The GPU capabilies of this module have been only tested using nvidia hardware, but, as openCL has been also implemented by AMD, this should work on either one. (Those are included in the CUDA package for nvidia graphic card owners) - -The \link org_mitk_gui_qt_photoacoustics_imageprocessing Photoacoustic Imageprocessing plugin \endlink provides a GUI to access all of thePhotoacoustic Algorithms Module's filters. - -\section PAModuleClasses The Photoacoustic Algorithms Module's Classes - -
    -
  • mitk::PhotoacousticImage: The class where all filters are managed. -
  • mitk::BeamformingSettings: The class used by many filters for storing the configuration to be used when applying them. -
  • Five filters are currently implemented in the Photoacoustic Algorithms module: -
      -
    • mitk::PhotoacousticBModeFilter: A class for the B-Mode filter on GPU and CPU. -
    • Resampling Filter: A resampling filter for post-processing. -
    • mitk::BeamformingFilter: A filter with a switch for GPU/CPU computation, to compute the beamformed image out of raw ultrasound/photoacoustic data. -
    • Crop Filter: A filter for cropping artifacts on the upper and lower edges of the image. -
    • Bandpass Filter: A Filter to filter image data in the fourier domain, using a tukey window to cut off low or high frequency parts of the image. -
    -
  • -
-*/ \ No newline at end of file diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/LICENSE b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/LICENSE deleted file mode 100644 index d645695673..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/README.rst b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/README.rst deleted file mode 100644 index a008a380db..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/README.rst +++ /dev/null @@ -1,11 +0,0 @@ -================== -ITKUltrasound -================== - -Purpose -======= - -This module contains filters for use with the `Insight Toolkit`_ (ITK) that -may be particularly useful for the reconstruction and analysis of ultrasound. - -.. _Insight Toolkit: http://www.itk.org/ diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkAnalyticSignalImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkAnalyticSignalImageFilter.h deleted file mode 100644 index a766265540..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkAnalyticSignalImageFilter.h +++ /dev/null @@ -1,139 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkAnalyticSignalImageFilter_h -#define itkAnalyticSignalImageFilter_h - -#include - -#include "itkFFT1DComplexToComplexImageFilter.h" -#include "itkFFT1DRealToComplexConjugateImageFilter.h" -#include "itkImageRegionSplitterDirection.h" - -namespace itk -{ -/** \class AnalyticSignalImageFilter - * \brief Generates the analytic signal from one direction of an image. - * - * This filter generates the complex valued analytic signal along one direction - * of an image. This input is a real valued image, and the output is a complex - * image. - * - * The analytic signal is given by - * - * f_a(x) = f(x) - i f_H(x) - * - * Where i is the square root of one and f_H(x) is the Hibert transform of f(x). - * - * Since the Hilbert transform in the Fourier domain is - * - * F_H(k) = F(k) i sign(k), - * - * f_a(x) is calculated by - * - * f_a(x) = F^{-1}( F(k) 2 U(k) ) - * - * where U(k) is the unit step function. - * - * \ingroup FourierTransform - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage > -class AnalyticSignalImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension); - - typedef AnalyticSignalImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkTypeMacro( AnalyticSignalImageFilter, ImageToImageFilter ); - itkNewMacro( Self ); - - /** Get the direction in which the filter is to be applied. */ - virtual unsigned int GetDirection() const - { - return this->m_FFTRealToComplexFilter->GetDirection(); - } - - /** Set the direction in which the filter is to be applied. */ - virtual void SetDirection( const unsigned int direction ) - { - if( this->m_FFTRealToComplexFilter->GetDirection() != direction ) - { - this->m_FFTRealToComplexFilter->SetDirection( direction ); - this->m_FFTComplexToComplexFilter->SetDirection( direction ); - this->Modified(); - } - } - -protected: - AnalyticSignalImageFilter(); - ~AnalyticSignalImageFilter() override {} - - void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - // These behave like their analogs in FFT1DRealToComplexConjugateImageFilter. - void GenerateInputRequestedRegion() ITK_OVERRIDE; - void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - void BeforeThreadedGenerateData() ITK_OVERRIDE; - void ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType threadId ) ITK_OVERRIDE; - void AfterThreadedGenerateData() ITK_OVERRIDE; - - typedef FFT1DRealToComplexConjugateImageFilter< InputImageType, OutputImageType > FFTRealToComplexType; - typedef FFT1DComplexToComplexImageFilter< OutputImageType, OutputImageType > FFTComplexToComplexType; - - typename FFTRealToComplexType::Pointer m_FFTRealToComplexFilter; - typename FFTComplexToComplexType::Pointer m_FFTComplexToComplexFilter; - - /** Override to return a splitter that does not split along the direction we - * are performing the transform. */ - const ImageRegionSplitterBase* GetImageRegionSplitter() const ITK_OVERRIDE; - -private: - AnalyticSignalImageFilter( const Self& ); // purposely not implemented - void operator=( const Self& ); // purposely not implemented - - ImageRegionSplitterDirection::Pointer m_ImageRegionSplitter; -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkAnalyticSignalImageFilter.hxx" -#endif - -#endif // itkAnalyticSignalImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkAnalyticSignalImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkAnalyticSignalImageFilter.hxx deleted file mode 100644 index 6f9bed0161..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkAnalyticSignalImageFilter.hxx +++ /dev/null @@ -1,267 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkAnalyticSignalImageFilter_hxx -#define itkAnalyticSignalImageFilter_hxx - -#include "itkAnalyticSignalImageFilter.h" - -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.h" -#include "itkVnlFFT1DComplexToComplexImageFilter.h" - -#if defined(ITK_USE_FFTWD) || defined(ITK_USE_FFTWF) -#include "itkFFTW1DRealToComplexConjugateImageFilter.h" -#include "itkFFTW1DComplexToComplexImageFilter.h" -#endif - -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkMetaDataObject.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::AnalyticSignalImageFilter() -{ - m_FFTRealToComplexFilter = FFTRealToComplexType::New(); - m_FFTComplexToComplexFilter = FFTComplexToComplexType::New(); - - m_FFTComplexToComplexFilter->SetTransformDirection( FFTComplexToComplexType::INVERSE ); - - this->SetDirection( 0 ); - - this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New(); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - typename InputImageType::Pointer inputPtr = - const_cast (this->GetInput()); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->GetDirection(); - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast< OutputImageType* >( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - const unsigned int direction = this->GetDirection (); - enlargedSize[direction] = outputLargeSize[direction]; - enlargedIndex[direction] = outputLargeIndex[direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - const unsigned int direction = this->GetDirection(); - os << indent << "Direction: " << direction << std::endl; - - os << indent << "FFTRealToComplexFilter: " << std::endl; - m_FFTRealToComplexFilter->Print( os, indent ); - os << indent << "FFTComplexToComplexFilter: " << std::endl; - m_FFTComplexToComplexFilter->Print( os, indent ); -} - - -template< typename TInputImage, typename TOutputImage > -const ImageRegionSplitterBase * -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::GetImageRegionSplitter() const -{ - return this->m_ImageRegionSplitter.GetPointer(); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - this->m_ImageRegionSplitter->SetDirection( this->GetDirection() ); - - m_FFTRealToComplexFilter->SetInput( this->GetInput() ); - m_FFTRealToComplexFilter->GetOutput()->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() ); - m_FFTRealToComplexFilter->GetOutput()->SetLargestPossibleRegion( this->GetOutput()->GetLargestPossibleRegion() ); - m_FFTRealToComplexFilter->SetNumberOfThreads( this->GetNumberOfThreads() ); - m_FFTRealToComplexFilter->Update (); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType itkNotUsed( threadId ) ) -{ - // get pointers to the input and output - const typename FFTRealToComplexType::OutputImageType * inputPtr = m_FFTRealToComplexFilter->GetOutput(); - OutputImageType * outputPtr = this->GetOutput(); - - const typename FFTRealToComplexType::OutputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - const unsigned int direction = this->GetDirection (); - const unsigned int size = inputSize[direction]; - unsigned int dub_size; - bool even; - if( size % 2 == 0 ) - { - even = true; - dub_size = size / 2 - 1; - } - else - { - even = false; - dub_size = (size + 1) / 2 - 1; - } - - typedef ImageLinearConstIteratorWithIndex< typename FFTRealToComplexType::OutputImageType > InputIteratorType; - typedef ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegionForThread ); - OutputIteratorType outputIt( outputPtr, outputRegionForThread ); - inputIt.SetDirection( direction ); - outputIt.SetDirection( direction ); - - unsigned int i; - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - inputIt.GoToBeginOfLine(); - outputIt.GoToBeginOfLine(); - - // DC - outputIt.Set( inputIt.Get() ); - ++inputIt; - ++outputIt; - - for( i = 0; i < dub_size; i++ ) - { - outputIt.Set( inputIt.Get() * static_cast< typename TInputImage::PixelType >( 2 ) ); - ++outputIt; - ++inputIt; - } - if( even ) - { - outputIt.Set( inputIt.Get() ); - ++inputIt; - ++outputIt; - } - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( static_cast< typename TInputImage::PixelType >( 0 ) ); - ++outputIt; - } - } -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::AfterThreadedGenerateData() -{ - // Trippy, eh? - m_FFTComplexToComplexFilter->SetInput( this->GetOutput() ); - m_FFTComplexToComplexFilter->GetOutput()->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() ); - m_FFTComplexToComplexFilter->GetOutput()->SetLargestPossibleRegion( this->GetOutput()->GetLargestPossibleRegion() ); - m_FFTComplexToComplexFilter->SetNumberOfThreads( this->GetNumberOfThreads() ); - m_FFTComplexToComplexFilter->Update (); - this->GraftOutput( m_FFTComplexToComplexFilter->GetOutput() ); -} - -} // end namespace itk - -#endif // itkAnalyticSignalImageFilter_hxx diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkBModeImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkBModeImageFilter.h deleted file mode 100644 index baeb5c5e67..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkBModeImageFilter.h +++ /dev/null @@ -1,152 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkBModeImageFilter_h -#define itkBModeImageFilter_h - -#include "itkAddImageFilter.h" -#include "itkComplexToModulusImageFilter.h" -#include "itkConstantPadImageFilter.h" -#include "itkRegionFromReferenceImageFilter.h" -#include "itkImageToImageFilter.h" -#include "itkImage.h" -#include "itkLog10ImageFilter.h" - -#include "itkAnalyticSignalImageFilter.h" - -namespace itk -{ - -/** - * \class BModeImageFilter - * - * \brief Create an ultrasound B-Mode (Brightness-Mode) image from raw - * "RF" data. The RF's envelope is calculated from the analytic signal and - * logarithmic intensity transform is applied. - * - * Use SetDirection() to define the axis of propagation. - * - * \ingroup Ultrasound - * - * \sa AnalyticSignalImageFilter - * - */ -template < typename TInputImage, typename TOutputImage=TInputImage, typename TComplexImage=Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > -class BModeImageFilter : - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef BModeImageFilter Self; - typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - /** The type of input image. */ - typedef TInputImage InputImageType; - - /** Dimension of the input and output images. */ - itkStaticConstMacro (ImageDimension, unsigned int, - TInputImage::ImageDimension); - - /** Typedef support for the input image scalar value type. */ - typedef typename InputImageType::PixelType InputPixelType; - - /** The type of output image. */ - typedef TOutputImage OutputImageType; - - /** Typedef support for the output image scalar value type. */ - typedef typename OutputImageType::PixelType OutputPixelType; - - /** Typedef of the image used for internal computations that has - * std::complex pixels. */ - typedef TComplexImage ComplexImageType; - - /** Other convenient typedefs */ - typedef typename InputImageType::RegionType InputRegionType; - typedef typename InputImageType::SizeType InputSizeType; - typedef typename InputImageType::IndexType InputIndexType; - - /** Run-time type information (and related methods) */ - itkTypeMacro( BModeImageFilter, ImageToImageFilter ); - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Set the direction in which the envelope is to be calculated. */ - virtual void SetDirection( unsigned int direction ) - { - this->m_AnalyticFilter->SetDirection( direction ); - this->Modified(); - } - - /** Get the direction in which the envelope is to be calculated. */ - virtual unsigned int GetDirection() const - { - return m_AnalyticFilter->GetDirection(); - } - -protected: - BModeImageFilter(); - ~BModeImageFilter() override {} - - void PrintSelf( std::ostream& os, Indent indent ) const ITK_OVERRIDE; - - void GenerateData() ITK_OVERRIDE; - - // These behave like their analogs in FFT1DRealToComplexConjugateImageFilter. - void GenerateInputRequestedRegion() ITK_OVERRIDE; - void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - /** Component filters. */ - typedef AnalyticSignalImageFilter< InputImageType, ComplexImageType > AnalyticType; - typedef ComplexToModulusImageFilter< typename AnalyticType::OutputImageType, OutputImageType > ComplexToModulusType; - typedef ConstantPadImageFilter< InputImageType, InputImageType > PadType; - typedef AddImageFilter< InputImageType, InputImageType > AddConstantType; - typedef Log10ImageFilter< InputImageType, OutputImageType > LogType; - typedef RegionFromReferenceImageFilter< OutputImageType, OutputImageType > ROIType; - -private: - BModeImageFilter( const Self& ); // purposely not implemented - void operator=( const Self& ); // purposely not implemented - - typename AnalyticType::Pointer m_AnalyticFilter; - typename ComplexToModulusType::Pointer m_ComplexToModulusFilter; - typename PadType::Pointer m_PadFilter; - typename AddConstantType::Pointer m_AddConstantFilter; - typename LogType::Pointer m_LogFilter; - typename ROIType::Pointer m_ROIFilter; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkBModeImageFilter.hxx" -#endif - -#endif // itkBModeImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkBModeImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkBModeImageFilter.hxx deleted file mode 100644 index f45b42fe37..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkBModeImageFilter.hxx +++ /dev/null @@ -1,208 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkBModeImageFilter_hxx -#define itkBModeImageFilter_hxx - -#include "itkBModeImageFilter.h" - -#include "itkMetaDataDictionary.h" - -#include -#include -#include - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::BModeImageFilter() -{ - m_AnalyticFilter = AnalyticType::New(); - m_ComplexToModulusFilter = ComplexToModulusType::New(); - m_PadFilter = PadType::New(); - m_AddConstantFilter = AddConstantType::New(); - m_LogFilter = LogType::New(); - m_ROIFilter = ROIType::New(); - - // Avoid taking the log of zero. Assuming that the original input is coming - // from a digitizer that outputs integer types, so 1 is small. - m_AddConstantFilter->SetConstant2( 1 ); - m_PadFilter->SetConstant( 0. ); - - m_ComplexToModulusFilter->SetInput( m_AnalyticFilter->GetOutput() ); - m_ROIFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); - m_LogFilter->SetInput( m_AddConstantFilter->GetOutput() ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - InputImageType * inputPtr = const_cast (this->GetInput()); - OutputImageType * outputPtr = this->GetOutput(); - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->GetDirection(); - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast< OutputImageType* >( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - const unsigned int direction = this->GetDirection (); - enlargedSize[direction] = outputLargeSize[direction]; - enlargedIndex[direction] = outputLargeIndex[direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::GenerateData() -{ - this->AllocateOutputs(); - - const InputImageType * inputPtr = this->GetInput(); - OutputImageType * outputPtr = this->GetOutput(); - - const unsigned int direction = m_AnalyticFilter->GetDirection(); - typename InputImageType::SizeType size = inputPtr->GetLargestPossibleRegion().GetSize(); - - // Zero padding. FFT direction should be factorable by 2 for all FFT - // implementations to work. - unsigned int n = size[direction]; - while( n % 2 == 0 ) - { - n /= 2; - } - bool doPadding; - if( n == 1 ) - { - doPadding = false; - } - else - { - doPadding = true; - } - if( doPadding ) - { - n = size[direction]; - unsigned int newSizeDirection = 1; - while( newSizeDirection < n ) - { - newSizeDirection *= 2; - } - typename InputImageType::SizeType padSize; - padSize.Fill( 0 ); - padSize[direction] = newSizeDirection - size[direction]; - size[direction] = newSizeDirection; - m_PadFilter->SetPadUpperBound( padSize ); - m_PadFilter->SetInput( inputPtr ); - m_AnalyticFilter->SetInput( m_PadFilter->GetOutput() ); - m_ROIFilter->SetReferenceImage( inputPtr ); - m_ROIFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); - m_AddConstantFilter->SetInput( m_ROIFilter->GetOutput() ); - } - else // padding is not required - { - m_AnalyticFilter->SetInput( inputPtr ); - m_AddConstantFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); - } - m_LogFilter->GraftOutput( outputPtr ); - m_LogFilter->Update(); - this->GraftOutput( m_LogFilter->GetOutput() ); -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkCurvilinearArraySpecialCoordinatesImage.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkCurvilinearArraySpecialCoordinatesImage.h deleted file mode 100644 index 982f0397d5..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkCurvilinearArraySpecialCoordinatesImage.h +++ /dev/null @@ -1,347 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkCurvilinearArraySpecialCoordinatesImage_h -#define itkCurvilinearArraySpecialCoordinatesImage_h - -#include "itkSpecialCoordinatesImage.h" -#include "itkPoint.h" -#include "vnl/vnl_math.h" -#include "itkNeighborhoodAccessorFunctor.h" - -namespace itk -{ -/** \class CurvilinearArraySpecialCoordinatesImage - * - * \brief Templated 2D nonrectilinear-coordinate image class for - * curvilinear/phased-array "range" images. - * - * \verbatim - * - * +---------------------> x-axis - * |\ - * / | \ - * |-~\ - * / | \ - * | \ - * / | \ - * | lateral - * | - * v y-axis - * - * \endverbatim - * - * The equations form performing the conversion from Cartesian coordinates to - * curvilinear/phased array coordinates are as follows: - * - * lateral = arctan(x/y) - * radius = std::sqrt(x^2 + y^2) - * - * The reversed transforms are: - * - * x = radius * std::sin(lateral) - * y = radius * std::cos(lateral) - * - * CurvilinearArraySpecialCoordinatesImages are templated over a pixel - * type and follow the SpecialCoordinatesImage interface. The data in - * an image is arranged in a 1D array as - * [lateral-index][radius-index] with radius-index - * varying most rapidly. The Index type reverses the order so that - * Index[0] = radius-index, Index[1] = lateral-index. - * - * Lateral is discretized into m_LateralAngularSeparation intervals - * per angular voxel, the most negative lateral interval containing - * data is then mapped to lateral-index=0, and the largest lateral - * interval containing data is then mapped to lateral-index=( number - * of samples along lateral axis - 1 ). Elevation is discretized in - * the same manner. This way, the mapping to Cartesian space is - * symmetric about the x axis such that the line defined by - * lateral/2 = x-axis. Radius is discretized into - * m_RadiusSampleSize units per angular voxel. The smallest range - * interval containing data is then mapped to radius-index=0, such - * that radius = m_FirstSampleDistance + (radius-index * - * m_RadiusSampleSize). - * - * \sa SpecialCoordinatesImage - * \sa PhasedArray3DSpecialCoordinatesImage - * - * \ingroup Ultrasound - * - * \ingroup ImageObjects - * \ingroup ITKCommon - */ -template< typename TPixel, unsigned int VDimension > -class CurvilinearArraySpecialCoordinatesImage: - public SpecialCoordinatesImage< TPixel, VDimension > -{ -public: - /** Standard class typedefs */ - typedef CurvilinearArraySpecialCoordinatesImage Self; - typedef SpecialCoordinatesImage< TPixel, VDimension > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - typedef WeakPointer< const Self > ConstWeakPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(CurvilinearArraySpecialCoordinatesImage, SpecialCoordinatesImage); - - /** Pixel typedef support. Used to declare pixel type in filters - * or other operations. */ - typedef TPixel PixelType; - - /** Typedef alias for PixelType */ - typedef TPixel ValueType; - - /** Internal Pixel representation. Used to maintain a uniform API - * with Image Adaptors and allow to keep a particular internal - * representation of data while showing a different external - * representation. */ - typedef TPixel InternalPixelType; - - typedef typename Superclass::IOPixelType IOPixelType; - - /** Accessor type that convert data between internal and external - * representations. */ - typedef DefaultPixelAccessor< PixelType > AccessorType; - - /** Accessor functor to choose between accessors: DefaultPixelAccessor for - * the Image, and DefaultVectorPixelAccessor for the vector image. The - * functor provides a generic API between the two accessors. */ - typedef DefaultPixelAccessorFunctor< Self > AccessorFunctorType; - - /** Typedef for the functor used to access a neighborhood of pixel - * pointers. */ - typedef NeighborhoodAccessorFunctor< Self > NeighborhoodAccessorFunctorType; - - /** Dimension of the image. This constant is used by functions that are - * templated over image type (as opposed to being templated over pixel type - * and dimension) when they need compile time access to the dimension of - * the image. */ - itkStaticConstMacro(ImageDimension, unsigned int, VDimension); - - /** Index typedef support. An index is used to access pixel values. */ - typedef typename Superclass::IndexType IndexType; - typedef typename Superclass::IndexValueType IndexValueType; - - /** Offset typedef support. An offset is used to access pixel values. */ - typedef typename Superclass::OffsetType OffsetType; - - /** Size typedef support. A size is used to define region bounds. */ - typedef typename Superclass::SizeType SizeType; - typedef typename Superclass::SizeValueType SizeValueType; - - /** Container used to store pixels in the image. */ - typedef ImportImageContainer< SizeValueType, PixelType > PixelContainer; - - /** Region typedef support. A region is used to specify a subset of - * an image. - */ - typedef typename Superclass::RegionType RegionType; - - /** Spacing typedef support. Spacing holds the "fake" size of a - * pixel, making each pixel look like a 1 unit hyper-cube to filters - * that were designed for normal images and that therefore use - * m_Spacing. The spacing is the geometric distance between image - * samples. - */ - typedef typename Superclass::SpacingType SpacingType; - - /** Origin typedef support. The origin is the "fake" geometric - * coordinates of the index (0,0). Also for use w/ filters designed - * for normal images. - */ - typedef typename Superclass::PointType PointType; - - /** A pointer to the pixel container. */ - typedef typename PixelContainer::Pointer PixelContainerPointer; - typedef typename PixelContainer::ConstPointer PixelContainerConstPointer; - - /** Graft the data and information from one image to another. This - * is a convenience method to setup a second image with all the meta - * information of another image and use the same pixel - * container. Note that this method is different than just using two - * SmartPointers to the same image since separate DataObjects are - * still maintained. This method is similar to - * ImageSource::GraftOutput(). The implementation in ImageBase - * simply calls CopyInformation() and copies the region ivars. - * The implementation here refers to the superclass' implementation - * and then copies over the pixel container. */ - virtual void Graft(const DataObject *data) ITK_OVERRIDE; - - /** \brief Get the continuous index from a physical point - * - * Returns true if the resulting index is within the image, false otherwise. - * \sa Transform */ - template< typename TCoordRep > - bool TransformPhysicalPointToContinuousIndex( - const Point< TCoordRep, VDimension > & point, - ContinuousIndex< TCoordRep, VDimension > & index) const - { - const RegionType & region = this->GetLargestPossibleRegion(); - const double maxLateral = region.GetSize(1) - 1; - - // Convert Cartesian coordinates into angular coordinates - const TCoordRep lateral = std::atan(point[0] / point[1]); - const TCoordRep radius = std::sqrt(point[0] * point[0] + point[1] * point[1] ); - - // Convert the "proper" angular coordinates into index format - index[0] = static_cast< TCoordRep >( ( ( radius - m_FirstSampleDistance ) - / m_RadiusSampleSize ) ); - index[1] = static_cast< TCoordRep >( ( lateral / m_LateralAngularSeparation ) - + ( maxLateral / 2.0 ) ); - - // Now, check to see if the index is within allowed bounds - const bool isInside = region.IsInside(index); - - return isInside; - } - - /** Get the index (discrete) from a physical point. - * Floating point index results are truncated to integers. - * Returns true if the resulting index is within the image, false otherwise - * \sa Transform */ - template< typename TCoordRep > - bool TransformPhysicalPointToIndex( - const Point< TCoordRep, VDimension > & point, - IndexType & index) const - { - const RegionType & region = this->GetLargestPossibleRegion(); - const double maxLateral = region.GetSize(1) - 1; - - // Convert Cartesian coordinates into angular coordinates - const TCoordRep lateral = std::atan(point[0] / point[1]); - const TCoordRep radius = std::sqrt(point[0] * point[0] + point[1] * point[1] ); - - // Convert the "proper" angular coordinates into index format - index[0] = static_cast< IndexValueType >( ( ( radius - m_FirstSampleDistance ) - / m_RadiusSampleSize ) ); - index[1] = static_cast< IndexValueType >( ( lateral / m_LateralAngularSeparation ) - + ( maxLateral / 2.0 ) ); - - // Now, check to see if the index is within allowed bounds - const bool isInside = region.IsInside(index); - - return isInside; - } - - /** Get a physical point (in the space which - * the origin and spacing information comes from) - * from a continuous index (in the index space) - * \sa Transform */ - template< typename TCoordRep > - void TransformContinuousIndexToPhysicalPoint( - const ContinuousIndex< TCoordRep, VDimension > & index, - Point< TCoordRep, VDimension > & point) const - { - const RegionType & region = this->GetLargestPossibleRegion(); - const double maxLateral = region.GetSize(1) - 1; - - // Convert the index into proper angular coordinates - const TCoordRep radius = ( index[0] * m_RadiusSampleSize ) + m_FirstSampleDistance; - const TCoordRep lateral = ( index[1] - ( maxLateral / 2.0 ) ) * m_LateralAngularSeparation; - - // Convert the angular coordinates into Cartesian coordinates - point[0] = static_cast< TCoordRep >( radius * std::sin(lateral) ); - point[1] = static_cast< TCoordRep >( radius * std::cos(lateral) ); - } - - /** Get a physical point (in the space which - * the origin and spacing information comes from) - * from a discrete index (in the index space) - * - * \sa Transform */ - template< typename TCoordRep > - void TransformIndexToPhysicalPoint( - const IndexType & index, - Point< TCoordRep, VDimension > & point) const - { - const RegionType & region = this->GetLargestPossibleRegion(); - const double maxLateral = region.GetSize(1) - 1; - - // Convert the index into proper angular coordinates - const TCoordRep radius = ( index[0] * m_RadiusSampleSize ) + m_FirstSampleDistance; - const TCoordRep lateral = ( index[1] - ( maxLateral / 2.0 ) ) * m_LateralAngularSeparation; - - // Convert the angular coordinates into Cartesian coordinates - point[0] = static_cast< TCoordRep >( radius * std::sin(lateral) ); - point[1] = static_cast< TCoordRep >( radius * std::cos(lateral) ); - } - - /** Set/Get the number of radians between each lateral unit. */ - itkSetMacro(LateralAngularSeparation, double); - itkGetConstMacro(LateralAngularSeparation, double); - - /** Set/Get the number of cartesian units between each unit along the R . */ - itkSetMacro(RadiusSampleSize, double); - itkGetConstMacro(RadiusSampleSize, double); - - /** Set the distance to add to the radius. */ - itkSetMacro(FirstSampleDistance, double); - itkGetConstMacro(FirstSampleDistance, double); - - template< typename TCoordRep > - void TransformLocalVectorToPhysicalVector( - FixedArray< TCoordRep, VDimension > & ) const - {} - - template< typename TCoordRep > - void TransformPhysicalVectorToLocalVector( - const FixedArray< TCoordRep, VDimension > & , - FixedArray< TCoordRep, VDimension > & ) const - {} - -protected: - CurvilinearArraySpecialCoordinatesImage() - { - m_RadiusSampleSize = 1; - m_LateralAngularSeparation = 1 * ( 2.0 * vnl_math::pi / 360.0 ); // 1 - // degree - m_FirstSampleDistance = 0; - } - - virtual ~CurvilinearArraySpecialCoordinatesImage() {} - virtual void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; - -private: - CurvilinearArraySpecialCoordinatesImage(const Self &); // purposely not implemented - void operator=(const Self &); // purposely not implemented - - double m_LateralAngularSeparation; // in radians - double m_RadiusSampleSize; - double m_FirstSampleDistance; -}; -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkCurvilinearArraySpecialCoordinatesImage.hxx" -#endif - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkCurvilinearArraySpecialCoordinatesImage.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkCurvilinearArraySpecialCoordinatesImage.hxx deleted file mode 100644 index f543e172a0..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkCurvilinearArraySpecialCoordinatesImage.hxx +++ /dev/null @@ -1,98 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -/*========================================================================= - * - * Portions of this file are subject to the VTK Toolkit Version 3 copyright. - * - * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen - * - * For complete copyright, license and disclaimer of warranty information - * please refer to the NOTICE file at the top of the ITK source tree. - * - *=========================================================================*/ -#ifndef itkCurvilinearArraySpecialCoordinatesImage_hxx -#define itkCurvilinearArraySpecialCoordinatesImage_hxx -#include "itkCurvilinearArraySpecialCoordinatesImage.h" - -namespace itk -{ - -template< typename TPixel, unsigned int VDimension > -void -CurvilinearArraySpecialCoordinatesImage< TPixel, VDimension > -::PrintSelf(std::ostream & os, Indent indent) const -{ - Superclass::PrintSelf(os, indent); - - os << indent - << "RadiusSampleSize = " << m_RadiusSampleSize - << std::endl; - os << indent - << "LateralAngularSeparation = " - << m_LateralAngularSeparation - << std::endl; - os << indent - << "FirstSampleDistance = " - << m_FirstSampleDistance - << std::endl; -} - - -template< typename TPixel, unsigned int VDimension > -void -CurvilinearArraySpecialCoordinatesImage< TPixel, VDimension > -::Graft(const DataObject *data) -{ - // call the superclass' implementation - Superclass::Graft(data); - - if ( data ) - { - // Attempt to cast data to a CurvilinearArraySpecialCoordinatesImage - const Self * const imgData = dynamic_cast< const Self * >( data ); - - if ( imgData ) - { - // Now copy anything remaining that is needed - this->SetPixelContainer( const_cast< PixelContainer * > - ( imgData->GetPixelContainer() ) ); - } - else - { - // pointer could not be cast back down - itkExceptionMacro( << "itk::Image::Graft() cannot cast " - << typeid( data ).name() << " to " - << typeid( const Self * ).name() ); - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.h deleted file mode 100644 index c363c456f4..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.h +++ /dev/null @@ -1,117 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DComplexConjugateToRealImageFilter_h -#define itkFFT1DComplexConjugateToRealImageFilter_h - -#include - -#include "itkImageToImageFilter.h" -#include "itkImageRegionSplitterDirection.h" - -namespace itk -{ -/** \class FFT1DComplexConjugateToRealImageFilter - * \brief Perform the Fast Fourier Transform, in the reverse direction, with - * real output, but only along one dimension. - * - * \ingroup FourierTransform - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=Image< typename NumericTraits< typename TInputImage::PixelType >::ValueType, TInputImage::ImageDimension > > -class FFT1DComplexConjugateToRealImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - typedef FFT1DComplexConjugateToRealImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension ); - - itkTypeMacro( FFT1DComplexConjugateToRealImageFilter, ImageToImageFilter ); - - /** Customized object creation methods that support configuration-based - * selection of FFT implementation. - * - * Default implementation is VnlFFT1D. - */ - static Pointer New(void); - - /** Get the direction in which the filter is to be applied. */ - itkGetMacro(Direction, unsigned int); - - /** Set the direction in which the filter is to be applied. */ - itkSetClampMacro(Direction, unsigned int, 0, ImageDimension - 1); - -protected: - FFT1DComplexConjugateToRealImageFilter(); - ~FFT1DComplexConjugateToRealImageFilter() override {} - - void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - void GenerateInputRequestedRegion() ITK_OVERRIDE; - void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - void BeforeThreadedGenerateData() ITK_OVERRIDE; - - /** Override to return a splitter that does not split along the direction we - * are performing the transform. */ - const ImageRegionSplitterBase* GetImageRegionSplitter() const ITK_OVERRIDE; - - /** Direction in which the filter is to be applied - * this should be in the range [0,ImageDimension-1]. */ - unsigned int m_Direction; - -private: - FFT1DComplexConjugateToRealImageFilter( const Self& ); - void operator=( const Self& ); - - ImageRegionSplitterDirection::Pointer m_ImageRegionSplitter; -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -#ifndef itkVnlFFT1DComplexConjugateToRealImageFilter_h -#ifndef itkVnlFFT1DComplexConjugateToRealImageFilter_hxx -#ifndef itkFFTW1DComplexConjugateToRealImageFilter_h -#ifndef itkFFTW1DComplexConjugateToRealImageFilter_hxx -#include "itkFFT1DComplexConjugateToRealImageFilter.hxx" -#endif -#endif -#endif -#endif -#endif - -#endif // itkFFT1DComplexConjugateToRealImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.hxx deleted file mode 100644 index e2c87d77da..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.hxx +++ /dev/null @@ -1,204 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DComplexConjugateToRealImageFilter_hxx -#define itkFFT1DComplexConjugateToRealImageFilter_hxx - -#include "itkFFT1DComplexConjugateToRealImageFilter.h" - -#include "itkVnlFFT1DComplexConjugateToRealImageFilter.h" - -#if defined(ITK_USE_FFTWD) || defined(ITK_USE_FFTWF) -#include "itkFFTW1DComplexConjugateToRealImageFilter.h" -#endif - -#include "itkMetaDataDictionary.h" -#include "itkMetaDataObject.h" - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage > -typename FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage >::Pointer -FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::New() -{ - Pointer smartPtr = ::itk::ObjectFactory< Self >::Create(); - -#ifdef ITK_USE_FFTWD - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( double ) ) - { - smartPtr = dynamic_cast< Self* >( - FFTW1DComplexConjugateToRealImageFilter< double, VDimension > - ::New().GetPointer() ); - } - } -#endif -#ifdef ITK_USE_FFTWF - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( float ) ) - { - smartPtr = dynamic_cast( - FFTW1DComplexConjugateToRealImageFilter< float, VDimension > - ::New().GetPointer() ); - } - } -#endif - - if( smartPtr.IsNull() ) - { - smartPtr = VnlFFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > - ::New().GetPointer(); - } - - return smartPtr; -} - - -template < typename TInputImage, typename TOutputImage > -FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::FFT1DComplexConjugateToRealImageFilter(): - m_Direction( 0 ) -{ - this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New(); -} - - -template -const ImageRegionSplitterBase* -FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::GetImageRegionSplitter() const -{ - return this->m_ImageRegionSplitter.GetPointer(); -} - - -template -void -FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - this->m_ImageRegionSplitter->SetDirection( this->GetDirection() ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - typename InputImageType::Pointer inputPtr = - const_cast (this->GetInput()); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->m_Direction; - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - enlargedSize[this->m_Direction] = outputLargeSize[this->m_Direction]; - enlargedIndex[this->m_Direction] = outputLargeIndex[this->m_Direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - os << indent << "Direction: " << m_Direction << std::endl; -} - -} // end namespace itk - -#endif // itkFFT1DComplexConjugateToRealImageFilter_hxx diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.h deleted file mode 100644 index 9c130d753e..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.h +++ /dev/null @@ -1,138 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DComplexToComplexImageFilter_h -#define itkFFT1DComplexToComplexImageFilter_h - -#include - -#include "itkImage.h" -#include "itkImageToImageFilter.h" -#include "itkImageRegionSplitterDirection.h" - -namespace itk -{ -/** \class FFT1DComplexToComplexImageFilter - * \brief Perform the Fast Fourier Transform, complex input to complex output, - * but only along one dimension. - * - * The direction of the transform, 'Forward' or 'Inverse', can be set with - * SetTransformDirection() and GetTransformDirection(). - * - * The dimension along which to apply to filter can be specified with - * SetDirection() and GetDirection(). - * - * \ingroup FourierTransform - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=TInputImage > -class FFT1DComplexToComplexImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - typedef FFT1DComplexToComplexImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension ); - - itkTypeMacro( FFT1DComplexToComplexImageFilter, ImageToImageFilter ); - - /** Customized object creation methods that support configuration-based - * selection of FFT implementation. - * - * Default implementation is VnlFFT1D. - */ - static Pointer New(); - - /** Transform direction. */ - typedef enum { DIRECT = 1, INVERSE } TransformDirectionType; - - /** Set/Get the direction in which the transform will be applied. - * By selecting DIRECT, this filter will perform a direct (forward) Fourier - * Transform. - * By selecting INVERSE, this filter will perform an inverse Fourier - * Transform. */ - itkSetMacro( TransformDirection, TransformDirectionType ); - itkGetConstMacro( TransformDirection, TransformDirectionType ); - - /** Get the direction in which the filter is to be applied. */ - itkGetMacro(Direction, unsigned int); - - /** Set the direction in which the filter is to be applied. */ - itkSetClampMacro(Direction, unsigned int, 0, ImageDimension - 1); - -protected: - FFT1DComplexToComplexImageFilter(); - ~FFT1DComplexToComplexImageFilter() override {} - - void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - void GenerateInputRequestedRegion() ITK_OVERRIDE; - void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - void BeforeThreadedGenerateData() ITK_OVERRIDE; - - /** Override to return a splitter that does not split along the direction we - * are performing the transform. */ - const ImageRegionSplitterBase* GetImageRegionSplitter() const ITK_OVERRIDE; - - /** Direction in which the filter is to be applied - * this should be in the range [0,ImageDimension-1]. */ - unsigned int m_Direction; - - /** Direction to apply the transform (forward/inverse). */ - TransformDirectionType m_TransformDirection; - -private: - FFT1DComplexToComplexImageFilter( const Self& ); - void operator=( const Self& ); - - ImageRegionSplitterDirection::Pointer m_ImageRegionSplitter; -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -#ifndef itkVnlFFT1DComplexToComplexImageFilter_h -#ifndef itkVnlFFT1DComplexToComplexImageFilter_hxx -#ifndef itkFFTW1DComplexToComplexImageFilter_h -#ifndef itkFFTW1DComplexToComplexImageFilter_hxx -#include "itkFFT1DComplexToComplexImageFilter.hxx" -#endif -#endif -#endif -#endif -#endif - -#endif // itkFFT1DComplexToComplexImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.hxx deleted file mode 100644 index af4c9d7b1c..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.hxx +++ /dev/null @@ -1,206 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DComplexToComplexImageFilter_hxx -#define itkFFT1DComplexToComplexImageFilter_hxx - -#include "itkFFT1DComplexToComplexImageFilter.h" - -#include "itkVnlFFT1DComplexToComplexImageFilter.h" - -#if defined(ITK_USE_FFTWD) || defined(ITK_USE_FFTWF) -#include "itkFFTW1DComplexToComplexImageFilter.h" -#endif - -#include "itkMetaDataDictionary.h" -#include "itkMetaDataObject.h" - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage > -typename FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage >::Pointer -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::New() -{ - Pointer smartPtr = ::itk::ObjectFactory< Self >::Create(); - -#ifdef ITK_USE_FFTWD - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( double ) ) - { - smartPtr = dynamic_cast< Self* >( - FFTW1DComplexToComplexImageFilter< double, VDimension > - ::New().GetPointer() ); - } - } -#endif -#ifdef ITK_USE_FFTWF - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( float ) ) - { - smartPtr = dynamic_cast( - FFTW1DComplexToComplexImageFilter< float, VDimension > - ::New().GetPointer() ); - } - } -#endif - - if( smartPtr.IsNull() ) - { - smartPtr = VnlFFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > - ::New().GetPointer(); - } - - return smartPtr; -} - - -template< typename TInputImage, typename TOutputImage > -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::FFT1DComplexToComplexImageFilter(): - m_Direction(0), m_TransformDirection( DIRECT ) -{ - this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New(); -} - - -template -const ImageRegionSplitterBase* -FFT1DComplexToComplexImageFilter < TInputImage, TOutputImage > -::GetImageRegionSplitter(void) const -{ - return this->m_ImageRegionSplitter.GetPointer(); -} - - -template -void -FFT1DComplexToComplexImageFilter < TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - this->m_ImageRegionSplitter->SetDirection( this->GetDirection() ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - typename InputImageType::Pointer inputPtr = - const_cast (this->GetInput()); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->m_Direction; - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - enlargedSize[this->m_Direction] = outputLargeSize[this->m_Direction]; - enlargedIndex[this->m_Direction] = outputLargeIndex[this->m_Direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - os << indent << "Direction: " << m_Direction << std::endl; - os << indent << "TransformDirection: " << m_TransformDirection << std::endl; -} - - -} // end namespace itk - -#endif // itkFFT1DComplexToComplexImageFilter_hxx diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h deleted file mode 100644 index a388268a68..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DRealToComplexConjugateImageFilter_h -#define itkFFT1DRealToComplexConjugateImageFilter_h - -#include - -#include "itkImageToImageFilter.h" -#include "itkImageRegionSplitterDirection.h" - -namespace itk -{ -/** \class FFT1DRealToComplexConjugateImageFilter - * \brief Perform the Fast Fourier Transform, in the forward direction, with - * real inputs, but only along one dimension. - * - * \ingroup FourierTransform - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > -class FFT1DRealToComplexConjugateImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - typedef FFT1DRealToComplexConjugateImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkStaticConstMacro( ImageDimension, unsigned int, InputImageType::ImageDimension ); - - itkTypeMacro( FFT1DRealToComplexConjugateImageFilter, ImageToImageFilter ); - - /** Customized object creation methods that support configuration-based - * selection of FFT implementation. - * - * Default implementation is VnlFFT1D. - */ - static Pointer New(); - - /** Get the direction in which the filter is to be applied. */ - itkGetMacro(Direction, unsigned int); - - /** Set the direction in which the filter is to be applied. */ - itkSetClampMacro(Direction, unsigned int, 0, ImageDimension - 1); - -protected: - FFT1DRealToComplexConjugateImageFilter(); - ~FFT1DRealToComplexConjugateImageFilter() override {} - - void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - void GenerateInputRequestedRegion() ITK_OVERRIDE; - void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - void BeforeThreadedGenerateData() ITK_OVERRIDE; - - /** Override to return a splitter that does not split along the direction we - * are performing the transform. */ - const ImageRegionSplitterBase* GetImageRegionSplitter() const ITK_OVERRIDE; - -private: - FFT1DRealToComplexConjugateImageFilter( const Self& ); - void operator=( const Self& ); - - ImageRegionSplitterDirection::Pointer m_ImageRegionSplitter; - - /** Direction in which the filter is to be applied - * this should be in the range [0,ImageDimension-1]. */ - unsigned int m_Direction; - -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_h -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_hxx -#ifndef itkFFTW1DRealToComplexConjugateImageFilter_h -#ifndef itkFFTW1DRealToComplexConjugateImageFilter_hxx -#include "itkFFT1DRealToComplexConjugateImageFilter.hxx" -#endif -#endif -#endif -#endif -#endif - -#endif // itkFFT1DRealToComplexConjugateImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.hxx deleted file mode 100644 index 469f702479..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.hxx +++ /dev/null @@ -1,203 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DRealToComplexConjugateImageFilter_hxx -#define itkFFT1DRealToComplexConjugateImageFilter_hxx - -#include "itkFFT1DRealToComplexConjugateImageFilter.h" - -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.h" - -#if defined(ITK_USE_FFTWD) || defined(ITK_USE_FFTWF) -#include "itkFFTW1DRealToComplexConjugateImageFilter.h" -#endif - -#include "itkMetaDataObject.h" - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage > -typename FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage >::Pointer -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::New() -{ - Pointer smartPtr = ::itk::ObjectFactory< Self >::Create(); - -#ifdef ITK_USE_FFTWD - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( double ) ) - { - smartPtr = dynamic_cast< Self* >( - FFTW1DRealToComplexConjugateImageFilter< double, VDimension > - ::New().GetPointer() ); - } - } -#endif -#ifdef ITK_USE_FFTWF - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( float ) ) - { - smartPtr = dynamic_cast( - FFTW1DRealToComplexConjugateImageFilter< float, VDimension > - ::New().GetPointer() ); - } - } -#endif - - if( smartPtr.IsNull() ) - { - smartPtr = VnlFFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > - ::New().GetPointer(); - } - - return smartPtr; -} - - -template< typename TInputImage, typename TOutputImage > -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::FFT1DRealToComplexConjugateImageFilter(): - m_Direction( 0 ) -{ - this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New(); -} - - -template< typename TInputImage, typename TOutputImage > -const ImageRegionSplitterBase* -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::GetImageRegionSplitter() const -{ - return this->m_ImageRegionSplitter.GetPointer(); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - this->m_ImageRegionSplitter->SetDirection( this->GetDirection() ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - typename InputImageType::Pointer inputPtr = - const_cast (this->GetInput()); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->m_Direction; - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter < TInputImage, TOutputImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast< OutputImageType * >( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - enlargedSize[this->m_Direction] = outputLargeSize[this->m_Direction]; - enlargedIndex[this->m_Direction] = outputLargeIndex[this->m_Direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter < TInputImage, TOutputImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - os << indent << "Direction: " << m_Direction << std::endl; -} - -} // end namespace itk - -#endif // itkFFT1DRealToComplexConjugateImageFilter_hxx diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkRegionFromReferenceImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkRegionFromReferenceImageFilter.h deleted file mode 100644 index 976f59ac76..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkRegionFromReferenceImageFilter.h +++ /dev/null @@ -1,139 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkRegionFromReferenceImageFilter_h -#define itkRegionFromReferenceImageFilter_h - -#include "itkExtractImageFilter.h" - -namespace itk -{ - -/** \class RegionFromReferenceImageFilter - * \brief Decrease the image size by cropping the image by an itk::Size at - * both the upper and lower bounds of the largest possible region. - * - * RegionFromReferenceImageFilter changes the image boundary of an image by removing - * pixels outside the target region. The target region is not specified in - * advance, but calculated in BeforeThreadedGenerateData(). - * - * This filter uses ExtractImageFilter to perform the cropping. - * - * \ingroup GeometricTransforms - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=TInputImage > -class RegionFromReferenceImageFilter: - public ExtractImageFilter -{ -public: - /** Standard class typedefs. */ - typedef RegionFromReferenceImageFilter Self; - typedef ExtractImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(RegionFromReferenceImageFilter, ExtractImageFilter); - - /** Typedef to describe the output and input image region types. */ - typedef typename Superclass::OutputImageRegionType OutputImageRegionType; - typedef typename Superclass::InputImageRegionType InputImageRegionType; - - /** Typedef to describe the type of pixel. */ - typedef typename Superclass::OutputImagePixelType OutputImagePixelType; - typedef typename Superclass::InputImagePixelType InputImagePixelType; - - /** Typedef to describe the output and input image index and size types. */ - typedef typename Superclass::OutputImageIndexType OutputImageIndexType; - typedef typename Superclass::InputImageIndexType InputImageIndexType; - typedef typename Superclass::OutputImageSizeType OutputImageSizeType; - typedef typename Superclass::InputImageSizeType InputImageSizeType; - typedef InputImageSizeType SizeType; - - /** ImageDimension constants */ - itkStaticConstMacro(InputImageDimension, unsigned int, - Superclass::InputImageDimension); - itkStaticConstMacro(OutputImageDimension, unsigned int, - Superclass::OutputImageDimension); - itkStaticConstMacro(ImageDimension, unsigned int, - Superclass::OutputImageDimension); - - typedef ImageBase< itkGetStaticConstMacro( ImageDimension ) > ReferenceImageType; - - /** Copy the output information from another Image. */ - void SetReferenceImage ( const ReferenceImageType *image ); - - const ReferenceImageType * GetReferenceImage() const; - - /** Set the input image */ - void SetInput1(const TInputImage *input) - { - this->SetInput( input ); - } - - /** Set the reference image */ - void SetInput2(const ReferenceImageType *input) - { - this->SetReferenceImage( input ); - } - - -#ifdef ITK_USE_CONCEPT_CHECKING - /** Begin concept checking */ - itkConceptMacro(InputConvertibleToOutputCheck, - (Concept::Convertible)); - itkConceptMacro(SameDimensionCheck, - (Concept::SameDimension)); - /** End concept checking */ -#endif - -protected: - RegionFromReferenceImageFilter() - { - this->SetNumberOfRequiredInputs(2); - } - ~RegionFromReferenceImageFilter() override {} - - void GenerateOutputInformation() ITK_OVERRIDE; - -private: - RegionFromReferenceImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkRegionFromReferenceImageFilter.hxx" -#endif - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkRegionFromReferenceImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkRegionFromReferenceImageFilter.hxx deleted file mode 100644 index 277794c7f2..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkRegionFromReferenceImageFilter.hxx +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkRegionFromReferenceImageFilter_hxx -#define itkRegionFromReferenceImageFilter_hxx - -#include "itkRegionFromReferenceImageFilter.h" - -namespace itk -{ - -template -void -RegionFromReferenceImageFilter -::GenerateOutputInformation() -{ - if( !this->GetInput() || !this->GetReferenceImage() ) - { - return; - } - - // Superclass::Superclass::GenerateOutputInformation(); - this->SetExtractionRegion( this->GetReferenceImage()->GetLargestPossibleRegion() ); - Superclass::GenerateOutputInformation(); -} - - -template -void -RegionFromReferenceImageFilter -::SetReferenceImage ( const ReferenceImageType *image ) -{ - itkDebugMacro("setting input ReferenceImage to " << image); - if( image != static_cast(this->GetInput( 1 )) ) - { - this->ProcessObject::SetNthInput(1, const_cast< ReferenceImageType *>( image ) ); - this->Modified(); - } -} - - -template -const typename RegionFromReferenceImageFilter::ReferenceImageType * -RegionFromReferenceImageFilter -::GetReferenceImage() const -{ - Self * surrogate = const_cast< Self * >( this ); - - const DataObject * input = surrogate->ProcessObject::GetInput(1); - - const ReferenceImageType * referenceImage = static_cast( input ); - - return referenceImage; -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DImageFilter.h deleted file mode 100644 index cf23fc58bf..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DImageFilter.h +++ /dev/null @@ -1,135 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkSpectra1DImageFilter_h -#define itkSpectra1DImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkDefaultConvertPixelTraits.h" -#include "itkImageRegionConstIterator.h" - -#include "vnl/algo/vnl_fft_base.h" -#include "vnl/algo/vnl_fft_1d.h" - -#include -#include - -#include "itkSpectra1DSupportWindowImageFilter.h" - -namespace itk -{ - -/** \class Spectra1DImageFilter - * \brief Generate an image of local spectra. - * - * This image takes in the input image and image that has indexes of the local - * lines used to compute the local spectra. - * - * \ingroup Ultrasound - * - * \sa Spectra1DSupportWindowImageFilter - */ -template< typename TInputImage, typename TSupportWindowImage, typename TOutputImage > -class Spectra1DImageFilter: - public ImageToImageFilter< TInputImage, - TOutputImage > -{ -public: - itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); - - typedef TInputImage InputImageType; - typedef TSupportWindowImage SupportWindowImageType; - typedef TOutputImage OutputImageType; - - typedef typename DefaultConvertPixelTraits< typename OutputImageType::PixelType >::ComponentType - ScalarType; - - /** Standard class typedefs. */ - typedef Spectra1DImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkTypeMacro( Spectra1DImageFilter, ImageToImageFilter ); - itkNewMacro( Self ); - - /** Set/get the input image containning the support window for local spectra - * computation. */ - itkSetInputMacro( SupportWindowImage, SupportWindowImageType ); - itkGetInputMacro( SupportWindowImage, SupportWindowImageType ); - -protected: - Spectra1DImageFilter(); - virtual ~Spectra1DImageFilter() {}; - - typedef typename OutputImageType::RegionType OutputImageRegionType; - - virtual void GenerateOutputInformation() ITK_OVERRIDE; - virtual void BeforeThreadedGenerateData() ITK_OVERRIDE; - virtual void ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId ) ITK_OVERRIDE; - -private: - Spectra1DImageFilter( const Self & ); // purposely not implemented - void operator=( const Self & ); // purposely not implemented - - typedef vcl_complex< ScalarType > ComplexType; - typedef vnl_vector< ComplexType > ComplexVectorType; - typedef vnl_vector< ScalarType > SpectraVectorType; - typedef typename InputImageType::IndexType IndexType; - typedef std::pair< IndexType, SpectraVectorType > SpectraLineType; - typedef std::deque< SpectraLineType > SpectraLinesContainerType; - typedef typename SupportWindowImageType::PixelType SupportWindowType; - typedef ImageRegionConstIterator< InputImageType > InputImageIteratorType; - typedef vnl_fft_1d< ScalarType > FFT1DType; - - typedef Spectra1DSupportWindowImageFilter< OutputImageType > Spectra1DSupportWindowFilterType; - typedef typename Spectra1DSupportWindowFilterType::FFT1DSizeType FFT1DSizeType; - - typedef std::map< FFT1DSizeType, SpectraVectorType > LineWindowMapType; - - struct PerThreadData - { - ComplexVectorType ComplexVector; - SpectraVectorType SpectraVector; - typename InputImageType::SizeType LineImageRegionSize; - LineWindowMapType LineWindowMap; - }; - typedef std::vector< PerThreadData > PerThreadDataContainerType; - PerThreadDataContainerType m_PerThreadDataContainer; - - SpectraLineType ComputeSpectra( const IndexType & lineIndex, ThreadIdType threadId ); - void AddLineWindow( FFT1DSizeType length, LineWindowMapType & lineWindowMap ); -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkSpectra1DImageFilter.hxx" -#endif - -#endif // itkSpectra1DImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DImageFilter.hxx deleted file mode 100644 index 7830428ef8..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DImageFilter.hxx +++ /dev/null @@ -1,273 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkSpectra1DImageFilter_hxx -#define itkSpectra1DImageFilter_hxx - -#include "itkSpectra1DImageFilter.h" - -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkImageRegionConstIterator.h" -#include "itkMetaDataObject.h" - -#include "itkSpectra1DSupportWindowImageFilter.h" - -namespace itk -{ - -template< typename TInputImage, typename TSupportWindowImage, typename TOutputImage > -Spectra1DImageFilter< TInputImage, TSupportWindowImage, TOutputImage > -::Spectra1DImageFilter() -{ - this->AddRequiredInputName( "SupportWindowImage" ); -} - - -template< typename TInputImage, typename TSupportWindowImage, typename TOutputImage > -void -Spectra1DImageFilter< TInputImage, TSupportWindowImage, TOutputImage > -::GenerateOutputInformation() -{ - Superclass::GenerateOutputInformation(); - - const SupportWindowImageType * supportWindowImage = this->GetSupportWindowImage(); - const MetaDataDictionary & dict = supportWindowImage->GetMetaDataDictionary(); - FFT1DSizeType fft1DSize = 32; - ExposeMetaData< FFT1DSizeType >( dict, "FFT1DSize", fft1DSize ); - const FFT1DSizeType spectraComponents = fft1DSize / 2 - 1; - - OutputImageType * output = this->GetOutput(); - output->SetVectorLength( spectraComponents ); -} - - -template< typename TInputImage, typename TSupportWindowImage, typename TOutputImage > -void -Spectra1DImageFilter< TInputImage, TSupportWindowImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - const SupportWindowImageType * supportWindowImage = this->GetSupportWindowImage(); - const MetaDataDictionary & dict = supportWindowImage->GetMetaDataDictionary(); - FFT1DSizeType fft1DSize = 32; - ExposeMetaData< FFT1DSizeType >( dict, "FFT1DSize", fft1DSize ); - const FFT1DSizeType spectraComponents = fft1DSize / 2 - 1; - - const ThreadIdType numberOfThreads = this->GetNumberOfThreads(); - this->m_PerThreadDataContainer.resize( numberOfThreads ); - for( ThreadIdType threadId = 0; threadId < numberOfThreads; ++threadId ) - { - PerThreadData & perThreadData = this->m_PerThreadDataContainer[threadId]; - perThreadData.ComplexVector.set_size( fft1DSize ); - perThreadData.SpectraVector.set_size( spectraComponents ); - perThreadData.LineImageRegionSize.Fill( 1 ); - perThreadData.LineImageRegionSize[0] = fft1DSize; - } -} - - -template< typename TInputImage, typename TSupportWindowImage, typename TOutputImage > -void -Spectra1DImageFilter< TInputImage, TSupportWindowImage, TOutputImage > -::AddLineWindow( FFT1DSizeType length, LineWindowMapType & lineWindowMap ) -{ - if( lineWindowMap.count( length ) == 1 ) - { - return; - } - // Currently using a Hamming Window - SpectraVectorType window( length ); - ScalarType sum = NumericTraits< ScalarType >::ZeroValue(); - const ScalarType twopi = 2 * vnl_math::pi; - for( FFT1DSizeType sample = 0; sample < length; ++sample ) - { - window[sample] = 0.54 + 0.46 * std::cos( (twopi * sample) / (length - 1) ); - sum += window[sample]; - } - for( FFT1DSizeType sample = 0; sample < length; ++sample ) - { - window[sample] /= sum; - } - lineWindowMap[length] = window; -} - - -template< typename TInputImage, typename TSupportWindowImage, typename TOutputImage > -typename Spectra1DImageFilter< TInputImage, TSupportWindowImage, TOutputImage >::SpectraLineType -Spectra1DImageFilter< TInputImage, TSupportWindowImage, TOutputImage > -::ComputeSpectra( const IndexType & lineIndex, ThreadIdType threadId ) -{ - const InputImageType * input = this->GetInput(); - PerThreadData & perThreadData = this->m_PerThreadDataContainer[threadId]; - - const FFT1DSizeType fft1DSize = static_cast< FFT1DSizeType >( perThreadData.ComplexVector.size() ); - - const typename InputImageType::RegionType lineRegion( lineIndex, perThreadData.LineImageRegionSize ); - InputImageIteratorType inputIt( input, lineRegion ); - inputIt.GoToBegin(); - perThreadData.ComplexVector.fill( 0 ); - typename ComplexVectorType::iterator complexVectorIt = perThreadData.ComplexVector.begin(); - typename SpectraVectorType::const_iterator windowIt = perThreadData.LineWindowMap[fft1DSize].begin(); - while( !inputIt.IsAtEnd() ) - { - *complexVectorIt = inputIt.Value() * *windowIt; - ++inputIt; - ++complexVectorIt; - ++windowIt; - } - FFT1DType fft1D( fft1DSize ); - fft1D.bwd_transform( perThreadData.ComplexVector ); - typename ComplexVectorType::const_iterator complexVectorConstIt = perThreadData.ComplexVector.begin(); - typename SpectraVectorType::iterator spectraVectorIt = perThreadData.SpectraVector.begin(); - // drop DC component - ++complexVectorConstIt; - const size_t highFreq = perThreadData.SpectraVector.size(); - for( size_t freq = 0; freq < highFreq; ++freq ) - { - spectraVectorIt[freq] = std::real(*complexVectorConstIt * std::conj(*complexVectorConstIt)); - ++complexVectorConstIt; - } - return std::make_pair( lineIndex, perThreadData.SpectraVector ); -} - - -template< typename TInputImage, typename TSupportWindowImage, typename TOutputImage > -void -Spectra1DImageFilter< TInputImage, TSupportWindowImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId ) -{ - OutputImageType * output = this->GetOutput(); - const SupportWindowImageType * supportWindowImage = this->GetSupportWindowImage(); - - typedef ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - OutputIteratorType outputIt( output, outputRegionForThread ); - outputIt.SetDirection( 1 ); - - const MetaDataDictionary & dict = supportWindowImage->GetMetaDataDictionary(); - FFT1DSizeType fft1DSize = 32; - ExposeMetaData< FFT1DSizeType >( dict, "FFT1DSize", fft1DSize ); - PerThreadData & perThreadData = this->m_PerThreadDataContainer[threadId]; - this->AddLineWindow( fft1DSize, perThreadData.LineWindowMap ); - - ComplexVectorType complexVector( fft1DSize ); - SpectraVectorType spectraVector( fft1DSize ); - typename InputImageType::SizeType lineImageRegionSize; - lineImageRegionSize.Fill( 1 ); - lineImageRegionSize[0] = fft1DSize; - vnl_fft_1d< ScalarType > fft1D( fft1DSize ); - SpectraLinesContainerType spectraLines; - - typedef ImageLinearConstIteratorWithIndex< SupportWindowImageType > SupportWindowIteratorType; - SupportWindowIteratorType supportWindowIt( supportWindowImage, outputRegionForThread ); - supportWindowIt.SetDirection( 1 ); - - for( outputIt.GoToBegin(), supportWindowIt.GoToBegin(); - !outputIt.IsAtEnd(); - outputIt.NextLine(), supportWindowIt.NextLine() ) - { - spectraLines.clear(); - while( ! outputIt.IsAtEndOfLine() ) - { - // Compute the per line spectra. - const SupportWindowType & supportWindow = supportWindowIt.Value(); - if( spectraLines.size() == 0 ) // first window in this lateral direction - { - const typename SupportWindowType::const_iterator windowLineEnd = supportWindow.end(); - for( typename SupportWindowType::const_iterator windowLine = supportWindow.begin(); - windowLine != windowLineEnd; - ++windowLine ) - { - const IndexType & lineIndex = *windowLine; - const SpectraLineType & spectraLine = this->ComputeSpectra( lineIndex, threadId ); - spectraLines.push_back( spectraLine ); - } - } - else // subsequent window along a line - { - const IndexValueType desiredFirstLine = supportWindow[0][1]; - while( spectraLines[0].first[1] < desiredFirstLine ) - { - spectraLines.pop_front(); - } - const typename SupportWindowType::const_iterator windowLineEnd = supportWindow.end(); - typename SpectraLinesContainerType::iterator spectraLinesIt = spectraLines.begin(); - const typename SpectraLinesContainerType::iterator spectraLinesEnd = spectraLines.end(); - for( typename SupportWindowType::const_iterator windowLine = supportWindow.begin(); - windowLine != windowLineEnd; - ++windowLine ) - { - const IndexType & lineIndex = *windowLine; - if( spectraLinesIt == spectraLinesEnd ) // past the end of the previously processed lines - { - const SpectraLineType & spectraLine = this->ComputeSpectra( lineIndex, threadId ); - spectraLines.push_back( spectraLine ); - } - else if( lineIndex[1] == (spectraLinesIt->first)[1] ) // one of the same lines that was previously computed - { - if( lineIndex[0] != (spectraLinesIt->first)[0] ) - { - const SpectraLineType & spectraLine = this->ComputeSpectra( lineIndex, threadId ); - *spectraLinesIt = spectraLine; - } - ++spectraLinesIt; - } - else - { - itkExceptionMacro( "Unexpected line" ); - } - } - } - - const size_t spectraLinesCount = spectraLines.size(); - this->AddLineWindow( spectraLinesCount, perThreadData.LineWindowMap ); - typename OutputImageType::PixelType outputPixel; - outputPixel.SetSize( fft1DSize ); - outputPixel.Fill( NumericTraits< ScalarType >::ZeroValue() ); - typename SpectraVectorType::const_iterator windowIt = perThreadData.LineWindowMap[spectraLinesCount].begin(); - for( size_t line = 0; line < spectraLinesCount; ++line ) - { - typename SpectraVectorType::const_iterator spectraIt = spectraLines[line].second.begin(); - for( FFT1DSizeType sample = 0; sample < fft1DSize; ++sample ) - { - outputPixel[sample] += *windowIt * *spectraIt; - ++spectraIt; - } - ++windowIt; - } - outputIt.Set( outputPixel ); - - ++outputIt; - ++supportWindowIt; - } - } -} - - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowImageFilter.h deleted file mode 100644 index d9b0d65807..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowImageFilter.h +++ /dev/null @@ -1,113 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkSpectra1DSupportWindowImageFilter_h -#define itkSpectra1DSupportWindowImageFilter_h - -#include - -#include "itkImageToImageFilter.h" - -namespace itk -{ - -/** \class Spectra1DSupportWindowImageFilter - * \brief Generate an image of local spectra computation support windows. - * - * The information from the input image is used to determine the output image - * information. The pixel value of the input image is used to specify the - * nominal number of lines on either side of the central FFT line to add to - * the window. The nominal size of the 1D FFT is specified with SetFFTSize() - * - * The overlap between windows is specified with SetStep(). By default, the - * Step is only one sample. - * - * \ingroup Ultrasound - */ -template< typename TInputImage > -class Spectra1DSupportWindowImageFilter: - public ImageToImageFilter< TInputImage, - Image< std::deque< typename TInputImage::IndexType >, TInputImage::ImageDimension > > -{ -public: - itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); - - typedef TInputImage InputImageType; - typedef typename InputImageType::IndexType IndexType; - - typedef std::deque< IndexType > OutputPixelType; - typedef Image< OutputPixelType, ImageDimension > OutputImageType; - - typedef unsigned int FFT1DSizeType; - - /** Standard class typedefs. */ - typedef Spectra1DSupportWindowImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkTypeMacro( Spectra1DSupportWindowImageFilter, ImageToImageFilter ); - itkNewMacro( Self ); - - /** Set/Get the nominal size of the FFT. This will be truncated at the - * boundary of image. */ - itkGetConstMacro( FFT1DSize, FFT1DSizeType ); - itkSetMacro( FFT1DSize, FFT1DSizeType ); - - /** Set/Get the number of samples between windows -- defaults to 1. */ - itkGetConstMacro( Step, SizeValueType ); - itkSetMacro( Step, SizeValueType ); - -protected: - Spectra1DSupportWindowImageFilter(); - virtual ~Spectra1DSupportWindowImageFilter() {}; - - typedef typename OutputImageType::RegionType OutputImageRegionType; - - virtual void GenerateOutputInformation() ITK_OVERRIDE; - - virtual void ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId ) ITK_OVERRIDE; - virtual void AfterThreadedGenerateData() ITK_OVERRIDE; - - virtual void PrintSelf( std::ostream & os, Indent indent ) const ITK_OVERRIDE; - -private: - Spectra1DSupportWindowImageFilter( const Self & ); // purposely not implemented - void operator=( const Self & ); // purposely not implemented - - FFT1DSizeType m_FFT1DSize; - SizeValueType m_Step; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkSpectra1DSupportWindowImageFilter.hxx" -#endif - -#endif // itkSpectra1DSupportWindowImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowImageFilter.hxx deleted file mode 100644 index 1a8521fad1..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowImageFilter.hxx +++ /dev/null @@ -1,168 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkSpectra1DSupportWindowImageFilter_hxx -#define itkSpectra1DSupportWindowImageFilter_hxx - -#include "itkSpectra1DSupportWindowImageFilter.h" -#include "itkImageRegionIterator.h" -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkMetaDataObject.h" -#include "itkImageScanlineIterator.h" - -namespace itk -{ - -template< typename TInputImage > -Spectra1DSupportWindowImageFilter< TInputImage > -::Spectra1DSupportWindowImageFilter(): - m_FFT1DSize( 32 ), - m_Step( 1 ) -{ -} - - -template< typename TInputImage > -void -Spectra1DSupportWindowImageFilter< TInputImage > -::GenerateOutputInformation() -{ - Superclass::GenerateOutputInformation(); - - OutputImageType * output = this->GetOutput(); - const InputImageType * input = this->GetInput(); - - OutputImageRegionType outputRegion = input->GetLargestPossibleRegion(); - typename OutputImageType::SizeType outputSize = outputRegion.GetSize(); - outputSize[0] /= this->GetStep(); - outputRegion.SetSize( outputSize ); - output->SetLargestPossibleRegion( outputRegion ); - - typename OutputImageType::SpacingType outputSpacing = input->GetSpacing(); - outputSpacing[0] *= this->GetStep(); - output->SetSpacing( outputSpacing ); -} - - -template< typename TInputImage > -void -Spectra1DSupportWindowImageFilter< TInputImage > -::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, ThreadIdType itkNotUsed( threadId ) ) -{ - OutputImageType * output = this->GetOutput(); - const InputImageType * input = this->GetInput(); - - const OutputImageRegionType outputLargestRegion = output->GetLargestPossibleRegion(); - typedef typename OutputImageType::IndexType IndexType; - const IndexType largestIndexStart = outputLargestRegion.GetIndex(); - IndexType largestIndexStop = largestIndexStart + outputLargestRegion.GetSize(); - for( unsigned int dim = 0; dim < ImageDimension; ++dim ) - { - largestIndexStop[dim] -= 1; - } - - typedef ImageLinearConstIteratorWithIndex< InputImageType > InputIteratorType; - InputIteratorType inputIt( input, outputRegionForThread ); - typedef ImageScanlineIterator< OutputImageType > OutputIteratorType; - OutputIteratorType outputIt( output, outputRegionForThread ); - const FFT1DSizeType fftSize = this->GetFFT1DSize(); - const SizeValueType sampleStep = this->GetStep(); - if( outputLargestRegion.GetSize()[0] < fftSize ) - { - itkExceptionMacro( "Insufficient size in the FFT direction." ); - } - for( inputIt.GoToBegin(), outputIt.GoToBegin(); !outputIt.IsAtEnd(); ) - { - while( !outputIt.IsAtEndOfLine() ) - { - OutputPixelType & supportWindow = outputIt.Value(); - supportWindow.clear(); - - const IndexType inputIndex = inputIt.GetIndex(); - - IndexType lineIndex; - lineIndex[0] = inputIndex[0] - fftSize / 2; - if( lineIndex[0] < largestIndexStart[0] ) - { - lineIndex[0] = largestIndexStart[0]; - } - - if( lineIndex[0] + fftSize > largestIndexStop[0] ) - { - lineIndex[0] = largestIndexStop[0] - fftSize; - } - - const IndexValueType sideLines = static_cast< IndexValueType >( inputIt.Get() ); - for( IndexValueType line = inputIndex[1] - sideLines; - line < inputIndex[1] + sideLines; - ++line ) - { - if( line < largestIndexStart[1] || line > largestIndexStop[1] ) - { - continue; - } - lineIndex[1] = line; - supportWindow.push_back( lineIndex ); - } - for( SizeValueType ii = 0; ii < sampleStep; ++ii ) - { - ++inputIt; - } - ++outputIt; - } - inputIt.NextLine(); - outputIt.NextLine(); - } -} - - -template< typename TInputImage > -void -Spectra1DSupportWindowImageFilter< TInputImage > -::AfterThreadedGenerateData() -{ - OutputImageType * output = this->GetOutput(); - MetaDataDictionary & dict = output->GetMetaDataDictionary(); - EncapsulateMetaData< FFT1DSizeType >( dict, "FFT1DSize", this->GetFFT1DSize() ); -} - - -template< typename TInputImage > -void -Spectra1DSupportWindowImageFilter< TInputImage > -::PrintSelf( std::ostream & os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - os << indent << "FFT1DSize: " << this->GetFFT1DSize() << std::endl; - os << indent << "Step: " << this->GetStep() << std::endl; -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowToMaskImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowToMaskImageFilter.h deleted file mode 100644 index 1132a46300..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowToMaskImageFilter.h +++ /dev/null @@ -1,101 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkSpectra1DSupportWindowToMaskImageFilter_h -#define itkSpectra1DSupportWindowToMaskImageFilter_h - -#include "itkImageToImageFilter.h" - -namespace itk -{ - -/** \class Spectra1DSupportWindowToMaskImageFilter - * \brief Generate a mask image from the support window at a given index. - * - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage > -class Spectra1DSupportWindowToMaskImageFilter: - public ImageToImageFilter< TInputImage, - TOutputImage > -{ -public: - itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); - - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - - typedef typename InputImageType::IndexType IndexType; - typedef typename OutputImageType::PixelType OutputPixelType; - - /** Standard class typedefs. */ - typedef Spectra1DSupportWindowToMaskImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkTypeMacro( Spectra1DSupportWindowToMaskImageFilter, ImageToImageFilter ); - itkNewMacro( Self ); - - /** Set/Get the index of the support window to create the mask for. */ - itkGetConstReferenceMacro( MaskIndex, IndexType ); - itkSetMacro( MaskIndex, IndexType ); - - /** Set/Get the value to consider as "background". Defaults to zero. */ - itkSetMacro( BackgroundValue, OutputPixelType ); - itkGetConstMacro( BackgroundValue, OutputPixelType ); - - /** Set/Get the value in the image to consider as "foreground". Defaults to - * maximum value of the OutputPixelType. */ - itkSetMacro( ForegroundValue, OutputPixelType ); - itkGetConstMacro( ForegroundValue, OutputPixelType ); - - -protected: - Spectra1DSupportWindowToMaskImageFilter(); - virtual ~Spectra1DSupportWindowToMaskImageFilter() {}; - - virtual void GenerateData() ITK_OVERRIDE; - -private: - Spectra1DSupportWindowToMaskImageFilter( const Self & ); // purposely not implemented - void operator=( const Self & ); // purposely not implemented - - IndexType m_MaskIndex; - - OutputPixelType m_BackgroundValue; - OutputPixelType m_ForegroundValue; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkSpectra1DSupportWindowToMaskImageFilter.hxx" -#endif - -#endif // itkSpectra1DSupportWindowToMaskImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowToMaskImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowToMaskImageFilter.hxx deleted file mode 100644 index 165cda2b6f..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkSpectra1DSupportWindowToMaskImageFilter.hxx +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkSpectra1DSupportWindowToMaskImageFilter_hxx -#define itkSpectra1DSupportWindowToMaskImageFilter_hxx - -#include "itkSpectra1DSupportWindowToMaskImageFilter.h" -#include "itkSpectra1DSupportWindowImageFilter.h" -#include "itkImageRegionIterator.h" -#include "itkImageRegionConstIteratorWithIndex.h" -#include "itkMetaDataObject.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -Spectra1DSupportWindowToMaskImageFilter< TInputImage, TOutputImage > -::Spectra1DSupportWindowToMaskImageFilter(): - m_BackgroundValue( NumericTraits< OutputPixelType >::ZeroValue() ), - m_ForegroundValue( NumericTraits< OutputPixelType >::max() ) -{ - m_MaskIndex.Fill( 0 ); -} - - -template< typename TInputImage, typename TOutputImage > -void -Spectra1DSupportWindowToMaskImageFilter< TInputImage, TOutputImage > -::GenerateData() -{ - this->AllocateOutputs(); - - const InputImageType * input = this->GetInput(); - typedef typename InputImageType::PixelType InputPixelType; - const InputPixelType & inputPixel = input->GetPixel( this->GetMaskIndex() ); - - typedef Spectra1DSupportWindowImageFilter< OutputImageType > Spectra1DSupportWindowFilterType; - typedef typename Spectra1DSupportWindowFilterType::FFT1DSizeType FFT1DSizeType; - - const MetaDataDictionary & dict = input->GetMetaDataDictionary(); - FFT1DSizeType fft1DSize = 32; - ExposeMetaData< FFT1DSizeType >( dict, "FFT1DSize", fft1DSize ); - - OutputImageType * output = this->GetOutput(); - output->FillBuffer( this->GetBackgroundValue() ); - - for( typename InputPixelType::const_iterator lineIt = inputPixel.begin(); lineIt != inputPixel.end(); ++lineIt ) - { - const IndexType startIndex = *lineIt; - IndexType index = startIndex; - for( FFT1DSizeType sampleIndex = 0; sampleIndex < fft1DSize; ++sampleIndex ) - { - index[0] = startIndex[0] + sampleIndex; - output->SetPixel( index, this->GetForegroundValue() ); - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkTimeGainCompensationImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkTimeGainCompensationImageFilter.h deleted file mode 100644 index 46a5f1f0fa..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkTimeGainCompensationImageFilter.h +++ /dev/null @@ -1,97 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkTimeGainCompensationImageFilter_h -#define itkTimeGainCompensationImageFilter_h - -#include "itkImageToImageFilter.h" - -#include "itkArray2D.h" - -namespace itk -{ - -/** - * \class TimeGainCompensationImageFilter - * \brief Applies a linear piecewise time gain compensation. - * - * This filter applies a linear piecewise gain with depth. The depth - * direction is assumed to be the first direction (0th direction). - * - * \ingroup Ultrasound - * */ -template< typename TInputImage, typename TOutputImage = TInputImage > -class TimeGainCompensationImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - - typedef TimeGainCompensationImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkTypeMacro( TimeGainCompensationImageFilter, ImageToImageFilter ); - itkNewMacro( Self ); - - typedef Array2D< double > GainType; - - /** Set/Get the gain. The first column specifies the depth. The second - * column specifies the gain. */ - itkSetMacro( Gain, GainType ); - itkGetConstReferenceMacro( Gain, GainType ); - -protected: - typedef typename OutputImageType::RegionType OutputImageRegionType; - - TimeGainCompensationImageFilter(); - virtual ~TimeGainCompensationImageFilter() {} - - void PrintSelf( std::ostream & os, Indent indent ) const ITK_OVERRIDE; - - virtual void BeforeThreadedGenerateData() ITK_OVERRIDE; - virtual void ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType threadId ) ITK_OVERRIDE; - -private: - TimeGainCompensationImageFilter( const Self& ); // purposely not implemented - void operator=( const Self& ); // purposely not implemented - - GainType m_Gain; -}; - -} - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkTimeGainCompensationImageFilter.hxx" -#endif - -#endif // itkTimeGainCompensationImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkTimeGainCompensationImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkTimeGainCompensationImageFilter.hxx deleted file mode 100644 index c6df4bacc3..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkTimeGainCompensationImageFilter.hxx +++ /dev/null @@ -1,176 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkTimeGainCompensationImageFilter_hxx -#define itkTimeGainCompensationImageFilter_hxx - -#include "itkTimeGainCompensationImageFilter.h" - -#include "itkImageScanlineIterator.h" -#include "itkImageScanlineConstIterator.h" -#include "itkArray.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -TimeGainCompensationImageFilter< TInputImage, TOutputImage > -::TimeGainCompensationImageFilter(): - m_Gain( 2, 2 ) -{ - m_Gain(0, 0) = NumericTraits< double >::min(); - m_Gain(0, 1) = NumericTraits< double >::OneValue(); - m_Gain(1, 0) = NumericTraits< double >::max(); - m_Gain(1, 1) = NumericTraits< double >::OneValue(); -} - - -template< typename TInputImage, typename TOutputImage > -void -TimeGainCompensationImageFilter< TInputImage, TOutputImage > -::PrintSelf( std::ostream & os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - os << indent << "Gain:" << std::endl; - for( unsigned int ii = 0; ii < m_Gain.rows(); ++ii ) - { - os << indent.GetNextIndent() << "[" << m_Gain( ii, 0 ) << ", " << m_Gain( ii, 1 ) << "]" << std::endl; - } -} - - -template< typename TInputImage, typename TOutputImage > -void -TimeGainCompensationImageFilter< TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - const GainType & gain = this->GetGain(); - if( gain.cols() != 2 ) - { - itkExceptionMacro( "Gain should have two columns." ); - } - if( gain.rows() < 2 ) - { - itkExceptionMacro( "Insufficient depths specified in Gain." ); - } - double depth = gain( 0, 0 ); - for( unsigned int ii = 1; ii < gain.rows(); ++ii ) - { - if( gain( ii, 0 ) <= depth ) - { - itkExceptionMacro( "Gain depths must be strictly increasing." ); - } - depth = gain( ii, 0 ); - } -} - - -template< typename TInputImage, typename TOutputImage > -void -TimeGainCompensationImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread, ThreadIdType itkNotUsed( threadId ) ) -{ - const InputImageType * inputImage = this->GetInput(); - OutputImageType * outputImage = this->GetOutput(); - - // Compute the line gain once. - const GainType & gain = this->GetGain(); - double pieceStart = gain( 0, 0 ); - double pieceEnd = gain( 1, 0 ); - double gainStart = gain( 0, 1 ); - double gainEnd = gain( 1, 1 ); - SizeValueType gainSegment = 1; - - typedef Array< double > LineGainType; - const SizeValueType lineGainSize = outputRegionForThread.GetSize()[0]; - const typename InputImageType::RegionType & inputRegion = inputImage->GetLargestPossibleRegion(); - const IndexValueType imageStartIndex = inputRegion.GetIndex()[0]; - const typename InputImageType::PointType origin = inputImage->GetOrigin(); - const SpacePrecisionType pixelSpacing = inputImage->GetSpacing()[0]; - IndexValueType indexOffset = outputRegionForThread.GetIndex()[0] - imageStartIndex; - LineGainType lineGain( lineGainSize ); - for( SizeValueType lineGainIndex = 0; lineGainIndex < lineGainSize; ++lineGainIndex ) - { - const SpacePrecisionType pixelLocation = origin[0] + pixelSpacing * indexOffset; - if( pixelLocation <= pieceStart ) - { - lineGain[lineGainIndex] = gainStart; - } - else if( pixelLocation > pieceEnd ) - { - if( gainSegment >= gain.rows() - 1 ) - { - lineGain[lineGainIndex] = gainEnd; - } - else - { - ++gainSegment; - pieceStart = gain( gainSegment - 1, 0 ); - pieceEnd = gain( gainSegment, 0 ); - gainStart = gain( gainSegment - 1, 1 ); - gainEnd = gain( gainSegment, 1 ); - - const SpacePrecisionType offset = static_cast< SpacePrecisionType >( pixelLocation - pieceStart ); - lineGain[lineGainIndex] = offset * ( gainEnd - gainStart ) / ( pieceEnd - pieceStart ) + gainStart; - } - } - else - { - const SpacePrecisionType offset = static_cast< SpacePrecisionType >( pixelLocation - pieceStart ); - lineGain[lineGainIndex] = offset * ( gainEnd - gainStart ) / ( pieceEnd - pieceStart ) + gainStart; - } - ++indexOffset; - } - - typedef ImageScanlineConstIterator< InputImageType > InputIteratorType; - InputIteratorType inputIt( inputImage, outputRegionForThread ); - - typedef ImageScanlineIterator< OutputImageType > OutputIteratorType; - OutputIteratorType outputIt( outputImage, outputRegionForThread ); - - for( inputIt.GoToBegin(), outputIt.GoToBegin(); - !outputIt.IsAtEnd(); - inputIt.NextLine(), outputIt.NextLine() ) - { - inputIt.GoToBeginOfLine(); - outputIt.GoToBeginOfLine(); - SizeValueType lineGainIndex = 0; - while( ! outputIt.IsAtEndOfLine() ) - { - outputIt.Set( inputIt.Value() * lineGain[lineGainIndex] ); - ++inputIt; - ++outputIt; - ++lineGainIndex; - } - } -} - -} // end namespace itk - -#endif // itkTimeGainCompensationImageFilter_hxx diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.h deleted file mode 100644 index 1ccada5222..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.h +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexConjugateToRealImageFilter_h -#define itkVnlFFT1DComplexConjugateToRealImageFilter_h - -#include "itkFFT1DComplexConjugateToRealImageFilter.h" -#include - -namespace itk -{ - -/** \class VnlFFT1DComplexConjugateToRealImageFilter - * - * \brief Perform the FFT along one dimension of an image using Vnl as a - * backend. - * - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=Image< typename NumericTraits< typename TInputImage::PixelType >::ValueType, TInputImage::ImageDimension > > -class VnlFFT1DComplexConjugateToRealImageFilter: - public FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef VnlFFT1DComplexConjugateToRealImageFilter Self; - typedef FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Run-time type information (and related methods). */ - itkTypeMacro( VnlFFT1DComplexConjugateToRealImageFilter, FFT1DComplexConjugateToRealImageFilter ); - -protected: - void ThreadedGenerateData( const OutputImageRegionType&, ThreadIdType threadID ) override; // generates output from input - - VnlFFT1DComplexConjugateToRealImageFilter() { } - ~VnlFFT1DComplexConjugateToRealImageFilter() override { } - -private: - VnlFFT1DComplexConjugateToRealImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkVnlFFT1DComplexConjugateToRealImageFilter.hxx" -#endif - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.hxx deleted file mode 100644 index d77ad681a1..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.hxx +++ /dev/null @@ -1,110 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexConjugateToRealImageFilter_hxx -#define itkVnlFFT1DComplexConjugateToRealImageFilter_hxx - -#include "itkVnlFFT1DComplexConjugateToRealImageFilter.h" - -#include "itkFFT1DComplexConjugateToRealImageFilter.hxx" -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkIndent.h" -#include "itkMetaDataObject.h" -#include "itkExceptionObject.h" -#include "vnl/algo/vnl_fft_base.h" -#include "vnl/algo/vnl_fft_1d.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -void -VnlFFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegion, ThreadIdType itkNotUsed( threadID ) ) -{ - // get pointers to the input and output - const typename Superclass::InputImageType * inputPtr = this->GetInput(); - typename Superclass::OutputImageType * outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - const typename Superclass::InputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - - unsigned int vec_size = inputSize[this->m_Direction]; - - typedef itk::ImageLinearConstIteratorWithIndex< InputImageType > InputIteratorType; - typedef itk::ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegion ); - OutputIteratorType outputIt( outputPtr, outputRegion ); - - inputIt.SetDirection(this->m_Direction); - outputIt.SetDirection(this->m_Direction); - - typedef typename TOutputImage::PixelType OutputPixelType; - vnl_vector< vcl_complex< OutputPixelType > > inputBuffer( vec_size ); - typename vnl_vector< vcl_complex< OutputPixelType > >::iterator inputBufferIt = inputBuffer.begin(); - // fft is done in-place - typename vnl_vector< vcl_complex< OutputPixelType > >::iterator outputBufferIt = inputBuffer.begin(); - vnl_fft_1d< OutputPixelType > v1d(vec_size); - - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - // copy the input line into our buffer - inputIt.GoToBeginOfLine(); - inputBufferIt = inputBuffer.begin(); - while( !inputIt.IsAtEndOfLine() ) - { - *inputBufferIt = inputIt.Get(); - ++inputIt; - ++inputBufferIt; - } - - // do the transform - v1d.fwd_transform(inputBuffer); - - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( (*outputBufferIt).real() / vec_size ); - ++outputIt; - ++outputBufferIt; - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.h deleted file mode 100644 index 4fbbbd10b0..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.h +++ /dev/null @@ -1,85 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexToComplexImageFilter_h -#define itkVnlFFT1DComplexToComplexImageFilter_h - -#include "itkFFT1DComplexToComplexImageFilter.h" -#include - -namespace itk -{ - -/** \class VnlFFT1DComplexToComplexImageFilter - * - * \brief Perform the FFT along one dimension of an image using Vnl as a - * backend. - * - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage > -class VnlFFT1DComplexToComplexImageFilter: - public FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef VnlFFT1DComplexToComplexImageFilter Self; - typedef FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - typedef typename Superclass::TransformDirectionType TransformDirectionType; - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Run-time type information (and related methods). */ - itkTypeMacro( VnlFFT1DComplexToComplexImageFilter, FFT1DComplexToComplexImageFilter ); - -protected: - VnlFFT1DComplexToComplexImageFilter() {} - ~VnlFFT1DComplexToComplexImageFilter() override {} - - void ThreadedGenerateData( const OutputImageRegionType&, ThreadIdType threadID ) ITK_OVERRIDE; - -private: - VnlFFT1DComplexToComplexImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkVnlFFT1DComplexToComplexImageFilter.hxx" -#endif - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.hxx deleted file mode 100644 index 3ab41c2caa..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.hxx +++ /dev/null @@ -1,127 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexToComplexImageFilter_hxx -#define itkVnlFFT1DComplexToComplexImageFilter_hxx - -#include "itkVnlFFT1DComplexToComplexImageFilter.h" - -#include "itkFFT1DComplexToComplexImageFilter.hxx" -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkIndent.h" -#include "itkMetaDataObject.h" -#include "itkExceptionObject.h" -#include "vnl/algo/vnl_fft_base.h" -#include "vnl/algo/vnl_fft_1d.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -void -VnlFFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegion, ThreadIdType itkNotUsed( threadID ) ) -{ - // get pointers to the input and output - const typename Superclass::InputImageType * inputPtr = this->GetInput(); - typename Superclass::OutputImageType * outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - const typename Superclass::InputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - - const unsigned int direction = this->GetDirection(); - const unsigned int vectorSize = inputSize[direction]; - - typedef itk::ImageLinearConstIteratorWithIndex< InputImageType > InputIteratorType; - typedef itk::ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegion ); - OutputIteratorType outputIt( outputPtr, outputRegion ); - - inputIt.SetDirection( direction ); - outputIt.SetDirection( direction ); - - typedef typename TInputImage::PixelType PixelType; - typedef vnl_vector< PixelType > VNLVectorType; - VNLVectorType inputBuffer( vectorSize ); - typename VNLVectorType::iterator inputBufferIt = inputBuffer.begin(); - // fft is done in-place - typename VNLVectorType::iterator outputBufferIt = inputBuffer.begin(); - vnl_fft_1d< typename NumericTraits< PixelType >::ValueType > v1d(vectorSize); - - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - // copy the input line into our buffer - inputIt.GoToBeginOfLine(); - inputBufferIt = inputBuffer.begin(); - while( !inputIt.IsAtEndOfLine() ) - { - *inputBufferIt = inputIt.Get(); - ++inputIt; - ++inputBufferIt; - } - - // do the transform - if( this->m_TransformDirection == Superclass::DIRECT ) - { - v1d.bwd_transform(inputBuffer); - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( *outputBufferIt ); - ++outputIt; - ++outputBufferIt; - } - } - else // m_TransformDirection == INVERSE - { - v1d.fwd_transform(inputBuffer); - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( (*outputBufferIt) / static_cast< PixelType >( vectorSize )); - ++outputIt; - ++outputBufferIt; - } - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.h deleted file mode 100644 index 1d8c15ab2d..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.h +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_h -#define itkVnlFFT1DRealToComplexConjugateImageFilter_h - -#include "itkFFT1DRealToComplexConjugateImageFilter.h" -#include - -namespace itk -{ - -/** \class VnlFFT1DRealToComplexConjugateImageFilter - * - * \brief Perform the FFT along one dimension of an image using Vnl as a - * backend. - * - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > -class VnlFFT1DRealToComplexConjugateImageFilter : - public FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef VnlFFT1DRealToComplexConjugateImageFilter Self; - typedef FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Run-time type information (and related methods). */ - itkTypeMacro( VnlFFT1DRealToComplexConjugateImageFilter, FFT1DRealToComplexConjugateImageFilter ); - -protected: - void ThreadedGenerateData( const OutputImageRegionType&, ThreadIdType threadID ) ITK_OVERRIDE; - - VnlFFT1DRealToComplexConjugateImageFilter() { } - ~VnlFFT1DRealToComplexConjugateImageFilter() override { } - -private: - VnlFFT1DRealToComplexConjugateImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.hxx" -#endif - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.hxx deleted file mode 100644 index 0d38c0d745..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.hxx +++ /dev/null @@ -1,115 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_hxx -#define itkVnlFFT1DRealToComplexConjugateImageFilter_hxx - -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.h" - -#include "itkFFT1DRealToComplexConjugateImageFilter.hxx" -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkIndent.h" -#include "itkMetaDataObject.h" -#include "itkExceptionObject.h" -#include "itkVnlFFTCommon.h" -#include "vnl/algo/vnl_fft_base.h" -#include "vnl/algo/vnl_fft_1d.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -void -VnlFFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegion, ThreadIdType itkNotUsed( threadID ) ) -{ - // get pointers to the input and output - const typename Superclass::InputImageType * inputPtr = this->GetInput(); - typename Superclass::OutputImageType * outputPtr = this->GetOutput(); - - const typename Superclass::InputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - - const unsigned int direction = this->GetDirection(); - unsigned int vectorSize = inputSize[direction]; - if( ! VnlFFTCommon::IsDimensionSizeLegal(vectorSize) ) - { - itkExceptionMacro("Illegal Array DIM for FFT"); - } - - - typedef ImageLinearConstIteratorWithIndex< InputImageType > InputIteratorType; - typedef ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegion ); - OutputIteratorType outputIt( outputPtr, outputRegion ); - - inputIt.SetDirection( direction ); - outputIt.SetDirection( direction ); - - typedef typename TInputImage::PixelType PixelType; - typedef vcl_complex< PixelType > ComplexType; - typedef vnl_vector< ComplexType > ComplexVectorType; - ComplexVectorType inputBuffer( vectorSize ); - typename ComplexVectorType::iterator inputBufferIt = inputBuffer.begin(); - // fft is done in-place - typename ComplexVectorType::iterator outputBufferIt = inputBuffer.begin(); - vnl_fft_1d< PixelType > v1d( vectorSize ); - - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); - !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - // copy the input line into our buffer - inputIt.GoToBeginOfLine(); - inputBufferIt = inputBuffer.begin(); - while( !inputIt.IsAtEndOfLine() ) - { - *inputBufferIt = inputIt.Value(); - ++inputIt; - ++inputBufferIt; - } - - // do the transform - v1d.bwd_transform( inputBuffer ); - - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( *outputBufferIt ); - ++outputIt; - ++outputBufferIt; - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/itkPhotoacousticBModeImageFilter.h b/Modules/PhotoacousticsAlgorithms/ITKFilter/itkPhotoacousticBModeImageFilter.h deleted file mode 100644 index 00f14ab7fc..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/itkPhotoacousticBModeImageFilter.h +++ /dev/null @@ -1,143 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkPhotoacousticBModeImageFilter_h -#define itkPhotoacousticBModeImageFilter_h - -#include "itkComplexToModulusImageFilter.h" -#include "itkConstantPadImageFilter.h" -#include "itkImageToImageFilter.h" -#include "itkImage.h" - -#include "ITKUltrasound/itkRegionFromReferenceImageFilter.h" -#include "ITKUltrasound/itkAnalyticSignalImageFilter.h" - -namespace itk -{ - -/** - * \class PhotoacousticBModeImageFilter - * - * \brief Create an Photoacoustic B-Mode (Brightness-Mode) image from raw - * "RF" data. The RF's envelope is calculated from the analytic signal and - * logarithmic intensity transform is NOT applied. This is for now the only - * difference to the "normal" BModeImageFilter. - * - * Use SetDirection() to define the axis of propagation. - * - */ -template < typename TInputImage, typename TOutputImage=TInputImage, typename TComplexImage=Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > -class PhotoacousticBModeImageFilter : - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef PhotoacousticBModeImageFilter Self; - typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - /** The type of input image. */ - typedef TInputImage InputImageType; - - /** Dimension of the input and output images. */ - itkStaticConstMacro (ImageDimension, unsigned int, - TInputImage::ImageDimension); - - /** Typedef support for the input image scalar value type. */ - typedef typename InputImageType::PixelType InputPixelType; - - /** The type of output image. */ - typedef TOutputImage OutputImageType; - - /** Typedef support for the output image scalar value type. */ - typedef typename OutputImageType::PixelType OutputPixelType; - - /** Typedef of the image used for internal computations that has - * std::complex pixels. */ - typedef TComplexImage ComplexImageType; - - /** Other convenient typedefs */ - typedef typename InputImageType::RegionType InputRegionType; - typedef typename InputImageType::SizeType InputSizeType; - typedef typename InputImageType::IndexType InputIndexType; - - /** Run-time type information (and related methods) */ - itkTypeMacro( PhotoacousticBModeImageFilter, ImageToImageFilter ); - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Set the direction in which the envelope is to be calculated. */ - virtual void SetDirection( unsigned int direction ) - { - this->m_AnalyticFilter->SetDirection( direction ); - this->Modified(); - } - - /** Get the direction in which the envelope is to be calculated. */ - virtual unsigned int GetDirection() const - { - return m_AnalyticFilter->GetDirection(); - } - -protected: - PhotoacousticBModeImageFilter(); - ~PhotoacousticBModeImageFilter() override {} - - void PrintSelf( std::ostream& os, Indent indent ) const ITK_OVERRIDE; - - void GenerateData() ITK_OVERRIDE; - - // These behave like their analogs in FFT1DRealToComplexConjugateImageFilter. - void GenerateInputRequestedRegion() ITK_OVERRIDE; - void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - /** Component filters. */ - typedef AnalyticSignalImageFilter< InputImageType, ComplexImageType > AnalyticType; - typedef ComplexToModulusImageFilter< typename AnalyticType::OutputImageType, OutputImageType > ComplexToModulusType; - typedef ConstantPadImageFilter< InputImageType, InputImageType > PadType; - typedef RegionFromReferenceImageFilter< OutputImageType, OutputImageType > ROIType; - -private: - PhotoacousticBModeImageFilter( const Self& ); // purposely not implemented - void operator=( const Self& ); // purposely not implemented - - typename AnalyticType::Pointer m_AnalyticFilter; - typename ComplexToModulusType::Pointer m_ComplexToModulusFilter; - typename PadType::Pointer m_PadFilter; - typename ROIType::Pointer m_ROIFilter; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkPhotoacousticBModeImageFilter.hxx" -#endif - -#endif // itkPhotoacousticBModeImageFilter_h diff --git a/Modules/PhotoacousticsAlgorithms/ITKFilter/itkPhotoacousticBModeImageFilter.hxx b/Modules/PhotoacousticsAlgorithms/ITKFilter/itkPhotoacousticBModeImageFilter.hxx deleted file mode 100644 index cf58bf31eb..0000000000 --- a/Modules/PhotoacousticsAlgorithms/ITKFilter/itkPhotoacousticBModeImageFilter.hxx +++ /dev/null @@ -1,203 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkPhotoacousticBModeImageFilter_hxx -#define itkPhotoacousticBModeImageFilter_hxx - -#include "itkPhotoacousticBModeImageFilter.h" - -#include "itkMetaDataDictionary.h" - -#include -#include -#include - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::PhotoacousticBModeImageFilter() -{ - m_AnalyticFilter = AnalyticType::New(); - m_ComplexToModulusFilter = ComplexToModulusType::New(); - m_PadFilter = PadType::New(); - m_ROIFilter = ROIType::New(); - - m_PadFilter->SetConstant( 0. ); - m_ComplexToModulusFilter->SetInput( m_AnalyticFilter->GetOutput() ); - m_ROIFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - InputImageType * inputPtr = const_cast (this->GetInput()); - OutputImageType * outputPtr = this->GetOutput(); - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->GetDirection(); - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast< OutputImageType* >( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - const unsigned int direction = this->GetDirection (); - enlargedSize[direction] = outputLargeSize[direction]; - enlargedIndex[direction] = outputLargeIndex[direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::GenerateData() -{ - this->AllocateOutputs(); - - const InputImageType * inputPtr = this->GetInput(); - OutputImageType * outputPtr = this->GetOutput(); - - const unsigned int direction = m_AnalyticFilter->GetDirection(); - typename InputImageType::SizeType size = inputPtr->GetLargestPossibleRegion().GetSize(); - - // Zero padding. FFT direction should be factorable by 2 for all FFT - // implementations to work. - unsigned int n = size[direction]; - while( n % 2 == 0 ) - { - n /= 2; - } - bool doPadding; - if( n == 1 ) - { - doPadding = false; - } - else - { - doPadding = true; - } - if( doPadding ) - { - n = size[direction]; - unsigned int newSizeDirection = 1; - while( newSizeDirection < n ) - { - newSizeDirection *= 2; - } - typename InputImageType::SizeType padSize; - padSize.Fill( 0 ); - padSize[direction] = newSizeDirection - size[direction]; - size[direction] = newSizeDirection; - m_PadFilter->SetPadUpperBound( padSize ); - m_PadFilter->SetInput( inputPtr ); - m_AnalyticFilter->SetInput( m_PadFilter->GetOutput() ); - m_ROIFilter->SetReferenceImage( inputPtr ); - m_ROIFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); - m_ROIFilter->GraftOutput( outputPtr ); - m_ROIFilter->Update(); - this->GraftOutput( m_ROIFilter->GetOutput() ); - } - else // padding is not required - { - m_AnalyticFilter->SetInput( inputPtr ); - m_ComplexToModulusFilter->GraftOutput( outputPtr ); - m_ComplexToModulusFilter->Update(); - this->GraftOutput( m_ComplexToModulusFilter->GetOutput() ); - } - -} - -} // end namespace itk - -#endif diff --git a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/CMakeLists.txt b/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/CMakeLists.txt deleted file mode 100644 index ef003473c5..0000000000 --- a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -OPTION(BUILD_PhotoacousticBeamformingTool "Build MiniApp for beamforming of a PA image" OFF) - -IF(BUILD_PhotoacousticBeamformingTool) - PROJECT( MitkPABeamformingTool ) - mitk_create_executable(PABeamformingTool - DEPENDS MitkCommandLine MitkCore MitkPhotoacousticsAlgorithms - PACKAGE_DEPENDS tinyxml2|tinyxml2 - CPP_FILES PABeamformingTool.cpp) - - if(TARGET ${EXECUTABLE_TARGET}) - target_link_libraries(${MODULE_TARGET} - PRIVATE tinyxml2::tinyxml2 - ) - endif() - - install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) - ENDIF() diff --git a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/PABeamformingTool.cpp b/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/PABeamformingTool.cpp deleted file mode 100644 index 3fe1900be7..0000000000 --- a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/PABeamformingTool.cpp +++ /dev/null @@ -1,397 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -struct InputParameters -{ - mitk::Image::Pointer inputImage; - std::string outputFilename; - bool verbose; - std::string settingsFile; - std::string imageType; -}; - -struct BandpassSettings -{ - float highPass; - float lowPass; - float alphaLow; - float alphaHigh; - float speedOfSound; -}; - -struct CropSettings -{ - int above; - int below; - int right; - int left; - int zStart; - int zEnd; -}; - -struct ResampleSettings -{ - double spacing; - unsigned int dimX; -}; - -struct BModeSettings -{ - mitk::PhotoacousticFilterService::BModeMethod method; - bool UseLogFilter; -}; - -struct ProcessSettings -{ - bool DoBeamforming; - bool DoBandpass; - bool DoCropping; - bool DoResampling; - bool DoBmode; -}; - -InputParameters parseInput(int argc, char* argv[]) -{ - mitkCommandLineParser parser; - parser.setCategory("MITK-Photoacoustics"); - parser.setTitle("Mitk Photoacoustics Beamforming Tool"); - parser.setDescription("Reads a nrrd file as an input and applies a beamforming method as set with the parameters defined in an additionally provided xml file."); - parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); - - parser.setArgumentPrefix("--", "-"); - - parser.beginGroup("Required parameters"); - parser.addArgument( - "inputImage", "i", mitkCommandLineParser::Image, - "Input image (mitk::Image)", "input image (.nrrd file)", - us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "output", "o", mitkCommandLineParser::File, - "Output filename", "output image (.nrrd file)", - us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument( - "settings", "s", mitkCommandLineParser::String, - "settings file", "file containing beamforming and other specifications(.xml file)", - us::Any(), false); - parser.addArgument( - "type", "t", mitkCommandLineParser::String, - "image type", "Specifies whether to use the PA or US subsection of the xml file must be 'PA' or 'US'", - us::Any(), false); - parser.endGroup(); - - parser.beginGroup("Optional parameters"); - parser.addArgument( - "verbose", "v", mitkCommandLineParser::Bool, - "Verbose Output", "Whether to produce verbose, or rather debug output. (default: false)"); - parser.endGroup(); - - InputParameters input; - - std::map parsedArgs = parser.parseArguments(argc, argv); - if (parsedArgs.size() == 0) - exit(-1); - - input.verbose = (bool)parsedArgs.count("verbose"); - MITK_INFO(input.verbose) << "### VERBOSE OUTPUT ENABLED ###"; - - if (parsedArgs.count("inputImage")) - { - MITK_INFO(input.verbose) << "Reading input image..."; - input.inputImage = mitk::IOUtil::Load(us::any_cast(parsedArgs["inputImage"])); - MITK_INFO(input.verbose) << "Reading input image...[Done]"; - } - else - mitkThrow() << "No input image given."; - - if (parsedArgs.count("output")) - input.outputFilename = us::any_cast(parsedArgs["output"]); - else - mitkThrow() << "No output image path given.."; - - if (parsedArgs.count("settings")) - input.settingsFile = us::any_cast(parsedArgs["settings"]); - else - mitkThrow() << "No settings image path given.."; - - if (parsedArgs.count("type")) - input.imageType = us::any_cast(parsedArgs["type"]); - else - mitkThrow() << "No settings image type given.."; - - return input; -} - -TiXmlElement* getRootChild(TiXmlElement* root, std::string childName) -{ - for (TiXmlElement* elem = root->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement()) - { - if (elem->Value() == childName) - return elem; - } - return nullptr; -} - -void ParseXML(std::string xmlFile, InputParameters input, mitk::BeamformingSettings::Pointer *bfSet, BandpassSettings& bandpassSet, CropSettings& cropSet, ResampleSettings& resSet, BModeSettings& bmodeSet, ProcessSettings& processSet) -{ - MITK_INFO << "Loading configuration File \"" << xmlFile << "\""; - TiXmlDocument doc(xmlFile); - if (!doc.LoadFile()) - mitkThrow() << "Failed to load settings file \"" << xmlFile << "\" Error: " << doc.ErrorDesc(); - - TiXmlElement* root = doc.FirstChildElement(); - if (root == NULL) - { - mitkThrow() << "Failed to load file: No root element."; - doc.Clear(); - } - - TiXmlElement* elemtop = getRootChild(root, input.imageType); - if(elemtop == nullptr) - mitkThrow() << "The xml file is wrongly formatted, no element \"" << input.imageType << "\" found"; - - for (TiXmlElement* elem = elemtop->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement()) - { - std::string elemName = elem->Value(); - if (elemName == "Beamforming") - { - processSet.DoBeamforming = std::stoi(elem->Attribute("do")); - if (!processSet.DoBeamforming) - continue; - - float SpeedOfSound = std::stof(elem->Attribute("speedOfSoundMeterPerSecond")); - float PitchMeter = std::stof(elem->Attribute("pitchMilliMeter"))/1000; - float TimeSpacingMicroSecond = (float)(input.inputImage->GetGeometry()->GetSpacing()[1] / 1000000); - - if (std::stof(elem->Attribute("timeSpacingMicroSecond")) > 0) { - TimeSpacingMicroSecond = std::stof(elem->Attribute("timeSpacingMicroSecond")); - MITK_INFO << "TIME: " << TimeSpacingMicroSecond; - } - - float Angle = std::stof(elem->Attribute("apodizationAngle")); - bool IsPhotoacousticImage = true; - if (std::string(elem->Attribute("imageType")).compare("US") == 0) { - IsPhotoacousticImage = false; - MITK_INFO << "US IMAGE"; - } - - unsigned int SamplesPerLine = std::stoi(elem->Attribute("reconstructedYDimension")); - unsigned int ReconstructionLines = std::stoi(elem->Attribute("reconstructedXDimension")); - - - float ReconstructionDepth = std::stof(elem->Attribute("reconstructionDepthMeter")); - bool UseGPU = std::stoi(elem->Attribute("useGPU")); - unsigned int GPUBatchSize = std::stoi(elem->Attribute("GPUBatchSize")); - - std::string apodizationStr = elem->Attribute("apodizationFunction"); - mitk::BeamformingSettings::Apodization Apodization = mitk::BeamformingSettings::Apodization::Box; - if (apodizationStr == "Box") - Apodization = mitk::BeamformingSettings::Apodization::Box; - else if (apodizationStr == "Hann") - Apodization = mitk::BeamformingSettings::Apodization::Hann; - else if (apodizationStr == "Hamm") - Apodization = mitk::BeamformingSettings::Apodization::Hamm; - else - mitkThrow() << "Apodization incorrectly defined in settings"; - - std::string geomStr = elem->Attribute("probeGeometry"); - mitk::BeamformingSettings::ProbeGeometry ProbeGeometry = mitk::BeamformingSettings::ProbeGeometry::Linear; - if (geomStr == "linear") - ProbeGeometry = mitk::BeamformingSettings::ProbeGeometry::Linear; - else if(geomStr == "concave") - ProbeGeometry = mitk::BeamformingSettings::ProbeGeometry::Concave; - else - mitkThrow() << "geometry incorrectly defined in settings"; - - float radius = std::stof(elem->Attribute("radiusMilliMeter"))/1000; - - unsigned int ApodizationArraySize = ReconstructionLines; - - std::string algorithmStr = elem->Attribute("algorithm"); - mitk::BeamformingSettings::BeamformingAlgorithm Algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DAS; - if (algorithmStr == "DAS") - Algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DAS; - else if (algorithmStr == "DMAS") - Algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DMAS; - else if (algorithmStr == "sDMAS") - Algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::sDMAS; - else - mitkThrow() << "Beamforming algorithm incorrectly defined in settings"; - - *bfSet = mitk::BeamformingSettings::New( - PitchMeter, - SpeedOfSound, - TimeSpacingMicroSecond, - Angle, - IsPhotoacousticImage, - SamplesPerLine, - ReconstructionLines, - input.inputImage->GetDimensions(), - ReconstructionDepth, - UseGPU, - GPUBatchSize, - Apodization, - ApodizationArraySize, - Algorithm, - ProbeGeometry, - radius - ); - } - if (elemName == "Bandpass") - { - processSet.DoBandpass = std::stoi(elem->Attribute("do")); - if (!processSet.DoBandpass) - continue; - - bandpassSet.highPass = std::stof(elem->Attribute("highPass")); - bandpassSet.lowPass = std::stof(elem->Attribute("lowPass")); - bandpassSet.alphaLow = std::stof(elem->Attribute("alphaLow")); - bandpassSet.alphaHigh = std::stof(elem->Attribute("alphaHigh")); - } - if (elemName == "Cropping") - { - processSet.DoCropping = std::stoi(elem->Attribute("do")); - if (!processSet.DoCropping) - continue; - - cropSet.above = std::stoi(elem->Attribute("cutAbove")); - cropSet.below = std::stoi(elem->Attribute("cutBelow")); - cropSet.right = std::stoi(elem->Attribute("cutRight")); - cropSet.left = std::stoi(elem->Attribute("cutLeft")); - cropSet.zStart = std::stoi(elem->Attribute("firstSlice")); - cropSet.zEnd = std::stoi(elem->Attribute("cutSlices")); - } - if (elemName == "Resampling") - { - processSet.DoResampling = std::stoi(elem->Attribute("do")); - if (!processSet.DoResampling) - continue; - - resSet.spacing = std::stod(elem->Attribute("spacing")); - resSet.dimX = std::stoi(elem->Attribute("dimX")); - } - if (elemName == "BMode") - { - processSet.DoBmode = std::stoi(elem->Attribute("do")); - if (!processSet.DoBmode) - continue; - - std::string methodStr = elem->Attribute("method"); - if (methodStr == "EnvelopeDetection") - bmodeSet.method = mitk::PhotoacousticFilterService::BModeMethod::EnvelopeDetection; - else if (methodStr == "Abs") - bmodeSet.method = mitk::PhotoacousticFilterService::BModeMethod::Abs; - else - mitkThrow() << "BMode method incorrectly set in configuration file"; - bmodeSet.UseLogFilter = (bool)std::stoi(elem->Attribute("useLogFilter")); - } - } -} - -int main(int argc, char * argv[]) -{ - auto input = parseInput(argc, argv); - - mitk::BeamformingSettings::Pointer bfSettings; - BandpassSettings bandpassSettings{5,10,1,1,1540}; - BModeSettings bmodeSettings{ mitk::PhotoacousticFilterService::BModeMethod::EnvelopeDetection, false }; - CropSettings cropSettings{ 0,0,0,0,0,0 }; - ResampleSettings resSettings{ 0.15 , 256}; - ProcessSettings processSettings{ false, false, false, false, false }; - - MITK_INFO << "Parsing settings XML..."; - try - { - ParseXML(input.settingsFile, input, &bfSettings, bandpassSettings, cropSettings, resSettings, bmodeSettings, processSettings); - } - catch (mitk::Exception e) - { - MITK_INFO << e; - return -1; - } - - MITK_INFO << "Parsing settings XML...[Done]"; - - MITK_INFO(input.verbose) << "Beamforming input image..."; - mitk::Image::Pointer inputImage = input.inputImage; - if (!(inputImage->GetPixelType().GetTypeAsString() == "scalar (float)" || inputImage->GetPixelType().GetTypeAsString() == " (float)")) - { - // we need a float image, so cast it here - MITK_INFO(input.verbose) << "Casting input image to float..."; - mitk::CastToFloatImageFilter::Pointer castFilter = mitk::CastToFloatImageFilter::New(); - castFilter->SetInput(inputImage); - castFilter->Update(); - inputImage = castFilter->GetOutput(); - MITK_INFO << inputImage->GetPixelType().GetPixelTypeAsString(); - MITK_INFO(input.verbose) << "Casting input image to float...[Done]"; - } - - mitk::PhotoacousticFilterService::Pointer m_FilterService = mitk::PhotoacousticFilterService::New(); - - mitk::Image::Pointer output = inputImage; - if (processSettings.DoBandpass) - { - MITK_INFO(input.verbose) << "Bandpassing input image..."; - output = m_FilterService->ApplyBandpassFilter(output, bandpassSettings.highPass*1e6, bandpassSettings.lowPass*1e6, bandpassSettings.alphaHigh, bandpassSettings.alphaLow, 1, bandpassSettings.speedOfSound, true); - MITK_INFO(input.verbose) << "Bandpassing input image...[Done]"; - } - if (processSettings.DoBeamforming) - { - MITK_INFO(input.verbose) << "Beamforming input image..."; - output = m_FilterService->ApplyBeamforming(output, bfSettings); - MITK_INFO(input.verbose) << "Beamforming input image...[Done]"; - } - if (processSettings.DoCropping) - { - int err; - MITK_INFO(input.verbose) << "Applying Crop filter to image..."; - output = m_FilterService->ApplyCropping(output, - cropSettings.above, cropSettings.below, cropSettings.right, cropSettings.left, cropSettings.zStart, cropSettings.zEnd, &err); - MITK_INFO(input.verbose) << "Applying Crop filter to image...[Done]"; - } - if (processSettings.DoBmode) - { - MITK_INFO(input.verbose) << "Applying BModeFilter to image..."; - output = m_FilterService->ApplyBmodeFilter(output, bmodeSettings.method, bmodeSettings.UseLogFilter); - MITK_INFO(input.verbose) << "Applying BModeFilter to image...[Done]"; - } - if (processSettings.DoResampling) - { - double spacing[3] = { output->GetGeometry()->GetSpacing()[0] * output->GetDimension(0) / resSettings.dimX, resSettings.spacing, output->GetGeometry()->GetSpacing()[2] }; - MITK_INFO(input.verbose) << "Applying Resample filter to image..."; - output = m_FilterService->ApplyResampling(output, spacing); - if (output->GetDimension(0) != resSettings.dimX) - { - double dim[3] = { (double)resSettings.dimX, (double)output->GetDimension(1), (double)output->GetDimension(2) }; - output = m_FilterService->ApplyResamplingToDim(output, dim); - } - MITK_INFO(input.verbose) << "Applying Resample filter to image...[Done]"; - } - - MITK_INFO(input.verbose) << "Saving image..."; - mitk::IOUtil::Save(output, input.outputFilename); - MITK_INFO(input.verbose) << "Saving image...[Done]"; - - MITK_INFO(input.verbose) << "Beamforming input image...[Done]"; -} diff --git a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/files.cmake b/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/files.cmake deleted file mode 100644 index 1bed148e42..0000000000 --- a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/files.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CPP_FILES - PABeamformingTool.cpp -) diff --git a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/name.options.xml b/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/name.options.xml deleted file mode 100644 index ec367585b5..0000000000 --- a/Modules/PhotoacousticsAlgorithms/MitkPABeamformingTool/name.options.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/CMakeLists.txt b/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/CMakeLists.txt deleted file mode 100644 index 517752db0d..0000000000 --- a/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -OPTION(BUILD_PhotoacousticResampleCropTool "Build MiniApp for resampling and cropping of images" OFF) - -IF(BUILD_PhotoacousticResampleCropTool) - PROJECT( MitkPAResampleCropTool ) - mitk_create_executable(PAResampleCropTool - DEPENDS MitkCommandLine MitkCore MitkPhotoacousticsAlgorithms - PACKAGE_DEPENDS tinyxml2|tinyxml2 - CPP_FILES PAResampleCropTool.cpp) - - if(TARGET ${EXECUTABLE_TARGET}) - target_link_libraries(${MODULE_TARGET} - PRIVATE tinyxml2::tinyxml2 - ) - endif() - - install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) - ENDIF() diff --git a/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/PAResampleCropTool.cpp b/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/PAResampleCropTool.cpp deleted file mode 100644 index 7fef39afe0..0000000000 --- a/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/PAResampleCropTool.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -struct InputParameters -{ - mitk::Image::Pointer inputImage; - std::string outputFilename; - bool verbose; - std::string settingsFile; -}; - -struct CropSettings -{ - unsigned int dimX; - unsigned int dimY; - unsigned int cutAbove; -}; - -struct ResamplingSettings -{ - double spacing[3]; -}; - - -InputParameters parseInput(int argc, char* argv[]) -{ - mitkCommandLineParser parser; - parser.setCategory("MITK-Photoacoustics"); - parser.setTitle("Mitk Photoacoustics Resample and Crop Tool"); - parser.setDescription("Reads a nrrd file as an input and crops and resamples it as set with the parameters defined in an additionally provided xml file."); - parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); - - parser.setArgumentPrefix("--", "-"); - - parser.beginGroup("Required parameters"); - parser.addArgument( - "inputImage", "i", mitkCommandLineParser::Image, - "Input image (mitk::Image)", "input image (.nrrd file)", - us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "output", "o", mitkCommandLineParser::File, - "Output filename", "output image (.nrrd file)", - us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.addArgument( - "settings", "s", mitkCommandLineParser::String, - "settings file", "file containing specifications (.xml file)", - us::Any(), false); - parser.endGroup(); - - parser.beginGroup("Optional parameters"); - parser.addArgument( - "verbose", "v", mitkCommandLineParser::Bool, - "Verbose Output", "Whether to produce verbose, or rather debug output. (default: false)"); - parser.endGroup(); - - InputParameters input; - - std::map parsedArgs = parser.parseArguments(argc, argv); - if (parsedArgs.size() == 0) - exit(-1); - - input.verbose = (bool)parsedArgs.count("verbose"); - MITK_INFO(input.verbose) << "### VERBOSE OUTPUT ENABLED ###"; - - if (parsedArgs.count("inputImage")) - { - MITK_INFO(input.verbose) << "Reading input image..."; - input.inputImage = mitk::IOUtil::Load(us::any_cast(parsedArgs["inputImage"])); - MITK_INFO(input.verbose) << "Reading input image...[Done]"; - } - else - mitkThrow() << "No input image given."; - - if (parsedArgs.count("output")) - input.outputFilename = us::any_cast(parsedArgs["output"]); - else - mitkThrow() << "No output image path given.."; - - if (parsedArgs.count("settings")) - input.settingsFile = us::any_cast(parsedArgs["settings"]); - else - mitkThrow() << "No settings image path given.."; - - return input; -} - -void ParseXML(std::string xmlFile, InputParameters input, CropSettings& cropSet, ResamplingSettings& resSet) -{ - MITK_INFO << "Loading configuration File \"" << xmlFile << "\""; - TiXmlDocument doc(xmlFile); - if (!doc.LoadFile()) - mitkThrow() << "Failed to load settings file \"" << xmlFile << "\" Error: " << doc.ErrorDesc(); - - TiXmlElement* root = doc.FirstChildElement(); - if (root == NULL) - { - mitkThrow() << "Failed to load file: No root element."; - doc.Clear(); - } - for (TiXmlElement* elem = root->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement()) - { - std::string elemName = elem->Value(); - if (elemName == "ResampleCrop") - { - cropSet.dimX = std::stoi(elem->Attribute("dimX")); - cropSet.dimY = std::stoi(elem->Attribute("dimY")); - cropSet.cutAbove = std::stoi(elem->Attribute("cutAbove")); - resSet.spacing[0] = std::stod(elem->Attribute("spacingX")); - resSet.spacing[1] = std::stod(elem->Attribute("spacingY")); - resSet.spacing[2] = std::stod(elem->Attribute("spacingZ")); - } - } -} - -int main(int argc, char * argv[]) -{ - auto input = parseInput(argc, argv); - - CropSettings cropSettings{ 0,0,0 }; - ResamplingSettings resSettings{ 0 }; - - MITK_INFO << "Parsing settings XML..."; - try - { - ParseXML(input.settingsFile, input, cropSettings, resSettings); - } - catch (mitk::Exception e) - { - MITK_INFO << e; - return -1; - } - - MITK_INFO << "Parsing settings XML...[Done]"; - - MITK_INFO(input.verbose) << "Processing input image..."; - - mitk::PhotoacousticFilterService::Pointer m_FilterService = mitk::PhotoacousticFilterService::New(); - - mitk::Image::Pointer output = input.inputImage; - MITK_INFO(input.verbose) << "Resampling input image..."; - MITK_INFO << resSettings.spacing[0]; - output = m_FilterService->ApplyResampling(output, resSettings.spacing); - MITK_INFO(input.verbose) << "Resampling input image...[Done]"; - - if (output->GetDimension(0) != cropSettings.dimX) - { - double outputDim[] = {(double)cropSettings.dimX, (double)output->GetDimension(1), (double)output->GetDimension(2)}; - output = m_FilterService->ApplyResamplingToDim(output, outputDim); - } - - int err = 0; - int below = output->GetDimension(1) - cropSettings.dimY - cropSettings.cutAbove; - if (below < 0) - { - MITK_INFO(input.verbose) << "Extending input image..."; - output = m_FilterService->ExtendImage(output, 0, cropSettings.dimY); - MITK_INFO(input.verbose) << "Extending input image...[Done]"; - } - else - { - MITK_INFO(input.verbose) << "Cropping input image..."; - output = m_FilterService->ApplyCropping(output, cropSettings.cutAbove, below, 0, 0, 0, 0, &err); - MITK_INFO(input.verbose) << "Cropping input image...[Done]"; - } - - - MITK_INFO(input.verbose) << "Saving image..."; - mitk::IOUtil::Save(output, input.outputFilename); - MITK_INFO(input.verbose) << "Saving image...[Done]"; - - MITK_INFO(input.verbose) << "Processing input image...[Done]"; -} diff --git a/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/files.cmake b/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/files.cmake deleted file mode 100644 index f8bb3ffe66..0000000000 --- a/Modules/PhotoacousticsAlgorithms/MitkPAResampleCropTool/files.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CPP_FILES - PAResampleCropTool.cpp -) diff --git a/Modules/PhotoacousticsAlgorithms/Resources/DAS.cl b/Modules/PhotoacousticsAlgorithms/Resources/DAS.cl deleted file mode 100644 index b814242b05..0000000000 --- a/Modules/PhotoacousticsAlgorithms/Resources/DAS.cl +++ /dev/null @@ -1,120 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -__kernel void ckDAS( - __global float* dSource, // input image - __global float* dDest, // output buffer - __global unsigned short* usedLines, - __global unsigned short* delays, - __constant float* apodArray, - unsigned short apodArraySize, - unsigned int inputL, - unsigned int inputS, - unsigned int Slices, - unsigned int outputL, - unsigned int outputS // parameters -) -{ - // get thread identifier - unsigned int globalPosX = get_global_id(0); - unsigned int globalPosY = get_global_id(1); - unsigned int globalPosZ = get_global_id(2); - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS && globalPosZ < Slices ) - { - float l_i = (float)globalPosX / (float)outputL * (float)inputL; - - unsigned short curUsedLines = usedLines[globalPosY * 3 * outputL + 3 * globalPosX]; - unsigned short minLine = usedLines[globalPosY * 3 * outputL + 3 * globalPosX + 1]; - unsigned short maxLine = usedLines[globalPosY * 3 *outputL + 3 * globalPosX + 2]; - - float apod_mult = (float)apodArraySize / (float)curUsedLines; - - unsigned short Delay = 0; - - float output = 0; - float mult = 0; - - for (short l_s = minLine; l_s < maxLine; ++l_s) - { - Delay = delays[globalPosY * (outputL / 2) + (int)(fabs(l_s - l_i)/(float)inputL * (float)outputL)]; - if (Delay < inputS && Delay >= 0) { - output += apodArray[(int)((l_s - minLine)*apod_mult)] * dSource[(int)(globalPosZ * inputL * inputS + Delay * inputL + l_s)]; - } - else - --curUsedLines; - } - - dDest[ globalPosZ * outputL * outputS + globalPosY * outputL + globalPosX ] = output / (float)curUsedLines; - } -} - -__kernel void ckDAS_g( - __global float* dSource, // input image - __global float* dDest, // output buffer - __global float* elementHeights, - __global float* elementPositions, - __constant float* apodArray, - unsigned short apodArraySize, - unsigned int inputL, - unsigned int inputS, - int Slices, - int outputL, - int outputS, - float totalSamples_i, - float horizontalExtent, - float mult, - char isPAImage, - __global unsigned short* usedLines // parameters -) -{ - // get thread identifier - int globalPosX = get_global_id(0); - int globalPosY = get_global_id(1); - int globalPosZ = get_global_id(2); - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS && globalPosZ < Slices ) - { - int AddSample = 0; - float l_p = 0; - float s_i = 0; - - float apod_mult = 1; - - float output = 0; - - l_p = (float)globalPosX / outputL * horizontalExtent; - s_i = (float)globalPosY / outputS * totalSamples_i; - - unsigned short curUsedLines = usedLines[globalPosY * 3 * outputL + 3 * globalPosX]; - unsigned short minLine = usedLines[globalPosY * 3 * outputL + 3 * globalPosX + 1]; - unsigned short maxLine = usedLines[globalPosY * 3 *outputL + 3 * globalPosX + 2]; - - apod_mult = (float)apodArraySize / curUsedLines; - - for (int l_s = minLine; l_s < maxLine; ++l_s) - { - AddSample = (int)sqrt( - pow(s_i-elementHeights[l_s]*mult, 2) - + - pow(mult * (l_p - elementPositions[l_s]), 2) - ) + (1 - isPAImage)*s_i; - if (AddSample < inputS && AddSample >= 0) - output += dSource[(int)(globalPosZ * inputL * inputS + l_s + AddSample*inputL)] * apodArray[(int)((l_s - minLine)*apod_mult)]; - else - --curUsedLines; - } - dDest[ globalPosZ * outputL * outputS + globalPosY * outputL + globalPosX ] = output / curUsedLines; - } -} diff --git a/Modules/PhotoacousticsAlgorithms/Resources/DMAS.cl b/Modules/PhotoacousticsAlgorithms/Resources/DMAS.cl deleted file mode 100644 index a4fecfda31..0000000000 --- a/Modules/PhotoacousticsAlgorithms/Resources/DMAS.cl +++ /dev/null @@ -1,163 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -__kernel void ckDMAS( - __global float* dSource, // input image - __global float* dDest, // output buffer - __global unsigned short* usedLines, - __global unsigned short* AddSamples, - __constant float* apodArray, - unsigned short apodArraySize, - unsigned int inputL, - unsigned int inputS, - unsigned int Slices, - unsigned int outputL, - unsigned int outputS // parameters -) -{ - // get thread identifier - unsigned int globalPosX = get_global_id(0); - unsigned int globalPosY = get_global_id(1); - unsigned int globalPosZ = get_global_id(2); - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS && globalPosZ < Slices ) - { - float l_i = (float)globalPosX / (float)outputL * (float)inputL; - - unsigned short curUsedLines = usedLines[globalPosY * 3 * outputL + 3 * globalPosX]; - unsigned short minLine = usedLines[globalPosY * 3 * outputL + 3 * globalPosX + 1]; - unsigned short maxLine = usedLines[globalPosY * 3 *outputL + 3 * globalPosX + 2]; - - float apod_mult = (float)apodArraySize / (float)curUsedLines; - - unsigned short Delay1 = 0; - unsigned short Delay2 = 0; - - float output = 0; - float mult = 0; - - float s_1 = 0; - float s_2 = 0; - float apod_1 = 0; - - for (short l_s1 = minLine; l_s1 < maxLine; ++l_s1) - { - Delay1 = AddSamples[globalPosY * (outputL / 2) + (int)(fabs(l_s1 - l_i)/(float)inputL * (float)outputL)]; - if (Delay1 < inputS && Delay1 >= 0) - { - s_1 = dSource[(int)(globalPosZ * inputL * inputS + Delay1 * inputL + l_s1)]; - apod_1 = apodArray[(int)((l_s1 - minLine)*apod_mult)]; - - for (short l_s2 = l_s1 + 1; l_s2 < maxLine; ++l_s2) - { - Delay2 = AddSamples[globalPosY * (outputL / 2) + (int)(fabs(l_s2 - l_i)/(float)inputL * (float)outputL)]; - if (Delay2 < inputS && Delay2 >= 0) - { - s_2 = dSource[(int)(globalPosZ * inputL * inputS + Delay2 * inputL + l_s2)]; - - mult = apodArray[(int)((l_s2 - minLine)*apod_mult)] * s_2 * apod_1 * s_1; - - output += sqrt(fabs(mult)) * sign(mult); - } - } - } - else - --curUsedLines; - } - - dDest[ globalPosZ * outputL * outputS + globalPosY * outputL + globalPosX ] = output / (float)(curUsedLines * curUsedLines - (curUsedLines - 1)); - } -} - -__kernel void ckDMAS_g( - __global float* dSource, // input image - __global float* dDest, // output buffer - __global float* elementHeights, - __global float* elementPositions, - __constant float* apodArray, - unsigned short apodArraySize, - unsigned int inputL, - unsigned int inputS, - int Slices, - int outputL, - int outputS, - float totalSamples_i, - float horizontalExtent, - float mult, - char isPAImage, - __global unsigned short* usedLines // parameters -) -{ - // get thread identifier - int globalPosX = get_global_id(0); - int globalPosY = get_global_id(1); - int globalPosZ = get_global_id(2); - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS && globalPosZ < Slices ) - { - int AddSample1 = 0; - int AddSample2 = 0; - - float output = 0; - - float s_1 = 0; - float s_2 = 0; - float apod_1 = 0; - - float l_p = (float)globalPosX / outputL * horizontalExtent; - float s_i = (float)globalPosY / outputS * totalSamples_i; - - unsigned short curUsedLines = usedLines[globalPosY * 3 * outputL + 3 * globalPosX]; - unsigned short minLine = usedLines[globalPosY * 3 * outputL + 3 * globalPosX + 1]; - unsigned short maxLine = usedLines[globalPosY * 3 *outputL + 3 * globalPosX + 2]; - - float apod_mult = (float)apodArraySize / curUsedLines; - - float multiplication = 0; - - for (int l_s1 = minLine; l_s1 < maxLine; ++l_s1) - { - AddSample1 = (int)sqrt( - pow(s_i-elementHeights[l_s1]*mult, 2) - + - pow(mult * (l_p - elementPositions[l_s1]), 2) - ) + (1 - isPAImage)*s_i; - - if (AddSample1 < inputS && AddSample1 >= 0) - { - s_1 = dSource[(int)(globalPosZ * inputL * inputS + AddSample1 * inputL + l_s1)]; - apod_1 = apodArray[(int)((l_s1 - minLine)*apod_mult)]; - - for (int l_s2 = minLine; l_s2 < maxLine; ++l_s2) - { - AddSample2 = (int)sqrt( - pow(s_i-elementHeights[l_s2]*mult, 2) - + - pow(mult * (l_p - elementPositions[l_s2]), 2) - ) + (1 - isPAImage)*s_i; - if (AddSample2 < inputS && AddSample2 >= 0) - { - s_2 = dSource[(int)(globalPosZ * inputL * inputS + AddSample2 * inputL + l_s2)]; - multiplication = apodArray[(int)((l_s2 - minLine)*apod_mult)] * s_2 * apod_1 * s_1; - - output += sqrt(fabs(multiplication)) * sign(multiplication); - } - } - } - else - --curUsedLines; - } - dDest[ globalPosZ * outputL * outputS + globalPosY * outputL + globalPosX ] = output / (float)(pow((float)curUsedLines, 2) - (curUsedLines - 1)); - } -} diff --git a/Modules/PhotoacousticsAlgorithms/Resources/DelayCalculation.cl b/Modules/PhotoacousticsAlgorithms/Resources/DelayCalculation.cl deleted file mode 100644 index 0ecda5781e..0000000000 --- a/Modules/PhotoacousticsAlgorithms/Resources/DelayCalculation.cl +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -__kernel void ckDelayCalculationSphe( __global unsigned short *gDest, - __global unsigned short *usedLines, - unsigned int inputL, - unsigned int inputS, - unsigned int outputL, - unsigned int outputS, - char isPAImage, - float delayMultiplicatorRaw, - float totalSamples_i // parameters - ) -{ - uint globalPosX = get_global_id(0); - uint globalPosY = get_global_id(1); - - if (globalPosX * 2 < outputL && globalPosY < outputS) - { - float l_i = 0; // we calculate the delays relative to line zero - float s_i = (float)globalPosY / (float)outputS * totalSamples_i; - float l_s = (float)globalPosX / (float)outputL * (float)inputL; // the currently calculated line - - gDest[globalPosY * (outputL / 2) + globalPosX] = - sqrt( - pow(s_i, 2) - + - pow((delayMultiplicatorRaw * ((l_s - l_i)) / inputL), 2) - ) + (1-isPAImage)*s_i; - } -} diff --git a/Modules/PhotoacousticsAlgorithms/Resources/UsedLinesCalculation.cl b/Modules/PhotoacousticsAlgorithms/Resources/UsedLinesCalculation.cl deleted file mode 100644 index 46d4629000..0000000000 --- a/Modules/PhotoacousticsAlgorithms/Resources/UsedLinesCalculation.cl +++ /dev/null @@ -1,128 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -__kernel void ckUsedLines( - __global unsigned short* dDest, // output buffer - float partMult, - unsigned int inputL, - unsigned int inputS, - unsigned int outputL, - unsigned int outputS, - float totalSamples_i // parameters -) -{ - // get thread identifier - unsigned int globalPosX = get_global_id(0); - unsigned int globalPosY = get_global_id(1); - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS) - { - float l_i = (float)globalPosX / outputL * inputL; - float s_i = (float)globalPosY / (float)outputS * totalSamples_i; - - float part = partMult * s_i; - if (part < 1) - part = 1; - - unsigned short maxLine = min((l_i + part) + 1, (float)inputL); - unsigned short minLine = max((l_i - part), 0.0f); - - dDest[globalPosY * 3 * outputL + 3 * globalPosX] = (maxLine - minLine); //usedLines - dDest[globalPosY * 3 * outputL + 3 * globalPosX + 1] = minLine; //minLine - dDest[globalPosY * 3 * outputL + 3 * globalPosX + 2] = maxLine; //maxLine - } -} - -__kernel void ckUsedLines_g( - __global unsigned short* dDest, // output buffer - __global float* elementHeights, - __global float* elementPositions, - float sin_deg, - float probeRadius, - unsigned int inputL, - unsigned int inputS, - unsigned int outputL, - unsigned int outputS, - float horizontalExtent, - float verticalExtent -) -{ - // get thread identifier - unsigned int globalPosX = get_global_id(0); - unsigned int globalPosY = get_global_id(1); - - float x_sensor_pos = 0; - float y_sensor_pos = 0; - float center_to_sensor_a = 0; - float center_to_sensor_b = 0; - float center_to_sensor_c = 0; - float distance_to_sensor_direction = 0; - float distance_sensor_target = 0; - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS) - { - float x_cm = (float)globalPosX / outputL * horizontalExtent; // x*Xspacing - float y_cm = (float)globalPosY / (float)outputS * verticalExtent; // y*Yspacing - - int maxLine = inputL; - int minLine = 0; - - float x_center_pos = horizontalExtent / 2.0; - float y_center_pos = probeRadius; - - for (int l_s = minLine; l_s <= inputL; l_s += 1) - { - x_sensor_pos = elementPositions[l_s]; - y_sensor_pos = elementHeights[l_s]; - - distance_sensor_target = sqrt((x_cm - x_sensor_pos)*(x_cm - x_sensor_pos) + (y_cm - y_sensor_pos)*(y_cm - y_sensor_pos)); - - // solving line equation - center_to_sensor_a = y_sensor_pos - y_center_pos; - center_to_sensor_b = x_center_pos - x_sensor_pos; - center_to_sensor_c = -(center_to_sensor_a * x_center_pos + center_to_sensor_b * y_center_pos); - distance_to_sensor_direction = fabs((center_to_sensor_a * x_cm + center_to_sensor_b * y_cm + center_to_sensor_c)) / (sqrt(center_to_sensor_a*center_to_sensor_a + center_to_sensor_b*center_to_sensor_b)); - - if (distance_to_sensor_direction < (sin_deg*distance_sensor_target)) - { - minLine = l_s; - break; - } - } - - for (int l_s = maxLine - 1; l_s > minLine; l_s -= 1) // start with maxline-1 otherwise elementPositions[] will go out of range - { - x_sensor_pos = elementPositions[l_s]; - y_sensor_pos = elementHeights[l_s]; - - distance_sensor_target = sqrt((x_cm - x_sensor_pos)*(x_cm - x_sensor_pos) + (y_cm - y_sensor_pos)*(y_cm - y_sensor_pos)); - - // solving line equation - center_to_sensor_a = y_sensor_pos - y_center_pos; - center_to_sensor_b = x_center_pos - x_sensor_pos; - center_to_sensor_c = -(center_to_sensor_a * x_center_pos + center_to_sensor_b * y_center_pos); - distance_to_sensor_direction = fabs((center_to_sensor_a * x_cm + center_to_sensor_b * y_cm + center_to_sensor_c)) / (sqrt(center_to_sensor_a*center_to_sensor_a + center_to_sensor_b*center_to_sensor_b)); - - if (distance_to_sensor_direction < sin_deg*distance_sensor_target) - { - maxLine = l_s; - break; - } - } - - dDest[globalPosY * 3 * outputL + 3 * globalPosX] = (maxLine - minLine); //usedLines - dDest[globalPosY * 3 * outputL + 3 * globalPosX + 1] = minLine; //minLine - dDest[globalPosY * 3 * outputL + 3 * globalPosX + 2] = maxLine; //maxLine - } -} diff --git a/Modules/PhotoacousticsAlgorithms/Resources/sDMAS.cl b/Modules/PhotoacousticsAlgorithms/Resources/sDMAS.cl deleted file mode 100644 index ab37ae7e0a..0000000000 --- a/Modules/PhotoacousticsAlgorithms/Resources/sDMAS.cl +++ /dev/null @@ -1,167 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -__kernel void cksDMAS( - __global float* dSource, // input image - __global float* dDest, // output buffer - __global unsigned short* usedLines, - __global unsigned short* AddSamples, - __constant float* apodArray, - unsigned short apodArraySize, - unsigned int inputL, - unsigned int inputS, - unsigned int Slices, - unsigned int outputL, - unsigned int outputS // parameters -) -{ - // get thread identifier - unsigned int globalPosX = get_global_id(0); - unsigned int globalPosY = get_global_id(1); - unsigned int globalPosZ = get_global_id(2); - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS && globalPosZ < Slices ) - { - float l_i = (float)globalPosX / (float)outputL * (float)inputL; - - unsigned short curUsedLines = usedLines[globalPosY * 3 * outputL + 3 * globalPosX]; - unsigned short minLine = usedLines[globalPosY * 3 * outputL + 3 * globalPosX + 1]; - unsigned short maxLine = usedLines[globalPosY * 3 *outputL + 3 * globalPosX + 2]; - - float apod_mult = (float)apodArraySize / (float)curUsedLines; - - unsigned short Delay1 = 0; - unsigned short Delay2 = 0; - - float output = 0; - float mult = 0; - - float s_1 = 0; - float s_2 = 0; - float dSign = 0; - float apod_1 = 0; - - for (short l_s1 = minLine; l_s1 < maxLine; ++l_s1) - { - Delay1 = AddSamples[globalPosY * (outputL / 2) + (int)(fabs(l_s1 - l_i)/(float)inputL * (float)outputL)]; - if (Delay1 < inputS && Delay1 >= 0) - { - s_1 = dSource[(int)(globalPosZ * inputL * inputS + Delay1 * inputL + l_s1)]; - apod_1 = apodArray[(int)((l_s1 - minLine)*apod_mult)]; - dSign += s_1; - - for (short l_s2 = l_s1 + 1; l_s2 < maxLine; ++l_s2) - { - Delay2 = AddSamples[globalPosY * (outputL / 2) + (int)(fabs(l_s2 - l_i)/(float)inputL * (float)outputL)]; - if (Delay2 < inputS && Delay2 >= 0) - { - s_2 = dSource[(int)(globalPosZ * inputL * inputS + Delay2 * inputL + l_s2)]; - - mult = apodArray[(int)((l_s2 - minLine)*apod_mult)] * s_2 * apod_1 * s_1; - - output += sqrt(fabs(mult)) * ((mult > 0) - (mult < 0)); - } - } - } - else - --curUsedLines; - } - - dDest[ globalPosZ * outputL * outputS + globalPosY * outputL + globalPosX ] = output / (float)(curUsedLines * curUsedLines - (curUsedLines - 1)) * sign(dSign); - } -} - -__kernel void cksDMAS_g( - __global float* dSource, // input image - __global float* dDest, // output buffer - __global float* elementHeights, - __global float* elementPositions, - __constant float* apodArray, - unsigned short apodArraySize, - unsigned int inputL, - unsigned int inputS, - int Slices, - int outputL, - int outputS, - float totalSamples_i, - float horizontalExtent, - float mult, - char isPAImage, - __global unsigned short* usedLines // parameters -) -{ - // get thread identifier - int globalPosX = get_global_id(0); - int globalPosY = get_global_id(1); - int globalPosZ = get_global_id(2); - - // terminate non-valid threads - if ( globalPosX < outputL && globalPosY < outputS && globalPosZ < Slices ) - { - int AddSample1 = 0; - int AddSample2 = 0; - - float output = 0; - - float s_1 = 0; - float s_2 = 0; - float apod_1 = 0; - - float l_p = (float)globalPosX / outputL * horizontalExtent; - float s_i = (float)globalPosY / outputS * totalSamples_i; - - unsigned short curUsedLines = usedLines[globalPosY * 3 * outputL + 3 * globalPosX]; - unsigned short minLine = usedLines[globalPosY * 3 * outputL + 3 * globalPosX + 1]; - unsigned short maxLine = usedLines[globalPosY * 3 *outputL + 3 * globalPosX + 2]; - - float apod_mult = (float)apodArraySize / curUsedLines; - float dSign = 0; - - float multiplication = 0; - - for (int l_s1 = minLine; l_s1 < maxLine; ++l_s1) - { - AddSample1 = (int)sqrt( - pow(s_i-elementHeights[l_s1]*mult, 2) - + - pow(mult * (l_p - elementPositions[l_s1]), 2) - ) + (1 - isPAImage)*s_i; - - if (AddSample1 < inputS && AddSample1 >= 0) - { - s_1 = dSource[(int)(globalPosZ * inputL * inputS + AddSample1 * inputL + l_s1)]; - apod_1 = apodArray[(int)((l_s1 - minLine)*apod_mult)]; - dSign += s_1; - - for (int l_s2 = minLine; l_s2 < maxLine; ++l_s2) - { - AddSample2 = (int)sqrt( - pow(s_i-elementHeights[l_s2]*mult, 2) - + - pow(mult * (l_p - elementPositions[l_s2]), 2) - ) + (1 - isPAImage)*s_i; - if (AddSample2 < inputS && AddSample2 >= 0) - { - s_2 = dSource[(int)(globalPosZ * inputL * inputS + AddSample2 * inputL + l_s2)]; - multiplication = apodArray[(int)((l_s2 - minLine)*apod_mult)] * s_2 * apod_1 * s_1; - - output += sqrt(fabs(multiplication)) * sign(multiplication); - } - } - } - else - --curUsedLines; - } - dDest[ globalPosZ * outputL * outputS + globalPosY * outputL + globalPosX ] = output / (float)(pow((float)curUsedLines, 2) - (curUsedLines - 1)) * sign(dSign); - } -} diff --git a/Modules/PhotoacousticsAlgorithms/files.cmake b/Modules/PhotoacousticsAlgorithms/files.cmake deleted file mode 100644 index 87f8116092..0000000000 --- a/Modules/PhotoacousticsAlgorithms/files.cmake +++ /dev/null @@ -1,31 +0,0 @@ - -file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") - -set(CPP_FILES - source/filters/mitkBeamformingFilter.cpp - source/filters/mitkBeamformingSettings.cpp - source/filters/mitkImageSliceSelectionFilter.cpp - source/filters/mitkCastToFloatImageFilter.cpp - source/filters/mitkCropImageFilter.cpp - source/filters/mitkBandpassFilter.cpp - source/OpenCLFilter/mitkPhotoacousticBModeFilter.cpp - source/utils/mitkPhotoacousticFilterService.cpp - source/utils/mitkBeamformingUtils.cpp - source/mitkPhotoacousticMotionCorrectionFilter.cpp -) - -IF(MITK_USE_OpenCL) -list(APPEND CPP_FILES - source/OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.cpp - source/OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.cpp - source/OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.cpp -) -ENDIF(MITK_USE_OpenCL) - -set(RESOURCE_FILES - UsedLinesCalculation.cl - DelayCalculation.cl - DMAS.cl - DAS.cl - sDMAS.cl -) diff --git a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticBModeFilter.h b/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticBModeFilter.h deleted file mode 100644 index 63c239e9f3..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticBModeFilter.h +++ /dev/null @@ -1,63 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef _MITKPHOTOACOUSTICSBMODEFILTER_H_ -#define _MITKPHOTOACOUSTICSBMODEFILTER_H_ - -#include -#include "mitkImageToImageFilter.h" - -namespace mitk -{ - /*! - * \brief Class implementing a mitk::ImageToImageFilter for BMode filtering on CPU - * - * The only parameter that needs to be provided is whether it should use a logfilter. - * Currently this class only performs an absolute BMode filter. - */ - class PhotoacousticBModeFilter : public ImageToImageFilter - { - public: - mitkClassMacro(PhotoacousticBModeFilter, ImageToImageFilter); - - itkFactorylessNewMacro(Self); - itkCloneMacro(Self); - - /** \brief Set parameters for the filter - * - * @param useLogFilter If true, the filter will apply a logfilter on the processed image - */ - void UseLogFilter(bool useLogFilter) - { - m_UseLogFilter = useLogFilter; - } - - protected: - - PhotoacousticBModeFilter(); - - ~PhotoacousticBModeFilter() override; - - void GenerateInputRequestedRegion() override; - - void GenerateOutputInformation() override; - - void GenerateData() override; - - //##Description - //## @brief Time when Header was last initialized - itk::TimeStamp m_TimeOfHeaderInitialization; - - bool m_UseLogFilter; - }; -} -#endif /* _MITKPHOTOACOUSTICSBMODEFILTER_H_ */ diff --git a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.h b/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.h deleted file mode 100644 index 2c2bd99680..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.h +++ /dev/null @@ -1,143 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef _MITKPHOTOACOUSTICSOCLBEAMFORMER_H_ -#define _MITKPHOTOACOUSTICSOCLBEAMFORMER_H_ - -#include - -#if defined(PHOTOACOUSTICS_USE_GPU) || DOXYGEN - -#include "mitkOclDataSetToDataSetFilter.h" -#include "mitkBeamformingSettings.h" -#include "mitkPhotoacousticOCLDelayCalculation.h" -#include "mitkPhotoacousticOCLUsedLinesCalculation.h" - -#include - -namespace mitk -{ - /*! - * \brief Class implementing a mitk::OclDataSetToDataSetFilter for beamforming on GPU - * - * The class must be given a configuration class instance of mitk::BeamformingSettings for beamforming parameters through mitk::PhotoacousticOCLBeamformingFilter::SetConfig(BeamformingSettings settings) - * Additional configuration of the apodisation function is needed. - */ - - class PhotoacousticOCLBeamformingFilter : public OclDataSetToDataSetFilter, public itk::Object - { - public: - mitkClassMacroItkParent(PhotoacousticOCLBeamformingFilter, itk::Object); - mitkNewMacro1Param(Self, BeamformingSettings::Pointer); - - /** - * @brief SetInput Set the input data through an image. Arbitrary images are supported - */ - void SetInput(Image::Pointer image); - /** - * brief SetInput Manually set the input data while providing 3 dimensions and memory size of the input data (Bytes per element). - */ - void SetInput(void* data, unsigned int* dimensions, unsigned int BpE); - /** - * @brief GetOutput Get a pointer to the processed data. The standard datatype is float. - */ - void* GetOutput(); - - /** - * @brief GetOutputAsImage Returns an mitk::Image constructed from the processed data - */ - mitk::Image::Pointer GetOutputAsImage(); - - /** \brief Update the filter */ - void Update(); - - /** \brief Set the Apodisation function to apply when beamforming */ - void SetApodisation(const float* apodisation, unsigned short apodArraySize) - { - m_ApodArraySize = apodArraySize; - m_Apodisation = apodisation; - } - - protected: - - PhotoacousticOCLBeamformingFilter(BeamformingSettings::Pointer settings); - virtual ~PhotoacousticOCLBeamformingFilter(); - - /** \brief Initialize the filter */ - bool Initialize(); - - /** \brief Updated the used data for beamforming depending on whether the configuration has significantly changed */ - void UpdateDataBuffers(); - - /** \brief Execute the filter */ - void Execute(); - - mitk::PixelType GetOutputType() - { - return mitk::MakeScalarPixelType(); - } - - int GetBytesPerElem() - { - return sizeof(float); - } - - virtual us::Module* GetModule(); - - private: - /** The OpenCL kernel for the filter */ - cl_kernel m_PixelCalculation; - - unsigned int m_OutputDim[3]; - - const float* m_Apodisation; - unsigned short m_ApodArraySize; - unsigned int m_inputSlices; - - unsigned short m_PAImage; - - BeamformingSettings::Pointer m_Conf; - - mitk::Image::Pointer m_InputImage; - - size_t m_ChunkSize[3]; - - mitk::OCLUsedLinesCalculation::Pointer m_UsedLinesCalculation; - mitk::OCLDelayCalculation::Pointer m_DelayCalculation; - - cl_mem m_ApodizationBuffer; - cl_mem m_DelaysBuffer; - cl_mem m_UsedLinesBuffer; - cl_mem m_ElementHeightsBuffer; - cl_mem m_ElementPositionsBuffer; - - }; -} -#else -namespace mitk -{ - class PhotoacousticOCLBeamformingFilter : public itk::Object - { - public: - mitkClassMacroItkParent(mitk::PhotoacousticOCLBeamformingFilter, itk::Object); - itkNewMacro(Self); - - protected: - /** Constructor */ - PhotoacousticOCLBeamformingFilter() {} - - /** Destructor */ - ~PhotoacousticOCLBeamformingFilter() override {} - }; -} -#endif -#endif diff --git a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.h b/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.h deleted file mode 100644 index 3b0bb88905..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.h +++ /dev/null @@ -1,85 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef _MITKPHOTOACOUSTICSDELAYCALC_H_ -#define _MITKPHOTOACOUSTICSDELAYCALC_H_ - -#if defined(PHOTOACOUSTICS_USE_GPU) || DOXYGEN - -#include "mitkOclDataSetToDataSetFilter.h" -#include -#include "mitkBeamformingSettings.h" - -namespace mitk -{ - /*! - * \brief Class implementing a mitk::OclDataSetToDataSetFilter to calculate the delays used for beamforming. - * - * The class must be given a configuration class instance of mitk::BeamformingSettings for beamforming parameters through mitk::OCLDelayCalculation::SetConfig(BeamformingSettings conf) - * Additionally the output of an instance of mitk::OCLUsedLinesCalculation is needed to calculate the delays. - */ - - class OCLDelayCalculation : public OclDataSetToDataSetFilter, public itk::Object - { - public: - mitkClassMacroItkParent(OCLDelayCalculation, itk::Object); - mitkNewMacro1Param(Self, mitk::BeamformingSettings::Pointer); - - void Update(); - - /** \brief Sets the usedLines buffer object to use for the calculation of the delays. - * - * @param usedLines An buffer generated as the output of an instance of mitk::OCLUsedLinesCalculation. - */ - void SetInputs(cl_mem usedLines) - { - m_UsedLines = usedLines; - } - - protected: - - OCLDelayCalculation(mitk::BeamformingSettings::Pointer settings); - virtual ~OCLDelayCalculation(); - - /** Initialize the filter */ - bool Initialize(); - - void Execute(); - - mitk::PixelType GetOutputType() - { - return mitk::MakeScalarPixelType(); - } - - int GetBytesPerElem() - { - return sizeof(unsigned short); - } - - virtual us::Module* GetModule(); - - int m_sizeThis; - - private: - /** The OpenCL kernel for the filter */ - cl_kernel m_PixelCalculation; - - BeamformingSettings::Pointer m_Conf; - cl_mem m_UsedLines; - unsigned int m_BufferSize; - float m_DelayMultiplicatorRaw; - char m_IsPAImage; - size_t m_ChunkSize[3]; - }; -} -#endif -#endif diff --git a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.h b/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.h deleted file mode 100644 index 2fbe81bf48..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.h +++ /dev/null @@ -1,80 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef _MITKPHOTOACOUSTICSOCLUSEDLINESCALCULATION_H_ -#define _MITKPHOTOACOUSTICSOCLUSEDLINESCALCULATION_H_ - -#if defined(PHOTOACOUSTICS_USE_GPU) || DOXYGEN - -#include "mitkOclDataSetToDataSetFilter.h" -#include -#include "mitkBeamformingSettings.h" - -namespace mitk -{ - /*! - * \brief Class implementing a mitk::OclDataSetToDataSetFilter to calculate which lines each sample should use when beamforming. - * - * The class must be given a configuration class instance of mitk::BeamformingSettings for beamforming parameters through mitk::OCLDelayCalculation::SetConfig(BeamformingSettings conf) - */ - - class OCLUsedLinesCalculation : public OclDataSetToDataSetFilter, public itk::Object - { - public: - mitkClassMacroItkParent(OCLUsedLinesCalculation, itk::Object); - mitkNewMacro1Param(Self, mitk::BeamformingSettings::Pointer); - - void Update(); - - void SetElementHeightsBuffer(cl_mem elementHeightsBuffer); - void SetElementPositionsBuffer(cl_mem elementPositionsBuffer); - - protected: - - /** Constructor */ - OCLUsedLinesCalculation(mitk::BeamformingSettings::Pointer settings); - - /** Destructor */ - virtual ~OCLUsedLinesCalculation(); - - /** Initialize the filter */ - bool Initialize(); - - void Execute(); - - mitk::PixelType GetOutputType() - { - return mitk::MakeScalarPixelType(); - } - - int GetBytesPerElem() - { - return sizeof(unsigned short); - } - - virtual us::Module* GetModule(); - - int m_sizeThis; - - private: - /** The OpenCL kernel for the filter */ - cl_kernel m_PixelCalculation; - - BeamformingSettings::Pointer m_Conf; - float m_part; - size_t m_ChunkSize[3]; - cl_mem m_ElementHeightsBuffer; - cl_mem m_ElementPositionsBuffer; - }; -} -#endif -#endif diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkBandpassFilter.h b/Modules/PhotoacousticsAlgorithms/include/mitkBandpassFilter.h deleted file mode 100644 index a3f990736a..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkBandpassFilter.h +++ /dev/null @@ -1,61 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_BANDPASS_FILTER -#define MITK_BANDPASS_FILTER - -#include "mitkImageToImageFilter.h" -#include "MitkPhotoacousticsAlgorithmsExports.h" -#include "mitkPhotoacousticFilterService.h" - -namespace mitk { - /*! - * \brief Class implementing an mitk::ImageToImageFilter for casting any mitk image to a float image - */ - - class MITKPHOTOACOUSTICSALGORITHMS_EXPORT BandpassFilter : public ImageToImageFilter - { - public: - mitkClassMacro(BandpassFilter, ImageToImageFilter); - - itkFactorylessNewMacro(Self); - itkCloneMacro(Self); - - itkSetMacro(HighPass, float); - itkSetMacro(LowPass, float); - itkSetMacro(HighPassAlpha, float); - itkSetMacro(LowPassAlpha, float); - itkSetMacro(SpeedOfSound, float); - itkSetMacro(TimeSpacing, float); - itkSetMacro(IsBFImage, bool); - - protected: - BandpassFilter(); - - ~BandpassFilter() override; - - void SanityCheckPreconditions(); - - float m_SpeedOfSound; - float m_TimeSpacing; - bool m_IsBFImage; - float m_HighPass; - float m_LowPass; - float m_HighPassAlpha; - float m_LowPassAlpha; - mitk::PhotoacousticFilterService::Pointer m_FilterService; - - void GenerateData() override; - }; -} // namespace mitk - -#endif //MITK_CAST_TO_FLOAT_IMAGE_FILTER diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingFilter.h b/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingFilter.h deleted file mode 100644 index 8828ed1d29..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingFilter.h +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_PHOTOACOUSTICS_BEAMFORMING_FILTER -#define MITK_PHOTOACOUSTICS_BEAMFORMING_FILTER - -#include "mitkImageToImageFilter.h" -#include -#include "./OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.h" -#include "mitkBeamformingSettings.h" -#include "mitkBeamformingUtils.h" -#include "MitkPhotoacousticsAlgorithmsExports.h" - -namespace mitk { - /*! - * \brief Class implementing an mitk::ImageToImageFilter for beamforming on both CPU and GPU - * - * The class must be given a configuration class instance of mitk::BeamformingSettings for beamforming parameters through mitk::BeamformingFilter::Configure(BeamformingSettings settings) - * Whether the GPU is used can be set in the configuration. - * For significant problems or important messages a string is written, which can be accessed via GetMessageString(). - */ - - class MITKPHOTOACOUSTICSALGORITHMS_EXPORT BeamformingFilter : public ImageToImageFilter - { - public: - mitkClassMacro(BeamformingFilter, ImageToImageFilter); - - mitkNewMacro1Param(Self, mitk::BeamformingSettings::Pointer); - itkCloneMacro(Self); - - /** \brief Sets a callback for progress checking - * - * An std::function can be set, through which progress of the currently updating filter is reported. - * The integer argument is a number between 0 an 100 to indicate how far completion has been achieved, the std::string argument indicates what the filter is currently doing. - */ - void SetProgressHandle(std::function progressHandle); - - protected: - BeamformingFilter(mitk::BeamformingSettings::Pointer settings); - - ~BeamformingFilter() override; - - void GenerateInputRequestedRegion() override; - - void GenerateOutputInformation() override; - - void GenerateData() override; - - //##Description - //## @brief Time when Header was last initialized - itk::TimeStamp m_TimeOfHeaderInitialization; - - /** \brief The std::function, through which progress of the currently updating filter is reported. - */ - std::function m_ProgressHandle; - - float* m_OutputData; - float* m_InputData; - float* m_InputDataPuffer; - unsigned short* m_MinMaxLines; - - /** \brief Current configuration set - */ - BeamformingSettings::Pointer m_Conf; - - /** - * The size of the apodization array when it last changed. - */ - int m_LastApodizationArraySize; - - /** \brief Pointer to the GPU beamforming filter class; for performance reasons the filter is initialized within the constructor and kept for all later computations. - */ - mitk::PhotoacousticOCLBeamformingFilter::Pointer m_BeamformingOclFilter; - }; -} // namespace mitk - -#endif //MITK_PHOTOACOUSTICS_BEAMFORMING_FILTER diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingSettings.h b/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingSettings.h deleted file mode 100644 index dbb6c4f129..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingSettings.h +++ /dev/null @@ -1,244 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_BEAMFORMING_SETTINGS -#define MITK_BEAMFORMING_SETTINGS - -#include -#include -#include -#include - -namespace mitk { - /*! - * \brief Class holding the configuration data for the beamforming filters mitk::BeamformingFilter and mitk::PhotoacousticOCLBeamformingFilter - * - * A detailed description can be seen below. All parameters should be set manually for successfull beamforming. - */ - - class MITKPHOTOACOUSTICSALGORITHMS_EXPORT BeamformingSettings : public itk::Object - { - public: - mitkClassMacroItkParent(BeamformingSettings, itk::Object); - itkCloneMacro(Self); - - /** \brief Available apodization functions: - * - Hamming function. - * - Von-Hann function. - * - Box function. - */ - enum Apodization { Hamm, Hann, Box }; - - /** \brief Available beamforming algorithms: - * - DAS (Delay and sum). - * - DMAS (Delay multiply and sum). - */ - enum BeamformingAlgorithm { DMAS, DAS, sDMAS }; - - /** \brief Available geometries for Probes: - * - Linear - * - Concave - */ - enum ProbeGeometry { Linear, Concave}; - - itkGetConstMacro(PitchInMeters, float); - itkGetConstMacro(SpeedOfSound, float); - itkGetConstMacro(TimeSpacing, float); - itkGetConstMacro(Angle, float); - itkGetConstMacro(IsPhotoacousticImage, bool); - itkGetConstMacro(TransducerElements, unsigned int); - itkGetConstMacro(SamplesPerLine, unsigned int); - itkGetConstMacro(ReconstructionLines, unsigned int); - itkGetConstMacro(InputDim, const unsigned int*); - itkGetConstMacro(UseGPU, bool); - itkGetConstMacro(GPUBatchSize, unsigned int); - itkGetConstMacro(ApodizationFunction, const float*); - itkGetConstMacro(Apod, Apodization); - itkGetConstMacro(ApodizationArraySize, int); - itkGetConstMacro(Algorithm, BeamformingAlgorithm); - itkGetConstMacro(ReconstructionDepth, float); - itkGetConstMacro(Geometry, ProbeGeometry); - itkGetConstMacro(ProbeRadius, float); - itkGetConstMacro(ElementHeights, float*); - itkGetConstMacro(ElementPositions, float*); - itkGetConstMacro(HorizontalExtent, float); - - /** \brief function for mitk::PhotoacousticOCLBeamformingFilter to check whether buffers need to be updated - * this method only checks parameters relevant for the openCL implementation - */ - static bool SettingsChangedOpenCL(const BeamformingSettings::Pointer lhs, const BeamformingSettings::Pointer rhs) - { - return !((std::abs(lhs->GetAngle() - rhs->GetAngle()) < 0.01f) && // 0.01 degree error margin - (lhs->GetApod() == rhs->GetApod()) && - (lhs->GetGeometry() == rhs->GetGeometry()) && - (std::abs(lhs->GetProbeRadius() - rhs->GetProbeRadius()) < 0.001f) && - (lhs->GetIsPhotoacousticImage() == rhs->GetIsPhotoacousticImage()) && - (std::abs(lhs->GetPitchInMeters() - rhs->GetPitchInMeters()) < 0.000001f) && // 0.0001 mm error margin - (lhs->GetReconstructionLines() == rhs->GetReconstructionLines()) && - (lhs->GetSamplesPerLine() == rhs->GetSamplesPerLine()) && - (lhs->GetReconstructionDepth() == rhs->GetReconstructionDepth()) && - (std::abs(lhs->GetSpeedOfSound() - rhs->GetSpeedOfSound()) < 0.01f) && - (std::abs(lhs->GetTimeSpacing() - rhs->GetTimeSpacing()) < 0.00000000001f) && //0.01 ns error margin - (lhs->GetTransducerElements() == rhs->GetTransducerElements())); - } - - static Pointer New(float pitchInMeters, - float speedOfSound, - float timeSpacing, - float angle, - bool isPhotoacousticImage, - unsigned int samplesPerLine, - unsigned int reconstructionLines, - unsigned int* inputDim, - float reconstructionDepth, - bool useGPU, - unsigned int GPUBatchSize, - Apodization apod, - unsigned int apodizationArraySize, - BeamformingAlgorithm algorithm, - ProbeGeometry geometry, - float probeRadius) - { - Pointer smartPtr = new BeamformingSettings(pitchInMeters, - speedOfSound, - timeSpacing, - angle, - isPhotoacousticImage, - samplesPerLine, - reconstructionLines, - inputDim, - reconstructionDepth, - useGPU, - GPUBatchSize, - apod, - apodizationArraySize, - algorithm, - geometry, - probeRadius); - smartPtr->UnRegister(); - return smartPtr; - } - - unsigned short* GetMinMaxLines(); - - protected: - - /** - */ - BeamformingSettings(float pitchInMeters, - float speedOfSound, - float timeSpacing, - float angle, - bool isPhotoacousticImage, - unsigned int samplesPerLine, - unsigned int reconstructionLines, - unsigned int* inputDim, - float reconstructionDepth, - bool useGPU, - unsigned int GPUBatchSize, - Apodization apod, - unsigned int apodizationArraySize, - BeamformingAlgorithm algorithm, - ProbeGeometry geometry, - float probeRadius - ); - - ~BeamformingSettings() override; - - /** \brief Pitch of the used transducer in [m]. - */ - float m_PitchInMeters; - - /** \brief Speed of sound in the used medium in [m/s]. - */ - float m_SpeedOfSound; - - /** \brief The time spacing of the input image - */ - float m_TimeSpacing; // [s] - - /** \brief The angle of the transducer elements - */ - float m_Angle; - - /** \brief Flag whether processed image is a photoacoustic image or an ultrasound image - */ - bool m_IsPhotoacousticImage; - - /** \brief How many transducer elements the used transducer had. - */ - unsigned int m_TransducerElements; - - /** \brief How many vertical samples should be used in the final image. - */ - unsigned int m_SamplesPerLine; - - /** \brief How many lines should be reconstructed in the final image. - */ - unsigned int m_ReconstructionLines; - - /** \brief Sets the dimensions of the inputImage. - */ - const unsigned int* m_InputDim; - - /** \brief The Depth up to which the filter should reconstruct the image [m] - */ - float m_ReconstructionDepth; - - /** \brief Decides whether GPU computing should be used - */ - bool m_UseGPU; - - unsigned int m_GPUBatchSize; - /** \brief Sets the amount of image slices in batches when GPU is used - */ - - const float* m_ApodizationFunction; - - /** \brief Sets the used apodization function. - */ - Apodization m_Apod; - - /** \brief Sets the resolution of the apodization array (must be greater than 0). - */ - int m_ApodizationArraySize; - - /** \brief Sets the used beamforming algorithm. - */ - BeamformingAlgorithm m_Algorithm; - - /** \brief Sets the used probe geometry - */ - ProbeGeometry m_Geometry; - - /** \brief Sets the radius of the curved probe [m] - */ - float m_ProbeRadius; - - /** - */ - float *m_ElementHeights; - - /** - */ - float *m_ElementPositions; - - /** - */ - float m_HorizontalExtent; - - /** - */ - unsigned short* m_MinMaxLines; - }; -} -#endif //MITK_BEAMFORMING_SETTINGS diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingUtils.h b/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingUtils.h deleted file mode 100644 index 5a53157e44..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkBeamformingUtils.h +++ /dev/null @@ -1,68 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_BEAMFORMING_FILTER_UTILS -#define MITK_BEAMFORMING_FILTER_UTILS - -#include "mitkImageToImageFilter.h" -#include -#include "./OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.h" -#include "mitkBeamformingSettings.h" - -namespace mitk { - /*! - * \brief Class implementing util functionality for beamforming on CPU - * - */ - class BeamformingUtils final - { - public: - - /** \brief Function to perform beamforming on CPU for a single line, using DAS and spherical delay - */ - static void DASSphericalLine(float* input, float* output, float inputDim[2], float outputDim[2], const short& line, const mitk::BeamformingSettings::Pointer config); - - /** \brief Function to perform beamforming on CPU for a single line, using DMAS and spherical delay - */ - static void DMASSphericalLine(float* input, float* output, float inputDim[2], float outputDim[2], const short& line, const mitk::BeamformingSettings::Pointer config); - - /** \brief Function to perform beamforming on CPU for a single line, using signed DMAS and spherical delay - */ - static void sDMASSphericalLine(float* input, float* output, float inputDim[2], float outputDim[2], const short& line, const mitk::BeamformingSettings::Pointer config); - - /** \brief Pointer holding the Von-Hann apodization window for beamforming - * @param samples the resolution at which the window is created - */ - static float* VonHannFunction(int samples); - - /** \brief Function to create a Hamming apodization window - * @param samples the resolution at which the window is created - */ - static float* HammFunction(int samples); - - /** \brief Function to create a Box apodization window - * @param samples the resolution at which the window is created - */ - static float* BoxFunction(int samples); - - /** \brief - */ - static unsigned short* MinMaxLines(const mitk::BeamformingSettings::Pointer config); - - protected: - BeamformingUtils(); - - ~BeamformingUtils(); - }; -} // namespace mitk - -#endif //MITK_BEAMFORMING_FILTER_UTILS diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkCastToFloatImageFilter.h b/Modules/PhotoacousticsAlgorithms/include/mitkCastToFloatImageFilter.h deleted file mode 100644 index 94a49f3e7e..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkCastToFloatImageFilter.h +++ /dev/null @@ -1,41 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_CAST_TO_FLOAT_IMAGE_FILTER -#define MITK_CAST_TO_FLOAT_IMAGE_FILTER - -#include "mitkImageToImageFilter.h" -#include "MitkPhotoacousticsAlgorithmsExports.h" - -namespace mitk { - /*! - * \brief Class implementing an mitk::ImageToImageFilter for casting any mitk image to a float image - */ - - class MITKPHOTOACOUSTICSALGORITHMS_EXPORT CastToFloatImageFilter : public ImageToImageFilter - { - public: - mitkClassMacro(CastToFloatImageFilter, ImageToImageFilter); - - itkFactorylessNewMacro(Self); - itkCloneMacro(Self); - - protected: - CastToFloatImageFilter(); - - ~CastToFloatImageFilter() override; - - void GenerateData() override; - }; -} // namespace mitk - -#endif //MITK_CAST_TO_FLOAT_IMAGE_FILTER diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkCropImageFilter.h b/Modules/PhotoacousticsAlgorithms/include/mitkCropImageFilter.h deleted file mode 100644 index 3316865d0b..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkCropImageFilter.h +++ /dev/null @@ -1,65 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_CROP_IMAGE_FILTER -#define MITK_CROP_IMAGE_FILTER - -#include -#include "mitkImageToImageFilter.h" -#include "itkMacro.h" - -namespace mitk { - /*! - * \brief Class implementing an mitk::ImageToImageFilter for casting any mitk image to a float image - */ - - class MITKPHOTOACOUSTICSALGORITHMS_EXPORT CropImageFilter : public ImageToImageFilter - { - public: - mitkClassMacro(CropImageFilter, ImageToImageFilter); - - itkFactorylessNewMacro(Self); - itkCloneMacro(Self); - - itkGetMacro(XPixelsCropStart, unsigned int); - itkSetMacro(XPixelsCropStart, unsigned int); - itkGetMacro(YPixelsCropStart, unsigned int); - itkSetMacro(YPixelsCropStart, unsigned int); - itkGetMacro(ZPixelsCropStart, unsigned int); - itkSetMacro(ZPixelsCropStart, unsigned int); - - itkGetMacro(XPixelsCropEnd, unsigned int); - itkSetMacro(XPixelsCropEnd, unsigned int); - itkGetMacro(YPixelsCropEnd, unsigned int); - itkSetMacro(YPixelsCropEnd, unsigned int); - itkGetMacro(ZPixelsCropEnd, unsigned int); - itkSetMacro(ZPixelsCropEnd, unsigned int); - - protected: - CropImageFilter(); - - ~CropImageFilter() override; - - void GenerateData() override; - - void SanityCheckPreconditions(); - - unsigned int m_XPixelsCropStart; - unsigned int m_YPixelsCropStart; - unsigned int m_ZPixelsCropStart; - unsigned int m_XPixelsCropEnd; - unsigned int m_YPixelsCropEnd; - unsigned int m_ZPixelsCropEnd; - }; -} // namespace mitk - -#endif //MITK_CROP_IMAGE_FILTER diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkImageSliceSelectionFilter.h b/Modules/PhotoacousticsAlgorithms/include/mitkImageSliceSelectionFilter.h deleted file mode 100644 index 4e7aaa59cc..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkImageSliceSelectionFilter.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITK_IMAGE_SLICE_SELECTION_FILTER -#define MITK_IMAGE_SLICE_SELECTION_FILTER - -#include "mitkImageToImageFilter.h" - -namespace mitk { - /*! - * \brief Class implementing an mitk::ImageToImageFilter for casting any mitk image to a float image - */ - - class ImageSliceSelectionFilter : public ImageToImageFilter - { - public: - mitkClassMacro(ImageSliceSelectionFilter, ImageToImageFilter); - - itkFactorylessNewMacro(Self); - itkCloneMacro(Self); - - protected: - ImageSliceSelectionFilter(); - - ~ImageSliceSelectionFilter() override; - - void GenerateData() override; - }; -} // namespace mitk - -#endif //MITK_IMAGE_SLICE_SELECTION_FILTER diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkPhotoacousticFilterService.h b/Modules/PhotoacousticsAlgorithms/include/mitkPhotoacousticFilterService.h deleted file mode 100644 index 4bc3447162..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkPhotoacousticFilterService.h +++ /dev/null @@ -1,129 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef mitkPhotoacousticFilterService_H_HEADER_INCLUDED -#define mitkPhotoacousticFilterService_H_HEADER_INCLUDED - -#include "itkObject.h" -#include "mitkCommon.h" -#include "mitkImage.h" -#include - -#include "mitkBeamformingSettings.h" -#include "mitkBeamformingFilter.h" -#include "MitkPhotoacousticsAlgorithmsExports.h" - -namespace mitk { - /*! - * \brief Class holding methods to apply all Filters within the Photoacoustics Algorithms Module - * - * Implemented are: - * - A B-Mode Filter - * - A Resampling Filter - * - Beamforming on GPU and CPU - * - A Bandpass Filter - */ - - class MITKPHOTOACOUSTICSALGORITHMS_EXPORT PhotoacousticFilterService : public itk::Object - { - public: - mitkClassMacroItkParent(mitk::PhotoacousticFilterService, itk::Object); - itkFactorylessNewMacro(Self); - - /** \brief Defines the methods for the B-Mode filter - * Currently implemented are an Envelope Detection filter and a simple Absolute filter. - */ - enum BModeMethod { EnvelopeDetection, Abs }; - - /** \brief Applies a B-Mode Filter - * - * Applies a B-Mode filter using the given parameters. - * @param inputImage The image to be processed. - * @param method The kind of B-Mode Filter to be used. - * @param UseLogFilter Setting this to true will apply a simple logarithm to the image after the B-Mode Filter has been applied. - * @return The processed image is returned after the filter has finished. - */ - mitk::Image::Pointer ApplyBmodeFilter(mitk::Image::Pointer inputImage, - BModeMethod method = BModeMethod::Abs, - bool UseLogFilter = false); - - /** \brief Resamples the given image - * - * Resamples an image using the given parameters. - * @param inputImage The image to be processed. - * @param outputSpacing An array of dimensions the image should be resampled to. - * @return The processed image is returned after the filter has finished. - */ - mitk::Image::Pointer ApplyResampling(mitk::Image::Pointer inputImage, double* outputSpacing); - - mitk::Image::Pointer ApplyResamplingToDim(mitk::Image::Pointer inputImage, double* outputDimension); - - /** \brief Beamforms the given image - * - * Resamples an image using the given parameters. - * @param inputImage The image to be processed. - * @param config The configuration set to be used for beamforming. - * @param progressHandle An std::function, through which progress of the currently updating filter is reported. - * The integer argument is a number between 0 an 100 to indicate how far completion has been achieved, the std::string argument indicates what the filter is currently doing. - * @return The processed image is returned after the filter has finished. - */ - mitk::Image::Pointer ApplyBeamforming(mitk::Image::Pointer inputImage, BeamformingSettings::Pointer config, std::function progressHandle = [](int, std::string) {}); - - /** \brief Crops the given image - * - * Crops an image in 3 dimension using the given parameters. - * @param inputImage The image to be processed. - * @param above How many voxels will be cut from the top of the image. - * @param below How many voxels will be cut from the bottom of the image. - * @param right How many voxels will be cut from the right side of the image. - * @param left How many voxels will be cut from the left side of the image. - * @param minSlice The first slice to be present in the resulting volume. - * @param maxSlice How many slices are cut off from the end of the volume. - * @param errCode - * @return The processed image is returned after the filter has finished. For the purposes of this module, the returned image is always of type float. - */ - mitk::Image::Pointer ApplyCropping(mitk::Image::Pointer inputImage, int above, int below, int right, int left, int minSlice, int maxSlice, int* errCode); - - mitk::Image::Pointer ExtendImage(mitk::Image::Pointer inputImage, float pixelColor, unsigned int outputDimensionY); - - /** \brief Applies a Bandpass filter to the given image - * - * Applies a bandpass filter to the given image using the given parameters. - * @param data The image to be processed. - * @param BPHighPass The position at which Lower frequencies are completely cut off in Hz. - * @param BPLowPass The position at which Higher frequencies are completely cut off in Hz. - * @param alphaHighPass The high pass tukey window parameter to control the shape of the bandpass filter: 0 will make it a Box function, 1 a Hann function. alpha can be set between those two bounds. - * @param alphaLowPass The low passtukey window parameter to control the shape of the bandpass filter: 0 will make it a Box function, 1 a Hann function. alpha can be set between those two bounds. - * @param timeSpacing - * @param SpeedOfSound - * @param IsBFImage - * @return The processed image is returned after the filter has finished. - */ - mitk::Image::Pointer ApplyBandpassFilter(mitk::Image::Pointer data, - float BPHighPass, float BPLowPass, - float alphaHighPass, float alphaLowPass, - float timeSpacing, float SpeedOfSound, bool IsBFImage); - - protected: - PhotoacousticFilterService(); - ~PhotoacousticFilterService() override; - - /** \brief - For performance reasons, an instance of the Beamforming filter is initialized as soon as possible and kept for all further uses. - */ - mitk::BeamformingFilter::Pointer m_BeamformingFilter; - - mitk::Image::Pointer ConvertToFloat(mitk::Image::Pointer); - }; -} // namespace mitk - -#endif /* mitkPhotoacousticFilterService_H_HEADER_INCLUDED */ diff --git a/Modules/PhotoacousticsAlgorithms/include/mitkPhotoacousticMotionCorrectionFilter.h b/Modules/PhotoacousticsAlgorithms/include/mitkPhotoacousticMotionCorrectionFilter.h deleted file mode 100644 index de4d9124dc..0000000000 --- a/Modules/PhotoacousticsAlgorithms/include/mitkPhotoacousticMotionCorrectionFilter.h +++ /dev/null @@ -1,307 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef _MITKPHOTOACOUSTICSMOTIONCORRECTIONFILTER_H_ -#define _MITKPHOTOACOUSTICSMOTIONCORRECTIONFILTER_H_ - -#include "mitkImageToImageFilter.h" -#include - -#include "opencv2/imgproc.hpp" -// TODO: Find out why build fails with this option or replace with something -// else -/* #include "opencv2/opencv.hpp" */ -#include "opencv2/video/tracking.hpp" - -#include "itkOpenCVImageBridge.h" - -#include - -#include "mitkImageCast.h" -#include -#include -#include - -#define IMAGE_DIMENSION 3 /*!< All images need to have dimension 3*/ -#define MAX_MATRIX 255.0 /*!< Rescaling constant to maximum character*/ - -namespace mitk -{ - /*! - * \brief Class implementing a mitk::ImageToImageFilter for PAUS motion - * correction. - * - * The filter takes a stack of PA and US images. It then computes the optical - * flow - * within the US image and compensates the PA and US images for the flow. - * Afterwards it - * returns the stack of PA and US images. - * - * @see - * https://docs.opencv.org/3.0-beta/modules/video/doc/motion_analysis_and_object_tracking.html#calcopticalflowfarneback - */ - class MITKPHOTOACOUSTICSALGORITHMS_EXPORT PhotoacousticMotionCorrectionFilter : public ImageToImageFilter - { - public: - mitkClassMacro(PhotoacousticMotionCorrectionFilter, ImageToImageFilter); - - itkFactorylessNewMacro(Self); - - // Setters and Getters for the class variables - itkSetMacro(BatchSize, unsigned int); - itkSetMacro(PyrScale, double); - itkSetMacro(Levels, unsigned int); - itkSetMacro(WinSize, unsigned int); - itkSetMacro(Iterations, unsigned int); - itkSetMacro(PolyN, unsigned int); - itkSetMacro(PolySigma, double); - itkSetMacro(Flags, unsigned int); - itkGetConstMacro(BatchSize, unsigned int); - itkGetConstMacro(PyrScale, double); - itkGetConstMacro(Levels, unsigned int); - itkGetConstMacro(WinSize, unsigned int); - itkGetConstMacro(Iterations, unsigned int); - itkGetConstMacro(PolyN, unsigned int); - itkGetConstMacro(PolySigma, double); - itkGetConstMacro(Flags, unsigned int); - - // Wrapper for SetInput, GetInput and GetOutput - /*! - * \brief Wrapper which sets the photoacoustic image as the correct input - * - * This method is a wrapper around the @c SetInput method. It is implemented - * for convenience such that you do not have to remember which input is for - * which image. - * - * @param input The photoacoustic image - */ - void SetPaInput(mitk::Image::Pointer input); - /*! - * \brief Wrapper which gets the photoacoustic image out of the correct input - * - * This method is a wrapper around the @c GetInput method. It is implemented - * for convenience such that you do not have to remember which input is for - * which image. - * - * @return The photoacoustic image - */ - mitk::Image::Pointer GetPaInput(); - /*! - * \brief Wrapper which sets the ultrasonic image as the correct input - * - * This method is a wrapper around the @c SetInput method. It is implemented - * for convenience such that you do not have to remember which input is for - * which image. - * - * @param input The ultrasonic image - */ - void SetUsInput(mitk::Image::Pointer input); - /*! - * \brief Wrapper which gets the ultrasonic image out of the correct input - * - * This method is a wrapper around the @c GetInput method. It is implemented - * for convenience such that you do not have to remember which input is for - * which image. - * - * @return The ultrasonic image - */ - mitk::Image::Pointer GetUsInput(); - /*! - * \brief Wrapper which gets the photoacoustic image out of the correct output - * - * This method is a wrapper around the @c GetOutput method. It is implemented - * for convenience such that you do not have to remember which output is for - * which image. - * - * @return The photoacoustic image - */ - mitk::Image::Pointer GetPaOutput(); - /*! - * \brief Wrapper which gets the ultrasonic image out of the correct output - * - * This method is a wrapper around the @c GetOutput method. It is implemented - * for convenience such that you do not have to remember which output is for - * which image. - * - * @return The ultrasonic image - */ - mitk::Image::Pointer GetUsOutput(); - - protected: - PhotoacousticMotionCorrectionFilter(); - - ~PhotoacousticMotionCorrectionFilter() override; - - /*! - * \brief Apply OpenCV algorithm to compensate motion in a 2d image time - * series - * - * This method uses two 3d mitk images. Both will be interpreted as time - * series of 2d images. @c GetInput(0) should be a photoacoustic image whereas - * @c GetInput(1) should be an ultrasound image. The input will be validated - * and then converted to OpenCV matrices. In the end the Farneback algorithm - * will be used to compute the optical flow in consecutive images and - * compensate for this flow. The Output will be two 3d mitk images of the same - * dimensions as the input containing the compensated data. - * - * @warning The input images need to be 3-dimensional (with the same size in - * each dimension). Otherwise, an @c invalid_argument exception will be - * thrown. - * @throws invalid_argument - */ - void GenerateData() override; - /*! - * \brief Validate the input images - * - * The input images have to be non-empty, 3d and have to coincide in the - * length in each dimension. If any of these conditions are violated, the - * method will throw an @c invalid_argument exception. - * - * @param paImage A mitk image - * @param usImage A mitk image - * @warning If the two images are not 3d and do not coincide in the length in - * each dimension, this method will throw an @c invalid_argument exception. - * @throws invalid_argument - */ - void CheckInput(mitk::Image::Pointer paImage, mitk::Image::Pointer usImage); - /*! - * \brief Assure that the output images have the same dimensions as the input - * images. - * - * The output images need to have the same dimensions as the input images. - * This will be checked here. If the dimensions do not match, the output will - * be reinitialized and the image data from the input images will be copied to - * the output images (in order to make sure that they have a valid data - * pointer). - * - * @param paInput Pointer to the photoacoustic input image - * @param usInput Pointer to the ultrasonic input image - * @param paOutput Pointer to the photoacoustic output image - * @param usOutput Pointer to the ultrasonic output image - */ - void InitializeOutputIfNecessary(mitk::Image::Pointer paInput, - mitk::Image::Pointer usInput, - mitk::Image::Pointer paOutput, - mitk::Image::Pointer usOutput); - /*! - * \brief Copy the image data from the input image to the output image - * - * This method copys the image data from @p input to @p output. This method - * assumes that the dimensions of the two images match and will not test this. - * - * @param input A mitk image - * @param output A mitk image - */ - void InitializeOutput(mitk::Image::Pointer input, mitk::Image::Pointer output); - /*! - * \brief This method performs the actual motion compensation. - * - * This method uses the ultrasonic input image @p usInput to compute the - * optical flow in the time series of 2d images. Then it compensates both the - * @p usInput and @p paInput for it and saves the result in @p usOutput and @p - * paOutput respectively. In the background the OpenCV Farneback algorithm is - * used for the flow determination. - * - * @param paInput The photoacoustic input image - * @param usInput The ultrasonic input image - * @param paOutput The photoacoustic output image - * @param usOutput The ultrasonic output image - */ - void PerformCorrection(mitk::Image::Pointer paInput, - mitk::Image::Pointer usInput, - mitk::Image::Pointer paOutput, - mitk::Image::Pointer usOutput); - /*! - * \brief Extract a 2d slice as OpenCV matrix. - * - * This method extracts slice @p i from the 3-dimensional image @p input and - * converts it to a OpenCV matrix. Internally, the - * mitkImageToOpenCVImageFilter is used. - * - * @param input A 3d image from which a slice is extracted as a 2d OpenCV - * matrix. - * @param i Determines the slice to be extracted. - * @return returns a OpenCV matrix containing the 2d slice. - */ - cv::Mat GetMatrix(const mitk::Image::Pointer input, unsigned int i); - - /*! - * \brief Rescale matrix such that the values lie between 0 and 255 - * - * This method rescales the matrix such that its values lie between 0 and 255. In order to do that it uses the maximum and the minimum of the input ultrasonic image. - * - * @warning This is a specialized method which does not perform the operation in general, but only if the matrix stems from the right ultrasonic image. Therefore, the method should only be called internally. - * - * @param mat The OpenCV matrix to be rescaled - * @return The rescaled OpenCV matrix - */ - cv::Mat FitMatrixToChar(cv::Mat mat); - - /*! - * \brief Insert a OpenCV matrix as a slice into an image - * - * This method converts the 2d OpenCV matrix @p mat into an mitk image using - * the mitkOpenCVToMitkImageFilter. Afterwards it inserts the image as slice - * @p i into the 3d mitk image @p output. - * - * @param mat The matrix to be inserted as a slice - * @param output The 3d image the matrix is inserted into - * @param i The index of the slice to be replaced. - */ - void InsertMatrixAsSlice(cv::Mat mat, mitk::Image::Pointer output, unsigned int i); - - /*! - * \brief Compute the remapping map from an optical flow - * - * The optical flow cannot be used directly to compensate an image. Instead we have to generate an appropriate map. - * - * @param flow The optical flow which is the base for the remapping. - * @return The remapping map. - */ - cv::Mat ComputeFlowMap(cv::Mat flow); - - private: - // Parameters - double m_PyrScale; /*!< See @c pyr_scale in @c cv::calcOpticalFlowFarneback - */ - double m_PolySigma; /*!< See @c poly_sigma in @c cv::calcOpticalFlowFarneback - */ - unsigned int m_Levels; /*!< See @c levels in @c cv::calcOpticalFlowFarneback */ - unsigned int m_WinSize; /*!< See @c winsize in @c cv::calcOpticalFlowFarneback */ - unsigned int m_Iterations; /*!< See @c iterations in @c cv::calcOpticalFlowFarneback */ - unsigned int m_PolyN; /*!< See @c poly_n in @c cv::calcOpticalFlowFarneback */ - unsigned int m_Flags; /*!< See @c flags in @c cv::calcOpticalFlowFarneback */ - unsigned int m_BatchSize; /*!< Determines how many slices belong together and will be - motion compensated with regard to the first image in the - batch. If the variable is set to 0, the whole time series will - be processed as one batch. */ - float m_MaxValue; /*!< The maximum of the ultrasonic image*/ - float m_MinValue; /*!< The minimum of the ultrasonic image*/ - - // Stuff that OpenCV needs - cv::Mat m_UsRef; /*!< Contains the reference ultrasonic image to which the - motion compensation is compared to.*/ - cv::Mat m_Flow; /*!< Contains the optical flow between @c m_UsRef and @c m_UsMat*/ - cv::Mat m_PaRes; /*!< Contains the motion compensated photoacoustic image*/ - cv::Mat m_UsRes; /*!< Contains the motion compensated ultrasonic image*/ - cv::Mat m_PaMat; /*!< Contains the latest photoacoustic image to be motion compensated*/ - cv::Mat m_UsMat; /*!< Contains the latest ultrasonic image on which the - optical flow is to be computed */ - cv::Mat m_Map; /*!< Contains the remapping map */ - - mitk::OpenCVToMitkImageFilter::Pointer m_OpenCVToImageFilter = - mitk::OpenCVToMitkImageFilter::New(); /*!< Filter which converts an OpenCV matrix to a mitk image */ - mitk::ImageToOpenCVImageFilter::Pointer m_ImageToOpenCVFilter = - mitk::ImageToOpenCVImageFilter::New(); /*!< Filter which converts a mitk image to an OpenCV matrix */ - }; -} -#endif diff --git a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticBModeFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticBModeFilter.cpp deleted file mode 100644 index 785100fe4a..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticBModeFilter.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "./OpenCLFilter/mitkPhotoacousticBModeFilter.h" -#include "usServiceReference.h" -#include - -mitk::PhotoacousticBModeFilter::PhotoacousticBModeFilter() : m_UseLogFilter(false) -{ - this->SetNumberOfIndexedInputs(1); - this->SetNumberOfRequiredInputs(1); -} - -mitk::PhotoacousticBModeFilter::~PhotoacousticBModeFilter() -{ -} - -void mitk::PhotoacousticBModeFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - mitk::Image::Pointer output = this->GetOutput(); - mitk::Image::Pointer input = this->GetInput(); - - if (!output->IsInitialized()) - return; - - input->SetRequestedRegionToLargestPossibleRegion(); -} - -void mitk::PhotoacousticBModeFilter::GenerateOutputInformation() -{ - mitk::Image::ConstPointer input = this->GetInput(); - mitk::Image::Pointer output = this->GetOutput(); - - if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime())) - return; - - output->Initialize(input->GetPixelType(), input->GetDimension(), input->GetDimensions()); - output->GetGeometry()->SetSpacing(input->GetGeometry()->GetSpacing()); - output->GetGeometry()->Modified(); - output->SetPropertyList(input->GetPropertyList()->Clone()); - - m_TimeOfHeaderInitialization.Modified(); -} - -void mitk::PhotoacousticBModeFilter::GenerateData() -{ - GenerateOutputInformation(); - mitk::Image::Pointer input = this->GetInput(); - mitk::Image::Pointer output = this->GetOutput(); - - if (!output->IsInitialized()) - return; - - mitk::ImageReadAccessor reader(input); - - unsigned int size = output->GetDimension(0) * output->GetDimension(1) * output->GetDimension(2); - - const float* InputData = (const float*)(reader.GetData()); - float* OutputData = new float[size]; - if (!m_UseLogFilter) - for (unsigned int i = 0; i < size; ++i) - { - OutputData[i] = std::abs(InputData[i]); - } - else - { - for (unsigned int i = 0; i < size; ++i) - { - OutputData[i] = log(std::abs(InputData[i])); - } - } - - output->SetImportVolume(OutputData, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - delete[] OutputData; - m_TimeOfHeaderInitialization.Modified(); -} diff --git a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.cpp deleted file mode 100644 index 4dcd2933d5..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#if defined(PHOTOACOUSTICS_USE_GPU) || DOXYGEN - -#include "./OpenCLFilter/mitkPhotoacousticOCLBeamformingFilter.h" -#include "usServiceReference.h" - -mitk::PhotoacousticOCLBeamformingFilter::PhotoacousticOCLBeamformingFilter(BeamformingSettings::Pointer settings) : - m_PixelCalculation(NULL), - m_inputSlices(1), - m_Conf(settings), - m_InputImage(mitk::Image::New()), - m_ApodizationBuffer(nullptr), - m_DelaysBuffer(nullptr), - m_UsedLinesBuffer(nullptr), - m_ElementHeightsBuffer(nullptr), - m_ElementPositionsBuffer(nullptr) -{ - MITK_INFO << "Instantiating OCL beamforming Filter..."; - this->AddSourceFile("DAS.cl"); - this->AddSourceFile("DMAS.cl"); - this->AddSourceFile("sDMAS.cl"); - this->m_FilterID = "OpenCLBeamformingFilter"; - - this->Initialize(); - - unsigned int dim[] = { 128, 2048, 2 }; - - m_InputImage->Initialize(mitk::MakeScalarPixelType(), 3, dim); - - m_ChunkSize[0] = 128; - m_ChunkSize[1] = 128; - m_ChunkSize[2] = 8; - - m_UsedLinesCalculation = mitk::OCLUsedLinesCalculation::New(m_Conf); - m_DelayCalculation = mitk::OCLDelayCalculation::New(m_Conf); - MITK_INFO << "Instantiating OCL beamforming Filter...[Done]"; -} - -mitk::PhotoacousticOCLBeamformingFilter::~PhotoacousticOCLBeamformingFilter() -{ - if (this->m_PixelCalculation) - { - clReleaseKernel(m_PixelCalculation); - } - - if (m_ApodizationBuffer) clReleaseMemObject(m_ApodizationBuffer); - if (m_ElementHeightsBuffer) clReleaseMemObject(m_ElementHeightsBuffer); - if (m_ElementPositionsBuffer) clReleaseMemObject(m_ElementPositionsBuffer); -} - -void mitk::PhotoacousticOCLBeamformingFilter::Update() -{ - //Check if context & program available - if (!this->Initialize()) - { - us::ServiceReference ref = GetModuleContext()->GetServiceReference(); - OclResourceService* resources = GetModuleContext()->GetService(ref); - - // clean-up also the resources - resources->InvalidateStorage(); - mitkThrow() << "Filter is not initialized. Cannot update."; - } - else { - // Execute - this->Execute(); - } -} - -void mitk::PhotoacousticOCLBeamformingFilter::UpdateDataBuffers() -{ - us::ServiceReference ref = GetModuleContext()->GetServiceReference(); - OclResourceService* resources = GetModuleContext()->GetService(ref); - cl_context gpuContext = resources->GetContext(); - - //Initialize the Output - try - { - size_t outputSize = (size_t)m_Conf->GetReconstructionLines() * (size_t)m_Conf->GetSamplesPerLine() * - (size_t)m_inputSlices; - m_OutputDim[0] = m_Conf->GetReconstructionLines(); - m_OutputDim[1] = m_Conf->GetSamplesPerLine(); - m_OutputDim[2] = m_inputSlices; - this->InitExec(this->m_PixelCalculation, m_OutputDim, outputSize, sizeof(float)); - } - catch (const mitk::Exception& e) - { - MITK_ERROR << "Caught exception while initializing filter: " << e.what(); - return; - } - - cl_int clErr = 0; - MITK_DEBUG << "Updating GPU Buffers for new configuration"; - - // create the apodisation buffer - if (m_Apodisation == nullptr) - { - MITK_INFO << "No apodisation function set; Beamforming will be done without any apodisation."; - m_Apodisation = new float[1]{ 1 }; - m_ApodArraySize = 1; - } - - if (m_ApodizationBuffer) clReleaseMemObject(m_ApodizationBuffer); - - this->m_ApodizationBuffer = clCreateBuffer(gpuContext, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(float) * m_ApodArraySize, const_cast(m_Apodisation), &clErr); - CHECK_OCL_ERR(clErr); - - if (m_ElementHeightsBuffer) clReleaseMemObject(m_ElementHeightsBuffer); - this->m_ElementHeightsBuffer = clCreateBuffer(gpuContext, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(float) * m_Conf->GetTransducerElements(), const_cast(m_Conf->GetElementHeights()), &clErr); - CHECK_OCL_ERR(clErr); - - if (m_ElementPositionsBuffer) clReleaseMemObject(m_ElementPositionsBuffer); - this->m_ElementPositionsBuffer = clCreateBuffer(gpuContext, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(float) * m_Conf->GetTransducerElements(), const_cast(m_Conf->GetElementPositions()), &clErr); - CHECK_OCL_ERR(clErr); - // calculate used lines - - m_UsedLinesCalculation->SetElementPositionsBuffer(m_ElementPositionsBuffer); - m_UsedLinesCalculation->SetElementHeightsBuffer(m_ElementHeightsBuffer); - m_UsedLinesCalculation->Update(); - m_UsedLinesBuffer = m_UsedLinesCalculation->GetGPUOutput()->GetGPUBuffer(); - - // calculate the Delays - m_DelayCalculation->SetInputs(m_UsedLinesBuffer); - m_DelayCalculation->Update(); - - m_DelaysBuffer = m_DelayCalculation->GetGPUOutput()->GetGPUBuffer(); -} - -void mitk::PhotoacousticOCLBeamformingFilter::Execute() -{ - cl_int clErr = 0; - UpdateDataBuffers(); - if (m_Conf->GetGeometry() == mitk::BeamformingSettings::ProbeGeometry::Linear) - { - unsigned int reconstructionLines = this->m_Conf->GetReconstructionLines(); - unsigned int samplesPerLine = this->m_Conf->GetSamplesPerLine(); - - clErr = clSetKernelArg(this->m_PixelCalculation, 2, sizeof(cl_mem), &(this->m_UsedLinesBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 3, sizeof(cl_mem), &(this->m_DelaysBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 4, sizeof(cl_mem), &(this->m_ApodizationBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 5, sizeof(cl_ushort), &(this->m_ApodArraySize)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 6, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[0])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 7, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[1])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 8, sizeof(cl_uint), &(m_inputSlices)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 9, sizeof(cl_uint), &(reconstructionLines)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 10, sizeof(cl_uint), &(samplesPerLine)); - } - else - { - int reconstructionLines = this->m_Conf->GetReconstructionLines(); - int samplesPerLine = this->m_Conf->GetSamplesPerLine(); - float totalSamples_i = (float)(m_Conf->GetReconstructionDepth()) / (float)(m_Conf->GetSpeedOfSound() * m_Conf->GetTimeSpacing()); - totalSamples_i = totalSamples_i <= m_Conf->GetInputDim()[1] ? totalSamples_i : m_Conf->GetInputDim()[1]; - float horizontalExtent = m_Conf->GetHorizontalExtent(); - float mult = 1 / (this->m_Conf->GetTimeSpacing() * this->m_Conf->GetSpeedOfSound()); - char isPAImage = (char)m_Conf->GetIsPhotoacousticImage(); - - clErr = clSetKernelArg(this->m_PixelCalculation, 2, sizeof(cl_mem), &(this->m_ElementHeightsBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 3, sizeof(cl_mem), &(this->m_ElementPositionsBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 4, sizeof(cl_mem), &(this->m_ApodizationBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 5, sizeof(cl_ushort), &(this->m_ApodArraySize)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 6, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[0])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 7, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[1])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 8, sizeof(cl_int), &(m_inputSlices)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 9, sizeof(cl_int), &(reconstructionLines)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 10, sizeof(cl_int), &(samplesPerLine)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 11, sizeof(cl_float), &(totalSamples_i)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 12, sizeof(cl_float), &(horizontalExtent)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 13, sizeof(cl_float), &(mult)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 14, sizeof(cl_char), &(isPAImage)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 15, sizeof(cl_mem), &(this->m_UsedLinesBuffer)); - } - // execute the filter on a 2D/3D NDRange - if (m_OutputDim[2] == 1 || m_ChunkSize[2] == 1) - { - if (!this->ExecuteKernelChunksInBatches(m_PixelCalculation, 2, m_ChunkSize, m_inputSlices, 50)) - mitkThrow() << "openCL Error when executing Kernel"; - } - else - { - if (!this->ExecuteKernelChunksInBatches(m_PixelCalculation, 3, m_ChunkSize, m_inputSlices, 50)) - mitkThrow() << "openCL Error when executing Kernel"; - } - - // signalize the GPU-side data changed - m_Output->Modified(GPU_DATA); -} - -us::Module *mitk::PhotoacousticOCLBeamformingFilter::GetModule() -{ - return us::GetModuleContext()->GetModule(); -} - -bool mitk::PhotoacousticOCLBeamformingFilter::Initialize() -{ - bool buildErr = true; - cl_int clErr = 0; - - if (OclFilter::Initialize()) - { - if (m_Conf->GetGeometry() == mitk::BeamformingSettings::ProbeGeometry::Linear) - { - switch (m_Conf->GetAlgorithm()) - { - case BeamformingSettings::BeamformingAlgorithm::DAS: - { - MITK_INFO << "DAS bf"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckDAS", &clErr); - break; - } - case BeamformingSettings::BeamformingAlgorithm::DMAS: - { - MITK_INFO << "DMAS bf"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckDMAS", &clErr); - break; - } - case BeamformingSettings::BeamformingAlgorithm::sDMAS: - { - MITK_INFO << "sDMAS bf"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "cksDMAS", &clErr); - break; - } - default: - { - MITK_INFO << "No beamforming algorithm specified, setting to DAS"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckDAS", &clErr); - break; - } - } - } - else - { - switch (m_Conf->GetAlgorithm()) - { - case BeamformingSettings::BeamformingAlgorithm::DAS: - { - MITK_INFO << "DAS bf"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckDAS_g", &clErr); - break; - } - case BeamformingSettings::BeamformingAlgorithm::DMAS: - { - MITK_INFO << "DMAS bf"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckDMAS_g", &clErr); - break; - } - case BeamformingSettings::BeamformingAlgorithm::sDMAS: - { - MITK_INFO << "sDMAS bf"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "cksDMAS_g", &clErr); - break; - } - default: - { - MITK_INFO << "No beamforming algorithm specified, setting to DAS"; - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckDAS_g", &clErr); - break; - } - } - } - buildErr |= CHECK_OCL_ERR(clErr); - } - - CHECK_OCL_ERR(clErr); - - return (OclFilter::IsInitialized() && buildErr); -} - -void mitk::PhotoacousticOCLBeamformingFilter::SetInput(mitk::Image::Pointer image) -{ - OclDataSetToDataSetFilter::SetInput(image); - m_InputImage = image; - m_inputSlices = image->GetDimension(2); -} - -void mitk::PhotoacousticOCLBeamformingFilter::SetInput(void* data, unsigned int* dimensions, unsigned int BpE) -{ - OclDataSetToDataSetFilter::SetInput(data, dimensions[0] * dimensions[1] * dimensions[2], BpE); -} - -mitk::Image::Pointer mitk::PhotoacousticOCLBeamformingFilter::GetOutputAsImage() -{ - mitk::Image::Pointer outputImage = mitk::Image::New(); - - if (m_Output->IsModified(GPU_DATA)) - { - void* pData = m_Output->TransferDataToCPU(m_CommandQue); - - const unsigned int dimension = 3; - unsigned int dimensions[3] = { (unsigned int)m_OutputDim[0], (unsigned int)m_OutputDim[1], (unsigned int)m_OutputDim[2] }; - - const mitk::SlicedGeometry3D::Pointer p_slg = m_InputImage->GetSlicedGeometry(); - - MITK_DEBUG << "Creating new MITK Image."; - - outputImage->Initialize(this->GetOutputType(), dimension, dimensions); - outputImage->SetSpacing(p_slg->GetSpacing()); - outputImage->SetImportVolume(pData, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - free(pData); - } - - MITK_DEBUG << "Image Initialized."; - - return outputImage; -} - -void* mitk::PhotoacousticOCLBeamformingFilter::GetOutput() -{ - return OclDataSetToDataSetFilter::GetOutput(); -} -#endif diff --git a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.cpp b/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.cpp deleted file mode 100644 index fb777ce6a1..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#define _USE_MATH_DEFINES - -#include -#include "./OpenCLFilter/mitkPhotoacousticOCLDelayCalculation.h" -#include "usServiceReference.h" -#include "mitkImageReadAccessor.h" - -mitk::OCLDelayCalculation::OCLDelayCalculation(mitk::BeamformingSettings::Pointer settings) - : m_PixelCalculation(NULL), - m_Conf(settings) -{ - this->AddSourceFile("DelayCalculation.cl"); - this->m_FilterID = "DelayCalculation"; - - m_ChunkSize[0] = 128; - m_ChunkSize[1] = 128; - m_ChunkSize[2] = 8; - - this->Initialize(); -} - -mitk::OCLDelayCalculation::~OCLDelayCalculation() -{ - if (this->m_PixelCalculation) - { - clReleaseKernel(m_PixelCalculation); - } -} - -void mitk::OCLDelayCalculation::Update() -{ - //Check if context & program available - if (!this->Initialize()) - { - us::ServiceReference ref = GetModuleContext()->GetServiceReference(); - OclResourceService* resources = GetModuleContext()->GetService(ref); - - // clean-up also the resources - resources->InvalidateStorage(); - mitkThrow() << "Filter is not initialized. Cannot update."; - } - else { - // Execute - this->Execute(); - } -} - -void mitk::OCLDelayCalculation::Execute() -{ - cl_int clErr = 0; - - unsigned int gridDim[3] = { m_Conf->GetReconstructionLines() / 2, m_Conf->GetSamplesPerLine(), 1 }; - m_BufferSize = gridDim[0] * gridDim[1] * 1; - - try - { - this->InitExecNoInput(this->m_PixelCalculation, gridDim, m_BufferSize, sizeof(unsigned short)); - } - catch (const mitk::Exception& e) - { - MITK_ERROR << "Caught exception while initializing Delay Calculation filter: " << e.what(); - return; - } - - // This calculation is the same for all kernels, so for performance reasons simply perform it here instead of within the kernels - m_DelayMultiplicatorRaw = 1 / (m_Conf->GetTimeSpacing()*m_Conf->GetSpeedOfSound()) * - (m_Conf->GetPitchInMeters()*(float)m_Conf->GetTransducerElements()); - - // as openCL does not support bool as a kernel argument, we need to buffer this value in a char... - m_IsPAImage = m_Conf->GetIsPhotoacousticImage(); - - unsigned int reconstructionLines = this->m_Conf->GetReconstructionLines(); - unsigned int samplesperLine = this->m_Conf->GetSamplesPerLine(); - - float totalSamples_i = (float)(m_Conf->GetReconstructionDepth()) / (float)(m_Conf->GetSpeedOfSound() * m_Conf->GetTimeSpacing()); - totalSamples_i = totalSamples_i <= m_Conf->GetInputDim()[1] ? totalSamples_i : m_Conf->GetInputDim()[1]; - - clErr = clSetKernelArg(this->m_PixelCalculation, 1, sizeof(cl_mem), &(this->m_UsedLines)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 2, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[0])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 3, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[1])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 4, sizeof(cl_uint), &(reconstructionLines)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 5, sizeof(cl_uint), &(samplesperLine)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 6, sizeof(cl_char), &(this->m_IsPAImage)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 7, sizeof(cl_float), &(this->m_DelayMultiplicatorRaw)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 8, sizeof(cl_float), &(totalSamples_i)); - - CHECK_OCL_ERR(clErr); - - // execute the filter on a 3D NDRange - if (!this->ExecuteKernelChunksInBatches(m_PixelCalculation, 2, m_ChunkSize, 16, 50)) - mitkThrow() << "openCL Error when executing Kernel"; - // signalize the GPU-side data changed - m_Output->Modified(GPU_DATA); -} - -us::Module *mitk::OCLDelayCalculation::GetModule() -{ - return us::GetModuleContext()->GetModule(); -} - -bool mitk::OCLDelayCalculation::Initialize() -{ - bool buildErr = true; - cl_int clErr = 0; - - if (OclFilter::Initialize()) - { - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckDelayCalculationSphe", &clErr); - buildErr |= CHECK_OCL_ERR(clErr); - } - return (OclFilter::IsInitialized() && buildErr); -} diff --git a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.cpp b/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.cpp deleted file mode 100644 index e7ef79294c..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#if defined(PHOTOACOUSTICS_USE_GPU) || DOXYGEN - -#include "./OpenCLFilter/mitkPhotoacousticOCLUsedLinesCalculation.h" -#include "usServiceReference.h" -#include "mitkImageReadAccessor.h" - -mitk::OCLUsedLinesCalculation::OCLUsedLinesCalculation(mitk::BeamformingSettings::Pointer settings) - : m_PixelCalculation(NULL), - m_Conf(settings) -{ - this->AddSourceFile("UsedLinesCalculation.cl"); - this->m_FilterID = "UsedLinesCalculation"; - - m_ChunkSize[0] = 128; - m_ChunkSize[1] = 128; - m_ChunkSize[2] = 8; - - this->Initialize(); -} - -mitk::OCLUsedLinesCalculation::~OCLUsedLinesCalculation() -{ - if (this->m_PixelCalculation) - { - clReleaseKernel(m_PixelCalculation); - } -} - -void mitk::OCLUsedLinesCalculation::SetElementHeightsBuffer(cl_mem elementHeightsBuffer) -{ - m_ElementHeightsBuffer = elementHeightsBuffer; -} - -void mitk::OCLUsedLinesCalculation::SetElementPositionsBuffer(cl_mem elementPositionsBuffer) -{ - m_ElementPositionsBuffer = elementPositionsBuffer; -} - -void mitk::OCLUsedLinesCalculation::Update() -{ - //Check if context & program available - if (!this->Initialize()) - { - us::ServiceReference ref = GetModuleContext()->GetServiceReference(); - OclResourceService* resources = GetModuleContext()->GetService(ref); - - // clean-up also the resources - resources->InvalidateStorage(); - mitkThrow() << "Filter is not initialized. Cannot update."; - } - else { - // Execute - this->Execute(); - } -} - -void mitk::OCLUsedLinesCalculation::Execute() -{ - cl_int clErr = 0; - - unsigned int gridDim[3] = { m_Conf->GetReconstructionLines(), m_Conf->GetSamplesPerLine(), 1 }; - size_t outputSize = gridDim[0] * gridDim[1] * 3; - - try - { - this->InitExecNoInput(this->m_PixelCalculation, gridDim, outputSize, sizeof(unsigned short)); - } - catch (const mitk::Exception& e) - { - MITK_ERROR << "Caught exception while initializing UsedLines filter: " << e.what(); - return; - } - - if (m_Conf->GetGeometry() == mitk::BeamformingSettings::ProbeGeometry::Linear) - { - // This calculation is the same for all kernels, so for performance reasons simply perform it here instead of within the kernels - m_part = (tan(m_Conf->GetAngle() / 360 * 2 * itk::Math::pi) * - ((m_Conf->GetSpeedOfSound() * m_Conf->GetTimeSpacing())) / - (m_Conf->GetPitchInMeters() * m_Conf->GetTransducerElements())) * m_Conf->GetInputDim()[0]; - unsigned int reconLines = this->m_Conf->GetReconstructionLines(); - unsigned int samplesPerLine = this->m_Conf->GetSamplesPerLine(); - - float totalSamples_i = (float)(m_Conf->GetReconstructionDepth()) / (float)(m_Conf->GetSpeedOfSound() * m_Conf->GetTimeSpacing()); - totalSamples_i = totalSamples_i <= m_Conf->GetInputDim()[1] ? totalSamples_i : m_Conf->GetInputDim()[1]; - clErr = clSetKernelArg(this->m_PixelCalculation, 1, sizeof(cl_float), &(this->m_part)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 2, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[0])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 3, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[1])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 4, sizeof(cl_uint), &(reconLines)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 5, sizeof(cl_uint), &(samplesPerLine)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 6, sizeof(cl_float), &(totalSamples_i)); - } - else - { - unsigned int reconLines = this->m_Conf->GetReconstructionLines(); - unsigned int samplesPerLine = this->m_Conf->GetSamplesPerLine(); - - float probeRadius = m_Conf->GetProbeRadius(); - float sin_deg = std::sin(m_Conf->GetAngle() / 360 * 2 * itk::Math::pi); - - float horizontalExtent = m_Conf->GetHorizontalExtent(); - float verticalExtent = m_Conf->GetReconstructionDepth(); - - clErr = clSetKernelArg(this->m_PixelCalculation, 1, sizeof(cl_mem), &(this->m_ElementHeightsBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 2, sizeof(cl_mem), &(this->m_ElementPositionsBuffer)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 3, sizeof(cl_float), &(sin_deg)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 4, sizeof(cl_float), &(probeRadius)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 5, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[0])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 6, sizeof(cl_uint), &(this->m_Conf->GetInputDim()[1])); - clErr |= clSetKernelArg(this->m_PixelCalculation, 7, sizeof(cl_uint), &(reconLines)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 8, sizeof(cl_uint), &(samplesPerLine)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 9, sizeof(cl_float), &(horizontalExtent)); - clErr |= clSetKernelArg(this->m_PixelCalculation, 10, sizeof(cl_float), &(verticalExtent)); - } - - CHECK_OCL_ERR(clErr); - - // execute the filter on a 2D NDRange - if (!this->ExecuteKernelChunksInBatches(m_PixelCalculation, 2, m_ChunkSize, 16, 50)) - mitkThrow() << "openCL Error when executing Kernel"; - - // signalize the GPU-side data changed - m_Output->Modified(GPU_DATA); -} - -us::Module *mitk::OCLUsedLinesCalculation::GetModule() -{ - return us::GetModuleContext()->GetModule(); -} - -bool mitk::OCLUsedLinesCalculation::Initialize() -{ - bool buildErr = true; - cl_int clErr = 0; - - if (OclFilter::Initialize()) - { - if (m_Conf->GetGeometry() == mitk::BeamformingSettings::ProbeGeometry::Linear) - { - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckUsedLines", &clErr); - buildErr |= CHECK_OCL_ERR(clErr); - } - else - { - this->m_PixelCalculation = clCreateKernel(this->m_ClProgram, "ckUsedLines_g", &clErr); - buildErr |= CHECK_OCL_ERR(clErr); - } - } - return (OclFilter::IsInitialized() && buildErr); -} -#endif diff --git a/Modules/PhotoacousticsAlgorithms/source/filters/mitkBandpassFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/filters/mitkBandpassFilter.cpp deleted file mode 100644 index eecd2270e4..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/filters/mitkBandpassFilter.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#define _USE_MATH_DEFINES -#include - -#include "mitkBandpassFilter.h" - -#include "../ITKFilter/ITKUltrasound/itkFFT1DComplexConjugateToRealImageFilter.h" -#include "../ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h" -#include "itkComplexToModulusImageFilter.h" -#include "itkMultiplyImageFilter.h" -#include "mitkIOUtil.h" -#include "mitkITKImageImport.h" -#include "mitkImageCast.h" - -mitk::BandpassFilter::BandpassFilter() - : m_HighPass(0), - m_LowPass(50), - m_HighPassAlpha(1), - m_LowPassAlpha(1), - m_FilterService(mitk::PhotoacousticFilterService::New()) -{ - MITK_INFO << "Instantiating BandpassFilter..."; - SetNumberOfIndexedInputs(1); - SetNumberOfIndexedOutputs(1); - MITK_INFO << "Instantiating BandpassFilter...[Done]"; -} - -mitk::BandpassFilter::~BandpassFilter() -{ - MITK_INFO << "Destructed BandpassFilter."; -} - -void mitk::BandpassFilter::SanityCheckPreconditions() -{ - auto input = GetInput(); - - std::string type = input->GetPixelType().GetTypeAsString(); - if (!(type == "scalar (float)" || type == " (float)")) - { - MITK_ERROR << "This filter can currently only handle float type images."; - mitkThrow() << "This filter can currently only handle float type images."; - } - if (m_HighPass > m_LowPass) - { - MITK_ERROR << "High Pass is higher than Low Pass; aborting."; - mitkThrow() << "High Pass is higher than Low Pass; aborting."; - } -} - -itk::Image::Pointer BPFunction(mitk::Image::Pointer reference, - float cutoffFrequencyPixelHighPass, - float cutoffFrequencyPixelLowPass, - float alphaHighPass, - float alphaLowPass) -{ - float *imageData = new float[reference->GetDimension(0) * reference->GetDimension(1)]; - - float width = cutoffFrequencyPixelLowPass - cutoffFrequencyPixelHighPass; - float center = cutoffFrequencyPixelHighPass + width / 2.f; - - for (unsigned int n = 0; n < reference->GetDimension(1); ++n) - { - imageData[reference->GetDimension(0) * n] = 0; - } - for (int n = 0; n < width; ++n) - { - imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = 1; - if (n <= (alphaHighPass * (width - 1)) / 2.f) - { - if (alphaHighPass > 0.00001f) - { - imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = - (1 + cos(itk::Math::pi * (2 * n / (alphaHighPass * (width - 1)) - 1))) / 2; - } - else - { - imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = 1; - } - } - else if (n >= (width - 1) * (1 - alphaLowPass / 2.f)) - { - if (alphaLowPass > 0.00001f) - { - imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = - (1 + cos(itk::Math::pi * (2 * n / (alphaLowPass * (width - 1)) + 1 - 2 / alphaLowPass))) / 2; - } - else - { - imageData[reference->GetDimension(0) * (int)(n + center - (width / 2.f))] = 1; - } - } - } - - for (unsigned int n = reference->GetDimension(1) / 2; n < reference->GetDimension(1); ++n) - { - imageData[reference->GetDimension(0) * n] = - imageData[(reference->GetDimension(1) - (n + 1)) * reference->GetDimension(0)]; - } - - for (unsigned int line = 1; line < reference->GetDimension(0); ++line) - { - for (unsigned int sample = 0; sample < reference->GetDimension(1); ++sample) - { - imageData[reference->GetDimension(0) * sample + line] = imageData[reference->GetDimension(0) * sample]; - } - } - - typedef itk::Image ImageType; - ImageType::RegionType region; - ImageType::IndexType start; - start.Fill(0); - - region.SetIndex(start); - - ImageType::SizeType size; - size[0] = reference->GetDimension(0); - size[1] = reference->GetDimension(1); - size[2] = reference->GetDimension(2); - - region.SetSize(size); - - ImageType::SpacingType SpacingItk; - SpacingItk[0] = reference->GetGeometry()->GetSpacing()[0]; - SpacingItk[1] = reference->GetGeometry()->GetSpacing()[1]; - SpacingItk[2] = reference->GetGeometry()->GetSpacing()[2]; - - ImageType::Pointer image = ImageType::New(); - image->SetRegions(region); - image->Allocate(); - image->FillBuffer(itk::NumericTraits::Zero); - image->SetSpacing(SpacingItk); - - ImageType::IndexType pixelIndex; - - for (unsigned int slice = 0; slice < reference->GetDimension(2); ++slice) - { - for (unsigned int line = 0; line < reference->GetDimension(0); ++line) - { - for (unsigned int sample = 0; sample < reference->GetDimension(1); ++sample) - { - pixelIndex[0] = line; - pixelIndex[1] = sample; - pixelIndex[2] = slice; - - image->SetPixel(pixelIndex, imageData[line + sample * reference->GetDimension(0)]); - } - } - } - - delete[] imageData; - - return image; -} - -void mitk::BandpassFilter::GenerateData() -{ - SanityCheckPreconditions(); - auto input = GetInput(); - auto output = GetOutput(); - mitk::Image::Pointer resampledInput = input; - - double powerOfTwo = std::log2(input->GetDimension(1)); - int finalSize = 0; - double spacingResize = 1; - - // check if this is a power of two by checking that log2 is int - if (std::fmod(powerOfTwo, 1.0) >= std::numeric_limits::epsilon()) - { - finalSize = (int)pow(2, std::ceil(powerOfTwo)); - double dim[2] = {(double)input->GetDimension(0), (double)finalSize }; - resampledInput = m_FilterService->ApplyResamplingToDim(input, dim); - spacingResize = (double)input->GetDimension(1) / finalSize; - } - - // do a fourier transform, multiply with an appropriate window for the filter, and transform back - typedef itk::Image RealImageType; - RealImageType::Pointer image; - mitk::CastToItkImage(resampledInput, image); - typedef itk::FFT1DRealToComplexConjugateImageFilter ForwardFFTFilterType; - typedef ForwardFFTFilterType::OutputImageType ComplexImageType; - ForwardFFTFilterType::Pointer forwardFFTFilter = ForwardFFTFilterType::New(); - forwardFFTFilter->SetInput(image); - forwardFFTFilter->SetDirection(1); - - try - { - forwardFFTFilter->UpdateOutputInformation(); - } - catch (itk::ExceptionObject &error) - { - std::cerr << "Error: " << error << std::endl; - MITK_ERROR << "Bandpass could not be applied"; - mitkThrow() << "bandpass error"; - } - - if (m_HighPass > m_LowPass) - mitkThrow() << "High pass frequency higher than low pass frequency, abort"; - - float singleVoxel = spacingResize / (m_TimeSpacing * resampledInput->GetDimension(1)); // [Hz] - if(m_IsBFImage) - singleVoxel = spacingResize / (resampledInput->GetGeometry()->GetSpacing()[1] / 1e3 / m_SpeedOfSound * resampledInput->GetDimension(1)); // [Hz] - float cutoffPixelHighPass = std::min((m_HighPass / singleVoxel), (float)resampledInput->GetDimension(1) / 2.0f); - float cutoffPixelLowPass = std::min((m_LowPass / singleVoxel), (float)resampledInput->GetDimension(1) / 2.0f); - - MITK_INFO << "SingleVoxel: " << singleVoxel; - MITK_INFO << "HighPass: " << m_HighPass; - MITK_INFO << "LowPass: " << m_LowPass; - - MITK_INFO << "cutoffPixelHighPass: " << cutoffPixelHighPass; - MITK_INFO << "cutoffPixelLowPass: " << cutoffPixelLowPass; - - RealImageType::Pointer fftMultiplicator = - BPFunction(resampledInput, cutoffPixelHighPass, cutoffPixelLowPass, m_HighPassAlpha, m_LowPassAlpha); - - typedef itk::MultiplyImageFilter MultiplyFilterType; - MultiplyFilterType::Pointer multiplyFilter = MultiplyFilterType::New(); - multiplyFilter->SetInput1(forwardFFTFilter->GetOutput()); - multiplyFilter->SetInput2(fftMultiplicator); - - /* - GrabItkImageMemory(fftMultiplicator, output); - mitk::IOUtil::Save(output, "D:/fftImage.nrrd"); - - typedef itk::ComplexToModulusImageFilter< ComplexImageType, RealImageType > modulusType; - modulusType::Pointer modul = modulusType::New(); - - modul->SetInput(multiplyFilter->GetOutput()); - GrabItkImageMemory(modul->GetOutput(), output); - mitk::IOUtil::Save(output, "D:/fftout.nrrd"); - - modul->SetInput(forwardFFTFilter->GetOutput()); - GrabItkImageMemory(modul->GetOutput(), output); - mitk::IOUtil::Save(output, "D:/fftin.nrrd");*/ - - typedef itk::FFT1DComplexConjugateToRealImageFilter InverseFilterType; - InverseFilterType::Pointer inverseFFTFilter = InverseFilterType::New(); - inverseFFTFilter->SetInput(multiplyFilter->GetOutput()); - inverseFFTFilter->SetDirection(1); - - GrabItkImageMemory(inverseFFTFilter->GetOutput(), output); - - double dim[2] = { (double)input->GetDimension(0), (double)input->GetDimension(1) }; - auto resampledOutput = m_FilterService->ApplyResamplingToDim(output, dim); - - output->Initialize(mitk::MakeScalarPixelType(), 3, input->GetDimensions()); - output->SetSpacing(resampledOutput->GetGeometry()->GetSpacing()); - ImageReadAccessor copy(resampledOutput); - output->SetImportVolume(copy.GetData()); -} diff --git a/Modules/PhotoacousticsAlgorithms/source/filters/mitkBeamformingFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/filters/mitkBeamformingFilter.cpp deleted file mode 100644 index fdd45dd679..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/filters/mitkBeamformingFilter.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkProperties.h" -#include "mitkImageReadAccessor.h" -#include -#include -#include -#include -#include -#include "mitkImageCast.h" -#include "mitkBeamformingFilter.h" -#include "mitkBeamformingUtils.h" - -mitk::BeamformingFilter::BeamformingFilter(mitk::BeamformingSettings::Pointer settings) : - m_OutputData(nullptr), - m_InputData(nullptr), - m_Conf(settings) -{ - MITK_INFO << "Instantiating BeamformingFilter..."; - this->SetNumberOfIndexedInputs(1); - this->SetNumberOfRequiredInputs(1); - - m_ProgressHandle = [](int, std::string) {}; -#if defined(PHOTOACOUSTICS_USE_GPU) - m_BeamformingOclFilter = mitk::PhotoacousticOCLBeamformingFilter::New(m_Conf); -#else - m_BeamformingOclFilter = mitk::PhotoacousticOCLBeamformingFilter::New(); -#endif - - MITK_INFO << "Instantiating BeamformingFilter...[Done]"; -} - -void mitk::BeamformingFilter::SetProgressHandle(std::function progressHandle) -{ - m_ProgressHandle = progressHandle; -} - -mitk::BeamformingFilter::~BeamformingFilter() -{ - MITK_INFO << "Destructed BeamformingFilter"; -} - -void mitk::BeamformingFilter::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - - mitk::Image* output = this->GetOutput(); - mitk::Image* input = const_cast (this->GetInput()); - if (!output->IsInitialized()) - { - return; - } - - input->SetRequestedRegionToLargestPossibleRegion(); -} - -void mitk::BeamformingFilter::GenerateOutputInformation() -{ - mitk::Image::ConstPointer input = this->GetInput(); - mitk::Image::Pointer output = this->GetOutput(); - - if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime())) - return; - - mitk::Vector3D spacing; - spacing[0] = m_Conf->GetHorizontalExtent() / m_Conf->GetReconstructionLines() * 1000; - float desiredYSpacing = m_Conf->GetReconstructionDepth() * 1000 / m_Conf->GetSamplesPerLine(); - float maxYSpacing = m_Conf->GetSpeedOfSound() * m_Conf->GetTimeSpacing() * input->GetDimension(1) / m_Conf->GetSamplesPerLine() * 1000; - spacing[1] = desiredYSpacing < maxYSpacing ? desiredYSpacing : maxYSpacing; - spacing[2] = 1; - - unsigned int dim[] = { m_Conf->GetReconstructionLines(), m_Conf->GetSamplesPerLine(), input->GetDimension(2)}; - output->Initialize(mitk::MakeScalarPixelType(), 3, dim); - output->GetGeometry()->SetSpacing(spacing); - output->GetGeometry()->Modified(); - output->SetPropertyList(input->GetPropertyList()->Clone()); - - m_TimeOfHeaderInitialization.Modified(); -} - -void mitk::BeamformingFilter::GenerateData() -{ - mitk::Image::Pointer input = this->GetInput(); - if (!(input->GetPixelType().GetTypeAsString() == "scalar (float)" || input->GetPixelType().GetTypeAsString() == " (float)")) - { - MITK_ERROR << "Pixel type of input needs to be float for this filter to work."; - mitkThrow() << "Pixel type of input needs to be float for this filter to work."; - } - - GenerateOutputInformation(); - mitk::Image::Pointer output = this->GetOutput(); - - if (!output->IsInitialized()) - return; - - auto begin = std::chrono::high_resolution_clock::now(); // debbuging the performance... - - if (!m_Conf->GetUseGPU()) - { - int progInterval = output->GetDimension(2) / 20 > 1 ? output->GetDimension(2) / 20 : 1; - // the interval at which we update the gui progress bar - - float inputDim[2] = { (float)input->GetDimension(0), (float)input->GetDimension(1) }; - float outputDim[2] = { (float)output->GetDimension(0), (float)output->GetDimension(1) }; - - for (unsigned int i = 0; i < output->GetDimension(2); ++i) // seperate Slices should get Beamforming seperately applied - { - mitk::ImageReadAccessor inputReadAccessor(input, input->GetSliceData(i)); - m_InputData = (float*)inputReadAccessor.GetData(); - - m_OutputData = new float[m_Conf->GetReconstructionLines()*m_Conf->GetSamplesPerLine()]; - - // fill the image with zeros - for (int l = 0; l < outputDim[0]; ++l) - { - for (int s = 0; s < outputDim[1]; ++s) - { - m_OutputData[l*(short)outputDim[1] + s] = 0; - } - } - - std::thread *threads = new std::thread[(short)outputDim[0]]; - - // every line will be beamformed in a seperate thread - if (m_Conf->GetAlgorithm() == BeamformingSettings::BeamformingAlgorithm::DAS) - { - for (short line = 0; line < outputDim[0]; ++line) - { - threads[line] = std::thread(&BeamformingUtils::DASSphericalLine, m_InputData, - m_OutputData, inputDim, outputDim, line, m_Conf); - } - } - else if (m_Conf->GetAlgorithm() == BeamformingSettings::BeamformingAlgorithm::DMAS) - { - for (short line = 0; line < outputDim[0]; ++line) - { - threads[line] = std::thread(&BeamformingUtils::DMASSphericalLine, m_InputData, - m_OutputData, inputDim, outputDim, line, m_Conf); - } - } - else if (m_Conf->GetAlgorithm() == BeamformingSettings::BeamformingAlgorithm::sDMAS) - { - for (short line = 0; line < outputDim[0]; ++line) - { - threads[line] = std::thread(&BeamformingUtils::sDMASSphericalLine, m_InputData, - m_OutputData, inputDim, outputDim, line, m_Conf); - } - } - // wait for all lines to finish - for (short line = 0; line < outputDim[0]; ++line) - { - threads[line].join(); - } - - output->SetSlice(m_OutputData, i); - - if (i % progInterval == 0) - m_ProgressHandle((int)((i + 1) / (float)output->GetDimension(2) * 100), "performing reconstruction"); - - delete[] m_OutputData; - m_OutputData = nullptr; - m_InputData = nullptr; - } - } -#if defined(PHOTOACOUSTICS_USE_GPU) || DOXYGEN - else - { - try - { - // first, we check whether the data is float, other formats are unsupported - if (!(input->GetPixelType().GetTypeAsString() == "scalar (float)" || input->GetPixelType().GetTypeAsString() == " (float)")) - { - MITK_ERROR << "Pixel type is not float, abort"; - mitkThrow() << "Pixel type is not float, abort"; - } - - unsigned long availableMemory = m_BeamformingOclFilter->GetDeviceMemory(); - - unsigned int batchSize = m_Conf->GetGPUBatchSize(); - unsigned int batches = (unsigned int)((float)input->GetDimension(2) / batchSize) + (input->GetDimension(2) % batchSize > 0); - - unsigned int batchDim[] = { input->GetDimension(0), input->GetDimension(1), batchSize }; - unsigned int batchDimLast[] = { input->GetDimension(0), input->GetDimension(1), input->GetDimension(2) % batchSize }; - - // the following safeguard is probably only needed for absurdly small GPU memory - if((unsigned long)batchSize * - ((unsigned long)(batchDim[0] * batchDim[1]) * 4 + // single input image (float) - (unsigned long)(m_Conf->GetReconstructionLines() * m_Conf->GetSamplesPerLine()) * 4) // single output image (float) - > availableMemory - - (unsigned long)(m_Conf->GetReconstructionLines() / 2 * m_Conf->GetSamplesPerLine()) * 2 - // Delays buffer (unsigned short) - (unsigned long)(m_Conf->GetReconstructionLines() * m_Conf->GetSamplesPerLine()) * 3 * 2 - // UsedLines buffer (unsigned short) - 50 * 1024 * 1024)// 50 MB buffer for local data, system purposes etc - { - MITK_ERROR << "device memory too small for GPU beamforming; try decreasing the batch size"; - return; - } - - mitk::ImageReadAccessor copy(input); - - for (unsigned int i = 0; i < batches; ++i) - { - m_ProgressHandle(100.f * (float)i / (float)batches, "performing reconstruction"); - - mitk::Image::Pointer inputBatch = mitk::Image::New(); - unsigned int num_Slices = 1; - if (i == batches - 1 && (input->GetDimension(2) % batchSize > 0)) - { - inputBatch->Initialize(mitk::MakeScalarPixelType(), 3, batchDimLast); - num_Slices = batchDimLast[2]; - } - else - { - inputBatch->Initialize(mitk::MakeScalarPixelType(), 3, batchDim); - num_Slices = batchDim[2]; - } - - inputBatch->SetSpacing(input->GetGeometry()->GetSpacing()); - - inputBatch->SetImportVolume(&(((float*)copy.GetData())[input->GetDimension(0) * input->GetDimension(1) * batchSize * i])); - - m_BeamformingOclFilter->SetApodisation(m_Conf->GetApodizationFunction(), m_Conf->GetApodizationArraySize()); - m_BeamformingOclFilter->SetInput(inputBatch); - m_BeamformingOclFilter->Update(); - - void* out = m_BeamformingOclFilter->GetOutput(); - - for (unsigned int slice = 0; slice < num_Slices; ++slice) - { - output->SetImportSlice( - &(((float*)out)[m_Conf->GetReconstructionLines() * m_Conf->GetSamplesPerLine() * slice]), - batchSize * i + slice, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - } - free(out); - } - } - catch (mitk::Exception &e) - { - std::string errorMessage = "Caught unexpected exception "; - errorMessage.append(e.what()); - MITK_ERROR << errorMessage; - - float* dummyData = new float[m_Conf->GetReconstructionLines() * m_Conf->GetSamplesPerLine() * m_Conf->GetInputDim()[2]]; - output->SetImportVolume(dummyData, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - } - } -#endif - m_TimeOfHeaderInitialization.Modified(); - - auto end = std::chrono::high_resolution_clock::now(); - MITK_INFO << "Beamforming of " << output->GetDimension(2) << " Images completed in " << ((float)std::chrono::duration_cast(end - begin).count()) / 1000000 << "ms" << std::endl; -} diff --git a/Modules/PhotoacousticsAlgorithms/source/filters/mitkBeamformingSettings.cpp b/Modules/PhotoacousticsAlgorithms/source/filters/mitkBeamformingSettings.cpp deleted file mode 100644 index 7afe9eb327..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/filters/mitkBeamformingSettings.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkBeamformingSettings.h" -#include "mitkBeamformingUtils.h" -#include "itkMutexLock.h" - -mitk::BeamformingSettings::BeamformingSettings(float pitchInMeters, - float speedOfSound, - float timeSpacing, - float angle, - bool isPhotoacousticImage, - unsigned int samplesPerLine, - unsigned int reconstructionLines, - unsigned int* inputDim, - float reconstructionDepth, - bool useGPU, - unsigned int GPUBatchSize, - Apodization apod, - unsigned int apodizationArraySize, - BeamformingAlgorithm algorithm, - ProbeGeometry geometry, - float probeRadius -) : - m_PitchInMeters(pitchInMeters), - m_SpeedOfSound(speedOfSound), - m_TimeSpacing(timeSpacing), - m_Angle(angle), - m_IsPhotoacousticImage(isPhotoacousticImage), - m_SamplesPerLine(samplesPerLine), - m_ReconstructionLines(reconstructionLines), - m_ReconstructionDepth(reconstructionDepth), - m_UseGPU(useGPU), - m_GPUBatchSize(GPUBatchSize), - m_Apod(apod), - m_ApodizationArraySize(apodizationArraySize), - m_Algorithm(algorithm), - m_Geometry(geometry), - m_ProbeRadius(probeRadius), - m_MinMaxLines(nullptr) -{ - if (inputDim == nullptr) - { - MITK_ERROR << "No input dimension given."; - mitkThrow() << "No input dimension given."; - } - - switch (GetApod()) - { - case BeamformingSettings::Apodization::Hann: - m_ApodizationFunction = mitk::BeamformingUtils::VonHannFunction(GetApodizationArraySize()); - break; - case BeamformingSettings::Apodization::Hamm: - m_ApodizationFunction = mitk::BeamformingUtils::HammFunction(GetApodizationArraySize()); - break; - case BeamformingSettings::Apodization::Box: - default: - m_ApodizationFunction = mitk::BeamformingUtils::BoxFunction(GetApodizationArraySize()); - break; - } - m_InputDim = new unsigned int[3]{ inputDim[0], inputDim[1], inputDim[2] }; - m_TransducerElements = m_InputDim[0]; - - m_ElementHeights = new float[m_TransducerElements]; - m_ElementPositions = new float[m_TransducerElements]; - - if (m_Geometry == ProbeGeometry::Concave) - { - float openingAngle = (m_TransducerElements * m_PitchInMeters) / (probeRadius * 2 * itk::Math::pi) * 2 * itk::Math::pi; - m_HorizontalExtent = std::sin(openingAngle / 2.f) * probeRadius * 2.f; - - float elementAngle = 0; - - for (unsigned int i = 0; i < m_TransducerElements; ++i) - { - elementAngle = ((i- m_TransducerElements /2.f) * m_PitchInMeters) / (probeRadius * 2 * itk::Math::pi) * 2 * itk::Math::pi; - m_ElementHeights[i] = probeRadius - std::cos(elementAngle) * probeRadius; - m_ElementPositions[i] = m_HorizontalExtent/2.f + std::sin(elementAngle) * probeRadius; - } - } - else - { - m_HorizontalExtent = m_PitchInMeters * m_TransducerElements; - for (unsigned int i = 0; i < m_TransducerElements; ++i) - { - m_ElementHeights[i] = 0; - m_ElementPositions[i] = i * m_PitchInMeters; - } - } -} - -mitk::BeamformingSettings::~BeamformingSettings() -{ - MITK_INFO << "Destructing beamforming settings..."; - //Free memory - if (m_ApodizationFunction != nullptr) - { - MITK_INFO << "Deleting apodization function..."; - delete[] m_ApodizationFunction; - MITK_INFO << "Deleting apodization function...[Done]"; - } - - if (m_InputDim != nullptr) - { - MITK_INFO << "Deleting input dim..."; - delete[] m_InputDim; - MITK_INFO << "Deleting input dim...[Done]"; - } - if (m_ElementHeights != nullptr || m_ElementPositions != nullptr) - { - MITK_INFO << "Deleting element geometry..."; - if (m_ElementHeights != nullptr) - delete[] m_ElementHeights; - - if (m_ElementPositions != nullptr) - delete[] m_ElementPositions; - MITK_INFO << "Destructing beamforming settings...[Done]"; - } - if (m_MinMaxLines) - delete[] m_MinMaxLines; -} - -unsigned short* mitk::BeamformingSettings::GetMinMaxLines() -{ - if (!m_MinMaxLines) - m_MinMaxLines = mitk::BeamformingUtils::MinMaxLines(this); - return m_MinMaxLines; -} diff --git a/Modules/PhotoacousticsAlgorithms/source/filters/mitkCastToFloatImageFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/filters/mitkCastToFloatImageFilter.cpp deleted file mode 100644 index ae7a162d83..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/filters/mitkCastToFloatImageFilter.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkCastToFloatImageFilter.h" -#include "mitkImageReadAccessor.h" -#include "mitkImageWriteAccessor.h" - -mitk::CastToFloatImageFilter::CastToFloatImageFilter() -{ - MITK_INFO << "Instantiating CastToFloatImageFilter..."; - SetNumberOfIndexedInputs(1); - SetNumberOfIndexedOutputs(1); - MITK_INFO << "Instantiating CastToFloatImageFilter...[Done]"; -} - -mitk::CastToFloatImageFilter::~CastToFloatImageFilter() -{ - MITK_INFO << "Destructed CastToFloatImageFilter."; -} - -template -float* CastData(const void* inputArray, unsigned long length) -{ - float* outputArray = new float[length]; - for (unsigned long i = 0; i < length; ++i) - { - outputArray[i] = (float)((TPixelType*)inputArray)[i]; - } - return outputArray; -} - -void mitk::CastToFloatImageFilter::GenerateData() -{ - mitk::Image::Pointer inputImage = GetInput(); - mitk::Image::Pointer outputImage = GetOutput(); - - std::string type = inputImage->GetPixelType().GetTypeAsString(); - - if (type == "scalar (float)" || type == " (float)") - { - outputImage->Initialize(mitk::MakeScalarPixelType(), inputImage->GetDimension(), inputImage->GetDimensions()); - outputImage->SetSpacing(inputImage->GetGeometry()->GetSpacing()); - outputImage->SetImportVolume(mitk::ImageWriteAccessor(inputImage).GetData(), 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - MITK_INFO << "Input is already float type. Nothing to do here."; - return; - } - if (outputImage.IsNull()) - { - outputImage = mitk::Image::New(); - } - - unsigned long length = 1; - for (unsigned int i = 0, limit = inputImage->GetDimension(); i < limit; ++i) - length *= inputImage->GetDimensions()[i]; - - float* outputData; - - mitk::ImageReadAccessor readAccess(inputImage); - - if (type == "scalar (short)" || type == " (short)") - outputData = CastData(readAccess.GetData(), length); - else if (type == "scalar (unsigned short)" || type == " (unsigned short)" || type == " (unsigned_short)" || type == "scalar (unsigned_short)") - outputData = CastData(readAccess.GetData(), length); - else if (type == "scalar (int)" || type == " (int)") - outputData = CastData(readAccess.GetData(), length); - else if (type == "scalar (unsigned int)" || type == " (unsigned int)" || type == " (unsigned_int)" || type == "scalar (unsigned_int)") - outputData = CastData(readAccess.GetData(), length); - else if (type == "scalar (double)" || type == " (double)") - outputData = CastData(readAccess.GetData(), length); - else if (type == "scalar (long)" || type == " (long)") - outputData = CastData(readAccess.GetData(), length); - else - mitkThrow() << "The given image has a datatype that is not yet supported. Given datatype: " << type; - - outputImage->Initialize(mitk::MakeScalarPixelType(), inputImage->GetDimension(), inputImage->GetDimensions()); - outputImage->SetSpacing(inputImage->GetGeometry()->GetSpacing()); - outputImage->SetImportVolume(outputData, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - delete[] outputData; -} diff --git a/Modules/PhotoacousticsAlgorithms/source/filters/mitkCropImageFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/filters/mitkCropImageFilter.cpp deleted file mode 100644 index 2ad7cc6ee7..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/filters/mitkCropImageFilter.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkCropImageFilter.h" -#include -#include - -mitk::CropImageFilter::CropImageFilter() : - m_XPixelsCropStart(0), - m_YPixelsCropStart(0), - m_ZPixelsCropStart(0), - m_XPixelsCropEnd(0), - m_YPixelsCropEnd(0), - m_ZPixelsCropEnd(0) -{ - MITK_INFO << "Instantiating CropImageFilter..."; - SetNumberOfIndexedInputs(1); - SetNumberOfIndexedOutputs(1); - MITK_INFO << "Instantiating CropImageFilter...[Done]"; -} - -mitk::CropImageFilter::~CropImageFilter() -{ - MITK_INFO << "Destructed CastToFloatImageFilter."; -} - -void mitk::CropImageFilter::SanityCheckPreconditions() -{ - mitk::Image::Pointer inputImage = GetInput(); - - std::string type = inputImage->GetPixelType().GetTypeAsString(); - if (!(type == "scalar (float)" || type == " (float)")) - { - MITK_ERROR << "This filter can currently only handle float type images."; - mitkThrow() << "This filter can currently only handle float type images."; - } - - if (m_XPixelsCropStart + m_XPixelsCropEnd >= inputImage->GetDimension(0)) - { - MITK_ERROR << "X Crop area too large for selected input image"; - mitkThrow() << "X Crop area too large for selected input image"; - } - if (m_YPixelsCropStart + m_YPixelsCropEnd >= inputImage->GetDimension(1)) - { - MITK_ERROR << "Y Crop area too large for selected input image"; - mitkThrow() << "Y Crop area too large for selected input image"; - } - - if (inputImage->GetDimension() == 3) - { - if (m_ZPixelsCropStart + m_ZPixelsCropEnd >= inputImage->GetDimension(2)) - { - MITK_INFO << m_ZPixelsCropStart + m_ZPixelsCropEnd << "vs" << inputImage->GetDimension(2); - MITK_ERROR << "Z Crop area too large for selected input image"; - mitkThrow() << "Z Crop area too large for selected input image"; - } - } - else - { - if (m_ZPixelsCropStart + m_ZPixelsCropEnd > 0) - { - mitkThrow() << "Z Crop area too large for selected input image"; - } - } -} - -void mitk::CropImageFilter::GenerateData() -{ - mitk::Image::Pointer inputImage = GetInput(); - mitk::Image::Pointer outputImage = GetOutput(); - - SanityCheckPreconditions(); - unsigned int* outputDim; - unsigned int* inputDim = inputImage->GetDimensions(); - if (inputImage->GetDimension() == 2) - outputDim = new unsigned int[2]{ inputImage->GetDimension(0) - m_XPixelsCropStart - m_XPixelsCropEnd, - inputImage->GetDimension(1) - m_YPixelsCropStart - m_YPixelsCropEnd }; - else - outputDim = new unsigned int[3]{ inputImage->GetDimension(0) - m_XPixelsCropStart - m_XPixelsCropEnd, - inputImage->GetDimension(1) - m_YPixelsCropStart - m_YPixelsCropEnd, - inputImage->GetDimension(2) - m_ZPixelsCropStart - m_ZPixelsCropEnd }; - - outputImage->Initialize(mitk::MakeScalarPixelType(), inputImage->GetDimension(), outputDim); - outputImage->SetSpacing(inputImage->GetGeometry()->GetSpacing()); - - ImageReadAccessor accR(inputImage); - const float* inputData = (const float*)(accR.GetData()); - - ImageWriteAccessor accW(outputImage); - float* outputData = (float*)(accW.GetData()); - - unsigned int zLength = inputImage->GetDimension() == 3 ? outputDim[2] : 1; - - for (unsigned int sl = 0; sl < zLength; ++sl) - { - for (unsigned int l = 0; l < outputDim[0]; ++l) - { - for (unsigned int s = 0; s < outputDim[1]; ++s) - { - outputData[l + s*outputDim[0] + sl*outputDim[0] * outputDim[1]] = - inputData[(l + m_XPixelsCropStart) + (s + m_YPixelsCropStart)*inputDim[0] + - (sl + m_ZPixelsCropStart)*inputDim[0] * inputDim[1]]; - } - } - } - delete[] outputDim; -} diff --git a/Modules/PhotoacousticsAlgorithms/source/filters/mitkImageSliceSelectionFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/filters/mitkImageSliceSelectionFilter.cpp deleted file mode 100644 index 6c609828e5..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/filters/mitkImageSliceSelectionFilter.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkImageSliceSelectionFilter.h" - -mitk::ImageSliceSelectionFilter::ImageSliceSelectionFilter() -{ - MITK_INFO << "Instantiating CropImageFilter..."; - SetNumberOfIndexedInputs(1); - SetNumberOfIndexedOutputs(1); - MITK_INFO << "Instantiating CropImageFilter...[Done]"; -} - -mitk::ImageSliceSelectionFilter::~ImageSliceSelectionFilter() -{ - MITK_INFO << "Destructed CastToFloatImageFilter."; -} - -void mitk::ImageSliceSelectionFilter::GenerateData() -{ -} diff --git a/Modules/PhotoacousticsAlgorithms/source/mitkPhotoacousticMotionCorrectionFilter.cpp b/Modules/PhotoacousticsAlgorithms/source/mitkPhotoacousticMotionCorrectionFilter.cpp deleted file mode 100644 index 3899b0617f..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/mitkPhotoacousticMotionCorrectionFilter.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "./mitkPhotoacousticMotionCorrectionFilter.h" -#include - -mitk::PhotoacousticMotionCorrectionFilter:: - PhotoacousticMotionCorrectionFilter() { - // Set the defaults for the OpticalFlowFarneback algorithm - // The values are taken directly out of Thomas's - // US-CV-Based-Optical-Flow-Carotis.ipyn - m_BatchSize = 5; - m_PyrScale = 0.5; - m_Levels = 1; - m_WinSize = 40; - m_Iterations = 2; - m_PolyN = 7; - m_PolySigma = 1.5; - m_Flags = 0; - - m_MaxValue = 255.0; - m_MinValue = 0.0; - - this->SetNumberOfIndexedInputs(2); - this->SetNumberOfIndexedOutputs(2); - this->SetNthOutput(0, mitk::Image::New()); - this->SetNthOutput(1, mitk::Image::New()); -} - -mitk::PhotoacousticMotionCorrectionFilter:: - ~PhotoacousticMotionCorrectionFilter() {} - -void mitk::PhotoacousticMotionCorrectionFilter::SetPaInput( - mitk::Image::Pointer input) { - this->SetInput(0, input); -} - -mitk::Image::Pointer mitk::PhotoacousticMotionCorrectionFilter::GetPaInput() { - return this->GetInput(0); -} - -void mitk::PhotoacousticMotionCorrectionFilter::SetUsInput( - mitk::Image::Pointer input) { - this->SetInput(1, input); -} - -mitk::Image::Pointer mitk::PhotoacousticMotionCorrectionFilter::GetUsInput() { - return this->GetInput(1); -} - -mitk::Image::Pointer mitk::PhotoacousticMotionCorrectionFilter::GetPaOutput() { - return this->GetOutput(0); -} - -mitk::Image::Pointer mitk::PhotoacousticMotionCorrectionFilter::GetUsOutput() { - return this->GetOutput(1); -} - -void mitk::PhotoacousticMotionCorrectionFilter::CheckInput( - mitk::Image::Pointer paImage, mitk::Image::Pointer usImage) { - // Check that we actually got some images - if (!paImage || !usImage) { - MITK_ERROR << "We did not get two images!"; - throw std::invalid_argument("One of the images was NULL."); - } - - // Check that the image dimensions are the same - if (paImage->GetDimension() != IMAGE_DIMENSION || usImage->GetDimension() != IMAGE_DIMENSION) { - MITK_ERROR << "Mismatching image dimensions detected in the motion " - "compensation filter."; - throw std::invalid_argument("Both images must have dimension 3."); - } - - // Check that each dimension has the same size - for (unsigned int i = 0; i < paImage->GetDimension(); ++i) { - if (paImage->GetDimensions()[i] != usImage->GetDimensions()[i]) { - MITK_ERROR << "Mismatching image dimensions detected in the motion " - "compensation filter."; - throw std::invalid_argument( - "Both images must have the same length in each dimension."); - } - } -} - -void mitk::PhotoacousticMotionCorrectionFilter::InitializeOutputIfNecessary( - mitk::Image::Pointer paInput, mitk::Image::Pointer usInput, - mitk::Image::Pointer paOutput, mitk::Image::Pointer usOutput) { - if (paOutput->GetDimension() != IMAGE_DIMENSION) { - this->InitializeOutput(paInput, paOutput); - this->InitializeOutput(usInput, usOutput); - } - - for (unsigned int i = 0; i < usOutput->GetDimension(); ++i) { - if (usOutput->GetDimensions()[i] != usInput->GetDimensions()[i]) { - this->InitializeOutput(paInput, paOutput); - this->InitializeOutput(usInput, usOutput); - break; - } - } -} - -void mitk::PhotoacousticMotionCorrectionFilter::InitializeOutput( - mitk::Image::Pointer input, mitk::Image::Pointer output) { - output->Initialize(input); - mitk::ImageReadAccessor accessor(input); - output->SetImportVolume(accessor.GetData()); -} - -void mitk::PhotoacousticMotionCorrectionFilter::PerformCorrection( - mitk::Image::Pointer paInput, mitk::Image::Pointer usInput, - mitk::Image::Pointer paOutput, mitk::Image::Pointer usOutput) { - - // If batch size was set to 0, use one single batch for the whole data set. - unsigned int batch; - if (m_BatchSize == 0) { - batch = paInput->GetDimensions()[IMAGE_DIMENSION - 1]; - } else { - batch = m_BatchSize; - } - - for (unsigned int i = 0; i < paInput->GetDimensions()[IMAGE_DIMENSION - 1]; ++i) { - - // Get the 2d matrix from slice at i - m_PaMat = this->GetMatrix(paInput, i); - m_UsMat = this->GetMatrix(usInput, i); - - // At the beginning of a batch we set the new reference image and directly - // write the result images - if (i % batch == 0) { - // Rescale reference to full char resolution - m_UsRef = this->FitMatrixToChar(m_UsMat); - m_UsRes = m_UsMat.clone(); - m_PaRes = m_PaMat.clone(); - } else { - cv::Mat UsMatRescaled = this->FitMatrixToChar(m_UsMat); - cv::calcOpticalFlowFarneback(m_UsRef, UsMatRescaled, m_Flow, m_PyrScale, - m_Levels, m_WinSize, m_Iterations, m_PolyN, - m_PolySigma, m_Flags); - - m_Map = this->ComputeFlowMap(m_Flow); - - // Apply the flow to the matrices - cv::remap(m_PaMat, m_PaRes, m_Map, cv::noArray(), cv::INTER_LINEAR); - cv::remap(m_UsMat, m_UsRes, m_Map, cv::noArray(), cv::INTER_LINEAR); - } - - // Enter the matrix as a slice at position i into output - this->InsertMatrixAsSlice(m_PaRes, paOutput, i); - this->InsertMatrixAsSlice(m_UsRes, usOutput, i); - } -} - -// Copied from https://stackoverflow.com/questions/17459584/opencv-warping-image-based-on-calcopticalflowfarneback -cv::Mat mitk::PhotoacousticMotionCorrectionFilter::ComputeFlowMap(cv::Mat flow) { - cv::Mat map(flow.size(), flow.type()); - - for (int y = 0; y < map.rows; ++y) { - for(int x = 0; x < map.cols; ++x) { - cv::Point2f f = flow.at(y,x); - map.at(y,x) = cv::Point2f(x + f.x, y + f.y); - } - } - - return map; -} - -cv::Mat mitk::PhotoacousticMotionCorrectionFilter::FitMatrixToChar(cv::Mat mat) { - - if (m_MaxValue == m_MinValue) { - - return mat.clone(); - } - - return MAX_MATRIX*(mat.clone() - m_MinValue) / (m_MaxValue - m_MinValue); -} - -cv::Mat mitk::PhotoacousticMotionCorrectionFilter::GetMatrix( - const mitk::Image::Pointer input, unsigned int i) { - - // Access slice i of image input - mitk::ImageReadAccessor accessor(input, input->GetSliceData(i)); - mitk::Image::Pointer slice = mitk::Image::New(); - slice->Initialize(input->GetPixelType(), IMAGE_DIMENSION - 1, input->GetDimensions()); - slice->SetVolume(accessor.GetData()); - - // Transform the slice to matrix - m_ImageToOpenCVFilter->SetImage(slice); - return m_ImageToOpenCVFilter->GetOpenCVMat(); -} - -void mitk::PhotoacousticMotionCorrectionFilter::InsertMatrixAsSlice( - cv::Mat mat, mitk::Image::Pointer output, unsigned int i) { - - m_OpenCVToImageFilter->SetOpenCVMat(mat); - m_OpenCVToImageFilter->Update(); - mitk::Image::Pointer slice = m_OpenCVToImageFilter->GetOutput(); - - mitk::ImageReadAccessor accessor(slice); - output->SetSlice(accessor.GetData(), i); -} - -// TODO: remove debug messages -void mitk::PhotoacousticMotionCorrectionFilter::GenerateData() { - MITK_INFO << "Start motion compensation."; - - mitk::Image::Pointer paInput = this->GetInput(0); - mitk::Image::Pointer usInput = this->GetInput(1); - mitk::Image::Pointer paOutput = this->GetOutput(0); - mitk::Image::Pointer usOutput = this->GetOutput(1); - - // Check that we have two input images with agreeing dimensions - this->CheckInput(paInput, usInput); - - // Check the output images and (re-)initialize, if necessary. - this->InitializeOutputIfNecessary(paInput, usInput, paOutput, usOutput); - - // Set Max and Min of ultrasonic image - this->m_MaxValue = usInput->GetStatistics()->GetScalarValueMax(); - this->m_MinValue = usInput->GetStatistics()->GetScalarValueMin(); - - // m_ImageToOpenCVFilter->SetImage(paInput); - this->PerformCorrection(paInput, usInput, paOutput, usOutput); - - MITK_INFO << "Motion compensation accomplished."; -} diff --git a/Modules/PhotoacousticsAlgorithms/source/utils/mitkBeamformingUtils.cpp b/Modules/PhotoacousticsAlgorithms/source/utils/mitkBeamformingUtils.cpp deleted file mode 100644 index 30c197f9e3..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/utils/mitkBeamformingUtils.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkProperties.h" -#include "mitkImageReadAccessor.h" -#include -#include -#include -#include -#include -#include "mitkImageCast.h" -#include "mitkBeamformingUtils.h" - -mitk::BeamformingUtils::BeamformingUtils() -{ -} - -mitk::BeamformingUtils::~BeamformingUtils() -{ -} - -float* mitk::BeamformingUtils::VonHannFunction(int samples) -{ - float* ApodWindow = new float[samples]; - - for (int n = 0; n < samples; ++n) - { - ApodWindow[n] = (1 - cos(2 * itk::Math::pi * n / (samples - 1))) / 2; - } - - return ApodWindow; -} - -float* mitk::BeamformingUtils::HammFunction(int samples) -{ - float* ApodWindow = new float[samples]; - - for (int n = 0; n < samples; ++n) - { - ApodWindow[n] = 0.54 - 0.46*cos(2 * itk::Math::pi*n / (samples - 1)); - } - - return ApodWindow; -} - -float* mitk::BeamformingUtils::BoxFunction(int samples) -{ - float* ApodWindow = new float[samples]; - - for (int n = 0; n < samples; ++n) - { - ApodWindow[n] = 1; - } - - return ApodWindow; -} - -unsigned short* mitk::BeamformingUtils::MinMaxLines(const mitk::BeamformingSettings::Pointer config) -{ - unsigned int outputL = (unsigned int)config->GetReconstructionLines(); - unsigned int outputS = (unsigned int)config->GetSamplesPerLine(); - - unsigned short* dDest = new unsigned short[outputL * outputS * 2]; - - unsigned int inputL = (unsigned int)config->GetInputDim()[0]; - - float horizontalExtent = config->GetHorizontalExtent(); - float verticalExtent = config->GetReconstructionDepth(); - - float partMult = (tan(config->GetAngle() / 360 * 2 * itk::Math::pi) * - ((config->GetSpeedOfSound() * config->GetTimeSpacing())) / - (config->GetPitchInMeters() * config->GetTransducerElements())) * inputL; - float totalSamples_i = (float)(config->GetReconstructionDepth()) / (float)(config->GetSpeedOfSound() * config->GetTimeSpacing()); - - totalSamples_i = totalSamples_i <= config->GetInputDim()[1] ? totalSamples_i : config->GetInputDim()[1]; - - if ((int)config->GetGeometry() == 0) // if this is raw data from a linear probe geometry - { - for (unsigned int x = 0; x < outputL; ++x) - { - for (unsigned int y = 0; y < outputS; ++y) - { - float l_i = (float)x / outputL * inputL; - float s_i = (float)y / (float)outputS * totalSamples_i; - - float part = partMult * s_i; - if (part < 1) - part = 1; - unsigned short maxLine = std::min((l_i + part) + 1, (float)inputL); - unsigned short minLine = std::max((l_i - part), 0.0f); - - dDest[y * 2 * outputL + 2 * x] = (unsigned short)minLine; //minLine - dDest[y * 2 * outputL + 2 * x + 1] = (unsigned short)maxLine; //maxLine - } - } - - } - else // if this is *not* raw data from a linear probe geometry (currently meaning its a concave geometry) - { - float probeRadius = config->GetProbeRadius(); - float* elementHeights = config->GetElementHeights(); - float* elementPositions = config->GetElementPositions(); - - float sin_deg = std::sin(config->GetAngle() / 360 * 2 * itk::Math::pi); - - float x_center_pos = horizontalExtent / 2.0; - float y_center_pos = probeRadius; - - for (unsigned int x = 0; x < outputL; ++x) - { - for (unsigned int y = 0; y < outputS; ++y) - { - float x_cm = (float)x / outputL * horizontalExtent; // x*Xspacing - float y_cm = (float)y / (float)outputS * verticalExtent; // y*Yspacing - - unsigned int maxLine = inputL; - unsigned int minLine = 0; - - for (unsigned int l_s = minLine; l_s <= inputL; l_s += 1) - { - float x_sensor_pos = elementPositions[l_s]; - float y_sensor_pos = elementHeights[l_s]; - - float distance_sensor_target = sqrt((x_cm - x_sensor_pos)*(x_cm - x_sensor_pos) - + (y_cm - y_sensor_pos)*(y_cm - y_sensor_pos)); - - // solving line equation - float center_to_sensor_a = y_sensor_pos - y_center_pos; - float center_to_sensor_b = x_center_pos - x_sensor_pos; - float center_to_sensor_c = -(center_to_sensor_a * x_center_pos + center_to_sensor_b * y_center_pos); - float distance_to_sensor_direction = std::fabs((center_to_sensor_a * x_cm - + center_to_sensor_b * y_cm - + center_to_sensor_c)) / - (sqrt(center_to_sensor_a*center_to_sensor_a + center_to_sensor_b*center_to_sensor_b)); - - if (distance_to_sensor_direction < sin_deg*distance_sensor_target) - { - minLine = l_s; - break; - } - } - - for (unsigned int l_s = maxLine - 1; l_s > minLine; l_s -= 1) // start with maxline-1 otherwise elementPositions[] will go out of range - { - float x_sensor_pos = elementPositions[l_s]; - float y_sensor_pos = elementHeights[l_s]; - - float distance_sensor_target = sqrt((x_cm - x_sensor_pos)*(x_cm - x_sensor_pos) - + (y_cm - y_sensor_pos)*(y_cm - y_sensor_pos)); - - // solving line equation - float center_to_sensor_a = y_sensor_pos - y_center_pos; - float center_to_sensor_b = x_center_pos - x_sensor_pos; - float center_to_sensor_c = -(center_to_sensor_a * x_center_pos + center_to_sensor_b * y_center_pos); - float distance_to_sensor_direction = std::fabs((center_to_sensor_a * x_cm - + center_to_sensor_b * y_cm - + center_to_sensor_c)) / - (sqrt(center_to_sensor_a*center_to_sensor_a + center_to_sensor_b*center_to_sensor_b)); - - if (distance_to_sensor_direction < sin_deg*distance_sensor_target) - { - maxLine = l_s; - break; - } - } - dDest[y * 2 * outputL + 2 * x] = (unsigned short)minLine; //minLine - dDest[y * 2 * outputL + 2 * x + 1] = (unsigned short)maxLine; //maxLine - } - } - } - return dDest; -} - -void mitk::BeamformingUtils::DASSphericalLine( - float* input, float* output, float inputDim[2], float outputDim[2], - const short& line, const mitk::BeamformingSettings::Pointer config) -{ - const float* apodisation = config->GetApodizationFunction(); - const short apodArraySize = config->GetApodizationArraySize(); - - const float* elementHeights = config->GetElementHeights(); - const float* elementPositions = config->GetElementPositions(); - - float& inputS = inputDim[1]; - float& inputL = inputDim[0]; - - float& outputS = outputDim[1]; - float& outputL = outputDim[0]; - - short AddSample = 0; - short maxLine = 0; - short minLine = 0; - float l_p = 0; - float s_i = 0; - - float apod_mult = 1; - - short usedLines = (maxLine - minLine); - - float totalSamples_i = (float)(config->GetReconstructionDepth()) / (float)(config->GetSpeedOfSound() * config->GetTimeSpacing()); - totalSamples_i = totalSamples_i <= inputS ? totalSamples_i : inputS; - - l_p = (float)line / outputL * config->GetHorizontalExtent(); - - for (short sample = 0; sample < outputS; ++sample) - { - s_i = (float)sample / outputS * totalSamples_i; - - minLine = config->GetMinMaxLines()[2*sample*(short)outputL + 2*line]; - maxLine = config->GetMinMaxLines()[2*sample*(short)outputL + 2*line + 1]; - usedLines = (maxLine - minLine); - - apod_mult = (float)apodArraySize / (float)usedLines; - - for (short l_s = minLine; l_s < maxLine; ++l_s) - { - AddSample = (int)sqrt( - pow(s_i-elementHeights[l_s]/(config->GetSpeedOfSound()*config->GetTimeSpacing()), 2) - + - pow((1 / (config->GetTimeSpacing()*config->GetSpeedOfSound())) * (l_p - elementPositions[l_s]), 2) - ) + (1 - config->GetIsPhotoacousticImage())*s_i; - if (AddSample < inputS && AddSample >= 0) - output[sample*(short)outputL + line] += input[l_s + AddSample*(short)inputL] * - apodisation[(short)((l_s - minLine)*apod_mult)]; - else - --usedLines; - } - output[sample*(short)outputL + line] = output[sample*(short)outputL + line] / usedLines; - } -} - -void mitk::BeamformingUtils::DMASSphericalLine( - float* input, float* output, float inputDim[2], float outputDim[2], - const short& line, const mitk::BeamformingSettings::Pointer config) -{ - const float* apodisation = config->GetApodizationFunction(); - const short apodArraySize = config->GetApodizationArraySize(); - - const float* elementHeights = config->GetElementHeights(); - const float* elementPositions = config->GetElementPositions(); - - float& inputS = inputDim[1]; - float& inputL = inputDim[0]; - - float& outputS = outputDim[1]; - float& outputL = outputDim[0]; - - short maxLine = 0; - short minLine = 0; - float l_p = 0; - float s_i = 0; - - float apod_mult = 1; - - float mult = 0; - - short usedLines = (maxLine - minLine); - - float totalSamples_i = (float)(config->GetReconstructionDepth()) / - (float)(config->GetSpeedOfSound() * config->GetTimeSpacing()); - totalSamples_i = totalSamples_i <= inputS ? totalSamples_i : inputS; - - l_p = (float)line / outputL * config->GetHorizontalExtent(); - - for (short sample = 0; sample < outputS; ++sample) - { - s_i = (float)sample / outputS * totalSamples_i; - - minLine = config->GetMinMaxLines()[2 * sample*(short)outputL + 2 * line]; - maxLine = config->GetMinMaxLines()[2 * sample*(short)outputL + 2 * line + 1]; - usedLines = (maxLine - minLine); - - apod_mult = (float)apodArraySize / (float)usedLines; - - //calculate the AddSamples beforehand to save some time - short* AddSample = new short[maxLine - minLine]; - for (short l_s = 0; l_s < maxLine - minLine; ++l_s) - { - AddSample[l_s] = (int)sqrt( - pow(s_i - elementHeights[l_s + minLine] / (config->GetSpeedOfSound()*config->GetTimeSpacing()), 2) - + - pow((1 / (config->GetTimeSpacing()*config->GetSpeedOfSound())) * (l_p - elementPositions[l_s + minLine]), 2) - ) + (1 - config->GetIsPhotoacousticImage())*s_i; - } - - float s_1 = 0; - float s_2 = 0; - - for (short l_s1 = minLine; l_s1 < maxLine - 1; ++l_s1) - { - if (AddSample[l_s1 - minLine] < inputS && AddSample[l_s1 - minLine] >= 0) - { - for (short l_s2 = l_s1 + 1; l_s2 < maxLine; ++l_s2) - { - if (AddSample[l_s2 - minLine] < inputS && AddSample[l_s2 - minLine] >= 0) - { - s_2 = input[l_s2 + AddSample[l_s2 - minLine] * (short)inputL]; - s_1 = input[l_s1 + AddSample[l_s1 - minLine] * (short)inputL]; - - mult = s_2 * apodisation[(int)((l_s2 - minLine)*apod_mult)] * s_1 * apodisation[(int)((l_s1 - minLine)*apod_mult)]; - output[sample*(short)outputL + line] += sqrt(fabs(mult)) * ((mult > 0) - (mult < 0)); - } - } - } - else - --usedLines; - } - - output[sample*(short)outputL + line] = output[sample*(short)outputL + line] / (float)(pow(usedLines, 2) - (usedLines - 1)); - - delete[] AddSample; - } -} - -void mitk::BeamformingUtils::sDMASSphericalLine( - float* input, float* output, float inputDim[2], float outputDim[2], - const short& line, const mitk::BeamformingSettings::Pointer config) -{ - const float* apodisation = config->GetApodizationFunction(); - const short apodArraySize = config->GetApodizationArraySize(); - - const float* elementHeights = config->GetElementHeights(); - const float* elementPositions = config->GetElementPositions(); - - float& inputS = inputDim[1]; - float& inputL = inputDim[0]; - - float& outputS = outputDim[1]; - float& outputL = outputDim[0]; - - short maxLine = 0; - short minLine = 0; - float l_p = 0; - float s_i = 0; - - float apod_mult = 1; - - float mult = 0; - - short usedLines = (maxLine - minLine); - - float totalSamples_i = (float)(config->GetReconstructionDepth()) / - (float)(config->GetSpeedOfSound() * config->GetTimeSpacing()); - totalSamples_i = totalSamples_i <= inputS ? totalSamples_i : inputS; - - l_p = (float)line / outputL * config->GetHorizontalExtent(); - - for (short sample = 0; sample < outputS; ++sample) - { - s_i = (float)sample / outputS * totalSamples_i; - - minLine = config->GetMinMaxLines()[2 * sample*(short)outputL + 2 * line]; - maxLine = config->GetMinMaxLines()[2 * sample*(short)outputL + 2 * line + 1]; - usedLines = (maxLine - minLine); - - apod_mult = (float)apodArraySize / (float)usedLines; - - //calculate the AddSamples beforehand to save some time - short* AddSample = new short[maxLine - minLine]; - for (short l_s = 0; l_s < maxLine - minLine; ++l_s) - { - AddSample[l_s] = (int)sqrt( - pow(s_i - elementHeights[l_s + minLine] / (config->GetSpeedOfSound()*config->GetTimeSpacing()), 2) - + - pow((1 / (config->GetTimeSpacing()*config->GetSpeedOfSound())) * (l_p - elementPositions[l_s + minLine]), 2) - ) + (1 - config->GetIsPhotoacousticImage())*s_i; - } - - float s_1 = 0; - float s_2 = 0; - float sign = 0; - - for (short l_s1 = minLine; l_s1 < maxLine - 1; ++l_s1) - { - if (AddSample[l_s1 - minLine] < inputS && AddSample[l_s1 - minLine] >= 0) - { - s_1 = input[l_s1 + AddSample[l_s1 - minLine] * (short)inputL]; - sign += s_1; - - for (short l_s2 = l_s1 + 1; l_s2 < maxLine; ++l_s2) - { - if (AddSample[l_s2 - minLine] < inputS && AddSample[l_s2 - minLine] >= 0) - { - s_2 = input[l_s2 + AddSample[l_s2 - minLine] * (short)inputL]; - - mult = s_2 * apodisation[(int)((l_s2 - minLine)*apod_mult)] * s_1 * apodisation[(int)((l_s1 - minLine)*apod_mult)]; - output[sample*(short)outputL + line] += sqrt(fabs(mult)) * ((mult > 0) - (mult < 0)); - } - } - } - else - --usedLines; - } - - output[sample*(short)outputL + line] = output[sample*(short)outputL + line] / (float)(pow(usedLines, 2) - (usedLines - 1)) * ((sign > 0) - (sign < 0)); - - delete[] AddSample; - } -} diff --git a/Modules/PhotoacousticsAlgorithms/source/utils/mitkPhotoacousticFilterService.cpp b/Modules/PhotoacousticsAlgorithms/source/utils/mitkPhotoacousticFilterService.cpp deleted file mode 100644 index cd3f6749c5..0000000000 --- a/Modules/PhotoacousticsAlgorithms/source/utils/mitkPhotoacousticFilterService.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPhotoacousticFilterService.h" - -#include "mitkITKImageImport.h" -#include -#include -#include "./OpenCLFilter/mitkPhotoacousticBModeFilter.h" -#include "mitkConvert2Dto3DImageFilter.h" -#include -#include "../ITKFilter/ITKUltrasound/itkBModeImageFilter.h" -#include "../ITKFilter/itkPhotoacousticBModeImageFilter.h" -#include - -// itk dependencies -#include "itkImage.h" -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkCropImageFilter.h" -#include "itkRescaleIntensityImageFilter.h" -#include "itkIntensityWindowingImageFilter.h" -#include -#include "itkBSplineInterpolateImageFunction.h" -#include - -// needed itk image filters -#include "mitkImageCast.h" - -mitk::PhotoacousticFilterService::PhotoacousticFilterService() -{ - MITK_INFO << "[PhotoacousticFilterService] created filter service"; -} - -mitk::PhotoacousticFilterService::~PhotoacousticFilterService() -{ - MITK_INFO << "[PhotoacousticFilterService] destructed filter service"; -} - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ApplyBmodeFilter( - mitk::Image::Pointer inputImage, - BModeMethod method, bool UseLogFilter) -{ - // the image needs to be of floating point type for the envelope filter to work; the casting is done automatically by the CastToItkImage - typedef itk::Image< float, 3 > itkFloatImageType; - - auto floatImage = ConvertToFloat(inputImage); - - if (method == BModeMethod::Abs) - { - PhotoacousticBModeFilter::Pointer filter = PhotoacousticBModeFilter::New(); - filter->UseLogFilter(UseLogFilter); - filter->SetInput(floatImage); - filter->Update(); - return filter->GetOutput(); - } - - typedef itk::BModeImageFilter < itkFloatImageType, itkFloatImageType > BModeFilterType; - BModeFilterType::Pointer bModeFilter = BModeFilterType::New(); // LogFilter - - typedef itk::PhotoacousticBModeImageFilter < itkFloatImageType, itkFloatImageType > PhotoacousticBModeImageFilter; - PhotoacousticBModeImageFilter::Pointer photoacousticBModeFilter = PhotoacousticBModeImageFilter::New(); // No LogFilter - - typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; - ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); - - itkFloatImageType::Pointer itkImage; - - mitk::CastToItkImage(floatImage, itkImage); - - if (UseLogFilter) - { - bModeFilter->SetInput(itkImage); - bModeFilter->SetDirection(1); - itkImage = bModeFilter->GetOutput(); - } - else - { - photoacousticBModeFilter->SetInput(itkImage); - photoacousticBModeFilter->SetDirection(1); - itkImage = photoacousticBModeFilter->GetOutput(); - } - - return mitk::GrabItkImageMemory(itkImage); -} - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ApplyResampling( - mitk::Image::Pointer inputImage, - double *outputSpacing) -{ - typedef itk::Image< float, 3 > itkFloatImageType; - - auto floatImage = ConvertToFloat(inputImage); - - typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; - ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); - - itkFloatImageType::Pointer itkImage; - - mitk::CastToItkImage(floatImage, itkImage); - - itkFloatImageType::SpacingType outputSpacingItk; - itkFloatImageType::SizeType inputSizeItk = itkImage->GetLargestPossibleRegion().GetSize(); - itkFloatImageType::SizeType outputSizeItk = inputSizeItk; - - outputSpacingItk[0] = outputSpacing[0]; - outputSpacingItk[1] = outputSpacing[1]; - outputSpacingItk[2] = itkImage->GetSpacing()[2]; - - outputSizeItk[0] = outputSizeItk[0] * (floatImage->GetGeometry()->GetSpacing()[0] / outputSpacing[0]); - outputSizeItk[1] = outputSizeItk[1] * (floatImage->GetGeometry()->GetSpacing()[1] / outputSpacing[1]); - - resampleImageFilter->SetInput(itkImage); - resampleImageFilter->SetSize(outputSizeItk); - resampleImageFilter->SetOutputSpacing(outputSpacingItk); - - resampleImageFilter->UpdateLargestPossibleRegion(); - return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput()); -} - - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ApplyResamplingToDim( - mitk::Image::Pointer inputImage, - double *outputDimension) -{ - typedef itk::Image< float, 3 > itkFloatImageType; - - auto floatImage = ConvertToFloat(inputImage); - - typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; - ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); - - itkFloatImageType::Pointer itkImage; - - mitk::CastToItkImage(floatImage, itkImage); - - itkFloatImageType::SpacingType outputSpacingItk; - itkFloatImageType::SizeType inputSizeItk = itkImage->GetLargestPossibleRegion().GetSize(); - itkFloatImageType::SizeType outputSizeItk = inputSizeItk; - - outputSizeItk[0] = outputDimension[0]; - outputSizeItk[1] = outputDimension[1]; - - MITK_INFO << outputSizeItk[0] << " " << outputSizeItk[1]; - - outputSpacingItk[0] = (double)inputSizeItk[0] / (double)outputSizeItk[0] * floatImage->GetGeometry()->GetSpacing()[0]; - outputSpacingItk[1] = (double)inputSizeItk[1] / (double)outputSizeItk[1] * floatImage->GetGeometry()->GetSpacing()[1]; - outputSpacingItk[2] = itkImage->GetSpacing()[2]; - - MITK_INFO << outputSpacingItk[0] << " " << outputSpacingItk[1]; - - resampleImageFilter->SetInput(itkImage); - resampleImageFilter->SetSize(outputSizeItk); - resampleImageFilter->SetOutputSpacing(outputSpacingItk); - - resampleImageFilter->UpdateLargestPossibleRegion(); - return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput()); -} - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ApplyCropping( - mitk::Image::Pointer inputImage, - int above, int below, - int right, int left, - int zStart, int zEnd, - int* errCode) -{ - *errCode = 0; - try - { - auto floatImage = ConvertToFloat(inputImage); - mitk::CropImageFilter::Pointer cropImageFilter = mitk::CropImageFilter::New(); - cropImageFilter->SetInput(floatImage); - cropImageFilter->SetXPixelsCropStart(left); - cropImageFilter->SetXPixelsCropEnd(right); - cropImageFilter->SetYPixelsCropStart(above); - cropImageFilter->SetYPixelsCropEnd(below); - cropImageFilter->SetZPixelsCropStart(zStart); - cropImageFilter->SetZPixelsCropEnd(zEnd); - cropImageFilter->Update(); - return cropImageFilter->GetOutput(); - } - catch (mitk::Exception &e) - { - std::string errorMessage = "Caught unexpected exception "; - errorMessage.append(e.what()); - MITK_ERROR << errorMessage; - *errCode = -1; - mitk::Image::Pointer ret = mitk::Image::New(); - unsigned int dim[3] = { 1,1,1 }; - ret->Initialize(MakeScalarPixelType(), 3, dim); - - return ret; - } -} - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ExtendImage(mitk::Image::Pointer inputImage, float pixelColor, unsigned int outputDimensionY) -{ - mitk::Image::Pointer outputImage = mitk::Image::New(); - unsigned int dim[] = {inputImage->GetDimension(0), outputDimensionY, inputImage->GetDimension(2)}; - outputImage->Initialize(inputImage->GetPixelType(), 3, dim); - - float *sliceData = new float[dim[0] * dim[1]]; - - for (size_t i = inputImage->GetDimension(1) * dim[0]; i < dim[0] * dim[1]; ++i) - { - sliceData[i] = pixelColor; - } - - for (unsigned int slice = 0; slice < dim[2]; ++slice) - { - mitk::ImageReadAccessor cpy(inputImage, inputImage->GetSliceData(slice)); - cpy.GetData(); - std::memcpy((void*)sliceData, cpy.GetData(), sizeof(float) * inputImage->GetDimension(1) * dim[0]); - outputImage->SetSlice(sliceData, slice); - } - - delete[] sliceData; - return outputImage; -} - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ApplyBeamforming( - mitk::Image::Pointer inputImage, - BeamformingSettings::Pointer config, - std::function progressHandle) -{ - Image::Pointer processedImage = mitk::Image::New(); - - if (inputImage->GetDimension() != 3) - { - mitk::Convert2Dto3DImageFilter::Pointer dimensionImageFilter = mitk::Convert2Dto3DImageFilter::New(); - dimensionImageFilter->SetInput(inputImage); - dimensionImageFilter->Update(); - processedImage = dimensionImageFilter->GetOutput(); - } - else - { - processedImage = inputImage; - } - - m_BeamformingFilter = mitk::BeamformingFilter::New(config); - m_BeamformingFilter->SetInput(ConvertToFloat(processedImage)); - m_BeamformingFilter->SetProgressHandle(progressHandle); - m_BeamformingFilter->UpdateLargestPossibleRegion(); - - processedImage = m_BeamformingFilter->GetOutput(); - - return processedImage; -} - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ApplyBandpassFilter( - mitk::Image::Pointer data, - float BPHighPass, float BPLowPass, - float alphaHighPass, float alphaLowPass, - float TimeSpacing, float SpeedOfSound, bool IsBFImage) -{ - try - { - auto floatData = ConvertToFloat(data); - mitk::BandpassFilter::Pointer bandpassFilter = mitk::BandpassFilter::New(); - bandpassFilter->SetInput(floatData); - bandpassFilter->SetHighPass(BPHighPass); - bandpassFilter->SetLowPass(BPLowPass); - bandpassFilter->SetHighPassAlpha(alphaHighPass); - bandpassFilter->SetLowPassAlpha(alphaLowPass); - bandpassFilter->SetSpeedOfSound(SpeedOfSound); - bandpassFilter->SetTimeSpacing(TimeSpacing); - bandpassFilter->SetIsBFImage(IsBFImage); - bandpassFilter->Update(); - return bandpassFilter->GetOutput(); - } - catch (mitk::Exception &e) - { - std::string errorMessage = "Caught unexpected exception "; - errorMessage.append(e.what()); - MITK_ERROR << errorMessage; - - return data; - } -} - -mitk::Image::Pointer mitk::PhotoacousticFilterService::ConvertToFloat(mitk::Image::Pointer inputImage) -{ - if ((inputImage->GetPixelType().GetTypeAsString() == "scalar (float)" || - inputImage->GetPixelType().GetTypeAsString() == " (float)")) - { - return inputImage; - } - - mitk::CastToFloatImageFilter::Pointer castToFloatImageFilter = mitk::CastToFloatImageFilter::New(); - castToFloatImageFilter->SetInput(inputImage); - castToFloatImageFilter->Update(); - return castToFloatImageFilter->GetOutput(); -} diff --git a/Modules/PhotoacousticsAlgorithms/test/CMakeLists.txt b/Modules/PhotoacousticsAlgorithms/test/CMakeLists.txt deleted file mode 100644 index 153cd81e2e..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -MITK_CREATE_MODULE_TESTS() diff --git a/Modules/PhotoacousticsAlgorithms/test/files.cmake b/Modules/PhotoacousticsAlgorithms/test/files.cmake deleted file mode 100644 index f3ac9a4454..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/files.cmake +++ /dev/null @@ -1,21 +0,0 @@ -set(MODULE_TESTS - # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. - # - # Example: #mitkMyTest #this test is commented out because of bug 12345 - # - # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that - # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and - # mark it as critical. - ################## DISABLED TESTS ##################################################### - - #mitkBandpassFilterTest.cpp #This test is disabled because of T25780 - #mitkBeamformingFilterTest.cpp #This test is disabled because of T25780 - - ################# RUNNING TESTS ####################################################### - - mitkPhotoacousticMotionCorrectionFilterTest.cpp - mitkPAFilterServiceTest.cpp - mitkCastToFloatImageFilterTest.cpp - mitkCropImageFilterTest.cpp - ) -set(RESOURCE_FILES) diff --git a/Modules/PhotoacousticsAlgorithms/test/mitkBandpassFilterTest.cpp b/Modules/PhotoacousticsAlgorithms/test/mitkBandpassFilterTest.cpp deleted file mode 100644 index 373435a6af..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/mitkBandpassFilterTest.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#define _USE_MATH_DEFINES -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "../ITKFilter/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h" -#include "mitkImageCast.h" -#include "mitkITKImageImport.h" -#include "itkComplexToModulusImageFilter.h" - -class mitkBandpassFilterTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkBandpassFilterTestSuite); - MITK_TEST(testHighPass); - MITK_TEST(testLowPass); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::PhotoacousticFilterService::Pointer m_FilterService; - const unsigned int NUM_ITERATIONS = 10; - const unsigned int DATA_XY_DIM = 512; - const unsigned int DATA_Z_DIM = 8; - const float TIME_SPACING = 0.00625; // [us] - float FREQUENCY_RESOLUTION = 1 / (TIME_SPACING / 1e6 * DATA_XY_DIM); // [Hz] - const float MAX_FREQUENCY = FREQUENCY_RESOLUTION * DATA_XY_DIM / 2.f; // [Hz] - const float HIGHPASS_FREQENCY = MAX_FREQUENCY * 0.8f; // [Hz] - const float LOWPASS_FREQENCY = MAX_FREQUENCY * 0.1f; // [Hz] - const float ALPHA = 0.01; // 0 = box, 1 = von Hann; changing this may make the test invalid - const float EPSILON_FFT = 0.0001f; - -public: - - void setUp() override - { - m_FilterService = mitk::PhotoacousticFilterService::New(); - } - - void test(float HighPass, float LowPass, float HighPassAlpha, float LowPassAlpha, bool useLow, bool useHigh) - { - std::random_device r; - std::default_random_engine randGen(r()); - std::uniform_real_distribution randDistrHighPass(HighPass * 0.01f, HighPass * 0.2f); - std::uniform_real_distribution randDistrLowPass(LowPass * 1.5f, LowPass * 2.f); - float* data = new float[DATA_XY_DIM*DATA_XY_DIM*DATA_Z_DIM]; - - mitk::Image::Pointer inputImage = mitk::Image::New(); - unsigned int dimension[3]{ DATA_XY_DIM, DATA_XY_DIM, DATA_Z_DIM }; - inputImage->Initialize(mitk::MakeScalarPixelType(), 3, dimension); - mitk::Vector3D spacing; - spacing[0] = 1; - spacing[1] = TIME_SPACING; - spacing[2] = 1; - inputImage->SetSpacing(spacing); - - for (unsigned int iteration = 0; iteration < NUM_ITERATIONS; ++iteration) - { - // fill image with zeros - for (unsigned int i = 0; i < DATA_XY_DIM*DATA_XY_DIM*DATA_Z_DIM; ++i) - { - data[i] = 0; - } - - // write specific frequencies to the image - if (useHigh) - addFrequency(randDistrHighPass(randGen), TIME_SPACING, data, dimension); - if (useLow) - addFrequency(randDistrLowPass(randGen), TIME_SPACING, data, dimension); - - inputImage->SetImportVolume(data, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - - if (!useHigh) - HighPass = 0; - - if (!useLow) - LowPass = MAX_FREQUENCY; - - mitk::Image::Pointer outputImage = m_FilterService->ApplyBandpassFilter(inputImage, HighPass, LowPass, HighPassAlpha, LowPassAlpha, TIME_SPACING / 1e6, 0, false); - - // do a fourier transform, and check whether the part of the image that has been filtered is zero - typedef itk::Image< float, 3 > RealImageType; - RealImageType::Pointer image; - - mitk::CastToItkImage(outputImage, image); - - typedef itk::FFT1DRealToComplexConjugateImageFilter ForwardFFTFilterType; - // typedef ForwardFFTFilterType::OutputImageType ComplexImageType; - ForwardFFTFilterType::Pointer forwardFFTFilter = ForwardFFTFilterType::New(); - forwardFFTFilter->SetInput(image); - forwardFFTFilter->SetDirection(1); - forwardFFTFilter->UpdateOutputInformation(); - forwardFFTFilter->Update(); - - auto fftResult = forwardFFTFilter->GetOutput(); - - /* - std::string img = "D:/img" + std::to_string(iteration) + ".nrrd"; - mitk::IOUtil::Save(inputImage, img); - std::string res = "D:/res" + std::to_string(iteration) + ".nrrd"; - mitk::IOUtil::Save(outputImage, res);*/ - - // the resulting image should consist only of zeros, as we filtered the frequencies out - for (unsigned int z = 0; z < DATA_Z_DIM; ++z) - { - for (unsigned int y = 0; y < DATA_XY_DIM / 2; ++y) - { - if (y < (unsigned int)std::floor(0.95 * HighPass / FREQUENCY_RESOLUTION) || y >(unsigned int)std::ceil(1.05 * LowPass / FREQUENCY_RESOLUTION)) - { - for (unsigned int x = 0; x < DATA_XY_DIM; ++x) - { - // unsigned int outPos = x + y * DATA_XY_DIM + z * DATA_XY_DIM * DATA_XY_DIM; - std::complex value = fftResult->GetPixel({ x,y,z }); - CPPUNIT_ASSERT_MESSAGE(std::string("Expected 0, got (" + std::to_string(value.real()) + " + " + std::to_string(value.imag()) + "i) at " + std::to_string(x) + "-" + std::to_string(y) + "-" + std::to_string(z)), - (value.real() < EPSILON_FFT) && (value.imag() < EPSILON_FFT)); - } - } - } - - for (unsigned int y = DATA_XY_DIM / 2; y < DATA_XY_DIM; ++y) - { - if (y > DATA_XY_DIM - (unsigned int)std::floor(HighPass / FREQUENCY_RESOLUTION) || y < DATA_XY_DIM - (unsigned int)std::ceil(LowPass / FREQUENCY_RESOLUTION)) - { - for (unsigned int x = 0; x < DATA_XY_DIM; ++x) - { - // unsigned int outPos = x + y * DATA_XY_DIM + z * DATA_XY_DIM * DATA_XY_DIM; - std::complex value = fftResult->GetPixel({ x,y,z }); - CPPUNIT_ASSERT_MESSAGE(std::string("Expected 0, got (" + std::to_string(value.real()) + " + " + std::to_string(value.imag()) + "i) at " + std::to_string(x) + "-" + std::to_string(y) + "-" + std::to_string(z)), - (value.real() < EPSILON_FFT) && (value.imag() < EPSILON_FFT)); - } - } - } - } - } - - delete[] data; - } - - // write a fixed-frequency signal to the image - void addFrequency(float freq, float timeSpacing, float* data, unsigned int* dim) - { - for (unsigned int z = 0; z < dim[2]; ++z) - { - for (unsigned int y = 0; y < dim[1]; ++y) - { - for (unsigned int x = 0; x < dim[0]; ++x) - { - data[x + y * dim[0] + z * dim[0] * dim[1]] += std::sin(freq * timeSpacing * y); - } - } - } - } - - void testHighPass() - { - MITK_INFO << "Performing HighPass test"; - test(HIGHPASS_FREQENCY, 0, ALPHA, ALPHA, false, true); - } - - void testLowPass() - { - MITK_INFO << "Performing LowPass test"; - test(0, LOWPASS_FREQENCY, ALPHA, ALPHA, true, false); - } - - void tearDown() override - { - m_FilterService = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkBandpassFilter) diff --git a/Modules/PhotoacousticsAlgorithms/test/mitkBeamformingFilterTest.cpp b/Modules/PhotoacousticsAlgorithms/test/mitkBeamformingFilterTest.cpp deleted file mode 100644 index b8867a6c62..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/mitkBeamformingFilterTest.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -class SyntheticPAImageData -{ -public: - SyntheticPAImageData(float spacing_x, float spacing_y, unsigned int samples, unsigned int num_transducers, float speedOfSound) - { - m_Spacing_x = spacing_x; - m_Spacing_y = spacing_y; - m_TransducerElements = num_transducers; - m_Samples = samples; - m_SpeedOfSound = speedOfSound; - m_Data = new float[m_Samples*m_TransducerElements]; - - for (size_t i = 0; i < m_Samples * m_TransducerElements; ++i) - { - m_Data[i] = 0; - } - } - - ~SyntheticPAImageData() - { - delete[] m_Data; - } - - void AddWave(float origin_depth, float origin_x, float base_value= 10000) - { - AddLine(origin_depth, origin_x, base_value); - AddLine(origin_depth + 0.0001f, origin_x, -base_value); - } - - const float* GetData() - { - return (const float*)m_Data; - } - -private: - void AddLine(float origin_depth, unsigned int origin_x, float base_value = 10000) - { - for (unsigned int x = 0; x < m_TransducerElements; ++x) - { - float distance = std::abs((int)x - (int)origin_x); - float delay_in_seconds = std::sqrt(std::pow(origin_depth, 2) + std::pow(distance*m_Spacing_x, 2)) / m_SpeedOfSound; - int pixels = std::round(delay_in_seconds / m_Spacing_y); - - for (int index = -4; index < 9; ++index) - { - if ((int)pixels + index < (int)m_Samples && (int)pixels + index > 0) - { - m_Data[(size_t)(x + (pixels + index)*m_TransducerElements)] += base_value / std::sqrt(distance + 1); - } - } - } - } - - float* m_Data; - float m_Spacing_x; - float m_Spacing_y; - unsigned int m_TransducerElements; - unsigned int m_Samples; - float m_SpeedOfSound; -}; - -class mitkBeamformingFilterTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkBeamformingFilterTestSuite); - MITK_TEST(testBeamformingCPU_DAS); - MITK_TEST(testBeamformingGPU_DAS); - MITK_TEST(testBeamformingCPU_DMAS); - MITK_TEST(testBeamformingGPU_DMAS); - MITK_TEST(testBeamformingCPU_sDMAS); - MITK_TEST(testBeamformingGPU_sDMAS); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::BeamformingFilter::Pointer m_BeamformingFilter; - const unsigned int NUM_ITERATIONS = 15; - const unsigned int SAMPLES = 5000 * 2; - const unsigned int RECONSTRUCTED_SAMPLES = 2048; - const unsigned int ELEMENTS = 128; - const unsigned int RECONSTRUCTED_LINES = 128; - const float SPEED_OF_SOUND = 1540; // m/s - const float SPACING_X = 0.3; // mm - const float SPACING_Y = 0.00625 / 2; // us - const unsigned int GPU_BATCH_SIZE = 16; - -public: - - void setUp() override - { - - } - - void test() - { - std::random_device r; - std::default_random_engine randGen(r()); - float maxDepthInMeters = SAMPLES * (SPACING_Y / 1000000) * SPEED_OF_SOUND / 2; - std::uniform_real_distribution randDistrDepth(maxDepthInMeters*0.1, maxDepthInMeters*0.8); - - for (unsigned int iteration = 0; iteration < NUM_ITERATIONS; ++iteration) - { - // create some synthetic input data - float depth_in_meters1 = randDistrDepth(randGen); - float depth_in_meters2 = randDistrDepth(randGen); - float depth_in_meters3 = randDistrDepth(randGen); - - unsigned int element1 = 29; - unsigned int element2 = 63; - unsigned int element3 = 98; - - SyntheticPAImageData image(SPACING_X / 1000.f, SPACING_Y / 1000000.f, SAMPLES, ELEMENTS, SPEED_OF_SOUND); - image.AddWave(depth_in_meters1, 29); - image.AddWave(depth_in_meters2, 63); - image.AddWave(depth_in_meters3, 98); - - mitk::Image::Pointer inputImage = mitk::Image::New(); - unsigned int dimension[3]{ ELEMENTS, SAMPLES, 1 }; - inputImage->Initialize(mitk::MakeScalarPixelType(), 3, dimension); - mitk::Vector3D spacing; - spacing[0] = SPACING_X; - spacing[1] = SPACING_Y; - spacing[2] = 1; - inputImage->SetSpacing(spacing); - inputImage->SetImportVolume((const void*)image.GetData(), mitk::Image::CopyMemory); - - // setup the beamforming filter - m_BeamformingFilter->SetInput(inputImage); - m_BeamformingFilter->Update(); - - mitk::Image::Pointer outputImage = m_BeamformingFilter->GetOutput(); - mitk::ImageReadAccessor readAccess(outputImage); - const float* outputData = (const float*)readAccess.GetData(); - - unsigned int pos1[3] = { element1, (unsigned int)std::round(depth_in_meters1 * 1000.f / outputImage->GetGeometry()->GetSpacing()[1]), 0 }; - unsigned int pos2[3] = { element2, (unsigned int)std::round(depth_in_meters2 * 1000.f / outputImage->GetGeometry()->GetSpacing()[1]), 0 }; - unsigned int pos3[3] = { element3, (unsigned int)std::round(depth_in_meters3 * 1000.f / outputImage->GetGeometry()->GetSpacing()[1]), 0 }; - - double average = 0; - - for (unsigned int i = 0; i < RECONSTRUCTED_LINES*RECONSTRUCTED_SAMPLES; ++i) - { - average += outputData[i] / (RECONSTRUCTED_LINES*RECONSTRUCTED_SAMPLES); - } - - CPPUNIT_ASSERT_MESSAGE(std::string("Iteration " + std::to_string(iteration) + ": first point source incorrectly reconstructed; should be > average*100, is " + - std::to_string(abs(outputData[pos1[0] + pos1[1] * RECONSTRUCTED_LINES]))) + " < " + std::to_string(average) + "*100" - , abs(outputData[pos1[0] + pos1[1]*RECONSTRUCTED_LINES] / average) > 100); - CPPUNIT_ASSERT_MESSAGE(std::string("Iteration " + std::to_string(iteration) + ": second point source incorrectly reconstructed; should be > average*100, is " + - std::to_string(abs(outputData[pos2[0] + pos2[1] * RECONSTRUCTED_LINES]))) + " < " + std::to_string(average) + "*100" - , abs(outputData[pos2[0] + pos2[1] * RECONSTRUCTED_LINES] / average) > 100); - CPPUNIT_ASSERT_MESSAGE(std::string("Iteration " + std::to_string(iteration) + ": third point source incorrectly reconstructed; should be > average*100, is " + - std::to_string(abs(outputData[pos3[0] + pos3[1] * RECONSTRUCTED_LINES]))) + " < " + std::to_string(average) + "*100" - , abs(outputData[pos3[0] + pos3[1] * RECONSTRUCTED_LINES] / average) > 100); - } - } - - mitk::BeamformingSettings::Pointer createConfig(bool UseGPU, unsigned int* inputDim, mitk::BeamformingSettings::BeamformingAlgorithm alg) - { - return mitk::BeamformingSettings::New(SPACING_X / 1000, - SPEED_OF_SOUND, - SPACING_Y / 1000000, - 27.f, - true, - RECONSTRUCTED_SAMPLES, - RECONSTRUCTED_LINES, - inputDim, - SPEED_OF_SOUND * (SPACING_Y / 1000000) * SAMPLES, - UseGPU, - GPU_BATCH_SIZE, - mitk::BeamformingSettings::DelayCalc::Spherical, - mitk::BeamformingSettings::Apodization::Box, - ELEMENTS * 2, - alg); - } - - void testBeamformingCPU_DAS() - { - MITK_INFO << "Started DAS test on CPU"; - unsigned int* inputDim = new unsigned int[3]; - inputDim[0] = ELEMENTS; - inputDim[1] = SAMPLES; - inputDim[2] = 1; - m_BeamformingFilter = mitk::BeamformingFilter::New(createConfig(false, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::DAS)); - - test(); - delete[] inputDim; - } - - void testBeamformingGPU_DAS() - { - MITK_INFO << "Started DAS test on GPU"; - unsigned int* inputDim = new unsigned int[3]; - inputDim[0] = ELEMENTS; - inputDim[1] = SAMPLES; - inputDim[2] = 1; - m_BeamformingFilter = mitk::BeamformingFilter::New(createConfig(true, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::DAS)); - - test(); - delete[] inputDim; - } - - void testBeamformingCPU_sDMAS() - { - MITK_INFO << "Started sDMAS test on CPU"; - unsigned int* inputDim = new unsigned int[3]; - inputDim[0] = ELEMENTS; - inputDim[1] = SAMPLES; - inputDim[2] = 1; - m_BeamformingFilter = mitk::BeamformingFilter::New(createConfig(false, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::sDMAS)); - - test(); - delete[] inputDim; - } - - void testBeamformingGPU_sDMAS() - { - MITK_INFO << "Started sDMAS test on GPU"; - unsigned int* inputDim = new unsigned int[3]; - inputDim[0] = ELEMENTS; - inputDim[1] = SAMPLES; - inputDim[2] = 1; - m_BeamformingFilter = mitk::BeamformingFilter::New(createConfig(true, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::sDMAS)); - - test(); - delete[] inputDim; - } - - void testBeamformingCPU_DMAS() - { - MITK_INFO << "Started DMAS test on CPU"; - unsigned int* inputDim = new unsigned int[3]; - inputDim[0] = ELEMENTS; - inputDim[1] = SAMPLES; - inputDim[2] = 1; - m_BeamformingFilter = mitk::BeamformingFilter::New(createConfig(false, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::DMAS)); - - test(); - delete[] inputDim; - } - - void testBeamformingGPU_DMAS() - { - MITK_INFO << "Started DMAS test on GPU"; - unsigned int* inputDim = new unsigned int[3]; - inputDim[0] = ELEMENTS; - inputDim[1] = SAMPLES; - inputDim[2] = 1; - m_BeamformingFilter = mitk::BeamformingFilter::New(createConfig(true, inputDim, mitk::BeamformingSettings::BeamformingAlgorithm::DMAS)); - - test(); - delete[] inputDim; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkBeamformingFilter) diff --git a/Modules/PhotoacousticsAlgorithms/test/mitkCastToFloatImageFilterTest.cpp b/Modules/PhotoacousticsAlgorithms/test/mitkCastToFloatImageFilterTest.cpp deleted file mode 100644 index 4cbb826971..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/mitkCastToFloatImageFilterTest.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include - -class mitkCastToFloatImageFilterTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkCastToFloatImageFilterTestSuite); - MITK_TEST(testShortConversion); - MITK_TEST(testIntConversion); - MITK_TEST(testLongConversion); - MITK_TEST(testFloatConversion); - MITK_TEST(testDoubleConversion); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::CastToFloatImageFilter::Pointer m_CastToFloatImageFilter; - const unsigned int NUM_ITERATIONS = 15; - const unsigned int DATA_DIM = 10; - -public: - - void setUp() override - { - m_CastToFloatImageFilter = mitk::CastToFloatImageFilter::New(); - } - - template - void test() - { - TPixelType* data = new TPixelType[DATA_DIM*DATA_DIM*DATA_DIM]; - - for (unsigned int i = 0; i < DATA_DIM*DATA_DIM*DATA_DIM; ++i) - { - data[i] = (TPixelType)i; - } - - mitk::Image::Pointer inputImage = mitk::Image::New(); - unsigned int dimension[3]{ DATA_DIM, DATA_DIM, DATA_DIM }; - inputImage->Initialize(mitk::MakeScalarPixelType(), 3, dimension); - inputImage->SetImportVolume(data); - - for (unsigned int iteration = 0; iteration < NUM_ITERATIONS; ++iteration) - { - m_CastToFloatImageFilter->SetInput(inputImage); - m_CastToFloatImageFilter->Update(); - mitk::Image::Pointer outputImage = m_CastToFloatImageFilter->GetOutput(); - mitk::ImageReadAccessor readAccess(outputImage); - const float* outputData = (const float*)readAccess.GetData(); - for (unsigned int i = 0; i < DATA_DIM*DATA_DIM*DATA_DIM; ++i) - { - CPPUNIT_ASSERT_MESSAGE(std::string("expected " + std::to_string(data[i]) + " but was " + std::to_string(outputData[i])), std::abs(outputData[i] - data[i]) < mitk::eps); - } - } - } - - void testFloatConversion() - { - test(); - } - - void testShortConversion() - { - test(); - test(); - } - - void testIntConversion() - { - test(); - test(); - } - - void testDoubleConversion() - { - test(); - } - - void testLongConversion() - { - test(); - } - - void tearDown() override - { - m_CastToFloatImageFilter = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkCastToFloatImageFilter) diff --git a/Modules/PhotoacousticsAlgorithms/test/mitkCropImageFilterTest.cpp b/Modules/PhotoacousticsAlgorithms/test/mitkCropImageFilterTest.cpp deleted file mode 100644 index 1248d6231c..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/mitkCropImageFilterTest.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include -#include - -class mitkCropImageFilterTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkCropImageFilterTestSuite); - MITK_TEST(testCropImage); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::CropImageFilter::Pointer m_CropImageFilter; - const unsigned int NUM_ITERATIONS = 5; - const unsigned int DATA_DIM = 25; - -public: - - void setUp() override - { - m_CropImageFilter = mitk::CropImageFilter::New(); - } - - void test() - { - std::random_device r; - std::default_random_engine randGen(r()); - std::uniform_int_distribution randDistr(0, (DATA_DIM / 2) - 1); - - float* data = new float[DATA_DIM*DATA_DIM*DATA_DIM]; - - for (unsigned int i = 0; i < DATA_DIM*DATA_DIM*DATA_DIM; ++i) - { - data[i] = (float)i; - } - - mitk::Image::Pointer inputImage = mitk::Image::New(); - unsigned int dimension[3]{ DATA_DIM, DATA_DIM, DATA_DIM }; - inputImage->Initialize(mitk::MakeScalarPixelType(), 3, dimension); - inputImage->SetImportVolume(data, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - - for (unsigned int iteration = 0; iteration < NUM_ITERATIONS; ++iteration) - { - unsigned int XPixelsCropStart = randDistr(randGen); - unsigned int YPixelsCropStart = randDistr(randGen); - unsigned int ZPixelsCropStart = randDistr(randGen); - unsigned int XPixelsCropEnd = randDistr(randGen); - unsigned int YPixelsCropEnd = randDistr(randGen); - unsigned int ZPixelsCropEnd = randDistr(randGen); - - unsigned int newXDim = DATA_DIM - XPixelsCropStart - XPixelsCropEnd; - unsigned int newYDim = DATA_DIM - YPixelsCropStart - YPixelsCropEnd; - unsigned int newZDim = DATA_DIM - ZPixelsCropStart - ZPixelsCropEnd; - - m_CropImageFilter->SetInput(inputImage); - - m_CropImageFilter->SetXPixelsCropStart(XPixelsCropStart); - m_CropImageFilter->SetYPixelsCropStart(YPixelsCropStart); - m_CropImageFilter->SetZPixelsCropStart(ZPixelsCropStart); - m_CropImageFilter->SetXPixelsCropEnd(XPixelsCropEnd); - m_CropImageFilter->SetYPixelsCropEnd(YPixelsCropEnd); - m_CropImageFilter->SetZPixelsCropEnd(ZPixelsCropEnd); - - m_CropImageFilter->Update(); - mitk::Image::Pointer outputImage = m_CropImageFilter->GetOutput(); - - mitk::ImageReadAccessor readAccess(outputImage); - const float* outputData = (const float*)readAccess.GetData(); - - CPPUNIT_ASSERT_MESSAGE(std::string("expected x size to be " + std::to_string(newXDim) + " but was " + std::to_string(outputImage->GetDimension(0))), newXDim == outputImage->GetDimension(0)); - CPPUNIT_ASSERT_MESSAGE(std::string("expected y size to be " + std::to_string(newYDim) + " but was " + std::to_string(outputImage->GetDimension(1))), newYDim == outputImage->GetDimension(1)); - CPPUNIT_ASSERT_MESSAGE(std::string("expected z size to be " + std::to_string(newZDim) + " but was " + std::to_string(outputImage->GetDimension(2))), newZDim == outputImage->GetDimension(2)); - - for (unsigned int z = 0; z < newZDim; ++z) - { - for (unsigned int y = 0; y < newYDim; ++y) - { - for (unsigned int x = 0; x < newXDim; ++x) - { - unsigned int origPos = (x + XPixelsCropStart) + (y + YPixelsCropStart) * DATA_DIM + (z + ZPixelsCropStart) * DATA_DIM * DATA_DIM; - unsigned int outPos = x + y * newXDim + z * newXDim * newYDim; - CPPUNIT_ASSERT_MESSAGE(std::string("expected " + std::to_string(data[origPos]) - + " but was " + std::to_string(outputData[outPos])), - std::abs((float)outputData[outPos] - (float)data[origPos]) < mitk::eps); - } - } - } - } - - delete[] data; - } - - void testCropImage() - { - for (int repetition = 0; repetition < 20; ++repetition) - { - MITK_INFO << "[" << (repetition + 1) << "/20]"; - test(); - } - } - - void tearDown() override - { - m_CropImageFilter = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkCropImageFilter) diff --git a/Modules/PhotoacousticsAlgorithms/test/mitkPAFilterServiceTest.cpp b/Modules/PhotoacousticsAlgorithms/test/mitkPAFilterServiceTest.cpp deleted file mode 100644 index d85d536145..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/mitkPAFilterServiceTest.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include -#include -#include -#include - -// us -#include -#include -#include -#include -#include - -#include -#include - -class mitkPAFilterServiceTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPAFilterServiceTestSuite); - MITK_TEST(testRunning); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::PhotoacousticFilterService::Pointer m_PhotoacousticFilterService; - mitk::BeamformingSettings::Pointer m_BeamformingSettings; - unsigned int* inputDimensions; - const int xDim = 16; - const int yDim = 128; - const int length = yDim * xDim; - -public: - - void setUp() override - { - m_PhotoacousticFilterService = mitk::PhotoacousticFilterService::New(); - m_BeamformingSettings = CreateBeamformingSettings(); - } - - mitk::BeamformingSettings::Pointer CreateBeamformingSettings() - { - inputDimensions = new unsigned int[length]; - inputDimensions[0] = yDim; - inputDimensions[1] = xDim; - mitk::BeamformingSettings::Pointer outputSettings = mitk::BeamformingSettings::New( - (float)(0.3 / 1000), - (float)(1500), - (float)(0.0125 / 1000000), - 27, - true, - 3000, - 128, - inputDimensions, - yDim * (0.0125 / 1000000) * (1500), - false, - 16, - mitk::BeamformingSettings::Apodization::Box, - 128, - mitk::BeamformingSettings::BeamformingAlgorithm::DAS, - mitk::BeamformingSettings::ProbeGeometry::Linear, - 0); - - return outputSettings; - } - - void testRunning() - { - float* testArray = new float[length]; - for (int i = 0; i < length; ++i) - { - testArray[i] = 0; - } - - mitk::PixelType pixelType = mitk::MakeScalarPixelType(); - mitk::Image::Pointer testImage = mitk::Image::New(); - testImage->Initialize(pixelType, 2, inputDimensions); - testImage->SetImportSlice(testArray, 0, 0, 0, mitk::Image::ImportMemoryManagementType::CopyMemory); - delete[] testArray; - - mitk::ImageReadAccessor readAccessInput(testImage); - const float* inputArray = (const float*)readAccessInput.GetData(); - - for (int i = 0; i < length; ++i) - { - CPPUNIT_ASSERT_MESSAGE(std::string("Input array already not correct: " + std::to_string(inputArray[i])), std::abs(inputArray[i]) < 1e-5f); - } - - auto output = m_PhotoacousticFilterService->ApplyBeamforming(testImage, m_BeamformingSettings); - - mitk::ImageReadAccessor readAccess(output); - const float* outputArray = (const float*)readAccess.GetData(); - - for (int i = 0; i < length; ++i) - { - CPPUNIT_ASSERT_MESSAGE(std::string("Output array not correct: " + std::to_string(std::abs(outputArray[i]))), std::abs(outputArray[i]) < 1e-5f); - } - } - - void tearDown() override - { - m_PhotoacousticFilterService = nullptr; - delete[] inputDimensions; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPAFilterService) diff --git a/Modules/PhotoacousticsAlgorithms/test/mitkPhotoacousticMotionCorrectionFilterTest.cpp b/Modules/PhotoacousticsAlgorithms/test/mitkPhotoacousticMotionCorrectionFilterTest.cpp deleted file mode 100644 index d30aed5df2..0000000000 --- a/Modules/PhotoacousticsAlgorithms/test/mitkPhotoacousticMotionCorrectionFilterTest.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -class mitkPhotoacousticMotionCorrectionFilterTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticMotionCorrectionFilterTestSuite); - MITK_TEST(testSettingFirstInput); - MITK_TEST(testSettingSecondInput); - // MITK_TEST(testNoThirdInput); - MITK_TEST(testGetFirstEmptyOutput); - MITK_TEST(testGetSecondEmptyOutput); - MITK_TEST(testSameInOutDimensions); - MITK_TEST(testNo3DError); - MITK_TEST(testSameInputDimension1); - MITK_TEST(testSameInputDimension2); - MITK_TEST(testNullPtr1); - MITK_TEST(testNullPtr2); - MITK_TEST(testNullPtr3); - MITK_TEST(testSameInputDimensions); - MITK_TEST(testStaticSliceCorrection); - CPPUNIT_TEST_SUITE_END(); - - -private: - mitk::PhotoacousticMotionCorrectionFilter::Pointer filter; - mitk::Image::Pointer image, image4d, image2d, image3d1slice; - float * data2d; - -public: - void setUp() override { - // get the filter I need - filter = mitk::PhotoacousticMotionCorrectionFilter::New(); - // get a 3d mitk image - image = mitk::Image::New(); - image2d = mitk::Image::New(); - image4d = mitk::Image::New(); - image3d1slice = mitk::Image::New(); - unsigned int * dimensions = new unsigned int[3] {2, 2, 2}; - unsigned int * dimensions2 = new unsigned int[3] {2, 2, 1}; - unsigned int * dim2 = new unsigned int[4] {2, 2, 2, 2}; - mitk::PixelType pt = mitk::MakeScalarPixelType(); - float * data = new float[8] {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - float * data4d = new float[16]; - data2d = new float[4] {500.0, -500.5, 1000.0, 0.5}; - image->Initialize(pt, 3, dimensions); - image->SetVolume(data); - image4d->Initialize(pt, 4, dim2); - image4d->SetVolume(data4d); - image2d->Initialize(pt, 2, dimensions); - image2d->SetVolume(data2d); - image3d1slice->Initialize(pt, 3, dimensions2); - image3d1slice->SetVolume(data); - delete[] dimensions; - delete[] dimensions2; - delete[] data; - delete[] data4d; - delete[] dim2; - } - - void tearDown() override { - delete[] data2d; - } - - void testSettingFirstInput() { - filter->SetInput(0, image); - mitk::Image::Pointer out = filter->GetInput(0); - CPPUNIT_ASSERT_EQUAL(image, out); - } - - void testSettingSecondInput() { - filter->SetInput(1, image); - mitk::Image::Pointer out = filter->GetInput(1); - CPPUNIT_ASSERT_EQUAL(image, out); - } - - // void testNoThirdInput() { - // CPPUNIT_ASSERT_NO_THROW(filter->SetInput(2, image)); - // // CPPUNIT_ASSERT(true); - // } - - void testGetFirstEmptyOutput() { - mitk::Image::Pointer out = filter->GetOutput(0); - unsigned int dim = 0; - CPPUNIT_ASSERT_EQUAL(dim, out->GetDimension()); - } - - void testGetSecondEmptyOutput() { - mitk::Image::Pointer out = filter->GetOutput(1); - unsigned int dim = 0; - CPPUNIT_ASSERT_EQUAL(dim, out->GetDimension()); - } - - void testSameInOutDimensions() { - filter->SetInput(0, image); - filter->SetInput(1, image); - filter->Update(); - mitk::Image::Pointer out = filter->GetOutput(0); - CPPUNIT_ASSERT_EQUAL(image->GetDimension(), out->GetDimension()); - out = filter->GetOutput(1); - CPPUNIT_ASSERT_EQUAL(image->GetDimension(), out->GetDimension()); - } - - void testNo3DError() { - filter->SetInput(0, image4d); - filter->SetInput(1, image4d); - CPPUNIT_ASSERT_THROW(filter->Update(), std::invalid_argument); - } - - // I only test for dim input0 <= dim input1, because otherwise - // itk will throw an error before the program even reaches the - // parts I wrote. - // Same for testSameInputDimension2 - void testSameInputDimension1() { - filter->SetInput(0, image); - filter->SetInput(1, image4d); - CPPUNIT_ASSERT_THROW(filter->Update(), std::invalid_argument); - } - - // See previous comment - void testSameInputDimension2() { - filter->SetInput(0, image2d); - filter->SetInput(1, image); - CPPUNIT_ASSERT_THROW(filter->Update(), std::invalid_argument); - } - - // I tried to catch the error myself in the filter, but itk does some magic beforehand - void testNullPtr1() { - filter->SetInput(0, nullptr); - filter->SetInput(1, image); - CPPUNIT_ASSERT_THROW(filter->Update(), itk::ExceptionObject); - } - - // Now I am allowed to catch it myself, because the first input is fine -.- - void testNullPtr2() { - filter->SetInput(0, image); - filter->SetInput(1, nullptr); - CPPUNIT_ASSERT_THROW(filter->Update(), std::invalid_argument); - } - - void testNullPtr3() { - filter->SetInput(0, nullptr); - filter->SetInput(1, nullptr); - CPPUNIT_ASSERT_THROW(filter->Update(), itk::ExceptionObject); - } - - void testSameInputDimensions() { - filter->SetInput(0, image3d1slice); - filter->SetInput(1, image); - CPPUNIT_ASSERT_THROW(filter->Update(), std::invalid_argument); - } - - void testStaticSliceCorrection() { - image->SetSlice(data2d, 0); - image->SetSlice(data2d, 1); - filter->SetInput(0, image); - filter->SetInput(1, image); - filter->Update(); - mitk::Image::Pointer out1 = filter->GetOutput(0); - mitk::Image::Pointer out2 = filter->GetOutput(1); - MITK_ASSERT_EQUAL(image, out1, "Check that static image does not get changed."); - } - -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticMotionCorrectionFilter) diff --git a/Modules/PhotoacousticsHardware/CMakeLists.txt b/Modules/PhotoacousticsHardware/CMakeLists.txt deleted file mode 100644 index 6ce8caa586..0000000000 --- a/Modules/PhotoacousticsHardware/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -if(WIN32) - - option(MITK_USE_GALIL_HARDWARE "Enable support for OPOTEK Lasers" OFF) - option(MITK_USE_OPHIR_PYRO_HARDWARE "Enable support for Ophir Pyroelectrical Sensors" OFF) - - if(MITK_USE_OPHIR_PYRO_HARDWARE) - set(MITK_OPHIR_API_PATH "" CACHE PATH "Path to Ophir API lib.") - endif() - - if(MITK_USE_GALIL_HARDWARE) - set(MITK_GALIL_API_PATH "" CACHE PATH "Path to Galil API header files.") - MITK_CREATE_MODULE( - DEPENDS MitkIGT - INCLUDE_DIRS PUBLIC "${MITK_GALIL_API_PATH}/include" "${MITK_OPHIR_API_PATH}" - INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} - ADDITIONAL_LIBS "${MITK_GALIL_API_PATH}/lib/dynamic/x64/gclib.lib" "${MITK_GALIL_API_PATH}/lib/dynamic/x64/gclibo.lib" "${MITK_OPHIR_API_PATH}/OphirPyroWrapper.lib" - PACKAGE_DEPENDS tinyxml2|tinyxml2 - ) - - if(TARGET ${MODULE_TARGET}) - target_link_libraries(${MODULE_TARGET} - PRIVATE tinyxml2::tinyxml2 - ) - endif() - endif() -endif() diff --git a/Modules/PhotoacousticsHardware/OphirCppWrapper/ConsoleExample.cpp b/Modules/PhotoacousticsHardware/OphirCppWrapper/ConsoleExample.cpp deleted file mode 100644 index a55a50fce9..0000000000 --- a/Modules/PhotoacousticsHardware/OphirCppWrapper/ConsoleExample.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include "OphirPyroWrapper.h" -#include - -int main() -{ - OphirPyroWrapper pyro; - - char* sn = pyro.ScanUSB(); - if (sn != 0) - std::cout << "sn: " << sn << std::endl; - else - std::cout << "sn: NULL" << std::endl; - - int handle = pyro.OpenDevice(sn); - std::cout << "handle: " << handle << std::endl; - - char* wl = pyro.GetWavelengths(handle); - std::cout << "wl: " << wl << std::endl; - char* gr = pyro.GetRanges(handle); - std::cout << "gr: " << gr << std::endl; - - bool start = pyro.StartStream(handle); - std::cout << "start: " << start << std::endl; - - std::vector data; - std::vector timestamp; - std::vector status; - Sleep(100); - unsigned int gd = pyro.GetData(handle, &data, ×tamp, &status); - std::cout << "gd: " << gd << std::endl; - std::cout << "length: " << data.size() << std::endl; - for(int i = 0; i -#include -#include "OphirPyroWrapper.h" - -using namespace System::Runtime::InteropServices; // Marshal - -class OphirPyroWrapperPrivate -{ - public: msclr::auto_gcroot ophirAPI; -}; - -OphirPyroWrapper::OphirPyroWrapper() -{ - _private = new OphirPyroWrapperPrivate(); - _private->ophirAPI = gcnew OphirLMMeasurementLib::CoLMMeasurement(); -} - -OphirPyroWrapper::~OphirPyroWrapper() -{ - delete _private; -} - -char* OphirPyroWrapper::ScanUSB() -{ - char* foo; - System::Object^ managedObject; - _private->ophirAPI->ScanUSB(managedObject); - array^ managedCapi = dynamic_cast^>(managedObject); - if (managedCapi->Length != 0) - return (char*)Marshal::StringToHGlobalAnsi(managedCapi[0]).ToPointer(); - else - return 0; -} - -int OphirPyroWrapper::OpenDevice(char* serialNumber) -{ - int deviceHandle; - _private->ophirAPI->OpenUSBDevice(gcnew System::String(serialNumber), deviceHandle); - - return deviceHandle; -} - -char* OphirPyroWrapper::GetWavelengths(int deviceHandle) -{ - int index; - System::Object^ options; - // Show wavelengths of channel 0 - _private->ophirAPI->GetWavelengths(deviceHandle, 0, index, options); - array^ managedCapi = dynamic_cast^>(options); - if (managedCapi->Length != 0) - return (char*)Marshal::StringToHGlobalAnsi(managedCapi[index]).ToPointer(); - else - return 0; -} - -char* OphirPyroWrapper::GetRanges(int deviceHandle) -{ - int index; - System::Object^ options; - // Show ranges of channel 0 - _private->ophirAPI->GetRanges(deviceHandle, 0, index, options); - array^ managedCapi = dynamic_cast^>(options); - if (managedCapi->Length != 0) - return (char*)Marshal::StringToHGlobalAnsi(managedCapi[index]).ToPointer(); - else - return 0; -} - -bool OphirPyroWrapper::StartStream(int deviceHandle) -{ - _private->ophirAPI->StartStream(deviceHandle, 0); - return true; -} - -bool OphirPyroWrapper::StopStream(int deviceHandle) -{ - _private->ophirAPI->StopStream(deviceHandle, 0); - return true; -} - -bool OphirPyroWrapper::CloseDevice(int deviceHandle) -{ - _private->ophirAPI->Close(deviceHandle); - return true; -} - -unsigned int OphirPyroWrapper::GetData(int deviceHandle, std::vector* data, std::vector* timestamp, std::vector* status) -{ - System::Object^ dataArray; - System::Object^ timeStampArray; - System::Object^ statusArray; - array^ managedDataArray; - array^ managedTimeStampArray; - array^ managedStatusArray; - _private->ophirAPI->GetData(deviceHandle, 0, dataArray, timeStampArray, statusArray); - managedDataArray = (array^)dataArray; - managedTimeStampArray = (array^)timeStampArray; - managedStatusArray = (array^)statusArray; - if (managedDataArray->Length > 0) - { - data->resize(managedDataArray->Length); - timestamp->resize(managedDataArray->Length); - status->resize(managedDataArray->Length); - for(int i = 0; iLength; i++) - { - (*data)[i] = managedDataArray[i]; - (*timestamp)[i] = managedTimeStampArray[i]; - (*status)[i] = managedStatusArray[i]; - // DEBUG: std::cout << "managedDataArray " << i << ": " << managedDataArray[i] << " ts: " << managedTimeStampArray[i] << " status: " << managedStatusArray[i] << std::endl; - } - return managedDataArray->Length; - } - else - { - data->resize(1); - timestamp->resize(1); - status->resize(1); - (*data)[0] = -1; - (*timestamp)[0] = -1; - (*status)[0] = -1; - } - - return 0; -} diff --git a/Modules/PhotoacousticsHardware/OphirCppWrapper/OphirPyroWrapper.h b/Modules/PhotoacousticsHardware/OphirCppWrapper/OphirPyroWrapper.h deleted file mode 100644 index dd3decfeb8..0000000000 --- a/Modules/PhotoacousticsHardware/OphirCppWrapper/OphirPyroWrapper.h +++ /dev/null @@ -1,40 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include - -class OphirPyroWrapperPrivate; - -class __declspec(dllexport) OphirPyroWrapper -{ - private: OphirPyroWrapperPrivate* _private; - - public: OphirPyroWrapper(); - - public: ~OphirPyroWrapper(); - - public: char* ScanUSB(); - - public: int OpenDevice(char* serialNumber); - - public: char* GetWavelengths(int deviceHandle); - - public: char* GetRanges(int deviceHandle); - - public: bool StartStream(int deviceHandle); - - public: bool StopStream(int deviceHandle); - - public: bool CloseDevice(int deviceHandle); - - public: unsigned int GetData(int deviceHandle, std::vector* data, std::vector* timestamp, std::vector* status); -}; diff --git a/Modules/PhotoacousticsHardware/OphirCppWrapper/readme.txt b/Modules/PhotoacousticsHardware/OphirCppWrapper/readme.txt deleted file mode 100644 index 312e900b17..0000000000 --- a/Modules/PhotoacousticsHardware/OphirCppWrapper/readme.txt +++ /dev/null @@ -1,16 +0,0 @@ -A C++/CLI Wrapper for Ophir Pyroelectrical Sensors - -compile release version of wapper via: cl /clr /LD OphirPyroWrapper.cpp -compile debug version of wapper via: cl /clr /LDd OphirPyroWrapper.cpp -you'll need: Interop.OphirLMMeasurementLib.dll - -compile shitty console example via: cl ConsoleExample.cpp OphirPyroWrapper.lib - -tested with: -VS2015, Windows 10 + 8, Starlab 3.20 - -todo: -- write documentation - -thanks to: -pragmateek for http://pragmateek.com/using-c-from-native-c-with-the-help-of-ccli-v2/ \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/FTUNE.dmc b/Modules/PhotoacousticsHardware/Resources/FTUNE.dmc deleted file mode 100644 index 454e5dacab..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/FTUNE.dmc +++ /dev/null @@ -1,57 +0,0 @@ -#AUTO -#MAIN -WT 1 -'AMP SETTINGS -AU 0 -BR 1 -AG 0 -TM 1000 -TL 3 -TK 9.998 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -MT -1 -CE 0 -CN-1 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -' -SHX -WT 10 -JS#HOME -WT 10 -JS#RESETP -WT 10 -' -SP 3000000 -AC 60000000 -DC 60000000 -count=0 -idx=0 -#MOVE -II 1 -WT 5 -JP #MOVE -EN -#HOME -OE 0 -JG -10000;BG -#JOG;JP#JOG,@ABS[_TEX]<1000 -ST;AM -OE 1 -WT 10 -EN -#RESETP -PR 32561;BG;AM -DP*=0 -EN -#ININT -idx = count % points -PA pos[idx];BG;AM; -WT 10 -count = count + 1 -RI 1; diff --git a/Modules/PhotoacousticsHardware/Resources/GHOME.dmc b/Modules/PhotoacousticsHardware/Resources/GHOME.dmc deleted file mode 100644 index 7900469823..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/GHOME.dmc +++ /dev/null @@ -1,44 +0,0 @@ -#AUTO -#MAIN -#GHOME -suc=99 -'AMP SETTINGS -AU 0 -BR 1 -AG 0 -TM 1000 -TL 3 -TK 9.998 -suc=98 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -MT -1 -CE 0 -CN-1 -suc=97 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -suc=96 -SHX -WT 10 -SP 3000000 -AC 60000000 -DC 60000000 -' -suc=95 -OE 0 -JG -10000;BG -#JOG;JP#JOG,@ABS[_TEX]<1000 -ST;AM -suc=94 -OE 1 -WT10 -PR 32561;BG;AM -suc=93 -DP*=0 -suc=1 -EN diff --git a/Modules/PhotoacousticsHardware/Resources/OpotekPhocusMobile.xml b/Modules/PhotoacousticsHardware/Resources/OpotekPhocusMobile.xml deleted file mode 100644 index 04f9701ac9..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/OpotekPhocusMobile.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - -4.30076111e+07 - 3.12495804e+05 - -9.43122022e+02 - 1.51584088e+00 - -1.36913735e-03 - 6.59021774e-07 - -1.32069448e-10 - 32561 - - - 690.000 - 750.000 - 950.000 - - - 5 - 115200 - 8 - 0 - 10 - - - 690.0|695.2|700.4|705.6|710.8|716.0|721.2|726.4|731.6|736.8|742.0|747.2|752.4|757.6|762.8|768.0|773.2|778.4|783.6|788.8|794.0|799.2|804.4|809.6|814.8|820.0|825.2|830.4|835.6|840.8|846.0|851.2|856.4|861.6|866.8|872.0|877.2|882.4|887.6|892.8|898.0|903.2|908.4|913.6|918.8|924.0|929.2|934.4|939.6|944.8 - - 0.000727|0.000726|0.000764|0.000795|0.000824|0.000817|0.000832|0.000893|0.000898|0.000881|0.000870|0.000834|0.000849|0.000793|0.000778|0.000753|0.000755|0.000812|0.000843|0.000818|0.000843|0.000824|0.000829|0.000837|0.000832|0.000796|0.000808|0.000796|0.000774|0.000778|0.000760|0.000741|0.000724|0.000725|0.000703|0.000703|0.000695|0.000697|0.000671|0.000702|0.000679|0.000671|0.000676|0.000647|0.000660|0.000674|0.000686|0.000664|0.000658|0.000643 - - 0.042647|0.043251|0.045291|0.047462|0.048515|0.049305|0.049513|0.050434|0.049656|0.050895|0.048269|0.049129|0.050182|0.049334|0.046761|0.045675|0.045061|0.049129|0.050357|0.049206|0.050050|0.048745|0.048822|0.049041|0.048976|0.047813|0.047082|0.046980|0.046980|0.046442|0.045445|0.044063|0.043909|0.042451|0.041058|0.041760|0.042374|0.041683|0.040269|0.042374|0.041299|0.038996|0.041069|0.040736|0.039994|0.040839|0.040225|0.039994|0.038613|0.037692 - - - - - - 4 - 115200 - 8 - N - 1 - - \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/STUNE.dmc b/Modules/PhotoacousticsHardware/Resources/STUNE.dmc deleted file mode 100644 index edc14db0ae..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/STUNE.dmc +++ /dev/null @@ -1,34 +0,0 @@ -#AUTO -#STUNE -suc=-1 -'***************** -'AMP SETTINGS -AU 0 -BR 1 -AG 0 -TM 1000 -TL 3 -TK 9.998 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -MT -1 -CE 0 -CN-1 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -' -SHX -WT 10 -SP 3000000 -AC 60000000 -DC 60000000 -' -suc=-102 -WT 10 -PA pos;BG;AM -suc=1 -EN diff --git a/Modules/PhotoacousticsHardware/Resources/configFastTuneOPO.dmc b/Modules/PhotoacousticsHardware/Resources/configFastTuneOPO.dmc deleted file mode 100644 index e60875bc93..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/configFastTuneOPO.dmc +++ /dev/null @@ -1,28 +0,0 @@ -#AUTO -#MAIN -rt=-1 -II1 -'AMP SETTINGS -AU 0 -BR 1 -'AG 0 -TM 1000 -TL 3 -TK 9.998 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -'MT -1 -'CE 0 -CN-1 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -' -SHX -WT 250 -SP 3000000 -AC 120000000 -DC 120000000 \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/configSlowTuneOPO.dmc b/Modules/PhotoacousticsHardware/Resources/configSlowTuneOPO.dmc deleted file mode 100644 index 91b36d58b1..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/configSlowTuneOPO.dmc +++ /dev/null @@ -1,7 +0,0 @@ -#AUTO -#MAIN -rt=0 -' -SP 150000 -AC 12000000 -DC 12000000 \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/executeFastTuneOPO.dmc b/Modules/PhotoacousticsHardware/Resources/executeFastTuneOPO.dmc deleted file mode 100644 index e616d85969..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/executeFastTuneOPO.dmc +++ /dev/null @@ -1,14 +0,0 @@ -points=pos[-1] -#MOVE -II 1 -WT 5 -rt=1 -JP #MOVE -EN -#ININT -idx = count % points -PA pos[idx];BG;AM; -BG;AM; -count = count + 1 -WT 1 -RI 1; \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/executeSlowTuneOPO.dmc b/Modules/PhotoacousticsHardware/Resources/executeSlowTuneOPO.dmc deleted file mode 100644 index 741d78c64d..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/executeSlowTuneOPO.dmc +++ /dev/null @@ -1,5 +0,0 @@ -PA pos;BG;AM; -BG;AM; -WT 100 -rt = 1 -EN \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/fastTuneOPO.dmc b/Modules/PhotoacousticsHardware/Resources/fastTuneOPO.dmc deleted file mode 100644 index e2d7463d93..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/fastTuneOPO.dmc +++ /dev/null @@ -1,55 +0,0 @@ -#AUTO -#FTUNE -rt=-1 -II1 -'AMP SETTINGS -AU 0 -BR 1 -'AG 0 -TM 1000 -TL 3 -TK 9.998 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -'MT -1 -'CE 0 -CN-1 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -' -SHX -WT 250 -SP 3000000 -AC 120000000 -DC 120000000 -rt=-2 -count=0;idx=0;DM pos[2] -rt=-3 -pos[0]=36459 -pos[1]=24577 -rt=-4 -points=pos[-1] -rt=-5 -#MOVE -rt=-6 -II 1 -WT 5 -rt=1 -JP #MOVE -EN -#ININT -'MG "INSIDE INTERUPPT ROUTINE" -rt=-7 -idx = count % points -MG "idx = ", idx {F2.2} -PA pos[idx];BG;AM; -BG;AM; -rt=-8 -count = count + 1 -WT 1 -RI 1; 'Return to the main program -'and restore trip point \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/fastTuneOPO700to900.dmc b/Modules/PhotoacousticsHardware/Resources/fastTuneOPO700to900.dmc deleted file mode 100644 index 10c65430d7..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/fastTuneOPO700to900.dmc +++ /dev/null @@ -1,48 +0,0 @@ -#AUTO -#MAIN -rt=-1 -II1 -'AMP SETTINGS -AU 0 -BR 1 -'AG 0 -TM 1000 -TL 3 -TK 9.998 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -'MT -1 -'CE 0 -CN-1 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -' -SHX -WT 250 -SP 3000000 -AC 120000000 -DC 120000000 -count=0;idx=0;DM pos[2] -pos[0]=36459 -pos[1]=24577 -points=pos[-1] -#MOVE -II 1 -WT 5 -rt=1 -JP #MOVE -EN -#ININT -'MG "INSIDE INTERUPPT ROUTINE" -idx = count % points -MG "idx = ", idx {F2.2} -PA pos[idx];BG;AM; -BG;AM; -count = count + 1 -WT 1 -RI 1; 'Return to the main program -'and restore trip point \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/homeOPO.dmc b/Modules/PhotoacousticsHardware/Resources/homeOPO.dmc deleted file mode 100644 index 80ef2aaaba..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/homeOPO.dmc +++ /dev/null @@ -1,35 +0,0 @@ -#AUTO -#MAIN -rh=-1 -'***************** -'AMP SETTINGS -AU 0 -BR 1 -'AG 0 -TM 1000 -TL 3 -TK 9.998 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -'MT -1 -'CE 0 -CN-1 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -' -SHX -WT 250 -' -OE 0 -JG -10000;BG -#JOG;JP#JOG,@ABS[_TEX]<1000 -ST;AM -OE 1 -WT 100 -DP*=0 -rh=1 -EN diff --git a/Modules/PhotoacousticsHardware/Resources/opotekPhocusMobileDkfz160907.ini b/Modules/PhotoacousticsHardware/Resources/opotekPhocusMobileDkfz160907.ini deleted file mode 100644 index d2d84f4cfd..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/opotekPhocusMobileDkfz160907.ini +++ /dev/null @@ -1,747 +0,0 @@ -[Index] -Motor Config Size=6 -Current Config=0 -Show Spectrometer=FALSE - -[Software Version] -Software Version="1.3.2" - -[Motor Config 0] -Double BL=1 -Name="SIGNAL" -Default Wavelength=750.000000 -Motor 0 Equation=1 -Motor 0 Coeff="-10034351.9962601084000000000|66823.5712450537248000000|-182.2028426992165750000|0.2617740803347156640|-0.0002092387122824080|0.0000000881876090298|-0.0000000000152863918|146.4419507104903460000" -Motor 0 Speed=150.000000 -Motor 0 Acceleration=10.000000 -Motor 0 Current=0.600000 -Motor 0 Home=0 -Motor 0 BL Size=0 -Motor 0 BL Dir=1 -Motor 0 Max Step=50000 -Motor 0 Min Step=0 -Motor 0 Mix WL=1064.000000 -Motor 0 Name="OPO" -Motor 0 Park=0 -Motor 0 Ramp=150.000000 -Motor 0 Slope=10.000000 -Motor 0 First=0.600000 -Motor 1 Equation=0 -Motor 1 Coeff="" -Motor 1 Speed=150.000000 -Motor 1 Acceleration=10.000000 -Motor 1 Current=0.600000 -Motor 1 Home=0 -Motor 1 BL Size=650 -Motor 1 BL Dir=1 -Motor 1 Max Step=69000 -Motor 1 Min Step=-200 -Motor 1 Mix WL=1064.000000 -Motor 1 Name="UV" -Motor 1 Park=0 -Motor 1 Ramp=150.000000 -Motor 1 Slope=10.000000 -Motor 1 First=0.600000 -Motor 2 Equation=0 -Motor 2 Coeff="" -Motor 2 Speed=150.000000 -Motor 2 Acceleration=10.000000 -Motor 2 Current=0.600000 -Motor 2 Home=0 -Motor 2 BL Size=650 -Motor 2 BL Dir=1 -Motor 2 Max Step=200000 -Motor 2 Min Step=-20000 -Motor 2 Mix WL=1064.000000 -Motor 2 Name="Beamguide" -Motor 2 Park=0 -Motor 2 Ramp=150.000000 -Motor 2 Slope=10.000000 -Motor 2 First=0.600000 -Motor 3 Equation=0 -Motor 3 Coeff="" -Motor 3 Speed=150.000000 -Motor 3 Acceleration=10.000000 -Motor 3 Current=0.600000 -Motor 3 Home=0 -Motor 3 BL Size=650 -Motor 3 BL Dir=1 -Motor 3 Max Step=69000 -Motor 3 Min Step=-200 -Motor 3 Mix WL=1064.000000 -Motor 3 Name="UV L2" -Motor 3 Park=0 -Motor 3 Ramp=150.000000 -Motor 3 Slope=10.000000 -Motor 3 First=0.600000 - -[Motor Config 1] -Double BL=1 -Name="IDLER" -Default Wavelength=1200.000000 -Motor 0 Equation=2 -Motor 0 Coeff="-10034351.9962601084000000000|66823.5712450537248000000|-182.2028426992165750000|0.2617740803347156640|-0.0002092387122824080|0.0000000881876090298|-0.0000000000152863918|146.4419507104903460000" -Motor 0 Speed=150.000000 -Motor 0 Acceleration=10.000000 -Motor 0 Current=0.600000 -Motor 0 Home=0 -Motor 0 BL Size=0 -Motor 0 BL Dir=1 -Motor 0 Max Step=50000 -Motor 0 Min Step=0 -Motor 0 Mix WL=1064.000000 -Motor 0 Name="OPO" -Motor 0 Park=0 -Motor 0 Ramp=150.000000 -Motor 0 Slope=10.000000 -Motor 0 First=0.600000 -Motor 1 Equation=0 -Motor 1 Coeff="" -Motor 1 Speed=150.000000 -Motor 1 Acceleration=10.000000 -Motor 1 Current=0.600000 -Motor 1 Home=0 -Motor 1 BL Size=650 -Motor 1 BL Dir=1 -Motor 1 Max Step=69000 -Motor 1 Min Step=-200 -Motor 1 Mix WL=1064.000000 -Motor 1 Name="UV" -Motor 1 Park=0 -Motor 1 Ramp=150.000000 -Motor 1 Slope=10.000000 -Motor 1 First=0.600000 -Motor 2 Equation=0 -Motor 2 Coeff="" -Motor 2 Speed=150.000000 -Motor 2 Acceleration=10.000000 -Motor 2 Current=0.600000 -Motor 2 Home=0 -Motor 2 BL Size=650 -Motor 2 BL Dir=1 -Motor 2 Max Step=200000 -Motor 2 Min Step=-20000 -Motor 2 Mix WL=1064.000000 -Motor 2 Name="Beamguide" -Motor 2 Park=0 -Motor 2 Ramp=150.000000 -Motor 2 Slope=10.000000 -Motor 2 First=0.600000 -Motor 3 Equation=0 -Motor 3 Coeff="" -Motor 3 Speed=150.000000 -Motor 3 Acceleration=10.000000 -Motor 3 Current=0.600000 -Motor 3 Home=0 -Motor 3 BL Size=650 -Motor 3 BL Dir=1 -Motor 3 Max Step=69000 -Motor 3 Min Step=-200 -Motor 3 Mix WL=1064.000000 -Motor 3 Name="UV L2" -Motor 3 Park=0 -Motor 3 Ramp=150.000000 -Motor 3 Slope=10.000000 -Motor 3 First=0.600000 - -[Motor Config 2] -Double BL=1 -Name="UV-1" -Default Wavelength=230.000000 -Motor 0 Equation=4 -Motor 0 Coeff="-10034351.9962601084000000000|66823.5712450537248000000|-182.2028426992165750000|0.2617740803347156640|-0.0002092387122824080|0.0000000881876090298|-0.0000000000152863918|146.4419507104903460000" -Motor 0 Speed=150.000000 -Motor 0 Acceleration=10.000000 -Motor 0 Current=0.600000 -Motor 0 Home=0 -Motor 0 BL Size=0 -Motor 0 BL Dir=1 -Motor 0 Max Step=50000 -Motor 0 Min Step=0 -Motor 0 Mix WL=1064.000000 -Motor 0 Name="OPO" -Motor 0 Park=0 -Motor 0 Ramp=150.000000 -Motor 0 Slope=10.000000 -Motor 0 First=0.600000 -Motor 1 Equation=3 -Motor 1 Coeff="" -Motor 1 Speed=150.000000 -Motor 1 Acceleration=10.000000 -Motor 1 Current=0.600000 -Motor 1 Home=0 -Motor 1 BL Size=650 -Motor 1 BL Dir=1 -Motor 1 Max Step=69000 -Motor 1 Min Step=-200 -Motor 1 Mix WL=1064.000000 -Motor 1 Name="UV" -Motor 1 Park=0 -Motor 1 Ramp=150.000000 -Motor 1 Slope=10.000000 -Motor 1 First=0.600000 -Motor 2 Equation=0 -Motor 2 Coeff="" -Motor 2 Speed=150.000000 -Motor 2 Acceleration=10.000000 -Motor 2 Current=0.600000 -Motor 2 Home=0 -Motor 2 BL Size=650 -Motor 2 BL Dir=1 -Motor 2 Max Step=200000 -Motor 2 Min Step=-20000 -Motor 2 Mix WL=1064.000000 -Motor 2 Name="Beamguide" -Motor 2 Park=0 -Motor 2 Ramp=150.000000 -Motor 2 Slope=10.000000 -Motor 2 First=0.600000 -Motor 3 Equation=0 -Motor 3 Coeff="" -Motor 3 Speed=150.000000 -Motor 3 Acceleration=10.000000 -Motor 3 Current=0.600000 -Motor 3 Home=0 -Motor 3 BL Size=650 -Motor 3 BL Dir=1 -Motor 3 Max Step=69000 -Motor 3 Min Step=-200 -Motor 3 Mix WL=1064.000000 -Motor 3 Name="UV L2" -Motor 3 Park=0 -Motor 3 Ramp=150.000000 -Motor 3 Slope=10.000000 -Motor 3 First=0.600000 - -[Motor Config 3] -Double BL=1 -Name="UV-2" -Default Wavelength=400.000000 -Motor 0 Equation=4 -Motor 0 Coeff="-10034351.9962601084000000000|66823.5712450537248000000|-182.2028426992165750000|0.2617740803347156640|-0.0002092387122824080|0.0000000881876090298|-0.0000000000152863918|146.4419507104903460000" -Motor 0 Speed=150.000000 -Motor 0 Acceleration=10.000000 -Motor 0 Current=0.600000 -Motor 0 Home=0 -Motor 0 BL Size=0 -Motor 0 BL Dir=1 -Motor 0 Max Step=50000 -Motor 0 Min Step=0 -Motor 0 Mix WL=1064.000000 -Motor 0 Name="OPO" -Motor 0 Park=0 -Motor 0 Ramp=150.000000 -Motor 0 Slope=10.000000 -Motor 0 First=0.600000 -Motor 1 Equation=3 -Motor 1 Coeff="" -Motor 1 Speed=150.000000 -Motor 1 Acceleration=10.000000 -Motor 1 Current=0.600000 -Motor 1 Home=0 -Motor 1 BL Size=650 -Motor 1 BL Dir=1 -Motor 1 Max Step=69000 -Motor 1 Min Step=-200 -Motor 1 Mix WL=1064.000000 -Motor 1 Name="UV" -Motor 1 Park=0 -Motor 1 Ramp=150.000000 -Motor 1 Slope=10.000000 -Motor 1 First=0.600000 -Motor 2 Equation=0 -Motor 2 Coeff="" -Motor 2 Speed=150.000000 -Motor 2 Acceleration=10.000000 -Motor 2 Current=0.600000 -Motor 2 Home=0 -Motor 2 BL Size=650 -Motor 2 BL Dir=1 -Motor 2 Max Step=200000 -Motor 2 Min Step=-20000 -Motor 2 Mix WL=1064.000000 -Motor 2 Name="Beamguide" -Motor 2 Park=0 -Motor 2 Ramp=150.000000 -Motor 2 Slope=10.000000 -Motor 2 First=0.600000 -Motor 3 Equation=0 -Motor 3 Coeff="" -Motor 3 Speed=150.000000 -Motor 3 Acceleration=10.000000 -Motor 3 Current=0.600000 -Motor 3 Home=0 -Motor 3 BL Size=650 -Motor 3 BL Dir=1 -Motor 3 Max Step=69000 -Motor 3 Min Step=-200 -Motor 3 Mix WL=1064.000000 -Motor 3 Name="UV L2" -Motor 3 Park=0 -Motor 3 Ramp=150.000000 -Motor 3 Slope=10.000000 -Motor 3 First=0.600000 - -[Motor Config 4] -Double BL=1 -Name="UV-3" -Default Wavelength=365.000000 -Motor 0 Equation=5 -Motor 0 Coeff="-10034351.9962601084000000000|66823.5712450537248000000|-182.2028426992165750000|0.2617740803347156640|-0.0002092387122824080|0.0000000881876090298|-0.0000000000152863918|146.4419507104903460000" -Motor 0 Speed=150.000000 -Motor 0 Acceleration=10.000000 -Motor 0 Current=0.600000 -Motor 0 Home=0 -Motor 0 BL Size=0 -Motor 0 BL Dir=1 -Motor 0 Max Step=50000 -Motor 0 Min Step=0 -Motor 0 Mix WL=1064.000000 -Motor 0 Name="OPO" -Motor 0 Park=0 -Motor 0 Ramp=150.000000 -Motor 0 Slope=10.000000 -Motor 0 First=0.600000 -Motor 1 Equation=3 -Motor 1 Coeff="" -Motor 1 Speed=150.000000 -Motor 1 Acceleration=10.000000 -Motor 1 Current=0.600000 -Motor 1 Home=0 -Motor 1 BL Size=650 -Motor 1 BL Dir=1 -Motor 1 Max Step=69000 -Motor 1 Min Step=-200 -Motor 1 Mix WL=1064.000000 -Motor 1 Name="UV" -Motor 1 Park=0 -Motor 1 Ramp=150.000000 -Motor 1 Slope=10.000000 -Motor 1 First=0.600000 -Motor 2 Equation=0 -Motor 2 Coeff="" -Motor 2 Speed=150.000000 -Motor 2 Acceleration=10.000000 -Motor 2 Current=0.600000 -Motor 2 Home=0 -Motor 2 BL Size=650 -Motor 2 BL Dir=1 -Motor 2 Max Step=200000 -Motor 2 Min Step=-20000 -Motor 2 Mix WL=1064.000000 -Motor 2 Name="Beamguide" -Motor 2 Park=0 -Motor 2 Ramp=150.000000 -Motor 2 Slope=10.000000 -Motor 2 First=0.600000 -Motor 3 Equation=0 -Motor 3 Coeff="" -Motor 3 Speed=150.000000 -Motor 3 Acceleration=10.000000 -Motor 3 Current=0.600000 -Motor 3 Home=0 -Motor 3 BL Size=650 -Motor 3 BL Dir=1 -Motor 3 Max Step=69000 -Motor 3 Min Step=-200 -Motor 3 Mix WL=1064.000000 -Motor 3 Name="UV L2" -Motor 3 Park=0 -Motor 3 Ramp=150.000000 -Motor 3 Slope=10.000000 -Motor 3 First=0.600000 - -[Motor Config 5] -Double BL=1 -Name="UV-X" -Default Wavelength=450.000000 -Motor 0 Equation=6 -Motor 0 Coeff="-10034351.9962601084000000000|66823.5712450537248000000|-182.2028426992165750000|0.2617740803347156640|-0.0002092387122824080|0.0000000881876090298|-0.0000000000152863918|146.4419507104903460000" -Motor 0 Speed=150.000000 -Motor 0 Acceleration=10.000000 -Motor 0 Current=0.600000 -Motor 0 Home=0 -Motor 0 BL Size=0 -Motor 0 BL Dir=1 -Motor 0 Max Step=50000 -Motor 0 Min Step=0 -Motor 0 Mix WL=1064.000000 -Motor 0 Name="OPO" -Motor 0 Park=0 -Motor 0 Ramp=150.000000 -Motor 0 Slope=10.000000 -Motor 0 First=0.600000 -Motor 1 Equation=3 -Motor 1 Coeff="" -Motor 1 Speed=150.000000 -Motor 1 Acceleration=10.000000 -Motor 1 Current=0.600000 -Motor 1 Home=0 -Motor 1 BL Size=650 -Motor 1 BL Dir=1 -Motor 1 Max Step=69000 -Motor 1 Min Step=-200 -Motor 1 Mix WL=1064.000000 -Motor 1 Name="UV" -Motor 1 Park=0 -Motor 1 Ramp=150.000000 -Motor 1 Slope=10.000000 -Motor 1 First=0.600000 -Motor 2 Equation=0 -Motor 2 Coeff="" -Motor 2 Speed=150.000000 -Motor 2 Acceleration=10.000000 -Motor 2 Current=0.600000 -Motor 2 Home=0 -Motor 2 BL Size=650 -Motor 2 BL Dir=1 -Motor 2 Max Step=200000 -Motor 2 Min Step=-20000 -Motor 2 Mix WL=1064.000000 -Motor 2 Name="Beamguide" -Motor 2 Park=0 -Motor 2 Ramp=150.000000 -Motor 2 Slope=10.000000 -Motor 2 First=0.600000 -Motor 3 Equation=0 -Motor 3 Coeff="" -Motor 3 Speed=150.000000 -Motor 3 Acceleration=10.000000 -Motor 3 Current=0.600000 -Motor 3 Home=0 -Motor 3 BL Size=650 -Motor 3 BL Dir=1 -Motor 3 Max Step=69000 -Motor 3 Min Step=-200 -Motor 3 Mix WL=1064.000000 -Motor 3 Name="UV L2" -Motor 3 Park=0 -Motor 3 Ramp=150.000000 -Motor 3 Slope=10.000000 -Motor 3 First=0.600000 - -[Port Config] -Port=7 -Baud=19200 -Data Bits=8 -Parity=0 -Stop BIts=10 -Flow=0 - -[Laser Serial Port] -Port=5 -Baud=115200 -Data Bits=8 -Parity=0 -Stop BIts=10 -Flow=0 - -[SSC Serial Port] -Port=0 -Baud=9600 -Data Bits=8 -Parity=0 -Stop BIts=10 -Flow=0 - -[Laser Config] -Laser Type=6 -Rep Rate=20 -MAX Power Param.=10.000000 -MIN Power Param.=100.000000 -Soft-Start=FALSE -SS Initial %=10.000000 -SS Steps=10 -Check Safety Interlocks=FALSE -Old Brilliant (no Q-switch control)=FALSE -Load Configuration=0 -Use External Timing=FALSE - -[Spectrometer] -Spectrometer=FALSE -Integration Time=8 -Trigger Mode=3 -Model=0 -Closed-Loop Tuning=FALSE -CL Resolution=0.500000 - -[Module Config] -Pump Wavelength=532.000000 -System Type=9 -Signal-lo=690.000000 -Signal-hi=950.000000 -Idler-lo=1200.000000 -Idler-hi=2400.000000 -UV-1=FALSE -UV-1-lo=0.000000 -UV-1-hi=0.000000 -UV-2=FALSE -UV-2-lo=0.000000 -UV-2-hi=0.000000 -UV-3=FALSE -UV-3-lo=0.000000 -UV-3-hi=0.000000 -UV-M=FALSE -UV-M-lo=0.000000 -UV-M-hi=0.000000 -UV-0=FALSE -UV-0-lo=0.000000 -UV-0-hi=0.000000 -Beamguide=FALSE - -[Miscellaneous] -OPO Recalibrate Max Step=1000 -UV Module Present=FALSE -Beamguide Present=FALSE -Period Decimal Notation=TRUE -OPO Cal. Limit Lo=0 -OPO Cal. Limit Hi=0 -Laser Control Mode=0 -Show User's LSODMM=FALSE -Hide System Configuration menu=TRUE -Closed-loop Tuning=FALSE -Digits of Precision=0 -Polarizer Present=FALSE -Attenuator Present=FALSE -LSODMM=FALSE -Show "Shutter (axis#1)"=FALSE -Shutter (axis#1).Label="" -Disable Tuning=FALSE -Suppress Polarizer Messages=FALSE - -[Automated Polarizer] -Automated Polarizer=FALSE -SIGNAL Position=293 -IDLER Position=438 -Stepper Current=0.600000 - -[Motorized Harmonics] -Motorized Harmonics=TRUE -SHG Min=-200000 -SHG Max=200000 -SHG Last=0 -THG Min=-200000 -THG Max=200000 -THG Last=0 -Fine Step=10 -Medium Step=20 -Coarse Step=50 -Stepper Current=0.600000 -Speed=100 -BL Size=200 -Steps per Revolution=96000 -Auto Optimization=TRUE -Feedback Device=2 -OPO Wavelength=760.000000 -OPO Threshold=0.000050 -Multi-Input Fiber=FALSE -532 Input=FALSE -532 Threshold=425.000000 -355 Input=FALSE -355 Threshold=425.000000 -Energy=90.000000 -Averaging=5 - -[DAQ Device] -DAQ Installed=FALSE -Model=1 -Device S/N=0 - -[Motorized Attenuator] -Motorized Attenuator=FALSE -Current Position=100.000000 -Attenuator Coeff="" -Stepper Current=0.600000 - -[Motor Controller] -Controller Type=1 -Auto Module Detection=FALSE -Motor Addresses="-1|4" -Wiring Scheme=1 - -[KAE Parameters] -Speed Mode=0 -Min Speed=10 -Run Current=20 -Hold Current=10 -Thermal Limit=0 -Output 1=FALSE -Output 2=TRUE -Output 3=TRUE -Output 4=TRUE -Output 5=FALSE -Ignore Limits=FALSE -Ignore E-Stop=TRUE -Off on E-Stop=TRUE - -[Scan Parameters] -Start WL=690.000000 -Period=50.000000 -End WL=950.000000 -Nr of shots/set=10 -Rep Rate=0 -Laser Energy=0.000000 - -[Advanced Scan Parameters] -Wavelengths="" -No. Cycles=0 - -[Burst Parameters] -Wavelength=690 -Nr of shots=10 -Rep Rate=0 -Laser Energy=0.000000 - -[Fast-Scan Parameters] -Start WL=0 -Period=50 -End WL=0 -Laser Energy=0.000000 - -[Shutter Parameters] -SSC32 Installed=FALSE -Shutter0_SSC32_Channel=0 -Shutter0_SIGNAL_Position=0 -Shutter0_IDLER_Position=0 -Shutter0_UV-1_Position=0 -Shutter0_UV-2_Position=0 -Shutter0_UV-3_Position=0 -Shutter0_UV-M_Position=0 -Shutter0_UV-0_Position=0 -Shutter1_SSC32_Channel=0 -Shutter1_SIGNAL_Position=0 -Shutter1_IDLER_Position=0 -Shutter1_UV-1_Position=0 -Shutter1_UV-2_Position=0 -Shutter1_UV-3_Position=0 -Shutter1_UV-M_Position=0 -Shutter1_UV-0_Position=0 -Shutter2_SSC32_Channel=0 -Shutter2_SIGNAL_Position=0 -Shutter2_IDLER_Position=0 -Shutter2_UV-1_Position=0 -Shutter2_UV-2_Position=0 -Shutter2_UV-3_Position=0 -Shutter2_UV-M_Position=0 -Shutter2_UV-0_Position=0 -Shutter3_SSC32_Channel=0 -Shutter3_SIGNAL_Position=0 -Shutter3_IDLER_Position=0 -Shutter3_UV-1_Position=0 -Shutter3_UV-2_Position=0 -Shutter3_UV-3_Position=0 -Shutter3_UV-M_Position=0 -Shutter3_UV-0_Position=0 -Shutter4_SSC32_Channel=0 -Shutter4_SIGNAL_Position=0 -Shutter4_IDLER_Position=0 -Shutter4_UV-1_Position=0 -Shutter4_UV-2_Position=0 -Shutter4_UV-3_Position=0 -Shutter4_UV-M_Position=0 -Shutter4_UV-0_Position=0 - -[Demo Parameters] -Motor Speed=80 -Start WL=0.000000 -End WL=0.000000 - -[Energy Metering] -Meter Installed=FALSE -Device=0 -Use Range #=0 -Device S/N="786441" -OPO S/N="781544" -OPO Channel=-1 -532nm S/N="" -532nm Scale Factor=0.000000 -532nm Channel=-1 -1064nm S/N="" -1064nm Scale Factor=0.000000 -1064nm Channel=-1 -355nm S/N="" -355nm Scale Factor=0.000000 -355nm Channel=-1 -Motor Config 0 Wavelengths="690.0|695.2|700.4|705.6|710.8|716.0|721.2|726.4|731.6|736.8|742.0|747.2|752.4|757.6|762.8|768.0|773.2|778.4|783.6|788.8|794.0|799.2|804.4|809.6|814.8|820.0|825.2|830.4|835.6|840.8|846.0|851.2|856.4|861.6|866.8|872.0|877.2|882.4|887.6|892.8|898.0|903.2|908.4|913.6|918.8|924.0|929.2|934.4|939.6|944.8" -Motor Config 0 Amplitudes="0.000727|0.000726|0.000764|0.000795|0.000824|0.000817|0.000832|0.000893|0.000898|0.000881|0.000870|0.000834|0.000849|0.000793|0.000778|0.000753|0.000755|0.000812|0.000843|0.000818|0.000843|0.000824|0.000829|0.000837|0.000832|0.000796|0.000808|0.000796|0.000774|0.000778|0.000760|0.000741|0.000724|0.000725|0.000703|0.000703|0.000695|0.000697|0.000671|0.000702|0.000679|0.000671|0.000676|0.000647|0.000660|0.000674|0.000686|0.000664|0.000658|0.000643" -Motor Config 0 Energies="0.042647|0.043251|0.045291|0.047462|0.048515|0.049305|0.049513|0.050434|0.049656|0.050895|0.048269|0.049129|0.050182|0.049334|0.046761|0.045675|0.045061|0.049129|0.050357|0.049206|0.050050|0.048745|0.048822|0.049041|0.048976|0.047813|0.047082|0.046980|0.046980|0.046442|0.045445|0.044063|0.043909|0.042451|0.041058|0.041760|0.042374|0.041683|0.040269|0.042374|0.041299|0.038996|0.041069|0.040736|0.039994|0.040839|0.040225|0.039994|0.038613|0.037692" -Motor Config 1 Wavelengths="" -Motor Config 1 Amplitudes="" -Motor Config 1 Energies="" -Motor Config 2 Wavelengths="" -Motor Config 2 Amplitudes="" -Motor Config 2 Energies="" -Motor Config 3 Wavelengths="" -Motor Config 3 Amplitudes="" -Motor Config 3 Energies="" -Motor Config 4 Wavelengths="" -Motor Config 4 Amplitudes="" -Motor Config 4 Energies="" -Motor Config 5 Wavelengths="" -Motor Config 5 Amplitudes="" -Motor Config 5 Energies="" - -[Ophir Sensor Settings] -Sensor1.Model Number="PE25-C" -Sensor1.Sensor Type="Pyroelectric" -Sensor1.Sensor S/N="781544" -Sensor1.Mode=1 -Sensor1.Wavelength=750 -Sensor1.Range=4 -Sensor1.Diffuser=FALSE -Sensor1.Pulsewidth=0 -Sensor1.Threshold=0 -Sensor1.Ext. Trigger=FALSE -Sensor2.Model Number="" -Sensor2.Sensor Type="" -Sensor2.Sensor S/N="" -Sensor2.Mode=0 -Sensor2.Wavelength=0 -Sensor2.Range=0 -Sensor2.Diffuser=FALSE -Sensor2.Pulsewidth=0 -Sensor2.Threshold=0 -Sensor2.Ext. Trigger=FALSE -Sensor3.Model Number="" -Sensor3.Sensor Type="" -Sensor3.Sensor S/N="" -Sensor3.Mode=0 -Sensor3.Wavelength=0 -Sensor3.Range=0 -Sensor3.Diffuser=FALSE -Sensor3.Pulsewidth=0 -Sensor3.Threshold=0 -Sensor3.Ext. Trigger=FALSE -Sensor4.Model Number="" -Sensor4.Sensor Type="" -Sensor4.Sensor S/N="" -Sensor4.Mode=0 -Sensor4.Wavelength=0 -Sensor4.Range=0 -Sensor4.Diffuser=FALSE -Sensor4.Pulsewidth=0 -Sensor4.Threshold=0 -Sensor4.Ext. Trigger=FALSE - -[UV Look-up Table] -UV-1 Use Lookup Table=FALSE -UV-1 Wavelengths="" -UV-1 Steps="" -UV-2 Use Lookup Table=FALSE -UV-2 Wavelengths="" -UV-2 Steps="" -UV-3 Use Lookup Table=FALSE -UV-3 Wavelengths="" -UV-3 Steps="" -UV-M Use Lookup Table=FALSE -UV-M Wavelengths="" -UV-M Steps="" -UV-0 Use Lookup Table=FALSE -UV-0 Wavelengths="" -UV-0 Steps="" - -[Fast Tuning] -Fast Tuning=TRUE -Kp=0.000000 -Ki=0.000000 -Kd=0.000000 \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/test.dmc b/Modules/PhotoacousticsHardware/Resources/test.dmc deleted file mode 100644 index af11477497..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/test.dmc +++ /dev/null @@ -1,46 +0,0 @@ -#FASTTUNE -rtf=-1 -II1 -'AMP SETTINGS -AU 0 -BR 1 -'AG 0 -TM 1000 -TL 3 -TK 9.998 -' -'GENERAL SETTINGS -ER 10000 -OE 1 -'MT -1 -'CE 0 -CN-1 -'PID PARAMETERS -KD 17.5 -KP 15 -KI 0 -' -SHX -WT 1000 -SP 1500000 -AC 120000000 -DC 120000000 -count=0;idx=0;DM pos[2] -pos[0]=27200 -pos[1]=30900 -points=pos[-1] -#MOVE; -II 1 -WT 10 -JP #MOVE; -EN -'SUBROUTINE -'************************************** -#ININT -rtf=count+10000000; -idx = count % points -'PA pos[idx];BG;AM; -'BG;AM; -count = count + 1 -WT 1 -RI 1; \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/Resources/tuneOPOto700.dmc b/Modules/PhotoacousticsHardware/Resources/tuneOPOto700.dmc deleted file mode 100644 index ac97c28bc2..0000000000 --- a/Modules/PhotoacousticsHardware/Resources/tuneOPOto700.dmc +++ /dev/null @@ -1,13 +0,0 @@ -#AUTO -#MAIN -rt=0 -' -SP 150000 -AC 12000000 -DC 12000000 -pos=36459 -PA pos;BG;AM; -BG;AM; -WT 100 -rt=1 -EN \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/files.cmake b/Modules/PhotoacousticsHardware/files.cmake deleted file mode 100644 index d6d5d51880..0000000000 --- a/Modules/PhotoacousticsHardware/files.cmake +++ /dev/null @@ -1,23 +0,0 @@ -set(CPP_FILES - mitkQuantelLaser.cpp - mitkGalilMotor.cpp - mitkOphirPyro.cpp -) - -set(RESOURCE_FILES - homeOPO.dmc - - GHOME.dmc - STUNE.dmc - FTUNE.dmc - - configSlowTuneOPO.dmc - executeSlowTuneOPO.dmc - - configFastTuneOPO.dmc - executeFastTuneOPO.dmc - - test.dmc - tuneOPOto700.dmc - OpotekPhocusMobile.xml -) \ No newline at end of file diff --git a/Modules/PhotoacousticsHardware/mitkGalilMotor.cpp b/Modules/PhotoacousticsHardware/mitkGalilMotor.cpp deleted file mode 100644 index 74cbef697b..0000000000 --- a/Modules/PhotoacousticsHardware/mitkGalilMotor.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkGalilMotor.h" - -#include -#include - -#include - -#include "gclib.h" -#include "gclib_errors.h" - -#include "gclibo.h" - -mitk::GalilMotor::GalilMotor() : -m_ComPort(0), -m_BaudRate(0), -m_ErrorMessage("undefined"), -m_CurrentWavelength(0), -m_HomePosition(32561) -{ -} - -mitk::GalilMotor::~GalilMotor() -{ - this->CloseConnection(); - MITK_INFO << "[GalilMotor Debug] destroyed that motor"; -} - -void mitk::GalilMotor::LoadResorceFile(std::string filename, std::string* lines) -{ - us::ModuleResource resorceFile = us::GetModuleContext()->GetModule()->GetResource(filename); - std::string line; - if (resorceFile.IsValid() && resorceFile.IsFile()) - { - us::ModuleResourceStream stream(resorceFile); - while (std::getline(stream, line)) - { - *lines = *lines + line + "\n"; - } - } - else - { - MITK_ERROR << "Resource file was not valid"; - } -} - -bool mitk::GalilMotor::OpenConnection(std::string configuration) -{ - m_GalilSystem = 0; - m_ReturnCode = G_NO_ERROR; - LoadResorceFile(configuration + ".xml", &m_XmlOpoConfiguration); - TiXmlDocument xmlDoc; - - if (xmlDoc.Parse(m_XmlOpoConfiguration.c_str(), 0, TIXML_ENCODING_UTF8)) - { - TiXmlElement* root = xmlDoc.FirstChildElement("Motor"); - if (root) - { - TiXmlElement* elementNode = root->FirstChildElement("Coefficients"); - TiXmlElement* element = elementNode->FirstChildElement("lambda0"); - m_WavelengthToStepCalibration[0] = std::stod(element->GetText()); - element = elementNode->FirstChildElement("lambda1"); - m_WavelengthToStepCalibration[1] = std::stod(element->GetText()); - element = elementNode->FirstChildElement("lambda2"); - m_WavelengthToStepCalibration[2] = std::stod(element->GetText()); - element = elementNode->FirstChildElement("lambda3"); - m_WavelengthToStepCalibration[3] = std::stod(element->GetText()); - element = elementNode->FirstChildElement("lambda4"); - m_WavelengthToStepCalibration[4] = std::stod(element->GetText()); - element = elementNode->FirstChildElement("lambda5"); - m_WavelengthToStepCalibration[5] = std::stod(element->GetText()); - element = elementNode->FirstChildElement("lambda6"); - m_WavelengthToStepCalibration[6] = std::stod(element->GetText()); - element = elementNode->FirstChildElement("home"); - m_HomePosition = std::stod(element->GetText()); - elementNode = root->FirstChildElement("Signal"); - element = elementNode->FirstChildElement("Signal-low"); - m_MinWavelength = std::stod(element->GetText()); - element = elementNode->FirstChildElement("Signal-default"); - m_CurrentWavelength = std::stod(element->GetText()); - element = elementNode->FirstChildElement("Signal-high"); - m_MaxWavelength = std::stod(element->GetText()); - elementNode = root->FirstChildElement("Seriell"); - element = elementNode->FirstChildElement("PortNumber"); - m_ComPort = std::stoi(element->GetText()); - element = elementNode->FirstChildElement("Baud"); - m_BaudRate = std::stoi(element->GetText()); - } - } - else - { - MITK_ERROR << "[GalilMotor Debug] Could not load configuration xml "; - } - std::string openCommand("COM" + std::to_string(m_ComPort) + " --baud " + std::to_string(m_BaudRate) + " --subscribe ALL --direct"); - MITK_INFO << "[Galil Debug] before GOpen(" << openCommand << ") = " << m_ReturnCode << "; m_GalilSystem = " << m_GalilSystem; - m_ReturnCode = GOpen(openCommand.c_str(), &m_GalilSystem); - MITK_INFO << "[Galil Debug] after GOpen = " << m_ReturnCode << "; m_GalilSystem = " << m_GalilSystem; - this->Home(); - return true; -} - -bool mitk::GalilMotor::CloseConnection() -{ - if (m_GalilSystem) - { - this->Home(); - m_ReturnCode = GClose(m_GalilSystem); - m_GalilSystem = 0; - return true; - } - else - return false; -} - -int mitk::GalilMotor::GetPositionFromWavelength(double wavelength) -{ - double posDouble = 0; - posDouble = m_WavelengthToStepCalibration[0] - m_HomePosition; - posDouble += (m_WavelengthToStepCalibration[1] * wavelength); - posDouble += (m_WavelengthToStepCalibration[2] * std::pow(wavelength, 2)); - posDouble += (m_WavelengthToStepCalibration[3] * std::pow(wavelength, 3)); - posDouble += (m_WavelengthToStepCalibration[4] * std::pow(wavelength, 4)); - posDouble += (m_WavelengthToStepCalibration[5] * std::pow(wavelength, 5)); - posDouble += (m_WavelengthToStepCalibration[6] * std::pow(wavelength, 6)); - int pos = posDouble; - return pos; -} - -bool mitk::GalilMotor::TuneToWavelength(double wavelength, bool isRecalibrating) -{ - std::string positionCommand; - if (!isRecalibrating) - { - positionCommand = "pos=" + std::to_string(this->GetPositionFromWavelength(wavelength)); - } - else - { - int posAbs = wavelength - m_HomePosition; - positionCommand = "pos=" + std::to_string(posAbs); - } - - m_ReturnCode = GCmd(m_GalilSystem, "AB"); // Abort any running programs - MITK_INFO << "[Galil Debug] after AB: " << m_ReturnCode << ""; - m_ReturnCode = GCmd(m_GalilSystem, "BV"); // Burn all variables - MITK_INFO << "[Galil Debug] after BV: " << m_ReturnCode << ""; - m_ReturnCode = GProgramDownload(m_GalilSystem, "", 0); // Erase the program on the system - MITK_INFO << "[Galil Debug] after empty GProgramDownload: " << m_ReturnCode << ""; - - m_ReturnCode = GCmd(m_GalilSystem, positionCommand.c_str()); - MITK_INFO << "[Galil Debug] after sending tune position(" << positionCommand << "): " << m_ReturnCode << ""; - - std::string galilProgramSTUNE; - this->LoadResorceFile("STUNE.dmc", &galilProgramSTUNE); - m_ReturnCode = GProgramDownload(m_GalilSystem, galilProgramSTUNE.c_str(), 0); - MITK_INFO << "[Galil Debug] after STUNE progam: " << m_ReturnCode << galilProgramSTUNE; - - GSleep(10); - m_ReturnCode = GCmd(m_GalilSystem, "XQ#STUNE"); - MITK_INFO << "[Galil Debug] after sending XQ#STUNE = " << m_ReturnCode; - GSleep(10000); - int success, pos = -1; - m_ReturnCode = GCmdI(m_GalilSystem, "suc=?", &success); - MITK_INFO << "[Galil Debug] after asking suc=? = " << m_ReturnCode << "; successfulTune = " << success; - m_ReturnCode = GCmdI(m_GalilSystem, "pos=?", &pos); - MITK_INFO << "[Galil Debug] after asking pos=? = " << m_ReturnCode << "; pos = " << pos; - if (success == 1) - { - m_CurrentWavelength = wavelength; - return true; - } - else - return false; -} - -bool mitk::GalilMotor::FastTuneWavelengths(std::vector wavelengthList) -{ - m_ReturnCode = GCmd(m_GalilSystem, "AB"); // Abort any running programs - GSleep(1000); - MITK_INFO << "[Galil Debug] after AB: " << m_ReturnCode << ""; - m_ReturnCode = GCmd(m_GalilSystem, "BV"); // Burn all variables - GSleep(2000); - MITK_INFO << "[Galil Debug] after BV: " << m_ReturnCode << ""; - - m_ReturnCode = GProgramDownload(m_GalilSystem, "", 0); // Erase the program on the system - MITK_INFO << "[Galil Debug] after empty GProgramDownload: " << m_ReturnCode << ""; - GSleep(1000); - std::string positionsCommand("#AUTO\n#PARA\nDA pos[0]\npoints = "+std::to_string(wavelengthList.size())+"\nDM pos[" + std::to_string(wavelengthList.size()) + "];\n"); - - for (int wavelengthIterator = 0; wavelengthIterator < wavelengthList.size(); wavelengthIterator++) - { - positionsCommand += "pos[" + std::to_string(wavelengthIterator) + "]=" + std::to_string(this->GetPositionFromWavelength(wavelengthList[wavelengthIterator])) + "\n"; - } - positionsCommand += "EN\n"; - - m_ReturnCode = GProgramDownload(m_GalilSystem, positionsCommand.c_str(), 0); - MITK_INFO << "[Galil Debug] after sending positions command(" << positionsCommand << "): " << m_ReturnCode << ""; - GSleep(1000); - m_ReturnCode = GCmd(m_GalilSystem, "XQ"); // FTUNE - MITK_INFO << "[Galil Debug] after asking XQ#PARA = " << m_ReturnCode; - m_ReturnCode = GProgramDownload(m_GalilSystem, "", 0); // Erase the program on the system - MITK_INFO << "[Galil Debug] after empty GProgramDownload: " << m_ReturnCode << ""; - GSleep(1000); - std::string galilProgramFTUNE; - this->LoadResorceFile("FTUNE.dmc", &galilProgramFTUNE); - m_ReturnCode = GProgramDownload(m_GalilSystem, galilProgramFTUNE.c_str(), 0); - MITK_INFO << "[Galil Debug] after FTUNE progam upload: " << m_ReturnCode << ""; - - GSleep(1000); - m_ReturnCode = GCmd(m_GalilSystem, "XQ"); // FTUNE - MITK_INFO << "[Galil Debug] after asking XQ#FTUNE = " << m_ReturnCode; - GSleep(10000); - int count = -1; - m_ReturnCode = GCmdI(m_GalilSystem, "count=?", &count); - MITK_INFO << "[Galil Debug] cycles = " << count; - m_ReturnCode = GCmdI(m_GalilSystem, "pos=?", &count); - MITK_INFO << "[Galil Debug] pos = " << count; - m_ReturnCode = GCmdI(m_GalilSystem, "points=?", &count); - MITK_INFO << "[Galil Debug] points = " << count; - - if (count > 0) - return true; - else - return false; -} - -bool mitk::GalilMotor::Home() -{ - m_ReturnCode = GCmd(m_GalilSystem, "AB"); // Abort any running programs - MITK_INFO << "[Galil Debug] after AB: " << m_ReturnCode << ""; - GSleep(1000); - m_ReturnCode = GCmd(m_GalilSystem, "BV"); // Burn all variables - MITK_INFO << "[Galil Debug] after BV: " << m_ReturnCode << ""; - GSleep(1000); - m_ReturnCode = GProgramDownload(m_GalilSystem, "", 0); // Erase the program on the system - MITK_INFO << "[Galil Debug] after empty GProgramDownload: " << m_ReturnCode << ""; - - std::string galilProgram; - this->LoadResorceFile("GHOME.dmc", &galilProgram); - - m_ReturnCode = GProgramDownload(m_GalilSystem, galilProgram.c_str(), 0); - MITK_INFO << "[Galil Debug] after home GProgramDownloadFile = " << m_ReturnCode << "; m_GalilSystem = " << m_GalilSystem; - - m_ReturnCode = GCmd(m_GalilSystem, "XQ"); // HOME - GSleep(15000); - int val = -2; - m_ReturnCode = GCmdI(m_GalilSystem, "suc=?", &val); - - MITK_INFO << "[Galil Debug] after home execution = " << m_ReturnCode << "; m_GalilSystem = " << m_GalilSystem << " homed = " << val; - - return true; -} - -double mitk::GalilMotor::GetMinWavelength() -{ - return m_MinWavelength; -} - -double mitk::GalilMotor::GetMaxWavelength() -{ - return m_MaxWavelength; -} - -double mitk::GalilMotor::GetCurrentWavelength() -{ - return m_CurrentWavelength; -} diff --git a/Modules/PhotoacousticsHardware/mitkGalilMotor.h b/Modules/PhotoacousticsHardware/mitkGalilMotor.h deleted file mode 100644 index 966dfe707d..0000000000 --- a/Modules/PhotoacousticsHardware/mitkGalilMotor.h +++ /dev/null @@ -1,76 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef MITKGalilAPI_H_HEADER_INCLUDED -#define MITKGalilAPI_H_HEADER_INCLUDED - -#include "itkObject.h" -#include "mitkCommon.h" - -#include "vector" -#include "MitkPhotoacousticsHardwareExports.h" - -#include "gclib.h" -#include "gclibo.h" - -#include -#include -#include -#include -#include - -#include - -namespace mitk { - - class MITKPHOTOACOUSTICSHARDWARE_EXPORT GalilMotor : public itk::Object - { - public: - mitkClassMacroItkParent(mitk::GalilMotor, itk::Object); - itkFactorylessNewMacro(Self); - - virtual bool OpenConnection(std::string configuration); - virtual bool CloseConnection(); - - double GetMinWavelength(); - double GetMaxWavelength(); - double GetCurrentWavelength(); - - bool TuneToWavelength(double wavelength, bool isRecalibrating); - - bool FastTuneWavelengths(std::vector wavelengthList); - - protected: - virtual bool Home(); - void LoadResorceFile(std::string filename, std::string* lines); - int GetPositionFromWavelength(double wavelength); - GalilMotor(); - virtual ~GalilMotor(); - - int m_ComPort; - int m_BaudRate; - std::string m_ErrorMessage; - GCon m_GalilSystem; - GReturn m_ReturnCode; - - std::string m_XmlOpoConfiguration; - double m_MinWavelength; - double m_MaxWavelength; - double m_CurrentWavelength; - double m_WavelengthToStepCalibration[7]; - double m_HomePosition; - - }; -} // namespace mitk - -#endif /* MITKGalilAPI_H_HEADER_INCLUDED */ diff --git a/Modules/PhotoacousticsHardware/mitkOphirPyro.cpp b/Modules/PhotoacousticsHardware/mitkOphirPyro.cpp deleted file mode 100644 index 54081c8922..0000000000 --- a/Modules/PhotoacousticsHardware/mitkOphirPyro.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkOphirPyro.h" - -#include -#include -#include -#include - -mitk::OphirPyro::OphirPyro() : -m_CurrentWavelength(0), -m_DeviceHandle(0), -m_Connected(false), -m_Streaming(false), -m_SerialNumber(nullptr), -m_GetDataThread(), -m_ImagePyroDelay(0), -m_EnergyMultiplicator(60000) -{ - m_PulseEnergy.clear(); - m_PulseTime.clear(); - m_PulseStatus.clear(); - m_TimeStamps.clear(); -} - -mitk::OphirPyro::~OphirPyro() -{ - if (m_Connected) - { - this->CloseConnection(); - if (m_GetDataThread.joinable()) - { - m_GetDataThread.join(); - MITK_INFO << "[OphirPyro Debug] joined data thread"; - } - } - MITK_INFO << "[OphirPyro Debug] destroying that Pyro"; - /* cleanup thread */ -} - -bool mitk::OphirPyro::StartDataAcquisition() -{ - if (ophirAPI.StartStream(m_DeviceHandle)) - { - m_Streaming = true; - m_GetDataThread = std::thread(&mitk::OphirPyro::GetDataFromSensorThread, this); - } - return m_Streaming; -} - -// this is just a little function to set the filenames below right -inline void replaceAll(std::string& str, const std::string& from, const std::string& to) { - if (from.empty()) - return; - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' - } -} - -void mitk::OphirPyro::SaveCsvData() -{ - // get the time and date, put them into a nice string and create a folder for the images - time_t time = std::time(nullptr); - time_t* timeptr = &time; - std::string currentDate = std::ctime(timeptr); - replaceAll(currentDate, ":", "-"); - currentDate.pop_back(); - - std::string pathTS = "c:\\ImageData\\" + currentDate + " pyro-ts" + ".csv"; - - std::ofstream timestampFile; - timestampFile.open(pathTS); - - timestampFile << ",timestamp,PulseEnergy,PulseTime"; - - int currentSize = m_TimeStamps.size(); - - for (int index = 0; index < currentSize; ++index) - { - timestampFile << "\n" << index << "," << m_TimeStamps.at(index) << ","<< m_PulseEnergySaved.at(index) << "," << (long)m_PulseTimeSaved.at(index); - } - timestampFile.close(); -} - -void mitk::OphirPyro::SaveData() -{ - SaveCsvData(); -} - -bool mitk::OphirPyro::StopDataAcquisition() -{ - if (ophirAPI.StopStream(m_DeviceHandle)) - m_Streaming = false; - - SaveCsvData(); - MITK_INFO << "[OphirPyro Debug] m_Streaming = "<< m_Streaming; - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - if (m_GetDataThread.joinable()) - { - m_GetDataThread.join(); - } - return !m_Streaming; -} - -unsigned int mitk::OphirPyro::GetDataFromSensor() -{ - if (m_Streaming) - { - std::vector newEnergy; - std::vector newTimestamp; - std::vector newStatus; - unsigned int noPackages = 0; - try - { - noPackages = ophirAPI.GetData(m_DeviceHandle, &newEnergy, &newTimestamp, &newStatus); - if (noPackages > 0) - { - m_PulseEnergy.insert(m_PulseEnergy.end(), newEnergy.begin(), newEnergy.end()); - for (unsigned int i=0; iGetDataFromSensor(); - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - return; -} - -double mitk::OphirPyro::LookupCurrentPulseEnergy() -{ - if (m_Connected && !m_PulseEnergy.empty()) - { - MITK_INFO << m_PulseEnergy.size(); - return m_PulseEnergy.back(); - } - return 0; -} - -double mitk::OphirPyro::GetClosestEnergyInmJ(long long ImageTimeStamp, double interval) -{ - if (m_PulseTime.size() == 0) - return 0; - - long long searchTime = (ImageTimeStamp/1000000) - m_ImagePyroDelay; // conversion from ns to ms - - //MITK_INFO << "searchTime = " << searchTime; - int foundIndex = -1; - long long shortestDifference = 250*interval; - - // search the list for a fitting energy value time - for (int index = 0; index < m_PulseTime.size();++index) - { - long long newDifference = abs(((int)m_PulseTime[index]) - searchTime); - //MITK_INFO << "newDifference[" << index << "] = " << newDifference; - if (newDifference < shortestDifference) - { - shortestDifference = newDifference; - foundIndex = index; - //MITK_INFO << "foundIndex = " << foundIndex; - } - } - - if (abs(shortestDifference) < interval) - { - // delete all elements before the one found - m_PulseEnergy.erase(m_PulseEnergy.begin(), m_PulseEnergy.begin() + foundIndex); - m_PulseTime.erase(m_PulseTime.begin(), m_PulseTime.begin() + foundIndex); - m_PulseStatus.erase(m_PulseStatus.begin(), m_PulseStatus.begin() + foundIndex); - - // multipy with m_EnergyMultiplicator, because the Pyro gives just a fraction of the actual Laser Energy - return (GetNextPulseEnergy()*m_EnergyMultiplicator); - } - - //MITK_INFO << "No matching energy value for image found in interval of " << interval << "ms. sd: " << shortestDifference; - return -1; -} - -double mitk::OphirPyro::GetNextEnergyInmJ(long long ImageTimeStamp, double interval) -{ - if (m_Connected && !(m_PulseTime.size() > 0)) - return 0; - - long long searchTime = (ImageTimeStamp / 1000000) - m_ImagePyroDelay; // conversion from ns to ms - - if (abs(searchTime - m_PulseTime.front()) < interval) - { - return (GetNextPulseEnergy()*m_EnergyMultiplicator); // multipy with m_EnergyMultiplicator, because the Pyro gives just a fraction of the actual Laser Energy - } - - MITK_INFO << "Image aquisition and energy measurement ran out of sync"; - return -1; -} - -void mitk::OphirPyro::SetSyncDelay(long long FirstImageTimeStamp) -{ - while (!m_PulseTime.size()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - m_ImagePyroDelay = (FirstImageTimeStamp / 1000000) - m_PulseTime.at(0); - - MITK_INFO << "m_ImagePyroDelay = " << m_ImagePyroDelay; - return; -} - -bool mitk::OphirPyro::IsSyncDelaySet() -{ - return (m_ImagePyroDelay != 0); -} - -double mitk::OphirPyro::GetNextPulseEnergy() -{ - if (m_Connected && m_PulseEnergy.size()>=1) - { - double out = m_PulseEnergy.front(); - m_PulseEnergy.erase(m_PulseEnergy.begin()); - m_PulseTime.erase(m_PulseTime.begin()); - m_PulseStatus.erase(m_PulseStatus.begin()); - return out; - } - return 0; -} - -double mitk::OphirPyro::LookupCurrentPulseEnergy(double* timestamp, int* status) -{ - if (m_Connected) - { - *timestamp = m_PulseTime.back(); - *status = m_PulseStatus.back(); - return m_PulseEnergy.back(); - } - return 0; -} - -double mitk::OphirPyro::GetNextPulseEnergy(double* timestamp, int* status) -{ - if (m_Connected) - { - double out = m_PulseEnergy.front(); - *timestamp = m_PulseTime.front(); - *status = m_PulseStatus.front(); - m_PulseEnergy.erase(m_PulseEnergy.begin()); - m_PulseTime.erase(m_PulseTime.begin()); - m_PulseStatus.erase(m_PulseStatus.begin()); - return out; - } - return 0; -} - -bool mitk::OphirPyro::OpenConnection() -{ - if (!m_Connected) - { - char* m_SerialNumber; - try { - MITK_INFO << "Scanning for Ophir connection"; - m_SerialNumber = ophirAPI.ScanUSB(); - } - catch (...) - { - MITK_INFO << "Scanning failed, trying again in 2 seconds..."; - std::this_thread::sleep_for(std::chrono::seconds(2)); - MITK_INFO << "Scanning for Ophir connection"; - m_SerialNumber = ophirAPI.ScanUSB(); - } - - if (m_SerialNumber != 0) - { - try { - MITK_INFO << "Opening Ophir connection"; - m_DeviceHandle = ophirAPI.OpenDevice(m_SerialNumber); - } - catch (...) - { - MITK_INFO << "Ophir connection failed, trying again in 2 seconds..."; - std::this_thread::sleep_for(std::chrono::seconds(2)); - MITK_INFO << "Opening Ophir connection"; - m_DeviceHandle = ophirAPI.OpenDevice(m_SerialNumber); - } - - if (m_DeviceHandle != 0) - { - m_Connected = true; - return true; - } - } - } - return false; -} - -bool mitk::OphirPyro::CloseConnection() -{ - if (m_Connected) - { - bool closed = ophirAPI.CloseDevice(m_DeviceHandle); - if (closed) m_DeviceHandle = 0; - m_Connected = !closed; - return closed; - } - return false; -} diff --git a/Modules/PhotoacousticsHardware/mitkOphirPyro.h b/Modules/PhotoacousticsHardware/mitkOphirPyro.h deleted file mode 100644 index b6f09654a7..0000000000 --- a/Modules/PhotoacousticsHardware/mitkOphirPyro.h +++ /dev/null @@ -1,90 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef MITKOPHIRPYRO_H_HEADER_INCLUDED -#define MITKOPHIRPYRO_H_HEADER_INCLUDED - -#include "itkObject.h" -#include "mitkCommon.h" - -#include "vector" -#include "MitkPhotoacousticsHardwareExports.h" - -#include "OphirPyroWrapper.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mitk { - - class MITKPHOTOACOUSTICSHARDWARE_EXPORT OphirPyro : public itk::Object - { - public: - mitkClassMacroItkParent(mitk::OphirPyro, itk::Object); - itkFactorylessNewMacro(Self); - - virtual bool OpenConnection(); - virtual bool CloseConnection(); - virtual bool StartDataAcquisition(); - virtual bool StopDataAcquisition(); - unsigned int GetDataFromSensor(); - void GetDataFromSensorThread(); - void SaveData(); - - virtual double LookupCurrentPulseEnergy(); - virtual double GetNextPulseEnergy(); - virtual double LookupCurrentPulseEnergy(double* timestamp, int* status); - virtual double GetNextPulseEnergy(double* timestamp, int* status); - - virtual double GetClosestEnergyInmJ(long long ImageTimeStamp, double interval=20); - virtual double GetNextEnergyInmJ(long long ImageTimeStamp, double interval = 20); - virtual void SetSyncDelay(long long FirstImageTimeStamp); - virtual bool IsSyncDelaySet(); - - - protected: - OphirPyro(); - virtual ~OphirPyro(); - void SaveCsvData(); - OphirPyroWrapper ophirAPI; - char* m_SerialNumber; - int m_DeviceHandle; - bool m_Connected; - bool m_Streaming; - std::vector m_PulseEnergy; - std::vector m_PulseTime; - std::vector m_PulseStatus; - std::vector m_TimeStamps; - - std::vector m_PulseEnergySaved; - std::vector m_PulseTimeSaved; - std::vector m_PulseStatusSaved; - std::vector m_TimeStampsSaved; - - double m_CurrentWavelength; - double m_CurrentEnergyRange; - long long m_ImagePyroDelay; - float m_EnergyMultiplicator; - - std::thread m_GetDataThread; - }; -} // namespace mitk - -#endif /* MITKOPHIRPYRO_H_HEADER_INCLUDED */ diff --git a/Modules/PhotoacousticsHardware/mitkQuantelLaser.cpp b/Modules/PhotoacousticsHardware/mitkQuantelLaser.cpp deleted file mode 100644 index c742b8b072..0000000000 --- a/Modules/PhotoacousticsHardware/mitkQuantelLaser.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkQuantelLaser.h" - -#include -#include -#include - -#include - -#include -#include - -const unsigned char CR = 0xD; // == '\r' - carriage return -const unsigned char LF = 0xA; // == '\n' - line feed - -mitk::QuantelLaser::QuantelLaser() : - m_State(mitk::QuantelLaser::UNCONNECTED), - m_FlashlampRunning(false), - m_ShutterOpen(false), - m_LaserEmission(false), - m_DeviceName(), - m_PortNumber(mitk::SerialCommunication::COM6), - m_BaudRate(mitk::SerialCommunication::BaudRate115200), - m_DataBits(mitk::SerialCommunication::DataBits8), - m_Parity(mitk::SerialCommunication::None), - m_StopBits(mitk::SerialCommunication::StopBits1), - m_HardwareHandshake(mitk::SerialCommunication::HardwareHandshakeOff), - m_SerialCommunication(nullptr), - m_StayAliveMessageThread(), - m_SerialCommunicationMutex() -{ -} - -mitk::QuantelLaser::~QuantelLaser() -{ - /* stop tracking and disconnect from tracking device */ - if ((GetState() == STATE3) || (GetState() == STATE4) || (GetState() == STATE5) || (GetState() == STATE6)) - { - this->StopQswitching(); - this->StopFlashing(); - } - if (GetState() == STATE2) - { - this->CloseConnection(); - } - /* cleanup stay alive thread */ - if (m_StayAliveMessageThread.joinable()) - m_StayAliveMessageThread.join(); - - /* free serial communication interface */ - if (m_SerialCommunication.IsNotNull()) - { - m_SerialCommunication->ClearReceiveBuffer(); - m_SerialCommunication->ClearSendBuffer(); - m_SerialCommunication->CloseConnection(); - m_SerialCommunication = nullptr; - } -} - -std::string mitk::QuantelLaser::SendAndReceiveLine(const std::string* input, std::string* answer) -{ - MITK_INFO << "[Quantel Laser Debug] sending: " << input->c_str(); - if (input == nullptr) - return "SERIALSENDERROR"; - - std::string message; - - message = *input + '\n'; - - // Clear send buffer - m_SerialCommunication->ClearSendBuffer(); - m_SerialCommunication->Send(message); - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - std::string m; - do - { - long returnvalue = m_SerialCommunication->Receive(m, 1); - if ((returnvalue == 0) || (m.size() != 1)) - return "SERIALRECEIVEERROR"; - *answer += m; - } while (m.at(0) != LF); - m_SerialCommunication->ClearReceiveBuffer(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - m_SerialCommunication->ClearReceiveBuffer(); - MITK_INFO << "[Quantel Laser Debug] received: " << answer->c_str(); - return "OK"; -} - -void mitk::QuantelLaser::LoadResorceFile(std::string filename, std::string* lines) -{ - us::ModuleResource resorceFile = us::GetModuleContext()->GetModule()->GetResource(filename); - std::string line; - if (resorceFile.IsValid() && resorceFile.IsFile()) - { - us::ModuleResourceStream stream(resorceFile); - while (std::getline(stream, line)) - { - *lines = *lines + line + "\n"; - } - } - else - { - MITK_ERROR << "[Quantel Laser Debug] Resource file was not valid"; - } -} - -bool mitk::QuantelLaser::OpenConnection(std::string configurationFile) -{ - LoadResorceFile(configurationFile + ".xml", &m_XmlPumpLaserConfiguration); - TiXmlDocument xmlDoc; - - if (xmlDoc.Parse(m_XmlPumpLaserConfiguration.c_str(), 0, TIXML_ENCODING_UTF8)) - { - TiXmlElement* root = xmlDoc.FirstChildElement("PumpLaser"); - if (root) - { - TiXmlElement* elementNode = root->FirstChildElement("Seriell"); - TiXmlElement* element = elementNode->FirstChildElement("PortNumber"); - m_PortNumber = mitk::SerialCommunication::PortNumber(std::stoi(element->GetText())); - element = elementNode->FirstChildElement("Baud"); - m_BaudRate = mitk::SerialCommunication::BaudRate(std::stoi(element->GetText())); - - MITK_INFO << m_PortNumber << m_BaudRate; - } - } - else - { - MITK_ERROR << "[Quantel Laser Debug] Could not load configuration xml "; - return false; - } - - m_SerialCommunication = mitk::SerialCommunication::New(); - - if (m_DeviceName.empty()) - m_SerialCommunication->SetPortNumber(m_PortNumber); - else - m_SerialCommunication->SetDeviceName(m_DeviceName); - - m_SerialCommunication->SetBaudRate(m_BaudRate); - m_SerialCommunication->SetDataBits(m_DataBits); - m_SerialCommunication->SetParity(m_Parity); - m_SerialCommunication->SetStopBits(m_StopBits); - m_SerialCommunication->SetSendTimeout(1000); - m_SerialCommunication->SetReceiveTimeout(1000); - if (m_SerialCommunication->OpenConnection() == 0) // 0 == ERROR_VALUE - { - m_SerialCommunication->CloseConnection(); - m_SerialCommunication = nullptr; - MITK_ERROR << "[Quantel Laser Debug] " << "Can not open serial port"; - return false; - } - - if (this->GetState() != UNCONNECTED) - { - std::string *command = new std::string; - std::string answer(""); - command->assign("STOP"); - this->SendAndReceiveLine(command, &answer); - return true; - } - else - return false; -} - -bool mitk::QuantelLaser::CloseConnection() -{ - if (this->GetState() != UNCONNECTED) - { - this->StopQswitching(); - this->StopFlashing(); - - // close the serial connection - m_SerialCommunication->CloseConnection(); - m_SerialCommunication = nullptr; - this->GetState(); - } - return true; -} - -mitk::QuantelLaser::LaserState mitk::QuantelLaser::GetState() -{ - if (m_SerialCommunication == nullptr) - { - m_State = UNCONNECTED; - return m_State; - } - - if (!m_SerialCommunication->IsConnected()) - { - m_State = UNCONNECTED; - return m_State; - } - - std::string *command = new std::string; - std::string answer(""); - command->assign("STATE"); - this->SendAndReceiveLine(command, &answer); - MITK_INFO << "[Quantel Laser Debug] get state:" << answer; - if (answer == "STATE = 0\n") - m_State = STATE0; - else if(answer == "STATE = 1\n") - { - m_State = STATE1; - m_FlashlampRunning = false; - m_ShutterOpen = false; - m_LaserEmission = false; - } - else if(answer == "STATE = 2\n") // laser ready for RUN - { - m_State = STATE2; - m_FlashlampRunning = false; - m_ShutterOpen = false; - m_LaserEmission = false; - } - else if(answer == "STATE = 3\n") - { - m_State = STATE3; - m_FlashlampRunning = true; - m_ShutterOpen = false; - m_LaserEmission = false; - } - else if(answer == "STATE = 4\n") - { - m_State = STATE4; - m_FlashlampRunning = true; - m_ShutterOpen = false; - m_LaserEmission = false; - } - else if (answer == "STATE = 5\n") - { - m_State = STATE5; - m_FlashlampRunning = true; - m_ShutterOpen = true; - m_LaserEmission = false; - } - else if (answer == "STATE = 6\n") - { - m_State = STATE6; - m_FlashlampRunning = true; - m_ShutterOpen = true; - m_LaserEmission = true; - } - else if (answer == "STATE = 7\n") - { - m_State = STATE7; - m_FlashlampRunning = true; - m_ShutterOpen = true; - m_LaserEmission = true; - } - else - { - m_State = UNCONNECTED; - m_FlashlampRunning = false; - m_ShutterOpen = false; - m_LaserEmission = false; - } - - return m_State; -} - - -void mitk::QuantelLaser::StayAlive() -{ - do{ - std::this_thread::sleep_for(std::chrono::seconds(2)); - std::string *command = new std::string; - std::string answer(""); - command->assign("STATE"); - this->SendAndReceiveLine(command, &answer); - } while (m_KeepAlive); -} - -bool mitk::QuantelLaser::StartFlashing() -{ - this->GetState(); - if (!m_FlashlampRunning) - { - if (m_LaserEmission) - this->StopQswitching(); - - std::string *command = new std::string; - std::string answer(""); - command->assign("RUN"); - this->SendAndReceiveLine(command, &answer); - MITK_INFO << answer; - if (answer.at(0) == 'O' && answer.at(1) == 'K') - { - m_FlashlampRunning = true; - m_ShutterOpen = false; - m_KeepAlive = true; - //m_StayAliveMessageThread = std::thread(&mitk::QuantelLaser::StayAlive, this); - } - else - { - MITK_ERROR << "[Quantel Laser Debug] " << "Cannot start flashlamps." << " Laser is telling me: " << answer; - return false; - } - } - else - MITK_INFO << "[Quantel Laser Debug] " << "Flashlamps are already running"; - - return true; -} - -bool mitk::QuantelLaser::StopFlashing() -{ - this->GetState(); - if (m_FlashlampRunning) - { - if (m_LaserEmission) - this->StopQswitching(); - - std::string *command = new std::string; - std::string answer(""); - command->assign("STOP"); - this->SendAndReceiveLine(command, &answer); - MITK_INFO << answer; - if (answer.at(0) == 'O' && answer.at(1) == 'K') - { - m_FlashlampRunning = false; - m_ShutterOpen = false; - m_KeepAlive = false; - } - else - { - MITK_ERROR << "[Quantel Laser Debug] " << "Cannot Stop flashlamps." << " Laser is telling me: " << answer; - return false; - } - - } - else - MITK_INFO << "[Quantel Laser Debug] " << "Flashlamps are not running"; - - return true; -} - -bool mitk::QuantelLaser::StartQswitching() -{ - this->GetState(); - if (!m_LaserEmission) - { - std::string *command = new std::string; - std::string answer(""); - command->assign("QSW 1"); - this->SendAndReceiveLine(command, &answer); - MITK_INFO << answer; - if (answer.at(0) == 'O' && answer.at(1) == 'K') - { - m_FlashlampRunning = true; - m_ShutterOpen = true; - return true; - } - else - { - MITK_ERROR << "[Quantel Laser Debug] " << "Cannot start Qswitch." << " Laser is telling me: " << answer; - return false; - } - } - else - { - MITK_INFO << "[Quantel Laser Debug] " << "Laser is already emitting"; - return true; - } -} - -bool mitk::QuantelLaser::StopQswitching() -{ - this->GetState(); - if (m_FlashlampRunning && m_LaserEmission) - { - std::string *command = new std::string; - std::string answer(""); - command->assign("QSW 0"); - this->SendAndReceiveLine(command, &answer); - MITK_INFO << answer; - if (answer.at(0) == 'O' && answer.at(1) == 'K') - { - m_LaserEmission = false; - } - else - MITK_ERROR << "[Quantel Laser Debug] " << "Cannot stop Q-switch."; - - } - return true; -} - -bool mitk::QuantelLaser::IsEmitting() -{ - return m_LaserEmission; -} -bool mitk::QuantelLaser::IsFlashing() -{ - return m_FlashlampRunning; -} diff --git a/Modules/PhotoacousticsHardware/mitkQuantelLaser.h b/Modules/PhotoacousticsHardware/mitkQuantelLaser.h deleted file mode 100644 index 761fcb66ee..0000000000 --- a/Modules/PhotoacousticsHardware/mitkQuantelLaser.h +++ /dev/null @@ -1,105 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef MITKQUANTELLASER_H_HEADER_INCLUDED -#define MITKQUANTELLASER_H_HEADER_INCLUDED - -#include "itkObject.h" -#include "mitkCommon.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "mitkSerialCommunication.h" -#include "MitkPhotoacousticsHardwareExports.h" - -namespace mitk { - - class MITKPHOTOACOUSTICSHARDWARE_EXPORT QuantelLaser : public itk::LightObject - { - public: - mitkClassMacroItkParent(QuantelLaser, itk::LightObject); - itkFactorylessNewMacro(Self); - - enum LaserState { UNCONNECTED, STATE0, STATE1, STATE2, STATE3, STATE4, STATE5, STATE6, STATE7 }; ///< Type for STATE variable. The LaserDevice is always in one of these states - /** - * \brief Opens a connection to the device - * - * This may only be called if there is currently no connection to the device. - * If OpenConnection() is successful, the object will change from UNCONNECTED state to a STATE state - */ - virtual bool OpenConnection(std::string configurationFile); - - /** - * \brief Closes the connection to the device - * - * This may only be called if there is currently a connection to the device. (e.g. object is in a STATE state) - */ - virtual bool CloseConnection(); ///< Closes the connection with the device - - virtual std::string SendAndReceiveLine(const std::string* input, std::string* answer); - - virtual void StayAlive(); - virtual bool StartFlashing(); - virtual bool StopFlashing(); - - virtual bool StartQswitching(); - virtual bool StopQswitching(); - virtual bool IsEmitting(); - virtual bool IsFlashing(); - - virtual LaserState GetState(); - - typedef mitk::SerialCommunication::PortNumber PortNumber; ///< Port number of the serial connection - typedef mitk::SerialCommunication::BaudRate BaudRate; ///< Baud rate of the serial connection - typedef mitk::SerialCommunication::DataBits DataBits; ///< Number of data bits used in the serial connection - typedef mitk::SerialCommunication::Parity Parity; ///< Parity mode used in the serial connection - typedef mitk::SerialCommunication::StopBits StopBits; ///< Number of stop bits used in the serial connection - typedef mitk::SerialCommunication::HardwareHandshake HardwareHandshake; ///< Hardware handshake mode of the serial connection - - private: - LaserState m_State; ///< current Laser state - protected: - - QuantelLaser(); - virtual ~QuantelLaser(); - - bool m_KeepAlive = false; - bool m_FlashlampRunning = false; - bool m_ShutterOpen = false; - bool m_LaserEmission = false; - void LoadResorceFile(std::string filename, std::string* lines); - - std::string m_DeviceName;///< Device Name - PortNumber m_PortNumber; ///< COM Port Number - BaudRate m_BaudRate; ///< COM Port Baud Rate - DataBits m_DataBits; ///< Number of Data Bits per token - Parity m_Parity; ///< Parity mode for communication - StopBits m_StopBits; ///< number of stop bits per token - HardwareHandshake m_HardwareHandshake; ///< use hardware handshake for serial port connection - - std::string m_XmlPumpLaserConfiguration; - mitk::SerialCommunication::Pointer m_SerialCommunication; ///< serial communication interface - std::thread m_StayAliveMessageThread; - std::mutex m_SerialCommunicationMutex; ///< mutex for coordinated access of serial communication interface - }; -} // namespace mitk - -#endif /* MITKQUANTELLASER_H_HEADER_INCLUDED */ diff --git a/Modules/PhotoacousticsLib/CMakeLists.txt b/Modules/PhotoacousticsLib/CMakeLists.txt deleted file mode 100644 index 881f0ffe29..0000000000 --- a/Modules/PhotoacousticsLib/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -MITK_CREATE_MODULE( - INCLUDE_DIRS PUBLIC include - INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} - DEPENDS PUBLIC MitkAlgorithmsExt - PACKAGE_DEPENDS - tinyxml2|tinyxml2 Vigra - PUBLIC ITK -) - -if(TARGET ${MODULE_TARGET}) - target_link_libraries(${MODULE_TARGET} - PRIVATE tinyxml2::tinyxml2 - ) -endif() - -add_subdirectory(MitkMCxyz) - -add_subdirectory(MitkTissueBatchGenerator) -add_subdirectory(MitkPAPhantomGenerator) -add_subdirectory(MitkSpectralUnmixing) - -add_subdirectory(test) diff --git a/Modules/PhotoacousticsLib/MitkMCxyz/CMakeLists.txt b/Modules/PhotoacousticsLib/MitkMCxyz/CMakeLists.txt deleted file mode 100644 index 8e528dc475..0000000000 --- a/Modules/PhotoacousticsLib/MitkMCxyz/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -OPTION(BUILD_PhotoacousticSimulationMCxyz "Build MiniApp for Photoacoustic Simulation Module (mcxyz)" OFF) - -IF(BUILD_PhotoacousticSimulationMCxyz) - PROJECT( MitkMCxyz ) - mitk_create_executable(MCxyz - DEPENDS MitkCommandLine MitkCore MitkPhotoacousticsLib - PACKAGE_DEPENDS - CPP_FILES MitkMCxyz.cpp) - - install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) - ENDIF() diff --git a/Modules/PhotoacousticsLib/MitkMCxyz/MitkMCxyz.cpp b/Modules/PhotoacousticsLib/MitkMCxyz/MitkMCxyz.cpp deleted file mode 100644 index 103c01275e..0000000000 --- a/Modules/PhotoacousticsLib/MitkMCxyz/MitkMCxyz.cpp +++ /dev/null @@ -1,1470 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -// Please retain the following copyright notice -/****************************************************************** - * based on mcxyz.c Oct2014 - * - * mcxyz.c, in ANSI Standard C programing language - * - * created 2010, 2012 by - * Steven L. JACQUES - * Ting LI - * Oregon Health & Science University - * - *******************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "mitkCommandLineParser.h" -#include "mitkIOUtil.h" -#include "mitkImageCast.h" -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef _WIN32 -#include -#else -#include -#include -#endif - -#define ls 1.0E-7 /* Moving photon a little bit off the voxel face */ -#define PI 3.1415926 -#define ALIVE 1 /* if photon not yet terminated */ -#define DEAD 0 /* if photon is to be terminated */ -#define THRESHOLD 0.01 /* used in roulette */ -#define CHANCE 0.1 /* used in roulette */ -#define SQR(x) (x*x) -#define SIGN(x) ((x)>=0 ? 1:-1) -#define ONE_MINUS_COSZERO 1.0E-12 /* If 1-cos(theta) <= ONE_MINUS_COSZERO, fabs(theta) <= 1e-6 rad. */ - /* If 1+cos(theta) <= ONE_MINUS_COSZERO, fabs(PI-theta) <= 1e-6 rad. */ - - /* Struct for storing x,y and z coordinates */ -struct Location -{ - int x, y, z; - double absorb; -}; - -struct Location initLocation(int x, int y, int z, double absorb) -{ - struct Location loc; - loc.x = x; - loc.y = y; - loc.z = z; - loc.absorb = absorb; - return loc; -} - -class DetectorVoxel -{ -public: - Location location; - std::vector* recordedPhotonRoute = new std::vector(); - double* fluenceContribution; - double m_PhotonNormalizationValue; - long m_NumberPhotonsCurrent; - - DetectorVoxel(Location location, long totalNumberOfVoxels, double photonNormalizationValue) - { - this->location = location; - this->fluenceContribution = (double *)malloc(totalNumberOfVoxels * sizeof(double)); - for (int j = 0; j < totalNumberOfVoxels; j++) fluenceContribution[j] = 0; // ensure fluenceContribution[] starts empty. - m_NumberPhotonsCurrent = 0; - m_PhotonNormalizationValue = photonNormalizationValue; - } -}; - -bool verbose(false); - -class InputValues -{ -private: - std::string inputFilename; - int tissueIterator; - long long ix, iy, iz; -public: - int mcflag, launchflag, boundaryflag; - double xfocus, yfocus, zfocus; - double ux0, uy0, uz0; - double radius; - double waist; - double xs, ys, zs; /* launch position */ - int Nx, Ny, Nz, numberOfTissueTypes; /* # of bins */ - - char* tissueType; - double* muaVector; - double* musVector; - double* gVector; - double* normalizationVector; - - double xSpacing, ySpacing, zSpacing; - double simulationTimeFromFile; - long long Nphotons; - long totalNumberOfVoxels; - double* totalFluence; - std::string myname; - DetectorVoxel* detectorVoxel; - mitk::Image::Pointer m_inputImage; - mitk::Image::Pointer m_normalizationImage; - - InputValues() - { - tissueType = nullptr; - muaVector = nullptr; - musVector = nullptr; - gVector = nullptr; - detectorVoxel = nullptr; - normalizationVector = nullptr; - - mcflag = 0; - launchflag = 0; - boundaryflag = 0; - } - - double GetNormalizationValue(int x, int y, int z) - { - if (normalizationVector) - return normalizationVector[z*Ny*Nx + x*Ny + y]; - else - return 1; - } - - void LoadValues(std::string localInputFilename, float yOffset, std::string normalizationFilename, bool simulatePVFC) - { - inputFilename = localInputFilename; - try - { - if (verbose) std::cout << "Loading input image..." << std::endl; - m_inputImage = mitk::IOUtil::Load(inputFilename); - if (verbose) std::cout << "Loading input image... [Done]" << std::endl; - } - catch (...) - { - if (verbose) std::cout << "No .nrrd file found ... switching to legacy mode." << std::endl; - } - - try - { - if (simulatePVFC && !normalizationFilename.empty()) - m_normalizationImage = mitk::IOUtil::Load(normalizationFilename); - } - catch (...) - { - if (verbose) std::cout << "No normalization .nrrd file found ... will not normalize PVFC" << std::endl; - } - - if (m_normalizationImage.IsNotNull()) - { - mitk::ImageReadAccessor readAccess3(m_normalizationImage, m_normalizationImage->GetVolumeData(0)); - normalizationVector = (double *)readAccess3.GetData(); - } - - if (m_inputImage.IsNotNull()) // load stuff from nrrd file - { - simulationTimeFromFile = 0; - - Nx = m_inputImage->GetDimensions()[1]; - Ny = m_inputImage->GetDimensions()[0]; - Nz = m_inputImage->GetDimensions()[2]; - - xSpacing = m_inputImage->GetGeometry(0)->GetSpacing()[0]; - ySpacing = m_inputImage->GetGeometry(0)->GetSpacing()[1]; - zSpacing = m_inputImage->GetGeometry(0)->GetSpacing()[2]; - - mcflag = std::stoi(m_inputImage->GetProperty("mcflag")->GetValueAsString().c_str()); // mcflag, 0 = uniform, 1 = Gaussian, 2 = iso-pt, 4 = monospectral fraunhofer setup - launchflag = std::stoi(m_inputImage->GetProperty("launchflag")->GetValueAsString().c_str());// 0 = let mcxyz calculate trajectory, 1 = manually set launch vector - boundaryflag = std::stoi(m_inputImage->GetProperty("boundaryflag")->GetValueAsString().c_str());// 0 = no boundaries, 1 = escape at boundaries, 2 = escape at surface only - - xs = std::stod(m_inputImage->GetProperty("launchPointX")->GetValueAsString().c_str()); - ys = std::stod(m_inputImage->GetProperty("launchPointY")->GetValueAsString().c_str()) + yOffset; - zs = std::stod(m_inputImage->GetProperty("launchPointZ")->GetValueAsString().c_str()); - - xfocus = std::stod(m_inputImage->GetProperty("focusPointX")->GetValueAsString().c_str()); - yfocus = std::stod(m_inputImage->GetProperty("focusPointY")->GetValueAsString().c_str()); - zfocus = std::stod(m_inputImage->GetProperty("focusPointZ")->GetValueAsString().c_str()); - - ux0 = std::stod(m_inputImage->GetProperty("trajectoryVectorX")->GetValueAsString().c_str()); - uy0 = std::stod(m_inputImage->GetProperty("trajectoryVectorY")->GetValueAsString().c_str()); - uz0 = std::stod(m_inputImage->GetProperty("trajectoryVectorZ")->GetValueAsString().c_str()); - - radius = std::stod(m_inputImage->GetProperty("radius")->GetValueAsString().c_str()); - waist = std::stod(m_inputImage->GetProperty("waist")->GetValueAsString().c_str()); - - totalNumberOfVoxels = Nx*Ny*Nz; - if (verbose) std::cout << totalNumberOfVoxels << " = sizeof totalNumberOfVoxels" << std::endl; - - muaVector = (double *)malloc(totalNumberOfVoxels * sizeof(double)); /* tissue structure */ - musVector = (double *)malloc(totalNumberOfVoxels * sizeof(double)); /* tissue structure */ - gVector = (double *)malloc(totalNumberOfVoxels * sizeof(double)); /* tissue structure */ - - mitk::ImageReadAccessor readAccess0(m_inputImage, m_inputImage->GetVolumeData(0)); - muaVector = (double *)readAccess0.GetData(); - mitk::ImageReadAccessor readAccess1(m_inputImage, m_inputImage->GetVolumeData(1)); - musVector = (double *)readAccess1.GetData(); - mitk::ImageReadAccessor readAccess2(m_inputImage, m_inputImage->GetVolumeData(2)); - gVector = (double *)readAccess2.GetData(); - } - else - { - mitkThrow() << "No longer support loading of binary tissue files."; - } - } -}; - -class ReturnValues -{ -private: - long i1 = 0, i2 = 31; // used Random Generator - long ma[56]; // used Random Generator /* ma[0] is not used. */ - long mj, mk; - short i, ii; -public: - long long Nphotons; - double* totalFluence; - std::string myname; - DetectorVoxel* detectorVoxel; - - ReturnValues() - { - detectorVoxel = nullptr; - Nphotons = 0; - totalFluence = nullptr; - } - - /* SUBROUTINES */ - - /************************************************************************** - * RandomGen - * A random number generator that generates uniformly - * distributed random numbers between 0 and 1 inclusive. - * The algorithm is based on: - * W.H. Press, S.A. Teukolsky, W.T. Vetterling, and B.P. - * Flannery, "Numerical Recipes in C," Cambridge University - * Press, 2nd edition, (1992). - * and - * D.E. Knuth, "Seminumerical Algorithms," 2nd edition, vol. 2 - * of "The Art of Computer Programming", Addison-Wesley, (1981). - * - * When Type is 0, sets Seed as the seed. Make sure 0 b) - m = a; - else - m = b; - return m; - } - - /*********************************************************** - * min2 - ****/ - double min2(double a, double b) { - double m; - if (a >= b) - m = b; - else - m = a; - return m; - } - /*********************************************************** - * min3 - ****/ - double min3(double a, double b, double c) { - double m; - if (a <= min2(b, c)) - m = a; - else if (b <= min2(a, c)) - m = b; - else - m = c; - return m; - } - - /******************** - * my version of FindVoxelFace for no scattering. - * s = ls + FindVoxelFace2(x,y,z, tempx, tempy, tempz, dx, dy, dz, ux, uy, uz); - ****/ - double FindVoxelFace2(double x1, double y1, double z1, double /*x2*/, double /*y2*/, double /*z2*/, double dx, double dy, double dz, double ux, double uy, double uz) - { - int ix1 = floor(x1 / dx); - int iy1 = floor(y1 / dy); - int iz1 = floor(z1 / dz); - - int ix2, iy2, iz2; - if (ux >= 0) - ix2 = ix1 + 1; - else - ix2 = ix1; - - if (uy >= 0) - iy2 = iy1 + 1; - else - iy2 = iy1; - - if (uz >= 0) - iz2 = iz1 + 1; - else - iz2 = iz1; - - double xs = fabs((ix2*dx - x1) / ux); - double ys = fabs((iy2*dy - y1) / uy); - double zs = fabs((iz2*dz - z1) / uz); - - double s = min3(xs, ys, zs); - - return s; - } - - /*********************************************************** - * FRESNEL REFLECTANCE - * Computes reflectance as photon passes from medium 1 to - * medium 2 with refractive indices n1,n2. Incident - * angle a1 is specified by cosine value ca1 = cos(a1). - * Program returns value of transmitted angle a1 as - * value in *ca2_Ptr = cos(a2). - ****/ - double RFresnel(double n1, /* incident refractive index.*/ - double n2, /* transmit refractive index.*/ - double ca1, /* cosine of the incident */ - /* angle a1, 00. */ - { - double r; - - if (n1 == n2) { /** matched boundary. **/ - *ca2_Ptr = ca1; - r = 0.0; - } - else if (ca1 > (1.0 - 1.0e-12)) { /** normal incidence. **/ - *ca2_Ptr = ca1; - r = (n2 - n1) / (n2 + n1); - r *= r; - } - else if (ca1 < 1.0e-6) { /** very slanted. **/ - *ca2_Ptr = 0.0; - r = 1.0; - } - else { /** general. **/ - double sa1, sa2; /* sine of incident and transmission angles. */ - double ca2; /* cosine of transmission angle. */ - sa1 = sqrt(1 - ca1*ca1); - sa2 = n1*sa1 / n2; - if (sa2 >= 1.0) { - /* double check for total internal reflection. */ - *ca2_Ptr = 0.0; - r = 1.0; - } - else { - double cap, cam; /* cosines of sum ap or diff am of the two */ - /* angles: ap = a1 + a2, am = a1 - a2. */ - double sap, sam; /* sines. */ - *ca2_Ptr = ca2 = sqrt(1 - sa2*sa2); - cap = ca1*ca2 - sa1*sa2; /* c+ = cc - ss. */ - cam = ca1*ca2 + sa1*sa2; /* c- = cc + ss. */ - sap = sa1*ca2 + ca1*sa2; /* s+ = sc + cs. */ - sam = sa1*ca2 - ca1*sa2; /* s- = sc - cs. */ - r = 0.5*sam*sam*(cam*cam + cap*cap) / (sap*sap*cam*cam); - /* rearranged for speed. */ - } - } - return(r); - } /******** END SUBROUTINE **********/ - - /*********************************************************** - * the boundary is the face of some voxel - * find the the photon's hitting position on the nearest face of the voxel and update the step size. - ****/ - double FindVoxelFace(double x1, double y1, double z1, double x2, double y2, double z2, double dx, double dy, double dz, double ux, double uy, double uz) - { - double x_1 = x1 / dx; - double y_1 = y1 / dy; - double z_1 = z1 / dz; - double x_2 = x2 / dx; - double y_2 = y2 / dy; - double z_2 = z2 / dz; - double fx_1 = floor(x_1); - double fy_1 = floor(y_1); - double fz_1 = floor(z_1); - double fx_2 = floor(x_2); - double fy_2 = floor(y_2); - double fz_2 = floor(z_2); - double x = 0, y = 0, z = 0, x0 = 0, y0 = 0, z0 = 0, s = 0; - - if ((fx_1 != fx_2) && (fy_1 != fy_2) && (fz_1 != fz_2)) { //#10 - fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added - fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added - fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added - - x = (max2(fx_1, fx_2) - x_1) / ux; - y = (max2(fy_1, fy_2) - y_1) / uy; - z = (max2(fz_1, fz_2) - z_1) / uz; - if (x == min3(x, y, z)) { - x0 = max2(fx_1, fx_2); - y0 = (x0 - x_1) / ux*uy + y_1; - z0 = (x0 - x_1) / ux*uz + z_1; - } - else if (y == min3(x, y, z)) { - y0 = max2(fy_1, fy_2); - x0 = (y0 - y_1) / uy*ux + x_1; - z0 = (y0 - y_1) / uy*uz + z_1; - } - else { - z0 = max2(fz_1, fz_2); - y0 = (z0 - z_1) / uz*uy + y_1; - x0 = (z0 - z_1) / uz*ux + x_1; - } - } - else if ((fx_1 != fx_2) && (fy_1 != fy_2)) { //#2 - fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added - fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added - x = (max2(fx_1, fx_2) - x_1) / ux; - y = (max2(fy_1, fy_2) - y_1) / uy; - if (x == min2(x, y)) { - x0 = max2(fx_1, fx_2); - y0 = (x0 - x_1) / ux*uy + y_1; - z0 = (x0 - x_1) / ux*uz + z_1; - } - else { - y0 = max2(fy_1, fy_2); - x0 = (y0 - y_1) / uy*ux + x_1; - z0 = (y0 - y_1) / uy*uz + z_1; - } - } - else if ((fy_1 != fy_2) && (fz_1 != fz_2)) { //#3 - fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added - fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added - y = (max2(fy_1, fy_2) - y_1) / uy; - z = (max2(fz_1, fz_2) - z_1) / uz; - if (y == min2(y, z)) { - y0 = max2(fy_1, fy_2); - x0 = (y0 - y_1) / uy*ux + x_1; - z0 = (y0 - y_1) / uy*uz + z_1; - } - else { - z0 = max2(fz_1, fz_2); - x0 = (z0 - z_1) / uz*ux + x_1; - y0 = (z0 - z_1) / uz*uy + y_1; - } - } - else if ((fx_1 != fx_2) && (fz_1 != fz_2)) { //#4 - fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added - fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added - x = (max2(fx_1, fx_2) - x_1) / ux; - z = (max2(fz_1, fz_2) - z_1) / uz; - if (x == min2(x, z)) { - x0 = max2(fx_1, fx_2); - y0 = (x0 - x_1) / ux*uy + y_1; - z0 = (x0 - x_1) / ux*uz + z_1; - } - else { - z0 = max2(fz_1, fz_2); - x0 = (z0 - z_1) / uz*ux + x_1; - y0 = (z0 - z_1) / uz*uy + y_1; - } - } - else if (fx_1 != fx_2) { //#5 - fx_2 = fx_1 + SIGN(fx_2 - fx_1);//added - x0 = max2(fx_1, fx_2); - y0 = (x0 - x_1) / ux*uy + y_1; - z0 = (x0 - x_1) / ux*uz + z_1; - } - else if (fy_1 != fy_2) { //#6 - fy_2 = fy_1 + SIGN(fy_2 - fy_1);//added - y0 = max2(fy_1, fy_2); - x0 = (y0 - y_1) / uy*ux + x_1; - z0 = (y0 - y_1) / uy*uz + z_1; - } - else { //#7 - z0 = max2(fz_1, fz_2); - fz_2 = fz_1 + SIGN(fz_2 - fz_1);//added - x0 = (z0 - z_1) / uz*ux + x_1; - y0 = (z0 - z_1) / uz*uy + y_1; - } - //s = ( (x0-fx_1)*dx + (y0-fy_1)*dy + (z0-fz_1)*dz )/3; - //s = sqrt( SQR((x0-x_1)*dx) + SQR((y0-y_1)*dy) + SQR((z0-z_1)*dz) ); - //s = sqrt(SQR(x0-x_1)*SQR(dx) + SQR(y0-y_1)*SQR(dy) + SQR(z0-z_1)*SQR(dz)); - s = sqrt(SQR((x0 - x_1)*dx) + SQR((y0 - y_1)*dy) + SQR((z0 - z_1)*dz)); - return (s); - } -}; - -/* DECLARE FUNCTIONS */ - -void runMonteCarlo(InputValues* inputValues, ReturnValues* returnValue, int thread, mitk::pa::MonteCarloThreadHandler::Pointer threadHandler); - -int detector_x = -1; -int detector_z = -1; -bool interpretAsTime = true; -bool simulatePVFC = false; -int requestedNumberOfPhotons = 100000; -float requestedSimulationTime = 0; // in minutes -int concurentThreadsSupported = -1; -float yOffset = 0; // in mm -bool saveLegacy = false; -std::string normalizationFilename; -std::string inputFilename; -std::string outputFilename; - -mitk::pa::Probe::Pointer m_PhotoacousticProbe; - -int main(int argc, char * argv[]) { - mitkCommandLineParser parser; - // set general information - parser.setCategory("MITK-Photoacoustics"); - parser.setTitle("Mitk MCxyz"); - parser.setDescription("Runs Monte Carlo simulations on inputed tissues."); - parser.setContributor("CAI, DKFZ based on code by Jacques and Li"); - - // how should arguments be prefixed - parser.setArgumentPrefix("--", "-"); - // add each argument, unless specified otherwise each argument is optional - // see mitkCommandLineParser::addArgument for more information - parser.beginGroup("Required I/O parameters"); - parser.addArgument( - "input", "i", mitkCommandLineParser::File, - "Input tissue file", "input tissue file (*.nrrd)", - us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "output", "o", mitkCommandLineParser::File, - "Output fluence file", "where to save the simulated fluence (*.nrrd)", - us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.endGroup(); - parser.beginGroup("Optional parameters"); - parser.addArgument( - "verbose", "v", mitkCommandLineParser::Bool, - "Verbose Output", "Whether to produce verbose, or rather debug output"); - parser.addArgument( - "detector-x", "dx", mitkCommandLineParser::Int, - "Detector voxel x position", "Determines the x position of the detector voxel (default: -1 = dont use detector voxel)", -1); - parser.addArgument( - "detector-z", "dz", mitkCommandLineParser::Int, - "Detector voxel z position", "Determines the z position of the detector voxel (default: -1 = dont use detector voxel)", -1); - parser.addArgument( - "number-of-photons", "n", mitkCommandLineParser::Int, - "Number of photons", "Specifies the number of photons (default: 100000). Simulation stops after that number. Use -t --timer to define a timer instead"); - parser.addArgument( - "timer", "t", mitkCommandLineParser::Float, - "Simulation time in min", "Specifies the amount of time for simutation (default: 0). Simulation stops after that number of minutes. -n --number-of-photons is the override and default behavior and defines the maximum number of photons instead. If no simulation time or number of photons is specified the file time is taken."); - parser.addArgument( - "y-offset", "yo", mitkCommandLineParser::Float, - "Probe Y-Offset in mm", "Specifies an offset of the photoacoustic probe in the y direction depending on the initial probe position (default: 0) in mm."); - parser.addArgument( - "jobs", "j", mitkCommandLineParser::Int, - "Number of jobs", "Specifies the number of jobs for simutation (default: -1 which starts as many jobs as supported)."); - parser.addArgument( - "probe-xml", "p", mitkCommandLineParser::File, - "Xml definition of the probe", "Specifies the absolute path of the location of the xml definition file of the probe design.", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.addArgument("normalization-file", "nf", mitkCommandLineParser::File, - "Input normalization file", "The input normalization file is used for normalization of the number of photons in the PVFC calculations.", us::Any(), true, false, false, mitkCommandLineParser::Input); - parser.endGroup(); - - // parse arguments, this method returns a mapping of long argument names and their values - std::map parsedArgs = parser.parseArguments(argc, argv); - if (parsedArgs.size() == 0) - return EXIT_FAILURE; - // parse, cast and set required arguments - inputFilename = us::any_cast(parsedArgs["input"]); - // strip ending - inputFilename = inputFilename.substr(0, inputFilename.find("_H.mci")); - inputFilename = inputFilename.substr(0, inputFilename.find("_T.bin")); - - outputFilename = us::any_cast(parsedArgs["output"]); - // add .nrrd if not there - std::string suffix = ".nrrd"; - if (outputFilename.compare(outputFilename.size() - suffix.size(), suffix.size(), suffix) != 0) - outputFilename = outputFilename + suffix; - - // default values for optional arguments - // parse, cast and set optional arguments if given - if (parsedArgs.count("verbose")) - { - verbose = us::any_cast(parsedArgs["verbose"]); - } - if (parsedArgs.count("detector-x")) - { - detector_x = us::any_cast(parsedArgs["detector-x"]); - } - if (parsedArgs.count("detector-z")) - { - detector_z = us::any_cast(parsedArgs["detector-z"]); - } - if (parsedArgs.count("timer")) - { - requestedSimulationTime = us::any_cast(parsedArgs["timer"]); - if (requestedSimulationTime > 0) interpretAsTime = true; - } - if (parsedArgs.count("y-offset")) - { - yOffset = us::any_cast(parsedArgs["y-offset"]); - } - if (parsedArgs.count("number-of-photons")) - { - requestedNumberOfPhotons = us::any_cast(parsedArgs["number-of-photons"]); - if (requestedNumberOfPhotons > 0) interpretAsTime = false; - } - if (parsedArgs.count("jobs")) - { - concurentThreadsSupported = us::any_cast(parsedArgs["jobs"]); - } - if (parsedArgs.count("probe-xml")) - { - std::string inputXmlProbeDesign = us::any_cast(parsedArgs["probe-xml"]); - m_PhotoacousticProbe = mitk::pa::Probe::New(inputXmlProbeDesign, verbose); - if (!m_PhotoacousticProbe->IsValid()) - { - std::cerr << "Xml File was not valid. Simulation failed." << std::endl; - return EXIT_FAILURE; - } - } - if (parsedArgs.count("normalization-file")) - { - normalizationFilename = us::any_cast(parsedArgs["normalization-file"]); - } - - if (concurentThreadsSupported == 0 || concurentThreadsSupported == -1) - { - concurentThreadsSupported = std::thread::hardware_concurrency(); - if (concurentThreadsSupported == 0) - { - std::cout << "Could not determine number of available threads. Launching only one." << std::endl; - concurentThreadsSupported = 1; - } - } - - if (detector_x != -1 && detector_z != -1) - { - if (verbose) - std::cout << "Performing PVFC calculation for x=" << detector_x << " and z=" << detector_z << std::endl; - simulatePVFC = true; - } - else - { - if (verbose) - std::cout << "Will not perform PVFC calculation due to x=" << detector_x << " and/or z=" << detector_z << std::endl; - } - - InputValues allInput = InputValues(); - allInput.LoadValues(inputFilename, yOffset, normalizationFilename, simulatePVFC); - - std::vector allValues(concurentThreadsSupported); - auto* threads = new std::thread[concurentThreadsSupported]; - - for (long i = 0; i < concurentThreadsSupported; i++) - { - auto* tmp = new ReturnValues(); - allValues.push_back(*tmp); - } - - if (verbose) std::cout << "Initializing MonteCarloThreadHandler" << std::endl; - - long timeMetric; - if (interpretAsTime) - { - if (requestedSimulationTime < mitk::eps) - requestedSimulationTime = allInput.simulationTimeFromFile; - - timeMetric = requestedSimulationTime * 60 * 1000; - } - else - { - timeMetric = requestedNumberOfPhotons; - } - - mitk::pa::MonteCarloThreadHandler::Pointer threadHandler = mitk::pa::MonteCarloThreadHandler::New(timeMetric, interpretAsTime); - - if (simulatePVFC) - threadHandler->SetPackageSize(1000); - - if (verbose) std::cout << "\nStarting simulation ...\n" << std::endl; - - auto simulationStartTime = std::chrono::system_clock::now(); - - for (int i = 0; i < concurentThreadsSupported; i++) - { - threads[i] = std::thread(runMonteCarlo, &allInput, &allValues[i], (i + 1), threadHandler); - } - - for (int i = 0; i < concurentThreadsSupported; i++) - { - threads[i].join(); - } - - auto simulationFinishTime = std::chrono::system_clock::now(); - auto simulationTimeElapsed = simulationFinishTime - simulationStartTime; - - if (verbose) std::cout << "\n\nFinished simulation\n\n" << std::endl; - std::cout << "total time for simulation: " - << (int)std::chrono::duration_cast(simulationTimeElapsed).count() << "sec " << std::endl; - - /**** SAVE - Convert data to relative fluence rate [cm^-2] and save. - *****/ - - if (!simulatePVFC) - { - if (verbose) std::cout << "Allocating memory for normal simulation result ... "; - auto* finalTotalFluence = (double *)malloc(allInput.totalNumberOfVoxels * sizeof(double)); - if (verbose) std::cout << "[OK]" << std::endl; - if (verbose) std::cout << "Cleaning memory for normal simulation result ..."; - for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { - finalTotalFluence[i] = 0; - } - if (verbose) std::cout << "[OK]" << std::endl; - - if (verbose) std::cout << "Calculating resulting fluence ... "; - double tdx = 0, tdy = 0, tdz = 0; - long long tNphotons = 0; - for (int t = 0; t < concurentThreadsSupported; t++) - { - tdx = allInput.xSpacing; - tdy = allInput.ySpacing; - tdz = allInput.zSpacing; - tNphotons += allValues[t].Nphotons; - for (int voxelNumber = 0; voxelNumber < allInput.totalNumberOfVoxels; voxelNumber++) { - finalTotalFluence[voxelNumber] += allValues[t].totalFluence[voxelNumber]; - } - } - if (verbose) std::cout << "[OK]" << std::endl; - std::cout << "total number of photons simulated: " - << tNphotons << std::endl; - - // Normalize deposition (A) to yield fluence rate (F). - double temp = tdx*tdy*tdz*tNphotons; - for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { - finalTotalFluence[i] /= temp*allInput.muaVector[i]; - } - - if (verbose) std::cout << "Saving normal simulated fluence result to " << outputFilename << " ... "; - - mitk::Image::Pointer resultImage = mitk::Image::New(); - mitk::PixelType TPixel = mitk::MakeScalarPixelType(); - auto* dimensionsOfImage = new unsigned int[3]; - - // Copy dimensions - dimensionsOfImage[0] = allInput.Ny; - dimensionsOfImage[1] = allInput.Nx; - dimensionsOfImage[2] = allInput.Nz; - - resultImage->Initialize(TPixel, 3, dimensionsOfImage); - - mitk::Vector3D spacing; - spacing[0] = allInput.ySpacing; - spacing[1] = allInput.xSpacing; - spacing[2] = allInput.zSpacing; - resultImage->SetSpacing(spacing); - resultImage->SetImportVolume(finalTotalFluence, 0, 0, mitk::Image::CopyMemory); - - resultImage->GetPropertyList()->SetFloatProperty("y-offset", yOffset); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("y-offset")); - - mitk::IOUtil::Save(resultImage, outputFilename); - - if (verbose) std::cout << "[OK]" << std::endl; - - if (verbose) - { - std::cout << "x spacing = " << tdx << std::endl; - std::cout << "y spacing = " << tdy << std::endl; - std::cout << "z spacing = " << tdz << std::endl; - std::cout << "total number of voxels = " << allInput.totalNumberOfVoxels << std::endl; - std::cout << "number of photons = " << (int)tNphotons << std::endl; - } - } - else // if simulate PVFC - { - if (verbose) std::cout << "Allocating memory for PVFC simulation result ... "; - double* detectorFluence = ((double*)malloc(allInput.totalNumberOfVoxels * sizeof(double))); - if (verbose) std::cout << "[OK]" << std::endl; - if (verbose) std::cout << "Cleaning memory for PVFC simulation result ..."; - for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { - detectorFluence[i] = 0; - } - if (verbose) std::cout << "[OK]" << std::endl; - - if (verbose) std::cout << "Calculating resulting PVFC fluence ... "; - double tdx = 0, tdy = 0, tdz = 0; - long long tNphotons = 0; - long pvfcPhotons = 0; - for (int t = 0; t < concurentThreadsSupported; t++) - { - tdx = allInput.xSpacing; - tdy = allInput.ySpacing; - tdz = allInput.zSpacing; - tNphotons += allValues[t].Nphotons; - pvfcPhotons += allValues[t].detectorVoxel->m_NumberPhotonsCurrent; - for (int voxelNumber = 0; voxelNumber < allInput.totalNumberOfVoxels; voxelNumber++) { - detectorFluence[voxelNumber] += - allValues[t].detectorVoxel->fluenceContribution[voxelNumber]; - } - } - if (verbose) std::cout << "[OK]" << std::endl; - std::cout << "total number of photons simulated: " - << tNphotons << std::endl; - - // Normalize deposition (A) to yield fluence rate (F). - double temp = tdx*tdy*tdz*tNphotons; - for (int i = 0; i < allInput.totalNumberOfVoxels; i++) { - detectorFluence[i] /= temp*allInput.muaVector[i]; - } - - if (verbose) std::cout << "Saving PVFC ..."; - - std::stringstream detectorname(""); - double detectorX = allValues[0].detectorVoxel->location.x; - double detectorY = allValues[0].detectorVoxel->location.y; - double detectorZ = allValues[0].detectorVoxel->location.z; - detectorname << detectorX << "," << detectorY << "," - << detectorZ << "FluenceContribution.nrrd"; - // Save the binary file - std::string outputFileBase = outputFilename.substr(0, outputFilename.find(".nrrd")); - outputFilename = outputFileBase + "_p" + detectorname.str().c_str(); - - mitk::Image::Pointer pvfcImage = mitk::Image::New(); - auto* dimensionsOfPvfcImage = new unsigned int[3]; - - // Copy dimensions - dimensionsOfPvfcImage[0] = allInput.Ny; - dimensionsOfPvfcImage[1] = allInput.Nx; - dimensionsOfPvfcImage[2] = allInput.Nz; - - pvfcImage->Initialize(mitk::MakeScalarPixelType(), 3, dimensionsOfPvfcImage); - - mitk::Vector3D pvfcSpacing; - pvfcSpacing[0] = allInput.ySpacing; - pvfcSpacing[1] = allInput.xSpacing; - pvfcSpacing[2] = allInput.zSpacing; - pvfcImage->SetSpacing(pvfcSpacing); - pvfcImage->SetImportVolume(detectorFluence, 0, 0, mitk::Image::CopyMemory); - - pvfcImage->GetPropertyList()->SetFloatProperty("detector-x", detectorX); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("detector-x")); - pvfcImage->GetPropertyList()->SetFloatProperty("detector-y", detectorY); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("detector-y")); - pvfcImage->GetPropertyList()->SetFloatProperty("detector-z", detectorZ); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("detector-z")); - pvfcImage->GetPropertyList()->SetFloatProperty("normalization-factor", allValues[0].detectorVoxel->m_PhotonNormalizationValue); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("normalization-factor")); - pvfcImage->GetPropertyList()->SetFloatProperty("simulated-photons", pvfcPhotons); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("simulated-photons")); - - mitk::IOUtil::Save(pvfcImage, outputFilename); - - if (verbose) std::cout << "[OK]" << std::endl; - - if (verbose) - { - std::cout << "x spacing = " << tdx << std::endl; - std::cout << "y spacing = " << tdy << std::endl; - std::cout << "z spacing = " << tdz << std::endl; - std::cout << "total number of voxels = " << allInput.totalNumberOfVoxels << std::endl; - std::cout << "number of photons = " << (int)tNphotons << std::endl; - } - } - - exit(EXIT_SUCCESS); -} /* end of main */ - -/* CORE FUNCTION */ -void runMonteCarlo(InputValues* inputValues, ReturnValues* returnValue, int thread, mitk::pa::MonteCarloThreadHandler::Pointer threadHandler) -{ - if (verbose) std::cout << "Thread " << thread << ": Locking Mutex ..." << std::endl; - if (verbose) std::cout << "[OK]" << std::endl; - if (verbose) std::cout << "Initializing ... "; - - /* Propagation parameters */ - double x, y, z; /* photon position */ - double ux, uy, uz; /* photon trajectory as cosines */ - double uxx, uyy, uzz; /* temporary values used during SPIN */ - double s; /* step sizes. s = -log(RND)/mus [cm] */ - double sleft; /* dimensionless */ - double costheta; /* cos(theta) */ - double sintheta; /* sin(theta) */ - double cospsi; /* cos(psi) */ - double sinpsi; /* sin(psi) */ - double psi; /* azimuthal angle */ - long photonIterator = 0; /* current photon */ - double W; /* photon weight */ - double absorb; /* weighted deposited in a step due to absorption */ - short photon_status; /* flag = ALIVE=1 or DEAD=0 */ - bool sv; /* Are they in the same voxel? */ - - /* dummy variables */ - double rnd; /* assigned random value 0-1 */ - double r, phi; /* dummy values */ - long i, j; /* dummy indices */ - double tempx, tempy, tempz; /* temporary variables, used during photon step. */ - int ix, iy, iz; /* Added. Used to track photons */ - double temp; /* dummy variable */ - int bflag; /* boundary flag: 0 = photon inside volume. 1 = outside volume */ - int CNT = 0; - - returnValue->totalFluence = (double *)malloc(inputValues->totalNumberOfVoxels * sizeof(double)); /* relative fluence rate [W/cm^2/W.delivered] */ - - if (detector_x != -1 && detector_z != -1) - { - if (detector_x<0 || detector_x>inputValues->Nx) - { - std::cout << "Requested detector x position not valid. Needs to be >= 0 and <= " << inputValues->Nx << std::endl; - exit(EXIT_FAILURE); - } - if (detector_z<1 || detector_z>inputValues->Nz) - { - std::cout << "Requested detector z position not valid. Needs to be > 0 and <= " << inputValues->Nz << std::endl; - exit(EXIT_FAILURE); - } - - double photonNormalizationValue = 1 / inputValues->GetNormalizationValue(detector_x, inputValues->Ny / 2, detector_z); - returnValue->detectorVoxel = new DetectorVoxel(initLocation(detector_x, inputValues->Ny / 2, detector_z, 0), inputValues->totalNumberOfVoxels, photonNormalizationValue); - } - - /**** ======================== MAJOR CYCLE ============================ *****/ - - auto duration = std::chrono::system_clock::now().time_since_epoch(); - returnValue->RandomGen(0, (std::chrono::duration_cast(duration).count() + thread) % 32000, nullptr); /* initiate with seed = 1, or any long integer. */ - for (j = 0; j < inputValues->totalNumberOfVoxels; j++) returnValue->totalFluence[j] = 0; // ensure F[] starts empty. - - /**** RUN Launch N photons, initializing each one before progation. *****/ - - long photonsToSimulate = 0; - - do { - photonsToSimulate = threadHandler->GetNextWorkPackage(); - if (returnValue->detectorVoxel != nullptr) - { - photonsToSimulate = photonsToSimulate * returnValue->detectorVoxel->m_PhotonNormalizationValue; - } - - if (verbose) - MITK_INFO << "Photons to simulate: " << photonsToSimulate; - - photonIterator = 0L; - - do { - /**** LAUNCH Initialize photon position and trajectory. *****/ - - photonIterator += 1; /* increment photon count */ - W = 1.0; /* set photon weight to one */ - photon_status = ALIVE; /* Launch an ALIVE photon */ - CNT = 0; - - /**** SET SOURCE* Launch collimated beam at x,y center.****/ - /****************************/ - /* Initial position. */ - - if (m_PhotoacousticProbe.IsNotNull()) - { - double rnd1 = -1; - double rnd2 = -1; - double rnd3 = -1; - double rnd4 = -1; - double rnd5 = -1; - double rnd6 = -1; - double rnd7 = -1; - double rnd8 = -1; - - while ((rnd1 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - while ((rnd2 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - while ((rnd3 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - while ((rnd4 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - while ((rnd5 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - while ((rnd6 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - while ((rnd7 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - while ((rnd8 = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - - mitk::pa::LightSource::PhotonInformation info = m_PhotoacousticProbe->GetNextPhoton(rnd1, rnd2, rnd3, rnd4, rnd5, rnd6, rnd7, rnd8); - x = info.xPosition; - y = yOffset + info.yPosition; - z = info.zPosition; - ux = info.xAngle; - uy = info.yAngle; - uz = info.zAngle; - if (verbose) - std::cout << "Created photon at position (" << x << "|" << y << "|" << z << ") with angles (" << ux << "|" << uy << "|" << uz << ")." << std::endl; - } - else - { - /* trajectory */ - if (inputValues->launchflag == 1) // manually set launch - { - x = inputValues->xs; - y = inputValues->ys; - z = inputValues->zs; - ux = inputValues->ux0; - uy = inputValues->uy0; - uz = inputValues->uz0; - } - else // use mcflag - { - if (inputValues->mcflag == 0) // uniform beam - { - // set launch point and width of beam - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 - r = inputValues->radius*sqrt(rnd); // radius of beam at launch point - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 - phi = rnd*2.0*PI; - x = inputValues->xs + r*cos(phi); - y = inputValues->ys + r*sin(phi); - z = inputValues->zs; - // set trajectory toward focus - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 - r = inputValues->waist*sqrt(rnd); // radius of beam at focus - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); // avoids rnd = 0 - phi = rnd*2.0*PI; - - // !!!!!!!!!!!!!!!!!!!!!!! setting input values will braek - - inputValues->xfocus = r*cos(phi); - inputValues->yfocus = r*sin(phi); - temp = sqrt((x - inputValues->xfocus)*(x - inputValues->xfocus) - + (y - inputValues->yfocus)*(y - inputValues->yfocus) + inputValues->zfocus*inputValues->zfocus); - ux = -(x - inputValues->xfocus) / temp; - uy = -(y - inputValues->yfocus) / temp; - uz = sqrt(1 - ux*ux + uy*uy); - } - else if (inputValues->mcflag == 5) // Multispectral DKFZ prototype - { - // set launch point and width of beam - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - - //offset in x direction in cm (random) - x = (rnd*2.5) - 1.25; - - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - double b = ((rnd)-0.5); - y = (b > 0 ? yOffset + 1.5 : yOffset - 1.5); - z = 0.1; - ux = 0; - - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - - //Angle of beam in y direction - uy = sin((rnd*0.42) - 0.21 + (b < 0 ? 1.0 : -1.0) * 0.436); - - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - - // angle of beam in x direction - ux = sin((rnd*0.42) - 0.21); - uz = sqrt(1 - ux*ux - uy*uy); - } - else if (inputValues->mcflag == 4) // Monospectral prototype DKFZ - { - // set launch point and width of beam - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - - //offset in x direction in cm (random) - x = (rnd*2.5) - 1.25; - - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - double b = ((rnd)-0.5); - y = (b > 0 ? yOffset + 0.83 : yOffset - 0.83); - z = 0.1; - ux = 0; - - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - - //Angle of beam in y direction - uy = sin((rnd*0.42) - 0.21 + (b < 0 ? 1.0 : -1.0) * 0.375); - - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - - // angle of beam in x direction - ux = sin((rnd*0.42) - 0.21); - uz = sqrt(1 - ux*ux - uy*uy); - } - else { // isotropic pt source - costheta = 1.0 - 2.0 * returnValue->RandomGen(1, 0, nullptr); - sintheta = sqrt(1.0 - costheta*costheta); - psi = 2.0 * PI * returnValue->RandomGen(1, 0, nullptr); - cospsi = cos(psi); - if (psi < PI) - sinpsi = sqrt(1.0 - cospsi*cospsi); - else - sinpsi = -sqrt(1.0 - cospsi*cospsi); - x = inputValues->xs; - y = inputValues->ys; - z = inputValues->zs; - ux = sintheta*cospsi; - uy = sintheta*sinpsi; - uz = costheta; - } - } // end use mcflag - } - /****************************/ - - /* Get tissue voxel properties of launchpoint. - * If photon beyond outer edge of defined voxels, - * the tissue equals properties of outermost voxels. - * Therefore, set outermost voxels to infinite background value. - */ - ix = (int)(inputValues->Nx / 2 + x / inputValues->xSpacing); - iy = (int)(inputValues->Ny / 2 + y / inputValues->ySpacing); - iz = (int)(z / inputValues->zSpacing); - if (ix >= inputValues->Nx) ix = inputValues->Nx - 1; - if (iy >= inputValues->Ny) iy = inputValues->Ny - 1; - if (iz >= inputValues->Nz) iz = inputValues->Nz - 1; - if (ix < 0) ix = 0; - if (iy < 0) iy = 0; - if (iz < 0) iz = 0; - /* Get the tissue type of located voxel */ - i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); - - bflag = 1; // initialize as 1 = inside volume, but later check as photon propagates. - - if (returnValue->detectorVoxel != nullptr) - returnValue->detectorVoxel->recordedPhotonRoute->clear(); - - /* HOP_DROP_SPIN_CHECK - Propagate one photon until it dies as determined by ROULETTE. - *******/ - do { - /**** HOP - Take step to new position - s = dimensionless stepsize - x, uy, uz are cosines of current photon trajectory - *****/ - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); /* yields 0 < rnd <= 1 */ - sleft = -log(rnd); /* dimensionless step */ - CNT += 1; - - do { // while sleft>0 - s = sleft / inputValues->musVector[i]; /* Step size [cm].*/ - tempx = x + s*ux; /* Update positions. [cm] */ - tempy = y + s*uy; - tempz = z + s*uz; - - sv = returnValue->SameVoxel(x, y, z, tempx, tempy, tempz, inputValues->xSpacing, inputValues->ySpacing, inputValues->zSpacing); - if (sv) /* photon in same voxel */ - { - x = tempx; /* Update positions. */ - y = tempy; - z = tempz; - - /**** DROP - Drop photon weight (W) into local bin. - *****/ - - absorb = W*(1 - exp(-inputValues->muaVector[i] * s)); /* photon weight absorbed at this step */ - W -= absorb; /* decrement WEIGHT by amount absorbed */ - // If photon within volume of heterogeneity, deposit energy in F[]. - // Normalize F[] later, when save output. - if (bflag) - { - i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); - returnValue->totalFluence[i] += absorb; - // only save data if blag==1, i.e., photon inside simulation cube - - //For each detectorvoxel - if (returnValue->detectorVoxel != nullptr) - { - //Add photon position to the recorded photon route - returnValue->detectorVoxel->recordedPhotonRoute->push_back(initLocation(ix, iy, iz, absorb)); - - //If the photon is currently at the detector position - if ((returnValue->detectorVoxel->location.x == ix) - && ((returnValue->detectorVoxel->location.y == iy) - || (returnValue->detectorVoxel->location.y - 1 == iy)) - && (returnValue->detectorVoxel->location.z == iz)) - { - //For each voxel in the recorded photon route - for (unsigned int routeIndex = 0; routeIndex < returnValue->detectorVoxel->recordedPhotonRoute->size(); routeIndex++) - { - //increment the fluence contribution at that particular position - i = (long)(returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).z*inputValues->Ny*inputValues->Nx - + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).x*inputValues->Ny - + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).y); - returnValue->detectorVoxel->fluenceContribution[i] += returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).absorb; - } - - //Clear the recorded photon route - returnValue->detectorVoxel->m_NumberPhotonsCurrent++; - returnValue->detectorVoxel->recordedPhotonRoute->clear(); - } - } - } - - /* Update sleft */ - sleft = 0; /* dimensionless step remaining */ - } - else /* photon has crossed voxel boundary */ - { - /* step to voxel face + "littlest step" so just inside new voxel. */ - s = ls + returnValue->FindVoxelFace2(x, y, z, tempx, tempy, tempz, inputValues->xSpacing, inputValues->ySpacing, inputValues->zSpacing, ux, uy, uz); - - /**** DROP - Drop photon weight (W) into local bin. - *****/ - absorb = W*(1 - exp(-inputValues->muaVector[i] * s)); /* photon weight absorbed at this step */ - W -= absorb; /* decrement WEIGHT by amount absorbed */ - // If photon within volume of heterogeneity, deposit energy in F[]. - // Normalize F[] later, when save output. - if (bflag) - { - // only save data if bflag==1, i.e., photon inside simulation cube - - //For each detectorvoxel - if (returnValue->detectorVoxel != nullptr) - { - //Add photon position to the recorded photon route - returnValue->detectorVoxel->recordedPhotonRoute->push_back(initLocation(ix, iy, iz, absorb)); - - //If the photon is currently at the detector position - if ((returnValue->detectorVoxel->location.x == ix) - && ((returnValue->detectorVoxel->location.y == iy) - || (returnValue->detectorVoxel->location.y - 1 == iy)) - && (returnValue->detectorVoxel->location.z == iz)) - { - //For each voxel in the recorded photon route - for (unsigned int routeIndex = 0; routeIndex < returnValue->detectorVoxel->recordedPhotonRoute->size(); routeIndex++) - { - //increment the fluence contribution at that particular position - i = (long)(returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).z*inputValues->Ny*inputValues->Nx - + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).x*inputValues->Ny - + returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).y); - returnValue->detectorVoxel->fluenceContribution[i] += returnValue->detectorVoxel->recordedPhotonRoute->at(routeIndex).absorb; - } - - //Clear the recorded photon route - returnValue->detectorVoxel->m_NumberPhotonsCurrent++; - returnValue->detectorVoxel->recordedPhotonRoute->clear(); - } - } - - i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); - returnValue->totalFluence[i] += absorb; - } - - /* Update sleft */ - sleft -= s*inputValues->musVector[i]; /* dimensionless step remaining */ - if (sleft <= ls) sleft = 0; - - /* Update positions. */ - x += s*ux; - y += s*uy; - z += s*uz; - - // pointers to voxel containing optical properties - ix = (int)(inputValues->Nx / 2 + x / inputValues->xSpacing); - iy = (int)(inputValues->Ny / 2 + y / inputValues->ySpacing); - iz = (int)(z / inputValues->zSpacing); - - bflag = 1; // Boundary flag. Initialize as 1 = inside volume, then check. - if (inputValues->boundaryflag == 0) { // Infinite medium. - // Check if photon has wandered outside volume. - // If so, set tissue type to boundary value, but let photon wander. - // Set blag to zero, so DROP does not deposit energy. - if (iz >= inputValues->Nz) { iz = inputValues->Nz - 1; bflag = 0; } - if (ix >= inputValues->Nx) { ix = inputValues->Nx - 1; bflag = 0; } - if (iy >= inputValues->Ny) { iy = inputValues->Ny - 1; bflag = 0; } - if (iz < 0) { iz = 0; bflag = 0; } - if (ix < 0) { ix = 0; bflag = 0; } - if (iy < 0) { iy = 0; bflag = 0; } - } - else if (inputValues->boundaryflag == 1) { // Escape at boundaries - if (iz >= inputValues->Nz) { iz = inputValues->Nz - 1; photon_status = DEAD; sleft = 0; } - if (ix >= inputValues->Nx) { ix = inputValues->Nx - 1; photon_status = DEAD; sleft = 0; } - if (iy >= inputValues->Ny) { iy = inputValues->Ny - 1; photon_status = DEAD; sleft = 0; } - if (iz < 0) { iz = 0; photon_status = DEAD; sleft = 0; } - if (ix < 0) { ix = 0; photon_status = DEAD; sleft = 0; } - if (iy < 0) { iy = 0; photon_status = DEAD; sleft = 0; } - } - else if (inputValues->boundaryflag == 2) { // Escape at top surface, no x,y bottom z boundaries - if (iz >= inputValues->Nz) { iz = inputValues->Nz - 1; bflag = 0; } - if (ix >= inputValues->Nx) { ix = inputValues->Nx - 1; bflag = 0; } - if (iy >= inputValues->Ny) { iy = inputValues->Ny - 1; bflag = 0; } - if (iz < 0) { iz = 0; photon_status = DEAD; sleft = 0; } - if (ix < 0) { ix = 0; bflag = 0; } - if (iy < 0) { iy = 0; bflag = 0; } - } - - // update pointer to tissue type - i = (long)(iz*inputValues->Ny*inputValues->Nx + ix*inputValues->Ny + iy); - } //(sv) /* same voxel */ - } while (sleft > 0); //do...while - - /**** SPIN - Scatter photon into new trajectory defined by theta and psi. - Theta is specified by cos(theta), which is determined - based on the Henyey-Greenstein scattering function. - Convert theta and psi into cosines ux, uy, uz. - *****/ - /* Sample for costheta */ - while ((rnd = returnValue->RandomGen(1, 0, nullptr)) <= 0.0); - if (inputValues->gVector[i] == 0.0) - { - costheta = 2.0 * rnd - 1.0; - } - else - { - double temp = (1.0 - inputValues->gVector[i] * inputValues->gVector[i]) - / (1.0 - inputValues->gVector[i] + 2 * inputValues->gVector[i] * rnd); - costheta = (1.0 + inputValues->gVector[i] * inputValues->gVector[i] - temp*temp) / (2.0*inputValues->gVector[i]); - } - sintheta = sqrt(1.0 - costheta*costheta); /* sqrt() is faster than sin(). */ - - /* Sample psi. */ - psi = 2.0*PI*returnValue->RandomGen(1, 0, nullptr); - cospsi = cos(psi); - if (psi < PI) - sinpsi = sqrt(1.0 - cospsi*cospsi); /* sqrt() is faster than sin(). */ - else - sinpsi = -sqrt(1.0 - cospsi*cospsi); - - /* New trajectory. */ - if (1 - fabs(uz) <= ONE_MINUS_COSZERO) { /* close to perpendicular. */ - uxx = sintheta * cospsi; - uyy = sintheta * sinpsi; - uzz = costheta * SIGN(uz); /* SIGN() is faster than division. */ - } - else { /* usually use this option */ - temp = sqrt(1.0 - uz * uz); - uxx = sintheta * (ux * uz * cospsi - uy * sinpsi) / temp + ux * costheta; - uyy = sintheta * (uy * uz * cospsi + ux * sinpsi) / temp + uy * costheta; - uzz = -sintheta * cospsi * temp + uz * costheta; - } - - /* Update trajectory */ - ux = uxx; - uy = uyy; - uz = uzz; - - /**** CHECK ROULETTE - If photon weight below THRESHOLD, then terminate photon using Roulette technique. - Photon has CHANCE probability of having its weight increased by factor of 1/CHANCE, - and 1-CHANCE probability of terminating. - *****/ - if (W < THRESHOLD) { - if (returnValue->RandomGen(1, 0, nullptr) <= CHANCE) - W /= CHANCE; - else photon_status = DEAD; - } - } while (photon_status == ALIVE); /* end STEP_CHECK_HOP_SPIN */ - /* if ALIVE, continue propagating */ - /* If photon DEAD, then launch new photon. */ - } while (photonIterator < photonsToSimulate); /* end RUN */ - - returnValue->Nphotons += photonsToSimulate; - } while (photonsToSimulate > 0); - - if (verbose) std::cout << "------------------------------------------------------" << std::endl; - if (verbose) std::cout << "Thread " << thread << " is finished." << std::endl; -} diff --git a/Modules/PhotoacousticsLib/MitkMCxyz/files.cmake b/Modules/PhotoacousticsLib/MitkMCxyz/files.cmake deleted file mode 100644 index 284bae1500..0000000000 --- a/Modules/PhotoacousticsLib/MitkMCxyz/files.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CPP_FILES - MitkMCxyz.cpp -) diff --git a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/CMakeLists.txt b/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/CMakeLists.txt deleted file mode 100644 index 8ebf2fa24d..0000000000 --- a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -OPTION(BUILD_PhotoacousticPhantomGenerator "Build MiniApp for generating a PA phantom in silico" OFF) - -IF(BUILD_PhotoacousticPhantomGenerator) - PROJECT( MitkPAPhantomGenerator ) - mitk_create_executable(PAPhantomGenerator - DEPENDS MitkCommandLine MitkCore MitkPhotoacousticsLib - PACKAGE_DEPENDS - CPP_FILES PAPhantomGenerator.cpp) - - install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) - ENDIF() diff --git a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/PAPhantomGenerator.cpp b/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/PAPhantomGenerator.cpp deleted file mode 100644 index 1f81720dbb..0000000000 --- a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/PAPhantomGenerator.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace mitk::pa; - -TissueGeneratorParameters::Pointer CreatePhantom_04_04_18_Parameters() -{ - auto returnParameters = TissueGeneratorParameters::New(); - returnParameters->SetAirThicknessInMillimeters(12); - returnParameters->SetMinBackgroundAbsorption(0.1); - returnParameters->SetMaxBackgroundAbsorption(0.1); - returnParameters->SetBackgroundAnisotropy(0.9); - returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine); - returnParameters->SetDoPartialVolume(true); - returnParameters->SetMinNumberOfVessels(1); - returnParameters->SetMaxNumberOfVessels(8); - returnParameters->SetMinVesselAbsorption(1); - returnParameters->SetMaxVesselAbsorption(10); - returnParameters->SetMinVesselAnisotropy(0.9); - returnParameters->SetMaxVesselAnisotropy(0.9); - returnParameters->SetMinVesselBending(0.1); - returnParameters->SetMaxVesselBending(0.3); - returnParameters->SetMinVesselRadiusInMillimeters(0.25); - returnParameters->SetMaxVesselRadiusInMillimeters(4); - returnParameters->SetMinVesselScattering(15); - returnParameters->SetMaxVesselScattering(15); - returnParameters->SetMinVesselZOrigin(1.6); - returnParameters->SetMaxVesselZOrigin(4); - returnParameters->SetVesselBifurcationFrequency(5000); - returnParameters->SetRandomizePhysicalProperties(false); - returnParameters->SetSkinThicknessInMillimeters(0); - returnParameters->SetUseRngSeed(false); - returnParameters->SetVoxelSpacingInCentimeters(0.03); - returnParameters->SetXDim(140); - returnParameters->SetYDim(100); - returnParameters->SetZDim(180); - //returnParameters->SetVoxelSpacingInCentimeters(0.015); - //returnParameters->SetXDim(280); - //returnParameters->SetYDim(200); - //returnParameters->SetZDim(360); - returnParameters->SetForceVesselsMoveAlongYDirection(true); - //returnParameters->SetVoxelSpacingInCentimeters(0.0075); - //returnParameters->SetXDim(560); - //returnParameters->SetYDim(400); - //returnParameters->SetZDim(720); - return returnParameters; -} - -struct InputParameters -{ - std::string saveFolderPath; - std::string identifyer; - std::string exePath; - std::string probePath; - bool empty; - bool verbose; -}; - -InputParameters parseInput(int argc, char* argv[]) -{ - MITK_INFO << "Parsing arguments..."; - mitkCommandLineParser parser; - - parser.setCategory("MITK-Photoacoustics"); - parser.setTitle("Mitk Tissue Batch Generator"); - parser.setDescription("Creates in silico tissue in batch processing and automatically calculates fluence values for the central slice of the volume."); - parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); - - parser.setArgumentPrefix("--", "-"); - - parser.beginGroup("Required parameters"); - parser.addArgument( - "savePath", "s", mitkCommandLineParser::Directory, - "Input save folder (directory)", "input save folder", - us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "mitkMcxyz", "m", mitkCommandLineParser::File, - "MitkMcxyz binary (file)", "path to the MitkMcxyz binary", - us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.endGroup(); - - parser.beginGroup("Optional parameters"); - parser.addArgument( - "probe", "p", mitkCommandLineParser::File, - "xml probe file (file)", "file to the definition of the used probe (*.xml)", - us::Any(), true, false, false, mitkCommandLineParser::Output); - parser.addArgument( - "verbose", "v", mitkCommandLineParser::Bool, - "Verbose Output", "Whether to produce verbose, or rather debug output"); - parser.addArgument( - "identifyer", "i", mitkCommandLineParser::String, - "Generator identifyer (string)", "A unique identifyer for the calculation instance"); - parser.addArgument( - "empty-volume", "e", mitkCommandLineParser::Bool, - "omit vessel structures (boolean flag)", "Whether to create an empty volume with no structures inside."); - parser.endGroup(); - - InputParameters input; - - std::map parsedArgs = parser.parseArguments(argc, argv); - if (parsedArgs.size() == 0) - exit(-1); - - if (parsedArgs.count("empty-volume")) - { - input.empty = us::any_cast(parsedArgs["empty-volume"]); - } - else - { - input.empty = false; - } - - if (parsedArgs.count("verbose")) - { - input.verbose = us::any_cast(parsedArgs["verbose"]); - } - else - { - input.verbose = false; - } - - if (parsedArgs.count("savePath")) - { - input.saveFolderPath = us::any_cast(parsedArgs["savePath"]); - } - - if (parsedArgs.count("mitkMcxyz")) - { - input.exePath = us::any_cast(parsedArgs["mitkMcxyz"]); - } - - if (parsedArgs.count("probe")) - { - input.probePath = us::any_cast(parsedArgs["probe"]); - } - - if (parsedArgs.count("identifyer")) - { - input.identifyer = us::any_cast(parsedArgs["identifyer"]); - } - else - { - input.identifyer = mitk::UIDGenerator().GetUID(); - } - MITK_INFO << "Parsing arguments...[Done]"; - return input; -} - -int main(int argc, char * argv[]) -{ - auto input = parseInput(argc, argv); - auto parameters = CreatePhantom_04_04_18_Parameters(); - if (input.empty) - { - parameters->SetMaxNumberOfVessels(0); - parameters->SetMinNumberOfVessels(0); - } - MITK_INFO(input.verbose) << "Generating tissue.."; - auto resultTissue = InSilicoTissueGenerator::GenerateInSilicoData(parameters); - MITK_INFO(input.verbose) << "Generating tissue..[Done]"; - - auto inputfolder = std::string(input.saveFolderPath + "input/"); - auto outputfolder = std::string(input.saveFolderPath + "output/"); - if (!itksys::SystemTools::FileIsDirectory(inputfolder)) - { - itksys::SystemTools::MakeDirectory(inputfolder); - } - if (!itksys::SystemTools::FileIsDirectory(outputfolder)) - { - itksys::SystemTools::MakeDirectory(outputfolder); - } - - std::string savePath = input.saveFolderPath + "input/Phantom_" + input.identifyer + - ".nrrd"; - mitk::IOUtil::Save(resultTissue->ConvertToMitkImage(), savePath); - std::string outputPath = input.saveFolderPath + "output/Phantom_" + input.identifyer + - "/"; - - resultTissue = nullptr; - - if (!itksys::SystemTools::FileIsDirectory(outputPath)) - { - itksys::SystemTools::MakeDirectory(outputPath); - } - - outputPath = outputPath + "Fluence_Phantom_" + input.identifyer; - - MITK_INFO(input.verbose) << "Simulating fluence.."; - - int result = -4; - - std::string cmdString = std::string(input.exePath + " -i " + savePath + " -o " + - (outputPath + ".nrrd") + - " -yo " + "0" + " -p " + input.probePath + - " -n 10000000"); - - MITK_INFO << "Executing: " << cmdString; - - result = std::system(cmdString.c_str()); - - MITK_INFO << result; - MITK_INFO(input.verbose) << "Simulating fluence..[Done]"; -} diff --git a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/files.cmake b/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/files.cmake deleted file mode 100644 index 07f708562d..0000000000 --- a/Modules/PhotoacousticsLib/MitkPAPhantomGenerator/files.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CPP_FILES - PAPhantomGenerator.cpp -) diff --git a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/CMakeLists.txt b/Modules/PhotoacousticsLib/MitkSpectralUnmixing/CMakeLists.txt deleted file mode 100644 index f2faf72a92..0000000000 --- a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -OPTION(BUILD_PhotoacousticSpectralUnmixing "Build MiniApp for batch generating of photoacoustic spectral unmixing" OFF) - -IF(BUILD_PhotoacousticSpectralUnmixing) - PROJECT( MitkSpectralUnmxing ) - mitk_create_executable(SpectralUnmxingApp - DEPENDS MitkCommandLine MitkCore MitkPhotoacousticsLib - PACKAGE_DEPENDS - CPP_FILES SpectralUnmixingApp.cpp) - - install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) - ENDIF() diff --git a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/ReadMe.txt b/Modules/PhotoacousticsLib/MitkSpectralUnmixing/ReadMe.txt deleted file mode 100644 index 5c2e7e3d2b..0000000000 --- a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/ReadMe.txt +++ /dev/null @@ -1,15 +0,0 @@ -/** - \spectral unmixing mini App (SUMA) - - \brief The SUMA is designed to enable batch processing for spectral unmixing. To use the SUMA one has to build the MitkSpectralUnmixingApp located in the PAlib. Afterwards a .bat script is available int the suberbuild/MITK-build/bin. This script takes 4 required and one optional parameter: - -Required parameters - -i, --inputFilename, input filename // "E:/mydata/awesome_exp/first_image.nrrd" image has to be an integer multiple of the number of wavelengths - -o, --outputFileStruct, input save name // "E:/mydata/awesome_exp_unmixed/first_image_ctr" will be saved as "_HbO2_SU_.nrrd", "_Hb_SU_.nrrd" and "_sO2_.nrrd"; it is recommended to add an counter (ctr) to the savenames otherwise they will be overwritten. - -l, --inputWavelengths, input wavelengths // (int) 299 < wavelength < 1001 with format: int blank int blank int blank ... - -a, --inputAlg, input algorithm // insert alg: "QR", "NNLS", "WLS", "SVD", "LU" - -w, --inputWeights, input weights (optional) // int weights in % format and order corresponding to the wavelength: int blank int blank ... - -To costumize the SUMA for batch processing of a whole directory, you can either write a script which calls the SUMA for every image again oR insert a loop arround the actual unmixing in the code entering your file structure (see comments inside the code). - -For further questions please contact Niklas Holzwarth (n.holzwarth@dkfz-heidelberg.de or niklas.holzwarth@gmail.com) \ No newline at end of file diff --git a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingApp.cpp b/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingApp.cpp deleted file mode 100644 index 89b3e472ad..0000000000 --- a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingApp.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include "mitkPALinearSpectralUnmixingFilter.h" -#include "mitkPASpectralUnmixingFilterBase.h" -#include "mitkPASpectralUnmixingFilterVigra.h" -#include "mitkPASpectralUnmixingSO2.h" -#include -#include -#include -#include -#include -#include "mitkPreferenceListReaderOptionsFunctor.h" - - -/* \brief The spectral unmixing mini app (SUMA) is designed to enable batch processing - for spectral unmixing. For detailed documentation look into the header files of the - included spectral unmixing filters.*/ - -struct InputParameters -{ - std::string inputFilename; - std::string outputFileStruct; // "E:/mydata/awesome_exp_unmixed/a" will be saved as "a_HbO2_SU_.nrrd", "a_Hb_SU_.nrrd" and "a_sO2_.nrrd"; - std::string inputAlg; - std::string outputFileNumber; - mitkCommandLineParser::StringContainerType inputWavelengths; - mitkCommandLineParser::StringContainerType inputWeights; -}; - -InputParameters parseInput(int argc, char *argv[]) -{ - //MITK_INFO << "Parsing arguments..."; - mitkCommandLineParser parser; - - parser.setCategory("MITK-Photoacoustics"); - parser.setTitle("Mitk Spectral Unmixing App"); - parser.setDescription("Batch processing for spectral unmixing."); - parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); - - parser.setArgumentPrefix("--", "-"); - - parser.beginGroup("Required parameters"); - parser.addArgument("inputFilename", - "i", - mitkCommandLineParser::Directory, - "Input Filename (NAME.nrrd)", - "input filename", - us::Any(), - false); - parser.addArgument("outputFileStruct", - "o", - mitkCommandLineParser::Directory, - "Output save name (name without ending!)", - "Output save name", - us::Any(), - false); - parser.addArgument("outputFileNumber", - "n", - mitkCommandLineParser::String, - "Output file number", - "Output save number", - us::Any(), - false); - parser.addArgument("inputWavelengths", - "l", - mitkCommandLineParser::StringList, - "Input wavelengths (123 124 125 ... int blank int blank)", - "input wavelengths", - us::Any(), - false); - parser.addArgument("inputAlg", - "a", - mitkCommandLineParser::String, - "Input algorithm (string)", - "input algorithm", - us::Any(), - false); - parser.addArgument("inputWeights", - "w", - mitkCommandLineParser::StringList, - "Input weights (123 124 125 ... int in % blank int in % blank)", - "input weights", - us::Any(), - true); - parser.endGroup(); - - InputParameters input; - - std::map parsedArgs = parser.parseArguments(argc, argv); - if (argc == 0) - exit(-1); - - //for (int i = 0; i < argc; ++i) - //{ - // MITK_INFO << argv[i]; - //} - - - if (parsedArgs.count("inputFilename")) - { - - input.inputFilename = us::any_cast(parsedArgs["inputFilename"]); - } - else - { - MITK_ERROR << "Error: No input file"; - mitkThrow() << "Error: No input file"; - } - - if (parsedArgs.count("outputFileStruct")) - { - input.outputFileStruct = us::any_cast(parsedArgs["outputFileStruct"]); - } - else - { - MITK_ERROR << "Error: No output"; - mitkThrow() << "Error: No output"; - } - - if (parsedArgs.count("outputFileNumber")) - { - input.outputFileNumber = us::any_cast(parsedArgs["outputFileNumber"]); - } - else - { - MITK_ERROR << "Error: No output number"; - mitkThrow() << "Error: No output number"; - } - - if (parsedArgs.count("inputWavelengths")) - { - input.inputWavelengths = us::any_cast(parsedArgs["inputWavelengths"]); - } - else - { - MITK_ERROR << "Error: No wavelengths"; - mitkThrow() << "Error: No wavelengths"; - } - if (parsedArgs.count("inputAlg")) - { - input.inputAlg = us::any_cast(parsedArgs["inputAlg"]); - } - else - { - MITK_ERROR << "Error: No algorithm"; - mitkThrow() << "Error: No algorithm"; - } - - if (parsedArgs.count("inputWeights")) - { - input.inputWeights = us::any_cast(parsedArgs["inputWeights"]); - } - - //MITK_INFO << "Parsing arguments...[Done]"; - return input; -} - -// Class takes string and sets algorithm for spectral unmixing in the corresponding filter class -mitk::pa::SpectralUnmixingFilterBase::Pointer GetFilterInstance(std::string algorithm, std::vector weights = std::vector()) -{ - mitk::pa::SpectralUnmixingFilterBase::Pointer spectralUnmixingFilter; - - if (algorithm == "QR") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - } - - else if (algorithm == "SVD") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::JACOBISVD); - } - - else if (algorithm == "LU") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVLU); - } - - else if (algorithm == "NNLS") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LARS); - } - - else if (algorithm == "WLS") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::WEIGHTED); - - std::vector weightVec = weights; - - for (unsigned int i = 0; i < weightVec.size(); ++i) - { - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->AddWeight(weightVec[i]); - } - } - return spectralUnmixingFilter; -} - -int main(int argc, char *argv[]) -{ - auto input = parseInput(argc, argv); - - std::string algo = input.inputAlg; - std::string outputDir = input.outputFileStruct; - std::string outputNumber = input.outputFileNumber; - - auto inputWls = input.inputWavelengths; - - std::vector wavelengths; - for (unsigned int s = 0; s < inputWls.size(); ++s) - { - int wl = std::stoi(inputWls[s]); - wavelengths.push_back(wl); - //MITK_INFO << "Wavelength: " << wl << "\n"; - } - - mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter; - - if (algo == "WLS") - { - auto inputW = input.inputWeights; - - std::vector Weights; - for (unsigned int s = 0; s < inputW.size(); ++s) - { - int w = std::stoi(inputW[s]); - Weights.push_back(w); - //MITK_INFO << "Weights: " << w << "\n"; - } - - m_SpectralUnmixingFilter = GetFilterInstance(algo, Weights); - } - else - { - m_SpectralUnmixingFilter = GetFilterInstance(algo); - } - - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - m_SpectralUnmixingFilter->AddOutputs(2); - - for (unsigned int wIdx = 0; wIdx < wavelengths.size(); ++wIdx) - { - m_SpectralUnmixingFilter->AddWavelength(wavelengths[wIdx]); - //MITK_INFO << wavelengths[wIdx]; - } - - //to add a batch processing: loop for a dir start here; don't forget to set a counter to the three output savenames!!! - std::string inputImage = input.inputFilename; - auto m_inputImage = mitk::IOUtil::Load(inputImage); - - m_SpectralUnmixingFilter->SetInput(m_inputImage); - - m_SpectralUnmixingFilter->Update(); - - auto output1 = m_SpectralUnmixingFilter->GetOutput(0); - auto output2 = m_SpectralUnmixingFilter->GetOutput(1); - output1->SetSpacing(m_inputImage->GetGeometry()->GetSpacing()); - output2->SetSpacing(m_inputImage->GetGeometry()->GetSpacing()); - - std::string unmixingOutputHbO2 = outputDir + "HbO2." + outputNumber + ".nrrd"; - std::string unmixingOutputHb = outputDir + "Hb." + outputNumber + ".nrrd"; - //mitk::IOUtil::Save(output1, unmixingOutputHbO2); - //mitk::IOUtil::Save(output2, unmixingOutputHb); - - auto m_sO2 = mitk::pa::SpectralUnmixingSO2::New(); - m_sO2->Verbose(false); - - m_sO2->SetInput(0, output1); - m_sO2->SetInput(1, output2); - - m_sO2->Update(); - - mitk::Image::Pointer sO2 = m_sO2->GetOutput(0); - mitk::Image::Pointer tHb = m_sO2->GetOutput(1); - sO2->SetSpacing(m_inputImage->GetGeometry()->GetSpacing()); - tHb->SetSpacing(m_inputImage->GetGeometry()->GetSpacing()); - - std::string outputSo2 = outputDir + "sO2." + outputNumber + ".nrrd"; - mitk::IOUtil::Save(sO2, outputSo2); - - std::string outputTHb = outputDir + "tHb." + outputNumber + ".nrrd"; - mitk::IOUtil::Save(tHb, outputTHb); - - m_sO2 = nullptr; - m_SpectralUnmixingFilter = nullptr; - //to add a batch processing: loop for a dir end here - MITK_INFO << "Spectral Unmixing DONE"; -} diff --git a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingAppTimeEval.cpp b/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingAppTimeEval.cpp deleted file mode 100644 index 1c484128ba..0000000000 --- a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingAppTimeEval.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -//#include -#include -#include - -#include "mitkPALinearSpectralUnmixingFilter.h" -#include "mitkPASpectralUnmixingFilterBase.h" -#include "mitkPASpectralUnmixingFilterVigra.h" -#include "mitkPASpectralUnmixingSO2.h" - -#include -#include -#include -#include - -#include - - -#include "mitkPreferenceListReaderOptionsFunctor.h" - - -struct InputParameters -{ - std::string inputPath; - std::string outputPath; - int numberOfInputs; -}; - -InputParameters parseInput(int argc, char *argv[]) -{ - MITK_INFO << "Parsing arguments..."; - mitkCommandLineParser parser; - - parser.setCategory("MITK-Photoacoustics"); - parser.setTitle("Mitk Spectral Unmixing App"); - parser.setDescription("Batch processing for spectral unmixing."); - parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); - - parser.setArgumentPrefix("--", "-"); - - parser.beginGroup("Required parameters"); - parser.addArgument("inputPath", - "i", - mitkCommandLineParser::Directory, - "Input folder (directory)", - "input folder", - us::Any(), - false, false, false, mitkCommandLineParser::Input); - parser.addArgument("outputPath", - "o", - mitkCommandLineParser::Directory, - "Input save folder (directory)", - "input save folder", - us::Any(), - false, false, false, mitkCommandLineParser::Output); - parser.addArgument("numberOfInputs", - "n", - mitkCommandLineParser::Int, - "Number of Input files", - "number of inputs", - us::Any(), - false); - parser.endGroup(); - - - InputParameters input; - - - std::map parsedArgs = parser.parseArguments(argc, argv); - if (argc == 0) - exit(-1); - - for (int i = 0; i < argc; ++i) - { - MITK_INFO << argv[i]; - } - - if (parsedArgs.count("inputPath")) - { - input.inputPath = us::any_cast(parsedArgs["inputPath"]); - } - else - { - MITK_ERROR << "Error: No inputPath"; - mitkThrow() << "Error: No inputPath"; - } - - if (parsedArgs.count("outputPath")) - { - input.outputPath = us::any_cast(parsedArgs["outputPath"]); - } - else - { - MITK_ERROR << "Error: No outputPath"; - mitkThrow() << "Error: No outputPath"; - } - if (parsedArgs.count("numberOfInputs")) - { - input.numberOfInputs = us::any_cast(parsedArgs["numberOfInputs"]); - } - else - { - MITK_ERROR << "Error: No number of Inputs"; - mitkThrow() << "Error: No number of Inputs"; - } - MITK_INFO << "Parsing arguments...[Done]"; - return input; -} - - -mitk::pa::SpectralUnmixingFilterBase::Pointer GetFilterInstance(std::string algorithm) -{ - mitk::pa::SpectralUnmixingFilterBase::Pointer spectralUnmixingFilter; - - if (algorithm == "QR") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - } - - else if (algorithm == "SVD") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::JACOBISVD); - } - - else if (algorithm == "LU") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVLU); - } - - else if (algorithm == "NNLS") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LARS); - } - - else if (algorithm == "WLS") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::WEIGHTED); - - /*std::vector weigthVec = {39, 45, 47}; - - for (int i = 0; i < 3; ++i) - { - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->AddWeight(weigthVec[i]); - }*/ - } - return spectralUnmixingFilter; -} - -void add_weight(int weights, mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter) -{ - std::vector weigthVec = { 30, 32, 33, 35, 37, 38, 40, 41, 43, 44, 45, 46, 47, 47, - 47, 47, 47, 46, 46, 45, 44, 44, 43, 42, 42, 41 }; - - for (int i = 0; i < weights; ++i) - { - dynamic_cast(m_SpectralUnmixingFilter.GetPointer()) - ->AddWeight(weigthVec[i]); - } -} - - - -int main(int argc, char *argv[]) -{ - auto input = parseInput(argc, argv); - - std::string inputDir = input.inputPath; - std::string outputDir = input.outputPath; - unsigned int N = input.numberOfInputs; - -/* - //maybee try with "itk system tools" - - //auto test = itksys::SystemTools::GetFilenameName(argv[0]).c_str(); - - //MITK_INFO << "test: " << test; - - - / +++ temporary solution BEGIN +++ - std::vector files; - std::string file; - for (int i = 1; i < 34; ++i) - { - - if (i < 10) - { - file = "E:/NHDATA/sdmas_beamformed/merged/static-oxy_sdmas_00" + std::to_string(i) + "_merged.nrrd"; - } - else - { - file = "E:/NHDATA/sdmas_beamformed/merged/static-oxy_sdmas_0" + std::to_string(i) + "_merged.nrrd"; - } - files.push_back(file); - } - / +++ temporary solution END +++ - - std::vector files; - std::string file; - for (int i = 0; i < 7; ++i) - { - file = "E:/NHCAMI/cami-experimental/PAI/spectralUnmixing/inSilico/paImages/selection/noiselevel1_rep1000_wavelength_selction_data_" + - std::to_string(i) + ".nrrd"; - files.push_back(file); - } - std::vector files; - std::string file; - file = "E:/NHCAMI/cami-experimental/PAI/spectralUnmixing/inSilico/paImages/selection/noiselevel1_rep1000_wavelength_selction_data.nrrd"; - files.push_back(file);*/ - - std::vector algorithms = { "QR", "LU", "SVD", "NNLS", "WLS" }; - int repetition = 6000; - - for (unsigned alg = 0; alg < 5; ++alg) - { - ofstream myerrorfile; - myerrorfile.open("E:/NHDATA/time/time_evaluation_" + std::to_string(repetition)+"_" + algorithms[alg] + "_new02.txt"); - - int ctr = 0; - for(int i = 2; i < 27; ++i) - { - myerrorfile << std::to_string(i) + "\t"; - std::string file; - if (i < 10) - file = "E:/NHDATA/time/input/time_0" + std::to_string(i) + ".nrrd"; - else - file = "E:/NHDATA/time/input/time_" + std::to_string(i) + ".nrrd"; - - auto m_inputImage = mitk::IOUtil::Load(file); - - MITK_INFO << "File: " << i; - - for (int j = 0; j < repetition; ++j) - { - std::chrono::steady_clock::time_point _start; - _start = std::chrono::steady_clock::now(); - - mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter = GetFilterInstance(algorithms[alg]); - m_SpectralUnmixingFilter->SetInput(m_inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - for (int wl = 0; wl < i; ++wl) - { - m_SpectralUnmixingFilter->AddWavelength(700 + wl * 10); - } - - if (alg == 4) - { - add_weight(i, m_SpectralUnmixingFilter); - } - - - m_SpectralUnmixingFilter->Update(); - - auto output1 = m_SpectralUnmixingFilter->GetOutput(0); - auto output2 = m_SpectralUnmixingFilter->GetOutput(1); - - m_SpectralUnmixingFilter = nullptr; - - std::chrono::steady_clock::time_point _end(std::chrono::steady_clock::now()); - myerrorfile << std::chrono::duration_cast>(_end - _start).count() << "\t"; - - /*std::string unmixingOutputHbO2 = "E:/NHDATA/time/output/time_" + std::to_string(i) + ".nrrd"; - std::string unmixingOutputHb = "E:/NHDATA/time/output/time_" + std::to_string(i) + ".nrrd"; - mitk::IOUtil::Save(output1, unmixingOutputHbO2); - mitk::IOUtil::Save(output2, unmixingOutputHb); - - //auto m_sO2 = mitk::pa::SpectralUnmixingSO2::New(); - //m_sO2->Verbose(false); - //auto output1 = m_SpectralUnmixingFilter->GetOutput(0); - //auto output2 = m_SpectralUnmixingFilter->GetOutput(1); - - - //std::string unmixingOutputHbO2 ="E:/NHDATA/time/input/time_" + std::to_string(i) + ".nrrd"; - //std::string unmixingOutputHb = outputDir + "/SUOutput/" + "Hb_" + algorithms[alg] + "_" + str_ctr + ".nrrd"; - //mitk::IOUtil::Save(output1, unmixingOutputHbO2); - //mitk::IOUtil::Save(output2, unmixingOutputHb); - - //m_sO2->SetInput(0, output1); - //m_sO2->SetInput(1, output2); - - //m_sO2->Update(); - - //mitk::Image::Pointer sO2 = m_sO2->GetOutput(0); - //sO2->SetSpacing(output1->GetGeometry()->GetSpacing()); - - //std::string outputSo2 = outputDir + "/So2/" + algorithms[alg] + "/So2_" + algorithms[alg] + "_" + str_ctr + ".nrrd"; - //std::string outputSo2 = outputDir + "/" + algorithms[alg] + "_sel_" + str_ctr + ".nrrd"; - //std::string outputSo2 = outputDir + "/" + algorithms[alg] + "_sel.nrrd"; - //mitk::IOUtil::Save(sO2, outputSo2); - - //std::string outputSo2 = "E:/NHDATA/time/output/time_" + std::to_string(i) + algorithms[alg] + ".nrrd"; - //mitk::IOUtil::Save(sO2, outputSo2);*/ - } - myerrorfile << "\n"; - } - myerrorfile.close(); - } - MITK_INFO << "Spectral Unmixing DONE"; -} diff --git a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/files.cmake b/Modules/PhotoacousticsLib/MitkSpectralUnmixing/files.cmake deleted file mode 100644 index a0a3a5cdb3..0000000000 --- a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/files.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CPP_FILES - SpectralUnmixingApp.cpp -) diff --git a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/CMakeLists.txt b/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/CMakeLists.txt deleted file mode 100644 index 7158831299..0000000000 --- a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -OPTION(BUILD_PhotoacousticTissueBatchGenerator "Build MiniApp for batch generating of photoacoustic tissue" OFF) - -IF(BUILD_PhotoacousticTissueBatchGenerator) - PROJECT( MitkTissueBatchGenerator ) - mitk_create_executable(TissueBatchGenerator - DEPENDS MitkCommandLine MitkCore MitkPhotoacousticsLib - PACKAGE_DEPENDS - CPP_FILES TissueBatchGenerator.cpp) - - install(TARGETS ${EXECUTABLE_TARGET} RUNTIME DESTINATION bin) - ENDIF() diff --git a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/TissueBatchGenerator.cpp b/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/TissueBatchGenerator.cpp deleted file mode 100644 index 7f2237754d..0000000000 --- a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/TissueBatchGenerator.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace mitk::pa; - -TissueGeneratorParameters::Pointer CreateMultiHB_13_02_18_Parameters() -{ - auto returnParameters = TissueGeneratorParameters::New(); - returnParameters->SetAirThicknessInMillimeters(1.8); - returnParameters->SetMinBackgroundAbsorption(0.001); - returnParameters->SetMaxBackgroundAbsorption(0.2); - returnParameters->SetBackgroundAnisotropy(0.9); - returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - returnParameters->SetDoPartialVolume(true); - returnParameters->SetMinNumberOfVessels(1); - returnParameters->SetMaxNumberOfVessels(7); - returnParameters->SetMinVesselAbsorption(1); - returnParameters->SetMaxVesselAbsorption(12); - returnParameters->SetMinVesselAnisotropy(0.9); - returnParameters->SetMaxVesselAnisotropy(0.9); - returnParameters->SetMinVesselBending(0); - returnParameters->SetMaxVesselBending(0.2); - returnParameters->SetMinVesselRadiusInMillimeters(0.5); - returnParameters->SetMaxVesselRadiusInMillimeters(6); - returnParameters->SetMinVesselScattering(15); - returnParameters->SetMaxVesselScattering(15); - returnParameters->SetMinVesselZOrigin(1); - returnParameters->SetMaxVesselZOrigin(3); - returnParameters->SetVesselBifurcationFrequency(5000); - returnParameters->SetRandomizePhysicalProperties(false); - returnParameters->SetSkinThicknessInMillimeters(0); - returnParameters->SetUseRngSeed(false); - returnParameters->SetVoxelSpacingInCentimeters(0.06); - returnParameters->SetXDim(70); - returnParameters->SetYDim(100); - returnParameters->SetZDim(100); - returnParameters->SetMCflag(4); - return returnParameters; -} - -TissueGeneratorParameters::Pointer CreateBaselineHB_13_02_18_Parameters() -{ - auto returnParameters = TissueGeneratorParameters::New(); - returnParameters->SetAirThicknessInMillimeters(1.8); - returnParameters->SetMinBackgroundAbsorption(0.001); - returnParameters->SetMaxBackgroundAbsorption(0.2); - returnParameters->SetBackgroundAnisotropy(0.9); - returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - returnParameters->SetDoPartialVolume(true); - returnParameters->SetMinNumberOfVessels(1); - returnParameters->SetMaxNumberOfVessels(1); - returnParameters->SetMinVesselAbsorption(4.73); - returnParameters->SetMaxVesselAbsorption(4.73); - returnParameters->SetMinVesselAnisotropy(0.9); - returnParameters->SetMaxVesselAnisotropy(0.9); - returnParameters->SetMinVesselBending(0); - returnParameters->SetMaxVesselBending(0.2); - returnParameters->SetMinVesselRadiusInMillimeters(3); - returnParameters->SetMaxVesselRadiusInMillimeters(3); - returnParameters->SetMinVesselScattering(15); - returnParameters->SetMaxVesselScattering(15); - returnParameters->SetMinVesselZOrigin(1); - returnParameters->SetMaxVesselZOrigin(3); - returnParameters->SetVesselBifurcationFrequency(5000); - returnParameters->SetRandomizePhysicalProperties(false); - returnParameters->SetSkinThicknessInMillimeters(0); - returnParameters->SetUseRngSeed(false); - returnParameters->SetVoxelSpacingInCentimeters(0.06); - returnParameters->SetXDim(70); - returnParameters->SetYDim(100); - returnParameters->SetZDim(100); - returnParameters->SetMCflag(4); - return returnParameters; -} - -TissueGeneratorParameters::Pointer CreateSingleVesselHeterogeneousBackground_08_02_18_Parameters() -{ - auto returnParameters = TissueGeneratorParameters::New(); - returnParameters->SetAirThicknessInMillimeters(1.8); - returnParameters->SetMinBackgroundAbsorption(0.001); - returnParameters->SetMaxBackgroundAbsorption(0.2); - returnParameters->SetBackgroundAnisotropy(0.9); - returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - returnParameters->SetDoPartialVolume(true); - returnParameters->SetMinNumberOfVessels(1); - returnParameters->SetMaxNumberOfVessels(1); - returnParameters->SetMinVesselAbsorption(1); - returnParameters->SetMaxVesselAbsorption(12); - returnParameters->SetMinVesselAnisotropy(0.9); - returnParameters->SetMaxVesselAnisotropy(0.9); - returnParameters->SetMinVesselBending(0); - returnParameters->SetMaxVesselBending(0.2); - returnParameters->SetMinVesselRadiusInMillimeters(0.5); - returnParameters->SetMaxVesselRadiusInMillimeters(6); - returnParameters->SetMinVesselScattering(15); - returnParameters->SetMaxVesselScattering(15); - returnParameters->SetMinVesselZOrigin(1); - returnParameters->SetMaxVesselZOrigin(3); - returnParameters->SetVesselBifurcationFrequency(5000); - returnParameters->SetRandomizePhysicalProperties(false); - returnParameters->SetSkinThicknessInMillimeters(0); - returnParameters->SetUseRngSeed(false); - returnParameters->SetVoxelSpacingInCentimeters(0.06); - returnParameters->SetXDim(70); - returnParameters->SetYDim(100); - returnParameters->SetZDim(100); - returnParameters->SetMCflag(4); - return returnParameters; -} - -TissueGeneratorParameters::Pointer CreateMultivessel_19_12_17_Parameters() -{ - auto returnParameters = TissueGeneratorParameters::New(); - returnParameters->SetAirThicknessInMillimeters(12); - returnParameters->SetMinBackgroundAbsorption(0.1); - returnParameters->SetMaxBackgroundAbsorption(0.1); - returnParameters->SetBackgroundAnisotropy(0.9); - returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - returnParameters->SetDoPartialVolume(true); - returnParameters->SetMinNumberOfVessels(1); - returnParameters->SetMaxNumberOfVessels(7); - returnParameters->SetMinVesselAbsorption(2); - returnParameters->SetMaxVesselAbsorption(8); - returnParameters->SetMinVesselAnisotropy(0.9); - returnParameters->SetMaxVesselAnisotropy(0.9); - returnParameters->SetMinVesselBending(0.1); - returnParameters->SetMaxVesselBending(0.3); - returnParameters->SetMinVesselRadiusInMillimeters(0.5); - returnParameters->SetMaxVesselRadiusInMillimeters(4); - returnParameters->SetMinVesselScattering(15); - returnParameters->SetMaxVesselScattering(15); - returnParameters->SetMinVesselZOrigin(2.2); - returnParameters->SetMaxVesselZOrigin(4); - returnParameters->SetVesselBifurcationFrequency(5000); - returnParameters->SetRandomizePhysicalProperties(false); - returnParameters->SetSkinThicknessInMillimeters(0); - returnParameters->SetUseRngSeed(false); - returnParameters->SetVoxelSpacingInCentimeters(0.06); - returnParameters->SetXDim(70); - returnParameters->SetYDim(100); - returnParameters->SetZDim(100); - return returnParameters; -} - -TissueGeneratorParameters::Pointer CreateMultivessel_19_10_17_Parameters() -{ - auto returnParameters = TissueGeneratorParameters::New(); - returnParameters->SetAirThicknessInMillimeters(12); - returnParameters->SetMinBackgroundAbsorption(0.1); - returnParameters->SetMaxBackgroundAbsorption(0.1); - returnParameters->SetBackgroundAnisotropy(0.9); - returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - returnParameters->SetDoPartialVolume(true); - returnParameters->SetMinNumberOfVessels(1); - returnParameters->SetMaxNumberOfVessels(7); - returnParameters->SetMinVesselAbsorption(2); - returnParameters->SetMaxVesselAbsorption(8); - returnParameters->SetMinVesselAnisotropy(0.9); - returnParameters->SetMaxVesselAnisotropy(0.9); - returnParameters->SetMinVesselBending(0.1); - returnParameters->SetMaxVesselBending(0.3); - returnParameters->SetMinVesselRadiusInMillimeters(0.5); - returnParameters->SetMaxVesselRadiusInMillimeters(4); - returnParameters->SetMinVesselScattering(15); - returnParameters->SetMaxVesselScattering(15); - returnParameters->SetMinVesselZOrigin(2.2); - returnParameters->SetMaxVesselZOrigin(4); - returnParameters->SetVesselBifurcationFrequency(5000); - returnParameters->SetRandomizePhysicalProperties(false); - returnParameters->SetSkinThicknessInMillimeters(0); - returnParameters->SetUseRngSeed(false); - returnParameters->SetVoxelSpacingInCentimeters(0.03); - returnParameters->SetXDim(140); - returnParameters->SetYDim(200); - returnParameters->SetZDim(180); - return returnParameters; -} - -TissueGeneratorParameters::Pointer CreateSinglevessel_19_10_17_Parameters() -{ - auto returnParameters = TissueGeneratorParameters::New(); - returnParameters->SetAirThicknessInMillimeters(12); - returnParameters->SetMinBackgroundAbsorption(0.1); - returnParameters->SetMaxBackgroundAbsorption(0.1); - returnParameters->SetBackgroundAnisotropy(0.9); - returnParameters->SetBackgroundScattering(15); - returnParameters->SetCalculateNewVesselPositionCallback(&VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - returnParameters->SetDoPartialVolume(true); - returnParameters->SetMinNumberOfVessels(1); - returnParameters->SetMaxNumberOfVessels(1); - returnParameters->SetMinVesselAbsorption(2); - returnParameters->SetMaxVesselAbsorption(8); - returnParameters->SetMinVesselAnisotropy(0.9); - returnParameters->SetMaxVesselAnisotropy(0.9); - returnParameters->SetMinVesselBending(0.1); - returnParameters->SetMaxVesselBending(0.3); - returnParameters->SetMinVesselRadiusInMillimeters(0.5); - returnParameters->SetMaxVesselRadiusInMillimeters(4); - returnParameters->SetMinVesselScattering(15); - returnParameters->SetMaxVesselScattering(15); - returnParameters->SetMinVesselZOrigin(2.2); - returnParameters->SetMaxVesselZOrigin(4); - returnParameters->SetVesselBifurcationFrequency(5000); - returnParameters->SetRandomizePhysicalProperties(false); - returnParameters->SetSkinThicknessInMillimeters(0); - returnParameters->SetUseRngSeed(false); - returnParameters->SetVoxelSpacingInCentimeters(0.03); - returnParameters->SetXDim(140); - returnParameters->SetYDim(200); - returnParameters->SetZDim(180); - return returnParameters; -} - -struct InputParameters -{ - std::string saveFolderPath; - std::string identifyer; - std::string exePath; - std::string probePath; - bool verbose; -}; - -InputParameters parseInput(int argc, char* argv[]) -{ - MITK_INFO << "Paring arguments..."; - mitkCommandLineParser parser; - // set general information - parser.setCategory("MITK-Photoacoustics"); - parser.setTitle("Mitk Tissue Batch Generator"); - parser.setDescription("Creates in silico tissue in batch processing and automatically calculates fluence values for the central slice of the volume."); - parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); - - // how should arguments be prefixed - parser.setArgumentPrefix("--", "-"); - // add each argument, unless specified otherwise each argument is optional - // see mitkCommandLineParser::addArgument for more information - parser.beginGroup("Required parameters"); - parser.addArgument( - "savePath", "s", mitkCommandLineParser::Directory, - "Input save folder (directory)", "input save folder", - us::Any(), false, false, false, mitkCommandLineParser::Input); - parser.addArgument( - "mitkMcxyz", "m", mitkCommandLineParser::File, - "MitkMcxyz binary (file)", "path to the MitkMcxyz binary", - us::Any(), false, false, false, mitkCommandLineParser::Output); - parser.endGroup(); - parser.beginGroup("Optional parameters"); - parser.addArgument( - "probe", "p", mitkCommandLineParser::File, - "xml probe file (file)", "file to the definition of the used probe (*.xml)", - us::Any(), true, false, false, mitkCommandLineParser::Output); - parser.addArgument( - "verbose", "v", mitkCommandLineParser::Bool, - "Verbose Output", "Whether to produce verbose, or rather debug output"); - parser.addArgument( - "identifyer", "i", mitkCommandLineParser::String, - "Generator identifyer (string)", "A unique identifyer for the calculation instance"); - - InputParameters input; - - std::map parsedArgs = parser.parseArguments(argc, argv); - if (parsedArgs.size() == 0) - exit(-1); - - if (parsedArgs.count("verbose")) - { - MITK_INFO << "verbose"; - input.verbose = us::any_cast(parsedArgs["verbose"]); - } - else - { - input.verbose = false; - } - - if (parsedArgs.count("savePath")) - { - MITK_INFO << "savePath"; - input.saveFolderPath = us::any_cast(parsedArgs["savePath"]); - } - - if (parsedArgs.count("mitkMcxyz")) - { - MITK_INFO << "mitkMcxyz"; - input.exePath = us::any_cast(parsedArgs["mitkMcxyz"]); - } - - if (parsedArgs.count("probe")) - { - MITK_INFO << "probe"; - input.probePath = us::any_cast(parsedArgs["probe"]); - } - - if (parsedArgs.count("identifyer")) - { - MITK_INFO << "identifyer"; - input.identifyer = us::any_cast(parsedArgs["identifyer"]); - } - else - { - MITK_INFO << "generating identifyer"; - input.identifyer = mitk::UIDGenerator().GetUID(); - } - MITK_INFO << "Paring arguments...[Done]"; - return input; -} - -int main(int argc, char * argv[]) -{ - auto input = parseInput(argc, argv); - unsigned int iterationNumber = 0; - - while (true) - { - auto parameters = CreateBaselineHB_13_02_18_Parameters(); - MITK_INFO(input.verbose) << "Generating tissue.."; - auto resultTissue = InSilicoTissueGenerator::GenerateInSilicoData(parameters); - MITK_INFO(input.verbose) << "Generating tissue..[Done]"; - - auto inputfolder = std::string(input.saveFolderPath + "input/"); - auto outputfolder = std::string(input.saveFolderPath + "output/"); - if (!itksys::SystemTools::FileIsDirectory(inputfolder)) - { - itksys::SystemTools::MakeDirectory(inputfolder); - } - if (!itksys::SystemTools::FileIsDirectory(outputfolder)) - { - itksys::SystemTools::MakeDirectory(outputfolder); - } - - std::string savePath = input.saveFolderPath + "input/BaselineHB_" + input.identifyer + - "_" + std::to_string(iterationNumber) + ".nrrd"; - mitk::IOUtil::Save(resultTissue->ConvertToMitkImage(), savePath); - std::string outputPath = input.saveFolderPath + "output/BaselineHB_" + input.identifyer + - "_" + std::to_string(iterationNumber) + "/"; - - if (!itksys::SystemTools::FileIsDirectory(outputPath)) - { - itksys::SystemTools::MakeDirectory(outputPath); - } - - outputPath = outputPath + "Fluence_BaselineHB_" + input.identifyer + "_" + std::to_string(iterationNumber); - - MITK_INFO(input.verbose) << "Simulating fluence.."; - for(double yo = -1.8; yo <= 1.81; yo=yo+0.12) - { - std::string yo_string = std::to_string(round(yo*100)/100.0); - int result = -4; - if(!input.probePath.empty()) - result = std::system(std::string(input.exePath + " -i " + savePath + " -o " + - (outputPath + "_yo" + yo_string + ".nrrd") + - " -yo " + yo_string + " -p " + input.probePath + - " -n 100000000").c_str()); - else - result = std::system(std::string(input.exePath + " -i " + savePath + " -o " + - (outputPath + "_yo" + yo_string + ".nrrd") + - " -yo " + yo_string + " -n 100000000").c_str()); - MITK_INFO << "yo: " << yo_string << ": " << result; - } - - MITK_INFO(input.verbose) << "Simulating fluence..[Done]"; - - iterationNumber++; - } -} diff --git a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/files.cmake b/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/files.cmake deleted file mode 100644 index d4e42c83d5..0000000000 --- a/Modules/PhotoacousticsLib/MitkTissueBatchGenerator/files.cmake +++ /dev/null @@ -1,3 +0,0 @@ -set(CPP_FILES - TissueBatchGenerator.cpp -) diff --git a/Modules/PhotoacousticsLib/Resources/photoacoustics128x128.png b/Modules/PhotoacousticsLib/Resources/photoacoustics128x128.png deleted file mode 100644 index 05deecf751..0000000000 Binary files a/Modules/PhotoacousticsLib/Resources/photoacoustics128x128.png and /dev/null differ diff --git a/Modules/PhotoacousticsLib/Resources/spectralLIB.dat b/Modules/PhotoacousticsLib/Resources/spectralLIB.dat deleted file mode 100644 index b2e2f59f24..0000000000 --- a/Modules/PhotoacousticsLib/Resources/spectralLIB.dat +++ /dev/null @@ -1 +0,0 @@ -300 353 345 0.0067 0.0001 3720 301 346 337 0.0066 0.0001 3680 302 338 328 0.0065 0.0001 3640 303 335 322 0.0064 0.0001 3600 304 332 315 0.0063 0.0001 3560 305 333 310 0.0062 0.0001 3520 306 334 305 0.0061 0.0001 3480 307 335 307 0.00599 0.0001 3450 308 337 309 0.00589 0.0001 3410 309 338 313 0.00579 0.0001 3370 310 339 317 0.00569 0.0001 3340 311 346 325 0.00559 0.0001 3300 312 353 333 0.00549 0.0001 3270 313 361 342 0.00539 0.0001 3230 314 370 350 0.00529 0.0001 3200 315 379 358 0.00519 0.0001 3160 316 388 366 0.00509 0.0001 3130 317 396 374 0.00499 0.0001 3100 318 404 381 0.00489 0.0001 3070 319 413 390 0.00478 0.0001 3030 320 422 399 0.00468 0.0001 3000 321 431 409 0.00458 0.0001 2970 322 440 419 0.00448 0.0001 2940 323 450 429 0.00438 0.0001 2910 324 460 439 0.00428 0.0001 2880 325 471 449 0.00418 0.0001 2850 326 481 458 0.00411 0.0001 2820 327 491 466 0.00403 0.0001 2790 328 502 474 0.00396 0.0001 2760 329 512 480 0.00388 0.0001 2740 330 522 487 0.00381 0.0001 2710 331 531 493 0.00374 0.0001 2680 332 541 499 0.00366 0.0001 2660 333 547 505 0.00359 0.0001 2630 334 554 512 0.00351 0.0001 2600 335 558 523 0.00344 0.0001 2580 336 562 534 0.00337 0.0001 2550 337 566 547 0.00329 0.0001 2530 338 570 559 0.00322 0.0001 2500 339 574 570 0.00314 0.0001 2480 340 578 581 0.00307 0.0001 2450 341 581 588 0.003 0.0001 2430 342 584 594 0.00292 0.0001 2410 343 587 601 0.00285 0.0001 2380 344 590 608 0.00277 0.0001 2360 345 587 615 0.0027 0.0001 2340 346 584 621 0.00263 0.0001 2310 347 581 629 0.00255 0.0001 2290 348 578 636 0.00248 0.0001 2270 349 574 645 0.0024 0.0001 2250 350 571 654 0.00233 0.0001 2230 351 567 663 0.00228 0.0001 2210 352 562 672 0.00224 0.0001 2190 353 559 681 0.00219 0.0001 2160 354 555 690 0.00214 0.0001 2140 355 550 699 0.0021 0.0001 2120 356 544 707 0.00205 0.0001 2100 357 534 712 0.00201 0.0001 2090 358 524 716 0.00196 0.0001 2070 359 516 719 0.00191 0.0001 2050 360 507 723 0.00187 0.0001 2030 361 501 726 0.00182 0.0001 2010 362 494 728 0.00177 0.0001 1990 363 488 731 0.00173 0.0001 1970 364 481 733 0.00168 0.0001 1950 365 477 736 0.00163 0.0001 1940 366 474 738 0.00159 0.0001 1920 367 471 741 0.00154 0.0001 1900 368 469 744 0.00149 0.0001 1880 369 470 747 0.00145 0.0001 1870 370 472 750 0.0014 0.0001 1850 371 481 752 0.00136 0.0001 1830 372 490 755 0.00131 0.0001 1820 373 500 758 0.00126 0.0001 1800 374 509 761 0.00122 0.0001 1790 375 520 764 0.00117 0.0001 1770 376 530 767 0.00115 0.0001 1750 377 542 770 0.00112 0.0001 1740 378 554 773 0.0011 0.0001 1720 379 570 776 0.00108 0.0001 1710 380 587 778 0.00105 0.0001 1690 381 607 778 0.00103 0.0001 1680 382 626 778 0.001 0.0001 1660 383 649 787 0.000981 0.0001 1650 384 672 796 0.000958 0.0001 1640 385 698 810 0.000934 0.0001 1620 386 724 824 0.00091 0.0001 1610 387 758 839 0.000887 0.0001 1590 388 793 854 0.000863 0.0001 1580 389 846 876 0.00084 0.0001 1570 390 898 898 0.000816 0.0001 1550 391 957 931 0.000792 0.0001 1540 392 1020 964 0.000769 0.0001 1530 393 1080 995 0.000745 0.0001 1510 394 1140 1030 0.000722 0.0001 1500 395 1190 1050 0.000698 0.0001 1490 396 1240 1080 0.000674 0.0001 1480 397 1290 1110 0.000651 0.0001 1460 398 1330 1140 0.000627 0.0001 1450 399 1380 1170 0.000604 0.0001 1440 400 1430 1200 0.00058 0.0001 1430 401 1470 1230 0.000572 0.0001 1420 402 1520 1260 0.000564 0.0001 1400 403 1590 1310 0.000556 0.0001 1390 404 1650 1360 0.000548 0.0001 1380 405 1770 1400 0.00054 0.0001 1370 406 1900 1450 0.000532 0.0001 1360 407 2080 1490 0.000524 0.0001 1350 408 2260 1540 0.000516 0.0001 1340 409 2380 1580 0.000508 0.0001 1330 410 2500 1630 0.0005 0.0001 1320 411 2590 1670 0.000492 0.0001 1300 412 2680 1720 0.000484 0.0001 1290 413 2740 1780 0.000476 0.0001 1280 414 2810 1830 0.000468 0.0001 1270 415 2800 1890 0.00046 0.0001 1260 416 2790 1950 0.000452 0.0001 1250 417 2780 2010 0.000444 0.0001 1240 418 2760 2070 0.000436 0.0001 1230 419 2670 2120 0.000428 0.0001 1220 420 2570 2180 0.00042 0.0001 1210 421 2440 2240 0.000412 0.0001 1200 422 2310 2300 0.000404 0.0001 1190 423 2160 2390 0.000396 0.0001 1190 424 2010 2470 0.000388 0.0001 1180 425 1880 2520 0.00038 0.0001 1170 426 1750 2580 0.000376 0.0001 1160 427 1630 2630 0.000372 0.0001 1150 428 1520 2680 0.000368 0.0001 1140 429 1420 2760 0.000364 8.28 1130 430 1320 2830 0.00036 8.216 1120 431 1230 2890 0.000356 8.158 1110 432 1150 2960 0.000352 8.069 1110 433 1020 2960 0.000348 7.927 1100 434 885 2960 0.000344 7.832 1090 435 798 2940 0.00034 7.721 1080 436 711 2930 0.000336 7.652 1070 437 675 2810 0.000332 7.623 1060 438 638 2690 0.000328 7.56 1060 439 594 2450 0.000324 7.474 1050 440 549 2210 0.00032 7.383 1040 441 523 2080 0.000316 7.244 1030 442 497 1950 0.000312 7.104 1020 443 466 1730 0.000308 7 1020 444 436 1510 0.000304 6.899 1010 445 422 1390 0.0003 6.811 1000 446 409 1270 0.000296 6.729 994 447 384 1100 0.000292 6.659 986 448 359 928 0.000288 6.571 979 449 348 741 0.000284 6.464 972 450 336 553 0.00028 6.375 965 451 326 444 0.000279 6.291 957 452 315 335 0.000277 6.21 950 453 301 265 0.000276 6.135 943 454 287 194 0.000275 6.049 937 455 276 179 0.000273 5.95 930 456 265 164 0.000272 5.837 923 457 260 152 0.000271 5.751 916 458 254 139 0.000269 5.663 910 459 246 132 0.000268 5.593 903 460 238 125 0.000267 5.523 897 461 230 119 0.000265 5.413 890 462 221 112 0.000264 5.288 884 463 217 108 0.000263 5.144 877 464 213 103 0.000262 4.985 871 465 206 100 0.00026 4.846 865 466 199 97.1 0.000259 4.72 859 467 193 94.2 0.000258 4.594 853 468 187 91.2 0.000256 4.513 846 469 182 88.8 0.000255 4.434 840 470 178 86.5 0.000254 4.327 835 471 174 84.2 0.000252 4.208 829 472 169 82 0.000251 4.084 823 473 165 81.3 0.00025 3.961 817 474 161 80.6 0.000248 3.843 811 475 158 79.9 0.000247 3.732 806 476 154 79.2 0.000247 3.635 800 477 151 78.9 0.000247 3.534 794 478 148 78.5 0.000247 3.452 789 479 146 78.2 0.000247 3.386 783 480 143 77.9 0.000248 3.315 778 481 140 78.8 0.000248 3.261 773 482 138 79.7 0.000248 3.192 767 483 136 80.6 0.000248 3.109 762 484 135 81.5 0.000248 3.013 757 485 133 82.3 0.000248 2.919 752 486 132 83.2 0.000248 2.832 747 487 131 84.2 0.000248 2.75 741 488 129 85.1 0.000249 2.676 736 489 128 87.2 0.000249 2.597 731 490 127 89.3 0.000249 2.515 726 491 125 91.4 0.000249 2.437 722 492 124 93.5 0.000249 2.368 717 493 122 95.7 0.000249 2.298 712 494 120 97.8 0.000249 2.25 707 495 119 99.9 0.000249 2.193 702 496 117 102 0.00025 2.124 698 497 115 104 0.00025 2.06 693 498 114 107 0.00025 1.998 688 499 113 109 0.00025 1.942 684 500 112 112 0.00025 1.906 679 501 111 114 0.000253 1.875 675 502 110 117 0.000256 1.828 670 503 110 120 0.000258 1.776 666 504 109 122 0.000261 1.724 661 505 108 125 0.000264 1.683 657 506 107 127 0.000267 1.648 653 507 107 130 0.00027 1.62 648 508 107 133 0.000272 1.576 644 509 107 135 0.000275 1.534 640 510 107 138 0.000278 1.501 636 511 108 141 0.000281 1.475 632 512 108 144 0.000284 1.457 628 513 109 147 0.000286 1.432 624 514 109 150 0.000289 1.403 619 515 111 154 0.000292 1.368 615 516 112 157 0.000295 1.33 612 517 116 160 0.000298 1.298 608 518 121 163 0.0003 1.27 604 519 125 166 0.000303 1.246 600 520 130 169 0.000306 1.231 596 521 136 173 0.000309 1.211 592 522 142 176 0.000312 1.189 588 523 149 180 0.000314 1.165 585 524 157 184 0.000317 1.145 581 525 165 188 0.00032 1.132 577 526 174 192 0.000325 1.113 574 527 183 197 0.00033 1.091 570 528 193 201 0.000336 1.064 566 529 203 205 0.000341 1.042 563 530 214 209 0.000346 1.031 559 531 224 213 0.000351 1.017 556 532 235 217 0.000356 1.002 552 533 243 221 0.000362 0.991 549 534 251 225 0.000367 0.984 546 535 259 229 0.000372 0.978 542 536 266 233 0.000377 0.97 539 537 272 237 0.000382 0.951 535 538 277 241 0.000388 0.929 532 539 281 245 0.000393 0.913 529 540 285 249 0.000398 0.896 526 541 285 254 0.000403 0.88 522 542 285 258 0.000408 0.864 519 543 282 262 0.000414 0.849 516 544 279 266 0.000419 0.84 513 545 273 270 0.000424 0.833 510 546 267 275 0.000429 0.828 507 547 258 278 0.000434 0.822 504 548 250 281 0.00044 0.805 500 549 240 284 0.000445 0.785 497 550 230 286 0.00045 0.773 494 551 221 288 0.000464 0.763 491 552 212 290 0.000477 0.76 489 553 205 291 0.000491 0.757 486 554 197 292 0.000504 0.746 483 555 191 292 0.000518 0.733 480 556 185 292 0.000532 0.724 477 557 182 291 0.000545 0.718 474 558 179 290 0.000559 0.71 471 559 177 289 0.000572 0.704 468 560 175 288 0.000586 0.698 466 561 175 284 0.0006 0.69 463 562 175 280 0.000613 0.682 460 563 178 275 0.000627 0.673 457 564 182 271 0.00064 0.662 455 565 189 266 0.000654 0.653 452 566 195 261 0.000668 0.647 449 567 205 256 0.000681 0.641 447 568 215 251 0.000695 0.636 444 569 227 246 0.000708 0.63 442 570 238 241 0.000722 0.629 439 571 251 237 0.000736 0.633 436 572 263 232 0.000749 0.639 434 573 274 228 0.000763 0.632 431 574 285 223 0.000776 0.613 429 575 291 219 0.00079 0.589 426 576 297 215 0.00085 0.573 424 577 295 210 0.000911 0.562 422 578 293 206 0.000971 0.563 419 579 281 202 0.00103 0.566 417 580 268 198 0.00109 0.566 414 581 250 195 0.00115 0.564 412 582 232 191 0.00121 0.562 410 583 209 187 0.00127 0.562 407 584 185 184 0.00133 0.557 405 585 164 180 0.00139 0.548 403 586 142 176 0.00145 0.541 400 587 124 171 0.00151 0.53 398 588 106 166 0.00158 0.52 396 589 91.5 159 0.00164 0.512 394 590 77.1 152 0.0017 0.502 391 591 66.6 144 0.00176 0.493 389 592 56.1 136 0.00182 0.488 387 593 48.6 129 0.00188 0.485 385 594 41.1 121 0.00194 0.486 383 595 35.8 113 0.002 0.487 381 596 30.4 106 0.00206 0.479 378 597 27.3 98.7 0.00212 0.472 376 598 24.1 91.3 0.00218 0.467 374 599 20.6 85 0.00224 0.462 372 600 17.1 78.6 0.0023 0.466 370 601 15.7 75.8 0.00232 0.471 368 602 14.3 72.9 0.00234 0.479 366 603 12.8 70.1 0.00236 0.487 364 604 11.4 67.3 0.00238 0.487 362 605 10.5 64.5 0.0024 0.484 360 606 9.58 61.7 0.00242 0.48 358 607 9.2 58.9 0.00244 0.475 356 608 8.82 56.1 0.00246 0.47 354 609 8.44 53.3 0.00248 0.469 352 610 8.06 50.6 0.0025 0.464 350 611 7.69 48.3 0.00252 0.458 348 612 7.31 46 0.00254 0.454 346 613 6.93 43.8 0.00256 0.442 345 614 6.55 41.6 0.00258 0.427 343 615 6.25 40.4 0.0026 0.422 341 616 5.94 39.3 0.00262 0.423 339 617 5.72 38.2 0.00264 0.43 337 618 5.49 37.1 0.00266 0.437 335 619 5.27 36 0.00268 0.435 334 620 5.04 34.9 0.0027 0.43 332 621 4.82 34 0.00272 0.425 330 622 4.59 33.2 0.00274 0.433 328 623 4.37 32.4 0.00276 0.44 327 624 4.14 31.6 0.00278 0.438 325 625 3.97 30.9 0.0028 0.432 323 626 3.79 30.1 0.00282 0.426 321 627 3.66 29.4 0.00283 0.424 320 628 3.53 28.7 0.00285 0.426 318 629 3.4 28.2 0.00286 0.428 316 630 3.27 27.6 0.00288 0.428 315 631 3.14 27 0.0029 0.429 313 632 3.01 26.4 0.00291 0.437 311 633 2.87 25.9 0.00293 0.444 310 634 2.74 25.3 0.00294 0.44 308 635 2.65 25 0.00296 0.431 306 636 2.56 24.6 0.00298 0.42 305 637 2.51 24.3 0.00299 0.422 303 638 2.47 24 0.00301 0.433 302 639 2.42 23.6 0.00302 0.446 300 640 2.37 23.3 0.00304 0.452 299 641 2.32 22.9 0.00306 0.45 297 642 2.27 22.6 0.00307 0.449 295 643 2.22 22.2 0.00309 0.453 294 644 2.17 21.9 0.0031 0.46 292 645 2.13 21.6 0.00312 0.465 291 646 2.09 21.2 0.00314 0.464 289 647 2.06 20.9 0.00315 0.464 288 648 2.03 20.7 0.00317 0.464 286 649 2 20.4 0.00318 0.465 285 650 1.97 20.1 0.0032 0.471 283 651 1.94 19.8 0.00324 0.472 282 652 1.91 19.5 0.00328 0.467 281 653 1.88 19.2 0.00331 0.464 279 654 1.85 18.9 0.00335 0.457 278 655 1.82 18.6 0.00339 0.448 276 656 1.79 18.4 0.00343 0.438 275 657 1.77 18.1 0.00347 0.428 274 658 1.74 17.8 0.0035 0.424 272 659 1.73 17.5 0.00354 0.422 271 660 1.71 17.3 0.00358 0.418 269 661 1.7 17 0.00362 0.414 268 662 1.68 16.8 0.00366 0.413 267 663 1.67 16.6 0.00369 0.414 265 664 1.65 16.4 0.00373 0.419 264 665 1.64 16.1 0.00377 0.428 263 666 1.62 15.9 0.00381 0.439 261 667 1.61 15.7 0.00385 0.447 260 668 1.6 15.4 0.00388 0.452 259 669 1.59 15.2 0.00392 0.453 258 670 1.57 15 0.00396 0.45 256 671 1.56 14.7 0.004 0.452 255 672 1.55 14.5 0.00404 0.457 254 673 1.54 14.3 0.00407 0.462 252 674 1.53 14.1 0.00411 0.463 251 675 1.52 13.9 0.00415 0.457 250 676 1.51 13.7 0.00422 0.446 249 677 1.5 13.5 0.0043 0.433 248 678 1.5 13.3 0.00437 0.422 246 679 1.49 13.1 0.00445 0.413 245 680 1.49 12.9 0.00452 0.406 244 681 1.48 12.7 0.00459 0.398 243 682 1.48 12.5 0.00467 0.387 242 683 1.47 12.3 0.00474 0.375 240 684 1.47 12.1 0.00482 0.37 239 685 1.47 11.9 0.00489 0.369 238 686 1.46 11.7 0.00496 0.366 237 687 1.47 11.5 0.00504 0.361 236 688 1.47 11.3 0.00511 0.354 235 689 1.47 11.2 0.00519 0.348 233 690 1.48 11 0.00526 0.342 232 691 1.48 10.9 0.00533 0.338 231 692 1.49 10.7 0.00541 0.335 230 693 1.49 10.6 0.00548 0.331 229 694 1.5 10.4 0.00556 0.328 228 695 1.5 10.3 0.00563 0.324 227 696 1.51 10.2 0.0057 0.321 226 697 1.52 10 0.00578 0.324 225 698 1.53 9.89 0.00585 0.327 224 699 1.54 9.75 0.00593 0.325 223 700 1.55 9.61 0.006 0.323 221 701 1.56 9.47 0.0064 0.32 220 702 1.57 9.32 0.00679 0.319 219 703 1.59 9.18 0.00719 0.322 218 704 1.6 9.04 0.00758 0.326 217 705 1.61 8.9 0.00798 0.323 216 706 1.62 8.75 0.00838 0.318 215 707 1.64 8.62 0.00877 0.313 214 708 1.65 8.48 0.00917 0.31 213 709 1.67 8.36 0.00956 0.311 212 710 1.68 8.25 0.00996 0.315 211 711 1.7 8.13 0.0104 0.32 210 712 1.71 8.02 0.0108 0.321 209 713 1.73 7.9 0.0111 0.32 208 714 1.74 7.79 0.0115 0.321 207 715 1.76 7.67 0.0119 0.326 206 716 1.78 7.56 0.0123 0.334 205 717 1.8 7.44 0.0127 0.343 204 718 1.82 7.33 0.0131 0.351 204 719 1.84 7.21 0.0135 0.358 203 720 1.86 7.1 0.0139 0.367 202 721 1.88 6.99 0.0143 0.376 201 722 1.91 6.88 0.0147 0.383 200 723 1.93 6.77 0.0151 0.39 199 724 1.95 6.66 0.0155 0.401 198 725 1.97 6.55 0.0159 0.415 197 726 1.99 6.45 0.0163 0.43 196 727 2.02 6.31 0.0167 0.447 195 728 2.04 6.17 0.0171 0.463 194 729 2.06 6.04 0.0175 0.48 193 730 2.09 5.9 0.0179 0.499 193 731 2.11 5.9 0.0183 0.516 192 732 2.14 5.9 0.0187 0.535 191 733 2.16 5.9 0.0191 0.552 190 734 2.18 5.9 0.0195 0.564 189 735 2.21 5.9 0.0199 0.576 188 736 2.24 5.9 0.0203 0.589 187 737 2.28 5.9 0.0207 0.6 187 738 2.32 5.89 0.0212 0.616 186 739 2.35 5.93 0.0216 0.636 185 740 2.39 5.98 0.022 0.654 184 741 2.42 6.1 0.0224 0.68 183 742 2.46 6.22 0.0228 0.707 182 743 2.5 6.34 0.0232 0.735 182 744 2.53 6.47 0.0236 0.768 181 745 2.57 6.62 0.024 0.801 180 746 2.61 6.78 0.0244 0.837 179 747 2.65 6.96 0.0248 0.874 178 748 2.69 7.14 0.0252 0.908 178 749 2.73 7.33 0.0256 0.941 177 750 2.77 7.52 0.026 0.972 176 751 2.81 7.82 0.0259 1.001 175 752 2.86 8.11 0.0258 1.03 174 753 2.9 8.19 0.0258 1.059 174 754 2.94 8.26 0.0257 1.089 173 755 2.97 8.31 0.0256 1.12 172 756 3.01 8.36 0.0255 1.155 171 757 3.04 8.36 0.0254 1.19 171 758 3.07 8.36 0.0254 1.227 170 759 3.11 8.32 0.0253 1.258 169 760 3.14 8.29 0.0252 1.278 168 761 3.17 8.18 0.0251 1.289 168 762 3.2 8.08 0.025 1.29 167 763 3.23 7.95 0.025 1.273 166 764 3.27 7.82 0.0249 1.249 166 765 3.3 7.68 0.0248 1.206 165 766 3.33 7.55 0.0247 1.153 164 767 3.37 7.42 0.0246 1.089 163 768 3.41 7.29 0.0246 1.021 163 769 3.44 7.16 0.0245 0.948 162 770 3.48 7.02 0.0244 0.871 161 771 3.52 6.89 0.0243 0.793 161 772 3.55 6.76 0.0242 0.719 160 773 3.59 6.63 0.0242 0.653 159 774 3.63 6.5 0.0241 0.596 159 775 3.66 6.36 0.024 0.553 158 776 3.69 6.23 0.0238 0.515 157 777 3.72 6.1 0.0237 0.481 156 778 3.75 5.97 0.0235 0.451 156 779 3.77 5.86 0.0234 0.426 155 780 3.8 5.76 0.0232 0.409 154 781 3.83 5.65 0.023 0.391 154 782 3.86 5.55 0.0229 0.378 153 783 3.89 5.44 0.0227 0.366 153 784 3.91 5.34 0.0226 0.36 152 785 3.94 5.23 0.0224 0.357 151 786 3.96 5.13 0.0222 0.355 151 787 3.98 5.03 0.0221 0.353 150 788 4.01 4.94 0.0219 0.349 149 789 4.03 4.85 0.0218 0.346 149 790 4.05 4.77 0.0216 0.346 148 791 4.07 4.69 0.0214 0.347 147 792 4.09 4.6 0.0213 0.347 147 793 4.11 4.52 0.0211 0.347 146 794 4.13 4.44 0.021 0.352 146 795 4.17 4.37 0.0208 0.359 145 796 4.21 4.3 0.0206 0.369 144 797 4.27 4.24 0.0205 0.379 144 798 4.32 4.19 0.0203 0.387 143 799 4.35 4.13 0.0202 0.393 143 800 4.37 4.08 0.02 0.403 142 801 4.4 4.03 0.02 0.413 141 802 4.43 3.98 0.02 0.424 141 803 4.46 3.97 0.02 0.434 140 804 4.48 3.95 0.0199 0.442 140 805 4.5 3.93 0.0199 0.454 139 806 4.52 3.91 0.0199 0.467 138 807 4.55 3.89 0.0199 0.482 138 808 4.58 3.87 0.0199 0.497 137 809 4.61 3.86 0.0199 0.511 137 810 4.63 3.84 0.0199 0.527 136 811 4.65 3.83 0.0203 0.547 136 812 4.67 3.81 0.0207 0.567 135 813 4.69 3.8 0.0211 0.583 135 814 4.71 3.78 0.0215 0.594 134 815 4.73 3.77 0.0219 0.603 133 816 4.75 3.76 0.0223 0.615 133 817 4.79 3.74 0.0227 0.633 132 818 4.83 3.73 0.0231 0.654 132 819 4.87 3.72 0.0235 0.674 131 820 4.91 3.71 0.0239 0.691 131 821 4.94 3.71 0.0247 0.708 130 822 4.98 3.71 0.0255 0.724 130 823 5.02 3.71 0.0264 0.74 129 824 5.06 3.71 0.0272 0.758 129 825 5.09 3.71 0.028 0.775 128 826 5.12 3.71 0.0282 0.786 128 827 5.14 3.71 0.0284 0.796 127 828 5.17 3.71 0.0286 0.799 127 829 5.19 3.71 0.0289 0.802 126 830 5.22 3.71 0.0291 0.803 126 831 5.24 3.71 0.0296 0.803 125 832 5.26 3.71 0.0302 0.801 125 833 5.29 3.71 0.0308 0.794 124 834 5.31 3.71 0.0313 0.785 124 835 5.34 3.71 0.0319 0.775 123 836 5.36 3.71 0.0325 0.764 123 837 5.39 3.71 0.033 0.757 122 838 5.42 3.71 0.0336 0.751 122 839 5.44 3.71 0.0341 0.739 121 840 5.47 3.71 0.0347 0.726 121 841 5.5 3.71 0.0355 0.715 120 842 5.53 3.71 0.0364 0.703 120 843 5.56 3.71 0.0372 0.692 119 844 5.58 3.71 0.038 0.685 119 845 5.6 3.7 0.0389 0.678 118 846 5.62 3.7 0.0397 0.669 118 847 5.63 3.7 0.0405 0.661 117 848 5.64 3.7 0.0413 0.651 117 849 5.65 3.7 0.0422 0.643 116 850 5.67 3.7 0.043 0.637 116 851 5.68 3.7 0.0434 0.633 116 852 5.69 3.7 0.0438 0.632 115 853 5.7 3.7 0.0441 0.631 115 854 5.71 3.7 0.0445 0.633 114 855 5.73 3.7 0.0449 0.639 114 856 5.74 3.7 0.0453 0.647 113 857 5.77 3.7 0.0456 0.656 113 858 5.8 3.71 0.046 0.662 112 859 5.82 3.71 0.0464 0.666 112 860 5.85 3.72 0.0468 0.674 112 861 5.87 3.72 0.0473 0.68 111 862 5.9 3.73 0.0478 0.69 111 863 5.92 3.73 0.0483 0.705 110 864 5.95 3.74 0.0489 0.724 110 865 5.97 3.74 0.0494 0.751 109 866 5.99 3.75 0.0499 0.786 109 867 6 3.75 0.0504 0.822 109 868 6.01 3.76 0.051 0.86 108 869 6.03 3.77 0.0515 0.899 108 870 6.04 3.78 0.052 0.938 107 871 6.05 3.79 0.0528 0.979 107 872 6.07 3.8 0.0536 1.022 107 873 6.08 3.81 0.0544 1.074 106 874 6.09 3.82 0.0552 1.133 106 875 6.11 3.83 0.056 1.198 105 876 6.12 3.85 0.056 1.264 105 877 6.13 3.86 0.056 1.345 105 878 6.15 3.87 0.056 1.43 104 879 6.16 3.88 0.056 1.527 104 880 6.18 3.89 0.056 1.636 103 881 6.19 3.9 0.0564 1.752 103 882 6.21 3.91 0.0569 1.867 103 883 6.22 3.92 0.0573 1.992 102 884 6.24 3.93 0.0578 2.121 102 885 6.25 3.94 0.0582 2.262 101 886 6.27 3.94 0.0587 2.414 101 887 6.28 3.95 0.0591 2.581 101 888 6.29 3.96 0.0595 2.754 100 889 6.3 3.97 0.06 2.932 99.9 890 6.31 3.98 0.0604 3.116 99.6 891 6.32 3.99 0.0612 3.305 99.2 892 6.33 4 0.0619 3.491 98.8 893 6.34 4.01 0.0627 3.674 98.4 894 6.35 4.02 0.0635 3.833 98.1 895 6.36 4.03 0.0642 3.983 97.7 896 6.37 4.04 0.065 4.121 97.4 897 6.38 4.05 0.0657 4.256 97 898 6.39 4.06 0.0665 4.384 96.6 899 6.4 4.07 0.0672 4.506 96.3 900 6.42 4.08 0.068 4.633 95.9 901 6.43 4.09 0.0685 4.766 95.6 902 6.44 4.1 0.069 4.915 95.2 903 6.45 4.1 0.0695 5.078 94.9 904 6.46 4.11 0.07 5.267 94.5 905 6.47 4.12 0.0705 5.472 94.2 906 6.48 4.12 0.0709 5.721 93.8 907 6.48 4.13 0.0714 5.994 93.5 908 6.49 4.13 0.0719 6.316 93.1 909 6.49 4.14 0.0724 6.663 92.8 910 6.5 4.15 0.0729 7.046 92.5 911 6.51 4.15 0.0765 7.438 92.1 912 6.51 4.16 0.0802 7.837 91.8 913 6.52 4.16 0.0838 8.234 91.4 914 6.53 4.17 0.0875 8.621 91.1 915 6.53 4.17 0.0911 8.994 90.8 916 6.54 4.17 0.0947 9.354 90.5 917 6.54 4.17 0.0984 9.683 90.1 918 6.55 4.16 0.102 10 89.8 919 6.55 4.16 0.106 10.32 89.5 920 6.55 4.16 0.109 10.65 89.2 921 6.56 4.16 0.116 10.99 88.8 922 6.56 4.16 0.123 11.33 88.5 923 6.57 4.16 0.13 11.67 88.2 924 6.57 4.16 0.137 12 87.9 925 6.57 4.15 0.144 12.31 87.6 926 6.57 4.14 0.15 12.6 87.2 927 6.56 4.12 0.156 12.82 86.9 928 6.56 4.11 0.161 12.99 86.6 929 6.55 4.1 0.167 13.07 86.3 930 6.54 4.09 0.173 13.1 86 931 6.54 4.06 0.182 12.99 85.7 932 6.53 4.03 0.192 12.83 85.4 933 6.52 3.99 0.201 12.53 85.1 934 6.52 3.95 0.211 12.18 84.8 935 6.51 3.91 0.22 11.75 84.5 936 6.51 3.87 0.23 11.26 84.2 937 6.51 3.83 0.239 10.7 83.9 938 6.51 3.79 0.248 10.08 83.6 939 6.5 3.75 0.258 9.433 83.3 940 6.5 3.71 0.267 8.754 83 941 6.5 3.67 0.28 8.088 82.7 942 6.5 3.63 0.292 7.446 82.4 943 6.49 3.59 0.304 6.822 82.1 944 6.49 3.54 0.316 6.25 81.8 945 6.49 3.48 0.329 5.704 81.5 946 6.48 3.43 0.341 5.234 81.3 947 6.47 3.38 0.353 4.802 81 948 6.46 3.33 0.365 4.445 80.7 949 6.46 3.28 0.378 4.109 80.4 950 6.45 3.22 0.39 3.799 80.1 951 6.44 3.17 0.393 3.519 79.8 952 6.43 3.12 0.396 3.274 79.6 953 6.42 3.09 0.399 3.046 79.3 954 6.41 3.05 0.402 2.852 79 955 6.4 3.01 0.405 2.666 78.7 956 6.39 2.97 0.408 2.504 78.5 957 6.38 2.93 0.411 2.358 78.2 958 6.37 2.89 0.414 2.242 77.9 959 6.36 2.85 0.417 2.133 77.6 960 6.35 2.81 0.42 2.047 77.4 961 6.34 2.78 0.423 1.975 77.1 962 6.33 2.74 0.426 1.917 76.8 963 6.32 2.69 0.429 1.86 76.6 964 6.31 2.65 0.432 1.808 76.3 965 6.3 2.59 0.435 1.753 76 966 6.28 2.53 0.438 1.693 75.8 967 6.27 2.48 0.441 1.639 75.5 968 6.25 2.42 0.444 1.589 75.3 969 6.24 2.36 0.447 1.554 75 970 6.22 2.3 0.45 1.528 74.7 971 6.21 2.26 0.45 1.51 74.5 972 6.19 2.22 0.45 1.491 74.2 973 6.18 2.19 0.45 1.463 74 974 6.16 2.15 0.45 1.431 73.7 975 6.14 2.12 0.45 1.413 73.5 976 6.13 2.08 0.446 1.408 73.2 977 6.1 2.05 0.442 1.414 73 978 6.08 2.01 0.438 1.421 72.7 979 6.06 1.97 0.434 1.423 72.5 980 6.04 1.93 0.43 1.417 72.2 981 6.02 1.88 0.428 1.407 72 982 6 1.84 0.426 1.406 71.7 983 5.98 1.8 0.424 1.42 71.5 984 5.95 1.76 0.422 1.441 71.3 985 5.93 1.72 0.42 1.481 71 986 5.9 1.68 0.418 1.524 70.8 987 5.87 1.64 0.416 1.564 70.5 988 5.84 1.6 0.414 1.607 70.3 989 5.81 1.56 0.412 1.652 70.1 990 5.78 1.52 0.41 1.716 69.8 991 5.75 1.48 0.405 1.793 69.6 992 5.72 1.43 0.4 1.891 69.4 993 5.69 1.39 0.395 1.994 69.1 994 5.66 1.35 0.39 2.087 68.9 995 5.63 1.31 0.385 2.178 68.7 996 5.6 1.27 0.38 2.272 68.4 997 5.57 1.23 0.375 2.366 68.2 998 5.54 1.19 0.37 2.464 68 999 5.51 1.15 0.365 2.56 67.8 1000 5.48 1.11 0.36 2.654 67.5 diff --git a/Modules/PhotoacousticsLib/files.cmake b/Modules/PhotoacousticsLib/files.cmake deleted file mode 100644 index 5bc7c84dfc..0000000000 --- a/Modules/PhotoacousticsLib/files.cmake +++ /dev/null @@ -1,65 +0,0 @@ -SET(H_FILES - include/mitkPAPropertyCalculator.h - include/mitkPAVector.h - include/mitkPATissueGeneratorParameters.h - include/mitkPAInSilicoTissueVolume.h - include/mitkPATissueGenerator.h - include/mitkPAVesselTree.h - include/mitkPAVessel.h - include/mitkPAVesselMeanderStrategy.h - include/mitkPANoiseGenerator.h - include/mitkPAVolume.h - include/mitkPAComposedVolume.h - include/mitkPASlicedVolumeGenerator.h - include/mitkPAProbe.h - include/mitkPALightSource.h - include/mitkPAIOUtil.h - include/mitkPAMonteCarloThreadHandler.h - include/mitkPASimulationBatchGenerator.h - include/mitkPAFluenceYOffsetPair.h - include/mitkPAVolumeManipulator.h - include/mitkPAVesselProperties.h - include/mitkPASimulationBatchGeneratorParameters.h - include/mitkPAExceptions.h - include/mitkPASpectralUnmixingFilterBase.h - include/mitkPALinearSpectralUnmixingFilter.h - include/mitkPASpectralUnmixingSO2.h - include/mitkPASpectralUnmixingFilterLagrange.h - include/mitkPASpectralUnmixingFilterSimplex.h - include/mitkPASpectralUnmixingFilterVigra.h -) - -set(CPP_FILES - Domain/Vessel/mitkPAVesselTree.cpp - Domain/Vessel/mitkPAVessel.cpp - Domain/Vessel/mitkPAVesselMeanderStrategy.cpp - Domain/Vessel/mitkPAVesselProperties.cpp - Domain/Volume/mitkPAInSilicoTissueVolume.cpp - Domain/Volume/mitkPAVolume.cpp - Domain/Volume/mitkPAComposedVolume.cpp - Domain/Volume/mitkPAFluenceYOffsetPair.cpp - Generator/mitkPATissueGenerator.cpp - Generator/mitkPANoiseGenerator.cpp - Generator/mitkPASlicedVolumeGenerator.cpp - Generator/mitkPASimulationBatchGenerator.cpp - Generator/mitkPASimulationBatchGeneratorParameters.cpp - IO/mitkPAIOUtil.cpp - Utils/mitkPAPropertyCalculator.cpp - Utils/mitkPAVector.cpp - Utils/mitkPATissueGeneratorParameters.cpp - Utils/mitkPAVolumeManipulator.cpp - Utils/ProbeDesign/mitkPAProbe.cpp - Utils/ProbeDesign/mitkPALightSource.cpp - Utils/Thread/mitkPAMonteCarloThreadHandler.cpp - SUFilter/mitkPASpectralUnmixingFilterBase.cpp - SUFilter/mitkPALinearSpectralUnmixingFilter.cpp - SUFilter/mitkPASpectralUnmixingSO2.cpp - SUFilter/mitkPASpectralUnmixingFilterSimplex.cpp - SUFilter/mitkPASpectralUnmixingFilterVigra.cpp - SUFilter/mitkPASpectralUnmixingFilterLagrange.cpp - Utils/mitkPAVesselDrawer.cpp -) - -set(RESOURCE_FILES - spectralLIB.dat -) diff --git a/Modules/PhotoacousticsLib/include/mitkPAComposedVolume.h b/Modules/PhotoacousticsLib/include/mitkPAComposedVolume.h deleted file mode 100644 index da76c63790..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAComposedVolume.h +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICCOMPOSEDVOLUME_H -#define MITKPHOTOACOUSTICCOMPOSEDVOLUME_H - -#include - -#include -#include -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - /** - * @brief The ComposedVolume class provides the means to systematically collect nrrd files that correspond to - * different simulation slices of the same InSilicoTissueVolume. - * - * An instance of this class is needed for the SlicedVolumeGenerator - */ - class MITKPHOTOACOUSTICSLIB_EXPORT ComposedVolume : public itk::Object - { - public: - mitkClassMacroItkParent(ComposedVolume, itk::Object); - mitkNewMacro1Param(Self, InSilicoTissueVolume::Pointer); - - /** - * @brief fluenceYOffsetPair - * - * @param fluenceYOffsetPair - */ - void AddSlice(mitk::pa::FluenceYOffsetPair::Pointer fluenceYOffsetPair); - - /** - * @brief GetNumberOfFluenceComponents - * @return the number of fluence components encapsuled by this ComposedVolume. - */ - int GetNumberOfFluenceComponents(); - - /** - * @brief GetFluenceValue - * @param fluenceComponent - * @param x - * @param y - * @param z - * @return the fluence value for a specific fluence component index at the given 3D location. - */ - double GetFluenceValue(int fluenceComponent, int x, int y, int z); - - /** - * @brief GetYOffsetForFluenceComponentInPixels - * @param fluenceComponent - * @return the y-offset value for a given fluence component index. - */ - int GetYOffsetForFluenceComponentInPixels(int fluenceComponent); - - void Sort(); - - itkGetMacro(GroundTruthVolume, InSilicoTissueVolume::Pointer); - - protected: - ComposedVolume(InSilicoTissueVolume::Pointer groundTruthVolume); - ~ComposedVolume() override; - - private: - int m_FluenceComponents; - InSilicoTissueVolume::Pointer m_GroundTruthVolume; - std::vector m_FluenceValues; - }; - } -} - -#endif // MITKPHOTOACOUSTICCOMPOSEDVOLUME_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAExceptions.h b/Modules/PhotoacousticsLib/include/mitkPAExceptions.h deleted file mode 100644 index 5eb8da3baa..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAExceptions.h +++ /dev/null @@ -1,66 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKEXCEPTIONS_H -#define MITKEXCEPTIONS_H - -#include - -#include - -//std -#include -#include - -namespace mitk { - namespace pa { - /** - *@brief this exception is thrown if an invalid input occurs - */ - class MITKPHOTOACOUSTICSLIB_EXPORT InvalidInputException : public std::exception - { - std::string m_InvalidParameter; - public: - InvalidInputException(std::string invalidparameter) - { - m_InvalidParameter = invalidparameter; - MITK_ERROR << GetFullMessage(); - } - - const std::string GetFullMessage() const throw() - { - return "InvalidInputException: " + m_InvalidParameter; - } - }; - - /** - *@brief this exception is thrown if an invalid value is supposed to be processed - */ - class MITKPHOTOACOUSTICSLIB_EXPORT InvalidValueException : public std::exception - { - std::string m_ValueType; - public: - InvalidValueException(std::string valueType) - { - m_ValueType = valueType; - MITK_ERROR << GetFullMessage(); - } - - const std::string GetFullMessage() const throw() - { - return "InvalidValueException: " + m_ValueType; - } - }; - } -} - -#endif // MITKEXCEPTIONS_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAFluenceYOffsetPair.h b/Modules/PhotoacousticsLib/include/mitkPAFluenceYOffsetPair.h deleted file mode 100644 index 1d73fd4d94..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAFluenceYOffsetPair.h +++ /dev/null @@ -1,59 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPAFLUENCEYOFFSETPAIR_H -#define MITKPAFLUENCEYOFFSETPAIR_H - -#include -#include - -#include "mitkCommon.h" -#include "itkLightObject.h" -#include - -namespace mitk -{ - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT FluenceYOffsetPair : public itk::LightObject - { - public: - mitkClassMacroItkParent(FluenceYOffsetPair, itk::LightObject); - mitkNewMacro2Param(Self, mitk::pa::Volume::Pointer, double); - - FluenceYOffsetPair(const FluenceYOffsetPair::Pointer other); - - const FluenceYOffsetPair &operator=(const FluenceYOffsetPair::Pointer other) - { - if (this == other) - return *this; - - m_FluenceValue = other->GetFluenceValue(); - m_YOffsetInCentimeters = other->GetYOffsetInCentimeters(); - - return *this; - } - - mitk::pa::Volume::Pointer GetFluenceValue() const; - double GetYOffsetInCentimeters() const; - - private: - FluenceYOffsetPair(mitk::pa::Volume::Pointer fluenceValue, double yOffset); - - ~FluenceYOffsetPair() override; - - mitk::pa::Volume::Pointer m_FluenceValue; - double m_YOffsetInCentimeters; - }; - } -} - -#endif // MITKPHOTOACOUSTICCOMPOSEDVOLUME_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAIOUtil.h b/Modules/PhotoacousticsLib/include/mitkPAIOUtil.h deleted file mode 100644 index d2a5d01b19..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAIOUtil.h +++ /dev/null @@ -1,120 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICIO_H -#define MITKPHOTOACOUSTICIO_H - -#include "MitkPhotoacousticsLibExports.h" - -#include -#include -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -#include "mitkPAVolume.h" -#include -#include - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT IOUtil final - { - public: - - struct Position - { - int x, z; - - bool operator <(const Position& rhs) const - { - return (x < rhs.x || ((x == rhs.x) && z < rhs.z)); - } - }; - - /** - * @brief LoadFluenceContributionMaps loads multiple nrrd files from a given folder - * and sorts them into a position map if such meta information is available in - * the filename. - * - * As this method was specifically designed to load many fluence files, the - * naming convention for the position values is: - * - * *_pN,N,NFluence*.nrrd - * - * @param foldername - * @param blur - * @param progress - * @param log10 - * - * @return - */ - static std::map LoadFluenceContributionMaps( - std::string foldername, double blur, int* progress, bool log10 = false); - - /** - * @brief loads a nrrd file from a given filename. - * @param filename - * @param sigma - * @return nullptr if the given filename was invalid. - */ - static Volume::Pointer LoadNrrd(std::string filename, double sigma = 0); - - /** - *@brief returns the number of .nrrd files in a given directory - */ - static int GetNumberOfNrrdFilesInDirectory(std::string directory); - - /** - *@brief returns a list of all .nrrd files in a given directory - */ - static std::vector GetListOfAllNrrdFilesInDirectory( - std::string directory, bool keepFileFormat = false); - - /** - *@brief convenience method to check wether a given strings ends on a given substring. - *@return false if the substring is longer than the string or if the strings are empty. - */ - static bool DoesFileHaveEnding(std::string const &fullString, std::string const &ending); - - /** - *@brief returns all child folders from a folder if there is no .nrrd file in the folder - * If there IS a .nrrd file in the folder this method will return the given folder path. - */ - static std::vector GetAllChildfoldersFromFolder(std::string folderPath); - - /** - *@brief loads an in silico tissue volume from a saved nrrd file. - */ - static InSilicoTissueVolume::Pointer LoadInSilicoTissueVolumeFromNrrdFile(std::string filePath); - - /** - * @brief LoadFluenceSimulation - * Adds a MC Simulation nrrd file to this composed volume. - * The given file needs to contain the meta information "y-offset". - * This method ensures that all added slices are in the correct order - * corresponding to their y-offset. - * - * @param fluenceSimulation path to the nrrd file on hard drive - */ - static FluenceYOffsetPair::Pointer LoadFluenceSimulation(std::string fluenceSimulation); - - private: - - IOUtil(); - ~IOUtil(); - }; - } -} -#endif // MITKPHOTOACOUSTICIO_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAInSilicoTissueVolume.h b/Modules/PhotoacousticsLib/include/mitkPAInSilicoTissueVolume.h deleted file mode 100644 index f72151ada8..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAInSilicoTissueVolume.h +++ /dev/null @@ -1,160 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICVOLUME_H -#define MITKPHOTOACOUSTICVOLUME_H - -#include -#include -#include -#include -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT InSilicoTissueVolume : public itk::LightObject - { - public: - mitkClassMacroItkParent(InSilicoTissueVolume, itk::LightObject); - mitkNewMacro2Param(Self, TissueGeneratorParameters::Pointer, std::mt19937*); - - enum SegmentationType - { - AIR = -1, - BACKGROUND = 0, - VESSEL = 1, - FAT = 2, - SKIN = 3 - }; - - /** - * @brief ConvertToMitkImage - * @return a pointer to an mitk image containing this volume. - */ - mitk::Image::Pointer ConvertToMitkImage(); - - /** - * @brief SetVolumeValues sets the values for aborption, scattering and anisotropy at the specified voxel location. - * - * @param x - * @param y - * @param z - * @param absorption - * @param scattering - * @param anisotropy - * @param segmentType - */ - void SetVolumeValues(int x, int y, int z, double absorption, double scattering, double anisotropy, SegmentationType segmentType); - - /** - * @brief SetVolumeValues sets the values for aborption, scattering and anisotropy at the specified voxel location. - * - * @param x - * @param y - * @param z - * @param absorption - * @param scattering - * @param anisotropy - */ - void SetVolumeValues(int x, int y, int z, double absorption, double scattering, double anisotropy); - - /** - * @brief IsInsideVolume - * - * @param x - * @param y - * @param z - * @return true if the voxel location is inside the volume - */ - bool IsInsideVolume(int x, int y, int z); - - /** - * @brief AddDoubleProperty adds a persistent property to the volume, which will be exported to the mitk image. - * - * @param label - * @param value - */ - void AddDoubleProperty(std::string label, double value); - - /** - * @brief AddIntProperty adds a persistent property to the volume, which will be exported to the mitk image. - * - * @param label - * @param value - */ - void AddIntProperty(std::string label, int value); - - Volume::Pointer GetAbsorptionVolume(); - Volume::Pointer GetScatteringVolume(); - Volume::Pointer GetAnisotropyVolume(); - Volume::Pointer GetSegmentationVolume(); - - void SetAbsorptionVolume(Volume::Pointer volume); - void SetScatteringVolume(Volume::Pointer volume); - void SetAnisotropyVolume(Volume::Pointer volume); - void SetSegmentationVolume(Volume::Pointer volume); - - double GetSpacing(); - void SetSpacing(double spacing); - - void FinalizeVolume(); - itkGetMacro(TissueParameters, TissueGeneratorParameters::Pointer); - itkGetMacro(TDim, unsigned int); - - static InSilicoTissueVolume::Pointer New(mitk::pa::Volume::Pointer absorptionVolume, - Volume::Pointer scatteringVolume, - Volume::Pointer anisotropyVolume, - Volume::Pointer segmentationVolume, - TissueGeneratorParameters::Pointer tissueParameters, - mitk::PropertyList::Pointer propertyList); - - protected: - InSilicoTissueVolume(TissueGeneratorParameters::Pointer parameters, std::mt19937* rng); - InSilicoTissueVolume(Volume::Pointer absorptionVolume, - Volume::Pointer scatteringVolume, - Volume::Pointer anisotropyVolume, - Volume::Pointer segmentationVolume, - TissueGeneratorParameters::Pointer tissueParameters, - mitk::PropertyList::Pointer propertyList); - ~InSilicoTissueVolume() override; - - mitk::pa::Volume::Pointer m_AbsorptionVolume; - mitk::pa::Volume::Pointer m_ScatteringVolume; - mitk::pa::Volume::Pointer m_AnisotropyVolume; - mitk::pa::Volume::Pointer m_SegmentationVolume; - - TissueGeneratorParameters::Pointer m_TissueParameters; - - unsigned int m_TDim; - - double m_InitialBackgroundAbsorption; - - std::mt19937* m_Rng; - - void RandomizeTissueCoefficients(long rngSeed, bool useRngSeed, double percentage); - - mitk::PropertyList::Pointer m_PropertyList; - - private: - void FillZLayer(int x, int y, double startIdx, double endIdx, - double absorption, double scattering, double anisotropy, - SegmentationType segmentationType); - void AddSkinAndAirLayers(); - void UpdatePropertyList(); - }; - } -} -#endif // MITKPHOTOACOUSTICVOLUME_H diff --git a/Modules/PhotoacousticsLib/include/mitkPALightSource.h b/Modules/PhotoacousticsLib/include/mitkPALightSource.h deleted file mode 100644 index 4dd982ea78..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPALightSource.h +++ /dev/null @@ -1,182 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICLIGHTSOURCE_H -#define MITKPHOTOACOUSTICLIGHTSOURCE_H - -#include - -#include "MitkPhotoacousticsLibExports.h" - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkObject.h" -#include "itkMacro.h" - -namespace tinyxml2 { - class XMLElement; -} - -namespace mitk { - namespace pa { - /** - * @brief The LightSource class - * The representation of a LightSource - */ - class MITKPHOTOACOUSTICSLIB_EXPORT LightSource : public itk::Object - { - public: - - mitkClassMacroItkParent(LightSource, itk::Object); - itkFactorylessNewMacro(Self); - mitkNewMacro2Param(Self, const tinyxml2::XMLElement*, bool); - - const std::string XML_TAG_X_ANGLE = "xAngle"; - const std::string XML_TAG_Y_ANGLE = "yAngle"; - const std::string XML_TAG_PHOTON_DIRECTION = "PhotonDirection"; - const std::string XML_TAG_MINIMUM = "min"; - const std::string XML_TAG_MAXIMUM = "max"; - const std::string XML_TAG_MODE = "mode"; - const std::string XML_TAG_ENERGY = "energy"; - const std::string XML_TAG_SPAWN_TYPE = "SpawnType"; - const std::string XML_TAG_SPAWN_TYPE_POINT = "POINT"; - const std::string XML_TAG_SPAWN_TYPE_RECTANGLE = "RECTANGLE"; - const std::string XML_TAG_SPAWN_TYPE_CIRCLE = "CIRCLE"; - const std::string XML_TAG_X = "x"; - const std::string XML_TAG_Y = "y"; - const std::string XML_TAG_Z = "z"; - const std::string XML_TAG_R = "r"; - const std::string XML_TAG_X_LENGTH = "xLength"; - const std::string XML_TAG_Y_LENGTH = "yLength"; - const std::string XML_TAG_Z_LENGTH = "zLength"; - - enum SpawnType - { - POINT, RECTANGLE, CIRCLE - }; - - enum DistributionMode - { - UNIFORM, GAUSSIAN - }; - - struct PhotonInformation - { - double xPosition; - double yPosition; - double zPosition; - double xAngle; - double yAngle; - double zAngle; - }; - - PhotonInformation GetNextPhoton(double rnd1, double rnd2, double rnd3, - double rnd4, double rnd5, double gau1, double gau2); - - bool IsValid(); - - LightSource(const tinyxml2::XMLElement* element, bool verbose); - LightSource(); - ~LightSource() override; - - void ParseAngle(const tinyxml2::XMLElement* direction, const std::string& angle); - - itkGetMacro(SpawnType, SpawnType); - - itkSetMacro(SpawnType, SpawnType); - - itkGetMacro(SpawnLocationX, double); - - itkSetMacro(SpawnLocationX, double); - itkGetMacro(SpawnLocationY, double); - itkSetMacro(SpawnLocationY, double); - itkGetMacro(SpawnLocationZ, double); - - itkSetMacro(SpawnLocationZ, double); - - itkGetMacro(SpawnLocationXLength, double); - - itkSetMacro(SpawnLocationXLength, double); - itkGetMacro(SpawnLocationYLength, double); - itkSetMacro(SpawnLocationYLength, double); - itkGetMacro(SpawnLocationZLength, double); - - itkSetMacro(SpawnLocationZLength, double); - - itkGetMacro(SpawnLocationRadius, double); - - itkSetMacro(SpawnLocationRadius, double); - itkGetMacro(Energy, double); - itkSetMacro(Energy, double); - itkGetMacro(AngleXMinimum, double); - - itkSetMacro(AngleXMinimum, double); - - itkGetMacro(AngleXMaximum, double); - - itkSetMacro(AngleXMaximum, double); - itkGetMacro(AngleYMinimum, double); - itkSetMacro(AngleYMinimum, double); - itkGetMacro(AngleYMaximum, double); - - itkSetMacro(AngleYMaximum, double); - - itkGetMacro(AngleXMode, DistributionMode); - - itkSetMacro(AngleXMode, DistributionMode); - itkGetMacro(AngleYMode, DistributionMode); - itkSetMacro(AngleYMode, DistributionMode); - itkGetMacro(Verbose, bool); - - itkSetMacro(Verbose, bool); - - protected: - - const double TWO_PI = 2.0*3.14159265358979323846; - - SpawnType m_SpawnType; - double m_SpawnLocationX; - double m_SpawnLocationY; - double m_SpawnLocationZ; - double m_SpawnLocationXLength; - double m_SpawnLocationYLength; - double m_SpawnLocationZLength; - double m_SpawnLocationRadius; - - double m_Energy; - - double m_AngleXMinimum; - double m_AngleXMaximum; - double m_AngleYMinimum; - double m_AngleYMaximum; - DistributionMode m_AngleXMode; - DistributionMode m_AngleYMode; - - bool m_IsValid; - bool m_Verbose; - - struct TransformResult - { - double z0; - double z1; - }; - - void ParsePhotonDirection(const tinyxml2::XMLElement* element); - void ParseEnergy(const tinyxml2::XMLElement* element); - void ParsePhotonSpawnArea(const tinyxml2::XMLElement* element); - - TransformResult BoxMuellerTransform(double u1, double u2, double mu, double sigma); - }; - } -} - -#endif // MITKPHOTOACOUSTICLIGHTSOURCE_H diff --git a/Modules/PhotoacousticsLib/include/mitkPALinearSpectralUnmixingFilter.h b/Modules/PhotoacousticsLib/include/mitkPALinearSpectralUnmixingFilter.h deleted file mode 100644 index c62b88d87b..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPALinearSpectralUnmixingFilter.h +++ /dev/null @@ -1,100 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKLINEARPHOTOACOUSTICSPECTRALUNMIXINGFILTER_H -#define MITKLINEARPHOTOACOUSTICSPECTRALUNMIXINGFILTER_H - -#include -#include - -namespace mitk { - namespace pa { - /** - * \brief This filter is subclass of the spectral unmixing filter base. All algorithms in this class are - * based on the Eigen open source c++ library. It takes a multispectral pixel as input and returns a vector - * with the unmixing result. - * - * Input: - * - endmemberMatrix Eigen Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains - * the absorbtion of chromophore j @ wavelength i taken from the database by PropertyElement method. - * - inputVector Eigen Vector containing values of one pixel of XY-plane image with number of wavelength rows (z-dimension of a sequenece) - * so the pixelvalue of the first wavelength is stored in inputVector[0] and so on. - * - * Output: - * - Eigen vector with unmixing result of one multispectral pixel. The ith element of the vector corresponds to the ith entry of the - * m_Chromophore vector. - * - * Algorithms (see AlgortihmType enum): - * - HOUSEHOLDERQR computes the solution by QR decomposition - * - COLPIVHOUSEHOLDERQR computes the solution by QR decomposition - * - FULLPIVHOUSEHOLDERQR computes the solution by QR decomposition - * - LDLT computes the solution by Cholesky decomposition - * - LLT computes the solution by Cholesky decomposition - * - JACOBISVD computes the solution by singular value decomposition uses least square solver - * - * Possible exceptions: - * - "algorithm not working": doesn't work now (2018/06/19) - * - "404 VIGRA ALGORITHM NOT FOUND": Algorithm not implemented - */ - - class MITKPHOTOACOUSTICSLIB_EXPORT LinearSpectralUnmixingFilter : public SpectralUnmixingFilterBase - { - public: - - mitkClassMacro(LinearSpectralUnmixingFilter, SpectralUnmixingFilterBase); - - itkFactorylessNewMacro(Self); - - /** - * \brief Contains all implemented Eigen algorithms for spectral unmixing. For detailed information of the algorithms look at the - * mitkPALinearSpectralUnmixingFilter.h documentation (section Algorithms). - */ - enum AlgortihmType - { - HOUSEHOLDERQR, - LDLT, - LLT, - COLPIVHOUSEHOLDERQR, - JACOBISVD, - FULLPIVLU, - FULLPIVHOUSEHOLDERQR - }; - - /** - * \brief Takes a mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType and fix it for usage at the "SpectralUnmixingAlgorithm" method. - * @param inputAlgorithmName has to be a mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType - */ - void SetAlgorithm(AlgortihmType inputAlgorithmName); - - protected: - LinearSpectralUnmixingFilter(); - ~LinearSpectralUnmixingFilter() override; - - /** - * \brief overrides the baseclass method with a mehtod to calculate the spectral unmixing result vector. Herain the class performs the - * algorithm set by the "SetAlgorithm" method and writes the result into a Eigen vector which is the return value. - * @param endmemberMatrix Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains - * the absorbtion of chromophore j @ wavelength i taken from the database by PropertyElement method. - * @param inputVector Vector containing values of one pixel of XY-plane image with number of wavelength rows (z-dimension of a sequenece) - * so the pixelvalue of the first wavelength is stored in inputVector[0] and so on. - * @throws if the algorithmName is not a member of the enum VigraAlgortihmType - * @throws if one chooses the ldlt/llt solver which doens't work yet - */ - Eigen::VectorXf SpectralUnmixingAlgorithm(Eigen::Matrix endmemberMatrix, - Eigen::VectorXf inputVector) override; - - private: - AlgortihmType algorithmName; - }; - } -} -#endif // MITKLINEARPHOTOACOUSTICSPECTRALUNMIXINGFILTER_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAMonteCarloThreadHandler.h b/Modules/PhotoacousticsLib/include/mitkPAMonteCarloThreadHandler.h deleted file mode 100644 index 0c8e02f381..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAMonteCarloThreadHandler.h +++ /dev/null @@ -1,91 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKMONTECARLOTHREADHANDLER_H -#define MITKMONTECARLOTHREADHANDLER_H - -#include -#include -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - /** - * @brief The PhotoacousticStatefulObject class - * Designed for inheritence. Provides a state member variable and convenience methods to check - * for the state. - */ - class MITKPHOTOACOUSTICSLIB_EXPORT MonteCarloThreadHandler : public itk::LightObject - { - public: - - mitkClassMacroItkParent(MonteCarloThreadHandler, itk::LightObject); - mitkNewMacro2Param(MonteCarloThreadHandler, long, bool); - mitkNewMacro3Param(MonteCarloThreadHandler, long, bool, bool); - - long GetNextWorkPackage(); - - void SetPackageSize(long sizeInMilliseconsOrNumberOfPhotons); - - itkGetMacro(NumberPhotonsToSimulate, long); - itkGetMacro(NumberPhotonsRemaining, long); - itkGetMacro(WorkPackageSize, long); - itkGetMacro(SimulationTime, long); - itkGetMacro(SimulateOnTimeBasis, bool); - itkGetMacro(Verbose, bool); - - protected: - long m_NumberPhotonsToSimulate; - long m_NumberPhotonsRemaining; - long m_WorkPackageSize; - long m_SimulationTime; - long m_Time; - bool m_SimulateOnTimeBasis; - bool m_Verbose; - std::mutex m_MutexRemainingPhotonsManipulation; - - /** - * @brief PhotoacousticThreadhandler - * @param timInMilliseconsOrNumberofPhotons - * @param simulateOnTimeBasis - */ - MonteCarloThreadHandler(long timInMilliseconsOrNumberofPhotons, bool simulateOnTimeBasis); - - /** - * @brief PhotoacousticThreadhandler - * @param timInMilliseconsOrNumberofPhotons - * @param simulateOnTimeBasis - * @param verbose - */ - MonteCarloThreadHandler(long timInMilliseconsOrNumberofPhotons, bool simulateOnTimeBasis, bool verbose); - ~MonteCarloThreadHandler() override; - }; - - /** - * @brief Equal A function comparing two thread handlers for beeing equal - * - * @param rightHandSide A object to be compared - * @param leftHandSide A object to be compared - * @param eps tolarence for comparison. You can use mitk::eps in most cases. - * @param verbose flag indicating if the user wants detailed console output or not. - * @return true, if all subsequent comparisons are true, false otherwise - */ - MITKPHOTOACOUSTICSLIB_EXPORT bool Equal(const MonteCarloThreadHandler::Pointer leftHandSide, - const MonteCarloThreadHandler::Pointer rightHandSide, double eps, bool verbose); - } -} - -#endif // MITKMONTECARLOTHREADHANDLER_H diff --git a/Modules/PhotoacousticsLib/include/mitkPANoiseGenerator.h b/Modules/PhotoacousticsLib/include/mitkPANoiseGenerator.h deleted file mode 100644 index 07a7fa3523..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPANoiseGenerator.h +++ /dev/null @@ -1,42 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICNOISEGENERATOR_H -#define MITKPHOTOACOUSTICNOISEGENERATOR_H - -#include "MitkPhotoacousticsLibExports.h" - -#include "mitkPAVolume.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT NoiseGenerator final - { - public: - - /** - * @brief ApplyNoiseModel - * Applies noise to an image. - * @param image the image to apply the noise to - * @param detectorNoise >= 0 - * @param speckleNoise >= 1 - */ - static void ApplyNoiseModel(mitk::pa::Volume::Pointer image, double detectorNoise, double speckleNoise); - - private: - NoiseGenerator(); - ~NoiseGenerator() {}; - }; - } -} - -#endif // MITKPHOTOACOUSTICNOISEGENERATOR_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAPhantomTissueGenerator.h b/Modules/PhotoacousticsLib/include/mitkPAPhantomTissueGenerator.h deleted file mode 100644 index 1c57151de6..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAPhantomTissueGenerator.h +++ /dev/null @@ -1,48 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef mitkPhotoacousticPhantomTissueGenerator_h -#define mitkPhotoacousticPhantomTissueGenerator_h - -#include -#include -#include -#include - -#include -#include - -#include "mitkPAVesselTree.h" -#include "mitkPAInSilicoTissueVolume.h" - -#include "mitkCommon.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT PhantomTissueGenerator final - { - public: - - /** - * @brief GenerateInSilicoData This method will return a InSilicoTissueVolume created in terms of the given parameters. - * @param parameters - * @return - */ - static InSilicoTissueVolume::Pointer GeneratePhantomData(TissueGeneratorParameters::Pointer parameters); - - private: - PhantomTissueGenerator(); - virtual ~PhantomTissueGenerator(); - }; - } -} -#endif diff --git a/Modules/PhotoacousticsLib/include/mitkPAProbe.h b/Modules/PhotoacousticsLib/include/mitkPAProbe.h deleted file mode 100644 index 606660046c..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAProbe.h +++ /dev/null @@ -1,68 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICPROBE_H -#define MITKPHOTOACOUSTICPROBE_H - -#include - -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -#include "mitkPALightSource.h" -#include - -namespace tinyxml2 { - class XMLDocument; -} - -namespace mitk { - namespace pa { - /** - * @brief The Probe class - * The representation of a Probe - */ - class MITKPHOTOACOUSTICSLIB_EXPORT Probe : public itk::LightObject - { - public: - - mitkClassMacroItkParent(Probe, itk::LightObject); - mitkNewMacro2Param(Self, std::string, bool); - mitkNewMacro2Param(Self, const char*, bool); - - const std::string XML_TAG_PROBE = "Probe"; - const std::string XML_TAG_LIGHT_SOURCE = "LightSource"; - - LightSource::PhotonInformation GetNextPhoton(double rng1, double rnd2, double rnd3, double rnd4, - double rnd5, double rnd6, double rnd7, double rnd8); - - bool IsValid(); - - Probe(std::string xmlFile, bool verbose); - Probe(const char* fileStream, bool verbose); - ~Probe() override; - - protected: - - std::vector m_LightSources; - bool m_IsValid; - double m_TotalEnergy; - bool m_Verbose; - - void InitProbe(const tinyxml2::XMLDocument& document); - }; - } -} -#endif // MITKPHOTOACOUSTICPROBE_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAPropertyCalculator.h b/Modules/PhotoacousticsLib/include/mitkPAPropertyCalculator.h deleted file mode 100644 index a83738b207..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAPropertyCalculator.h +++ /dev/null @@ -1,75 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICPROPERTYCALCULATOR_H -#define MITKPHOTOACOUSTICPROPERTYCALCULATOR_H - -#include "MitkPhotoacousticsLibExports.h" - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT PropertyCalculator : public itk::LightObject - { - public: - - mitkClassMacroItkParent(PropertyCalculator, itk::LightObject); - itkFactorylessNewMacro(Self); - - struct Properties - { - double mua; - double mus; - double g; - }; - - enum TissueType - { - AIR = 1, - BLOOD = 2, - EPIDERMIS = 3, - FAT = 4, - STANDARD_TISSUE = 5 - }; - - enum ChromophoreType - { - OXYGENATED = 1, - DEOXYGENATED = 2, - WATER = 3, - FATTY = 4, - MELANIN = 5, - ONEENDMEMBER = 6 - }; - - double GetAbsorptionForWavelength( - ChromophoreType chromophoreType, int wavelength); - - Properties CalculatePropertyForSpecificWavelength( - TissueType tissueType, int wavelength, double oxygenSaturatonInFraction = 0); - - protected: - PropertyCalculator(); - ~PropertyCalculator() override; - - bool m_Valid = false; - - std::map> m_SpectralLibMap; - - }; - } -} - -#endif // MITKPHOTOACOUSTICPROPERTYCALCULATOR_H diff --git a/Modules/PhotoacousticsLib/include/mitkPASimulationBatchGenerator.h b/Modules/PhotoacousticsLib/include/mitkPASimulationBatchGenerator.h deleted file mode 100644 index 1f48abfe47..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASimulationBatchGenerator.h +++ /dev/null @@ -1,45 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSIMULATIONBATCHGENERATOR_H -#define MITKPHOTOACOUSTICSIMULATIONBATCHGENERATOR_H - -#include -#include -#include - -#include - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT SimulationBatchGenerator - { - public: - static void WriteBatchFileAndSaveTissueVolume( - SimulationBatchGeneratorParameters::Pointer parameters, - mitk::Image::Pointer tissueVolume); - - static std::string CreateBatchSimulationString( - SimulationBatchGeneratorParameters::Pointer parameter); - protected: - SimulationBatchGenerator(); - virtual ~SimulationBatchGenerator(); - - static std::string GetVolumeNumber( - SimulationBatchGeneratorParameters::Pointer parameters); - - static std::string GetOutputFolderName( - SimulationBatchGeneratorParameters::Pointer parameter); - }; - } -} -#endif // MITKPHOTOACOUSTICSIMULATIONBATCHGENERATOR_H diff --git a/Modules/PhotoacousticsLib/include/mitkPASimulationBatchGeneratorParameters.h b/Modules/PhotoacousticsLib/include/mitkPASimulationBatchGeneratorParameters.h deleted file mode 100644 index d17c010833..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASimulationBatchGeneratorParameters.h +++ /dev/null @@ -1,67 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSimulationBatchGENERATORPARAMETERS_H -#define MITKPHOTOACOUSTICSimulationBatchGENERATORPARAMETERS_H - -#include -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT SimulationBatchGeneratorParameters : public itk::Object - { - public: - mitkClassMacroItkParent(SimulationBatchGeneratorParameters, itk::Object); - itkFactorylessNewMacro(Self); - itkSetMacro(VolumeIndex, unsigned int); - itkSetMacro(NrrdFilePath, std::string); - itkSetMacro(TissueName, std::string); - itkSetMacro(BinaryPath, std::string); - itkSetMacro(NumberOfPhotons, long); - itkSetMacro(YOffsetLowerThresholdInCentimeters, double); - itkSetMacro(YOffsetUpperThresholdInCentimeters, double); - itkSetMacro(YOffsetStepInCentimeters, double); - itkGetMacro(VolumeIndex, unsigned int); - - itkGetMacro(NrrdFilePath, std::string); - - itkGetMacro(TissueName, std::string); - - itkGetMacro(BinaryPath, std::string); - itkGetMacro(NumberOfPhotons, long); - itkGetMacro(YOffsetLowerThresholdInCentimeters, double); - itkGetMacro(YOffsetUpperThresholdInCentimeters, double); - itkGetMacro(YOffsetStepInCentimeters, double); - - protected: - SimulationBatchGeneratorParameters(); - ~SimulationBatchGeneratorParameters() override; - - private: - - unsigned int m_VolumeIndex; - std::string m_NrrdFilePath; - std::string m_TissueName; - std::string m_BinaryPath; - long m_NumberOfPhotons; - double m_YOffsetLowerThresholdInCentimeters; - double m_YOffsetUpperThresholdInCentimeters; - double m_YOffsetStepInCentimeters; - }; - } -} -#endif // MITKPHOTOACOUSTICSimulationBatchGENERATORPARAMETERS_H diff --git a/Modules/PhotoacousticsLib/include/mitkPASlicedVolumeGenerator.h b/Modules/PhotoacousticsLib/include/mitkPASlicedVolumeGenerator.h deleted file mode 100644 index 1316fab25b..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASlicedVolumeGenerator.h +++ /dev/null @@ -1,56 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSLICEDVOLUMEGENERATOR_H -#define MITKPHOTOACOUSTICSLICEDVOLUMEGENERATOR_H - -#include - -#include -#include -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT SlicedVolumeGenerator : public itk::LightObject - { - public: - mitkClassMacroItkParent(SlicedVolumeGenerator, itk::LightObject); - mitkNewMacro4Param(Self, int, bool, - mitk::pa::Volume::Pointer, bool); - - mitk::pa::Volume::Pointer GetSlicedFluenceImageFromComposedVolume( - mitk::pa::ComposedVolume::Pointer composedVolume); - - mitk::pa::Volume::Pointer GetSlicedSignalImageFromComposedVolume( - mitk::pa::ComposedVolume::Pointer composedVolume); - - mitk::pa::Volume::Pointer GetSlicedGroundTruthImageFromComposedVolume( - mitk::pa::ComposedVolume::Pointer composedVolume); - - protected: - SlicedVolumeGenerator(int centralYSlice, bool precorrect, - mitk::pa::Volume::Pointer precorrectionVolume, bool inverse); - ~SlicedVolumeGenerator() override; - - int m_CentralYSlice; - bool m_Precorrect; - bool m_Inverse; - mitk::pa::Volume::Pointer m_PrecorrectionVolume; - }; - } -} -#endif // MITKPHOTOACOUSTICSLICEDVOLUMEGENERATOR_H diff --git a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterBase.h b/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterBase.h deleted file mode 100644 index dce6a5d2ce..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterBase.h +++ /dev/null @@ -1,194 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERBASE_H -#define MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERBASE_H - -#include "mitkImageToImageFilter.h" -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -// Includes for AddEnmemberMatrix -#include "mitkPAPropertyCalculator.h" -#include - -namespace mitk { - namespace pa { - /** - * \brief The spectral unmixing filter base is designed as superclass for several spectral unmixing filter eg. Eigen- or Vigrabased ones. - * One can add wavelengths and chromophores and get a unmixed output images out of one MITK input image using algorithms from the subclasses. - * - * Input: - * The unmixing input has to be a 3D MITK image where the XY-plane is a image and the Z-direction represents recordings for different - * wavelengths. Herein a XY-plane for a specific Z-direction will be called "image". Every image has to be assigned to a certain wavelength. - * The "AddWavelength" uses "push_back" to write float values into a vector. The first wavelength will correspond to the first image!!! - * If there a more input images 'I' then added wavelengths 'w' the filter base interprets the next x images as repetition sequence of the same - * wavelengths. If I % w !=0 the surplus image(s) will be dropped. - * Addtionaly one has to add chromophores from the property calculator class enum "ChromophoreType" with the "AddChromophore" method. - * This method as well uses "push_back" but the chosen (arbitary) order will be the order of the outputs. - * - * Output: - * The output will be one MITK image per chosen chromophore. Where the XY-plane is a image and the Z-direction represents recordings for different - * sequences. Furthermore it is possible to creat an output image that contains the information about the relative error between unmixing result - * and the input image. - * - * Subclasses: - * - mitkPASpectralUnmixingFilterVigra - * - mitkPALinearSpectralUnmixingFilter (uses Eigen algorithms) - * - mitkPASpectralUnmixingFilterSimplex - * - * Possible exceptions: - * - "PIXELTYPE ERROR! FLOAT 32 REQUIRED": The MITK input image has to consist out of floats. - * - "ERROR! REMOVE WAVELENGTHS!": One needs at least the same amount of images (z-dimension) then added wavelengths. - * - "ADD MORE WAVELENGTHS!": One needs at least the same amount of wavelengths then added chromophores. - * - "WAVELENGTH XXX nm NOT SUPPORTED!": The wavelength is not part of the proptery calculater data base. The data base can be found @ - * [...]/mitk/Modules/PhotoacousticsLib/Resources/spectralLIB.dat - * - "ADD OUTPUTS HAS TO BE LARGER THEN ZERO!" - * - "NO WAVELENGHTS/CHROMOPHORES SELECZED! - * - "INDEX ERROR! NUMBER OF OUTPUTS DOESN'T FIT TO OTHER SETTIGNS!" - */ - - class MITKPHOTOACOUSTICSLIB_EXPORT SpectralUnmixingFilterBase : public mitk::ImageToImageFilter - { - public: - mitkClassMacro(SpectralUnmixingFilterBase, mitk::ImageToImageFilter); - - /** - * \brief AddChromophore takes mitk::pa::PropertyCalculator::ChromophoreType and writes them at the end of the m_Chromophore vector. - * The call of the method sets the order of the GetOutput method! - * - * @param chromophore has to be element of porperty calculater enum chromophore type - * @return for wavelength smaller then 300nm and larger then 1000nm the return will be 0, because not at the data base (2018/06/19) - */ - void AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType chromophore); - - /** - * \brief AddWavelength takes integers and writes them at the end of the m_Wavelength vector. The first call of the method then - * corresponds to the first input image and so on. - * @param wavelength database supports integers between 300 and 1000 nm - */ - void AddWavelength(int wavelength); - - /* - * \brief Verbose gives more information to the console. Default value is false. - * @param verbose is the boolian to activate the MITK_INFO logged to the console - */ - virtual void Verbose(bool verbose); - - /** - * \brief AddOutputs takes an integer and sets indexed outputs - * @param outputs integer correponds to the number of output images - * @throws if outputs == 0 - */ - virtual void AddOutputs(unsigned int outputs); - - /* - * \brief RelativeError returns a image which compare the L2 norm of the input vector with the unmixing result - * @param relativeError is the boolian to activate this tool - */ - virtual void RelativeError(bool relativeError); - - /** - * \brief AddRelativeErrorSettings takes integers and writes them at the end of the m_RelativeErrorSettings vector. - * @param value has to be a integer - */ - virtual void AddRelativeErrorSettings(int value); - - std::ofstream myfile; // just for testing purposes; has to be removeed - - protected: - /** - * \brief Constructor creats proptery calculater smart pointer new() - */ - SpectralUnmixingFilterBase(); - ~SpectralUnmixingFilterBase() override; - - /** - * \brief The subclasses will override the mehtod to calculate the spectral unmixing result vector. - * @param endmemberMatrix Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains - * the absorbtion of chromophore j @ wavelength i taken from the database by PropertyElement method. - * @param inputVector Vector containing values of one pixel of XY-plane image with number of wavelength rows (z-dimension of a sequenece) - * so the pixelvalue of the first wavelength is stored in inputVector[0] and so on. - * @throws if algorithm implementiation fails (implemented for the algorithms with critical requirements) - */ - virtual Eigen::VectorXf SpectralUnmixingAlgorithm(Eigen::Matrix endmemberMatrix, - Eigen::VectorXf inputVector) = 0; - - bool m_Verbose = false; - bool m_RelativeError = false; - - std::vector m_Chromophore; - std::vector m_Wavelength; - std::vector m_RelativeErrorSettings; - - private: - /* - * \brief Initialized output images with the same XY-plane size like the input image and total size in z-direction equals number of sequences. - * The pixel type is set to float. - * @param totalNumberOfSequences = (unsigned int) (numberOfInputImages / numberOfWavelength) >= 1 - */ - virtual void InitializeOutputs(unsigned int totalNumberOfSequences); - - /* - * \brief Checks if there are a suitable amount of wavelengths and if the input image consists of floats. - * @param input pointer on the MITK input image - * @throws if there are more wavelength then images - * @throws if there are more chromophores then wavelengths - * @throws if the pixel type is not float 32 - * @throws if no chromophores or wavelengths selected as input - * @throws if the number of indexed outputs does'nt fit to the expected number - */ - virtual void CheckPreConditions(mitk::Image::Pointer input); - - /* - * \brief Inherit from the "ImageToImageFilter" Superclass. Herain it calls InitializeOutputs, CalculateEndmemberMatrix and - * CheckPreConditions methods and enables pixelwise access to do spectral unmixing with the "SpectralUnmixingAlgorithm" - * method. In the end the method writes the results into the new MITK output images. - */ - void GenerateData() override; - - /* - * \brief Creats a Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains - * the absorbtion of chromophore j @ wavelength i. The absorbtion values are taken from the "PropertyElement" method. - * @param m_Chromophore is a vector of "PropertyCalculator::ChromophoreType" containing all selected chromophores for the unmixing - * @param m_Wavelength is a vector of integers containing all wavelengths of one sequence - */ - virtual Eigen::Matrix CalculateEndmemberMatrix( - std::vector m_Chromophore, std::vector m_Wavelength); - - /* - * \brief "PropertyElement" is the tool to access the absorbtion values out of the database using mitk::pa::PropertyCalculator::GetAbsorptionForWavelengt - * and checks if the requested wavelength is part of the database (not zero values). The "ONEENDMEMBER" is a pseudo absorber with static absorbtion 1 - * at every wavelength and is therefor not part of the database. If this one is the selected chromophore the return value is 1 for every wavelength. - * @param wavelength has to be integer between 300 and 1000 nm - * @param chromophore has to be a mitk::pa::PropertyCalculator::ChromophoreType - * @throws if mitk::pa::PropertyCalculator::GetAbsorptionForWavelengt returns 0, because this means that the delivered wavelength is not in the database. - */ - virtual float PropertyElement(mitk::pa::PropertyCalculator::ChromophoreType, int wavelength); - - /* - * \brief calculates the relative error between the input image and the unmixing result in the L2 norm - * @param endmemberMatrix is a Eigen matrix containing the endmember information - * @param inputVector is a Eigen vector containing the multispectral information of one pixel - * @param resultVector is a Eigen vector containing the spectral unmmixing result - */ - float CalculateRelativeError(Eigen::Matrix endmemberMatrix, - Eigen::VectorXf inputVector, Eigen::VectorXf resultVector); - - PropertyCalculator::Pointer m_PropertyCalculatorEigen; - }; - } -} -#endif // MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERBASE_ diff --git a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterLagrange.h b/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterLagrange.h deleted file mode 100644 index d99e73e310..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterLagrange.h +++ /dev/null @@ -1,36 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERLAGRANGE_H -#define MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERLAGRANGE_H - -#include -#include - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT SpectralUnmixingFilterLagrange : public SpectralUnmixingFilterBase - { - public: - - mitkClassMacro(SpectralUnmixingFilterLagrange, SpectralUnmixingFilterBase); - - protected: - SpectralUnmixingFilterLagrange(); - ~SpectralUnmixingFilterLagrange() override; - - private: - - }; - } -} -#endif // MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERLAGRANGE_H diff --git a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterSimplex.h b/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterSimplex.h deleted file mode 100644 index c5ca41dbe3..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterSimplex.h +++ /dev/null @@ -1,50 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERSIMPLEX_H -#define MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERSIMPLEX_H - -#include -#include - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT SpectralUnmixingFilterSimplex : public SpectralUnmixingFilterBase - { - public: - - mitkClassMacro(SpectralUnmixingFilterSimplex, SpectralUnmixingFilterBase); - - itkFactorylessNewMacro(Self); - - protected: - SpectralUnmixingFilterSimplex(); - ~SpectralUnmixingFilterSimplex() override; - - private: - - Eigen::VectorXf SpectralUnmixingAlgorithm(Eigen::Matrix EndmemberMatrix, - Eigen::VectorXf inputVector) override; - - int factorial(int n); - virtual Eigen::Matrix GenerateA(Eigen::Matrix EndmemberMatrix, - Eigen::VectorXf inputVector, int i); - Eigen::Matrix GenerateD2(Eigen::Matrix A); - float simplexVolume(Eigen::Matrix Matrix); - - virtual Eigen::VectorXf Normalization(Eigen::Matrix EndmemberMatrix, - Eigen::VectorXf inputVector); - - }; - } -} -#endif // MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERSIMPLEX_H diff --git a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterVigra.h b/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterVigra.h deleted file mode 100644 index f6d8f638b3..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterVigra.h +++ /dev/null @@ -1,104 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERVIGRA_H -#define MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERVIGRA_H - -#include -#include -#include - - - -namespace mitk { - namespace pa { - /** - * \brief This filter is subclass of the spectral unmixing filter base. All algorithms in this class are - * based on the vigra open source c++ library. It takes a multispectral pixel as input and returns a vector - * with the unmixing result. - * - * Input: - * - endmemberMatrix Eigen Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains - * the absorbtion of chromophore j @ wavelength i taken from the database by PropertyElement method. - * - inputVector Eigen Vector containing values of one pixel of XY-plane image with number of wavelength rows (z-dimension of a sequenece) - * so the pixelvalue of the first wavelength is stored in inputVector[0] and so on. - * - * Output: - * - Eigen vector with unmixing result of one multispectral pixel. The ith element of the vector corresponds to the ith entry of the - * m_Chromophore vector. - * - * Algorithms (see VigraAlgortihmType enum): - * - LARS algorithm minimizes (A*x-b)^2 s.t. x>=0 using least angle regression - * - GOLDFARB minimizes (A*x-b)^2 s.t. x>=0 using the Goldfarb-Idnani algorithm - * - WEIGHTED minimizes transpose(A*x-b)*diag(weights)*(A*x-b) using QR decomposition - * - LS minimizes (A*x-b)^2 using QR decomposition - * - * Possible exceptions: - * - "404 VIGRA ALGORITHM NOT FOUND": Algorithm not implemented - */ - - class MITKPHOTOACOUSTICSLIB_EXPORT SpectralUnmixingFilterVigra : public SpectralUnmixingFilterBase - { - public: - mitkClassMacro(SpectralUnmixingFilterVigra, SpectralUnmixingFilterBase); - itkFactorylessNewMacro(Self); - - /** - * \brief Contains all implemented Vigra algorithms for spectral unmixing. For detailed information of the algorithms look at the - * mitkPASpectralUnmixingFilterVigra.h documentation (section Algorithms). - */ - enum VigraAlgortihmType - { - LARS, - GOLDFARB, - WEIGHTED, - LS - }; - - /** - * \brief AddWeight takes integers and writes them at the end of the weightsvec vector. The first call of the method then - * corresponds to the first input image/wavelength and so on. - * @param weight is a percentage (integer) between 1 and 100 - */ - void AddWeight(unsigned int weight); - - /** - * \brief Takes a mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType and fix it for usage at the "SpectralUnmixingAlgorithm" - * method. - * @param inputAlgorithmName has to be a mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType - */ - void SetAlgorithm(VigraAlgortihmType inputAlgorithmName); - - protected: - SpectralUnmixingFilterVigra(); - ~SpectralUnmixingFilterVigra() override; - - /** - * \brief overrides the baseclass method with a mehtod to calculate the spectral unmixing result vector. Herain it first converts the - * Eigen inputs to the Vigra class. Afterwards the class performs the algorithm set by the "SetAlgorithm" method and writes the result - * into a Eigen vector which is the return value. - * @param EndmemberMatrix Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains - * the absorbtion of chromophore j @ wavelength i taken from the database by PropertyElement method. - * @param inputVector Vector containing values of one pixel of XY-plane image with number of wavelength rows (z-dimension of a sequenece) - * so the pixelvalue of the first wavelength is stored in inputVector[0] and so on. - * @throws if the algorithmName is not a member of the enum VigraAlgortihmType - */ - Eigen::VectorXf SpectralUnmixingAlgorithm(Eigen::Matrix EndmemberMatrix, - Eigen::VectorXf inputVector) override; - - private: - std::vector weightsvec; - SpectralUnmixingFilterVigra::VigraAlgortihmType algorithmName; - }; - } -} -#endif // MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERVIGRA_H diff --git a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingSO2.h b/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingSO2.h deleted file mode 100644 index a1b90efcf6..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingSO2.h +++ /dev/null @@ -1,112 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICSPECTRALUNMIXINGSO2_H -#define MITKPHOTOACOUSTICSPECTRALUNMIXINGSO2_H - -#include "mitkImageToImageFilter.h" -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - - -namespace mitk { - namespace pa { - /** - * \brief derives out of two identical sized MITK images the oxygen saturation and return one MITK image as result. Furthermore - * it is possible to set settings that the result shows just SO2 values above a threshold, or above a input value for Hb, HbO2 to - * get just a oxygen saturation image of interessting structures. - * - * Input: - * The input has to be two 3D MITK images. The order of the inputs matter! The first input has to be the Hb image the second input - * has to be the HbO2 image. The settings are integer values. The SO2 threshold therefore is percentage value. - * - * Output: - * The output will be one MITK image. Where one can see the oxygen saturation of all pixels above the set threholds. If a pixel is - * below a threhold or NAN then the value will be set to zero. - * - * UPDATE: SO2 Filter will get an second output, the total hemoglobin value with ->GetOutput(1). - */ - class MITKPHOTOACOUSTICSLIB_EXPORT SpectralUnmixingSO2 : public mitk::ImageToImageFilter - { - public: - mitkClassMacro(SpectralUnmixingSO2, mitk::ImageToImageFilter); - itkFactorylessNewMacro(Self); - - /** - * \brief AddSO2Settings takes integers and writes them at the end of the m_SO2Settings vector. - * @param value of the Setting - */ - virtual void AddSO2Settings(int value); - - /** - * \brief Verbose gives more information to the console. Default value is false. - * @param verbose is the boolian to activate the MITK_INFO logged to the console - */ - virtual void Verbose(bool verbose); - - protected: - /** - * \brief Constructor sets number of input images to two and number of output images to one, respectively. - */ - SpectralUnmixingSO2(); - ~SpectralUnmixingSO2() override; - - std::vector m_SO2Settings; - bool m_Verbose = false; - - private: - /** - * \brief Inherit from the "ImageToImageFilter" Superclass. Herain it calls InitializeOutputs and the CheckPreConditions - * methods and enables pixelwise access to the inputs to calculate the oxygen saturation via the "calculate SO2" method. - */ - void GenerateData() override; - - /** - * \brief Initialized output images with the same size like the input image. The pixel type is set to float. - */ - virtual void InitializeOutputs(); - - /** - * \brief Checks if the dimensions of the input images are equal and made out of floating poinhts. - * @throws if the inputs don't have the same size - * @throws if input images don't consist of floats - */ - virtual void CheckPreConditions(mitk::Image::Pointer inputHbO2, mitk::Image::Pointer inputHb); - - /** - * \brief calculates HbO2 / (Hb + HbO2) and afterwards checks if the result is significant (SO2ValueNotSiginificant method). - * If not the method returns zero otherwise it returns the calculated result. - * @param pixelHb is the pixel value of the Hb input. - * @param pixelHb is the pixel value of the Hb input. - * @warn if the sO2 value is NAN (in patricular if Hb == -HbO2), but result will be set to zero - */ - float CalculateSO2(float pixelHb, float pixelHbO2); - - /** - * \brief calculates (Hb + HbO2). - * @param pixelHb is the pixel value of the Hb input. - * @param pixelHb is the pixel value of the Hb input. - * @warn if the tHb value is NAN (in patricular if Hb == -HbO2), but result will be set to zero - */ - float CalculateTHb(float pixelHb, float pixelHbO2); - - /** - * \brief return true if SO2 result is not significant by checking if the input values are above the threshold of the settings - */ - bool SO2ValueNotSiginificant(float Hb, float HbO2, float result); - }; - } -} -#endif // MITKPHOTOACOUSTICSPECTRALUNMIXINGSO2_ diff --git a/Modules/PhotoacousticsLib/include/mitkPATissueGenerator.h b/Modules/PhotoacousticsLib/include/mitkPATissueGenerator.h deleted file mode 100644 index eb4c4450f7..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPATissueGenerator.h +++ /dev/null @@ -1,48 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef mitkPhotoacousticTissueGenerator_h -#define mitkPhotoacousticTissueGenerator_h - -#include -#include -#include -#include - -#include -#include - -#include "mitkPAVesselTree.h" -#include "mitkPAInSilicoTissueVolume.h" - -#include "mitkCommon.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT InSilicoTissueGenerator final - { - public: - - /** - * @brief GenerateInSilicoData This method will return a InSilicoTissueVolume created in terms of the given parameters. - * @param parameters - * @return - */ - static InSilicoTissueVolume::Pointer GenerateInSilicoData(TissueGeneratorParameters::Pointer parameters); - - private: - InSilicoTissueGenerator(); - virtual ~InSilicoTissueGenerator(); - }; - } -} -#endif diff --git a/Modules/PhotoacousticsLib/include/mitkPATissueGeneratorParameters.h b/Modules/PhotoacousticsLib/include/mitkPATissueGeneratorParameters.h deleted file mode 100644 index 6e249f2b06..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPATissueGeneratorParameters.h +++ /dev/null @@ -1,212 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTICTISSUEGENERATORPARAMETERS_H -#define MITKPHOTOACOUSTICTISSUEGENERATORPARAMETERS_H - -#include -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT TissueGeneratorParameters : public itk::Object - { - public: - mitkClassMacroItkParent(TissueGeneratorParameters, itk::Object); - itkFactorylessNewMacro(Self); - - /** - * Callback function definition of a VesselMeanderStrategy - */ - typedef void (VesselMeanderStrategy::*CalculateNewVesselPositionCallback) - (Vector::Pointer, double, std::mt19937*); - - itkGetMacro(XDim, int); - - itkGetMacro(YDim, int); - - itkGetMacro(ZDim, int); - - itkGetMacro(VoxelSpacingInCentimeters, double); - itkGetMacro(DoPartialVolume, bool); - itkGetMacro(UseRngSeed, bool); - itkGetMacro(RngSeed, long); - itkGetMacro(RandomizePhysicalProperties, bool); - itkGetMacro(RandomizePhysicalPropertiesPercentage, double); - itkGetMacro(ForceVesselsMoveAlongYDirection, bool); - itkGetMacro(MinBackgroundAbsorption, double); - itkGetMacro(MaxBackgroundAbsorption, double); - itkGetMacro(BackgroundScattering, double); - itkGetMacro(BackgroundAnisotropy, double); - itkGetMacro(AirAbsorption, double); - itkGetMacro(AirScattering, double); - itkGetMacro(AirAnisotropy, double); - itkGetMacro(AirThicknessInMillimeters, double); - itkGetMacro(SkinAbsorption, double); - itkGetMacro(SkinScattering, double); - itkGetMacro(SkinAnisotropy, double); - itkGetMacro(SkinThicknessInMillimeters, double); - itkGetMacro(CalculateNewVesselPositionCallback, CalculateNewVesselPositionCallback); - itkGetMacro(MinNumberOfVessels, int); - itkGetMacro(MaxNumberOfVessels, int); - itkGetMacro(MinVesselBending, double); - itkGetMacro(MaxVesselBending, double); - itkGetMacro(MinVesselAbsorption, double); - itkGetMacro(MaxVesselAbsorption, double); - itkGetMacro(MinVesselRadiusInMillimeters, double); - itkGetMacro(MaxVesselRadiusInMillimeters, double); - itkGetMacro(VesselBifurcationFrequency, int); - itkGetMacro(MinVesselScattering, double); - itkGetMacro(MaxVesselScattering, double); - itkGetMacro(MinVesselAnisotropy, double); - itkGetMacro(MaxVesselAnisotropy, double); - itkGetMacro(MinVesselZOrigin, double); - itkGetMacro(MaxVesselZOrigin, double); - itkGetMacro(MCflag, double); - itkGetMacro(MCLaunchflag, double); - itkGetMacro(MCBoundaryflag, double); - itkGetMacro(MCLaunchPointX, double); - itkGetMacro(MCLaunchPointY, double); - itkGetMacro(MCLaunchPointZ, double); - itkGetMacro(MCFocusPointX, double); - itkGetMacro(MCFocusPointY, double); - itkGetMacro(MCFocusPointZ, double); - itkGetMacro(MCTrajectoryVectorX, double); - itkGetMacro(MCTrajectoryVectorY, double); - itkGetMacro(MCTrajectoryVectorZ, double); - itkGetMacro(MCRadius, double); - itkGetMacro(MCWaist, double); - itkSetMacro(XDim, int); - itkSetMacro(YDim, int); - itkSetMacro(ZDim, int); - itkSetMacro(VoxelSpacingInCentimeters, double); - itkSetMacro(DoPartialVolume, bool); - itkSetMacro(UseRngSeed, bool); - itkSetMacro(RngSeed, long); - itkSetMacro(RandomizePhysicalProperties, bool); - itkSetMacro(RandomizePhysicalPropertiesPercentage, double); - itkSetMacro(ForceVesselsMoveAlongYDirection, bool); - itkSetMacro(MinBackgroundAbsorption, double); - itkSetMacro(MaxBackgroundAbsorption, double); - itkSetMacro(BackgroundScattering, double); - itkSetMacro(BackgroundAnisotropy, double); - itkSetMacro(AirAbsorption, double); - itkSetMacro(AirScattering, double); - itkSetMacro(AirAnisotropy, double); - itkSetMacro(AirThicknessInMillimeters, double); - itkSetMacro(SkinAbsorption, double); - itkSetMacro(SkinScattering, double); - itkSetMacro(SkinAnisotropy, double); - itkSetMacro(SkinThicknessInMillimeters, double); - itkSetMacro(CalculateNewVesselPositionCallback, CalculateNewVesselPositionCallback); - itkSetMacro(MinNumberOfVessels, int); - itkSetMacro(MaxNumberOfVessels, int); - itkSetMacro(MinVesselBending, double); - itkSetMacro(MaxVesselBending, double); - itkSetMacro(MinVesselAbsorption, double); - itkSetMacro(MaxVesselAbsorption, double); - itkSetMacro(MinVesselRadiusInMillimeters, double); - itkSetMacro(MaxVesselRadiusInMillimeters, double); - itkSetMacro(VesselBifurcationFrequency, int); - itkSetMacro(MinVesselScattering, double); - itkSetMacro(MaxVesselScattering, double); - itkSetMacro(MinVesselAnisotropy, double); - itkSetMacro(MaxVesselAnisotropy, double); - itkSetMacro(MinVesselZOrigin, double); - itkSetMacro(MaxVesselZOrigin, double); - itkSetMacro(MCflag, double); - - itkSetMacro(MCLaunchflag, double); - - itkSetMacro(MCBoundaryflag, double); - - itkSetMacro(MCLaunchPointX, double); - itkSetMacro(MCLaunchPointY, double); - itkSetMacro(MCLaunchPointZ, double); - itkSetMacro(MCFocusPointX, double); - itkSetMacro(MCFocusPointY, double); - itkSetMacro(MCFocusPointZ, double); - itkSetMacro(MCTrajectoryVectorX, double); - itkSetMacro(MCTrajectoryVectorY, double); - itkSetMacro(MCTrajectoryVectorZ, double); - itkSetMacro(MCRadius, double); - itkSetMacro(MCWaist, double); - - protected: - TissueGeneratorParameters(); - ~TissueGeneratorParameters() override; - - private: - - int m_XDim; - int m_YDim; - int m_ZDim; - double m_VoxelSpacingInCentimeters; - bool m_DoPartialVolume; - bool m_UseRngSeed; - long m_RngSeed; - bool m_RandomizePhysicalProperties; - double m_RandomizePhysicalPropertiesPercentage; - bool m_ForceVesselsMoveAlongYDirection; - - double m_MinBackgroundAbsorption; - double m_MaxBackgroundAbsorption; - double m_BackgroundScattering; - double m_BackgroundAnisotropy; - double m_AirAbsorption; - double m_AirScattering; - double m_AirAnisotropy; - double m_AirThicknessInMillimeters; - double m_SkinAbsorption; - double m_SkinScattering; - double m_SkinAnisotropy; - double m_SkinThicknessInMillimeters; - - CalculateNewVesselPositionCallback m_CalculateNewVesselPositionCallback; - int m_MinNumberOfVessels; - int m_MaxNumberOfVessels; - double m_MinVesselBending; - double m_MaxVesselBending; - double m_MinVesselAbsorption; - double m_MaxVesselAbsorption; - double m_MinVesselRadiusInMillimeters; - double m_MaxVesselRadiusInMillimeters; - int m_VesselBifurcationFrequency; - double m_MinVesselScattering; - double m_MaxVesselScattering; - double m_MinVesselAnisotropy; - double m_MaxVesselAnisotropy; - double m_MinVesselZOrigin; - double m_MaxVesselZOrigin; - - double m_MCflag; - double m_MCLaunchflag; - double m_MCBoundaryflag; - double m_MCLaunchPointX; - double m_MCLaunchPointY; - double m_MCLaunchPointZ; - double m_MCFocusPointX; - double m_MCFocusPointY; - double m_MCFocusPointZ; - double m_MCTrajectoryVectorX; - double m_MCTrajectoryVectorY; - double m_MCTrajectoryVectorZ; - double m_MCRadius; - double m_MCWaist; - }; - } -} -#endif // MITKPHOTOACOUSTICTISSUEGENERATORPARAMETERS_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVector.h b/Modules/PhotoacousticsLib/include/mitkPAVector.h deleted file mode 100644 index 3b25bf6b1c..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVector.h +++ /dev/null @@ -1,137 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKSMARTVECTOR_H -#define MITKSMARTVECTOR_H - -#include -#include - -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT Vector : public itk::LightObject - { - public: - mitkClassMacroItkParent(Vector, itk::LightObject); - itkFactorylessNewMacro(Self); - - /** - * @brief GetNorm calculates the length of this vector. - * @return the euclidean norm - */ - double GetNorm(); - - double GetElement(unsigned short index); - void SetElement(unsigned short index, double value); - - /** - * @brief Normalize normalizes this vector. After calling this GetNorm() will return 1. - */ - void Normalize(); - void SetValue(Vector::Pointer value); - - /** - * @brief RandomizeByPercentage alters this vector randomly by [-percentage, percentage] of the bendingFactor. - * - * @param percentage - * @param bendingFactor - * @param rng - */ - void RandomizeByPercentage(double percentage, double bendingFactor, std::mt19937* rng); - - /** - * @brief Randomize randomizes this vector to be [lowerLimit, upperLimit] in each element - * - * @param xLowerLimit - * @param xUpperLimit - * @param yLowerLimit - * @param yUpperLimit - * @param zLowerLimit - * @param zUpperLimit - * @param rng - */ - void Randomize(double xLowerLimit, double xUpperLimit, double yLowerLimit, double yUpperLimit, double zLowerLimit, double zUpperLimit, std::mt19937* rng); - - /** - * @brief Randomize randomizes this vector to be [0, limit] in each element - * - * @param xLimit - * @param yLimit - * @param zLimit - * @param rng - */ - void Randomize(double xLimit, double yLimit, double zLimit, std::mt19937* rng); - - /** - * @brief Randomize randomizes this vector to be [-1, 1] in each element - * - * @param rng - */ - void Randomize(std::mt19937* rng); - - /** - * @brief Rotate rotates this Vector around the x, y and z axis with the given angles in radians - * - * @param xAngle rotation of the inclination angle in radians - * @param yAngle rotation of the azimuthal angle in radians - */ - void Rotate(double xAngle, double yAngle); - - /** - * @brief Scale scales this Vector with the given factor - * - * @param factor the scaling factor - * - * If a negative number is provided, the direction of the vector will be inverted. - */ - void Scale(double factor); - - /** - * @brief Clone create a deep copy of this vector - * - * @return a new vector with the same values. - */ - Vector::Pointer Clone(); - - void Subtract(Vector::Pointer other); - - void Add(Vector::Pointer other); - - protected: - Vector(); - ~Vector() override; - - void PrintSelf(std::ostream& os, itk::Indent indent) const override; - - private: - mitk::Vector3D m_Vector; - }; - - /** - * @brief Equal A function comparing two vectors for beeing equal - * - * @param rightHandSide A Vector to be compared - * @param leftHandSide A Vector to be compared - * @param eps tolarence for comparison. You can use mitk::eps in most cases. - * @param verbose flag indicating if the user wants detailed console output or not. - * @return true, if all subsequent comparisons are true, false otherwise - */ - MITKPHOTOACOUSTICSLIB_EXPORT bool Equal(const Vector::Pointer leftHandSide, const Vector::Pointer rightHandSide, double eps, bool verbose); - } -} -#endif // MITKSMARTVECTOR_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVessel.h b/Modules/PhotoacousticsLib/include/mitkPAVessel.h deleted file mode 100644 index d75d0ed68c..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVessel.h +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKVESSEL_H -#define MITKVESSEL_H - -#include "mitkVector.h" -#include "mitkPAVesselMeanderStrategy.h" -#include "mitkPAInSilicoTissueVolume.h" -#include "mitkPAVector.h" -#include "mitkPAVesselProperties.h" -#include "mitkPAVesselDrawer.h" - -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT Vessel : public itk::LightObject - { - public: - mitkClassMacroItkParent(Vessel, itk::LightObject); - mitkNewMacro1Param(Self, VesselProperties::Pointer); - - /** - * Callback function definition of a VesselMeanderStrategy - */ - typedef void (VesselMeanderStrategy::*CalculateNewVesselPositionCallback) - (Vector::Pointer, double, std::mt19937*); - - /** - * @brief ExpandVessel makes this Vessel expand one step in its current direction. - * After expanding, the vessel will draw itself into the given InSilicoTissueVolume. - * - * @param volume volume for the vessel to draw itself in - * @param calculateNewPosition a callback function of the VesselMeanderStrategy class. - * It is used to calculate the final position after taking the step. - * @param bendingFactor a metric of how much the Vessel should bend. If set to 0 the vessel will go in a straight line. - * @param rng - */ - void ExpandVessel(mitk::pa::InSilicoTissueVolume::Pointer volume, - CalculateNewVesselPositionCallback calculateNewPosition, double bendingFactor, std::mt19937* rng); - - /** - * @brief CanBifurcate - * @return true if the Vessel is ready to Bifurcate() - */ - bool CanBifurcate(); - - /** - * @brief Bifurcate bifurcates this vessel into two new ones. Makes sure that the volume of the vessels stays the same. - * - * @return a new vessel split up from the current one. - */ - Vessel::Pointer Bifurcate(std::mt19937* rng); - - /** - * @brief IsFinished - * @return true if the vessel cannot expand any further - */ - bool IsFinished(); - - itkGetConstMacro(VesselProperties, VesselProperties::Pointer); - - protected: - Vessel(VesselProperties::Pointer parameters); - ~Vessel() override; - - private: - - const double MINIMUM_VESSEL_RADIUS = 0.1; - const double NEW_RADIUS_MINIMUM_RELATIVE_SIZE = 0.6; - const double NEW_RADIUS_MAXIMUM_RELATIVE_SIZE = 0.8; - - VesselMeanderStrategy::Pointer m_VesselMeanderStrategy; - bool m_Finished; - double m_WalkedDistance; - - std::uniform_real_distribution<> m_RangeDistribution; - std::uniform_real_distribution<> m_SignDistribution; - std::uniform_real_distribution<> m_RadiusRangeDistribution; - - int GetSign(std::mt19937* rng); - - VesselProperties::Pointer m_VesselProperties; - - VesselDrawer::Pointer m_VesselDrawer; - }; - - /** - * @brief Equal A function comparing two vessels for beeing equal - * - * @param rightHandSide A vessel to be compared - * @param leftHandSide A vessel to be compared - * @param eps tolarence for comparison. You can use mitk::eps in most cases. - * @param verbose flag indicating if the user wants detailed console output or not. - * @return true, if all subsequent comparisons are true, false otherwise - */ - MITKPHOTOACOUSTICSLIB_EXPORT bool Equal(const Vessel::Pointer leftHandSide, const Vessel::Pointer rightHandSide, double eps, bool verbose); - } -} -#endif // MITKVESSEL_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVesselDrawer.h b/Modules/PhotoacousticsLib/include/mitkPAVesselDrawer.h deleted file mode 100644 index 03453e9453..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVesselDrawer.h +++ /dev/null @@ -1,49 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKVESSELDRAWER_H -#define MITKVESSELDRAWER_H - -#include "mitkVector.h" -#include "mitkPAVesselMeanderStrategy.h" -#include "mitkPAInSilicoTissueVolume.h" -#include "mitkPAVector.h" -#include "mitkPAVesselProperties.h" - -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT VesselDrawer : public itk::LightObject - { - public: - mitkClassMacroItkParent(VesselDrawer, itk::LightObject); - itkFactorylessNewMacro(Self); - - void ExpandAndDrawVesselInVolume( - VesselProperties::Pointer properties, - InSilicoTissueVolume::Pointer volume); - - protected: - VesselDrawer(); - ~VesselDrawer() override; - - private: - }; - - } -} -#endif // MITKVESSELDRAWER_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVesselMeanderStrategy.h b/Modules/PhotoacousticsLib/include/mitkPAVesselMeanderStrategy.h deleted file mode 100644 index f8f551ba83..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVesselMeanderStrategy.h +++ /dev/null @@ -1,60 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKVESSELMEANDERSTRATEGY_H -#define MITKVESSELMEANDERSTRATEGY_H - -#include "mitkVector.h" -#include "mitkPAVector.h" - -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT VesselMeanderStrategy : public itk::LightObject - { - public: - mitkClassMacroItkParent(VesselMeanderStrategy, itk::LightObject); - itkFactorylessNewMacro(Self); - - /** - * @brief CalculateNewPositionInStraightLine calculates the new position by just following the direction vector. - * @param direction - * @param bendingFactor - * @param rng - */ - void CalculateNewDirectionVectorInStraightLine(Vector::Pointer direction, double bendingFactor, std::mt19937* rng); - - /** - * @brief CalculateRandomlyDivergingPosition calculates the new position by modifying the direction vector randomly, - * proportional to the selected bendingFactor. This means, that the vessels will bend in each expansion step, - * if bendingFactor > 0. - * - * @param direction - * @param bendingFactor - * @param rng - */ - void CalculateNewRandomlyDivergingDirectionVector(Vector::Pointer direction, double bendingFactor, std::mt19937* rng); - - protected: - VesselMeanderStrategy(); - ~VesselMeanderStrategy() override; - - const double RANDOMIZATION_PERCENTAGE = 0.4; - }; - } -} -#endif // MITKVESSELMEANDERSTRATEGY_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVesselProperties.h b/Modules/PhotoacousticsLib/include/mitkPAVesselProperties.h deleted file mode 100644 index 00bbaaf2ee..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVesselProperties.h +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPhotoacousticVesselParameters_H -#define MITKPhotoacousticVesselParameters_H - -#include - -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT VesselProperties : public itk::Object - { - public: - mitkClassMacroItkParent(VesselProperties, itk::Object); - itkFactorylessNewMacro(Self); - mitkNewMacro1Param(Self, Self::Pointer); - - itkGetMacro(PositionVector, Vector::Pointer); - itkGetMacro(DirectionVector, Vector::Pointer); - itkGetMacro(RadiusInVoxel, double); - itkGetMacro(AbsorptionCoefficient, double); - itkGetMacro(ScatteringCoefficient, double); - itkGetMacro(AnisotopyCoefficient, double); - itkGetMacro(BifurcationFrequency, double); - itkGetMacro(DoPartialVolume, bool); - - itkSetMacro(PositionVector, Vector::Pointer); - itkSetMacro(DirectionVector, Vector::Pointer); - itkSetMacro(RadiusInVoxel, double); - itkSetMacro(AbsorptionCoefficient, double); - itkSetMacro(ScatteringCoefficient, double); - itkSetMacro(AnisotopyCoefficient, double); - itkSetMacro(BifurcationFrequency, double); - itkSetMacro(DoPartialVolume, bool); - - protected: - VesselProperties(); - VesselProperties(Self::Pointer other); - ~VesselProperties() override; - - private: - Vector::Pointer m_PositionVector; - Vector::Pointer m_DirectionVector; - double m_RadiusInVoxel; - double m_AbsorptionCoefficient; - double m_ScatteringCoefficient; - double m_AnisotopyCoefficient; - double m_BifurcationFrequency; - bool m_DoPartialVolume; - }; - - /** - * @brief Equal A function comparing two VesselProperty instances for beeing equal - * - * @param rightHandSide A VesselProperty to be compared - * @param leftHandSide A Vesselproperty to be compared - * @param eps tolarence for comparison. You can use mitk::eps in most cases. - * @param verbose flag indicating if the user wants detailed console output or not. - * @return true, if all subsequent comparisons are true, false otherwise - */ - MITKPHOTOACOUSTICSLIB_EXPORT bool Equal(const VesselProperties::Pointer leftHandSide, const VesselProperties::Pointer rightHandSide, double eps, bool verbose); - } -} -#endif // MITKPhotoacousticVesselParameters_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVesselTree.h b/Modules/PhotoacousticsLib/include/mitkPAVesselTree.h deleted file mode 100644 index dbef42e6d9..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVesselTree.h +++ /dev/null @@ -1,67 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKVESSELSTRUCTURE_H -#define MITKVESSELSTRUCTURE_H - -//std includes -#include - -//mitk includes -#include "mitkPAVessel.h" -#include "mitkPAInSilicoTissueVolume.h" -#include - -//Includes for smart pointer usage -#include "mitkCommon.h" -#include "itkLightObject.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT VesselTree : public itk::LightObject - { - public: - mitkClassMacroItkParent(VesselTree, itk::LightObject); - mitkNewMacro1Param(Self, VesselProperties::Pointer); - - /** - * @brief Step Performs a simulation step, in which all subvessels of this VesselTree are expanded. - * - * @param volume - * @param calculateNewPosition - * @param bendingFactor - * @param rng - */ - void Step(InSilicoTissueVolume::Pointer volume, - Vessel::CalculateNewVesselPositionCallback calculateNewPosition, - double bendingFactor, std::mt19937* rng); - - /** - * @brief IsFinished - * @return true if no subvessel can be expanded. - */ - bool IsFinished(); - - itkGetConstMacro(CurrentSubvessels, std::vector*); - - protected: - VesselTree(VesselProperties::Pointer initialProperties); - ~VesselTree() override; - - private: - std::vector* m_CurrentSubvessels; - }; - - MITKPHOTOACOUSTICSLIB_EXPORT bool Equal(const VesselTree::Pointer leftHandSide, const VesselTree::Pointer rightHandSide, double eps, bool verbose); - } -} -#endif // MITKVESSELSTRUCTURE_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVolume.h b/Modules/PhotoacousticsLib/include/mitkPAVolume.h deleted file mode 100644 index 059b4df280..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVolume.h +++ /dev/null @@ -1,147 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTIC3dVOLUME_H -#define MITKPHOTOACOUSTIC3dVOLUME_H - -#include "MitkPhotoacousticsLibExports.h" - -//Includes for smart pointer usage -#include -#include - -namespace mitk -{ - namespace pa - { - /** - * @brief The Volume class is designed to encapsulate volumetric information and to provide convenience methods - * for data access and image conversions. - */ - class MITKPHOTOACOUSTICSLIB_EXPORT Volume : public itk::LightObject - { - public: - - mitkClassMacroItkParent(Volume, itk::LightObject); - - /** - *@brief returns smartpointer reference to a new instance of this objects. - * The given data array will be freed upon calling this constructor. - *@param data - *@param xDim - *@param yDim - *@param zDim - *@param spacing - *@return smartpointer reference to a new instance of this object - */ - static Volume::Pointer New(double* data, unsigned int xDim, unsigned int yDim, unsigned int zDim, double spacing); - - static Volume::Pointer New(mitk::Image::Pointer image); - - /** - * @brief GetData. Returns data at wanted position. For performance reasons, this method will not check, - * if the specified position it within the array. Please use the GetXDim(), GetYDim() and GetZDim() methods - * to check for yourself if necessary. - * - * @param x - * @param y - * @param z - * @return the data contained within the data array held by this Volume at - * positon x|y|z. - */ - double GetData(unsigned int x, unsigned int y, unsigned int z); - - /** - * Returns a const reference to the data encapsuled by this class. - */ - double* GetData() const; - - /** - * @brief SetData - * @param data - * @param x - * @param y - * @param z - */ - void SetData(double data, unsigned int x, unsigned int y, unsigned int z); - - /** - * @brief GetXDim - * @return size of x dimension of this Volume - */ - unsigned int GetXDim(); - - /** - * @brief GetYDim - * @return size of y dimension of this Volume - */ - unsigned int GetYDim(); - - /** - * @brief GetZDim - * @return size of z dimension of this Volume - */ - unsigned int GetZDim(); - - /** - *@brief returns the Volume instance as an mitk image - */ - Image::Pointer AsMitkImage(); - - /** - * @brief DeepCopy - * @return a deep copy of this Volume. the old volume remains intact and memory is NOT shared - * between the objects. - */ - Volume::Pointer DeepCopy(); - - /** - *@brief convenience method to enable consistent access to the dat array - *@return a 1d index from 3d pixel coordinates - */ - long long GetIndex(unsigned int x, unsigned int y, unsigned int z); - - double GetSpacing(); - - void SetSpacing(double spacing); - - protected: - /** - * @brief Initialize initializes this volume with the given pointer to the data array. - * It is assumed, that the array is of dimension xDim|yDim|zDim. - * The Photoacoustic3DVolume will handle memory management of the array and delete it on - * constructor call. - * - * @param data a pointer to the data array - * @param xDim x dimension of the data - * @param yDim y dimension of the data - * @param zDim z dimension of the data - * @param spacing spacing of the data - */ - Volume(double* data, unsigned int xDim, unsigned int yDim, unsigned int zDim, double spacing); - Volume(mitk::Image::Pointer image); - ~Volume() override; - - const int NUMBER_OF_SPATIAL_DIMENSIONS = 3; - - Image::Pointer m_InternalMitkImage; - - // this data is kept to enable fast access - unsigned int m_XDim; - unsigned int m_YDim; - unsigned int m_ZDim; - double* m_FastAccessDataPointer; - }; - } -} - -#endif // MITKPHOTOACOUSTIC3dVOLUME_H diff --git a/Modules/PhotoacousticsLib/include/mitkPAVolumeManipulator.h b/Modules/PhotoacousticsLib/include/mitkPAVolumeManipulator.h deleted file mode 100644 index 950a0ac28c..0000000000 --- a/Modules/PhotoacousticsLib/include/mitkPAVolumeManipulator.h +++ /dev/null @@ -1,61 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKPHOTOACOUSTIC3DVOLUMEMANIPULATOR_H -#define MITKPHOTOACOUSTIC3DVOLUMEMANIPULATOR_H - -#include -#include -#include "mitkPAVolume.h" -#include "mitkPAInSilicoTissueVolume.h" - -namespace mitk { - namespace pa { - class MITKPHOTOACOUSTICSLIB_EXPORT VolumeManipulator final - { - public: - - /** - * @brief ThresholdImage applies a binary threshold filter to this image. - * @param threshold - * @param image - */ - static void ThresholdImage(Volume::Pointer image, double threshold); - - /** - * @brief Multiplies the image with a given factor - * @param factor - * @param image - */ - static void MultiplyImage(Volume::Pointer image, double factor); - - /** - * @brief applies a Gaussian blur to an image - * @param sigma - * @param paVolume - */ - static void GaussianBlur3D(Volume::Pointer paVolume, double sigma); - - static void Log10Image(Volume::Pointer image); - - static void RescaleImage(InSilicoTissueVolume::Pointer image, double ratio); - - static Volume::Pointer RescaleImage(Volume::Pointer image, double ratio, double sigma); - - private: - VolumeManipulator(); - virtual ~VolumeManipulator(); - }; - } -} - -#endif // MITKPHOTOACOUSTIC3DVOLUMEMANIPULATOR_H diff --git a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVessel.cpp b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVessel.cpp deleted file mode 100644 index 3d2612927e..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVessel.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVessel.h" -#include -#include - -mitk::pa::Vessel::Vessel(VesselProperties::Pointer initialProperties) : - m_RangeDistribution(itk::Math::pi / 16, itk::Math::pi / 8), - m_SignDistribution(-1, 1) -{ - m_Finished = false; - //Copy this so it may be reused for other vessels. - m_VesselProperties = VesselProperties::New(initialProperties); - m_RadiusRangeDistribution = std::uniform_real_distribution<>(NEW_RADIUS_MINIMUM_RELATIVE_SIZE, - NEW_RADIUS_MAXIMUM_RELATIVE_SIZE); - m_VesselMeanderStrategy = VesselMeanderStrategy::New(); - m_WalkedDistance = 0; - m_VesselDrawer = VesselDrawer::New(); -} - -mitk::pa::Vessel::~Vessel() -{ - m_VesselProperties = nullptr; - m_VesselMeanderStrategy = nullptr; -} - -void mitk::pa::Vessel::ExpandVessel(InSilicoTissueVolume::Pointer volume, - CalculateNewVesselPositionCallback calculateNewPosition, double bendingFactor, std::mt19937* rng) -{ - m_VesselDrawer->ExpandAndDrawVesselInVolume(m_VesselProperties, volume); - (m_VesselMeanderStrategy->*calculateNewPosition)(m_VesselProperties->GetDirectionVector(), bendingFactor, rng); - m_WalkedDistance += (m_VesselProperties->GetDirectionVector()->GetNorm() / volume->GetSpacing()); -} - -bool mitk::pa::Vessel::CanBifurcate() -{ - return m_VesselProperties->GetBifurcationFrequency() < m_WalkedDistance; -} - -int mitk::pa::Vessel::GetSign(std::mt19937 *rng) -{ - if (m_SignDistribution(*rng) < 0) - return -1; - - return 1; -} - -mitk::pa::Vessel::Pointer mitk::pa::Vessel::Bifurcate(std::mt19937* rng) -{ - VesselProperties::Pointer vesselParams = VesselProperties::New(m_VesselProperties); - double thetaChange = m_RangeDistribution(*rng) * GetSign(rng); - double phiChange = m_RangeDistribution(*rng) * GetSign(rng); - - vesselParams->GetDirectionVector()->Rotate(thetaChange, phiChange); - m_VesselProperties->GetDirectionVector()->Rotate(-thetaChange, -phiChange); - - double newRadius = m_RadiusRangeDistribution(*rng)*m_VesselProperties->GetRadiusInVoxel(); - vesselParams->SetRadiusInVoxel(newRadius); - m_VesselProperties->SetRadiusInVoxel( - sqrt(m_VesselProperties->GetRadiusInVoxel()*m_VesselProperties->GetRadiusInVoxel() - newRadius*newRadius)); - - m_WalkedDistance = 0; - - return Vessel::New(vesselParams); -} - -bool mitk::pa::Vessel::IsFinished() -{ - return m_VesselProperties->GetRadiusInVoxel() < MINIMUM_VESSEL_RADIUS; -} - -bool mitk::pa::Equal(const Vessel::Pointer leftHandSide, const Vessel::Pointer rightHandSide, double eps, bool verbose) -{ - MITK_INFO(verbose) << "=== mitk::pa::Vessel Equal ==="; - - if (rightHandSide.IsNull() || leftHandSide.IsNull()) - { - MITK_INFO(verbose) << "Cannot compare nullpointers"; - return false; - } - - if (leftHandSide->IsFinished() != rightHandSide->IsFinished()) - { - MITK_INFO(verbose) << "Not same finished state."; - return false; - } - - if (leftHandSide->CanBifurcate() != rightHandSide->CanBifurcate()) - { - MITK_INFO(verbose) << "Not same bifurcation state."; - return false; - } - - if (!Equal(leftHandSide->GetVesselProperties(), rightHandSide->GetVesselProperties(), eps, verbose)) - { - MITK_INFO(verbose) << "Vesselproperties not equal"; - return false; - } - - return true; -} diff --git a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselMeanderStrategy.cpp b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselMeanderStrategy.cpp deleted file mode 100644 index fdd10f8cda..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselMeanderStrategy.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVesselMeanderStrategy.h" - -mitk::pa::VesselMeanderStrategy::VesselMeanderStrategy() -{ -} - -mitk::pa::VesselMeanderStrategy::~VesselMeanderStrategy() -{ -} - -void mitk::pa::VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine(Vector::Pointer direction, double /*bendingFactor*/, std::mt19937* rng) -{ - if (direction->GetNorm() <= mitk::eps) - { - direction->Randomize(rng); - } -} - -void mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector(Vector::Pointer direction, double bendingFactor, std::mt19937* rng) -{ - if (direction->GetNorm() <= mitk::eps) - { - direction->Randomize(rng); - } - - direction->RandomizeByPercentage(RANDOMIZATION_PERCENTAGE, bendingFactor, rng); - - direction->Normalize(); -} diff --git a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselProperties.cpp b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselProperties.cpp deleted file mode 100644 index fca82cfe7b..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselProperties.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVesselProperties.h" - -mitk::pa::VesselProperties::VesselProperties() -{ - m_PositionVector = Vector::New(); - m_DirectionVector = Vector::New(); - m_RadiusInVoxel = 0; - m_AbsorptionCoefficient = 0; - m_ScatteringCoefficient = 0; - m_AnisotopyCoefficient = 0; - m_BifurcationFrequency = 0; - m_DoPartialVolume = false; -} - -mitk::pa::VesselProperties::VesselProperties(Self::Pointer other) -{ - m_PositionVector = other->GetPositionVector()->Clone(); - m_DirectionVector = other->GetDirectionVector()->Clone(); - m_RadiusInVoxel = other->GetRadiusInVoxel(); - m_AbsorptionCoefficient = other->GetAbsorptionCoefficient(); - m_ScatteringCoefficient = other->GetScatteringCoefficient(); - m_AnisotopyCoefficient = other->GetAnisotopyCoefficient(); - m_BifurcationFrequency = other->GetBifurcationFrequency(); - m_DoPartialVolume = other->GetDoPartialVolume(); -} - -mitk::pa::VesselProperties::~VesselProperties() -{ - m_PositionVector = nullptr; - m_DirectionVector = nullptr; -} - -bool mitk::pa::Equal(const VesselProperties::Pointer leftHandSide, const VesselProperties::Pointer rightHandSide, - double eps, bool verbose) -{ - MITK_INFO(verbose) << "=== mitk::pa::VesselProperties Equal ==="; - - if (rightHandSide.IsNull() || leftHandSide.IsNull()) - { - MITK_INFO(verbose) << "Cannot compare nullpointers"; - return false; - } - - if (leftHandSide->GetAbsorptionCoefficient() - rightHandSide->GetAbsorptionCoefficient() > eps) - { - MITK_INFO(verbose) << "Not the same AbsorptionCoefficient."; - return false; - } - - if (leftHandSide->GetAnisotopyCoefficient() - rightHandSide->GetAnisotopyCoefficient() > eps) - { - MITK_INFO(verbose) << "Not the same AnisotropyCoefficient."; - return false; - } - - if (leftHandSide->GetBifurcationFrequency() - rightHandSide->GetBifurcationFrequency() > eps) - { - MITK_INFO(verbose) << "Not the same BifurcationFrequency."; - return false; - } - - if (leftHandSide->GetRadiusInVoxel() - rightHandSide->GetRadiusInVoxel() > eps) - { - MITK_INFO(verbose) << "Not the same RadiusInVoxel."; - return false; - } - - if (leftHandSide->GetScatteringCoefficient() - rightHandSide->GetScatteringCoefficient() > eps) - { - MITK_INFO(verbose) << "Not the same ScatteringCoefficient."; - return false; - } - - if (!Equal(leftHandSide->GetPositionVector(), rightHandSide->GetPositionVector(), eps, verbose)) - { - MITK_INFO(verbose) << "PositionVector not equal"; - return false; - } - - if (!Equal(leftHandSide->GetDirectionVector(), rightHandSide->GetDirectionVector(), eps, verbose)) - { - MITK_INFO(verbose) << "DirectionVector not equal"; - return false; - } - - if (!(leftHandSide->GetDoPartialVolume() == rightHandSide->GetDoPartialVolume())) - { - MITK_INFO(verbose) << "GetDoPartialVolume not equal"; - return false; - } - - return true; -} diff --git a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselTree.cpp b/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselTree.cpp deleted file mode 100644 index 31650d26de..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Vessel/mitkPAVesselTree.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVesselTree.h" -#include "thread" - -mitk::pa::VesselTree::VesselTree(VesselProperties::Pointer initialProperties) -{ - m_CurrentSubvessels = new std::vector(); - Vessel::Pointer tmpVessel = Vessel::New(initialProperties); - m_CurrentSubvessels->push_back(tmpVessel); -} - -mitk::pa::VesselTree::~VesselTree() -{ - m_CurrentSubvessels->clear(); - delete m_CurrentSubvessels; - m_CurrentSubvessels = nullptr; -} - -void mitk::pa::VesselTree::Step(mitk::pa::InSilicoTissueVolume::Pointer volume, - Vessel::CalculateNewVesselPositionCallback calculateNewPosition, double bendingFactor, std::mt19937* rng) -{ - std::vector newVessels; - - for (unsigned int vesselTreeIndex = 0; vesselTreeIndex < m_CurrentSubvessels->size(); vesselTreeIndex++) - { - Vessel::Pointer currentVessel = m_CurrentSubvessels->at(vesselTreeIndex); - if (!currentVessel->IsFinished()) - { - currentVessel->ExpandVessel(volume, calculateNewPosition, bendingFactor, rng); - if (currentVessel->CanBifurcate()) - { - newVessels.push_back(currentVessel->Bifurcate(rng)); - } - } - } - - for (unsigned int newVesselsIndex = 0; newVesselsIndex < newVessels.size(); newVesselsIndex++) - { - m_CurrentSubvessels->push_back(newVessels.at(newVesselsIndex)); - } -} - -bool mitk::pa::VesselTree::IsFinished() -{ - for (unsigned int vesselTreeIndex = 0; vesselTreeIndex < m_CurrentSubvessels->size(); vesselTreeIndex++) - { - if (!m_CurrentSubvessels->at(vesselTreeIndex)->IsFinished()) - return false; - } - return true; -} - -bool mitk::pa::Equal(const VesselTree::Pointer leftHandSide, const VesselTree::Pointer rightHandSide, double eps, bool verbose) -{ - MITK_INFO(verbose) << "=== mitk::pa::Vessel Equal ==="; - - if (rightHandSide.IsNull() || leftHandSide.IsNull()) - { - MITK_INFO(verbose) << "Cannot compare nullpointers"; - return false; - } - - if (leftHandSide->IsFinished() != rightHandSide->IsFinished()) - { - MITK_INFO(verbose) << "Not same finished state."; - return false; - } - - if (leftHandSide->GetCurrentSubvessels()->size() != rightHandSide->GetCurrentSubvessels()->size()) - { - MITK_INFO(verbose) << "Not same number of subvessels in the vesseltree."; - return false; - } - - for (unsigned int vesselIdx = 0, numVessels = leftHandSide->GetCurrentSubvessels()->size(); vesselIdx < numVessels; ++vesselIdx) - { - if (!Equal(leftHandSide->GetCurrentSubvessels()->at(vesselIdx), rightHandSide->GetCurrentSubvessels()->at(vesselIdx), eps, verbose)) - { - MITK_INFO(verbose) << "At least one vessel was not equal or the vessel list were not in order."; - return false; - } - } - - return true; -} diff --git a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAComposedVolume.cpp b/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAComposedVolume.cpp deleted file mode 100644 index f515bc9f17..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAComposedVolume.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include "mitkPAComposedVolume.h" -#include "mitkIOUtil.h" -#include "mitkImageReadAccessor.h" -#include - -mitk::pa::ComposedVolume::ComposedVolume(InSilicoTissueVolume::Pointer groundTruthVolume) -{ - m_GroundTruthVolume = groundTruthVolume; - m_FluenceComponents = 0; - m_FluenceValues.clear(); -} - -mitk::pa::ComposedVolume::~ComposedVolume() -{ - m_FluenceValues.clear(); -} - -int mitk::pa::ComposedVolume::GetNumberOfFluenceComponents() -{ - return m_FluenceComponents; -} - -int mitk::pa::ComposedVolume::GetYOffsetForFluenceComponentInPixels(int fluenceComponent) -{ - if (fluenceComponent >= m_FluenceComponents) - mitkThrow() << "Index out of bounds exception: There were less fluence components in the composed volume than the number you tried to access."; - - return (int)(m_FluenceValues.at(fluenceComponent)->GetYOffsetInCentimeters() / - m_GroundTruthVolume->GetTissueParameters()->GetVoxelSpacingInCentimeters()); -} - -double mitk::pa::ComposedVolume::GetFluenceValue(int fluenceComponent, int x, int y, int z) -{ - if (fluenceComponent >= m_FluenceComponents) - mitkThrow() << "Index out of bounds exception: There were less fluence components in the composed volume than the number you tried to access."; - - return m_FluenceValues.at(fluenceComponent)->GetFluenceValue()->GetData(x, y + GetYOffsetForFluenceComponentInPixels(fluenceComponent), z); -} - -void mitk::pa::ComposedVolume::AddSlice(mitk::pa::FluenceYOffsetPair::Pointer pairToAdd) -{ - m_FluenceValues.push_back(pairToAdd); - m_FluenceComponents++; -} - -void mitk::pa::ComposedVolume::Sort() -{ - std::sort(m_FluenceValues.begin(), m_FluenceValues.end(), [](const mitk::pa::FluenceYOffsetPair::Pointer& struct1, - const mitk::pa::FluenceYOffsetPair::Pointer& struct2) - { - return (struct1->GetYOffsetInCentimeters() < struct2->GetYOffsetInCentimeters()); - }); -} diff --git a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAFluenceYOffsetPair.cpp b/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAFluenceYOffsetPair.cpp deleted file mode 100644 index 73cc7edfb6..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAFluenceYOffsetPair.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include "mitkPAFluenceYOffsetPair.h" - -mitk::pa::FluenceYOffsetPair::FluenceYOffsetPair(mitk::pa::Volume::Pointer fluenceValue, double yOffset) -{ - m_FluenceValue = fluenceValue; - m_YOffsetInCentimeters = yOffset; -} - -mitk::pa::FluenceYOffsetPair::~FluenceYOffsetPair() -{ - m_FluenceValue = nullptr; -} - -mitk::pa::FluenceYOffsetPair::FluenceYOffsetPair(const mitk::pa::FluenceYOffsetPair::Pointer other) -{ - m_FluenceValue = other->GetFluenceValue(); - m_YOffsetInCentimeters = other->GetYOffsetInCentimeters(); -} - -mitk::pa::Volume::Pointer mitk::pa::FluenceYOffsetPair::GetFluenceValue() const -{ - return m_FluenceValue; -} - -double mitk::pa::FluenceYOffsetPair::GetYOffsetInCentimeters() const -{ - return m_YOffsetInCentimeters; -} diff --git a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAInSilicoTissueVolume.cpp b/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAInSilicoTissueVolume.cpp deleted file mode 100644 index 331c90c03b..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAInSilicoTissueVolume.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -mitk::pa::InSilicoTissueVolume::InSilicoTissueVolume(TissueGeneratorParameters::Pointer parameters, std::mt19937* rng) -{ - { - unsigned int xDim = parameters->GetXDim(); - unsigned int yDim = parameters->GetYDim(); - unsigned int zDim = parameters->GetZDim(); - m_TDim = 4; - unsigned int size = xDim * yDim * zDim; - auto* absorptionArray = new double[size]; - auto* scatteringArray = new double[size]; - auto* anisotropyArray = new double[size]; - auto* segmentationArray = new double[size]; - - m_InitialBackgroundAbsorption = (parameters->GetMinBackgroundAbsorption() + parameters->GetMaxBackgroundAbsorption()) / 2; - m_Rng = rng; - - for (unsigned int index = 0; index < size; index++) - { - absorptionArray[index] = m_InitialBackgroundAbsorption; - scatteringArray[index] = parameters->GetBackgroundScattering(); - anisotropyArray[index] = parameters->GetBackgroundAnisotropy(); - segmentationArray[index] = SegmentationType::BACKGROUND; - } - - m_AbsorptionVolume = Volume::New(absorptionArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); - m_ScatteringVolume = Volume::New(scatteringArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); - m_AnisotropyVolume = Volume::New(anisotropyArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); - m_SegmentationVolume = Volume::New(segmentationArray, xDim, yDim, zDim, parameters->GetVoxelSpacingInCentimeters()); - } - - m_TissueParameters = parameters; - m_PropertyList = mitk::PropertyList::New(); - UpdatePropertyList(); -} - -void mitk::pa::InSilicoTissueVolume::UpdatePropertyList() -{ - //Set properties - AddIntProperty("mcflag", m_TissueParameters->GetMCflag()); - AddIntProperty("launchflag", m_TissueParameters->GetMCLaunchflag()); - AddIntProperty("boundaryflag", m_TissueParameters->GetMCBoundaryflag()); - AddDoubleProperty("launchPointX", m_TissueParameters->GetMCLaunchPointX()); - AddDoubleProperty("launchPointY", m_TissueParameters->GetMCLaunchPointY()); - AddDoubleProperty("launchPointZ", m_TissueParameters->GetMCLaunchPointZ()); - AddDoubleProperty("focusPointX", m_TissueParameters->GetMCFocusPointX()); - AddDoubleProperty("focusPointY", m_TissueParameters->GetMCFocusPointY()); - AddDoubleProperty("focusPointZ", m_TissueParameters->GetMCFocusPointZ()); - AddDoubleProperty("trajectoryVectorX", m_TissueParameters->GetMCTrajectoryVectorX()); - AddDoubleProperty("trajectoryVectorY", m_TissueParameters->GetMCTrajectoryVectorY()); - AddDoubleProperty("trajectoryVectorZ", m_TissueParameters->GetMCTrajectoryVectorZ()); - AddDoubleProperty("radius", m_TissueParameters->GetMCRadius()); - AddDoubleProperty("waist", m_TissueParameters->GetMCWaist()); - AddDoubleProperty("partialVolume", m_TissueParameters->GetDoPartialVolume()); - AddDoubleProperty("standardTissueAbsorptionMin", m_TissueParameters->GetMinBackgroundAbsorption()); - AddDoubleProperty("standardTissueAbsorptionMax", m_TissueParameters->GetMaxBackgroundAbsorption()); - AddDoubleProperty("standardTissueScattering", m_TissueParameters->GetBackgroundScattering()); - AddDoubleProperty("standardTissueAnisotropy", m_TissueParameters->GetBackgroundAnisotropy()); - AddDoubleProperty("airThickness", m_TissueParameters->GetAirThicknessInMillimeters()); - AddDoubleProperty("skinThickness", m_TissueParameters->GetSkinThicknessInMillimeters()); -} - -mitk::pa::InSilicoTissueVolume::InSilicoTissueVolume( - Volume::Pointer absorptionVolume, - Volume::Pointer scatteringVolume, - Volume::Pointer anisotropyVolume, - Volume::Pointer segmentationVolume, - TissueGeneratorParameters::Pointer tissueParameters, - mitk::PropertyList::Pointer propertyList) -{ - m_AbsorptionVolume = absorptionVolume; - m_ScatteringVolume = scatteringVolume; - m_AnisotropyVolume = anisotropyVolume; - m_SegmentationVolume = segmentationVolume; - m_TissueParameters = tissueParameters; - m_PropertyList = propertyList; - if (m_SegmentationVolume.IsNotNull()) - m_TDim = 4; - else - m_TDim = 3; -} - -double mitk::pa::InSilicoTissueVolume::GetSpacing() -{ - return m_AbsorptionVolume->GetSpacing(); -} - -void mitk::pa::InSilicoTissueVolume::SetSpacing(double spacing) -{ - m_AbsorptionVolume->SetSpacing(spacing); - m_ScatteringVolume->SetSpacing(spacing); - m_AnisotropyVolume->SetSpacing(spacing); - if (m_SegmentationVolume.IsNotNull()) - { - m_SegmentationVolume->SetSpacing(spacing); - } -} - -void mitk::pa::InSilicoTissueVolume::AddDoubleProperty(std::string label, double value) -{ - m_PropertyList->SetDoubleProperty(label.c_str(), value); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New(label)); -} - -void mitk::pa::InSilicoTissueVolume::AddIntProperty(std::string label, int value) -{ - m_PropertyList->SetIntProperty(label.c_str(), value); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New(label)); -} - -mitk::Image::Pointer mitk::pa::InSilicoTissueVolume::ConvertToMitkImage() -{ - mitk::Image::Pointer resultImage = mitk::Image::New(); - mitk::PixelType TPixel = mitk::MakeScalarPixelType(); - auto* dimensionsOfImage = new unsigned int[4]; - - // Copy dimensions - dimensionsOfImage[0] = m_TissueParameters->GetYDim(); - dimensionsOfImage[1] = m_TissueParameters->GetXDim(); - dimensionsOfImage[2] = m_TissueParameters->GetZDim(); - dimensionsOfImage[3] = m_TDim; - - resultImage->Initialize(TPixel, 4, dimensionsOfImage, 1); - - mitk::Vector3D spacing; - spacing.Fill(m_TissueParameters->GetVoxelSpacingInCentimeters()); - resultImage->SetSpacing(spacing); - - resultImage->SetImportVolume(m_AbsorptionVolume->GetData(), 0, 0, mitk::Image::CopyMemory); - resultImage->SetImportVolume(m_ScatteringVolume->GetData(), 1, 0, mitk::Image::CopyMemory); - resultImage->SetImportVolume(m_AnisotropyVolume->GetData(), 2, 0, mitk::Image::CopyMemory); - if (m_TDim > 3) - { - resultImage->SetImportVolume(m_SegmentationVolume->GetData(), 3, 0, mitk::Image::CopyMemory); - } - - resultImage->SetPropertyList(m_PropertyList); - - return resultImage; -} - -mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::InSilicoTissueVolume::New( - Volume::Pointer absorptionVolume, - Volume::Pointer scatteringVolume, - Volume::Pointer anisotropyVolume, - Volume::Pointer segmentationVolume, - TissueGeneratorParameters::Pointer tissueParameters, - mitk::PropertyList::Pointer propertyList) -{ - InSilicoTissueVolume::Pointer smartPtr = new InSilicoTissueVolume( - absorptionVolume, scatteringVolume, anisotropyVolume, segmentationVolume, - tissueParameters, propertyList); - smartPtr->UnRegister(); - return smartPtr; -} - -mitk::pa::InSilicoTissueVolume::~InSilicoTissueVolume() -{ - m_AbsorptionVolume = nullptr; - m_ScatteringVolume = nullptr; - m_AnisotropyVolume = nullptr; - m_SegmentationVolume = nullptr; - m_TissueParameters = nullptr; - m_PropertyList = nullptr; -} - -void mitk::pa::InSilicoTissueVolume::SetVolumeValues(int x, int y, int z, double absorption, double scattering, double anisotropy) -{ - if (IsInsideVolume(x, y, z)) - { - m_AbsorptionVolume->SetData(absorption, x, y, z); - m_ScatteringVolume->SetData(scattering, x, y, z); - m_AnisotropyVolume->SetData(anisotropy, x, y, z); - } -} - -void mitk::pa::InSilicoTissueVolume::SetVolumeValues(int x, int y, int z, double absorption, double scattering, double anisotropy, SegmentationType segmentType) -{ - if (IsInsideVolume(x, y, z)) - { - m_AbsorptionVolume->SetData(absorption, x, y, z); - m_ScatteringVolume->SetData(scattering, x, y, z); - m_AnisotropyVolume->SetData(anisotropy, x, y, z); - if (m_SegmentationVolume.IsNotNull()) - { - m_SegmentationVolume->SetData(segmentType, x, y, z); - } - } -} - -bool mitk::pa::InSilicoTissueVolume::IsInsideVolume(int x, int y, int z) -{ - return x >= 0 && x < m_TissueParameters->GetXDim() && - y >= 0 && y < m_TissueParameters->GetYDim() && - z >= 0 && z < m_TissueParameters->GetZDim(); -} - -mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetAbsorptionVolume() -{ - return m_AbsorptionVolume; -} - -mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetSegmentationVolume() -{ - return m_SegmentationVolume; -} - -void mitk::pa::InSilicoTissueVolume::FinalizeVolume() -{ - AddSkinAndAirLayers(); - - // If specified, randomize all tissue parameters - if (m_TissueParameters->GetRandomizePhysicalProperties()) - { - RandomizeTissueCoefficients(m_TissueParameters->GetUseRngSeed(), - m_TissueParameters->GetRngSeed(), - m_TissueParameters->GetRandomizePhysicalPropertiesPercentage()); - } - - unsigned int xDim = m_TissueParameters->GetXDim(); - unsigned int yDim = m_TissueParameters->GetYDim(); - unsigned int zDim = m_TissueParameters->GetZDim(); - - std::uniform_real_distribution randomBackgroundAbsorptionDistribution( - m_TissueParameters->GetMinBackgroundAbsorption(), m_TissueParameters->GetMaxBackgroundAbsorption()); - - for (unsigned int z = 0; z < zDim; z++) - { - for (unsigned int y = 0; y < yDim; y++) - { - for (unsigned int x = 0; x < xDim; x++) - { - if (fabs(m_AbsorptionVolume->GetData(x, y, z) - m_InitialBackgroundAbsorption) < mitk::eps) - { - m_AbsorptionVolume->SetData(randomBackgroundAbsorptionDistribution(*m_Rng), x, y, z); - } - } - } - } -} - -void mitk::pa::InSilicoTissueVolume::AddSkinAndAirLayers() -{ - //Calculate the index location according to thickness in cm - double airvoxel = (m_TissueParameters->GetAirThicknessInMillimeters() / m_TissueParameters->GetVoxelSpacingInCentimeters()) / 10; - double skinvoxel = airvoxel + (m_TissueParameters->GetSkinThicknessInMillimeters() / m_TissueParameters->GetVoxelSpacingInCentimeters()) / 10; - - for (int y = 0; y < m_TissueParameters->GetYDim(); y++) - { - for (int x = 0; x < m_TissueParameters->GetXDim(); x++) - { - // Add air from index 0 to airvoxel - if (m_TissueParameters->GetAirThicknessInMillimeters() > mitk::eps) - { - FillZLayer(x, y, 0, airvoxel, - m_TissueParameters->GetAirAbsorption(), - m_TissueParameters->GetAirScattering(), - m_TissueParameters->GetAirAnisotropy(), - SegmentationType::AIR); - } - - //Add skin from index airvoxel to skinvoxel - if (m_TissueParameters->GetSkinThicknessInMillimeters() > mitk::eps) - { - FillZLayer(x, y, airvoxel, skinvoxel, - m_TissueParameters->GetSkinAbsorption(), - m_TissueParameters->GetSkinScattering(), - m_TissueParameters->GetSkinAnisotropy(), - SegmentationType::SKIN); - } - } - } -} - -void mitk::pa::InSilicoTissueVolume::FillZLayer(int x, int y, double startIdx, double endIdx, - double absorption, double scattering, double anisotropy, - SegmentationType segmentationType) -{ - for (int z = startIdx; z < endIdx; z++) - { - if (IsInsideVolume(x, y, z)) - { - if (endIdx - z < 1) - { - //Simulate partial volume effects - m_AbsorptionVolume->SetData((1 - (endIdx - z)) * - m_AbsorptionVolume->GetData(x, y, z) + (endIdx - z) * absorption, x, y, z); - m_ScatteringVolume->SetData((1 - (endIdx - z)) * - m_ScatteringVolume->GetData(x, y, z) + (endIdx - z) * scattering, x, y, z); - m_AnisotropyVolume->SetData((1 - (endIdx - z)) * - m_AnisotropyVolume->GetData(x, y, z) + (endIdx - z) * anisotropy, x, y, z); - if (endIdx - z > 0.5) - { - //Only put the segmentation label if more than half of the partial volume is the wanted tissue type - if (m_SegmentationVolume.IsNotNull()) - { - m_SegmentationVolume->SetData(segmentationType, x, y, z); - } - } - } - else - { - m_AbsorptionVolume->SetData(absorption, x, y, z); - m_ScatteringVolume->SetData(scattering, x, y, z); - m_AnisotropyVolume->SetData(anisotropy, x, y, z); - if (m_SegmentationVolume.IsNotNull()) - { - m_SegmentationVolume->SetData(segmentationType, x, y, z); - } - } - } - } -} - -void mitk::pa::InSilicoTissueVolume::RandomizeTissueCoefficients(long rngSeed, bool useRngSeed, double percentage) -{ - std::mt19937 rng; - std::random_device randomDevice; - if (useRngSeed) - { - rng.seed(rngSeed); - } - else - { - if (randomDevice.entropy() > 0.1) - { - rng.seed(randomDevice()); - } - else - { - rng.seed(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); - } - } - std::normal_distribution<> percentageDistribution(1, percentage / 100); - - for (int y = 0; y < m_TissueParameters->GetYDim(); y++) - { - for (int x = 0; x < m_TissueParameters->GetXDim(); x++) - { - for (int z = 0; z < m_TissueParameters->GetZDim(); z++) - { - m_AbsorptionVolume->SetData(m_AbsorptionVolume->GetData(x, y, z) * percentageDistribution(rng), x, y, z); - m_ScatteringVolume->SetData(m_ScatteringVolume->GetData(x, y, z) * percentageDistribution(rng), x, y, z); - } - } - } -} - -mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetScatteringVolume() -{ - return m_ScatteringVolume; -} - -mitk::pa::Volume::Pointer mitk::pa::InSilicoTissueVolume::GetAnisotropyVolume() -{ - return m_AnisotropyVolume; -} - -void mitk::pa::InSilicoTissueVolume::SetAbsorptionVolume(Volume::Pointer volume) -{ - m_AbsorptionVolume = volume; -} - -void mitk::pa::InSilicoTissueVolume::SetScatteringVolume(Volume::Pointer volume) -{ - m_ScatteringVolume = volume; -} - -void mitk::pa::InSilicoTissueVolume::SetAnisotropyVolume(Volume::Pointer volume) -{ - m_AnisotropyVolume = volume; -} - -void mitk::pa::InSilicoTissueVolume::SetSegmentationVolume(Volume::Pointer volume) -{ - m_SegmentationVolume = volume; -} diff --git a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAVolume.cpp b/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAVolume.cpp deleted file mode 100644 index 93fade9690..0000000000 --- a/Modules/PhotoacousticsLib/src/Domain/Volume/mitkPAVolume.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVolume.h" -#include -#include -#include - -mitk::pa::Volume::Volume(double* data, - unsigned int xDim, unsigned int yDim, unsigned int zDim, double spacing) -{ - MITK_INFO << "Initialized by data*"; - if (data == nullptr) - mitkThrow() << "You may not initialize a mitk::Volume with a nullptr"; - m_InternalMitkImage = mitk::Image::New(); - - auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS]; - dimensions[0] = yDim; - dimensions[1] = xDim; - dimensions[2] = zDim; - m_XDim = xDim; - m_YDim = yDim; - m_ZDim = zDim; - mitk::PixelType pixelType = mitk::MakeScalarPixelType(); - - m_InternalMitkImage->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions); - m_InternalMitkImage->SetImportVolume(data, Image::ImportMemoryManagementType::CopyMemory); - - SetSpacing(spacing); - - m_FastAccessDataPointer = GetData(); - - delete data; -} - -mitk::pa::Volume::Volume(mitk::Image::Pointer image) -{ - MITK_INFO << "Initialized by mitk::Image"; - - if (image.IsNull()) - mitkThrow() << "You may not initialize a mitk::Volume with a null reference to an mitk image"; - - unsigned int* dimensions = image->GetDimensions(); - m_YDim = dimensions[0]; - m_XDim = dimensions[1]; - m_ZDim = dimensions[2]; - - m_InternalMitkImage = image; - - m_FastAccessDataPointer = GetData(); -} - -double mitk::pa::Volume::GetSpacing() -{ - return m_InternalMitkImage->GetGeometry()->GetSpacing()[0]; -} - -void mitk::pa::Volume::SetSpacing(double spacing) -{ - const mitk::ScalarType spacingArray[]{ spacing, spacing, spacing }; - m_InternalMitkImage->SetSpacing(spacingArray); -} - -mitk::pa::Volume::~Volume() -{ - m_InternalMitkImage = nullptr; -} - -mitk::pa::Volume::Pointer mitk::pa::Volume::New(double* data, unsigned int xDim, unsigned int yDim, unsigned int zDim, double spacing) -{ - mitk::pa::Volume::Pointer smartPtr = new mitk::pa::Volume(data, xDim, yDim, zDim, spacing); - smartPtr->UnRegister(); - return smartPtr; -} - -mitk::pa::Volume::Pointer mitk::pa::Volume::New(mitk::Image::Pointer image) -{ - mitk::pa::Volume::Pointer smartPtr = new mitk::pa::Volume(image); - smartPtr->UnRegister(); - return smartPtr; -} - -mitk::Image::Pointer mitk::pa::Volume::AsMitkImage() -{ - return m_InternalMitkImage; -} - -mitk::pa::Volume::Pointer mitk::pa::Volume::DeepCopy() -{ - long length = GetXDim()*GetYDim()*GetZDim(); - auto* data = new double[length]; - memcpy(data, GetData(), length * sizeof(double)); - - return mitk::pa::Volume::New(data, GetXDim(), GetYDim(), GetZDim(), GetSpacing()); -} - -double mitk::pa::Volume::GetData(unsigned int x, unsigned int y, unsigned int z) -{ - return m_FastAccessDataPointer[GetIndex(x, y, z)]; -} - -void mitk::pa::Volume::SetData(double data, unsigned int x, unsigned int y, unsigned int z) -{ - m_FastAccessDataPointer[GetIndex(x, y, z)] = data; -} - -unsigned int mitk::pa::Volume::GetXDim() -{ - return m_XDim; -} - -unsigned int mitk::pa::Volume::GetYDim() -{ - return m_YDim; -} - -unsigned int mitk::pa::Volume::GetZDim() -{ - return m_ZDim; -} - -double* mitk::pa::Volume::GetData() const -{ - mitk::ImageWriteAccessor imgRead(m_InternalMitkImage, m_InternalMitkImage->GetVolumeData()); - return (double*)imgRead.GetData(); -} - -long long mitk::pa::Volume::GetIndex(unsigned int x, unsigned int y, unsigned int z) -{ -#ifdef _DEBUG - - if (x < 0 || x >(GetXDim() - 1) || y < 0 || y >(GetYDim() - 1) || z < 0 || z >(GetZDim() - 1)) - { - MITK_ERROR << "Index out of bounds at " << x << "|" << y << "|" << z; - mitkThrow() << "Index out of bounds exception!"; - } - -#endif - return ((long long)z) * m_XDim * m_YDim + ((long long)x) * m_YDim + ((long long)y); -} diff --git a/Modules/PhotoacousticsLib/src/Generator/mitkPANoiseGenerator.cpp b/Modules/PhotoacousticsLib/src/Generator/mitkPANoiseGenerator.cpp deleted file mode 100644 index 1ba0e43613..0000000000 --- a/Modules/PhotoacousticsLib/src/Generator/mitkPANoiseGenerator.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPANoiseGenerator.h" -#include "mitkPAIOUtil.h" -#include "mitkPAExceptions.h" -#include -#include -#include - -void mitk::pa::NoiseGenerator::ApplyNoiseModel(mitk::pa::Volume::Pointer image, double detectorNoise, double speckleNoise) -{ - if (detectorNoise < 0 || speckleNoise < 0) - throw mitk::pa::InvalidInputException("detectorNoise must be >= 0 and speckleNoise must be >= 0"); - - if (detectorNoise < mitk::eps && speckleNoise < mitk::eps) - return; - - std::mt19937 rng; - std::random_device randomDevice; - if (randomDevice.entropy() > mitk::eps) - { - rng.seed(randomDevice()); - } - else - { - rng.seed(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); - } - std::normal_distribution<> detector(detectorNoise / 2, detectorNoise / 2); - std::normal_distribution<> speckle(1, speckleNoise); - - unsigned int negativecounter = 0; - - double* data = image->GetData(); - - for (unsigned int x = 0, xLength = image->GetXDim(); x < xLength; x++) - for (unsigned int y = 0, yLength = image->GetYDim(); y < yLength; y++) - for (unsigned int z = 0, zLength = image->GetZDim(); z < zLength; z++) - { - double additiveNoise = detector(rng); - - double multiplicativeNoise = speckle(rng); - - double newSignal = (data[image->GetIndex(x, y, z)] + additiveNoise)*multiplicativeNoise; - - if (newSignal <= mitk::eps) - { - newSignal = mitk::eps; - negativecounter++; - } - - data[image->GetIndex(x, y, z)] = newSignal; - } -} diff --git a/Modules/PhotoacousticsLib/src/Generator/mitkPAPhantomTissueGenerator.cpp b/Modules/PhotoacousticsLib/src/Generator/mitkPAPhantomTissueGenerator.cpp deleted file mode 100644 index e129ec805a..0000000000 --- a/Modules/PhotoacousticsLib/src/Generator/mitkPAPhantomTissueGenerator.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAPhantomTissueGenerator.h" -#include "mitkPAVector.h" -#include "mitkPAVolumeManipulator.h" - -mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::PhantomTissueGenerator::GeneratePhantomData( - TissueGeneratorParameters::Pointer parameters) -{ - MITK_DEBUG << "Initializing Empty Volume"; - - const double RESAMPLING_FACTOR = 2; - - if (parameters->GetDoPartialVolume()) - { - parameters->SetXDim(parameters->GetXDim() * RESAMPLING_FACTOR); - parameters->SetYDim(parameters->GetYDim() * RESAMPLING_FACTOR); - parameters->SetZDim(parameters->GetZDim() * RESAMPLING_FACTOR); - parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() * RESAMPLING_FACTOR); - parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() / RESAMPLING_FACTOR); - } - - parameters->SetVesselBifurcationFrequency(10000); - - std::mt19937 randomNumberGenerator; - std::random_device randomDevice; - if (parameters->GetUseRngSeed()) - { - randomNumberGenerator.seed(parameters->GetRngSeed()); - } - else - { - if (randomDevice.entropy() > 0.1) - { - randomNumberGenerator.seed(randomDevice()); - } - else - { - randomNumberGenerator.seed(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); - } - } - - auto generatedVolume = mitk::pa::InSilicoTissueVolume::New(parameters, &randomNumberGenerator); - - const unsigned int NUMER_OF_VESSELS = 5; - const double START_DEPTH_IN_CM = 2.10; - const double START_X_IN_CM = 0.76; - const double RADIUS_IN_MM = 0.5; - const double INCREMENT_XZ_IN_CM = 0.50; - double ABSORPTION_PER_CM = parameters->GetMinVesselAbsorption(); - - generatedVolume->AddIntProperty("numberOfVessels", NUMER_OF_VESSELS); - generatedVolume->AddIntProperty("bifurcationFrequency", parameters->GetVesselBifurcationFrequency()); - - for (unsigned int vesselNumber = 0; vesselNumber < NUMER_OF_VESSELS; vesselNumber++) - { - Vector::Pointer initialPosition = Vector::New(); - Vector::Pointer initialDirection = Vector::New(); - - double initialRadius = RADIUS_IN_MM / parameters->GetVoxelSpacingInCentimeters() / 10; - std::stringstream radiusString; - radiusString << "vessel_" << vesselNumber + 1 << "_radius"; - generatedVolume->AddDoubleProperty(radiusString.str(), initialRadius); - - double absorptionCoefficient = ABSORPTION_PER_CM; - std::stringstream absorptionString; - absorptionString << "vessel_" << vesselNumber + 1 << "_absorption"; - generatedVolume->AddDoubleProperty(absorptionString.str(), absorptionCoefficient); - - double bendingFactor = 0; - std::stringstream bendingString; - bendingString << "vessel_" << vesselNumber + 1 << "_bendingFactor"; - generatedVolume->AddDoubleProperty(bendingString.str(), bendingFactor); - - double vesselScattering = 15; - std::stringstream scatteringString; - scatteringString << "vessel_" << vesselNumber + 1 << "_scattering"; - generatedVolume->AddDoubleProperty(scatteringString.str(), vesselScattering); - - double vesselAnisotropy = 0.9; - std::stringstream anisotropyString; - anisotropyString << "vessel_" << vesselNumber + 1 << "_anisotropy"; - generatedVolume->AddDoubleProperty(anisotropyString.str(), vesselAnisotropy); - - /*The vessel tree shall start at one of the 4 sides of the volume. - * The vessels will always be completely contained in the volume - * when starting to meander. - * They will meander in a direction perpendicular to the - * plane they started from (within the limits of the - * DIRECTION_VECTOR_INITIAL_VARIANCE) - */ - - double zposition = (START_DEPTH_IN_CM + (vesselNumber*INCREMENT_XZ_IN_CM)) / parameters->GetVoxelSpacingInCentimeters(); - - double xposition = (START_X_IN_CM + (vesselNumber*INCREMENT_XZ_IN_CM)) / parameters->GetVoxelSpacingInCentimeters(); - - initialPosition->Randomize(xposition, xposition, 0, 0, zposition, zposition, &randomNumberGenerator); - initialDirection->Randomize(0, 0, 1, 1, 0, 0, &randomNumberGenerator); - - initialDirection->Normalize(); - MITK_INFO << initialPosition->GetElement(0) << " | " << initialPosition->GetElement(1) << " | " << initialPosition->GetElement(2); - MITK_INFO << initialDirection->GetElement(0) << " | " << initialDirection->GetElement(1) << " | " << initialDirection->GetElement(2); - - VesselProperties::Pointer vesselParams = VesselProperties::New(); - vesselParams->SetDirectionVector(initialDirection); - vesselParams->SetPositionVector(initialPosition); - vesselParams->SetRadiusInVoxel(initialRadius); - vesselParams->SetAbsorptionCoefficient(absorptionCoefficient); - vesselParams->SetScatteringCoefficient(vesselScattering); - vesselParams->SetAnisotopyCoefficient(vesselAnisotropy); - vesselParams->SetBifurcationFrequency(parameters->GetVesselBifurcationFrequency()); - vesselParams->SetDoPartialVolume(parameters->GetDoPartialVolume()); - - VesselTree::Pointer vesselTree = VesselTree::New(vesselParams); - - while (!vesselTree->IsFinished()) - { - vesselTree->Step(generatedVolume, parameters->GetCalculateNewVesselPositionCallback(), bendingFactor, &randomNumberGenerator); - } - } - - if (parameters->GetDoPartialVolume()) - { - VolumeManipulator::RescaleImage(generatedVolume, (1.0 / RESAMPLING_FACTOR)); - parameters->SetXDim(parameters->GetXDim() / RESAMPLING_FACTOR); - parameters->SetYDim(parameters->GetYDim() / RESAMPLING_FACTOR); - parameters->SetZDim(parameters->GetZDim() / RESAMPLING_FACTOR); - parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() / RESAMPLING_FACTOR); - parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() * RESAMPLING_FACTOR); - } - - generatedVolume->FinalizeVolume(); - - return generatedVolume; -} - -mitk::pa::PhantomTissueGenerator::PhantomTissueGenerator() -{ -} - -mitk::pa::PhantomTissueGenerator::~PhantomTissueGenerator() -{ -} diff --git a/Modules/PhotoacousticsLib/src/Generator/mitkPASimulationBatchGenerator.cpp b/Modules/PhotoacousticsLib/src/Generator/mitkPASimulationBatchGenerator.cpp deleted file mode 100644 index 973fb6730b..0000000000 --- a/Modules/PhotoacousticsLib/src/Generator/mitkPASimulationBatchGenerator.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPASimulationBatchGenerator.h" -#include - -#include - -#ifdef _WIN32 -#include -#else -#include -#include -#endif - -mitk::pa::SimulationBatchGenerator::SimulationBatchGenerator() -{ -} - -mitk::pa::SimulationBatchGenerator::~SimulationBatchGenerator() -{ -} - -std::string mitk::pa::SimulationBatchGenerator::GetVolumeNumber( - SimulationBatchGeneratorParameters::Pointer parameters) -{ - std::string volumeNumber = std::to_string(parameters->GetVolumeIndex()); - volumeNumber = std::string((3 - volumeNumber.length()), '0') + volumeNumber; - return volumeNumber; -} - -std::string mitk::pa::SimulationBatchGenerator::GetOutputFolderName( - SimulationBatchGeneratorParameters::Pointer parameters) -{ - return (parameters->GetTissueName() + GetVolumeNumber(parameters)); -} - -std::string mitk::pa::SimulationBatchGenerator::CreateBatchSimulationString( - SimulationBatchGeneratorParameters::Pointer parameters) -{ - std::string outputFolderName = GetOutputFolderName(parameters); - std::string savePath = outputFolderName + ".nrrd"; - std::stringstream batchstring; - for (double d = parameters->GetYOffsetLowerThresholdInCentimeters(); - d <= parameters->GetYOffsetUpperThresholdInCentimeters() + 1e-5; - d += parameters->GetYOffsetStepInCentimeters()) - { - batchstring << parameters->GetBinaryPath() << " -p PROBE_DESIGN.xml -i " << savePath << " -o " << outputFolderName << "/" - << parameters->GetTissueName() << GetVolumeNumber(parameters) << "_yo" << round(d * 100) / 100 << ".nrrd" << " -yo " << round(d * 100) / 100 << " -n " - << parameters->GetNumberOfPhotons() << "\n"; - } - return batchstring.str(); -} - -void mitk::pa::SimulationBatchGenerator::WriteBatchFileAndSaveTissueVolume( - SimulationBatchGeneratorParameters::Pointer parameters, - mitk::Image::Pointer tissueVolume) -{ - std::string outputFolderName = parameters->GetNrrdFilePath() + GetOutputFolderName(parameters); - std::string savePath = outputFolderName + ".nrrd"; - mitk::IOUtil::Save(tissueVolume, savePath); - - std::string filenameAllSimulation = "simulate_all"; -#ifdef _WIN32 - mkdir(outputFolderName.c_str()); - filenameAllSimulation += ".bat"; -#else - mkdir(outputFolderName.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - filenameAllSimulation += ".sh"; -#endif - - std::ofstream fileAllSimulation(parameters->GetNrrdFilePath() + "/" + filenameAllSimulation, std::ios_base::app); - if (fileAllSimulation.is_open()) - { - fileAllSimulation << CreateBatchSimulationString(parameters); - fileAllSimulation.close(); - } -} diff --git a/Modules/PhotoacousticsLib/src/Generator/mitkPASimulationBatchGeneratorParameters.cpp b/Modules/PhotoacousticsLib/src/Generator/mitkPASimulationBatchGeneratorParameters.cpp deleted file mode 100644 index 20f78d606f..0000000000 --- a/Modules/PhotoacousticsLib/src/Generator/mitkPASimulationBatchGeneratorParameters.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPASimulationBatchGeneratorParameters.h" - -mitk::pa::SimulationBatchGeneratorParameters::SimulationBatchGeneratorParameters() -{ - m_BinaryPath = ""; - m_NrrdFilePath = ""; - m_NumberOfPhotons = 0; - m_TissueName = ""; - m_VolumeIndex = 0; - m_YOffsetLowerThresholdInCentimeters = 0; - m_YOffsetUpperThresholdInCentimeters = 0; - m_YOffsetStepInCentimeters = 0; -} - -mitk::pa::SimulationBatchGeneratorParameters::~SimulationBatchGeneratorParameters() -{ -} diff --git a/Modules/PhotoacousticsLib/src/Generator/mitkPASlicedVolumeGenerator.cpp b/Modules/PhotoacousticsLib/src/Generator/mitkPASlicedVolumeGenerator.cpp deleted file mode 100644 index dfa4c659b8..0000000000 --- a/Modules/PhotoacousticsLib/src/Generator/mitkPASlicedVolumeGenerator.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPASlicedVolumeGenerator.h" -#include - -mitk::pa::SlicedVolumeGenerator::SlicedVolumeGenerator(int centralYSlice, bool precorrect, - Volume::Pointer precorrectionVolume, bool inverse) -{ - m_CentralYSlice = centralYSlice; - m_Precorrect = precorrect; - m_Inverse = inverse; - m_PrecorrectionVolume = nullptr; - - if (m_Precorrect) - { - m_PrecorrectionVolume = precorrectionVolume; - } -} - -mitk::pa::SlicedVolumeGenerator::~SlicedVolumeGenerator() -{ - m_CentralYSlice = -1; - m_Precorrect = false; - m_PrecorrectionVolume = nullptr; -} - -mitk::pa::Volume::Pointer mitk::pa::SlicedVolumeGenerator::GetSlicedFluenceImageFromComposedVolume( - ComposedVolume::Pointer composedVolume) -{ - int fluenceComponents = composedVolume->GetNumberOfFluenceComponents(); - - int xDim = composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetXDim(); - int zDim = composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetZDim(); - - auto* imageArray = new double[xDim*zDim*fluenceComponents]; - - for (int fluenceComponentIdx = 0; fluenceComponentIdx < fluenceComponents; fluenceComponentIdx++) - for (int z = 0; z < zDim; z++) - for (int x = 0; x < xDim; x++) - { - int index = z * xDim * fluenceComponents + x * fluenceComponents + fluenceComponentIdx; - imageArray[index] = composedVolume->GetFluenceValue(fluenceComponentIdx, x, m_CentralYSlice, z); - - if (m_Precorrect) - { - imageArray[index] = imageArray[index] / m_PrecorrectionVolume->GetData(x, m_CentralYSlice, z); - } - - if (m_Inverse) - { - if (std::abs(imageArray[index] - 0) >= mitk::eps) - imageArray[index] = 1 / imageArray[index]; - else - imageArray[index] = INFINITY; - } - } - - return mitk::pa::Volume::New(imageArray, xDim, fluenceComponents, zDim, composedVolume->GetGroundTruthVolume()->GetSpacing()); -} - -mitk::pa::Volume::Pointer mitk::pa::SlicedVolumeGenerator::GetSlicedSignalImageFromComposedVolume( - ComposedVolume::Pointer composedVolume) -{ - int fluenceComponents = composedVolume->GetNumberOfFluenceComponents(); - - int xDim = composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetXDim(); - int zDim = composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetZDim(); - - auto* imageArray = new double[xDim*zDim*fluenceComponents]; - - for (int fluenceComponentIdx = 0; fluenceComponentIdx < fluenceComponents; fluenceComponentIdx++) - for (int z = 0; z < zDim; z++) - for (int x = 0; x < xDim; x++) - { - int y = m_CentralYSlice + composedVolume->GetYOffsetForFluenceComponentInPixels(fluenceComponentIdx); - imageArray[z * xDim * fluenceComponents + x * fluenceComponents + fluenceComponentIdx] = - composedVolume->GetFluenceValue(fluenceComponentIdx, x, m_CentralYSlice, z) - * composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetData(x, y, z); - } - - return mitk::pa::Volume::New(imageArray, xDim, fluenceComponents, zDim, composedVolume->GetGroundTruthVolume()->GetSpacing()); -} - -mitk::pa::Volume::Pointer mitk::pa::SlicedVolumeGenerator::GetSlicedGroundTruthImageFromComposedVolume( - ComposedVolume::Pointer composedVolume) -{ - int fluenceComponents = composedVolume->GetNumberOfFluenceComponents(); - - int xDim = composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetXDim(); - int zDim = composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetZDim(); - - auto* imageArray = new double[xDim*zDim*fluenceComponents]; - - for (int fluenceComponentIdx = 0; fluenceComponentIdx < fluenceComponents; fluenceComponentIdx++) - for (int z = 0; z < zDim; z++) - for (int x = 0; x < xDim; x++) - { - int y = m_CentralYSlice + composedVolume->GetYOffsetForFluenceComponentInPixels(fluenceComponentIdx); - imageArray[z * xDim * fluenceComponents + x * fluenceComponents + fluenceComponentIdx] = - composedVolume->GetGroundTruthVolume()->GetAbsorptionVolume()->GetData(x, y, z); - } - - return mitk::pa::Volume::New(imageArray, xDim, fluenceComponents, zDim, composedVolume->GetGroundTruthVolume()->GetSpacing()); -} diff --git a/Modules/PhotoacousticsLib/src/Generator/mitkPATissueGenerator.cpp b/Modules/PhotoacousticsLib/src/Generator/mitkPATissueGenerator.cpp deleted file mode 100644 index 8bca26a705..0000000000 --- a/Modules/PhotoacousticsLib/src/Generator/mitkPATissueGenerator.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPATissueGenerator.h" -#include "mitkPAVector.h" -#include "mitkPAVolumeManipulator.h" - -mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData( - TissueGeneratorParameters::Pointer parameters) -{ - MITK_DEBUG << "Initializing Empty Volume"; - - const double RESAMPLING_FACTOR = 2; - - if (parameters->GetDoPartialVolume()) - { - parameters->SetXDim(parameters->GetXDim() * RESAMPLING_FACTOR); - parameters->SetYDim(parameters->GetYDim() * RESAMPLING_FACTOR); - parameters->SetZDim(parameters->GetZDim() * RESAMPLING_FACTOR); - parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() * RESAMPLING_FACTOR); - parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() / RESAMPLING_FACTOR); - } - - std::mt19937 randomNumberGenerator; - std::random_device randomDevice; - if (parameters->GetUseRngSeed()) - { - randomNumberGenerator.seed(parameters->GetRngSeed()); - } - else - { - if (randomDevice.entropy() > 0.1) - { - randomNumberGenerator.seed(randomDevice()); - } - else - { - randomNumberGenerator.seed(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); - } - } - - auto generatedVolume = mitk::pa::InSilicoTissueVolume::New(parameters, &randomNumberGenerator); - - double DIRECTION_VECTOR_INITIAL_VARIANCE = 0.2; - - if(parameters->GetForceVesselsMoveAlongYDirection()) - DIRECTION_VECTOR_INITIAL_VARIANCE = 0; - - std::uniform_int_distribution randomNumVesselDistribution( - parameters->GetMinNumberOfVessels(), parameters->GetMaxNumberOfVessels()); - std::uniform_real_distribution randomBendingDistribution( - parameters->GetMinVesselBending(), parameters->GetMaxVesselBending()); - std::uniform_real_distribution randomAbsorptionDistribution( - parameters->GetMinVesselAbsorption(), parameters->GetMaxVesselAbsorption()); - std::uniform_real_distribution randomRadiusDistribution( - parameters->GetMinVesselRadiusInMillimeters(), parameters->GetMaxVesselRadiusInMillimeters()); - std::uniform_real_distribution randomScatteringDistribution( - parameters->GetMinVesselScattering(), parameters->GetMaxVesselScattering()); - std::uniform_real_distribution randomAnisotropyDistribution( - parameters->GetMinVesselAnisotropy(), parameters->GetMaxVesselAnisotropy()); - std::uniform_int_distribution borderTypeDistribution(0, 3); - - int numberOfBloodVessels = randomNumVesselDistribution(randomNumberGenerator); - - generatedVolume->AddIntProperty("numberOfVessels", numberOfBloodVessels); - generatedVolume->AddIntProperty("bifurcationFrequency", parameters->GetVesselBifurcationFrequency()); - - MITK_INFO << "Simulating " << numberOfBloodVessels << " vessel structures"; - for (int vesselNumber = 0; vesselNumber < numberOfBloodVessels; vesselNumber++) - { - Vector::Pointer initialPosition = Vector::New(); - Vector::Pointer initialDirection = Vector::New(); - - double initialRadius = randomRadiusDistribution(randomNumberGenerator) / parameters->GetVoxelSpacingInCentimeters() / 10; - std::stringstream radiusString; - radiusString << "vessel_" << vesselNumber + 1 << "_radius"; - generatedVolume->AddDoubleProperty(radiusString.str(), initialRadius); - - double absorptionCoefficient = randomAbsorptionDistribution(randomNumberGenerator); - std::stringstream absorptionString; - absorptionString << "vessel_" << vesselNumber + 1 << "_absorption"; - generatedVolume->AddDoubleProperty(absorptionString.str(), absorptionCoefficient); - - double bendingFactor = randomBendingDistribution(randomNumberGenerator); - std::stringstream bendingString; - bendingString << "vessel_" << vesselNumber + 1 << "_bendingFactor"; - generatedVolume->AddDoubleProperty(bendingString.str(), bendingFactor); - - double vesselScattering = randomScatteringDistribution(randomNumberGenerator); - std::stringstream scatteringString; - scatteringString << "vessel_" << vesselNumber + 1 << "_scattering"; - generatedVolume->AddDoubleProperty(scatteringString.str(), vesselScattering); - - double vesselAnisotropy = randomAnisotropyDistribution(randomNumberGenerator); - std::stringstream anisotropyString; - anisotropyString << "vessel_" << vesselNumber + 1 << "_anisotropy"; - generatedVolume->AddDoubleProperty(anisotropyString.str(), vesselAnisotropy); - - /*The vessel tree shall start at one of the 4 sides of the volume. - * The vessels will always be completely contained in the volume - * when starting to meander. - * They will meander in a direction perpendicular to the - * plane they started from (within the limits of the - * DIRECTION_VECTOR_INITIAL_VARIANCE) - */ - int borderType = borderTypeDistribution(randomNumberGenerator); - - if(parameters->GetForceVesselsMoveAlongYDirection()) - borderType = 2; - - switch (borderType) - { - case 0: - initialPosition->Randomize(0, 0, initialRadius, parameters->GetYDim() - initialRadius, - parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), - parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator); - initialDirection->Randomize(1, 2, -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, - -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator); - break; - case 1: - initialPosition->Randomize(parameters->GetXDim() - 1, parameters->GetXDim() - 1, initialRadius, parameters->GetYDim() - initialRadius, - parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), - parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator); - initialDirection->Randomize(-2, -1, -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, - -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator); - break; - case 2: - initialPosition->Randomize(initialRadius, parameters->GetXDim() - initialRadius, 0, 0, - parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), - parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator); - initialDirection->Randomize(-DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, 1, 2, - -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator); - break; - case 3: - initialPosition->Randomize(initialRadius, parameters->GetXDim() - initialRadius, parameters->GetYDim() - 1, parameters->GetYDim() - 1, - parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), - parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator); - initialDirection->Randomize(-DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, -2, -1, - -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator); - break; - } - - initialDirection->Normalize(); - MITK_INFO << initialPosition->GetElement(0) << " | " << initialPosition->GetElement(1) << " | " << initialPosition->GetElement(2); - MITK_INFO << initialDirection->GetElement(0) << " | " << initialDirection->GetElement(1) << " | " << initialDirection->GetElement(2); - - VesselProperties::Pointer vesselParams = VesselProperties::New(); - vesselParams->SetDirectionVector(initialDirection); - vesselParams->SetPositionVector(initialPosition); - vesselParams->SetRadiusInVoxel(initialRadius); - vesselParams->SetAbsorptionCoefficient(absorptionCoefficient); - vesselParams->SetScatteringCoefficient(vesselScattering); - vesselParams->SetAnisotopyCoefficient(vesselAnisotropy); - vesselParams->SetBifurcationFrequency(parameters->GetVesselBifurcationFrequency()); - vesselParams->SetDoPartialVolume(parameters->GetDoPartialVolume()); - - VesselTree::Pointer vesselTree = VesselTree::New(vesselParams); - - while (!vesselTree->IsFinished()) - { - vesselTree->Step(generatedVolume, parameters->GetCalculateNewVesselPositionCallback(), bendingFactor, &randomNumberGenerator); - } - } - - if (parameters->GetDoPartialVolume()) - { - VolumeManipulator::RescaleImage(generatedVolume, (1.0 / RESAMPLING_FACTOR)); - parameters->SetXDim(parameters->GetXDim() / RESAMPLING_FACTOR); - parameters->SetYDim(parameters->GetYDim() / RESAMPLING_FACTOR); - parameters->SetZDim(parameters->GetZDim() / RESAMPLING_FACTOR); - parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() / RESAMPLING_FACTOR); - parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() * RESAMPLING_FACTOR); - } - - generatedVolume->FinalizeVolume(); - - return generatedVolume; -} - -mitk::pa::InSilicoTissueGenerator::InSilicoTissueGenerator() -{ -} - -mitk::pa::InSilicoTissueGenerator::~InSilicoTissueGenerator() -{ -} diff --git a/Modules/PhotoacousticsLib/src/IO/mitkPAIOUtil.cpp b/Modules/PhotoacousticsLib/src/IO/mitkPAIOUtil.cpp deleted file mode 100644 index 3fe9583c7e..0000000000 --- a/Modules/PhotoacousticsLib/src/IO/mitkPAIOUtil.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAIOUtil.h" - -#include "mitkIOUtil.h" -#include "mitkImageReadAccessor.h" - -#include -#include -#include - -#include "mitkPAComposedVolume.h" -#include "mitkPASlicedVolumeGenerator.h" -#include "mitkPANoiseGenerator.h" -#include "mitkPAVolumeManipulator.h" -#include -#include -#include - -static std::vector splitString(const std::string &s, const char* delim) { - std::vector elems; - std::stringstream ss(s); - std::string item; - while (std::getline(ss, item, *delim)) - { - int numb; - std::stringstream(item) >> numb; - elems.push_back(numb); - } - return elems; -} - -bool mitk::pa::IOUtil::DoesFileHaveEnding(std::string const &fullString, std::string const &ending) { - if (fullString.length() == 0 || ending.length() == 0 || fullString.length() < ending.length()) - return false; - - return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); -} - -mitk::pa::IOUtil::IOUtil() {} - -mitk::pa::IOUtil::~IOUtil() {} - -mitk::pa::Volume::Pointer mitk::pa::IOUtil::LoadNrrd(std::string filename, double blur) -{ - if (filename.empty() || filename == "") - return nullptr; - - mitk::Image::Pointer inputImage = mitk::IOUtil::Load(filename); - - if (inputImage.IsNull()) - return nullptr; - - auto returnImage = Volume::New(inputImage); - - VolumeManipulator::GaussianBlur3D(returnImage, blur); - - return returnImage; -} - -std::map -mitk::pa::IOUtil::LoadFluenceContributionMaps(std::string foldername, double blur, int* progress, bool doLog10) -{ - std::map resultMap; - - itk::Directory::Pointer directoryHandler = itk::Directory::New(); - directoryHandler->Load(foldername.c_str()); - for (unsigned int fileIndex = 0, numFiles = directoryHandler->GetNumberOfFiles(); fileIndex < numFiles; ++fileIndex) - { - std::string filename = std::string(directoryHandler->GetFile(fileIndex)); - if (itksys::SystemTools::FileIsDirectory(filename)) - continue; - - if (!DoesFileHaveEnding(filename, ".nrrd")) - continue; - - size_t s = filename.find("_p"); - size_t e = filename.find("Fluence", s); - std::string sub = filename.substr(s + 2, e - s - 2); - std::vector coords = splitString(sub, ","); - - if (coords.size() != 3) - { - MITK_ERROR << "Some of the data to read was corrupted or did not match the " << - "naming pattern *_pN,N,NFluence*.nrrd"; - mitkThrow() << "Some of the data to read was corrupted or did not match the" << - " naming pattern *_pN,N,NFluence*.nrrd"; - } - else - { - MITK_DEBUG << "Extracted coords: " << coords[0] << "|" << coords[1] << "|" << coords[2] << " from string " << sub; - Volume::Pointer nrrdFile = LoadNrrd(foldername + filename, blur); - if (doLog10) - VolumeManipulator::Log10Image(nrrdFile); - resultMap[Position{ coords[0], coords[2] }] = nrrdFile; - *progress = *progress + 1; - } - } - - return resultMap; -} - -int mitk::pa::IOUtil::GetNumberOfNrrdFilesInDirectory(std::string directory) -{ - return GetListOfAllNrrdFilesInDirectory(directory).size(); -} - -std::vector mitk::pa::IOUtil::GetListOfAllNrrdFilesInDirectory(std::string directory, bool keepFileFormat) -{ - std::vector filenames; - itk::Directory::Pointer directoryHandler = itk::Directory::New(); - directoryHandler->Load(directory.c_str()); - for (unsigned int fileIndex = 0, numFiles = directoryHandler->GetNumberOfFiles(); fileIndex < numFiles; ++fileIndex) - { - std::string filename = std::string(directoryHandler->GetFile(fileIndex)); - if (itksys::SystemTools::FileIsDirectory(filename)) - continue; - - if (!DoesFileHaveEnding(filename, ".nrrd")) - continue; - - if (keepFileFormat) - { - filenames.push_back(filename); - } - else - { - filenames.push_back(filename.substr(0, filename.size() - 5)); - } - } - - return filenames; -} - -std::vector mitk::pa::IOUtil::GetAllChildfoldersFromFolder(std::string folderPath) -{ - std::vector returnVector; - - itksys::Directory directoryHandler; - directoryHandler.Load(folderPath.c_str()); - for (unsigned int fileIndex = 0, numFiles = directoryHandler.GetNumberOfFiles(); fileIndex < numFiles; ++fileIndex) - { - std::string foldername = std::string(directoryHandler.GetFile(fileIndex)); - std::string filename = folderPath + "/" + foldername; - if (itksys::SystemTools::FileIsDirectory(filename)) - { - if (foldername != std::string(".") && foldername != std::string("..")) - { - MITK_INFO << filename; - returnVector.push_back(filename); - } - continue; - } - - //If there is a nrrd file in the directory we assume that a bottom level directory was chosen. - if (DoesFileHaveEnding(filename, ".nrrd")) - { - returnVector.clear(); - returnVector.push_back(folderPath); - return returnVector; - } - } - - return returnVector; -} - -mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::IOUtil::LoadInSilicoTissueVolumeFromNrrdFile(std::string nrrdFile) -{ - MITK_INFO << "Initializing ComposedVolume by nrrd..."; - auto inputImage = mitk::IOUtil::Load(nrrdFile); - - auto tissueParameters = TissueGeneratorParameters::New(); - - unsigned int xDim = inputImage->GetDimensions()[1]; - unsigned int yDim = inputImage->GetDimensions()[0]; - unsigned int zDim = inputImage->GetDimensions()[2]; - tissueParameters->SetXDim(xDim); - tissueParameters->SetYDim(yDim); - tissueParameters->SetZDim(zDim); - - double xSpacing = inputImage->GetGeometry(0)->GetSpacing()[1]; - double ySpacing = inputImage->GetGeometry(0)->GetSpacing()[0]; - double zSpacing = inputImage->GetGeometry(0)->GetSpacing()[2]; - - if ((xSpacing - ySpacing) > mitk::eps || (xSpacing - zSpacing) > mitk::eps || (ySpacing - zSpacing) > mitk::eps) - { - throw mitk::Exception("Cannot handle unequal spacing."); - } - - tissueParameters->SetVoxelSpacingInCentimeters(xSpacing); - - mitk::PropertyList::Pointer propertyList = inputImage->GetPropertyList(); - - mitk::ImageReadAccessor readAccess0(inputImage, inputImage->GetVolumeData(0)); - auto* m_AbsorptionArray = new double[xDim*yDim*zDim]; - memcpy(m_AbsorptionArray, readAccess0.GetData(), xDim*yDim*zDim * sizeof(double)); - auto absorptionVolume = Volume::New(m_AbsorptionArray, xDim, yDim, zDim, xSpacing); - - mitk::ImageReadAccessor readAccess1(inputImage, inputImage->GetVolumeData(1)); - auto* m_ScatteringArray = new double[xDim*yDim*zDim]; - memcpy(m_ScatteringArray, readAccess1.GetData(), xDim*yDim*zDim * sizeof(double)); - auto scatteringVolume = Volume::New(m_ScatteringArray, xDim, yDim, zDim, xSpacing); - - mitk::ImageReadAccessor readAccess2(inputImage, inputImage->GetVolumeData(2)); - auto* m_AnisotropyArray = new double[xDim*yDim*zDim]; - memcpy(m_AnisotropyArray, readAccess2.GetData(), xDim*yDim*zDim * sizeof(double)); - auto anisotropyVolume = Volume::New(m_AnisotropyArray, xDim, yDim, zDim, xSpacing); - - Volume::Pointer segmentationVolume; - - if (inputImage->GetDimension() == 4) - { - mitk::ImageReadAccessor readAccess3(inputImage, inputImage->GetVolumeData(3)); - auto* m_SegmentationArray = new double[xDim*yDim*zDim]; - memcpy(m_SegmentationArray, readAccess3.GetData(), xDim*yDim*zDim * sizeof(double)); - segmentationVolume = Volume::New(m_SegmentationArray, xDim, yDim, zDim, xSpacing); - } - - return mitk::pa::InSilicoTissueVolume::New(absorptionVolume, scatteringVolume, - anisotropyVolume, segmentationVolume, tissueParameters, propertyList); -} - -mitk::pa::FluenceYOffsetPair::Pointer mitk::pa::IOUtil::LoadFluenceSimulation(std::string fluenceSimulation) -{ - MITK_INFO << "Adding slice..."; - - mitk::Image::Pointer inputImage = mitk::IOUtil::Load(fluenceSimulation); - - auto yOffsetProperty = inputImage->GetProperty("y-offset"); - - if (yOffsetProperty.IsNull()) - mitkThrow() << "No \"y-offset\" property found in fluence file!"; - - std::string yOff = yOffsetProperty->GetValueAsString(); - MITK_INFO << "Reading y Offset: " << yOff; -#ifdef __linux__ - std::replace(yOff.begin(), yOff.end(), '.', ','); -#endif // __linux__ - double yOffset = std::stod(yOff); - MITK_INFO << "Converted offset " << yOffset; - return FluenceYOffsetPair::New(Volume::New(inputImage), yOffset); -} diff --git a/Modules/PhotoacousticsLib/src/SUFilter/mitkPALinearSpectralUnmixingFilter.cpp b/Modules/PhotoacousticsLib/src/SUFilter/mitkPALinearSpectralUnmixingFilter.cpp deleted file mode 100644 index 0a83f8faad..0000000000 --- a/Modules/PhotoacousticsLib/src/SUFilter/mitkPALinearSpectralUnmixingFilter.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPALinearSpectralUnmixingFilter.h" - -// Testing algorithms -#include - -// ImageAccessor -#include -#include - -mitk::pa::LinearSpectralUnmixingFilter::LinearSpectralUnmixingFilter() -{ -} - -mitk::pa::LinearSpectralUnmixingFilter::~LinearSpectralUnmixingFilter() -{ -} - -void mitk::pa::LinearSpectralUnmixingFilter::SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType inputAlgorithmName) -{ - algorithmName = inputAlgorithmName; -} - -Eigen::VectorXf mitk::pa::LinearSpectralUnmixingFilter::SpectralUnmixingAlgorithm( - Eigen::Matrix endmemberMatrix, Eigen::VectorXf inputVector) -{ - Eigen::VectorXf resultVector; - - if (mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR == algorithmName) - resultVector = endmemberMatrix.householderQr().solve(inputVector); - - else if (mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::LDLT == algorithmName) - { - Eigen::LLT lltOfA(endmemberMatrix); - if (lltOfA.info() == Eigen::NumericalIssue) - { - mitkThrow() << "Possibly non semi-positive definitie endmembermatrix!"; - } - else - resultVector = endmemberMatrix.ldlt().solve(inputVector); - } - - else if (mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::LLT == algorithmName) - { - Eigen::LLT lltOfA(endmemberMatrix); - if (lltOfA.info() == Eigen::NumericalIssue) - { - mitkThrow() << "Possibly non semi-positive definitie endmembermatrix!"; - } - else - resultVector = endmemberMatrix.llt().solve(inputVector); - } - - else if (mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::COLPIVHOUSEHOLDERQR == algorithmName) - resultVector = endmemberMatrix.colPivHouseholderQr().solve(inputVector); - - else if (mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::JACOBISVD == algorithmName) - resultVector = endmemberMatrix.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV).solve(inputVector); - - else if (mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVLU == algorithmName) - resultVector = endmemberMatrix.fullPivLu().solve(inputVector); - - else if (mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVHOUSEHOLDERQR == algorithmName) - resultVector = endmemberMatrix.fullPivHouseholderQr().solve(inputVector); - else - mitkThrow() << "404 VIGRA ALGORITHM NOT FOUND"; - - return resultVector; -} diff --git a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterBase.cpp b/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterBase.cpp deleted file mode 100644 index 71d9fc6e14..0000000000 --- a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterBase.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPASpectralUnmixingFilterBase.h" - -// Includes for AddEnmemberMatrix -#include "mitkPAPropertyCalculator.h" -#include - -// ImageAccessor -#include -#include - -mitk::pa::SpectralUnmixingFilterBase::SpectralUnmixingFilterBase() -{ - m_PropertyCalculatorEigen = mitk::pa::PropertyCalculator::New(); -} - -mitk::pa::SpectralUnmixingFilterBase::~SpectralUnmixingFilterBase() -{ - -} - -void mitk::pa::SpectralUnmixingFilterBase::AddOutputs(unsigned int outputs) -{ - if (outputs == 0) - mitkThrow() << "ADD OUTPUTS HAS TO BE LARGER THEN ZERO!"; - this->SetNumberOfIndexedOutputs(outputs); - for (unsigned int i = 0; iSetNthOutput(i, mitk::Image::New()); -} - -void mitk::pa::SpectralUnmixingFilterBase::AddWavelength(int wavelength) -{ - m_Wavelength.push_back(wavelength); -} - -void mitk::pa::SpectralUnmixingFilterBase::AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType chromophore) -{ - m_Chromophore.push_back(chromophore); -} - -void mitk::pa::SpectralUnmixingFilterBase::Verbose(bool verbose) -{ - m_Verbose = verbose; -} - -void mitk::pa::SpectralUnmixingFilterBase::RelativeError(bool relativeError) -{ - m_RelativeError = relativeError; -} - -void mitk::pa::SpectralUnmixingFilterBase::AddRelativeErrorSettings(int value) -{ - m_RelativeErrorSettings.push_back(value); -} - -void mitk::pa::SpectralUnmixingFilterBase::GenerateData() -{ - MITK_INFO(m_Verbose) << "GENERATING DATA.."; - - mitk::Image::Pointer input = GetInput(0); - CheckPreConditions(input); - - unsigned int xDim = input->GetDimensions()[0]; - unsigned int yDim = input->GetDimensions()[1]; - unsigned int numberOfInputImages = input->GetDimensions()[2]; - - MITK_INFO(m_Verbose) << "x dimension: " << xDim; - MITK_INFO(m_Verbose) << "y dimension: " << yDim; - MITK_INFO(m_Verbose) << "z dimension: " << numberOfInputImages; - - // Copy input image into array - mitk::ImageReadAccessor readAccess(input); - const float* inputDataArray = ((const float*)readAccess.GetData()); - - unsigned int sequenceSize = m_Wavelength.size(); - unsigned int totalNumberOfSequences = numberOfInputImages / sequenceSize; - MITK_INFO(m_Verbose) << "TotalNumberOfSequences: " << totalNumberOfSequences; - - InitializeOutputs(totalNumberOfSequences); - - auto endmemberMatrix = CalculateEndmemberMatrix(m_Chromophore, m_Wavelength); - - // test to see pixel values @ txt file - myfile.open("SimplexNormalisation.txt"); - - unsigned int outputCounter = GetNumberOfIndexedOutputs(); - std::vector writteBufferVector; - for (unsigned int i = 0; i < outputCounter; ++i) - { - auto output = GetOutput(i); - mitk::ImageWriteAccessor writeOutput(output); - float* writeBuffer = (float *)writeOutput.GetData(); - writteBufferVector.push_back(writeBuffer); - } - - if (m_RelativeError == true) - { - // -1 because rel error is output[IndexedOutputs() - 1] and loop over chromophore outputs has to end at [IndexedOutputs() - 2] - outputCounter -= 1; - } - - for (unsigned int sequenceCounter = 0; sequenceCounter < totalNumberOfSequences; ++sequenceCounter) - { - MITK_INFO(m_Verbose) << "SequenceCounter: " << sequenceCounter; - //loop over every pixel in XY-plane - for (unsigned int x = 0; x < xDim; x++) - { - for (unsigned int y = 0; y < yDim; y++) - { - Eigen::VectorXf inputVector(sequenceSize); - for (unsigned int z = 0; z < sequenceSize; z++) - { - /** - * 'sequenceCounter*sequenceSize' has to be added to 'z' to ensure that one accesses the - * correct pixel, because the inputDataArray contains the information of all sequences and - * not just the one of the current sequence. - */ - unsigned int pixelNumber = (xDim*yDim*(z+sequenceCounter*sequenceSize)) + x * yDim + y; - auto pixel = inputDataArray[pixelNumber]; - - inputVector[z] = pixel; - } - Eigen::VectorXf resultVector = SpectralUnmixingAlgorithm(endmemberMatrix, inputVector); - - if (m_RelativeError == true) - { - float relativeError = CalculateRelativeError(endmemberMatrix, inputVector, resultVector); - writteBufferVector[outputCounter][(xDim*yDim * sequenceCounter) + x * yDim + y] = relativeError; - } - - for (unsigned int outputIdx = 0; outputIdx < outputCounter; ++outputIdx) - { - writteBufferVector[outputIdx][(xDim*yDim * sequenceCounter) + x * yDim + y] = resultVector[outputIdx]; - } - } - } - } - MITK_INFO(m_Verbose) << "GENERATING DATA...[DONE]"; - myfile.close(); -} - -void mitk::pa::SpectralUnmixingFilterBase::CheckPreConditions(mitk::Image::Pointer input) -{ - MITK_INFO(m_Verbose) << "CHECK PRECONDITIONS ..."; - - if (m_Chromophore.size() == 0 || m_Wavelength.size() == 0) - mitkThrow() << "NO WAVELENGHTS/CHROMOPHORES SELECTED!"; - - if (m_Wavelength.size() < input->GetDimensions()[2]) - MITK_WARN(m_Verbose) << "NUMBER OF WAVELENGTHS < NUMBER OF INPUT IMAGES"; - - if (m_Chromophore.size() > m_Wavelength.size()) - mitkThrow() << "ADD MORE WAVELENGTHS OR REMOVE ENDMEMBERS!"; - - if (input->GetPixelType() != mitk::MakeScalarPixelType()) - mitkThrow() << "PIXELTYPE ERROR! FLOAT REQUIRED"; - - if ((m_Chromophore.size()+ m_RelativeError )!= GetNumberOfIndexedOutputs() || input->GetDimensions()[2] < GetNumberOfIndexedOutputs()) - mitkThrow() << "INDEX ERROR! NUMBER OF OUTPUTS DOESN'T FIT TO OTHER SETTIGNS!"; - - MITK_INFO(m_Verbose) << "...[DONE]"; -} - -void mitk::pa::SpectralUnmixingFilterBase::InitializeOutputs(unsigned int totalNumberOfSequences) -{ - MITK_INFO(m_Verbose) << "Initialize Outputs ..."; - - unsigned int numberOfInputs = GetNumberOfIndexedInputs(); - unsigned int numberOfOutputs = GetNumberOfIndexedOutputs(); - MITK_INFO(m_Verbose) << "Inputs: " << numberOfInputs << " Outputs: " << numberOfOutputs; - - mitk::PixelType pixelType = mitk::MakeScalarPixelType(); - const int NUMBER_OF_SPATIAL_DIMENSIONS = 3; - auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS]; - for (unsigned int dimIdx = 0; dimIdx < 2; dimIdx++) - dimensions[dimIdx] = GetInput()->GetDimensions()[dimIdx]; - dimensions[2] = totalNumberOfSequences; - - for (unsigned int outputIdx = 0; outputIdx < numberOfOutputs; outputIdx++) - GetOutput(outputIdx)->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions); - MITK_INFO(m_Verbose) << "...[DONE]"; -} - -Eigen::Matrix mitk::pa::SpectralUnmixingFilterBase::CalculateEndmemberMatrix( - std::vector m_Chromophore, std::vector m_Wavelength) -{ - unsigned int numberOfChromophores = m_Chromophore.size(); //columns - unsigned int numberOfWavelengths = m_Wavelength.size(); //rows - Eigen::Matrix endmemberMatrixEigen(numberOfWavelengths, numberOfChromophores); - - for (unsigned int j = 0; j < numberOfChromophores; ++j) - { - for (unsigned int i = 0; i < numberOfWavelengths; ++i) - endmemberMatrixEigen(i, j) = PropertyElement(m_Chromophore[j], m_Wavelength[i]); - } - MITK_INFO(m_Verbose) << "GENERATING ENMEMBERMATRIX [DONE]"; - return endmemberMatrixEigen; -} - -float mitk::pa::SpectralUnmixingFilterBase::PropertyElement(mitk::pa::PropertyCalculator::ChromophoreType chromophore, int wavelength) -{ - if (chromophore == mitk::pa::PropertyCalculator::ChromophoreType::ONEENDMEMBER) - return 1; - else - { - float value = m_PropertyCalculatorEigen->GetAbsorptionForWavelength(chromophore, wavelength); - if (value == 0) - mitkThrow() << "WAVELENGTH " << wavelength << "nm NOT SUPPORTED!"; - else - return value; - } -} - -float mitk::pa::SpectralUnmixingFilterBase::CalculateRelativeError(Eigen::Matrix endmemberMatrix, - Eigen::VectorXf inputVector, Eigen::VectorXf resultVector) -{ - float relativeError = (endmemberMatrix*resultVector - inputVector).norm() / inputVector.norm(); - for (int i = 0; i < 2; ++i) - { - if (resultVector[i] < m_RelativeErrorSettings[i]) - return 0; - } - return relativeError; -} diff --git a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterLagrange.cpp b/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterLagrange.cpp deleted file mode 100644 index bb17f63882..0000000000 --- a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterLagrange.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPASpectralUnmixingFilterLagrange.h" - -// Includes for AddEnmemberMatrix -#include "mitkPAPropertyCalculator.h" -#include - - -mitk::pa::SpectralUnmixingFilterLagrange::SpectralUnmixingFilterLagrange() -{ - -} - -mitk::pa::SpectralUnmixingFilterLagrange::~SpectralUnmixingFilterLagrange() -{ - -} diff --git a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterSimplex.cpp b/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterSimplex.cpp deleted file mode 100644 index ed9ef82ce6..0000000000 --- a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterSimplex.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include - -// Includes for AddEnmemberMatrix -#include - -#include - -mitk::pa::SpectralUnmixingFilterSimplex::SpectralUnmixingFilterSimplex() -{ - -} - -mitk::pa::SpectralUnmixingFilterSimplex::~SpectralUnmixingFilterSimplex() -{ - -} - -Eigen::VectorXf mitk::pa::SpectralUnmixingFilterSimplex::SpectralUnmixingAlgorithm( - Eigen::Matrix EndmemberMatrix, Eigen::VectorXf inputVector) -{ - int numberOfChromophores = EndmemberMatrix.cols(); - - Eigen::VectorXf resultVector(numberOfChromophores); - Eigen::VectorXf normalizedInputVector(EndmemberMatrix.rows()); - normalizedInputVector = Normalization(EndmemberMatrix, inputVector); - //normalizedInputVector = inputVector; - - - float VolumeMax = simplexVolume(EndmemberMatrix); - for (int i = 0; i < numberOfChromophores; ++i) - { - Eigen::Matrix A = GenerateA(EndmemberMatrix, normalizedInputVector, i); - float Volume = simplexVolume(A); - - - resultVector[i] = Volume / VolumeMax; - - myfile << "resultVector["< mitk::pa::SpectralUnmixingFilterSimplex::GenerateA -(Eigen::Matrix EndmemberMatrix, Eigen::VectorXf inputVector, int i) -{ - Eigen::Matrix A = EndmemberMatrix; - int numberOfChromophores = EndmemberMatrix.cols(); - - for (int j = 0; j < numberOfChromophores; ++j) - { - A(i, j) = inputVector(j); - } - - return A; -} - -Eigen::Matrix mitk::pa::SpectralUnmixingFilterSimplex::GenerateD2 -(Eigen::Matrix A) -{ - int numberOfChromophores = A.cols(); - - Eigen::Matrix D2(numberOfChromophores, numberOfChromophores); - - for (int i = 0; i < numberOfChromophores; ++i) - { - for (int j = 0; j < numberOfChromophores; ++j) - { - Eigen::VectorXf x = A.col(i) - A.col(j); - //MITK_INFO << "a_col_i: " < Matrix) -{ - float Volume; - int numberOfChromophores = Matrix.cols(); - Eigen::Matrix C(numberOfChromophores + 1, numberOfChromophores + 1); - Eigen::Matrix D2 = GenerateD2(Matrix); - - for (int i = 0; i < numberOfChromophores; ++i) - { - for (int j = 0; j < numberOfChromophores; ++j) - { - C(i, j) = D2(i, j); - } - C(i, numberOfChromophores) = 1; - for (int k = 0; k < numberOfChromophores; ++k) - { - C(numberOfChromophores, k) = 1; - } - C(numberOfChromophores, numberOfChromophores) = 0; - } - - float detC = -C.determinant();// determinate von C - float denominator = (factorial(numberOfChromophores - 1)) ^ 2 * 2 ^ (numberOfChromophores - 1)*(-1) ^ numberOfChromophores; - Volume = std::sqrt(detC / denominator); - //MITK_INFO << "detC: " << detC; - - //MITK_INFO << "denominator: " << denominator; - - //MITK_INFO << "Volume: " << Volume; - - return Volume; -} - -int mitk::pa::SpectralUnmixingFilterSimplex::factorial(int n) -{ - if (n == 1) - return 1; - else - return n * factorial(n - 1); -} - -Eigen::VectorXf mitk::pa::SpectralUnmixingFilterSimplex::Normalization( - Eigen::Matrix EndmemberMatrix, Eigen::VectorXf inputVector) -{ - int numberOfWavelengths = inputVector.rows(); - Eigen::VectorXf result(numberOfWavelengths); - float NormalizationFactor = 1; - float foo; - float norm = 0; - - for (int i = 0; i < numberOfWavelengths; ++i) - { - foo = EndmemberMatrix(i, 0) - EndmemberMatrix(i, 1); - if (std::abs(foo) > norm) - norm = std::abs(foo); - } - -//ofstream myfile; -//myfile.open("SimplexNormalisation.txt"); - //NormalizationFactor = inputVector[0] * 2 / norm; - myfile << "Normalizationfactor " << NormalizationFactor << "\n"; - - for (int i = 0; i < numberOfWavelengths; ++i) - { - - result[i]=(inputVector[i]/NormalizationFactor); - } -//myfile.close(); - - return result; -} diff --git a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterVigra.cpp b/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterVigra.cpp deleted file mode 100644 index 878e331e06..0000000000 --- a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingFilterVigra.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPASpectralUnmixingFilterVigra.h" - -// ImageAccessor -#include -#include - -//vigra -#include -#include -#include - -mitk::pa::SpectralUnmixingFilterVigra::SpectralUnmixingFilterVigra() -{ -} - -mitk::pa::SpectralUnmixingFilterVigra::~SpectralUnmixingFilterVigra() -{ -} - -void mitk::pa::SpectralUnmixingFilterVigra::SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType inputAlgorithmName) -{ - algorithmName = inputAlgorithmName; -} - -void mitk::pa::SpectralUnmixingFilterVigra::AddWeight(unsigned int weight) -{ - double value = double(weight) / 100.0; - weightsvec.push_back(value); -} - -Eigen::VectorXf mitk::pa::SpectralUnmixingFilterVigra::SpectralUnmixingAlgorithm( - Eigen::Matrix endmemberMatrix, Eigen::VectorXf inputVector) -{ - unsigned int numberOfWavelengths = endmemberMatrix.rows(); - unsigned int numberOfChromophores = endmemberMatrix.cols(); - - // writes endmemberMatrix and inputVector into vigra::Matrix - std::vector aData; - std::vector bData; - for (unsigned int i = 0; i < numberOfWavelengths; ++i) - { - bData.push_back((double)inputVector(i)); - for (unsigned int j = 0; j < numberOfChromophores; ++j) - aData.push_back((double)endmemberMatrix(i, j)); - } - const double* aDat = aData.data(); - const double* bDat = bData.data(); - - vigra::Matrix A(vigra::Shape2(numberOfWavelengths, numberOfChromophores), aDat); - vigra::Matrix b(vigra::Shape2(numberOfWavelengths, 1), bDat); - vigra::Matrix x(vigra::Shape2(numberOfChromophores, 1)); - - if (mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LARS == algorithmName) - nonnegativeLeastSquares(A, b, x); - - else if (mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::GOLDFARB == algorithmName) - { - vigra::linalg::Matrix eye(vigra::linalg::identityMatrix(numberOfChromophores)), - zeros(vigra::Shape2(numberOfChromophores, 1)), - empty, - U = vigra::linalg::transpose(A)*A, - // v= -transpose(A)*b replaced by -v used in "quadraticProgramming" - v = vigra::linalg::transpose(A)*b; - x = 0; - quadraticProgramming(U, -v, empty, empty, eye, zeros, x); - } - - else if (mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::WEIGHTED == algorithmName) - { - if (weightsvec.size() != numberOfWavelengths) - mitkThrow() << "Number of weights and wavelengths doesn't match! OR Invalid weight!"; - const double* weightsdat = weightsvec.data(); - vigra::Matrix weigths(vigra::Shape2(numberOfWavelengths, 1), weightsdat); - vigra::linalg::weightedLeastSquares(A, b, weigths, x); - } - - else if (mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LS == algorithmName) - linearSolve(A, b, x); - - else - mitkThrow() << "404 VIGRA ALGORITHM NOT FOUND"; - - Eigen::VectorXf resultVector(numberOfChromophores); - for (unsigned int k = 0; k < numberOfChromophores; ++k) - resultVector[k] = (float)x(k, 0); - - return resultVector; -} diff --git a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingSO2.cpp b/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingSO2.cpp deleted file mode 100644 index f774b82f0a..0000000000 --- a/Modules/PhotoacousticsLib/src/SUFilter/mitkPASpectralUnmixingSO2.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPASpectralUnmixingSO2.h" - -// ImageAccessor -#include -#include - - -mitk::pa::SpectralUnmixingSO2::SpectralUnmixingSO2() -{ - this->SetNumberOfIndexedInputs(2); - this->SetNumberOfIndexedOutputs(2); - this->SetNthOutput(0, mitk::Image::New()); - this->SetNthOutput(1, mitk::Image::New()); - -} - -mitk::pa::SpectralUnmixingSO2::~SpectralUnmixingSO2() -{ - -} - -void mitk::pa::SpectralUnmixingSO2::Verbose(bool verbose) -{ - m_Verbose = verbose; -} - -void mitk::pa::SpectralUnmixingSO2::GenerateData() -{ - MITK_INFO(m_Verbose) << "GENERATING DATA.."; - - // Get input image - mitk::Image::Pointer inputHbO2 = GetInput(0); - mitk::Image::Pointer inputHb = GetInput(1); - - CheckPreConditions(inputHbO2, inputHb); - - unsigned int xDim = inputHbO2->GetDimensions()[0]; - unsigned int yDim = inputHbO2->GetDimensions()[1]; - unsigned int zDim = inputHbO2->GetDimensions()[2]; - - InitializeOutputs(); - - mitk::ImageReadAccessor readAccessHbO2(inputHbO2); - mitk::ImageReadAccessor readAccessHb(inputHb); - - const float* inputDataArrayHbO2 = ((const float*)readAccessHbO2.GetData()); - const float* inputDataArrayHb = ((const float*)readAccessHb.GetData()); - - auto output = GetOutput(0); - auto output1 = GetOutput(1); - - mitk::ImageWriteAccessor writeOutput(output); - float* writeBuffer = (float *)writeOutput.GetData(); - - mitk::ImageWriteAccessor writeOutput1(output1); - float* writeBuffer1 = (float *)writeOutput1.GetData(); - - for (unsigned int x = 0; x < xDim; x++) - { - for (unsigned int y = 0; y < yDim; y++) - { - for (unsigned int z = 0;z < zDim; z++) - { - unsigned int pixelNumber = (xDim*yDim * z) + x * yDim + y; - float pixelHb = inputDataArrayHb[pixelNumber]; - float pixelHbO2 = inputDataArrayHbO2[pixelNumber]; - float resultSO2 = CalculateSO2(pixelHb, pixelHbO2); - writeBuffer[(xDim*yDim * z) + x * yDim + y] = resultSO2; - float resultTHb = CalculateTHb(pixelHb, pixelHbO2); - writeBuffer1[(xDim*yDim * z) + x * yDim + y] = resultTHb; - } - } - } - MITK_INFO(m_Verbose) << "GENERATING DATA...[DONE]"; -} - -void mitk::pa::SpectralUnmixingSO2::CheckPreConditions(mitk::Image::Pointer inputHbO2, mitk::Image::Pointer inputHb) -{ - unsigned int xDimHb = inputHb->GetDimensions()[0]; - unsigned int yDimHb = inputHb->GetDimensions()[1]; - unsigned int zDimHb = inputHb->GetDimensions()[2]; - - unsigned int xDimHbO2 = inputHbO2->GetDimensions()[0]; - unsigned int yDimHbO2 = inputHbO2->GetDimensions()[1]; - unsigned int zDimHbO2 = inputHbO2->GetDimensions()[2]; - - if (xDimHb != xDimHbO2 || yDimHb != yDimHbO2 || zDimHb != zDimHbO2) - mitkThrow() << "DIMENTIONALITY ERROR!"; - - if (inputHbO2->GetPixelType() != mitk::MakeScalarPixelType()) - mitkThrow() << "PIXELTYPE ERROR! FLOAT REQUIRED"; - - if (inputHb->GetPixelType() != mitk::MakeScalarPixelType()) - mitkThrow() << "PIXELTYPE ERROR! FLOAT REQUIRED"; - - MITK_INFO(m_Verbose) << "CHECK PRECONDITIONS ...[DONE]"; -} - -void mitk::pa::SpectralUnmixingSO2::InitializeOutputs() -{ - // UNUSED unsigned int numberOfInputs = GetNumberOfIndexedInputs(); - unsigned int numberOfOutputs = GetNumberOfIndexedOutputs(); - - mitk::PixelType pixelType = mitk::MakeScalarPixelType(); - const int NUMBER_OF_SPATIAL_DIMENSIONS = 3; - auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS]; - for(unsigned int dimIdx=0; dimIdxGetDimensions()[dimIdx]; - } - - for (unsigned int outputIdx = 0; outputIdx < numberOfOutputs; outputIdx++) - { - GetOutput(outputIdx)->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions); - } -} - -float mitk::pa::SpectralUnmixingSO2::CalculateSO2(float Hb, float HbO2) -{ - float result = HbO2 / (Hb + HbO2); - - if (result != result) - { - MITK_WARN(m_Verbose) << "SO2 VALUE NAN! WILL BE SET TO ZERO!"; - return 0; - } - else - { - if (SO2ValueNotSiginificant(Hb, HbO2, result)) - { - return 0; - } - else return result; - } -} - -float mitk::pa::SpectralUnmixingSO2::CalculateTHb(float Hb, float HbO2) -{ - float result = (Hb + HbO2); - - if (result != result) - { - MITK_WARN(m_Verbose) << "SO2 VALUE NAN! WILL BE SET TO ZERO!"; - return 0; - } - else - { - return result; - } -} - -void mitk::pa::SpectralUnmixingSO2::AddSO2Settings(int value) -{ - m_SO2Settings.push_back(value); -} - -bool mitk::pa::SpectralUnmixingSO2::SO2ValueNotSiginificant(float Hb, float HbO2, float result) -{ - std::vector significant; - significant.push_back(HbO2); - significant.push_back(Hb); - significant.push_back(HbO2 + Hb); - significant.push_back(100*(result)); - - for (unsigned int i = 0; i < m_SO2Settings.size(); ++i) - { - if (m_SO2Settings[i] != 0 && m_SO2Settings[i] > significant[i] && (std::abs(m_SO2Settings[i] - significant[i]) > 1e-7)) - { - return true; - } - } - return false; -} diff --git a/Modules/PhotoacousticsLib/src/Utils/ProbeDesign/mitkPALightSource.cpp b/Modules/PhotoacousticsLib/src/Utils/ProbeDesign/mitkPALightSource.cpp deleted file mode 100644 index f42e51dbce..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/ProbeDesign/mitkPALightSource.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPALightSource.h" -#include -#include - -mitk::pa::LightSource::LightSource() : - m_IsValid(false) -{ -} - -mitk::pa::LightSource::LightSource(const tinyxml2::XMLElement* element, bool verbose) : - m_IsValid(true), - m_Verbose(verbose) -{ - ParseEnergy(element); - ParsePhotonSpawnArea(element); - ParsePhotonDirection(element); - - if (m_IsValid) - { - if (m_Verbose) - std::cout << "Successfully created LightSource" << std::endl; - } - else - { - if (m_Verbose) - std::cout << "Failed creating LightSource." << std::endl; - } -} - -mitk::pa::LightSource::~LightSource() -{ -} - -mitk::pa::LightSource::TransformResult mitk::pa::LightSource::BoxMuellerTransform(double u1, double u2, double mu, double sigma) -{ - TransformResult result; - result.z0 = sqrt(-2.0 * log(u1)) * cos(TWO_PI * u2) * sigma + mu; - result.z1 = sqrt(-2.0 * log(u1)) * sin(TWO_PI * u2) * sigma + mu; - return result; -} - -void mitk::pa::LightSource::ParsePhotonDirection(const tinyxml2::XMLElement* element) -{ - auto* direction = element->FirstChildElement(XML_TAG_PHOTON_DIRECTION.c_str()); - if (direction) - { - ParseAngle(direction, XML_TAG_X_ANGLE); - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_X_ANGLE << "\" field in xml. Setting to default (0, 0, UNIFORM)." << std::endl; - - m_AngleXMinimum = 0; - m_AngleXMaximum = 0; - m_AngleXMode = DistributionMode::UNIFORM; - } - - direction = element->FirstChildElement(XML_TAG_PHOTON_DIRECTION.c_str()); - if (direction) - { - ParseAngle(direction, XML_TAG_Y_ANGLE); - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_Y_ANGLE << "\" field in xml. Setting to default (0, 0, UNIFORM)." << std::endl; - - m_AngleYMinimum = 0; - m_AngleYMaximum = 0; - m_AngleYMode = DistributionMode::UNIFORM; - } -} - -void mitk::pa::LightSource::ParseAngle(const tinyxml2::XMLElement* direction, const std::string& angle) -{ - double minimum; - double maximum; - DistributionMode mode = DistributionMode::GAUSSIAN; - - if (m_Verbose) - std::cout << "Parsing " << angle << std::endl; - auto* angleElement = direction->FirstChildElement(angle.c_str()); - if (angleElement) - { - auto* angleMin = angleElement->FirstChildElement(XML_TAG_MINIMUM.c_str()); - if (angleMin) - { - std::string angleMinText = angleMin->GetText(); - minimum = std::stod(angleMinText); - if (m_Verbose) - std::cout << "Setting min=" << minimum << std::endl; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_MINIMUM << "\" tag in xml. Setting min=0" << std::endl; - minimum = 0; - } - - auto* angleMax = angleElement->FirstChildElement(XML_TAG_MAXIMUM.c_str()); - if (angleMax) - { - std::string angleMaxText = angleMax->GetText(); - maximum = std::stod(angleMaxText); - if (m_Verbose) - std::cout << "Setting max=" << maximum << std::endl; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_MAXIMUM << "\" tag in xml. Setting max=0" << std::endl; - maximum = 0; - } - - auto* angleMode = angleElement->FirstChildElement(XML_TAG_MODE.c_str()); - if (angleMode) - { - std::string angleModeText = angleMode->GetText(); - if (strcmp("UNIFORM", angleModeText.c_str()) == 0) - { - mode = DistributionMode::UNIFORM; - if (m_Verbose) - std::cout << "Setting mode=UNIFORM" << std::endl; - } - else if (strcmp("GAUSSIAN", angleModeText.c_str()) == 0) - { - mode = DistributionMode::GAUSSIAN; - if (m_Verbose) - std::cout << "Setting mode=GAUSSIAN" << std::endl; - } - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_MODE << "\" tag in xml. Setting mode=UNIFORM" << std::endl; - mode = DistributionMode::UNIFORM; - } - } - else - { - if (m_Verbose) - std::cerr << "No \"" << angle << "\" field in xml. Setting to default (0, 0, UNIFORM)." << std::endl; - - maximum = 0; - minimum = 0; - mode = DistributionMode::UNIFORM; - } - - if (strcmp(XML_TAG_X_ANGLE.c_str(), angle.c_str()) == 0) - { - m_AngleXMinimum = minimum; - m_AngleXMaximum = maximum; - m_AngleXMode = mode; - } - else if (strcmp(XML_TAG_Y_ANGLE.c_str(), angle.c_str()) == 0) - { - m_AngleYMinimum = minimum; - m_AngleYMaximum = maximum; - m_AngleYMode = mode; - } -} - -void mitk::pa::LightSource::ParseEnergy(const tinyxml2::XMLElement* element) -{ - auto* energy = element->FirstChildElement(XML_TAG_ENERGY.c_str()); - if (energy) - { - std::string energyText = energy->GetText(); - m_Energy = std::stod(energyText); - if (m_Verbose) - std::cout << "Setting energy=" << m_Energy; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_ENERGY << "\" field in xml. Setting Energy=1" << std::endl; - m_Energy = 1.0; - } -} - -void mitk::pa::LightSource::ParsePhotonSpawnArea(const tinyxml2::XMLElement* element) -{ - auto* spawnArea = element->FirstChildElement("PhotonSpawnArea"); - if (spawnArea) - { - auto* spawnType = spawnArea->FirstChildElement(XML_TAG_SPAWN_TYPE.c_str()); - if (spawnType) - { - std::string spawnTypeText = spawnType->GetText(); - if (strcmp(XML_TAG_SPAWN_TYPE_POINT.c_str(), spawnTypeText.c_str()) == 0) - { - m_SpawnType = SpawnType::POINT; - if (m_Verbose) - std::cout << "Setting " << XML_TAG_SPAWN_TYPE << " = " << XML_TAG_SPAWN_TYPE_POINT << std::endl; - } - else if (strcmp(XML_TAG_SPAWN_TYPE_RECTANGLE.c_str(), spawnTypeText.c_str()) == 0) - { - m_SpawnType = SpawnType::RECTANGLE; - if (m_Verbose) - std::cout << "Setting " << XML_TAG_SPAWN_TYPE << " = " << XML_TAG_SPAWN_TYPE_RECTANGLE << std::endl; - } - else if (strcmp(XML_TAG_SPAWN_TYPE_CIRCLE.c_str(), spawnTypeText.c_str()) == 0) - { - m_SpawnType = SpawnType::CIRCLE; - if (m_Verbose) - std::cout << "Setting " << XML_TAG_SPAWN_TYPE << " = " << XML_TAG_SPAWN_TYPE_CIRCLE << std::endl; - } - else - { - std::cerr << "The provided SpawnType (" << spawnTypeText << ") did not match any available spawn type. Light source is not valid." << std::endl; - m_IsValid = false; - } - } - else - { - std::cerr << "The \"" << XML_TAG_SPAWN_TYPE << "\" element was not provided for this light source. Light source is not valid." << std::endl; - m_IsValid = false; - } - - auto* xLocation = spawnArea->FirstChildElement(XML_TAG_X.c_str()); - if (xLocation) - { - std::string xLocationText = xLocation->GetText(); - m_SpawnLocationX = std::stod(xLocationText); - if (m_Verbose) - std::cout << "Setting " << XML_TAG_X << "=" << m_SpawnLocationX; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_X << "\" field in xml. Setting " << XML_TAG_X << "=0" << std::endl; - m_SpawnLocationX = 0; - } - - auto* yLocation = spawnArea->FirstChildElement(XML_TAG_Y.c_str()); - if (yLocation) - { - std::string yLocationText = yLocation->GetText(); - m_SpawnLocationY = std::stod(yLocationText); - if (m_Verbose) - std::cout << "Setting " << XML_TAG_Y << "=" << m_SpawnLocationY; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_Y << "\" field in xml. Setting " << XML_TAG_Y << "=0" << std::endl; - m_SpawnLocationY = 0; - } - - auto* zLocation = spawnArea->FirstChildElement(XML_TAG_Z.c_str()); - if (zLocation) - { - std::string zLocationText = zLocation->GetText(); - m_SpawnLocationZ = std::stod(zLocationText); - if (m_Verbose) - std::cout << "Setting " << XML_TAG_Z << "=" << m_SpawnLocationZ; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_Z << "\" field in xml. Setting " << XML_TAG_Z << "=0.1" << std::endl; - m_SpawnLocationZ = 0.1; - } - - auto* rLocation = spawnArea->FirstChildElement(XML_TAG_R.c_str()); - if (rLocation) - { - std::string rLocationText = rLocation->GetText(); - m_SpawnLocationRadius = std::stod(rLocationText); - if (m_Verbose) - std::cout << "Setting " << XML_TAG_R << "=" << m_SpawnLocationRadius; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_R << "\" field in xml. Setting " << XML_TAG_R << "=0" << std::endl; - m_SpawnLocationRadius = 0; - } - - auto* xLength = spawnArea->FirstChildElement(XML_TAG_X_LENGTH.c_str()); - if (xLength) - { - std::string xLengthText = xLength->GetText(); - m_SpawnLocationXLength = std::stod(xLengthText); - if (m_Verbose) - std::cout << "Setting " << XML_TAG_X_LENGTH << "=" << m_SpawnLocationXLength << std::endl; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_X_LENGTH << "\" field in xml. Setting " << XML_TAG_X_LENGTH << "=0" << std::endl; - m_SpawnLocationXLength = 0; - } - - auto* yLength = spawnArea->FirstChildElement(XML_TAG_Y_LENGTH.c_str()); - if (yLength) - { - std::string yLengthText = yLength->GetText(); - m_SpawnLocationYLength = std::stod(yLengthText); - if (m_Verbose) - std::cout << "Setting " << XML_TAG_Y_LENGTH << "=" << m_SpawnLocationYLength << std::endl; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_Y_LENGTH << "\" field in xml. Setting " << XML_TAG_Y_LENGTH << "=0" << std::endl; - m_SpawnLocationYLength = 0; - } - - auto* zLength = spawnArea->FirstChildElement(XML_TAG_Z_LENGTH.c_str()); - if (zLength) - { - std::string zLengthText = zLength->GetText(); - m_SpawnLocationZLength = std::stod(zLengthText); - if (m_Verbose) - std::cout << "Setting " << XML_TAG_Z_LENGTH << "=" << m_SpawnLocationZLength << std::endl; - } - else - { - if (m_Verbose) - std::cerr << "No \"" << XML_TAG_Z_LENGTH << "\" field in xml. Setting " << XML_TAG_Z_LENGTH << "=0" << std::endl; - m_SpawnLocationZLength = 0; - } - } - else - m_IsValid = false; -} - -mitk::pa::LightSource::PhotonInformation mitk::pa::LightSource::GetNextPhoton(double rnd1, double rnd2, double rnd3, - double rnd4, double rnd5, double gau1, double gau2) -{ - PhotonInformation returnValue; - - switch (m_SpawnType) - { - case POINT: - returnValue.xPosition = m_SpawnLocationX; - returnValue.yPosition = m_SpawnLocationY; - returnValue.zPosition = m_SpawnLocationZ; - break; - case RECTANGLE: - returnValue.xPosition = m_SpawnLocationX + rnd3 * m_SpawnLocationXLength; - returnValue.yPosition = m_SpawnLocationY + rnd4 * m_SpawnLocationYLength; - returnValue.zPosition = m_SpawnLocationZ + rnd5 * m_SpawnLocationZLength; - break; - case CIRCLE: - double radius = rnd3 * m_SpawnLocationRadius; - double angle = rnd4 * TWO_PI; - - returnValue.xPosition = m_SpawnLocationX + radius * cos(angle); - returnValue.yPosition = m_SpawnLocationY + radius * sin(angle); - returnValue.zPosition = m_SpawnLocationZ; - break; - } - - switch (m_AngleXMode) - { - case UNIFORM: - returnValue.xAngle = rnd1 * (m_AngleXMaximum - m_AngleXMinimum) + m_AngleXMinimum; - break; - case GAUSSIAN: - TransformResult trans = BoxMuellerTransform(gau1, gau2, (m_AngleXMaximum - m_AngleXMinimum) / 2 + m_AngleXMinimum, (m_AngleXMaximum - m_AngleXMinimum) / 2.355); - returnValue.xAngle = trans.z0; - break; - } - - switch (m_AngleYMode) - { - case UNIFORM: - returnValue.yAngle = rnd2 * (m_AngleYMaximum - m_AngleYMinimum) + m_AngleYMinimum; - break; - case GAUSSIAN: - TransformResult trans = BoxMuellerTransform(gau1, gau2, (m_AngleYMaximum - m_AngleYMinimum) / 2 + m_AngleYMinimum, (m_AngleYMaximum - m_AngleYMinimum) / 2.355); - returnValue.yAngle = trans.z1; - break; - } - - if ((returnValue.xAngle*returnValue.xAngle + returnValue.yAngle*returnValue.yAngle) > 1) - { - double unify = sqrt(returnValue.xAngle*returnValue.xAngle + returnValue.yAngle*returnValue.yAngle)*1.001; - returnValue.xAngle = returnValue.xAngle / unify; - returnValue.yAngle = returnValue.yAngle / unify; - } - - returnValue.zAngle = sqrt(1 - returnValue.xAngle*returnValue.xAngle - returnValue.yAngle*returnValue.yAngle); - - if (m_Verbose) - std::cout << "Created a new photon at (" << returnValue.xPosition << "|" << returnValue.yPosition << "|" << - returnValue.zPosition << ") with angle (" << returnValue.xAngle << "|" << returnValue.yAngle << "|" << - returnValue.zAngle << ")" << std::endl; - - return returnValue; -} - -bool mitk::pa::LightSource::IsValid() -{ - return m_IsValid; -} diff --git a/Modules/PhotoacousticsLib/src/Utils/ProbeDesign/mitkPAProbe.cpp b/Modules/PhotoacousticsLib/src/Utils/ProbeDesign/mitkPAProbe.cpp deleted file mode 100644 index 1f1884b4d8..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/ProbeDesign/mitkPAProbe.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAProbe.h" -#include - -mitk::pa::Probe::Probe(std::string file, bool verbose) : - m_TotalEnergy(0), - m_Verbose(verbose) -{ - tinyxml2::XMLDocument xmlDoc; - bool success = xmlDoc.LoadFile(file.c_str()) == tinyxml2::XML_SUCCESS; - if (m_Verbose) - { - std::cout << "reading of document was " << (success ? "" : "not ") << "successful" << std::endl; - std::cout << "Content of the Xml file:" << std::endl; - xmlDoc.Print(); - } - if (success) - { - InitProbe(xmlDoc); - } - else - { - if (m_Verbose) - { - std::cerr << "Could not load xml file" << std::endl; - } - } -} - -mitk::pa::Probe::Probe(const char* fileStream, bool verbose) : - m_TotalEnergy(0), - m_Verbose(verbose) -{ - tinyxml2::XMLDocument xmlDoc; - auto success = xmlDoc.Parse(fileStream); - if (m_Verbose) - { - std::cout << "reading document was " << (success == tinyxml2::XML_SUCCESS ? "" : "not ") << "successful" << std::endl; - std::cout << "Content of the Xml file:" << std::endl; - xmlDoc.Print(); - } - if (success == tinyxml2::XML_SUCCESS) - { - InitProbe(xmlDoc); - } - else - { - if (m_Verbose) - { - std::cerr << "Could not load xml file" << std::endl; - } - } -} - -mitk::pa::Probe::~Probe() -{ -} - -mitk::pa::LightSource::PhotonInformation mitk::pa::Probe::GetNextPhoton(double rng1, double rnd2, - double rnd3, double rnd4, double rnd5, - double rnd6, double rnd7, double rnd8) -{ - rng1 = rng1*m_TotalEnergy; - double currentEnergy = 0; - for (LightSource::Pointer lightSource : m_LightSources) - { - currentEnergy += lightSource->GetEnergy(); - if (currentEnergy >= rng1) - return lightSource->GetNextPhoton(rnd2, rnd3, rnd4, rnd5, rnd6, rnd7, rnd8); - } - - //Last resort: If something goes wrong, return a position from the first source. - return m_LightSources[0]->GetNextPhoton(rnd2, rnd3, rnd4, rnd5, rnd6, rnd7, rnd8); -} - -bool mitk::pa::Probe::IsValid() -{ - return m_IsValid; -} - -void mitk::pa::Probe::InitProbe(const tinyxml2::XMLDocument& xmlDoc) -{ - m_IsValid = true; - - auto* root = xmlDoc.FirstChildElement(XML_TAG_PROBE.c_str()); - if (root) - { - for (auto* element = root->FirstChildElement(XML_TAG_LIGHT_SOURCE.c_str()); - element != nullptr; element = element->NextSiblingElement(XML_TAG_LIGHT_SOURCE.c_str())) - { - LightSource::Pointer lightSource = LightSource::New(element, m_Verbose); - if (lightSource.IsNotNull() && lightSource->IsValid()) - { - m_LightSources.push_back(lightSource); - m_TotalEnergy += lightSource->GetEnergy(); - } - else - { - m_IsValid = false; - } - } - } - else - { - m_IsValid = false; - } - - if (!m_IsValid) - { - std::cerr << "Creation of a valid Photoacoustic Probe failed." << std::endl; - } - else - { - if (m_Verbose) - { - std::cout << "Successfully created Photoacoustic Probe." << std::endl; - } - } -} diff --git a/Modules/PhotoacousticsLib/src/Utils/Thread/mitkPAMonteCarloThreadHandler.cpp b/Modules/PhotoacousticsLib/src/Utils/Thread/mitkPAMonteCarloThreadHandler.cpp deleted file mode 100644 index 1d6ac5a582..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/Thread/mitkPAMonteCarloThreadHandler.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAMonteCarloThreadHandler.h" -#include "mitkCommon.h" - -mitk::pa::MonteCarloThreadHandler::MonteCarloThreadHandler(long timInMillisecondsOrNumberofPhotons, bool simulateOnTimeBasis) : - MonteCarloThreadHandler(timInMillisecondsOrNumberofPhotons, simulateOnTimeBasis, true){} - -mitk::pa::MonteCarloThreadHandler::MonteCarloThreadHandler(long timInMillisecondsOrNumberofPhotons, bool simulateOnTimeBasis, bool verbose) -{ - m_Verbose = verbose; - m_SimulateOnTimeBasis = simulateOnTimeBasis; - m_WorkPackageSize = 10000L; - m_SimulationTime = 0; - m_Time = 0; - m_NumberPhotonsToSimulate = 0; - m_NumberPhotonsRemaining = 0; - - if (m_SimulateOnTimeBasis) - { - m_SimulationTime = timInMillisecondsOrNumberofPhotons; - m_Time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); - } - else - { - m_NumberPhotonsToSimulate = timInMillisecondsOrNumberofPhotons; - m_NumberPhotonsRemaining = timInMillisecondsOrNumberofPhotons; - } -} - -mitk::pa::MonteCarloThreadHandler::~MonteCarloThreadHandler() -{ -} - -long mitk::pa::MonteCarloThreadHandler::GetNextWorkPackage() -{ - long workPackageSize = 0; - if (m_SimulateOnTimeBasis) - { - long now = std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); - if (now - m_Time <= m_SimulationTime) - { - workPackageSize = m_WorkPackageSize; - if (m_Verbose) - { - std::cout << "" << std::endl; - } - } - } - else - { - m_MutexRemainingPhotonsManipulation.lock(); - - if (m_NumberPhotonsRemaining < m_WorkPackageSize) - { - workPackageSize = m_NumberPhotonsRemaining; - } - else - { - workPackageSize = m_WorkPackageSize; - } - - m_NumberPhotonsRemaining -= workPackageSize; - m_MutexRemainingPhotonsManipulation.unlock(); - - if (m_Verbose) - { - std::cout << "" << std::endl; - } - } - - return workPackageSize; -} - -void mitk::pa::MonteCarloThreadHandler::SetPackageSize(long sizeInMilliseconsOrNumberOfPhotons) -{ - m_WorkPackageSize = sizeInMilliseconsOrNumberOfPhotons; -} - -bool mitk::pa::Equal(const MonteCarloThreadHandler::Pointer leftHandSide, - const MonteCarloThreadHandler::Pointer rightHandSide, double /*eps*/, bool verbose) -{ - if (rightHandSide->GetNumberPhotonsRemaining() != leftHandSide->GetNumberPhotonsRemaining()) - { - MITK_INFO(verbose) << "Number of Photons remaining wasnt equal: lhs=" << - leftHandSide->GetNumberPhotonsRemaining() << " rhs=" << rightHandSide->GetNumberPhotonsRemaining(); - return false; - } - - if (rightHandSide->GetNumberPhotonsToSimulate() != leftHandSide->GetNumberPhotonsToSimulate()) - { - MITK_INFO(verbose) << "Number of Photons to simulate wasnt equal: lhs=" << - leftHandSide->GetNumberPhotonsToSimulate() << " rhs=" << rightHandSide->GetNumberPhotonsToSimulate(); - return false; - } - - if (rightHandSide->GetWorkPackageSize() != leftHandSide->GetWorkPackageSize()) - { - MITK_INFO(verbose) << "WorkPackageSize wasnt equal: lhs=" << - leftHandSide->GetWorkPackageSize() << " rhs=" << rightHandSide->GetWorkPackageSize(); - return false; - } - - if (rightHandSide->GetSimulationTime() != leftHandSide->GetSimulationTime()) - { - MITK_INFO(verbose) << "Simulationtime wasnt equal: lhs=" << - leftHandSide->GetSimulationTime() << " rhs=" << rightHandSide->GetSimulationTime(); - return false; - } - - if (rightHandSide->GetSimulateOnTimeBasis() != leftHandSide->GetSimulateOnTimeBasis()) - { - MITK_INFO(verbose) << "simulation on time basis wasnt equal: lhs=" << - leftHandSide->GetSimulateOnTimeBasis() << " rhs=" << rightHandSide->GetSimulateOnTimeBasis(); - return false; - } - - if (rightHandSide->GetVerbose() != leftHandSide->GetVerbose()) - { - MITK_INFO(verbose) << "Verbose wasnt equal: lhs=" << - leftHandSide->GetVerbose() << " rhs=" << rightHandSide->GetVerbose(); - return false; - } - - return true; -} diff --git a/Modules/PhotoacousticsLib/src/Utils/mitkPAPropertyCalculator.cpp b/Modules/PhotoacousticsLib/src/Utils/mitkPAPropertyCalculator.cpp deleted file mode 100644 index 72cdd4f783..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/mitkPAPropertyCalculator.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAPropertyCalculator.h" -// us -#include -#include -#include -#include -#include - -mitk::pa::PropertyCalculator::Properties mitk::pa::PropertyCalculator:: -CalculatePropertyForSpecificWavelength( - TissueType tissueType, int wavelength, double bloodOxygenInFraction) -{ - Properties returnValue; - - if (!m_Valid) - { - mitkThrow() << "PhotoacousticPropertyGenerator was not loaded properly."; - return returnValue; - } - - double bloodOxygenation = bloodOxygenInFraction; - double bloodVolumeFraction; - double waterVolumeFraction; - double fatVolumeFraction; - double melanosomesVolumeFraction; - double musp500; - double fray; - double bmie; - double g; - - switch (tissueType) - { - case AIR: - returnValue.mua = 1e-4; - returnValue.mus = 1.0; - returnValue.g = 1.0; - return returnValue; - case BLOOD: - bloodVolumeFraction = 1.0; - waterVolumeFraction = 0.95; - fatVolumeFraction = 0.02; - melanosomesVolumeFraction = 0; - musp500 = 10; - fray = 0; - bmie = 1; - g = 0.9; - break; - case EPIDERMIS: - bloodVolumeFraction = 0; - bloodOxygenation = 0; - waterVolumeFraction = 0.75; - fatVolumeFraction = 0.01; - melanosomesVolumeFraction = 0.02; - musp500 = 40; - fray = 0; - bmie = 1; - g = 0.9; - break; - case FAT: - bloodVolumeFraction = 0.01; - bloodOxygenation = 0.75; - waterVolumeFraction = 0.5; - fatVolumeFraction = 0.6; - melanosomesVolumeFraction = 0; - musp500 = 17.47; - fray = 0.2; - bmie = 0.5; - g = 0.9; - break; - case STANDARD_TISSUE: - default: - bloodVolumeFraction = 0.02; - bloodOxygenation = 0.75; - waterVolumeFraction = 0.8; - fatVolumeFraction = 0.05; - melanosomesVolumeFraction = 0; - musp500 = 25; - fray = 0.25; - bmie = 1; - g = 0.9; - break; - } - - // We want the reduced scattering coefficient directly. - double musp = musp500 * (fray * pow(wavelength / 500.0, -4.0) + ((1 - fray) * pow(wavelength / 500.0, -bmie))); - returnValue.mus = musp; - returnValue.mus = 15;//musp; - - double mua = bloodVolumeFraction*bloodOxygenation*m_SpectralLibMap[ChromophoreType::OXYGENATED][wavelength] + - bloodVolumeFraction*(1 - bloodOxygenation)*m_SpectralLibMap[ChromophoreType::DEOXYGENATED][wavelength] + - waterVolumeFraction*m_SpectralLibMap[ChromophoreType::WATER][wavelength] + - fatVolumeFraction*m_SpectralLibMap[ChromophoreType::FATTY][wavelength] + - melanosomesVolumeFraction*m_SpectralLibMap[ChromophoreType::MELANIN][wavelength]; - - returnValue.mua = mua; - - returnValue.g = g; - - return returnValue; -} - -mitk::pa::PropertyCalculator::PropertyCalculator() -{ - us::ModuleResource resource = us::GetModuleContext()->GetModule()->GetResource("spectralLIB.dat"); - - if (resource.IsValid()) - { - us::ModuleResourceStream resourceStream(resource); - std::string line; - int wavelength = 300; - int counter = 0; - while (std::getline(resourceStream, line, '\t')) - { - int currentLineIdx = counter % 6; - if (currentLineIdx == 0) - wavelength = std::stoi(line); - else - { - std::istringstream lineStream(line); - double tempDouble; - lineStream >> tempDouble; - m_SpectralLibMap[currentLineIdx][wavelength] = tempDouble; - } - ++counter; - } - } - else - { - m_Valid = false; - } - - m_Valid = true; -} - -mitk::pa::PropertyCalculator::~PropertyCalculator() -{ - m_SpectralLibMap.clear(); - m_Valid = false; -} - -double mitk::pa::PropertyCalculator::GetAbsorptionForWavelength( - ChromophoreType ChromophoreType, int wavelength) -{ - return m_SpectralLibMap[ChromophoreType][wavelength]; -} diff --git a/Modules/PhotoacousticsLib/src/Utils/mitkPATissueGeneratorParameters.cpp b/Modules/PhotoacousticsLib/src/Utils/mitkPATissueGeneratorParameters.cpp deleted file mode 100644 index af644788e2..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/mitkPATissueGeneratorParameters.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPATissueGeneratorParameters.h" - -mitk::pa::TissueGeneratorParameters::TissueGeneratorParameters() -{ - m_XDim = 50; - m_YDim = 50; - m_ZDim = 50; - m_VoxelSpacingInCentimeters = 1; - m_DoPartialVolume = false; - m_UseRngSeed = false; - m_RngSeed = 1337L; - m_RandomizePhysicalProperties = false; - m_RandomizePhysicalPropertiesPercentage = 0; - m_ForceVesselsMoveAlongYDirection = false; - - m_MinBackgroundAbsorption = 0.1; - m_MaxBackgroundAbsorption = 0.1; - m_BackgroundScattering = 15; - m_BackgroundAnisotropy = 0.9; - m_AirAbsorption = 0.0001; - m_AirScattering = 1; - m_AirAnisotropy = 1; - m_AirThicknessInMillimeters = 0; - m_SkinAbsorption = 0.1; - m_SkinScattering = 15; - m_SkinAnisotropy = 0.9; - m_SkinThicknessInMillimeters = 0; - - m_CalculateNewVesselPositionCallback = &VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector; - m_MinNumberOfVessels = 0; - m_MaxNumberOfVessels = 0; - m_MinVesselBending = 0; - m_MaxVesselBending = 0.1; - m_MinVesselAbsorption = 1; - m_MaxVesselAbsorption = 8; - m_MinVesselRadiusInMillimeters = 1; - m_MaxVesselRadiusInMillimeters = 3; - m_VesselBifurcationFrequency = 25; - m_MinVesselScattering = 15; - m_MaxVesselScattering = 15; - m_MinVesselAnisotropy = 0.9; - m_MaxVesselAnisotropy = 0.9; - m_MinVesselZOrigin = 10; - m_MaxVesselZOrigin = 40; - - m_MCflag = 1; - m_MCLaunchflag = 0; - m_MCBoundaryflag = 2; - m_MCLaunchPointX = 25; - m_MCLaunchPointY = 25; - m_MCLaunchPointZ = 2; - m_MCFocusPointX = 25; - m_MCFocusPointY = 25; - m_MCFocusPointZ = 25; - m_MCTrajectoryVectorX = 0; - m_MCTrajectoryVectorY = 0; - m_MCTrajectoryVectorZ = 1; - m_MCRadius = 2; - m_MCWaist = 4; -} - -mitk::pa::TissueGeneratorParameters::~TissueGeneratorParameters() -{ -} diff --git a/Modules/PhotoacousticsLib/src/Utils/mitkPAVector.cpp b/Modules/PhotoacousticsLib/src/Utils/mitkPAVector.cpp deleted file mode 100644 index fd82072890..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/mitkPAVector.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVector.h" -#include "chrono" -#include -mitk::pa::Vector::Vector() -{ - m_Vector.Fill(0); -} - -mitk::pa::Vector::~Vector() -{ - m_Vector.Fill(0); -} - -double mitk::pa::Vector::GetNorm() -{ - return m_Vector.GetNorm(); -} - -double mitk::pa::Vector::GetElement(unsigned short index) -{ - return m_Vector.GetElement(index); -} - -void mitk::pa::Vector::SetElement(unsigned short index, double value) -{ - m_Vector.SetElement(index, value); -} - -void mitk::pa::Vector::Normalize() -{ - double norm = m_Vector.GetNorm(); - m_Vector.SetElement(0, m_Vector.GetElement(0) / norm); - m_Vector.SetElement(1, m_Vector.GetElement(1) / norm); - m_Vector.SetElement(2, m_Vector.GetElement(2) / norm); -} - -void mitk::pa::Vector::SetValue(mitk::pa::Vector::Pointer value) -{ - m_Vector.SetElement(0, value->GetElement(0)); - m_Vector.SetElement(1, value->GetElement(1)); - m_Vector.SetElement(2, value->GetElement(2)); -} - -void mitk::pa::Vector::RandomizeByPercentage(double percentage, double bendingFactor, std::mt19937* rng) -{ - std::uniform_real_distribution<> range(-percentage, percentage); - m_Vector.SetElement(0, m_Vector.GetElement(0) + (bendingFactor * range(*rng))); - m_Vector.SetElement(1, m_Vector.GetElement(1) + (bendingFactor * range(*rng))); - m_Vector.SetElement(2, m_Vector.GetElement(2) + (bendingFactor * range(*rng))); -} - -void mitk::pa::Vector::Randomize(double xLowerLimit, double xUpperLimit, double yLowerLimit, double yUpperLimit, double zLowerLimit, double zUpperLimit, std::mt19937* rng) -{ - std::uniform_real_distribution<> rangeX(xLowerLimit, xUpperLimit); - std::uniform_real_distribution<> rangeY(yLowerLimit, yUpperLimit); - std::uniform_real_distribution<> rangeZ(zLowerLimit, zUpperLimit); - m_Vector.SetElement(0, rangeX(*rng)); - m_Vector.SetElement(1, rangeY(*rng)); - m_Vector.SetElement(2, rangeZ(*rng)); -} - -void mitk::pa::Vector::Randomize(double xLimit, double yLimit, double zLimit, std::mt19937* rng) -{ - Randomize(0, xLimit, 0, yLimit, 0, zLimit, rng); -} - -void mitk::pa::Vector::Randomize(std::mt19937* rng) -{ - Randomize(-1, 1, -1, 1, -1, 1, rng); -} - -void mitk::pa::Vector::PrintSelf(std::ostream& os, itk::Indent /*indent*/) const -{ - os << "X: " << m_Vector.GetElement(0) << std::endl; - os << "Y: " << m_Vector.GetElement(1) << std::endl; - os << "Z: " << m_Vector.GetElement(2) << std::endl; - os << "Length: " << m_Vector.GetNorm() << std::endl; -} - -void mitk::pa::Vector::Rotate(double thetaChange, double phiChange) -{ - MITK_DEBUG << "Vector before rotation: (" << GetElement(0) << "|" << GetElement(1) << "|" << GetElement(2) << ")"; - if (thetaChange == 0 && phiChange == 0) - return; - - double x = GetElement(0); - double y = GetElement(1); - double z = GetElement(2); - - double r = sqrt(x*x + y*y + z*z); - if (r == 0) - return; - - double theta = acos(z / r); - double phi = atan2(y, x); - - theta += thetaChange; - phi += phiChange; - - SetElement(0, r * sin(theta) * cos(phi)); - SetElement(1, r * sin(theta) * sin(phi)); - SetElement(2, r * cos(theta)); - - MITK_DEBUG << "Vector after rotation: (" << GetElement(0) << "|" << GetElement(1) << "|" << GetElement(2) << ")"; -} - -void mitk::pa::Vector::Scale(double factor) -{ - m_Vector.SetElement(0, m_Vector.GetElement(0)*factor); - m_Vector.SetElement(1, m_Vector.GetElement(1)*factor); - m_Vector.SetElement(2, m_Vector.GetElement(2)*factor); -} - -mitk::pa::Vector::Pointer mitk::pa::Vector::Clone() -{ - auto returnVector = Vector::New(); - returnVector->SetElement(0, this->GetElement(0)); - returnVector->SetElement(1, this->GetElement(1)); - returnVector->SetElement(2, this->GetElement(2)); - return returnVector; -} - -void mitk::pa::Vector::Subtract(Vector::Pointer other) -{ - m_Vector.SetElement(0, m_Vector.GetElement(0) - other->GetElement(0)); - m_Vector.SetElement(1, m_Vector.GetElement(1) - other->GetElement(1)); - m_Vector.SetElement(2, m_Vector.GetElement(2) - other->GetElement(2)); -} - -void mitk::pa::Vector::Add(Vector::Pointer other) -{ - m_Vector.SetElement(0, m_Vector.GetElement(0) + other->GetElement(0)); - m_Vector.SetElement(1, m_Vector.GetElement(1) + other->GetElement(1)); - m_Vector.SetElement(2, m_Vector.GetElement(2) + other->GetElement(2)); -} - -bool mitk::pa::Equal(const Vector::Pointer leftHandSide, const Vector::Pointer rightHandSide, double eps, bool verbose) -{ - MITK_INFO(verbose) << "=== mitk::pa::Vector Equal ==="; - - if (rightHandSide.IsNull() || leftHandSide.IsNull()) - { - MITK_INFO(verbose) << "Cannot compare nullpointers"; - return false; - } - - if (leftHandSide->GetElement(0) - rightHandSide->GetElement(0) > eps) - { - MITK_INFO(verbose) << "Element[0] not equal"; - return false; - } - - if (leftHandSide->GetElement(1) - rightHandSide->GetElement(1) > eps) - { - MITK_INFO(verbose) << "Element[1] not equal"; - return false; - } - - if (leftHandSide->GetElement(2) - rightHandSide->GetElement(2) > eps) - { - MITK_INFO(verbose) << "Element[2] not equal"; - return false; - } - - return true; -} diff --git a/Modules/PhotoacousticsLib/src/Utils/mitkPAVesselDrawer.cpp b/Modules/PhotoacousticsLib/src/Utils/mitkPAVesselDrawer.cpp deleted file mode 100644 index 30c46f0432..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/mitkPAVesselDrawer.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVesselDrawer.h" -#include "mitkPAVesselProperties.h" - -mitk::pa::VesselDrawer::VesselDrawer() -{ -} - -mitk::pa::VesselDrawer::~VesselDrawer() -{ -} - -void mitk::pa::VesselDrawer::ExpandAndDrawVesselInVolume( - VesselProperties::Pointer properties, - InSilicoTissueVolume::Pointer volume) -{ - Vector::Pointer stepDirection = properties->GetDirectionVector(); - Vector::Pointer fromPosition = properties->GetPositionVector()->Clone(); - - Vector::Pointer totalWalkingDistance = stepDirection->Clone(); - totalWalkingDistance->Scale(1.0 / volume->GetSpacing()); - - while (totalWalkingDistance->GetNorm() >= 1) - { - double xPos = fromPosition->GetElement(0); - double yPos = fromPosition->GetElement(1); - double zPos = fromPosition->GetElement(2); - - if (!volume->IsInsideVolume(xPos, yPos, zPos)) - { - properties->SetRadiusInVoxel(0); - return; - } - - double radius = properties->GetRadiusInVoxel(); - double ceiledRadius = ceil(radius); - - for (int x = xPos - ceiledRadius; x <= xPos + ceiledRadius; x += 1) - for (int y = yPos - ceiledRadius; y <= yPos + ceiledRadius; y += 1) - for (int z = zPos - ceiledRadius; z <= zPos + ceiledRadius; z += 1) - { - if (!volume->IsInsideVolume(x, y, z)) - { - continue; - } - double xDiff = x - xPos; - double yDiff = y - yPos; - double zDiff = z - zPos; - double vectorLengthDiff = radius - sqrt(xDiff*xDiff + yDiff*yDiff + zDiff*zDiff); - - if (vectorLengthDiff > 0) - { - volume->SetVolumeValues(x, y, z, - properties->GetAbsorptionCoefficient(), - properties->GetScatteringCoefficient(), - properties->GetAnisotopyCoefficient(), - mitk::pa::InSilicoTissueVolume::SegmentationType::VESSEL); - } - } - - totalWalkingDistance->Subtract(stepDirection); - fromPosition->Add(stepDirection); - } - - properties->SetPositionVector(fromPosition); -} diff --git a/Modules/PhotoacousticsLib/src/Utils/mitkPAVolumeManipulator.cpp b/Modules/PhotoacousticsLib/src/Utils/mitkPAVolumeManipulator.cpp deleted file mode 100644 index 89c609158b..0000000000 --- a/Modules/PhotoacousticsLib/src/Utils/mitkPAVolumeManipulator.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkPAVolumeManipulator.h" -#include "mitkPAExceptions.h" -#include "mitkPAInSilicoTissueVolume.h" -#include "itkResampleImageFilter.h" -#include "itkGaussianInterpolateImageFunction.h" - -// Includes for image casting between ITK and MITK -#include -#include - -#include - -mitk::pa::VolumeManipulator::VolumeManipulator() {} - -mitk::pa::VolumeManipulator::~VolumeManipulator() {} - -void mitk::pa::VolumeManipulator::ThresholdImage(Volume::Pointer image, double threshold) -{ - for (unsigned int z = 0; z < image->GetZDim(); z++) - for (unsigned int y = 0; y < image->GetYDim(); y++) - for (unsigned int x = 0; x < image->GetXDim(); x++) - if (image->GetData(x, y, z) > threshold) - image->SetData(1, x, y, z); - else - image->SetData(0, x, y, z); -} - -void mitk::pa::VolumeManipulator::MultiplyImage(Volume::Pointer image, double factor) -{ - for (unsigned int z = 0; z < image->GetZDim(); z++) - for (unsigned int y = 0; y < image->GetYDim(); y++) - for (unsigned int x = 0; x < image->GetXDim(); x++) - image->SetData(image->GetData(x, y, z)*factor, x, y, z); -} - -void mitk::pa::VolumeManipulator::Log10Image(Volume::Pointer image) -{ - for (unsigned int z = 0; z < image->GetZDim(); z++) - for (unsigned int y = 0; y < image->GetYDim(); y++) - for (unsigned int x = 0; x < image->GetXDim(); x++) - { - if (image->GetData(x, y, z) < 0) - { - MITK_ERROR << "Signal was smaller than 0. There is an error in the input image file."; - throw InvalidValueException("Signal was smaller than 0. There is an error in the input image file."); - } - image->SetData(log10(image->GetData(x, y, z)), x, y, z); - } -} - -void mitk::pa::VolumeManipulator::RescaleImage(InSilicoTissueVolume::Pointer image, double ratio) -{ - MITK_INFO << "Rescaling images.."; - double sigma = image->GetSpacing() / (ratio * 2); - image->SetAbsorptionVolume(RescaleImage(image->GetAbsorptionVolume(), ratio, sigma)); - image->SetScatteringVolume(RescaleImage(image->GetScatteringVolume(), ratio, sigma)); - image->SetAnisotropyVolume(RescaleImage(image->GetAnisotropyVolume(), ratio, sigma)); - image->SetSegmentationVolume(RescaleImage(image->GetSegmentationVolume(), ratio, 0)); - MITK_INFO << "Rescaling images..[Done]"; -} - -mitk::pa::Volume::Pointer mitk::pa::VolumeManipulator::RescaleImage(Volume::Pointer image, double ratio, double sigma) -{ - MITK_INFO << "Rescaling image.."; - typedef itk::Image ImageType; - typedef itk::ResampleImageFilter FilterType; - typedef itk::GaussianInterpolateImageFunction InterpolatorType; - - auto input = image->AsMitkImage(); - ImageType::Pointer itkInput = ImageType::New(); - mitk::CastToItkImage(input, itkInput); - - ImageType::SizeType outputSize; - outputSize[0] = input->GetDimensions()[0] * ratio; - outputSize[1] = input->GetDimensions()[1] * ratio; - outputSize[2] = input->GetDimensions()[2] * ratio; - - FilterType::Pointer resampleImageFilter = FilterType::New(); - resampleImageFilter->SetInput(itkInput); - resampleImageFilter->SetSize(outputSize); - if (sigma > mitk::eps) - { - auto interpolator = InterpolatorType::New(); - interpolator->SetSigma(sigma); - resampleImageFilter->SetInterpolator(interpolator); - } - resampleImageFilter->SetOutputSpacing(input->GetGeometry()->GetSpacing()[0] / ratio); - - MITK_INFO << "Update.."; - resampleImageFilter->UpdateLargestPossibleRegion(); - MITK_INFO << "Update..[Done]"; - - ImageType::Pointer output = resampleImageFilter->GetOutput(); - mitk::Image::Pointer mitkOutput = mitk::Image::New(); - - GrabItkImageMemory(output, mitkOutput); - MITK_INFO << "Rescaling image..[Done]"; - return Volume::New(mitkOutput); -} - -/** -* @brief Fast 3D Gaussian convolution IIR approximation -* @param paVolume -* @param sigma -* @author Pascal Getreuer -* -* Copyright (c) 2011, Pascal Getreuer -* All rights reserved. -* -* This program is free software: you can redistribute it and/or modify it -* under the terms of the simplified BSD license. -* -* You should have received a copy of these licenses along with this program. -* If not, see . -*/ -void mitk::pa::VolumeManipulator::GaussianBlur3D(mitk::pa::Volume::Pointer paVolume, double sigma) -{ - double* volume = paVolume->GetData(); - long width = paVolume->GetYDim(); - long height = paVolume->GetXDim(); - long depth = paVolume->GetZDim(); - const long plane = width*height; - const long numel = plane*depth; - double lambda, dnu; - double nu, boundaryscale, postscale; - double *ptr; - long i, x, y, z; - int step; - - if (sigma <= 0) - return; - - lambda = (sigma*sigma) / (8.0); - dnu = (1.0 + 2.0*lambda - sqrt(1.0 + 4.0*lambda)) / (2.0*lambda); - nu = dnu; - boundaryscale = 1.0 / (1.0 - dnu); - postscale = pow(dnu / lambda, 12); - - /* Filter horizontally along each row */ - for (z = 0; z < depth; z++) - { - for (y = 0; y < height; y++) - { - for (step = 0; step < 4; step++) - { - ptr = volume + width*(y + height*z); - ptr[0] *= boundaryscale; - - /* Filter rightwards */ - for (x = 1; x < width; x++) - { - ptr[x] += nu*ptr[x - 1]; - } - - ptr[x = width - 1] *= boundaryscale; - /* Filter leftwards */ - for (; x > 0; x--) - { - ptr[x - 1] += nu*ptr[x]; - } - } - } - } - /* Filter vertically along each column */ - for (z = 0; z < depth; z++) - { - for (x = 0; x < width; x++) - { - for (step = 0; step < 4; step++) - { - ptr = volume + x + plane*z; - ptr[0] *= boundaryscale; - - /* Filter downwards */ - for (i = width; i < plane; i += width) - { - ptr[i] += nu*ptr[i - width]; - } - - ptr[i = plane - width] *= boundaryscale; - - /* Filter upwards */ - for (; i > 0; i -= width) - { - ptr[i - width] += nu*ptr[i]; - } - } - } - } - - /* Filter along z-dimension */ - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) - { - for (step = 0; step < 4; step++) - { - ptr = volume + x + width*y; - ptr[0] *= boundaryscale; - - for (i = plane; i < numel; i += plane) - { - ptr[i] += nu*ptr[i - plane]; - } - - ptr[i = numel - plane] *= boundaryscale; - - for (; i > 0; i -= plane) - { - ptr[i - plane] += nu*ptr[i]; - } - } - } - } - - for (i = 0; i < numel; i++) - { - volume[i] *= postscale; - } -} diff --git a/Modules/PhotoacousticsLib/test/CMakeLists.txt b/Modules/PhotoacousticsLib/test/CMakeLists.txt deleted file mode 100644 index 153cd81e2e..0000000000 --- a/Modules/PhotoacousticsLib/test/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -MITK_CREATE_MODULE_TESTS() diff --git a/Modules/PhotoacousticsLib/test/Resources/allsources.xml b/Modules/PhotoacousticsLib/test/Resources/allsources.xml deleted file mode 100644 index 36a213c5f9..0000000000 --- a/Modules/PhotoacousticsLib/test/Resources/allsources.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - 1 - - POINT - 0.3 - 0.2 - 0.1 - - - - -0.1 - 0.1 - UNIFORM - - - -0.2 - 0.2 - UNIFORM - - - - - 1 - - RECTANGLE - 0.4 - 0.5 - 0.6 - 0.7 - 0.8 - 0.9 - - - - -0.3 - 0.3 - GAUSSIAN - - - -0.4 - 0.4 - GAUSSIAN - - - - - 1 - - CIRCLE - 0.4 - 0.5 - 0.6 - 0.5 - - - - -0.3 - 0.3 - GAUSSIAN - - - -0.4 - 0.4 - GAUSSIAN - - - - diff --git a/Modules/PhotoacousticsLib/test/Resources/circlesource.xml b/Modules/PhotoacousticsLib/test/Resources/circlesource.xml deleted file mode 100644 index 14ef65dd58..0000000000 --- a/Modules/PhotoacousticsLib/test/Resources/circlesource.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - 1 - - CIRCLE - 0.3 - 0.2 - 0.1 - 2 - - - - -0.1 - 0.1 - GAUSSIAN - - - -0.2 - 0.2 - UNIFORM - - - - diff --git a/Modules/PhotoacousticsLib/test/Resources/pointsource.xml b/Modules/PhotoacousticsLib/test/Resources/pointsource.xml deleted file mode 100644 index 0ab73fdb8d..0000000000 --- a/Modules/PhotoacousticsLib/test/Resources/pointsource.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - 1 - - POINT - 0.3 - 0.2 - 0.1 - - - - -0.1 - 0.1 - UNIFORM - - - -0.2 - 0.2 - UNIFORM - - - - diff --git a/Modules/PhotoacousticsLib/test/Resources/rectanglesource.xml b/Modules/PhotoacousticsLib/test/Resources/rectanglesource.xml deleted file mode 100644 index 7c9a4f2f9e..0000000000 --- a/Modules/PhotoacousticsLib/test/Resources/rectanglesource.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - 1 - - RECTANGLE - 0.3 - 0.2 - 0.1 - 1 - 2 - 3 - - - - -0.1 - 0.1 - UNIFORM - - - -0.2 - 0.2 - UNIFORM - - - - diff --git a/Modules/PhotoacousticsLib/test/Resources/twopointsources.xml b/Modules/PhotoacousticsLib/test/Resources/twopointsources.xml deleted file mode 100644 index 5054ee51c8..0000000000 --- a/Modules/PhotoacousticsLib/test/Resources/twopointsources.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - 1 - - POINT - 0.3 - 0.2 - 0.1 - - - - -0.1 - 0.1 - UNIFORM - - - -0.2 - 0.2 - UNIFORM - - - - - 1 - - POINT - 0.4 - 0.5 - 0.6 - - - - -0.3 - 0.3 - GAUSSIAN - - - -0.4 - 0.4 - GAUSSIAN - - - - diff --git a/Modules/PhotoacousticsLib/test/files.cmake b/Modules/PhotoacousticsLib/test/files.cmake deleted file mode 100644 index 4026e7fcf2..0000000000 --- a/Modules/PhotoacousticsLib/test/files.cmake +++ /dev/null @@ -1,40 +0,0 @@ -set(MODULE_TESTS - # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. - # - # Example: #mitkMyTest #this test is commented out because of bug 12345 - # - # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that - # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and - # mark it as critical. - - ################## ON THE FENCE TESTS ################################################# - # none - - ################## DISABLED TESTS ##################################################### - # mitkMCThreadHandlerTest.cpp #Timing issue on VMs - # mitkPhotoacousticIOTest.cpp #Not suitable for large scale testing as it performs IO actions. - ################# RUNNING TESTS ####################################################### - - mitkSlicedVolumeGeneratorTest.cpp - mitkPhotoacousticTissueGeneratorTest.cpp - mitkPhotoacousticVectorTest.cpp - mitkPhotoacoustic3dVolumeTest.cpp - # mitkPhotoacousticVolumeTest.cpp (See T27024) - mitkPhotoacousticVesselTreeTest.cpp - mitkMcxyzXmlTest.cpp - mitkPhotoacousticComposedVolumeTest.cpp - mitkPhotoacousticNoiseGeneratorTest.cpp - mitkSimulationBatchGeneratorTest.cpp - mitkPropertyCalculatorTest.cpp - # mitkSpectralUnmixingTest.cpp (See T27024) - mitkPhotoacousticVesselMeanderStrategyTest.cpp - mitkPhotoacousticVesselTest.cpp -) - -set(RESOURCE_FILES - pointsource.xml - circlesource.xml - rectanglesource.xml - twopointsources.xml - allsources.xml -) diff --git a/Modules/PhotoacousticsLib/test/mitkMCThreadHandlerTest.cpp b/Modules/PhotoacousticsLib/test/mitkMCThreadHandlerTest.cpp deleted file mode 100644 index 65247b86a2..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkMCThreadHandlerTest.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -// us -#include -#include -#include -#include -#include - -#include -#include - -class mitkMCThreadHandlerTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkMCThreadHandlerTestSuite); - MITK_TEST(testConstructorBehavior); - MITK_TEST(testCorrectNumberOfPhotons); - MITK_TEST(testCorrectNumberOfPhotonsWithUnevenPackageSize); - MITK_TEST(testCorrectNumberOfPhotonsWithTooLargePackageSize); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::pa::MonteCarloThreadHandler::Pointer m_MonteCarloThreadHandler; - long m_NumberOrTime = 500; - -public: - - void setUp() override - { - } - - void testConstructorBehavior() - { - auto threadHandler1 = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true, true); - auto threadHandler2 = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, true); - - CPPUNIT_ASSERT(mitk::pa::Equal(threadHandler1, threadHandler2, 1e-6, true)); - } - - void testCorrectNumberOfPhotons() - { - m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false); - m_MonteCarloThreadHandler->SetPackageSize(100); - long numberOfPhotonsSimulated = 0; - long nextWorkPackage = 0; - while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0) - { - numberOfPhotonsSimulated += nextWorkPackage; - } - CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime); - } - - void testCorrectNumberOfPhotonsWithUnevenPackageSize() - { - m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false); - m_MonteCarloThreadHandler->SetPackageSize(77); - long numberOfPhotonsSimulated = 0; - long nextWorkPackage = 0; - while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0) - { - numberOfPhotonsSimulated += nextWorkPackage; - } - CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime); - } - - void testCorrectNumberOfPhotonsWithTooLargePackageSize() - { - m_MonteCarloThreadHandler = mitk::pa::MonteCarloThreadHandler::New(m_NumberOrTime, false, false); - m_MonteCarloThreadHandler->SetPackageSize(10000); - long numberOfPhotonsSimulated = 0; - long nextWorkPackage = 0; - while ((nextWorkPackage = m_MonteCarloThreadHandler->GetNextWorkPackage()) > 0) - { - numberOfPhotonsSimulated += nextWorkPackage; - } - CPPUNIT_ASSERT(numberOfPhotonsSimulated == m_NumberOrTime); - } - - void tearDown() override - { - m_MonteCarloThreadHandler = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkMCThreadHandler) diff --git a/Modules/PhotoacousticsLib/test/mitkMcxyzXmlTest.cpp b/Modules/PhotoacousticsLib/test/mitkMcxyzXmlTest.cpp deleted file mode 100644 index ac773e6309..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkMcxyzXmlTest.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -// us -#include -#include -#include -#include -#include -#include -#include -#include - -class mitkMcxyzXmlTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkMcxyzXmlTestSuite); - MITK_TEST(TestCreatePointSourceProbe); - MITK_TEST(TestCreateCircleSourceProbe); - MITK_TEST(TestCreateRectangleSourceProbe); - MITK_TEST(TestCreateTwoPointSourcesProbe); - MITK_TEST(TestCreateAllSourcesProbe); - MITK_TEST(TestValuesAreInBoundsUniformRectangle); - MITK_TEST(TestValuesAreInBoundsGaussianRectangle); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::pa::LightSource::Pointer m_LightSource; - mitk::pa::Probe::Pointer m_Probe; - std::string m_XmlProbePointSource; - std::string m_XmlProbeCircleSource; - std::string m_XmlProbeRectangleSource; - std::string m_XmlProbeTwoPointSources; - std::string m_XmlProbeAllSources; - -public: - - void setUp() override - { - m_LightSource = mitk::pa::LightSource::New(); - LoadXmlFile("pointsource.xml", &m_XmlProbePointSource); - LoadXmlFile("circlesource.xml", &m_XmlProbeCircleSource); - LoadXmlFile("rectanglesource.xml", &m_XmlProbeRectangleSource); - LoadXmlFile("twopointsources.xml", &m_XmlProbeTwoPointSources); - LoadXmlFile("allsources.xml", &m_XmlProbeAllSources); - } - - void LoadXmlFile(std::string filename, std::string* lines) - { - us::ModuleResource pointSourceXml = us::GetModuleContext()->GetModule()->GetResource(filename); - std::string line; - if (pointSourceXml.IsValid() && pointSourceXml.IsFile()) - { - us::ModuleResourceStream stream(pointSourceXml); - stream.std::istream::imbue(std::locale("C")); - while (std::getline(stream, line)) - { - *lines = *lines + line + " "; - } - } - else - { - MITK_ERROR << "Xml file was not valid"; - } - } - - void TestCreatePointSourceProbe() - { - m_Probe = mitk::pa::Probe::New(m_XmlProbePointSource.c_str(), true); - CPPUNIT_ASSERT(true == m_Probe->IsValid()); - } - - void TestCreateCircleSourceProbe() - { - m_Probe = mitk::pa::Probe::New(m_XmlProbeCircleSource.c_str(), true); - CPPUNIT_ASSERT(true == m_Probe->IsValid()); - } - - void TestCreateRectangleSourceProbe() - { - m_Probe = mitk::pa::Probe::New(m_XmlProbeRectangleSource.c_str(), true); - CPPUNIT_ASSERT(true == m_Probe->IsValid()); - } - - void TestCreateTwoPointSourcesProbe() - { - m_Probe = mitk::pa::Probe::New(m_XmlProbeTwoPointSources.c_str(), true); - CPPUNIT_ASSERT(true == m_Probe->IsValid()); - } - - void TestCreateAllSourcesProbe() - { - m_Probe = mitk::pa::Probe::New(m_XmlProbeAllSources.c_str(), true); - CPPUNIT_ASSERT(true == m_Probe->IsValid()); - } - - void TestValuesAreInBoundsUniformRectangle() - { - int MAXIMUM = 2; - int MINIMUM = -2; - - int ANGLE_MAXIMUM = 1; - int ANGLE_MINIMUM = -1; - - m_LightSource->SetAngleXMode(mitk::pa::LightSource::DistributionMode::UNIFORM); - m_LightSource->SetAngleYMode(mitk::pa::LightSource::DistributionMode::UNIFORM); - - m_LightSource->SetAngleXMaximum(ANGLE_MAXIMUM); - m_LightSource->SetAngleXMinimum(ANGLE_MINIMUM); - - m_LightSource->SetAngleYMaximum(ANGLE_MAXIMUM); - m_LightSource->SetAngleYMinimum(ANGLE_MINIMUM); - - m_LightSource->SetSpawnLocationX(MINIMUM); - m_LightSource->SetSpawnLocationXLength(2 * MAXIMUM); - - m_LightSource->SetSpawnLocationY(MINIMUM); - m_LightSource->SetSpawnLocationYLength(2 * MAXIMUM); - - m_LightSource->SetSpawnLocationZ(MINIMUM); - m_LightSource->SetSpawnLocationZLength(2 * MAXIMUM); - - m_LightSource->SetSpawnLocationRadius(MAXIMUM); - - m_LightSource->SetVerbose(false); - - m_LightSource->SetSpawnType(mitk::pa::LightSource::SpawnType::RECTANGLE); - - std::mt19937 rng; - rng.seed(std::chrono::duration_cast(std::chrono::high_resolution_clock:: - now().time_since_epoch()).count()); - std::uniform_real_distribution<> realDist(0, 1); - - for (int i = 0, length = 10000; i < length; i++) - { - auto result = - m_LightSource->GetNextPhoton(realDist(rng), realDist(rng), realDist(rng), realDist(rng), - realDist(rng), realDist(rng), realDist(rng)); - - CPPUNIT_ASSERT(result.xAngle >= ANGLE_MINIMUM); - CPPUNIT_ASSERT(result.xAngle <= ANGLE_MAXIMUM); - CPPUNIT_ASSERT(result.yAngle >= ANGLE_MINIMUM); - CPPUNIT_ASSERT(result.yAngle <= ANGLE_MAXIMUM); - CPPUNIT_ASSERT(result.zAngle >= 0); - CPPUNIT_ASSERT(result.zAngle <= ANGLE_MAXIMUM); - CPPUNIT_ASSERT(result.xPosition >= MINIMUM); - CPPUNIT_ASSERT(result.xPosition <= MAXIMUM); - CPPUNIT_ASSERT(result.yPosition >= MINIMUM); - CPPUNIT_ASSERT(result.yPosition <= MAXIMUM); - CPPUNIT_ASSERT(result.zPosition >= MINIMUM); - CPPUNIT_ASSERT(result.zPosition <= MAXIMUM); - } - } - - void TestValuesAreInBoundsGaussianRectangle() - { - int MAXIMUM = 2; - int MINIMUM = -2; - - int ANGLE_MAXIMUM = 1; - int ANGLE_MINIMUM = -1; - - m_LightSource->SetAngleXMode(mitk::pa::LightSource::DistributionMode::GAUSSIAN); - m_LightSource->SetAngleYMode(mitk::pa::LightSource::DistributionMode::GAUSSIAN); - - m_LightSource->SetAngleXMaximum(ANGLE_MAXIMUM); - m_LightSource->SetAngleXMinimum(ANGLE_MINIMUM); - - m_LightSource->SetAngleYMaximum(ANGLE_MAXIMUM); - m_LightSource->SetAngleYMinimum(ANGLE_MINIMUM); - - m_LightSource->SetSpawnLocationX(MINIMUM); - m_LightSource->SetSpawnLocationXLength(2 * MAXIMUM); - - m_LightSource->SetSpawnLocationY(MINIMUM); - m_LightSource->SetSpawnLocationYLength(2 * MAXIMUM); - - m_LightSource->SetSpawnLocationZ(MINIMUM); - m_LightSource->SetSpawnLocationZLength(2 * MAXIMUM); - - m_LightSource->SetSpawnLocationRadius(MAXIMUM); - - m_LightSource->SetVerbose(false); - - m_LightSource->SetSpawnType(mitk::pa::LightSource::SpawnType::RECTANGLE); - - std::mt19937 rng; - rng.seed(std::chrono::duration_cast(std::chrono::high_resolution_clock:: - now().time_since_epoch()).count()); - std::uniform_real_distribution<> realDist(0, 1); - - for (int i = 0, length = 10000; i < length; i++) - { - auto result = - m_LightSource->GetNextPhoton(realDist(rng), realDist(rng), realDist(rng), realDist(rng), - realDist(rng), realDist(rng), realDist(rng)); - - CPPUNIT_ASSERT(result.xAngle >= ANGLE_MINIMUM); - CPPUNIT_ASSERT(result.xAngle <= ANGLE_MAXIMUM); - CPPUNIT_ASSERT(result.yAngle >= ANGLE_MINIMUM); - CPPUNIT_ASSERT(result.yAngle <= ANGLE_MAXIMUM); - CPPUNIT_ASSERT(result.zAngle >= 0); - CPPUNIT_ASSERT(result.zAngle <= ANGLE_MAXIMUM); - CPPUNIT_ASSERT(result.xPosition >= MINIMUM); - CPPUNIT_ASSERT(result.xPosition <= MAXIMUM); - CPPUNIT_ASSERT(result.yPosition >= MINIMUM); - CPPUNIT_ASSERT(result.yPosition <= MAXIMUM); - CPPUNIT_ASSERT(result.zPosition >= MINIMUM); - CPPUNIT_ASSERT(result.zPosition <= MAXIMUM); - } - } - - void tearDown() override - { - m_XmlProbePointSource = ""; - m_XmlProbeCircleSource = ""; - m_XmlProbeRectangleSource = ""; - m_XmlProbeTwoPointSources = ""; - m_XmlProbeAllSources = ""; - m_Probe = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkMcxyzXml) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacoustic3dVolumeTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacoustic3dVolumeTest.cpp deleted file mode 100644 index 8452bdc5b7..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacoustic3dVolumeTest.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include "mitkPAVolume.h" -#include -#include - -class mitkPhotoacoustic3dVolumeTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacoustic3dVolumeTestSuite); - MITK_TEST(TestCorrectGetDataAndSetDataBehavior); - MITK_TEST(TestCallingConstructorWithNullParameter); - MITK_TEST(TestCallingConstructorWithCorrectParameters); - MITK_TEST(TestModifyImage); - MITK_TEST(TestModifyComplexImage); - MITK_TEST(TestConvertToMitkImage); - MITK_TEST(TestDeepCopy); - MITK_TEST(TestCatchException); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::pa::Volume::Pointer m_Photoacoustic3dVolume; - -public: - - void setUp() override - { - } - - void TestCallingConstructorWithNullParameter() - { - bool exceptionEncountered = false; - try - { - m_Photoacoustic3dVolume = mitk::pa::Volume::New(nullptr, 3, 3, 3, 1); - } - catch (...) - { - exceptionEncountered = true; - } - CPPUNIT_ASSERT(exceptionEncountered); - } - - void TestCallingConstructorWithCorrectParameters() - { - auto* data = new double[1]; - data[0] = 3; - m_Photoacoustic3dVolume = mitk::pa::Volume::New(data, 1, 1, 1, 1); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 0) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetXDim() == 1); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetYDim() == 1); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetZDim() == 1); - } - - void TestModifyImage() - { - auto* data = new double[1]; - data[0] = 3; - m_Photoacoustic3dVolume = mitk::pa::Volume::New(data, 1, 1, 1, 1); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_Photoacoustic3dVolume->GetData(0, 0, 0)), m_Photoacoustic3dVolume->GetData(0, 0, 0) == 3); - m_Photoacoustic3dVolume->SetData(17, 0, 0, 0); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 0) == 17); - } - - void TestModifyComplexImage() - { - unsigned int xDim = 4; - unsigned int yDim = 7; - unsigned int zDim = 12; - unsigned int length = xDim * yDim * zDim; - auto* data = new double[length]; - for (unsigned int i = 0; i < length; i++) - data[i] = 5; - - m_Photoacoustic3dVolume = mitk::pa::Volume::New(data, xDim, yDim, zDim, 1); - - for (unsigned int z = 0; z < zDim; z++) - for (unsigned int y = 0; y < yDim; y++) - for (unsigned int x = 0; x < xDim; x++) - { - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(x, y, z) == 5); - m_Photoacoustic3dVolume->SetData((x + y)*(z + 1), x, y, z); - CPPUNIT_ASSERT(std::abs(m_Photoacoustic3dVolume->GetData(x, y, z) - (x + y)*(z + 1)) < mitk::eps); - } - } - - void TestCorrectGetDataAndSetDataBehavior() - { - unsigned int xDim = 40; - unsigned int yDim = 7; - unsigned int zDim = 12; - unsigned int length = xDim * yDim * zDim; - auto* data = new double[length]; - for (unsigned int i = 0; i < length; i++) - data[i] = 0; - - m_Photoacoustic3dVolume = mitk::pa::Volume::New(data, xDim, yDim, zDim, 1); - - for (unsigned int z = 0; z < zDim; z++) - for (unsigned int y = 0; y < yDim; y++) - for (unsigned int x = 0; x < xDim; x++) - { - int index = z*xDim*yDim + x*yDim + y; - m_Photoacoustic3dVolume->SetData(index, x, y, z); - CPPUNIT_ASSERT_MESSAGE(std::to_string(index), m_Photoacoustic3dVolume->GetData(x, y, z) == index); - } - } - - void TestConvertToMitkImage() - { - auto* data = new double[6]; - data[0] = 3; - data[1] = 3; - data[2] = 3; - data[3] = 3; - data[4] = 3; - data[5] = 3; - m_Photoacoustic3dVolume = mitk::pa::Volume::New(data, 1, 2, 3, 1); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 0) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 1) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 2) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 1, 0) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 1, 1) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 1, 2) == 3); - - m_Photoacoustic3dVolume->SetData(17, 0, 0, 0); - m_Photoacoustic3dVolume->SetData(17, 0, 1, 0); - m_Photoacoustic3dVolume->SetData(17, 0, 1, 2); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 0) == 17); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 1) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 2) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 1, 0) == 17); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 1, 1) == 3); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 1, 2) == 17); - - mitk::Image::Pointer mitkImage = m_Photoacoustic3dVolume->AsMitkImage(); - CPPUNIT_ASSERT(mitkImage->GetDimensions()[0] == 2); - CPPUNIT_ASSERT(mitkImage->GetDimensions()[1] == 1); - CPPUNIT_ASSERT(mitkImage->GetDimensions()[2] == 3); - - mitk::ImageReadAccessor readAccess(mitkImage, mitkImage->GetVolumeData()); - auto* copyData = (double*)readAccess.GetData(); - CPPUNIT_ASSERT_MESSAGE(std::to_string(copyData[0]), copyData[0] == 17); - CPPUNIT_ASSERT_MESSAGE(std::to_string(copyData[1]), copyData[1] == 17); - CPPUNIT_ASSERT_MESSAGE(std::to_string(copyData[2]), copyData[2] == 3); - CPPUNIT_ASSERT_MESSAGE(std::to_string(copyData[3]), copyData[3] == 3); - CPPUNIT_ASSERT_MESSAGE(std::to_string(copyData[4]), copyData[4] == 3); - CPPUNIT_ASSERT_MESSAGE(std::to_string(copyData[5]), copyData[5] == 17); - } - - void TestDeepCopy() - { - auto* data = new double[1]; - data[0] = 3; - m_Photoacoustic3dVolume = mitk::pa::Volume::New(data, 1, 1, 1, 1); - mitk::pa::Volume::Pointer copiedVolume = m_Photoacoustic3dVolume->DeepCopy(); - - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetXDim() == copiedVolume->GetXDim()); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetYDim() == copiedVolume->GetYDim()); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetZDim() == copiedVolume->GetZDim()); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 0) == 3); - CPPUNIT_ASSERT(copiedVolume->GetData(0, 0, 0) == 3); - m_Photoacoustic3dVolume->SetData(17, 0, 0, 0); - CPPUNIT_ASSERT(m_Photoacoustic3dVolume->GetData(0, 0, 0) == 17); - CPPUNIT_ASSERT(copiedVolume->GetData(0, 0, 0) == 3); - } - - void AssertIndexException(unsigned int x, unsigned int y, unsigned int z) - { - bool exceptionCaught = false; - try - { - double thisIsIrrelevant = m_Photoacoustic3dVolume->GetData(x, y, z); - thisIsIrrelevant += 1; - } - catch (...) - { - exceptionCaught = true; - if (exceptionCaught) - exceptionCaught = true; - } -#ifdef _DEBUG - - CPPUNIT_ASSERT(exceptionCaught); - -#endif - } - - void TestCatchException() - { - auto* data = new double[1]; - data[0] = 3; - m_Photoacoustic3dVolume = mitk::pa::Volume::New(data, 1, 1, 1, 1); - - AssertIndexException(1, 0, 0); - AssertIndexException(0, 1, 0); - AssertIndexException(0, 0, 1); - AssertIndexException(18, 1, 222); - } - - void tearDown() override - { - m_Photoacoustic3dVolume = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacoustic3dVolume) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticComposedVolumeTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticComposedVolumeTest.cpp deleted file mode 100644 index 5d5b05a955..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticComposedVolumeTest.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include -#include - -#include "mitkPAComposedVolume.h" -#include "mitkIOUtil.h" -#include "mitkImageReadAccessor.h" -#include - -class mitkPhotoacousticComposedVolumeTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticComposedVolumeTestSuite); - MITK_TEST(TestCreateAndDestructComposedVolume); - MITK_TEST(TestAccessInvalidFluenceComponent); - MITK_TEST(TestAccessInvalidFluenceComponentIndex); - MITK_TEST(TestAddMultiplePairs); - MITK_TEST(TestSortFunctionality); - MITK_TEST(TestAccessInvalidFluenceComponentForYOffset); - CPPUNIT_TEST_SUITE_END(); - -private: - mitk::pa::ComposedVolume::Pointer m_ComposedVolume; - mitk::pa::TissueGeneratorParameters::Pointer m_DefaultParameters; - mitk::pa::InSilicoTissueVolume::Pointer m_InSilicoTissueVolume; - -public: - - void setUp() override - { - m_DefaultParameters = mitk::pa::TissueGeneratorParameters::New(); - m_DefaultParameters->SetXDim(5); - m_DefaultParameters->SetYDim(5); - m_DefaultParameters->SetZDim(5); - auto rng = std::mt19937(); - m_InSilicoTissueVolume = mitk::pa::InSilicoTissueVolume::New(m_DefaultParameters, &rng); - m_ComposedVolume = mitk::pa::ComposedVolume::New(m_InSilicoTissueVolume); - } - - mitk::pa::FluenceYOffsetPair::Pointer createFluenceYOffsetPair(double value, double yOffset) - { - auto* data = new double[125]; - for (int i = 0; i < 125; ++i) - data[i] = value; - mitk::pa::Volume::Pointer volume = mitk::pa::Volume::New(data, 5, 5, 5, 1); - return mitk::pa::FluenceYOffsetPair::New(volume, yOffset); - } - - void TestCreateAndDestructComposedVolume() - { - CPPUNIT_ASSERT(m_ComposedVolume->GetNumberOfFluenceComponents() == 0); - } - - void TestAccessInvalidFluenceComponent() - { - bool caughtException = false; - try - { - m_ComposedVolume->GetFluenceValue(0, 0, 0, 0); - } - catch (const mitk::Exception &) - { - caughtException = true; - } - CPPUNIT_ASSERT(caughtException); - } - - void TestAddMultiplePairs() - { - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(0, 0)); - CPPUNIT_ASSERT(m_ComposedVolume->GetNumberOfFluenceComponents() == 1); - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(1, 1)); - CPPUNIT_ASSERT(m_ComposedVolume->GetNumberOfFluenceComponents() == 2); - } - - void TestSortFunctionality() - { - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(2, 2)); - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(-1, -1)); - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(1, 1)); - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(0, 0)); - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(-2, -2)); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(0, 0, 2, 0) == 2); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(1, 0, 2, 0) == -1); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(2, 0, 2, 0) == 1); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(3, 0, 2, 0) == 0); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(4, 0, 2, 0) == -2); - - m_ComposedVolume->Sort(); - - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(0, 0, 2, 0) == -2); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(1, 0, 2, 0) == -1); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(2, 0, 2, 0) == 0); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(3, 0, 2, 0) == 1); - CPPUNIT_ASSERT(m_ComposedVolume->GetFluenceValue(4, 0, 2, 0) == 2); - } - - void TestAccessInvalidFluenceComponentIndex() - { -#ifdef _DEBUG - m_ComposedVolume->AddSlice(createFluenceYOffsetPair(0, 0)); - bool caughtException = false; - try - { - double unusedValue = m_ComposedVolume->GetFluenceValue(0, 1, 2, 300); - unusedValue = 0; - } - catch (const mitk::Exception e) - { - caughtException = true; - } - CPPUNIT_ASSERT(caughtException); -#endif - } - - void TestAccessInvalidFluenceComponentForYOffset() - { - bool caughtException = false; - try - { - m_ComposedVolume->GetYOffsetForFluenceComponentInPixels(0); - } - catch (const mitk::Exception &) - { - caughtException = true; - } - CPPUNIT_ASSERT(caughtException); - } - - void tearDown() override - { - m_ComposedVolume = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticComposedVolume) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticIOTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticIOTest.cpp deleted file mode 100644 index c242b55f46..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticIOTest.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -class mitkPhotoacousticIOTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticIOTestSuite); - MITK_TEST(testLoadInSilicoTissueNrrdFile); - MITK_TEST(testLoad3DVolumeNrrdFile); - MITK_TEST(testLoad3DVolumeNrrdFileWithBlur); - MITK_TEST(testGetNumberOfNrrdFilesInTestDir); - MITK_TEST(testGetChildFoldersFromFolder); - MITK_TEST(testLoadFCMs); - CPPUNIT_TEST_SUITE_END(); - -private: - - const std::string TEST_FOLDER_PATH = "testFiles/"; - const std::string TEST_IN_SILICO_VOLUME_PATH = "testInSilicoVolume"; - const std::string TEST_3D_Volume_PATH = "test3DVolume"; - const std::string TEST_FILE_ENDING = ".nrrd"; - const std::string TEST_QUALIFIED_FOLDER_PATH = TEST_FOLDER_PATH + TEST_IN_SILICO_VOLUME_PATH + "/"; - const std::string FOLDER_FOLDER = "folder/"; - const std::string FCM_PATH = TEST_FOLDER_PATH + "fcms/"; - const int NUMBER_OF_NRRD_FILES_IN_TEST_DIR = 2; - mitk::pa::TissueGeneratorParameters::Pointer m_VolumeProperties; - mitk::pa::InSilicoTissueVolume::Pointer m_TestInSilicoVolume; - mitk::pa::Volume::Pointer m_Test3DVolume; - -public: - - void setUp() override - { - m_VolumeProperties = createTestVolumeParameters(); - auto rng = std::mt19937(); - m_TestInSilicoVolume = mitk::pa::InSilicoTissueVolume::New(m_VolumeProperties, &rng); - m_Test3DVolume = createTest3DVolume(5); - itk::FileTools::CreateDirectory(TEST_FOLDER_PATH); - itk::FileTools::CreateDirectory(TEST_QUALIFIED_FOLDER_PATH); - itk::FileTools::CreateDirectory(TEST_FOLDER_PATH + FOLDER_FOLDER + FOLDER_FOLDER); - itk::FileTools::CreateDirectory(FCM_PATH); - CPPUNIT_ASSERT(itksys::SystemTools::FileIsDirectory(TEST_FOLDER_PATH)); - CPPUNIT_ASSERT(itksys::SystemTools::FileIsDirectory(TEST_QUALIFIED_FOLDER_PATH)); - CPPUNIT_ASSERT(itksys::SystemTools::FileIsDirectory(TEST_FOLDER_PATH + FOLDER_FOLDER + FOLDER_FOLDER)); - CPPUNIT_ASSERT(itksys::SystemTools::FileIsDirectory(FCM_PATH)); - - mitk::IOUtil::Save(m_TestInSilicoVolume->ConvertToMitkImage(), - TEST_FOLDER_PATH + TEST_IN_SILICO_VOLUME_PATH + TEST_FILE_ENDING); - mitk::IOUtil::Save(m_Test3DVolume->AsMitkImage(), - TEST_FOLDER_PATH + TEST_3D_Volume_PATH + TEST_FILE_ENDING); - auto yo0 = createTest3DVolume(1)->AsMitkImage(); - auto yo1 = createTest3DVolume(2)->AsMitkImage(); - - yo0->GetPropertyList()->SetStringProperty("y-offset", "0"); - yo1->GetPropertyList()->SetStringProperty("y-offset", "1"); - mitk::CoreServices::GetPropertyPersistence()->AddInfo(mitk::PropertyPersistenceInfo::New("y-offset")); - - mitk::IOUtil::Save(yo0, TEST_QUALIFIED_FOLDER_PATH + TEST_IN_SILICO_VOLUME_PATH + "_yo0" + TEST_FILE_ENDING); - mitk::IOUtil::Save(yo1, TEST_QUALIFIED_FOLDER_PATH + TEST_IN_SILICO_VOLUME_PATH + "_yo1" + TEST_FILE_ENDING); - } - - mitk::pa::Volume::Pointer createTest3DVolume(double value) - { - unsigned int xDim = 10; - unsigned int yDim = 10; - unsigned int zDim = 10; - unsigned int length = xDim * yDim * zDim; - auto* data = new double[length]; - for (unsigned int i = 0; i < length; i++) - data[i] = value; - - return mitk::pa::Volume::New(data, xDim, yDim, zDim, 1); - } - - mitk::pa::TissueGeneratorParameters::Pointer createTestVolumeParameters() - { - auto returnParameters = mitk::pa::TissueGeneratorParameters::New(); - returnParameters->SetXDim(10); - returnParameters->SetYDim(10); - returnParameters->SetZDim(10); - returnParameters->SetMinBackgroundAbsorption(0); - returnParameters->SetMaxBackgroundAbsorption(0); - returnParameters->SetBackgroundScattering(0); - returnParameters->SetBackgroundAnisotropy(0); - return returnParameters; - } - - void assertEqual(mitk::pa::Volume::Pointer first, mitk::pa::Volume::Pointer second) - { - CPPUNIT_ASSERT(first->GetXDim() == second->GetXDim()); - CPPUNIT_ASSERT(first->GetYDim() == second->GetYDim()); - CPPUNIT_ASSERT(first->GetZDim() == second->GetZDim()); - for (unsigned int x = 0; x < first->GetXDim(); ++x) - for (unsigned int y = 0; y < first->GetYDim(); ++y) - for (unsigned int z = 0; z < first->GetZDim(); ++z) - { - std::string message = "Expected " + std::to_string(first->GetData(x, y, z)) + " but was " + std::to_string(second->GetData(x, y, z)); - CPPUNIT_ASSERT_MESSAGE(message, std::abs(first->GetData(x, y, z) - second->GetData(x, y, z)) < 1e-6); - } - } - - void testLoadInSilicoTissueNrrdFile() - { - auto loadedVolume = mitk::pa::IOUtil::LoadInSilicoTissueVolumeFromNrrdFile(TEST_FOLDER_PATH + TEST_IN_SILICO_VOLUME_PATH + TEST_FILE_ENDING); - CPPUNIT_ASSERT(loadedVolume->GetTDim() == m_TestInSilicoVolume->GetTDim()); - assertEqual(m_TestInSilicoVolume->GetAbsorptionVolume(), loadedVolume->GetAbsorptionVolume()); - assertEqual(m_TestInSilicoVolume->GetScatteringVolume(), loadedVolume->GetScatteringVolume()); - assertEqual(m_TestInSilicoVolume->GetAnisotropyVolume(), loadedVolume->GetAnisotropyVolume()); - } - - void testLoad3DVolumeNrrdFile() - { - auto loadedVolume = mitk::pa::IOUtil::LoadNrrd(TEST_FOLDER_PATH + TEST_3D_Volume_PATH + TEST_FILE_ENDING); - assertEqual(loadedVolume, m_Test3DVolume); - } - - void testLoad3DVolumeNrrdFileWithBlur() - { - auto loadedVolume = mitk::pa::IOUtil::LoadNrrd(TEST_FOLDER_PATH + TEST_3D_Volume_PATH + TEST_FILE_ENDING, 1); - assertEqual(loadedVolume, m_Test3DVolume); - } - - void testGetNumberOfNrrdFilesInTestDir() - { - int numberOfFiles = mitk::pa::IOUtil::GetNumberOfNrrdFilesInDirectory(TEST_FOLDER_PATH); - CPPUNIT_ASSERT(numberOfFiles == NUMBER_OF_NRRD_FILES_IN_TEST_DIR); - } - - void testGetChildFoldersFromFolder() - { - std::vector childFolders = mitk::pa::IOUtil::GetAllChildfoldersFromFolder(TEST_FOLDER_PATH); - CPPUNIT_ASSERT(childFolders.size() == 1); - CPPUNIT_ASSERT(childFolders[0] == TEST_FOLDER_PATH); - childFolders = mitk::pa::IOUtil::GetAllChildfoldersFromFolder(TEST_FOLDER_PATH + FOLDER_FOLDER); - MITK_INFO << "ChildFolders: " << childFolders.size(); - CPPUNIT_ASSERT(childFolders.size() == 1); - CPPUNIT_ASSERT(childFolders[0] == TEST_FOLDER_PATH + FOLDER_FOLDER + "/folder"); - } - - void testLoadFCMs() - { - auto fcm1 = createTest3DVolume(1); - auto fcm2 = createTest3DVolume(2); - auto fcm3 = createTest3DVolume(3); - auto fcm4 = createTest3DVolume(4); - mitk::IOUtil::Save(fcm1->AsMitkImage(), FCM_PATH + "fcm1_p0,0,0FluenceContributionMap.nrrd"); - mitk::IOUtil::Save(fcm2->AsMitkImage(), FCM_PATH + "fcm1_p0,0,1FluenceContributionMap.nrrd"); - mitk::IOUtil::Save(fcm3->AsMitkImage(), FCM_PATH + "fcm1_p1,0,0FluenceContributionMap.nrrd"); - mitk::IOUtil::Save(fcm4->AsMitkImage(), FCM_PATH + "fcm1_p1,0,1FluenceContributionMap.nrrd"); - - int prog = 0; - auto map = mitk::pa::IOUtil::LoadFluenceContributionMaps(FCM_PATH, 0, &prog); - - assertEqual(fcm1, map[mitk::pa::IOUtil::Position{ 0,0 }]); - assertEqual(fcm2, map[mitk::pa::IOUtil::Position{ 0,1 }]); - assertEqual(fcm3, map[mitk::pa::IOUtil::Position{ 1,0 }]); - assertEqual(fcm4, map[mitk::pa::IOUtil::Position{ 1,1 }]); - } - - void tearDown() override - { - //CPPUNIT_ASSERT_MESSAGE("Resource leak of test files onto hard drive..", itksys::SystemTools::RemoveADirectory(TEST_FOLDER_PATH) == true); - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticIO) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticNoiseGeneratorTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticNoiseGeneratorTest.cpp deleted file mode 100644 index 38a5b5f3ce..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticNoiseGeneratorTest.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -#include "mitkPAVolume.h" -#include "mitkPANoiseGenerator.h" - -class mitkPhotoacousticNoiseGeneratorTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticNoiseGeneratorTestSuite); - MITK_TEST(testNoiseGenerator); - CPPUNIT_TEST_SUITE_END(); - -private: - -public: - - mitk::pa::Volume::Pointer m_Volume; - - void setUp() override - { - } - - void testNoiseGenerator() - { - int size = 1000 * 100 * 100; - auto* volume = new double[size]; - for (int i = 0; i < size; i++) - { - volume[i] = 1; - } - m_Volume = mitk::pa::Volume::New(volume, 1000, 100, 100, 1); - mitk::pa::NoiseGenerator::ApplyNoiseModel(m_Volume, 0.75, 0.1); - - int negativecounter = 0; - - for (int i = 0; i < size; i++) - { - if (m_Volume->GetData()[i] <= 0) - { - negativecounter++; - } - } - CPPUNIT_ASSERT_EQUAL_MESSAGE("More than one negative: " + - std::to_string(negativecounter) + " (" + - std::to_string((((double)negativecounter) / size) * 100) + "%)", negativecounter, 0); - } - - void tearDown() override - { - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticNoiseGenerator) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticTissueGeneratorTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticTissueGeneratorTest.cpp deleted file mode 100644 index 7168f292fa..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticTissueGeneratorTest.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include "mitkPATissueGenerator.h" - -class mitkPhotoacousticTissueGeneratorTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticTissueGeneratorTestSuite); - MITK_TEST(testCallWithEmptyParameters); - MITK_TEST(testCallWithWorkingParameters); - CPPUNIT_TEST_SUITE_END(); - -private: - -public: - - void setUp() override - { - } - - mitk::pa::TissueGeneratorParameters::Pointer createRandomTestVolumeParameters() - { - auto returnParameters = mitk::pa::TissueGeneratorParameters::New(); - - returnParameters->SetXDim(rand() % 50 + 1); - returnParameters->SetYDim(rand() % 50 + 1); - returnParameters->SetZDim(rand() % 50 + 1); - double absorb = rand() % 100 / 10.0; - returnParameters->SetMinBackgroundAbsorption(absorb); - returnParameters->SetMaxBackgroundAbsorption(absorb); - returnParameters->SetBackgroundScattering(rand() % 100 / 10.0); - returnParameters->SetBackgroundAnisotropy(rand() % 100 / 10.0); - int min = rand() % 10; - returnParameters->SetMinNumberOfVessels(min); - returnParameters->SetMaxNumberOfVessels(min + (rand() % 10)); - returnParameters->SetCalculateNewVesselPositionCallback( - &mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - returnParameters->SetMinVesselZOrigin(rand() % 3 + 1); - returnParameters->SetMaxVesselZOrigin(rand() % 3 + 1); - int minRad = rand() % 100; - returnParameters->SetMinVesselRadiusInMillimeters(minRad); - returnParameters->SetMaxVesselRadiusInMillimeters(minRad + (rand() % 100)); - returnParameters->SetVoxelSpacingInCentimeters(1); - return returnParameters; - } - - void testCallWithEmptyParameters() - { - auto parameters = mitk::pa::TissueGeneratorParameters::New(); - auto volume = mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(parameters); - CPPUNIT_ASSERT(volume.IsNotNull()); - } - - void testCallWithWorkingParameters() - { - for (int i = 0; i < 20; i++) - { - auto parameters = createRandomTestVolumeParameters(); - auto volume = mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(parameters); - CPPUNIT_ASSERT(volume.IsNotNull()); - } - } - - void tearDown() override - { - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticTissueGenerator) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVectorTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVectorTest.cpp deleted file mode 100644 index ac579e29b6..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVectorTest.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include "mitkPAVector.h" - -class mitkPhotoacousticVectorTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticVectorTestSuite); - - MITK_TEST(TestNormalizeVector); - MITK_TEST(TestRotateVectorZeroDegrees); - MITK_TEST(TestRotatedVectorPositiveDegrees); - MITK_TEST(TestRotateVectorZeroDegrees); - MITK_TEST(TestScaleVector); - MITK_TEST(TestCloneVector); - - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::pa::Vector::Pointer m_TestVector; - mitk::pa::Vector::Pointer m_TestReturnVector; - - const double DIF_VAL = 0.001; - const double TWO_PI = 6.283185; - -public: - - void setUp() override - { - m_TestVector = mitk::pa::Vector::New(); - m_TestReturnVector = mitk::pa::Vector::New(); - } - - void TestNormalizeVector() - { - std::stringstream output; - int a = 2; - int b = 3; - int c = 4; - - m_TestVector->SetElement(0, a); - m_TestVector->SetElement(1, b); - m_TestVector->SetElement(2, c); - - output << "The vectorlength should be"; - output << sqrt(a*a + b*b + c*c); - CPPUNIT_ASSERT_EQUAL_MESSAGE(output.str(), sqrt(a*a + b*b + c*c), m_TestVector->GetNorm()); - output.flush(); - - m_TestVector->Normalize(); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vectorlength should be 1.", true, m_TestVector->GetNorm() - 1 < DIF_VAL); - } - - void TestRotateVectorZeroDegrees() - { - int a = 1; - int b = 2; - int c = 3; - - double length; - - m_TestVector->SetElement(0, a); - m_TestVector->SetElement(1, b); - m_TestVector->SetElement(2, c); - - length = m_TestVector->GetNorm(); - - m_TestVector->Rotate(0, 0); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector length should be equal", length, m_TestVector->GetNorm()); - - CPPUNIT_ASSERT_MESSAGE("The vector value at index0 should be 1.0", m_TestVector->GetElement(0) - 1 < DIF_VAL); - CPPUNIT_ASSERT_MESSAGE("The vector value at index1 should be 2.0", m_TestVector->GetElement(1) - 2 < DIF_VAL); - CPPUNIT_ASSERT_MESSAGE("The vector value at index2 should be 3.0", m_TestVector->GetElement(2) - 3 < DIF_VAL); - } - - void TestRotatedVectorPositiveDegrees() - { - MITK_INFO << atan2(0, 0); - - for (int r = 0; r < 10; r++) - { - for (double phi = 0.1; phi < 3; phi += 0.1) - { - for (double theta = 0.1; theta < 3; theta += 0.1) - { - double rotateTheta = 0.1; - double rotatePhi = 0.1; - - m_TestVector->SetElement(0, r * sin(theta) * cos(phi)); - m_TestVector->SetElement(1, r * sin(theta) * sin(phi)); - m_TestVector->SetElement(2, r * cos(theta)); - - m_TestVector->Rotate(rotateTheta, rotatePhi); - - double newTheta = fmod(theta + rotateTheta, TWO_PI); - double newPhi = fmod(phi + rotatePhi, TWO_PI); - - double expectedX = r * sin(newTheta) * cos(newPhi); - double expectedY = r * sin(newTheta) * sin(newPhi); - double expectedZ = r * cos(newTheta); - - CPPUNIT_ASSERT_MESSAGE("The vector value at index0 should be " + std::to_string(expectedX) + " but was " + std::to_string(m_TestVector->GetElement(0)) - + " at r=" + std::to_string(r) + " phi=" + std::to_string(phi) + " theta=" + std::to_string(theta), - m_TestVector->GetElement(0) - expectedX < DIF_VAL); - CPPUNIT_ASSERT_MESSAGE("The vector value at index1 should be " + std::to_string(expectedY) + " but was " + std::to_string(m_TestVector->GetElement(0)) - + " at r=" + std::to_string(r) + " phi=" + std::to_string(phi) + " theta=" + std::to_string(theta), - m_TestVector->GetElement(1) - expectedY < DIF_VAL); - CPPUNIT_ASSERT_MESSAGE("The vector value at index2 should be " + std::to_string(expectedZ) + " but was " + std::to_string(m_TestVector->GetElement(0)) - + " at r=" + std::to_string(r) + " phi=" + std::to_string(phi) + " theta=" + std::to_string(theta), - m_TestVector->GetElement(2) - expectedZ < DIF_VAL); - } - } - } - } - - void TestRotatedVectorNegativeDegrees() - { - for (int r = 0; r < 10; r++) - { - for (double phi = -0.1; phi > -3; phi -= 0.1) - { - for (double theta = -0.1; theta > -3; theta -= 0.1) - { - double rotateTheta = -0.1; - double rotatePhi = -0.1; - - m_TestVector->SetElement(0, r * sin(theta) * cos(phi)); - m_TestVector->SetElement(1, r * sin(theta) * sin(phi)); - m_TestVector->SetElement(2, r * cos(theta)); - - m_TestVector->Rotate(rotateTheta, rotatePhi); - - double newTheta = fmod(theta + rotateTheta, TWO_PI); - double newPhi = fmod(phi + rotatePhi, TWO_PI); - - double expectedX = r * sin(newTheta) * cos(newPhi); - double expectedY = r * sin(newTheta) * sin(newPhi); - double expectedZ = r * cos(newTheta); - - CPPUNIT_ASSERT_MESSAGE("The vector value at index0 should be " + std::to_string(expectedX) + " but was " + std::to_string(m_TestVector->GetElement(0)) - + " at r=" + std::to_string(r) + " phi=" + std::to_string(phi) + " theta=" + std::to_string(theta), - m_TestVector->GetElement(0) - expectedX < DIF_VAL); - CPPUNIT_ASSERT_MESSAGE("The vector value at index1 should be " + std::to_string(expectedY) + " but was " + std::to_string(m_TestVector->GetElement(0)) - + " at r=" + std::to_string(r) + " phi=" + std::to_string(phi) + " theta=" + std::to_string(theta), - m_TestVector->GetElement(1) - expectedY < DIF_VAL); - CPPUNIT_ASSERT_MESSAGE("The vector value at index2 should be " + std::to_string(expectedZ) + " but was " + std::to_string(m_TestVector->GetElement(0)) - + " at r=" + std::to_string(r) + " phi=" + std::to_string(phi) + " theta=" + std::to_string(theta), - m_TestVector->GetElement(2) - expectedZ < DIF_VAL); - } - } - } - } - - void TestScaleVector() - { - double a = 1.0; - double b = 2.0; - double c = 3.0; - - for (double testFactor = -2.0; testFactor <= 2.0; testFactor += 0.3) - { - double potElement0Fctr; - double potElement1Fctr; - double potElement2Fctr; - - std::stringstream output; - - m_TestVector->SetElement(0, a); - m_TestVector->SetElement(1, b); - m_TestVector->SetElement(2, c); - - potElement0Fctr = (m_TestVector->GetElement(0)*testFactor)*(m_TestVector->GetElement(0)*testFactor); - potElement1Fctr = (m_TestVector->GetElement(1)*testFactor)*(m_TestVector->GetElement(1)*testFactor); - potElement2Fctr = (m_TestVector->GetElement(2)*testFactor)*(m_TestVector->GetElement(2)*testFactor); - - m_TestVector->Scale(testFactor); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector length should not be equal", - sqrt(potElement0Fctr + potElement1Fctr + potElement2Fctr), m_TestVector->GetNorm()); - - output << "The vector value at index0 should be"; - output << a*testFactor; - CPPUNIT_ASSERT_EQUAL_MESSAGE(output.str(), a*testFactor, m_TestVector->GetElement(0)); - output.flush(); - - output << "The vector value at index1 should be"; - output << b*testFactor; - CPPUNIT_ASSERT_EQUAL_MESSAGE(output.str(), b*testFactor, m_TestVector->GetElement(1)); - output.flush(); - - output << "The vector value at index2 should be"; - output << c*testFactor; - CPPUNIT_ASSERT_EQUAL_MESSAGE(output.str(), c*testFactor, m_TestVector->GetElement(2)); - output.flush(); - } - } - - void TestCloneVector() - { - int a = 1; - int b = 2; - int c = 3; - - m_TestVector->SetElement(0, a); - m_TestVector->SetElement(1, b); - m_TestVector->SetElement(2, c); - - m_TestReturnVector = m_TestVector->Clone(); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector length should be equal", (m_TestVector->GetNorm()), m_TestReturnVector->GetNorm()); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index0 should be equal", m_TestVector->GetElement(0), m_TestReturnVector->GetElement(0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index1 should be equal", m_TestVector->GetElement(1), m_TestReturnVector->GetElement(1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index2 should be equal", m_TestVector->GetElement(2), m_TestReturnVector->GetElement(2)); - - m_TestReturnVector->Rotate(itk::Math::pi / 4, itk::Math::pi / 4); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index0 should be not equal", true, m_TestVector->GetElement(0) != m_TestReturnVector->GetElement(0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index0 should be not equal", true, m_TestVector->GetElement(1) != m_TestReturnVector->GetElement(1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index0 should be not equal", true, m_TestVector->GetElement(2) != m_TestReturnVector->GetElement(2)); - - for (double testFactor = -2.0; testFactor <= 2.0; testFactor += 0.3) - { - m_TestReturnVector->Scale(testFactor); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index0 should be not equal", true, m_TestVector->GetElement(0) != m_TestReturnVector->GetElement(0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index0 should be not equal", true, m_TestVector->GetElement(1) != m_TestReturnVector->GetElement(1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("The vector value at index0 should be not equal", true, m_TestVector->GetElement(2) != m_TestReturnVector->GetElement(2)); - } - } - - void tearDown() override - { - m_TestVector = nullptr; - m_TestReturnVector = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVector) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselMeanderStrategyTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselMeanderStrategyTest.cpp deleted file mode 100644 index 717c60ede0..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselMeanderStrategyTest.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -#include "mitkPAInSilicoTissueVolume.h" -#include "mitkPATissueGenerator.h" -#include "mitkPAVesselMeanderStrategy.h" - -class mitkPhotoacousticVesselMeanderStrategyTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticVesselMeanderStrategyTestSuite); - MITK_TEST(TestCalculateNewPositionInStraightLine); - - CPPUNIT_TEST_SUITE_END(); - -private: - mitk::pa::VesselMeanderStrategy::Pointer m_TestStrategy; - mitk::pa::Vector::Pointer m_TestDirection; - -public: - - void setUp() override - { - m_TestStrategy = mitk::pa::VesselMeanderStrategy::New(); - m_TestDirection = mitk::pa::Vector::New(); - } - - void TestCalculateNewPositionInStraightLine() - { - int d = 3; - int e = 4; - int f = 5; - - for (int i = -2; i <= 2; i++) - { - if (i == 0) - { - i++; - } - - for (int j = -2; j <= 2; j++) - { - if (j == 0) - { - j++; - } - - m_TestDirection->SetElement(0, d*j); - m_TestDirection->SetElement(1, e*j); - m_TestDirection->SetElement(2, f*j); - - mitk::pa::Vector::Pointer directionBefore = m_TestDirection->Clone(); - m_TestStrategy->CalculateNewDirectionVectorInStraightLine(m_TestDirection, 0, nullptr); - CPPUNIT_ASSERT(mitk::pa::Equal(directionBefore, m_TestDirection, 1e-6, false)); - } - } - } - - void tearDown() override - { - m_TestStrategy = nullptr; - m_TestDirection = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVesselMeanderStrategy) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTest.cpp deleted file mode 100644 index ac144f5b57..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTest.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -#include "mitkPAInSilicoTissueVolume.h" -#include "mitkPAVector.h" -#include "mitkPAVessel.h" - -class mitkPhotoacousticVesselTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticVesselTestSuite); - MITK_TEST(testEmptyInitializationProperties); - MITK_TEST(testWalkInStraightLine); - MITK_TEST(testBifurcate); - CPPUNIT_TEST_SUITE_END(); - -private: - mitk::pa::Vessel::Pointer m_TestVessel; - mitk::pa::Vessel::CalculateNewVesselPositionCallback m_StraightLine; - mitk::pa::Vessel::CalculateNewVesselPositionCallback m_Diverging; - mitk::pa::InSilicoTissueVolume::Pointer m_TestInSilicoVolume; - mitk::pa::TissueGeneratorParameters::Pointer m_TestVolumeParameters; - -public: - - void setUp() override - { - auto params = mitk::pa::VesselProperties::New(); - m_TestVessel = mitk::pa::Vessel::New(params); - m_StraightLine = &mitk::pa::VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine; - m_Diverging = &mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector; - m_TestVolumeParameters = createTestVolumeParameters(); - auto rng = std::mt19937(); - m_TestInSilicoVolume = mitk::pa::InSilicoTissueVolume::New(m_TestVolumeParameters, &rng); - } - - mitk::pa::TissueGeneratorParameters::Pointer createTestVolumeParameters() - { - auto returnParameters = - mitk::pa::TissueGeneratorParameters::New(); - - returnParameters->SetXDim(10); - returnParameters->SetYDim(10); - returnParameters->SetZDim(10); - returnParameters->SetMinBackgroundAbsorption(0); - returnParameters->SetMaxBackgroundAbsorption(0); - returnParameters->SetBackgroundScattering(0); - returnParameters->SetBackgroundAnisotropy(0); - return returnParameters; - } - - void testEmptyInitializationProperties() - { - CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); - CPPUNIT_ASSERT(m_TestVessel->IsFinished() == true); - } - - void testWalkInStraightLine() - { - auto testPosition = mitk::pa::Vector::New(); - testPosition->SetElement(0, 0); - testPosition->SetElement(1, 4); - testPosition->SetElement(2, 4); - auto testDirection = mitk::pa::Vector::New(); - testDirection->SetElement(0, 1); - testDirection->SetElement(1, 0); - testDirection->SetElement(2, 0); - auto params = mitk::pa::VesselProperties::New(); - params->SetDoPartialVolume(false); - params->SetRadiusInVoxel(1); - params->SetBifurcationFrequency(100); - params->SetAbsorptionCoefficient(10); - params->SetScatteringCoefficient(10); - params->SetAnisotopyCoefficient(10); - params->SetPositionVector(testPosition); - params->SetDirectionVector(testDirection); - m_TestVessel = mitk::pa::Vessel::New(params); - - CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); - CPPUNIT_ASSERT(m_TestVessel->IsFinished() == false); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)) <= mitk::eps); - - m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 5, 4)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 6, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 6, 4)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 5)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 5)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 6)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 6)) <= mitk::eps); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)) <= mitk::eps); - - m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 5, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 5, 4)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 6, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 6, 4)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 5)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 5)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 6)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 6)) <= mitk::eps); - - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(1, 4, 4) - 10) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(2, 4, 4)) <= mitk::eps); - CPPUNIT_ASSERT_MESSAGE(std::to_string(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(3, 4, 4)), - std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(3, 4, 4)) <= mitk::eps); - } - - void testBifurcate() - { - auto testPosition = mitk::pa::Vector::New(); - testPosition->SetElement(0, 0); - testPosition->SetElement(1, 4); - testPosition->SetElement(2, 4); - auto testDirection = mitk::pa::Vector::New(); - testDirection->SetElement(0, 1); - testDirection->SetElement(1, 0); - testDirection->SetElement(2, 0); - auto params = mitk::pa::VesselProperties::New(); - params->SetRadiusInVoxel(1); - params->SetBifurcationFrequency(1); - params->SetAbsorptionCoefficient(10); - params->SetScatteringCoefficient(10); - params->SetAnisotopyCoefficient(10); - params->SetPositionVector(testPosition); - params->SetDirectionVector(testDirection); - m_TestVessel = mitk::pa::Vessel::New(params); - - CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); - CPPUNIT_ASSERT(m_TestVessel->IsFinished() == false); - - CPPUNIT_ASSERT(std::abs(m_TestInSilicoVolume->GetAbsorptionVolume()->GetData(0, 4, 4)) <= mitk::eps); - - m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); - m_TestVessel->ExpandVessel(m_TestInSilicoVolume, m_StraightLine, 0, nullptr); - - CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == true); - std::mt19937 rng; - auto bifurcationVessel = m_TestVessel->Bifurcate(&rng); - - CPPUNIT_ASSERT(m_TestVessel->CanBifurcate() == false); - CPPUNIT_ASSERT(bifurcationVessel->CanBifurcate() == false); - } - - void tearDown() override - { - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVessel) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTreeTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTreeTest.cpp deleted file mode 100644 index 058f6d1d05..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVesselTreeTest.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -#include "mitkPAVesselTree.h" -#include "mitkPAInSilicoTissueVolume.h" - -using namespace mitk::pa; - -class mitkPhotoacousticVesselTreeTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticVesselTreeTestSuite); - MITK_TEST(testVesselTreeInitialBehavior); - MITK_TEST(testCallStepMethod); - CPPUNIT_TEST_SUITE_END(); - -private: - -public: - - VesselTree::Pointer m_Tree; - VesselProperties::Pointer m_VesselProperties; - Vessel::CalculateNewVesselPositionCallback m_StraightLine; - InSilicoTissueVolume::Pointer m_TestInSilicoVolume; - - void setUp() override - { - m_VesselProperties = VesselProperties::New(); - m_Tree = VesselTree::New(m_VesselProperties); - m_StraightLine = &VesselMeanderStrategy::CalculateNewDirectionVectorInStraightLine; - auto rng = std::mt19937(); - m_TestInSilicoVolume = InSilicoTissueVolume::New(createTestVolumeParameters(), &rng); - } - - TissueGeneratorParameters::Pointer createTestVolumeParameters() - { - auto returnParameters = - TissueGeneratorParameters::New(); - - returnParameters->SetXDim(10); - returnParameters->SetYDim(10); - returnParameters->SetZDim(10); - returnParameters->SetMinBackgroundAbsorption(0); - returnParameters->SetMaxBackgroundAbsorption(0); - returnParameters->SetBackgroundScattering(0); - returnParameters->SetBackgroundAnisotropy(0); - return returnParameters; - } - - void testVesselTreeInitialBehavior() - { - CPPUNIT_ASSERT(m_Tree->IsFinished() == true); - } - - void testCallStepMethod() - { - //really bad test atm.. The only thing that is tested is that the method can be called without a crash. - //But hey - it is something :P - m_VesselProperties->SetRadiusInVoxel(2); - std::mt19937 rng; - rng.seed(1); - m_Tree = VesselTree::New(m_VesselProperties); - m_Tree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); - - rng.seed(1); - auto secondTree = VesselTree::New(m_VesselProperties); - secondTree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); - - CPPUNIT_ASSERT(Equal(m_Tree, secondTree, 1e-6, true)); - - secondTree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); - - CPPUNIT_ASSERT(!Equal(m_Tree, secondTree, 1e-6, true)); - - int i = 0; - for (; i < 1000; i++) - { - secondTree->Step(m_TestInSilicoVolume, m_StraightLine, 0, &rng); - if (secondTree->IsFinished()) - break; - } - - CPPUNIT_ASSERT(i < 999); - } - - void tearDown() override - { - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVesselTree) diff --git a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVolumeTest.cpp b/Modules/PhotoacousticsLib/test/mitkPhotoacousticVolumeTest.cpp deleted file mode 100644 index e92fdfc1f3..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPhotoacousticVolumeTest.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include - -#include - -#include "mitkPAInSilicoTissueVolume.h" -#include "mitkPATissueGeneratorParameters.h" - -class mitkPhotoacousticVolumeTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPhotoacousticVolumeTestSuite); - MITK_TEST(TestUniformDistributionIsUniform); - MITK_TEST(TestInitializedTissueContainsOnlyZeros); - MITK_TEST(TestConvertedMitkImageContainsOnlyZerosOrAir); - MITK_TEST(TestTissueVolumeContainsCorrectAbsorptionNumber); - MITK_TEST(TestTissueVolumeContainsCorrectScatteringNumber); - MITK_TEST(TestTissueVolumeContainsCorrectAnisotropyNumber); - MITK_TEST(testSecondConstructor); - MITK_TEST(testCompleteAirVoxelInclusion); - MITK_TEST(testHalfAirVoxelInclusion); - MITK_TEST(testCompleteAirAndSkinVoxelInclusion); - MITK_TEST(testRandomizeCoefficients); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::pa::InSilicoTissueVolume::Pointer m_PhotoacousticVolume; - mitk::pa::TissueGeneratorParameters::Pointer m_TissueGeneratorParameters; - -public: - - void setUp() override - { - m_TissueGeneratorParameters = mitk::pa::TissueGeneratorParameters::New(); - auto rng = std::mt19937(); - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(m_TissueGeneratorParameters, &rng); - } - - void TestUniformDistributionIsUniform() - { - - int dims = 30; - m_TissueGeneratorParameters->SetXDim(dims); - m_TissueGeneratorParameters->SetYDim(dims); - m_TissueGeneratorParameters->SetZDim(dims); - m_TissueGeneratorParameters->SetAirThicknessInMillimeters(0); - - m_TissueGeneratorParameters->SetMinBackgroundAbsorption(0.001); - m_TissueGeneratorParameters->SetMaxBackgroundAbsorption(0.2); - - auto rng = std::mt19937(); - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(m_TissueGeneratorParameters, &rng); - - for (int x = 0; x < dims; x++) - { - for (int y = 0; y < dims; y++) - { - for (int z = 0; z < dims; z++) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Every absorption should be in bounds.", - m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(x, y, z) >= 0.001 && - m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(x, y, z) <= 0.2, true); - } - } - } - - } - - void TestInitializedTissueContainsOnlyZeros() - { - int dims = 30; - m_TissueGeneratorParameters->SetXDim(dims); - m_TissueGeneratorParameters->SetYDim(dims); - m_TissueGeneratorParameters->SetZDim(dims); - m_TissueGeneratorParameters->SetAirThicknessInMillimeters(0); - m_TissueGeneratorParameters->SetMinBackgroundAbsorption(0); - m_TissueGeneratorParameters->SetMaxBackgroundAbsorption(0); - auto rng = std::mt19937(); - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(m_TissueGeneratorParameters, &rng); - - for (int x = 0; x < dims; x++) - { - for (int y = 0; y < dims; y++) - { - for (int z = 0; z < dims; z++) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Every field should be initialized with 0.", std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(x, y, z)) < mitk::eps, true); - } - } - } - } - - void TestConvertedMitkImageContainsOnlyZerosOrAir() - { - int dims = 30; - m_TissueGeneratorParameters->SetXDim(dims); - m_TissueGeneratorParameters->SetYDim(dims); - m_TissueGeneratorParameters->SetZDim(dims); - auto rng = std::mt19937(); - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(m_TissueGeneratorParameters, &rng); - - mitk::Image::Pointer testImage = m_PhotoacousticVolume->ConvertToMitkImage(); - - mitk::ImageReadAccessor imgMemAcc(testImage); - auto* imagePointer = (double*)imgMemAcc.GetData(); - - for (int index = 0; index < dims*dims*dims; index++, imagePointer++) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Every voxel in image should be 0.1 or 0.0001.", true, std::abs(*imagePointer - 0.1) <= mitk::eps || std::abs(*imagePointer - 0.0001) <= mitk::eps); - } - } - - void TestTissueVolumeContainsCorrectAbsorptionNumber() - { - int dims = 2; - m_TissueGeneratorParameters->SetXDim(dims); - m_TissueGeneratorParameters->SetYDim(dims); - m_TissueGeneratorParameters->SetZDim(dims); - auto rng = std::mt19937(); - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(m_TissueGeneratorParameters, &rng); - - m_PhotoacousticVolume->SetVolumeValues(0, 0, 0, 0, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(0, 0, 1, 1, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(0, 1, 0, 2, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(0, 1, 1, 3, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 0, 0, 4, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 0, 1, 5, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 1, 0, 6, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 1, 1, 7, 0, 0); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 0.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 0, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 1.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 0, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 2.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 1, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 3.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 1, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 4.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 0, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 5.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 0, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 6.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 7.0, m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 1)); - } - - void TestTissueVolumeContainsCorrectScatteringNumber() - { - int dims = 2; - m_TissueGeneratorParameters->SetXDim(dims); - m_TissueGeneratorParameters->SetYDim(dims); - m_TissueGeneratorParameters->SetZDim(dims); - auto rng = std::mt19937(); - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(m_TissueGeneratorParameters, &rng); - - m_PhotoacousticVolume->SetVolumeValues(0, 0, 0, 0, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(0, 0, 1, 0, 1, 0); - m_PhotoacousticVolume->SetVolumeValues(0, 1, 0, 0, 2, 0); - m_PhotoacousticVolume->SetVolumeValues(0, 1, 1, 0, 3, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 0, 0, 0, 4, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 0, 1, 0, 5, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 1, 0, 0, 6, 0); - m_PhotoacousticVolume->SetVolumeValues(1, 1, 1, 0, 7, 0); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 0.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 0, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 1.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 0, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 2.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 1, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 3.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 1, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 4.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 0, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 5.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 0, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 6.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 7.0, m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 1)); - } - - void TestTissueVolumeContainsCorrectAnisotropyNumber() - { - int dims = 2; - m_TissueGeneratorParameters->SetXDim(dims); - m_TissueGeneratorParameters->SetYDim(dims); - m_TissueGeneratorParameters->SetZDim(dims); - auto rng = std::mt19937(); - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(m_TissueGeneratorParameters, &rng); - - m_PhotoacousticVolume->SetVolumeValues(0, 0, 0, 0, 0, 0); - m_PhotoacousticVolume->SetVolumeValues(0, 0, 1, 0, 0, 1); - m_PhotoacousticVolume->SetVolumeValues(0, 1, 0, 0, 0, 2); - m_PhotoacousticVolume->SetVolumeValues(0, 1, 1, 0, 0, 3); - m_PhotoacousticVolume->SetVolumeValues(1, 0, 0, 0, 0, 4); - m_PhotoacousticVolume->SetVolumeValues(1, 0, 1, 0, 0, 5); - m_PhotoacousticVolume->SetVolumeValues(1, 1, 0, 0, 0, 6); - m_PhotoacousticVolume->SetVolumeValues(1, 1, 1, 0, 0, 7); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 0.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 0, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 1.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 0, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 2.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 1, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 3.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 1, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 4.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 0, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 5.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 0, 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 6.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should be correct value", 7.0, m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 1)); - } - - mitk::pa::Volume::Pointer createTestVolume(double value) - { - auto* data = new double[27]; - for (int i = 0; i < 27; ++i) - data[i] = value; - return mitk::pa::Volume::New(data, 3, 3, 3, 1); - } - - void assertEqual(mitk::pa::Volume::Pointer first, mitk::pa::Volume::Pointer second) - { - CPPUNIT_ASSERT(first->GetXDim() == second->GetXDim()); - CPPUNIT_ASSERT(first->GetYDim() == second->GetYDim()); - CPPUNIT_ASSERT(first->GetZDim() == second->GetZDim()); - for (unsigned int x = 0; x < first->GetXDim(); ++x) - for (unsigned int y = 0; y < first->GetYDim(); ++y) - for (unsigned int z = 0; z < first->GetZDim(); ++z) - CPPUNIT_ASSERT(std::abs(first->GetData(x, y, z) - second->GetData(x, y, z)) < mitk::eps); - } - - void testSecondConstructor() - { - mitk::pa::Volume::Pointer absorption = createTestVolume(1); - mitk::pa::Volume::Pointer scattering = createTestVolume(2); - mitk::pa::Volume::Pointer anisotropy = createTestVolume(3); - mitk::pa::Volume::Pointer segmentation = createTestVolume(4); - mitk::PropertyList::Pointer properties = mitk::PropertyList::New(); - - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(absorption, - scattering, anisotropy, segmentation, m_TissueGeneratorParameters, properties); - - assertEqual(m_PhotoacousticVolume->GetAbsorptionVolume(), absorption); - assertEqual(m_PhotoacousticVolume->GetScatteringVolume(), scattering); - assertEqual(m_PhotoacousticVolume->GetAnisotropyVolume(), anisotropy); - assertEqual(m_PhotoacousticVolume->GetSegmentationVolume(), segmentation); - } - - void testCompleteAirVoxelInclusion() - { - mitk::pa::Volume::Pointer absorption = createTestVolume(1); - mitk::pa::Volume::Pointer scattering = createTestVolume(2); - mitk::pa::Volume::Pointer anisotropy = createTestVolume(3); - mitk::pa::Volume::Pointer segmentation = createTestVolume(4); - mitk::PropertyList::Pointer properties = mitk::PropertyList::New(); - m_TissueGeneratorParameters->SetXDim(3); - m_TissueGeneratorParameters->SetYDim(3); - m_TissueGeneratorParameters->SetZDim(3); - m_TissueGeneratorParameters->SetAirThicknessInMillimeters(10); - m_TissueGeneratorParameters->SetSkinThicknessInMillimeters(0); - m_TissueGeneratorParameters->SetAirAbsorption(2); - m_TissueGeneratorParameters->SetAirScattering(4); - m_TissueGeneratorParameters->SetAirAnisotropy(6); - - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(absorption, - scattering, anisotropy, segmentation, m_TissueGeneratorParameters, properties); - - m_PhotoacousticVolume->FinalizeVolume(); - - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 0, 0) - 2) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 1) - 1) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 2) - 1) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 0, 0) - 4) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 1) - 2) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 2) - 2) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 0, 0) - 6) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 1) - 3) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 2) - 3) < mitk::eps); - } - - void testRandomizeCoefficients() - { - mitk::pa::Volume::Pointer absorption = createTestVolume(1); - mitk::pa::Volume::Pointer scattering = createTestVolume(1); - mitk::pa::Volume::Pointer anisotropy = createTestVolume(1); - mitk::pa::Volume::Pointer segmentation = createTestVolume(4); - mitk::PropertyList::Pointer properties = mitk::PropertyList::New(); - m_TissueGeneratorParameters->SetXDim(3); - m_TissueGeneratorParameters->SetYDim(3); - m_TissueGeneratorParameters->SetZDim(3); - m_TissueGeneratorParameters->SetRandomizePhysicalProperties(true); - m_TissueGeneratorParameters->SetRandomizePhysicalPropertiesPercentage(1); - m_TissueGeneratorParameters->SetRngSeed(17); - m_TissueGeneratorParameters->SetUseRngSeed(true); - - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(absorption, - scattering, anisotropy, segmentation, m_TissueGeneratorParameters, properties); - - m_PhotoacousticVolume->FinalizeVolume(); - - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 0, 0) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 1) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 2) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 0, 0) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 1) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 2) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 0, 0) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 1) - 1) < 0.1); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 2) - 1) < 0.1); - } - - void testCompleteAirAndSkinVoxelInclusion() - { - mitk::pa::Volume::Pointer absorption = createTestVolume(1); - mitk::pa::Volume::Pointer scattering = createTestVolume(2); - mitk::pa::Volume::Pointer anisotropy = createTestVolume(3); - mitk::pa::Volume::Pointer segmentation = createTestVolume(4); - mitk::PropertyList::Pointer properties = mitk::PropertyList::New(); - m_TissueGeneratorParameters->SetXDim(3); - m_TissueGeneratorParameters->SetYDim(3); - m_TissueGeneratorParameters->SetZDim(3); - m_TissueGeneratorParameters->SetAirThicknessInMillimeters(10); - m_TissueGeneratorParameters->SetSkinThicknessInMillimeters(10); - m_TissueGeneratorParameters->SetAirAbsorption(2); - m_TissueGeneratorParameters->SetAirScattering(4); - m_TissueGeneratorParameters->SetAirAnisotropy(6); - m_TissueGeneratorParameters->SetSkinAbsorption(4); - m_TissueGeneratorParameters->SetSkinScattering(8); - m_TissueGeneratorParameters->SetSkinAnisotropy(12); - - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(absorption, - scattering, anisotropy, segmentation, m_TissueGeneratorParameters, properties); - - m_PhotoacousticVolume->FinalizeVolume(); - - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 0, 0) - 2) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 1) - 4) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 2) - 1) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 0, 0) - 4) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 1) - 8) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 2) - 2) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 0, 0) - 6) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 1) - 12) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 2) - 3) < mitk::eps); - } - - void testHalfAirVoxelInclusion() - { - mitk::pa::Volume::Pointer absorption = createTestVolume(1); - mitk::pa::Volume::Pointer scattering = createTestVolume(2); - mitk::pa::Volume::Pointer anisotropy = createTestVolume(3); - mitk::pa::Volume::Pointer segmentation = createTestVolume(4); - mitk::PropertyList::Pointer properties = mitk::PropertyList::New(); - m_TissueGeneratorParameters->SetXDim(3); - m_TissueGeneratorParameters->SetYDim(3); - m_TissueGeneratorParameters->SetZDim(3); - m_TissueGeneratorParameters->SetAirThicknessInMillimeters(15); - m_TissueGeneratorParameters->SetSkinThicknessInMillimeters(0); - m_TissueGeneratorParameters->SetAirAbsorption(2); - m_TissueGeneratorParameters->SetAirScattering(4); - m_TissueGeneratorParameters->SetAirAnisotropy(6); - - m_PhotoacousticVolume = mitk::pa::InSilicoTissueVolume::New(absorption, - scattering, anisotropy, segmentation, m_TissueGeneratorParameters, properties); - - m_PhotoacousticVolume->FinalizeVolume(); - - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(0, 0, 0) - 2) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 1) - 1.5) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAbsorptionVolume()->GetData(1, 1, 2) - 1) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(0, 0, 0) - 4) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 1) - 3) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetScatteringVolume()->GetData(1, 1, 2) - 2) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(0, 0, 0) - 6) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 1) - 4.5) < mitk::eps); - CPPUNIT_ASSERT(std::abs(m_PhotoacousticVolume->GetAnisotropyVolume()->GetData(1, 1, 2) - 3) < mitk::eps); - } - - void tearDown() override - { - m_TissueGeneratorParameters = nullptr; - m_PhotoacousticVolume = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPhotoacousticVolume) diff --git a/Modules/PhotoacousticsLib/test/mitkPropertyCalculatorTest.cpp b/Modules/PhotoacousticsLib/test/mitkPropertyCalculatorTest.cpp deleted file mode 100644 index 1b780a7fa6..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkPropertyCalculatorTest.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include -#include - -#include - -class mitkPropertyCalculatorTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkPropertyCalculatorTestSuite); - MITK_TEST(testOutputIsNotEmpty); - CPPUNIT_TEST_SUITE_END(); - -private: - mitk::pa::PropertyCalculator::Pointer m_PropertyCalculator; - -public: - - void setUp() override - { - m_PropertyCalculator = mitk::pa::PropertyCalculator::New(); - } - - void assertProperties(mitk::pa::PropertyCalculator::Properties properties, - std::string type, int wavelength, int oxygenation) - { - CPPUNIT_ASSERT_MESSAGE("anisotropy " + std::to_string(properties.g) + " not bigger than 0 at type " - + type + " wv: " + std::to_string(wavelength) + " ox: " + std::to_string(oxygenation), properties.g > 0); - CPPUNIT_ASSERT_MESSAGE("absorption " + std::to_string(properties.mua) + " not bigger than 0 at type " - + type + " wv: " + std::to_string(wavelength) + " ox: " + std::to_string(oxygenation), properties.mua > 0); - CPPUNIT_ASSERT_MESSAGE("scattering " + std::to_string(properties.mus) + " not bigger than 0 at type " - + type + " wv: " + std::to_string(wavelength) + " ox: " + std::to_string(oxygenation), properties.mus > 0); - } - - void testOutputIsNotEmpty() - { - for (double oxygenation = 0; oxygenation <= 1; oxygenation += 0.05) - { - for (int wavelength = 700; wavelength <= 900; wavelength += 5) - { - auto properties = m_PropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::AIR, wavelength, oxygenation); - assertProperties(properties, "AIR", wavelength, oxygenation); - properties = m_PropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::BLOOD, wavelength, oxygenation); - assertProperties(properties, "BLOOD", wavelength, oxygenation); - properties = m_PropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::EPIDERMIS, wavelength, oxygenation); - assertProperties(properties, "EPIDERMIS", wavelength, oxygenation); - properties = m_PropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::FAT, wavelength, oxygenation); - assertProperties(properties, "FAT", wavelength, oxygenation); - properties = m_PropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::STANDARD_TISSUE, wavelength, oxygenation); - assertProperties(properties, "STANDARD_TISSUE", wavelength, oxygenation); - } - } - } - - void tearDown() override - { - m_PropertyCalculator = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkPropertyCalculator) diff --git a/Modules/PhotoacousticsLib/test/mitkSimulationBatchGeneratorTest.cpp b/Modules/PhotoacousticsLib/test/mitkSimulationBatchGeneratorTest.cpp deleted file mode 100644 index 7c8f44b1de..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkSimulationBatchGeneratorTest.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include -#include - -#include -#include -#include - -class mitkSimulationBatchGeneratorTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkSimulationBatchGeneratorTestSuite); - MITK_TEST(testGenerateBatchFileString); - MITK_TEST(testGenerateBatchFileAndSaveFile); - CPPUNIT_TEST_SUITE_END(); - -private: - - const std::string TEST_FOLDER_PATH = "testFiles/"; - mitk::pa::SimulationBatchGeneratorParameters::Pointer m_Parameters; - mitk::pa::Volume::Pointer m_Test3DVolume; - -public: - - void setUp() override - { - m_Parameters = mitk::pa::SimulationBatchGeneratorParameters::New(); - m_Parameters->SetBinaryPath("binary"); - m_Parameters->SetNrrdFilePath(TEST_FOLDER_PATH); - m_Parameters->SetNumberOfPhotons(100); - m_Parameters->SetTissueName("tissueName"); - m_Parameters->SetVolumeIndex(0); - m_Parameters->SetYOffsetLowerThresholdInCentimeters(-1); - m_Parameters->SetYOffsetUpperThresholdInCentimeters(1); - m_Parameters->SetYOffsetStepInCentimeters(0.5); - - m_Test3DVolume = createTest3DVolume(5); - itk::FileTools::CreateDirectory(TEST_FOLDER_PATH); - CPPUNIT_ASSERT(itksys::SystemTools::FileIsDirectory(TEST_FOLDER_PATH)); - } - - mitk::pa::Volume::Pointer createTest3DVolume(double value) - { - unsigned int xDim = 10; - unsigned int yDim = 10; - unsigned int zDim = 10; - unsigned int length = xDim * yDim * zDim; - auto* data = new double[length]; - for (unsigned int i = 0; i < length; i++) - data[i] = value; - - return mitk::pa::Volume::New(data, xDim, yDim, zDim, 1); - } - - void testGenerateBatchFileString() - { - std::string batchGenerationString = mitk::pa::SimulationBatchGenerator::CreateBatchSimulationString(m_Parameters); - CPPUNIT_ASSERT(!batchGenerationString.empty()); - } - - void testGenerateBatchFileAndSaveFile() - { - mitk::pa::SimulationBatchGenerator::WriteBatchFileAndSaveTissueVolume(m_Parameters, m_Test3DVolume->AsMitkImage()); - CPPUNIT_ASSERT(itksys::SystemTools::FileExists(TEST_FOLDER_PATH + m_Parameters->GetTissueName() + "000.nrrd")); - CPPUNIT_ASSERT(itksys::SystemTools::FileExists(TEST_FOLDER_PATH + "simulate_all.sh") || itksys::SystemTools::FileExists(TEST_FOLDER_PATH + "simulate_all.bat")); - CPPUNIT_ASSERT(itksys::SystemTools::FileExists(TEST_FOLDER_PATH + m_Parameters->GetTissueName() + "000") - && itksys::SystemTools::FileIsDirectory(TEST_FOLDER_PATH + m_Parameters->GetTissueName() + "000")); - } - - void tearDown() override - { - m_Parameters = nullptr; - CPPUNIT_ASSERT_MESSAGE("Resource leak of test files onto hard drive..", itksys::SystemTools::RemoveADirectory(TEST_FOLDER_PATH) == true); - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkSimulationBatchGenerator) diff --git a/Modules/PhotoacousticsLib/test/mitkSlicedVolumeGeneratorTest.cpp b/Modules/PhotoacousticsLib/test/mitkSlicedVolumeGeneratorTest.cpp deleted file mode 100644 index 85f28da73f..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkSlicedVolumeGeneratorTest.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include -#include - -#include - -class mitkSlicedVolumeGeneratorTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkSlicedVolumeGeneratorTestSuite); - MITK_TEST(testConstructorDestructor); - MITK_TEST(testGetSlicedFluenceVolume); - MITK_TEST(testGetSlicedFluenceVolumeInverse); - MITK_TEST(testGetSlicedFluenceVolumeWithPrecorrection); - MITK_TEST(testGetSlicedFluenceVolumeWithPrecorrectionInverse); - MITK_TEST(testGetSlicedSignalVolume); - MITK_TEST(testGetSlicedAbsorptionVolume); - CPPUNIT_TEST_SUITE_END(); - -private: - - mitk::pa::ComposedVolume::Pointer m_ComposedVolume; - mitk::pa::TissueGeneratorParameters::Pointer m_DefaultParameters; - mitk::pa::InSilicoTissueVolume::Pointer m_InSilicoTissueVolume; - mitk::pa::SlicedVolumeGenerator::Pointer m_SlicedVolumeGenerator; - mitk::pa::Volume::Pointer m_PrecorrectionVolume; - -public: - - void setUp() override - { - m_SlicedVolumeGenerator = nullptr; - m_DefaultParameters = mitk::pa::TissueGeneratorParameters::New(); - m_DefaultParameters->SetXDim(3); - m_DefaultParameters->SetYDim(3); - m_DefaultParameters->SetZDim(3); - auto rng = std::mt19937(); - m_InSilicoTissueVolume = mitk::pa::InSilicoTissueVolume::New(m_DefaultParameters, &rng); - m_ComposedVolume = mitk::pa::ComposedVolume::New(m_InSilicoTissueVolume); - m_ComposedVolume->AddSlice(CreateValidationPair(-1, 1)); - m_ComposedVolume->AddSlice(CreateValidationPair(0, 3)); - m_ComposedVolume->AddSlice(CreateValidationPair(1, 6)); - m_PrecorrectionVolume = CreatePrecorrectionVolume(); - } - - mitk::pa::Volume::Pointer CreatePrecorrectionVolume() - { - auto* data = new double[27]; - for (int i = 0; i < 27; ++i) - data[i] = 0.5; - return mitk::pa::Volume::New(data, 3, 3, 3, 1); - } - - void FillYSliceWith(mitk::pa::Volume::Pointer fluenceVolume, double ySlice, double value) - { - for (unsigned int x = 0; x < fluenceVolume->GetXDim(); ++x) - for (unsigned int z = 0; z < fluenceVolume->GetZDim(); ++z) - { - fluenceVolume->SetData(value, x, ySlice, z); - } - } - - mitk::pa::FluenceYOffsetPair::Pointer CreateValidationPair(double yOffset, int start) - { - auto* data = new double[27]; - mitk::pa::Volume::Pointer fluenceVolume = mitk::pa::Volume::New(data, 3, 3, 3, 1); - - FillYSliceWith(fluenceVolume, 0, start + 0); - FillYSliceWith(fluenceVolume, 1, start + 1); - FillYSliceWith(fluenceVolume, 2, start + 2); - - return mitk::pa::FluenceYOffsetPair::New(fluenceVolume, yOffset); - } - - void AssertYSliceValue(mitk::pa::Volume::Pointer fluenceVolume, double ySlice, double value) - { - for (unsigned int x = 0; x < fluenceVolume->GetXDim(); ++x) - for (unsigned int z = 0; z < fluenceVolume->GetZDim(); ++z) - { - std::string msg = "Expected: " + std::to_string(value) + " actual: " + std::to_string(fluenceVolume->GetData(x, ySlice, z)); - CPPUNIT_ASSERT_MESSAGE(msg, std::abs(fluenceVolume->GetData(x, ySlice, z) - value) < mitk::eps); - } - } - - void testConstructorDestructor() - { - m_SlicedVolumeGenerator = mitk::pa::SlicedVolumeGenerator::New(0, false, nullptr, false); - CPPUNIT_ASSERT(m_SlicedVolumeGenerator.IsNotNull()); - } - - void testGetSlicedFluenceVolume() - { - m_SlicedVolumeGenerator = mitk::pa::SlicedVolumeGenerator::New(1, false, nullptr, false); - mitk::pa::Volume::Pointer slicedFluence = - m_SlicedVolumeGenerator->GetSlicedFluenceImageFromComposedVolume(m_ComposedVolume); - CPPUNIT_ASSERT(slicedFluence->GetXDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetYDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetZDim() == 3); - AssertYSliceValue(slicedFluence, 0, 1); - AssertYSliceValue(slicedFluence, 1, 4); - AssertYSliceValue(slicedFluence, 2, 8); - } - - void testGetSlicedFluenceVolumeInverse() - { - m_SlicedVolumeGenerator = mitk::pa::SlicedVolumeGenerator::New(1, false, nullptr, true); - mitk::pa::Volume::Pointer slicedFluence = - m_SlicedVolumeGenerator->GetSlicedFluenceImageFromComposedVolume(m_ComposedVolume); - CPPUNIT_ASSERT(slicedFluence->GetXDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetYDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetZDim() == 3); - AssertYSliceValue(slicedFluence, 0, 1); - AssertYSliceValue(slicedFluence, 1, 1.0 / 4.0); - AssertYSliceValue(slicedFluence, 2, 1.0 / 8.0); - } - - void testGetSlicedFluenceVolumeWithPrecorrection() - { - m_SlicedVolumeGenerator = mitk::pa::SlicedVolumeGenerator::New(1, true, m_PrecorrectionVolume, false); - mitk::pa::Volume::Pointer slicedFluence = - m_SlicedVolumeGenerator->GetSlicedFluenceImageFromComposedVolume(m_ComposedVolume); - CPPUNIT_ASSERT(slicedFluence->GetXDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetYDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetZDim() == 3); - AssertYSliceValue(slicedFluence, 0, 2); - AssertYSliceValue(slicedFluence, 1, 8); - AssertYSliceValue(slicedFluence, 2, 16); - } - - void testGetSlicedFluenceVolumeWithPrecorrectionInverse() - { - m_SlicedVolumeGenerator = mitk::pa::SlicedVolumeGenerator::New(1, true, m_PrecorrectionVolume, true); - mitk::pa::Volume::Pointer slicedFluence = - m_SlicedVolumeGenerator->GetSlicedFluenceImageFromComposedVolume(m_ComposedVolume); - CPPUNIT_ASSERT(slicedFluence->GetXDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetYDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetZDim() == 3); - AssertYSliceValue(slicedFluence, 0, 1.0 / 2); - AssertYSliceValue(slicedFluence, 1, 1.0 / 8); - AssertYSliceValue(slicedFluence, 2, 1.0 / 16); - } - - void testGetSlicedSignalVolume() - { - m_SlicedVolumeGenerator = mitk::pa::SlicedVolumeGenerator::New(1, false, nullptr, false); - mitk::pa::Volume::Pointer slicedFluence = - m_SlicedVolumeGenerator->GetSlicedSignalImageFromComposedVolume(m_ComposedVolume); - CPPUNIT_ASSERT(slicedFluence->GetXDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetYDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetZDim() == 3); - AssertYSliceValue(slicedFluence, 0, 1 * m_DefaultParameters->GetMinBackgroundAbsorption()); - AssertYSliceValue(slicedFluence, 1, 4 * m_DefaultParameters->GetMinBackgroundAbsorption()); - AssertYSliceValue(slicedFluence, 2, 8 * m_DefaultParameters->GetMinBackgroundAbsorption()); - } - - void testGetSlicedAbsorptionVolume() - { - m_SlicedVolumeGenerator = mitk::pa::SlicedVolumeGenerator::New(1, false, nullptr, false); - mitk::pa::Volume::Pointer slicedFluence = - m_SlicedVolumeGenerator->GetSlicedGroundTruthImageFromComposedVolume(m_ComposedVolume); - CPPUNIT_ASSERT(slicedFluence->GetXDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetYDim() == 3); - CPPUNIT_ASSERT(slicedFluence->GetZDim() == 3); - AssertYSliceValue(slicedFluence, 0, m_DefaultParameters->GetMinBackgroundAbsorption()); - AssertYSliceValue(slicedFluence, 1, m_DefaultParameters->GetMinBackgroundAbsorption()); - AssertYSliceValue(slicedFluence, 2, m_DefaultParameters->GetMinBackgroundAbsorption()); - } - - void tearDown() override - { - m_SlicedVolumeGenerator = nullptr; - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkSlicedVolumeGenerator) diff --git a/Modules/PhotoacousticsLib/test/mitkSpectralUnmixingTest.cpp b/Modules/PhotoacousticsLib/test/mitkSpectralUnmixingTest.cpp deleted file mode 100644 index fc449d4b35..0000000000 --- a/Modules/PhotoacousticsLib/test/mitkSpectralUnmixingTest.cpp +++ /dev/null @@ -1,680 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#include -#include - -#include -#include -#include -#include -#include -#include - -class mitkSpectralUnmixingTestSuite : public mitk::TestFixture -{ - CPPUNIT_TEST_SUITE(mitkSpectralUnmixingTestSuite); - MITK_TEST(testEigenSUAlgorithm); - MITK_TEST(testVigraSUAlgorithm); - //MITK_TEST(testSimplexSUAlgorithm); - MITK_TEST(testSO2); - MITK_TEST(testExceptionSO2); - MITK_TEST(testWavelengthExceptions); - MITK_TEST(testNoChromophoresSelected); - MITK_TEST(testInputImage); - MITK_TEST(testAddOutput); - MITK_TEST(testWeightsError); - MITK_TEST(testOutputs); - CPPUNIT_TEST_SUITE_END(); - -private: - mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter; - mitk::Image::Pointer inputImage; - std::vector m_inputWavelengths; - std::vector m_inputWeights; - std::vector m_CorrectResult; - float threshold; - -public: - - void setUp() override - { - //Set empty input image: - inputImage = mitk::Image::New(); - mitk::PixelType pixelType = mitk::MakeScalarPixelType(); - const int NUMBER_OF_SPATIAL_DIMENSIONS = 3; - auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS]; - - dimensions[0] = 1; - dimensions[1] = 1; - dimensions[2] = 5; - - inputImage->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions); - - //Set wavelengths for unmixing: - m_inputWavelengths.push_back(750); - m_inputWavelengths.push_back(800); - - m_inputWeights.push_back(50); - m_inputWeights.push_back(100); - - //Set fraction of Hb and HbO2 to unmix: - float fracHb = 100; - float fracHbO2 = 300; - m_CorrectResult.push_back(fracHbO2); - m_CorrectResult.push_back(fracHb); - m_CorrectResult.push_back(fracHbO2 + 10); - m_CorrectResult.push_back(fracHb - 10); - threshold = 0.01; - - //Multiply values of wavelengths (750,800,850 nm) with fractions to get pixel values: - float px1 = fracHb * 7.52 + fracHbO2 * 2.77; - float px2 = fracHb * 4.08 + fracHbO2 * 4.37; - float px3 = (fracHb - 10) * 7.52 + (fracHbO2 + 10) * 2.77; - float px4 = (fracHb - 10) * 4.08 + (fracHbO2 + 10) * 4.37; - - float* data = new float[6]; - data[0] = px1; - data[1] = px2; - data[2] = px3; - data[3] = px4; - data[5] = 0; - - inputImage->SetImportVolume(data, mitk::Image::ImportMemoryManagementType::CopyMemory); - delete[] data; - } - - // Tests implemented EIGEN algortihms with correct inputs - void testEigenSUAlgorithm() - { - MITK_INFO << "START FILTER TEST ... "; - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - //Set Chromophores to filter - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - ofstream myfile; - myfile.open("EigenTestResult.txt"); - - std::vector m_Eigen = { - mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR, /* mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::LDLT, - mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::LLT,*/ mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::COLPIVHOUSEHOLDERQR, - mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::JACOBISVD, mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVLU, - mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVHOUSEHOLDERQR}; - - for (unsigned int Algorithmidx = 0; Algorithmidx < m_Eigen.size();++Algorithmidx) - { - m_SpectralUnmixingFilter->SetAlgorithm(m_Eigen[Algorithmidx]); - - m_SpectralUnmixingFilter->Update(); - - - /*For printed pixel values and results look at: [...]\mitk-superbuild\MITK-build\Modules\PhotoacousticsLib\test\*/ - - for (int i = 0; i < 2; ++i) - { - mitk::Image::Pointer output = m_SpectralUnmixingFilter->GetOutput(i); - mitk::ImageReadAccessor readAccess(output); - const float* inputDataArray = ((const float*)readAccess.GetData()); - auto pixel = inputDataArray[0]; - auto pixel2 = inputDataArray[1]; - - myfile << "Algorithmidx: " << Algorithmidx << "\n Output " << i << ": " << "\n" << inputDataArray[0] << "\n" << inputDataArray[1] << "\n"; - myfile << "Correct Result: " << "\n" << m_CorrectResult[i] << "\n" << m_CorrectResult[i + 2] << "\n"; - - CPPUNIT_ASSERT(std::abs(pixel - m_CorrectResult[i]) < threshold); - CPPUNIT_ASSERT(std::abs(pixel2 - m_CorrectResult[i + 2]) < threshold); - } - } - myfile.close(); - MITK_INFO << "EIGEN FILTER TEST SUCCESFULL :)"; - } - - // Tests implemented VIGRA algortihms with correct inputs - void testVigraSUAlgorithm() - { - MITK_INFO << "START FILTER TEST ... "; - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - double Weight = m_inputWeights[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - m_SpectralUnmixingFilter->AddWeight(Weight); - } - - //Set Chromophores to filter - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - - std::vector Vigra = { - mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LARS, mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::GOLDFARB, - mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::WEIGHTED, mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LS/*, - mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::vigratest*/}; - - ofstream myfile; - myfile.open("VigraTestResult.txt"); - - for (unsigned int Algorithmidx = 0; Algorithmidx < Vigra.size();++Algorithmidx) - { - m_SpectralUnmixingFilter->SetAlgorithm(Vigra[0]); - - m_SpectralUnmixingFilter->Update(); - - - /*For printed pixel values and results look at: [...]\mitk-superbuild\MITK-build\Modules\PhotoacousticsLib\test\*/ - - for (int i = 0; i < 2; ++i) - { - mitk::Image::Pointer output = m_SpectralUnmixingFilter->GetOutput(i); - mitk::ImageReadAccessor readAccess(output); - const float* inputDataArray = ((const float*)readAccess.GetData()); - auto pixel = inputDataArray[0]; - auto pixel2 = inputDataArray[1]; - - myfile << "Algorithmidx: " << Algorithmidx << "\n Output " << i << ": " << "\n" << inputDataArray[0] << "\n" << inputDataArray[1] << "\n"; - myfile << "Correct Result: " << "\n" << m_CorrectResult[i] << "\n" << m_CorrectResult[i + 2] << "\n"; - - CPPUNIT_ASSERT(std::abs(pixel - m_CorrectResult[i]) < threshold); - CPPUNIT_ASSERT(std::abs(pixel2 - m_CorrectResult[i + 2]) < threshold); - } - } - myfile.close(); - MITK_INFO << "VIGRA FILTER TEST SUCCESFULL :)"; - } - - void testSimplexSUAlgorithm() - { - MITK_INFO << "START FILTER TEST ... "; - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterSimplex::New(); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - m_SpectralUnmixingFilter->Verbose(true); - m_SpectralUnmixingFilter->RelativeError(false); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - //Set Chromophores to filter - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - m_SpectralUnmixingFilter->Update(); - - - /*For printed pixel values and results look at: [...]\mitk-superbuild\MITK-build\Modules\PhotoacousticsLib\test\*/ - ofstream myfile; - myfile.open("SimplexTestResult.txt"); - for (int i = 0; i < 2; ++i) - { - mitk::Image::Pointer output = m_SpectralUnmixingFilter->GetOutput(i); - mitk::ImageReadAccessor readAccess(output); - const float* inputDataArray = ((const float*)readAccess.GetData()); - auto pixel = inputDataArray[0]; - auto pixel2 = inputDataArray[1]; - - myfile << "Output " << i << ": " << "\n" << inputDataArray[0] << "\n" << inputDataArray[1] << "\n"; - myfile << "Correct Result: " << "\n" << m_CorrectResult[i] << "\n" << m_CorrectResult[i + 2] << "\n"; - - CPPUNIT_ASSERT(std::abs(pixel - m_CorrectResult[i])SetInput(0, inputImage); - - inputImage = nullptr; - inputImage = mitk::Image::New(); - mitk::PixelType pixelType = mitk::MakeScalarPixelType(); - const int NUMBER_OF_SPATIAL_DIMENSIONS = 3; - auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS]; - - dimensions[0] = 1; - dimensions[1] = 1; - dimensions[2] = 4; - - inputImage->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions); - - float* data = new float[4]; - data[0] = 1; - data[1] = 2; - data[2] = 3; - data[3] = 4; - - inputImage->SetImportVolume(data, mitk::Image::ImportMemoryManagementType::CopyMemory); - delete[] data; - - m_sO2->SetInput(1, inputImage); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_sO2->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - } - - // Tests SO2 Filter with correct inputs - void testSO2() - { - MITK_INFO << "START SO2 TEST ... "; - std::vector CorrectSO2Result1 = { 0, 0, 0, 0, 0 }; - std::vector Test1 = { 0,0,0,51 }; - std::vector CorrectSO2Result2 = { 0, 0.5, 0, 0.5, 0 }; - std::vector Test2 = { 1584, 0, 0, 0 }; - std::vector CorrectSO2Result3 = { 0.5, 0.5, 0, 0.5, 0 }; - std::vector Test3 = { 0, 1536, 0, 0 }; - std::vector CorrectSO2Result4 = { 0.5, 0.5, 0, 0.5, 0 }; - std::vector Test4 = { 0, 0, 3072, 49 }; - std::vector CorrectSO2Result5 = { 0.5, 0.5, 0.5, 0.5, 0 }; - std::vector Test5 = { 1, 1, 1, 49 }; - - std::vector> TestList; - std::vector> ResultList; - - TestList.push_back(Test1); - TestList.push_back(Test2); - TestList.push_back(Test3); - TestList.push_back(Test4); - TestList.push_back(Test5); - - ResultList.push_back(CorrectSO2Result1); - ResultList.push_back(CorrectSO2Result2); - ResultList.push_back(CorrectSO2Result3); - ResultList.push_back(CorrectSO2Result4); - ResultList.push_back(CorrectSO2Result5); - - /*For printed pixel values and results look at: [...]\mitk-superbuild\MITK-build\Modules\PhotoacousticsLib\test\*/ - ofstream myfile; - myfile.open("SO2TestResult.txt"); - - for (int k = 0; k < 5; ++k) - { - std::vector SO2Settings = TestList[k]; - std::vector m_CorrectSO2Result = ResultList[k]; - auto m_sO2 = mitk::pa::SpectralUnmixingSO2::New(); - m_sO2->SetInput(0, inputImage); - m_sO2->SetInput(1, inputImage); - for (unsigned int i = 0; i < SO2Settings.size(); ++i) - m_sO2->AddSO2Settings(SO2Settings[i]); - m_sO2->Update(); - - mitk::Image::Pointer output = m_sO2->GetOutput(0); - mitk::ImageReadAccessor readAccess(output); - const float* inputDataArray = ((const float*)readAccess.GetData()); - - for (unsigned int Pixel = 0; Pixel < inputImage->GetDimensions()[2]; ++Pixel) - { - auto Value = inputDataArray[Pixel]; - - myfile << "Output(Test " << k << ") " << Pixel << ": " << "\n" << Value << "\n"; - myfile << "Correct Result: " << "\n" << m_CorrectSO2Result[Pixel] << "\n"; - - CPPUNIT_ASSERT(std::abs(Value - m_CorrectSO2Result[Pixel]) < threshold); - } - } - myfile.close(); - MITK_INFO << "SO2 TEST SUCCESFULL :)"; - } - - // Test exceptions for wrong wavelength inputs - void testWavelengthExceptions() - { - MITK_INFO << "START WavelengthExceptions TEST ... "; - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - m_SpectralUnmixingFilter->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - - m_SpectralUnmixingFilter->AddWavelength(300); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - - m_SpectralUnmixingFilter->AddWavelength(299); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - MITK_INFO << "DONE"; - } - - // Test exceptions for wrong chromophore inputs - void testNoChromophoresSelected() - { - MITK_INFO << "testNoChromophoresSelected"; - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - m_SpectralUnmixingFilter->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - } - - // Test exceptions for wrong input image - void testInputImage() - { - MITK_INFO << "INPUT IMAGE TEST"; - inputImage = nullptr; - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - //m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - m_SpectralUnmixingFilter->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - - inputImage = mitk::Image::New(); - mitk::PixelType pixelType = mitk::MakeScalarPixelType(); - const int NUMBER_OF_SPATIAL_DIMENSIONS = 3; - auto* dimensions = new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS]; - - dimensions[0] = 1; - dimensions[1] = 1; - dimensions[2] = 5; - - inputImage->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions); - - double* data = new double[6]; - data[0] = 1; - data[1] = 2; - data[2] = 3; - data[3] = 4; - data[5] = 0; - - inputImage->SetImportVolume(data, mitk::Image::ImportMemoryManagementType::CopyMemory); - delete[] data; - - m_SpectralUnmixingFilter->SetInput(inputImage); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - } - - // Test exceptions for addOutputs method - void testAddOutput() - { - MITK_INFO << "addOutputs TEST"; - - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->SetInput(inputImage); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - m_SpectralUnmixingFilter->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - - for (int i = 0; i < 4; ++i) - { - MITK_INFO << "i: " << i; - if (i != 2) - { - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->AddOutputs(i); - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - } - else - { - m_SpectralUnmixingFilter->AddOutputs(2); - m_SpectralUnmixingFilter->Update(); - for (int i = 0; i < 2; ++i) - { - mitk::Image::Pointer output = m_SpectralUnmixingFilter->GetOutput(i); - mitk::ImageReadAccessor readAccess(output); - const float* inputDataArray = ((const float*)readAccess.GetData()); - auto pixel = inputDataArray[0]; - auto pixel2 = inputDataArray[1]; - - CPPUNIT_ASSERT(std::abs(pixel - m_CorrectResult[i]) < threshold); - CPPUNIT_ASSERT(std::abs(pixel2 - m_CorrectResult[i + 2]) < threshold); - } - } - } - } - - // Test exceptions for weights error - void testWeightsError() - { - MITK_INFO << "testWeightsError"; - - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - m_SpectralUnmixingFilter->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::WEIGHTED); - - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - - m_SpectralUnmixingFilter->AddWeight(50); - MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - - m_SpectralUnmixingFilter->AddWeight(50); - m_SpectralUnmixingFilter->Update(); - - for (int i = 0; i < 2; ++i) - { - mitk::Image::Pointer output = m_SpectralUnmixingFilter->GetOutput(i); - mitk::ImageReadAccessor readAccess(output); - const float* inputDataArray = ((const float*)readAccess.GetData()); - auto pixel = inputDataArray[0]; - auto pixel2 = inputDataArray[1]; - - CPPUNIT_ASSERT(std::abs(pixel - m_CorrectResult[i]) < threshold); - CPPUNIT_ASSERT(std::abs(pixel2 - m_CorrectResult[i + 2]) < threshold); - } - } - - // Test correct outputs - void testOutputs() - { - MITK_INFO << "TEST"; - - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - m_SpectralUnmixingFilter->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - - m_SpectralUnmixingFilter->Update(); - - for (int i = 0; i < 2; ++i) - { - mitk::Image::Pointer output = m_SpectralUnmixingFilter->GetOutput(i); - mitk::ImageReadAccessor readAccess(output); - const float* inputDataArray = ((const float*)readAccess.GetData()); - auto pixel = inputDataArray[0]; - auto pixel2 = inputDataArray[1]; - - CPPUNIT_ASSERT(std::abs(pixel - m_CorrectResult[i]) < threshold); - CPPUNIT_ASSERT(std::abs(pixel2 - m_CorrectResult[i + 2]) < threshold); - - // test correct output dimensions and pixel type - CPPUNIT_ASSERT(inputImage->GetDimensions()[0] == output->GetDimensions()[0]); - CPPUNIT_ASSERT(inputImage->GetDimensions()[0] == output->GetDimensions()[1]); - CPPUNIT_ASSERT(2 == output->GetDimensions()[2]); - CPPUNIT_ASSERT(output->GetPixelType() == mitk::MakeScalarPixelType()); - } - } - - // TEST TEMPLATE: - /* - // Test exceptions for - void test() - { - MITK_INFO << "TEST"; - - // Set input image - auto m_SpectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - m_SpectralUnmixingFilter->Verbose(false); - m_SpectralUnmixingFilter->RelativeError(false); - m_SpectralUnmixingFilter->SetInput(inputImage); - m_SpectralUnmixingFilter->AddOutputs(2); - - //Set wavelengths to filter - for (unsigned int imageIndex = 0; imageIndex < m_inputWavelengths.size(); imageIndex++) - { - unsigned int wavelength = m_inputWavelengths[imageIndex]; - m_SpectralUnmixingFilter->AddWavelength(wavelength); - } - - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); - m_SpectralUnmixingFilter->AddChromophore( - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); - - m_SpectralUnmixingFilter->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - - //MITK_TEST_FOR_EXCEPTION_BEGIN(itk::ExceptionObject) - m_SpectralUnmixingFilter->Update(); - //MITK_TEST_FOR_EXCEPTION_END(itk::ExceptionObject) - - }*/ - - void tearDown() override - { - m_SpectralUnmixingFilter = nullptr; - inputImage = nullptr; - m_inputWavelengths.clear(); - m_CorrectResult.clear(); - } -}; - -MITK_TEST_SUITE_REGISTRATION(mitkSpectralUnmixing) diff --git a/Modules/US/CMakeLists.txt b/Modules/US/CMakeLists.txt index 2f39a220c2..8b5a15cfe0 100644 --- a/Modules/US/CMakeLists.txt +++ b/Modules/US/CMakeLists.txt @@ -1,21 +1,20 @@ MITK_CREATE_MODULE( INCLUDE_DIRS USControlInterfaces USFilters USModel INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} PACKAGE_DEPENDS Poco PRIVATE tinyxml2|tinyxml2 DEPENDS MitkOpenCVVideoSupport MitkQtWidgetsExt MitkIGTBase MitkOpenIGTLink ) if(TARGET ${MODULE_TARGET}) target_link_libraries(${MODULE_TARGET} PRIVATE tinyxml2::tinyxml2 ) endif() ## create US config #CONFIGURE_FILE(mitkUSConfig.h.in ${PROJECT_BINARY_DIR}/mitkUSConfig.h @ONLY) ADD_SUBDIRECTORY(USHardwareTelemed) -ADD_SUBDIRECTORY(USHardwareDiPhAS) ADD_SUBDIRECTORY(USNavigation) ADD_SUBDIRECTORY(Testing) diff --git a/Modules/US/USControlInterfaces/mitkUSDiPhASDeviceCustomControls.cpp b/Modules/US/USControlInterfaces/mitkUSDiPhASDeviceCustomControls.cpp deleted file mode 100644 index 1cda345b0f..0000000000 --- a/Modules/US/USControlInterfaces/mitkUSDiPhASDeviceCustomControls.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkUSDiPhASDeviceCustomControls.h" - -mitk::USDiPhASDeviceCustomControls::USDiPhASDeviceCustomControls(itk::SmartPointer device) - : mitk::USAbstractControlInterface(device.GetPointer()), m_IsActive(false), silentUpdate(false) -{ -} - -mitk::USDiPhASDeviceCustomControls::~USDiPhASDeviceCustomControls() -{ -} - -void mitk::USDiPhASDeviceCustomControls::SetIsActive(bool isActive) -{ - m_IsActive = isActive; -} - -bool mitk::USDiPhASDeviceCustomControls::GetIsActive() -{ - return m_IsActive; -} - -void mitk::USDiPhASDeviceCustomControls::passGUIOut(std::function /*callback*/) {} - -void mitk::USDiPhASDeviceCustomControls::SetSilentUpdate(bool silent) -{ - silentUpdate = silent; -} - -bool mitk::USDiPhASDeviceCustomControls::GetSilentUpdate() -{ - return silentUpdate; -} - -//Set Functions - -void mitk::USDiPhASDeviceCustomControls::SetCompensateEnergy(bool compensate) -{ - this->OnSetCompensateEnergy(compensate); -} - -void mitk::USDiPhASDeviceCustomControls::SetUseBModeFilter(bool isSet) -{ - this->OnSetUseBModeFilter(isSet); -} - -void mitk::USDiPhASDeviceCustomControls::SetRecord(bool record) -{ - this->OnSetRecord(record); -} - -void mitk::USDiPhASDeviceCustomControls::SetVerticalSpacing(float mm) -{ - this->OnSetVerticalSpacing(mm); -} - -void mitk::USDiPhASDeviceCustomControls::SetScatteringCoefficient(float coeff) -{ - this->OnSetScatteringCoefficient(coeff); -} -void mitk::USDiPhASDeviceCustomControls::SetCompensateScattering(bool compensate) -{ - this->OnSetCompensateScattering(compensate); -} - -void mitk::USDiPhASDeviceCustomControls::SetSavingSettings(SavingSettings settings) -{ - this->OnSetSavingSettings(settings); -} - -//Transmit -void mitk::USDiPhASDeviceCustomControls::SetTransmitPhaseLength(double us) -{ - this->OnSetTransmitPhaseLength(us); -} - -void mitk::USDiPhASDeviceCustomControls::SetExcitationFrequency(double MHz) -{ - this->OnSetExcitationFrequency(MHz); -} - -void mitk::USDiPhASDeviceCustomControls::SetTransmitEvents(int events) -{ - this->OnSetTransmitEvents(events); -} - -void mitk::USDiPhASDeviceCustomControls::SetVoltage(int voltage) -{ - this->OnSetVoltage(voltage); -} - -void mitk::USDiPhASDeviceCustomControls::SetMode(bool interleaved) -{ - this->OnSetMode(interleaved); -} - -//Receive -void mitk::USDiPhASDeviceCustomControls::SetScanDepth(double mm) -{ - this->OnSetScanDepth(mm); -} - -void mitk::USDiPhASDeviceCustomControls::SetAveragingCount(int count) -{ - this->OnSetAveragingCount(count); -} - -void mitk::USDiPhASDeviceCustomControls::SetTGCMin(int min) -{ - this->OnSetTGCMin(min); -} - -void mitk::USDiPhASDeviceCustomControls::SetTGCMax(int max) -{ - this->OnSetTGCMax(max); - -} - -void mitk::USDiPhASDeviceCustomControls::SetDataType(DataType type) -{ - this->OnSetDataType(type); -} - -//Beamforming -void mitk::USDiPhASDeviceCustomControls::SetPitch(double mm) -{ - this->OnSetPitch(mm); -} - -void mitk::USDiPhASDeviceCustomControls::SetReconstructedSamples(int samples) -{ - this->OnSetReconstructedSamples(samples); -} - -void mitk::USDiPhASDeviceCustomControls::SetReconstructedLines(int lines) -{ - this->OnSetReconstructedLines(lines); -} - -void mitk::USDiPhASDeviceCustomControls::SetSpeedOfSound(int mps) -{ - this->OnSetSpeedOfSound(mps); -} - -//Bandpass -void mitk::USDiPhASDeviceCustomControls::SetBandpassEnabled(bool bandpass) -{ - this->OnSetBandpassEnabled(bandpass); -} - -void mitk::USDiPhASDeviceCustomControls::SetLowCut(double MHz) -{ - this->OnSetLowCut(MHz); -} - -void mitk::USDiPhASDeviceCustomControls::SetHighCut(double MHz) -{ - this->OnSetHighCut(MHz); -} - - -//OnSetDummies - -void mitk::USDiPhASDeviceCustomControls::OnSetCompensateEnergy(bool /*compensate*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetUseBModeFilter(bool /*isSet*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetRecord(bool /*record*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetVerticalSpacing(float /*mm*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetScatteringCoefficient(float /*coeff*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetCompensateScattering(bool /*compensate*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetSavingSettings(SavingSettings /*settings*/) {} -//Transmit -void mitk::USDiPhASDeviceCustomControls::OnSetTransmitPhaseLength(double /*ms*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetExcitationFrequency(double /*MHz*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetTransmitEvents(int /*events*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetVoltage(int /*voltage*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetMode(bool /*interleaved*/) {} -//Receive -void mitk::USDiPhASDeviceCustomControls::OnSetScanDepth(double /*mm*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetAveragingCount(int /*count*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetTGCMin(int /*min*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetTGCMax(int /*max*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetDataType(DataType /*type*/) {} -//Beamforming -void mitk::USDiPhASDeviceCustomControls::OnSetPitch(double /*mm*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetReconstructedSamples(int /*samples*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetReconstructedLines(int /*lines*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetSpeedOfSound(int /*mps*/) {} -//Bandpass -void mitk::USDiPhASDeviceCustomControls::OnSetBandpassEnabled(bool /*bandpass*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetLowCut(double /*MHz*/) {} -void mitk::USDiPhASDeviceCustomControls::OnSetHighCut(double /*MHz*/) {} diff --git a/Modules/US/USControlInterfaces/mitkUSDiPhASDeviceCustomControls.h b/Modules/US/USControlInterfaces/mitkUSDiPhASDeviceCustomControls.h deleted file mode 100644 index b7004e2711..0000000000 --- a/Modules/US/USControlInterfaces/mitkUSDiPhASDeviceCustomControls.h +++ /dev/null @@ -1,140 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKUSDiPhASDeviceCustomControls_H_HEADER_INCLUDED_ -#define MITKUSDiPhASDeviceCustomControls_H_HEADER_INCLUDED_ - -#include "mitkUSAbstractControlInterface.h" -#include "mitkUSImageVideoSource.h" -#include "mitkUSDevice.h" - -#include - -#include -#include - -namespace mitk { -/** - * \brief Custom controls for mitk::USDiPhASDevice. - */ -class MITKUS_EXPORT USDiPhASDeviceCustomControls : public USAbstractControlInterface -{ -public: - mitkClassMacro(USDiPhASDeviceCustomControls, USAbstractControlInterface); - mitkNewMacro1Param(Self, itk::SmartPointer); - - /** - * Activate or deactivate the custom controls. This is just for handling - * widget visibility in a GUI for example. - */ - void SetIsActive( bool isActive ) override; - - enum DataType { Image_uChar, Beamformed_Short }; - - struct SavingSettings - { - bool saveRaw; - bool saveBeamformed; - }; - /** - * \return if this custom controls are currently activated - */ - bool GetIsActive( ) override; - - virtual void SetCompensateEnergy(bool compensate); - virtual void SetUseBModeFilter(bool isSet); - virtual void SetVerticalSpacing(float mm); - virtual void SetRecord(bool record); - virtual void SetScatteringCoefficient(float coeff); - virtual void SetCompensateScattering(bool compensate); - virtual void SetSavingSettings(SavingSettings settings); - - //Transmit - virtual void SetTransmitPhaseLength(double us); - virtual void SetExcitationFrequency(double MHz); - virtual void SetTransmitEvents(int events); - virtual void SetVoltage(int voltage); - virtual void SetMode(bool interleaved); - - //Receive - virtual void SetScanDepth(double mm); - virtual void SetAveragingCount(int count); - virtual void SetTGCMin(int min); - virtual void SetTGCMax(int max); - virtual void SetDataType(DataType type); - - //Beamforming - virtual void SetPitch(double mm); - virtual void SetReconstructedSamples(int samples); - virtual void SetReconstructedLines(int lines); - virtual void SetSpeedOfSound(int mps); - - //Bandpass - virtual void SetBandpassEnabled(bool bandpass); - virtual void SetLowCut(double MHz); - virtual void SetHighCut(double MHz); - - virtual void passGUIOut(std::function /*callback*/); - virtual void SetSilentUpdate(bool silent); - virtual bool GetSilentUpdate(); - - - -protected: - /** - * Class needs an mitk::USDevice object for beeing constructed. - */ - USDiPhASDeviceCustomControls( itk::SmartPointer device ); - ~USDiPhASDeviceCustomControls( ) override; - - bool m_IsActive; - USImageVideoSource::Pointer m_ImageSource; - bool silentUpdate; - - /** virtual handlers implemented in Device Controls - */ - virtual void OnSetCompensateEnergy(bool /*compensate*/); - virtual void OnSetSavingSettings(SavingSettings /*settings*/); - virtual void OnSetUseBModeFilter(bool /*isSet*/); - virtual void OnSetRecord(bool /*record*/); - virtual void OnSetVerticalSpacing(float /*mm*/); - virtual void OnSetScatteringCoefficient(float /*coeff*/); - virtual void OnSetCompensateScattering(bool /*compensate*/); - //Transmit - virtual void OnSetTransmitPhaseLength(double /*us*/); - virtual void OnSetExcitationFrequency(double /*MHz*/); - virtual void OnSetTransmitEvents(int /*events*/); - virtual void OnSetVoltage(int /*voltage*/); - virtual void OnSetMode(bool /*interleaved*/); - - //Receive - virtual void OnSetScanDepth(double /*mm*/); - virtual void OnSetAveragingCount(int /*count*/); - virtual void OnSetTGCMin(int /*min*/); - virtual void OnSetTGCMax(int /*max*/); - virtual void OnSetDataType(DataType /*type*/); - - //Beamforming - virtual void OnSetPitch(double /*mm*/); - virtual void OnSetReconstructedSamples(int /*samples*/); - virtual void OnSetReconstructedLines(int /*lines*/); - virtual void OnSetSpeedOfSound(int /*mps*/); - - //Bandpass - virtual void OnSetBandpassEnabled(bool /*bandpass*/); - virtual void OnSetLowCut(double /*MHz*/); - virtual void OnSetHighCut(double /*MHz*/); - -}; -} // namespace mitk - -#endif // MITKUSDiPhASDeviceCustomControls_H_HEADER_INCLUDED_ diff --git a/Modules/US/USHardwareDiPhAS/CMakeLists.txt b/Modules/US/USHardwareDiPhAS/CMakeLists.txt deleted file mode 100644 index c72b11fa83..0000000000 --- a/Modules/US/USHardwareDiPhAS/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -if(WIN32) - - OPTION(MITK_USE_US_DiPhAS_SDK "Enable support for DiPhAS API devices" OFF) - - if(MITK_USE_US_DiPhAS_SDK) - - SET(MITK_US_DiPhAS_SDK_PATH "" CACHE PATH "Path to DiPhAS SDK header files.") - - MITK_CREATE_MODULE( - DEPENDS MitkUS MitkPhotoacousticsHardware - INCLUDE_DIRS PUBLIC "${MITK_US_DiPhAS_SDK_PATH}/Debug" "${MITK_US_DiPhAS_SDK_PATH}/Release" - INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} - ADDITIONAL_LIBS "${MITK_US_DiPhAS_SDK_PATH}/Debug/Framework.IBMT.US.CWrapper.lib" "${MITK_US_DiPhAS_SDK_PATH}/Release/Framework.IBMT.US.CWrapper.lib" - AUTOLOAD_WITH MitkUS - ) - - endif() - -endif() diff --git a/Modules/US/USHardwareDiPhAS/FranzTissue.nrrd b/Modules/US/USHardwareDiPhAS/FranzTissue.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/FranzTissue.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkAnalyticSignalImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkAnalyticSignalImageFilter.h deleted file mode 100644 index 0bd53ce42b..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkAnalyticSignalImageFilter.h +++ /dev/null @@ -1,139 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkAnalyticSignalImageFilter_h -#define itkAnalyticSignalImageFilter_h - -#include - -#include "itkFFT1DComplexToComplexImageFilter.h" -#include "itkFFT1DRealToComplexConjugateImageFilter.h" -#include "itkImageRegionSplitterDirection.h" - -namespace itk -{ -/** \class AnalyticSignalImageFilter - * \brief Generates the analytic signal from one direction of an image. - * - * This filter generates the complex valued analytic signal along one direction - * of an image. This input is a real valued image, and the output is a complex - * image. - * - * The analytic signal is given by - * - * f_a(x) = f(x) - i f_H(x) - * - * Where i is the square root of one and f_H(x) is the Hibert transform of f(x). - * - * Since the Hilbert transform in the Fourier domain is - * - * F_H(k) = F(k) i sign(k), - * - * f_a(x) is calculated by - * - * f_a(x) = F^{-1}( F(k) 2 U(k) ) - * - * where U(k) is the unit step function. - * - * \ingroup FourierTransform - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage > -class AnalyticSignalImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension); - - typedef AnalyticSignalImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkTypeMacro( AnalyticSignalImageFilter, ImageToImageFilter ); - itkNewMacro( Self ); - - /** Get the direction in which the filter is to be applied. */ - virtual unsigned int GetDirection() const - { - return this->m_FFTRealToComplexFilter->GetDirection(); - } - - /** Set the direction in which the filter is to be applied. */ - virtual void SetDirection( const unsigned int direction ) - { - if( this->m_FFTRealToComplexFilter->GetDirection() != direction ) - { - this->m_FFTRealToComplexFilter->SetDirection( direction ); - this->m_FFTComplexToComplexFilter->SetDirection( direction ); - this->Modified(); - } - } - -protected: - AnalyticSignalImageFilter(); - virtual ~AnalyticSignalImageFilter() {} - - void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - // These behave like their analogs in FFT1DRealToComplexConjugateImageFilter. - virtual void GenerateInputRequestedRegion() ITK_OVERRIDE; - virtual void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - virtual void BeforeThreadedGenerateData() ITK_OVERRIDE; - virtual void ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType threadId ) ITK_OVERRIDE; - virtual void AfterThreadedGenerateData() ITK_OVERRIDE; - - typedef FFT1DRealToComplexConjugateImageFilter< InputImageType, OutputImageType > FFTRealToComplexType; - typedef FFT1DComplexToComplexImageFilter< OutputImageType, OutputImageType > FFTComplexToComplexType; - - typename FFTRealToComplexType::Pointer m_FFTRealToComplexFilter; - typename FFTComplexToComplexType::Pointer m_FFTComplexToComplexFilter; - - /** Override to return a splitter that does not split along the direction we - * are performing the transform. */ - virtual const ImageRegionSplitterBase* GetImageRegionSplitter() const ITK_OVERRIDE; - -private: - AnalyticSignalImageFilter( const Self& ); // purposely not implemented - void operator=( const Self& ); // purposely not implemented - - ImageRegionSplitterDirection::Pointer m_ImageRegionSplitter; -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkAnalyticSignalImageFilter.hxx" -#endif - -#endif // itkAnalyticSignalImageFilter_h diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkAnalyticSignalImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkAnalyticSignalImageFilter.hxx deleted file mode 100644 index 6f9bed0161..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkAnalyticSignalImageFilter.hxx +++ /dev/null @@ -1,267 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkAnalyticSignalImageFilter_hxx -#define itkAnalyticSignalImageFilter_hxx - -#include "itkAnalyticSignalImageFilter.h" - -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.h" -#include "itkVnlFFT1DComplexToComplexImageFilter.h" - -#if defined(ITK_USE_FFTWD) || defined(ITK_USE_FFTWF) -#include "itkFFTW1DRealToComplexConjugateImageFilter.h" -#include "itkFFTW1DComplexToComplexImageFilter.h" -#endif - -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkMetaDataObject.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::AnalyticSignalImageFilter() -{ - m_FFTRealToComplexFilter = FFTRealToComplexType::New(); - m_FFTComplexToComplexFilter = FFTComplexToComplexType::New(); - - m_FFTComplexToComplexFilter->SetTransformDirection( FFTComplexToComplexType::INVERSE ); - - this->SetDirection( 0 ); - - this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New(); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - typename InputImageType::Pointer inputPtr = - const_cast (this->GetInput()); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->GetDirection(); - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast< OutputImageType* >( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - const unsigned int direction = this->GetDirection (); - enlargedSize[direction] = outputLargeSize[direction]; - enlargedIndex[direction] = outputLargeIndex[direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - const unsigned int direction = this->GetDirection(); - os << indent << "Direction: " << direction << std::endl; - - os << indent << "FFTRealToComplexFilter: " << std::endl; - m_FFTRealToComplexFilter->Print( os, indent ); - os << indent << "FFTComplexToComplexFilter: " << std::endl; - m_FFTComplexToComplexFilter->Print( os, indent ); -} - - -template< typename TInputImage, typename TOutputImage > -const ImageRegionSplitterBase * -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::GetImageRegionSplitter() const -{ - return this->m_ImageRegionSplitter.GetPointer(); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - this->m_ImageRegionSplitter->SetDirection( this->GetDirection() ); - - m_FFTRealToComplexFilter->SetInput( this->GetInput() ); - m_FFTRealToComplexFilter->GetOutput()->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() ); - m_FFTRealToComplexFilter->GetOutput()->SetLargestPossibleRegion( this->GetOutput()->GetLargestPossibleRegion() ); - m_FFTRealToComplexFilter->SetNumberOfThreads( this->GetNumberOfThreads() ); - m_FFTRealToComplexFilter->Update (); -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType itkNotUsed( threadId ) ) -{ - // get pointers to the input and output - const typename FFTRealToComplexType::OutputImageType * inputPtr = m_FFTRealToComplexFilter->GetOutput(); - OutputImageType * outputPtr = this->GetOutput(); - - const typename FFTRealToComplexType::OutputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - const unsigned int direction = this->GetDirection (); - const unsigned int size = inputSize[direction]; - unsigned int dub_size; - bool even; - if( size % 2 == 0 ) - { - even = true; - dub_size = size / 2 - 1; - } - else - { - even = false; - dub_size = (size + 1) / 2 - 1; - } - - typedef ImageLinearConstIteratorWithIndex< typename FFTRealToComplexType::OutputImageType > InputIteratorType; - typedef ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegionForThread ); - OutputIteratorType outputIt( outputPtr, outputRegionForThread ); - inputIt.SetDirection( direction ); - outputIt.SetDirection( direction ); - - unsigned int i; - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - inputIt.GoToBeginOfLine(); - outputIt.GoToBeginOfLine(); - - // DC - outputIt.Set( inputIt.Get() ); - ++inputIt; - ++outputIt; - - for( i = 0; i < dub_size; i++ ) - { - outputIt.Set( inputIt.Get() * static_cast< typename TInputImage::PixelType >( 2 ) ); - ++outputIt; - ++inputIt; - } - if( even ) - { - outputIt.Set( inputIt.Get() ); - ++inputIt; - ++outputIt; - } - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( static_cast< typename TInputImage::PixelType >( 0 ) ); - ++outputIt; - } - } -} - - -template< typename TInputImage, typename TOutputImage > -void -AnalyticSignalImageFilter< TInputImage, TOutputImage > -::AfterThreadedGenerateData() -{ - // Trippy, eh? - m_FFTComplexToComplexFilter->SetInput( this->GetOutput() ); - m_FFTComplexToComplexFilter->GetOutput()->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() ); - m_FFTComplexToComplexFilter->GetOutput()->SetLargestPossibleRegion( this->GetOutput()->GetLargestPossibleRegion() ); - m_FFTComplexToComplexFilter->SetNumberOfThreads( this->GetNumberOfThreads() ); - m_FFTComplexToComplexFilter->Update (); - this->GraftOutput( m_FFTComplexToComplexFilter->GetOutput() ); -} - -} // end namespace itk - -#endif // itkAnalyticSignalImageFilter_hxx diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkBModeImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkBModeImageFilter.h deleted file mode 100644 index ec84eee33f..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkBModeImageFilter.h +++ /dev/null @@ -1,152 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkBModeImageFilter_h -#define itkBModeImageFilter_h - -#include "itkAddImageFilter.h" -#include "itkComplexToModulusImageFilter.h" -#include "itkConstantPadImageFilter.h" -#include "itkRegionFromReferenceImageFilter.h" -#include "itkImageToImageFilter.h" -#include "itkImage.h" -#include "itkLog10ImageFilter.h" - -#include "itkAnalyticSignalImageFilter.h" - -namespace itk -{ - -/** - * \class BModeImageFilter - * - * \brief Create an ultrasound B-Mode (Brightness-Mode) image from raw - * "RF" data. The RF's envelope is calculated from the analytic signal and - * logarithmic intensity transform is applied. - * - * Use SetDirection() to define the axis of propagation. - * - * \ingroup Ultrasound - * - * \sa AnalyticSignalImageFilter - * - */ -template < typename TInputImage, typename TOutputImage=TInputImage, typename TComplexImage=Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > -class BModeImageFilter : - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef BModeImageFilter Self; - typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - /** The type of input image. */ - typedef TInputImage InputImageType; - - /** Dimension of the input and output images. */ - itkStaticConstMacro (ImageDimension, unsigned int, - TInputImage::ImageDimension); - - /** Typedef support for the input image scalar value type. */ - typedef typename InputImageType::PixelType InputPixelType; - - /** The type of output image. */ - typedef TOutputImage OutputImageType; - - /** Typedef support for the output image scalar value type. */ - typedef typename OutputImageType::PixelType OutputPixelType; - - /** Typedef of the image used for internal computations that has - * std::complex pixels. */ - typedef TComplexImage ComplexImageType; - - /** Other convenient typedefs */ - typedef typename InputImageType::RegionType InputRegionType; - typedef typename InputImageType::SizeType InputSizeType; - typedef typename InputImageType::IndexType InputIndexType; - - /** Run-time type information (and related methods) */ - itkTypeMacro( BModeImageFilter, ImageToImageFilter ); - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Set the direction in which the envelope is to be calculated. */ - virtual void SetDirection( unsigned int direction ) - { - this->m_AnalyticFilter->SetDirection( direction ); - this->Modified(); - } - - /** Get the direction in which the envelope is to be calculated. */ - virtual unsigned int GetDirection() const - { - return m_AnalyticFilter->GetDirection(); - } - -protected: - BModeImageFilter(); - ~BModeImageFilter() {} - - virtual void PrintSelf( std::ostream& os, Indent indent ) const ITK_OVERRIDE; - - virtual void GenerateData() ITK_OVERRIDE; - - // These behave like their analogs in FFT1DRealToComplexConjugateImageFilter. - virtual void GenerateInputRequestedRegion() ITK_OVERRIDE; - virtual void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - /** Component filters. */ - typedef AnalyticSignalImageFilter< InputImageType, ComplexImageType > AnalyticType; - typedef ComplexToModulusImageFilter< typename AnalyticType::OutputImageType, OutputImageType > ComplexToModulusType; - typedef ConstantPadImageFilter< InputImageType, InputImageType > PadType; - typedef AddImageFilter< InputImageType, InputImageType > AddConstantType; - typedef Log10ImageFilter< InputImageType, OutputImageType > LogType; - typedef RegionFromReferenceImageFilter< OutputImageType, OutputImageType > ROIType; - -private: - BModeImageFilter( const Self& ); // purposely not implemented - void operator=( const Self& ); // purposely not implemented - - typename AnalyticType::Pointer m_AnalyticFilter; - typename ComplexToModulusType::Pointer m_ComplexToModulusFilter; - typename PadType::Pointer m_PadFilter; - typename AddConstantType::Pointer m_AddConstantFilter; - typename LogType::Pointer m_LogFilter; - typename ROIType::Pointer m_ROIFilter; -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkBModeImageFilter.hxx" -#endif - -#endif // itkBModeImageFilter_h diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkBModeImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkBModeImageFilter.hxx deleted file mode 100644 index f45b42fe37..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkBModeImageFilter.hxx +++ /dev/null @@ -1,208 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkBModeImageFilter_hxx -#define itkBModeImageFilter_hxx - -#include "itkBModeImageFilter.h" - -#include "itkMetaDataDictionary.h" - -#include -#include -#include - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::BModeImageFilter() -{ - m_AnalyticFilter = AnalyticType::New(); - m_ComplexToModulusFilter = ComplexToModulusType::New(); - m_PadFilter = PadType::New(); - m_AddConstantFilter = AddConstantType::New(); - m_LogFilter = LogType::New(); - m_ROIFilter = ROIType::New(); - - // Avoid taking the log of zero. Assuming that the original input is coming - // from a digitizer that outputs integer types, so 1 is small. - m_AddConstantFilter->SetConstant2( 1 ); - m_PadFilter->SetConstant( 0. ); - - m_ComplexToModulusFilter->SetInput( m_AnalyticFilter->GetOutput() ); - m_ROIFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); - m_LogFilter->SetInput( m_AddConstantFilter->GetOutput() ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - InputImageType * inputPtr = const_cast (this->GetInput()); - OutputImageType * outputPtr = this->GetOutput(); - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->GetDirection(); - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast< OutputImageType* >( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - const unsigned int direction = this->GetDirection (); - enlargedSize[direction] = outputLargeSize[direction]; - enlargedIndex[direction] = outputLargeIndex[direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template < typename TInputImage, typename TOutputImage, typename TComplexImage > -void -BModeImageFilter< TInputImage, TOutputImage, TComplexImage > -::GenerateData() -{ - this->AllocateOutputs(); - - const InputImageType * inputPtr = this->GetInput(); - OutputImageType * outputPtr = this->GetOutput(); - - const unsigned int direction = m_AnalyticFilter->GetDirection(); - typename InputImageType::SizeType size = inputPtr->GetLargestPossibleRegion().GetSize(); - - // Zero padding. FFT direction should be factorable by 2 for all FFT - // implementations to work. - unsigned int n = size[direction]; - while( n % 2 == 0 ) - { - n /= 2; - } - bool doPadding; - if( n == 1 ) - { - doPadding = false; - } - else - { - doPadding = true; - } - if( doPadding ) - { - n = size[direction]; - unsigned int newSizeDirection = 1; - while( newSizeDirection < n ) - { - newSizeDirection *= 2; - } - typename InputImageType::SizeType padSize; - padSize.Fill( 0 ); - padSize[direction] = newSizeDirection - size[direction]; - size[direction] = newSizeDirection; - m_PadFilter->SetPadUpperBound( padSize ); - m_PadFilter->SetInput( inputPtr ); - m_AnalyticFilter->SetInput( m_PadFilter->GetOutput() ); - m_ROIFilter->SetReferenceImage( inputPtr ); - m_ROIFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); - m_AddConstantFilter->SetInput( m_ROIFilter->GetOutput() ); - } - else // padding is not required - { - m_AnalyticFilter->SetInput( inputPtr ); - m_AddConstantFilter->SetInput( m_ComplexToModulusFilter->GetOutput() ); - } - m_LogFilter->GraftOutput( outputPtr ); - m_LogFilter->Update(); - this->GraftOutput( m_LogFilter->GetOutput() ); -} - -} // end namespace itk - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.h deleted file mode 100644 index 9c6bede6c1..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.h +++ /dev/null @@ -1,138 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DComplexToComplexImageFilter_h -#define itkFFT1DComplexToComplexImageFilter_h - -#include - -#include "itkImage.h" -#include "itkImageToImageFilter.h" -#include "itkImageRegionSplitterDirection.h" - -namespace itk -{ -/** \class FFT1DComplexToComplexImageFilter - * \brief Perform the Fast Fourier Transform, complex input to complex output, - * but only along one dimension. - * - * The direction of the transform, 'Forward' or 'Inverse', can be set with - * SetTransformDirection() and GetTransformDirection(). - * - * The dimension along which to apply to filter can be specified with - * SetDirection() and GetDirection(). - * - * \ingroup FourierTransform - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=TInputImage > -class FFT1DComplexToComplexImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - typedef FFT1DComplexToComplexImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension ); - - itkTypeMacro( FFT1DComplexToComplexImageFilter, ImageToImageFilter ); - - /** Customized object creation methods that support configuration-based - * selection of FFT implementation. - * - * Default implementation is VnlFFT1D. - */ - static Pointer New(); - - /** Transform direction. */ - typedef enum { DIRECT = 1, INVERSE } TransformDirectionType; - - /** Set/Get the direction in which the transform will be applied. - * By selecting DIRECT, this filter will perform a direct (forward) Fourier - * Transform. - * By selecting INVERSE, this filter will perform an inverse Fourier - * Transform. */ - itkSetMacro( TransformDirection, TransformDirectionType ); - itkGetConstMacro( TransformDirection, TransformDirectionType ); - - /** Get the direction in which the filter is to be applied. */ - itkGetMacro(Direction, unsigned int); - - /** Set the direction in which the filter is to be applied. */ - itkSetClampMacro(Direction, unsigned int, 0, ImageDimension - 1); - -protected: - FFT1DComplexToComplexImageFilter(); - virtual ~FFT1DComplexToComplexImageFilter() {} - - void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - virtual void GenerateInputRequestedRegion() ITK_OVERRIDE; - virtual void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - virtual void BeforeThreadedGenerateData() ITK_OVERRIDE; - - /** Override to return a splitter that does not split along the direction we - * are performing the transform. */ - virtual const ImageRegionSplitterBase* GetImageRegionSplitter() const ITK_OVERRIDE; - - /** Direction in which the filter is to be applied - * this should be in the range [0,ImageDimension-1]. */ - unsigned int m_Direction; - - /** Direction to apply the transform (forward/inverse). */ - TransformDirectionType m_TransformDirection; - -private: - FFT1DComplexToComplexImageFilter( const Self& ); - void operator=( const Self& ); - - ImageRegionSplitterDirection::Pointer m_ImageRegionSplitter; -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -#ifndef itkVnlFFT1DComplexToComplexImageFilter_h -#ifndef itkVnlFFT1DComplexToComplexImageFilter_hxx -#ifndef itkFFTW1DComplexToComplexImageFilter_h -#ifndef itkFFTW1DComplexToComplexImageFilter_hxx -#include "itkFFT1DComplexToComplexImageFilter.hxx" -#endif -#endif -#endif -#endif -#endif - -#endif // itkFFT1DComplexToComplexImageFilter_h diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.hxx deleted file mode 100644 index af4c9d7b1c..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DComplexToComplexImageFilter.hxx +++ /dev/null @@ -1,206 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DComplexToComplexImageFilter_hxx -#define itkFFT1DComplexToComplexImageFilter_hxx - -#include "itkFFT1DComplexToComplexImageFilter.h" - -#include "itkVnlFFT1DComplexToComplexImageFilter.h" - -#if defined(ITK_USE_FFTWD) || defined(ITK_USE_FFTWF) -#include "itkFFTW1DComplexToComplexImageFilter.h" -#endif - -#include "itkMetaDataDictionary.h" -#include "itkMetaDataObject.h" - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage > -typename FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage >::Pointer -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::New() -{ - Pointer smartPtr = ::itk::ObjectFactory< Self >::Create(); - -#ifdef ITK_USE_FFTWD - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( double ) ) - { - smartPtr = dynamic_cast< Self* >( - FFTW1DComplexToComplexImageFilter< double, VDimension > - ::New().GetPointer() ); - } - } -#endif -#ifdef ITK_USE_FFTWF - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( float ) ) - { - smartPtr = dynamic_cast( - FFTW1DComplexToComplexImageFilter< float, VDimension > - ::New().GetPointer() ); - } - } -#endif - - if( smartPtr.IsNull() ) - { - smartPtr = VnlFFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > - ::New().GetPointer(); - } - - return smartPtr; -} - - -template< typename TInputImage, typename TOutputImage > -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::FFT1DComplexToComplexImageFilter(): - m_Direction(0), m_TransformDirection( DIRECT ) -{ - this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New(); -} - - -template -const ImageRegionSplitterBase* -FFT1DComplexToComplexImageFilter < TInputImage, TOutputImage > -::GetImageRegionSplitter(void) const -{ - return this->m_ImageRegionSplitter.GetPointer(); -} - - -template -void -FFT1DComplexToComplexImageFilter < TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - this->m_ImageRegionSplitter->SetDirection( this->GetDirection() ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - typename InputImageType::Pointer inputPtr = - const_cast (this->GetInput()); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->m_Direction; - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - enlargedSize[this->m_Direction] = outputLargeSize[this->m_Direction]; - enlargedIndex[this->m_Direction] = outputLargeIndex[this->m_Direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - os << indent << "Direction: " << m_Direction << std::endl; - os << indent << "TransformDirection: " << m_TransformDirection << std::endl; -} - - -} // end namespace itk - -#endif // itkFFT1DComplexToComplexImageFilter_hxx diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h deleted file mode 100644 index 6dfb296bc3..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.h +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DRealToComplexConjugateImageFilter_h -#define itkFFT1DRealToComplexConjugateImageFilter_h - -#include - -#include "itkImageToImageFilter.h" -#include "itkImageRegionSplitterDirection.h" - -namespace itk -{ -/** \class FFT1DRealToComplexConjugateImageFilter - * \brief Perform the Fast Fourier Transform, in the forward direction, with - * real inputs, but only along one dimension. - * - * \ingroup FourierTransform - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > -class FFT1DRealToComplexConjugateImageFilter: - public ImageToImageFilter< TInputImage, TOutputImage > -{ -public: - - /** Standard class typedefs. */ - typedef TInputImage InputImageType; - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - typedef FFT1DRealToComplexConjugateImageFilter Self; - typedef ImageToImageFilter< InputImageType, OutputImageType > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - itkStaticConstMacro( ImageDimension, unsigned int, InputImageType::ImageDimension ); - - itkTypeMacro( FFT1DRealToComplexConjugateImageFilter, ImageToImageFilter ); - - /** Customized object creation methods that support configuration-based - * selection of FFT implementation. - * - * Default implementation is VnlFFT1D. - */ - static Pointer New(); - - /** Get the direction in which the filter is to be applied. */ - itkGetMacro(Direction, unsigned int); - - /** Set the direction in which the filter is to be applied. */ - itkSetClampMacro(Direction, unsigned int, 0, ImageDimension - 1); - -protected: - FFT1DRealToComplexConjugateImageFilter(); - virtual ~FFT1DRealToComplexConjugateImageFilter() {} - - void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - virtual void GenerateInputRequestedRegion() ITK_OVERRIDE; - virtual void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - virtual void BeforeThreadedGenerateData() ITK_OVERRIDE; - - /** Override to return a splitter that does not split along the direction we - * are performing the transform. */ - virtual const ImageRegionSplitterBase* GetImageRegionSplitter() const ITK_OVERRIDE; - -private: - FFT1DRealToComplexConjugateImageFilter( const Self& ); - void operator=( const Self& ); - - ImageRegionSplitterDirection::Pointer m_ImageRegionSplitter; - - /** Direction in which the filter is to be applied - * this should be in the range [0,ImageDimension-1]. */ - unsigned int m_Direction; - -}; -} - -#ifndef ITK_MANUAL_INSTANTIATION -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_h -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_hxx -#ifndef itkFFTW1DRealToComplexConjugateImageFilter_h -#ifndef itkFFTW1DRealToComplexConjugateImageFilter_hxx -#include "itkFFT1DRealToComplexConjugateImageFilter.hxx" -#endif -#endif -#endif -#endif -#endif - -#endif // itkFFT1DRealToComplexConjugateImageFilter_h diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.hxx deleted file mode 100644 index 469f702479..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkFFT1DRealToComplexConjugateImageFilter.hxx +++ /dev/null @@ -1,203 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkFFT1DRealToComplexConjugateImageFilter_hxx -#define itkFFT1DRealToComplexConjugateImageFilter_hxx - -#include "itkFFT1DRealToComplexConjugateImageFilter.h" - -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.h" - -#if defined(ITK_USE_FFTWD) || defined(ITK_USE_FFTWF) -#include "itkFFTW1DRealToComplexConjugateImageFilter.h" -#endif - -#include "itkMetaDataObject.h" - -namespace itk -{ - -template < typename TInputImage, typename TOutputImage > -typename FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage >::Pointer -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::New() -{ - Pointer smartPtr = ::itk::ObjectFactory< Self >::Create(); - -#ifdef ITK_USE_FFTWD - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( double ) ) - { - smartPtr = dynamic_cast< Self* >( - FFTW1DRealToComplexConjugateImageFilter< double, VDimension > - ::New().GetPointer() ); - } - } -#endif -#ifdef ITK_USE_FFTWF - if( smartPtr.IsNull() ) - { - if( typeid( TPixel ) == typeid( float ) ) - { - smartPtr = dynamic_cast( - FFTW1DRealToComplexConjugateImageFilter< float, VDimension > - ::New().GetPointer() ); - } - } -#endif - - if( smartPtr.IsNull() ) - { - smartPtr = VnlFFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > - ::New().GetPointer(); - } - - return smartPtr; -} - - -template< typename TInputImage, typename TOutputImage > -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::FFT1DRealToComplexConjugateImageFilter(): - m_Direction( 0 ) -{ - this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New(); -} - - -template< typename TInputImage, typename TOutputImage > -const ImageRegionSplitterBase* -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::GetImageRegionSplitter() const -{ - return this->m_ImageRegionSplitter.GetPointer(); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::BeforeThreadedGenerateData() -{ - this->m_ImageRegionSplitter->SetDirection( this->GetDirection() ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::GenerateInputRequestedRegion() -{ - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - typename InputImageType::Pointer inputPtr = - const_cast (this->GetInput()); - typename OutputImageType::Pointer outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->m_Direction; - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize( inputRequestedRegionSize ); - inputRequestedRegion.SetIndex( inputRequestedRegionStartIndex ); - - inputPtr->SetRequestedRegion( inputRequestedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter < TInputImage, TOutputImage > -::EnlargeOutputRequestedRegion(DataObject *output) -{ - OutputImageType* outputPtr = dynamic_cast< OutputImageType * >( output ); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - enlargedSize[this->m_Direction] = outputLargeSize[this->m_Direction]; - enlargedIndex[this->m_Direction] = outputLargeIndex[this->m_Direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize( enlargedSize ); - enlargedRegion.SetIndex( enlargedIndex ); - outputPtr->SetRequestedRegion( enlargedRegion ); -} - - -template< typename TInputImage, typename TOutputImage > -void -FFT1DRealToComplexConjugateImageFilter < TInputImage, TOutputImage > -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - - os << indent << "Direction: " << m_Direction << std::endl; -} - -} // end namespace itk - -#endif // itkFFT1DRealToComplexConjugateImageFilter_hxx diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkRegionFromReferenceImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkRegionFromReferenceImageFilter.h deleted file mode 100644 index 41d9bc62d6..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkRegionFromReferenceImageFilter.h +++ /dev/null @@ -1,139 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkRegionFromReferenceImageFilter_h -#define itkRegionFromReferenceImageFilter_h - -#include "itkExtractImageFilter.h" - -namespace itk -{ - -/** \class RegionFromReferenceImageFilter - * \brief Decrease the image size by cropping the image by an itk::Size at - * both the upper and lower bounds of the largest possible region. - * - * RegionFromReferenceImageFilter changes the image boundary of an image by removing - * pixels outside the target region. The target region is not specified in - * advance, but calculated in BeforeThreadedGenerateData(). - * - * This filter uses ExtractImageFilter to perform the cropping. - * - * \ingroup GeometricTransforms - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=TInputImage > -class RegionFromReferenceImageFilter: - public ExtractImageFilter -{ -public: - /** Standard class typedefs. */ - typedef RegionFromReferenceImageFilter Self; - typedef ExtractImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(RegionFromReferenceImageFilter, ExtractImageFilter); - - /** Typedef to describe the output and input image region types. */ - typedef typename Superclass::OutputImageRegionType OutputImageRegionType; - typedef typename Superclass::InputImageRegionType InputImageRegionType; - - /** Typedef to describe the type of pixel. */ - typedef typename Superclass::OutputImagePixelType OutputImagePixelType; - typedef typename Superclass::InputImagePixelType InputImagePixelType; - - /** Typedef to describe the output and input image index and size types. */ - typedef typename Superclass::OutputImageIndexType OutputImageIndexType; - typedef typename Superclass::InputImageIndexType InputImageIndexType; - typedef typename Superclass::OutputImageSizeType OutputImageSizeType; - typedef typename Superclass::InputImageSizeType InputImageSizeType; - typedef InputImageSizeType SizeType; - - /** ImageDimension constants */ - itkStaticConstMacro(InputImageDimension, unsigned int, - Superclass::InputImageDimension); - itkStaticConstMacro(OutputImageDimension, unsigned int, - Superclass::OutputImageDimension); - itkStaticConstMacro(ImageDimension, unsigned int, - Superclass::OutputImageDimension); - - typedef ImageBase< itkGetStaticConstMacro( ImageDimension ) > ReferenceImageType; - - /** Copy the output information from another Image. */ - void SetReferenceImage ( const ReferenceImageType *image ); - - const ReferenceImageType * GetReferenceImage() const; - - /** Set the input image */ - void SetInput1(const TInputImage *input) - { - this->SetInput( input ); - } - - /** Set the reference image */ - void SetInput2(const ReferenceImageType *input) - { - this->SetReferenceImage( input ); - } - - -#ifdef ITK_USE_CONCEPT_CHECKING - /** Begin concept checking */ - itkConceptMacro(InputConvertibleToOutputCheck, - (Concept::Convertible)); - itkConceptMacro(SameDimensionCheck, - (Concept::SameDimension)); - /** End concept checking */ -#endif - -protected: - RegionFromReferenceImageFilter() - { - this->SetNumberOfRequiredInputs(2); - } - ~RegionFromReferenceImageFilter() {} - - virtual void GenerateOutputInformation() ITK_OVERRIDE; - -private: - RegionFromReferenceImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkRegionFromReferenceImageFilter.hxx" -#endif - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkRegionFromReferenceImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkRegionFromReferenceImageFilter.hxx deleted file mode 100644 index 277794c7f2..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkRegionFromReferenceImageFilter.hxx +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkRegionFromReferenceImageFilter_hxx -#define itkRegionFromReferenceImageFilter_hxx - -#include "itkRegionFromReferenceImageFilter.h" - -namespace itk -{ - -template -void -RegionFromReferenceImageFilter -::GenerateOutputInformation() -{ - if( !this->GetInput() || !this->GetReferenceImage() ) - { - return; - } - - // Superclass::Superclass::GenerateOutputInformation(); - this->SetExtractionRegion( this->GetReferenceImage()->GetLargestPossibleRegion() ); - Superclass::GenerateOutputInformation(); -} - - -template -void -RegionFromReferenceImageFilter -::SetReferenceImage ( const ReferenceImageType *image ) -{ - itkDebugMacro("setting input ReferenceImage to " << image); - if( image != static_cast(this->GetInput( 1 )) ) - { - this->ProcessObject::SetNthInput(1, const_cast< ReferenceImageType *>( image ) ); - this->Modified(); - } -} - - -template -const typename RegionFromReferenceImageFilter::ReferenceImageType * -RegionFromReferenceImageFilter -::GetReferenceImage() const -{ - Self * surrogate = const_cast< Self * >( this ); - - const DataObject * input = surrogate->ProcessObject::GetInput(1); - - const ReferenceImageType * referenceImage = static_cast( input ); - - return referenceImage; -} - -} // end namespace itk - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.h deleted file mode 100644 index bf225d99de..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.h +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexConjugateToRealImageFilter_h -#define itkVnlFFT1DComplexConjugateToRealImageFilter_h - -#include "itkFFT1DComplexConjugateToRealImageFilter.h" -#include - -namespace itk -{ - -/** \class VnlFFT1DComplexConjugateToRealImageFilter - * - * \brief Perform the FFT along one dimension of an image using Vnl as a - * backend. - * - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=Image< typename NumericTraits< typename TInputImage::PixelType >::ValueType, TInputImage::ImageDimension > > -class VnlFFT1DComplexConjugateToRealImageFilter: - public FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef VnlFFT1DComplexConjugateToRealImageFilter Self; - typedef FFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Run-time type information (and related methods). */ - itkTypeMacro( VnlFFT1DComplexConjugateToRealImageFilter, FFT1DComplexConjugateToRealImageFilter ); - -protected: - virtual void ThreadedGenerateData( const OutputImageRegionType&, ThreadIdType threadID ); // generates output from input - - VnlFFT1DComplexConjugateToRealImageFilter() { } - virtual ~VnlFFT1DComplexConjugateToRealImageFilter() { } - -private: - VnlFFT1DComplexConjugateToRealImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkVnlFFT1DComplexConjugateToRealImageFilter.hxx" -#endif - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.hxx deleted file mode 100644 index d77ad681a1..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexConjugateToRealImageFilter.hxx +++ /dev/null @@ -1,110 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexConjugateToRealImageFilter_hxx -#define itkVnlFFT1DComplexConjugateToRealImageFilter_hxx - -#include "itkVnlFFT1DComplexConjugateToRealImageFilter.h" - -#include "itkFFT1DComplexConjugateToRealImageFilter.hxx" -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkIndent.h" -#include "itkMetaDataObject.h" -#include "itkExceptionObject.h" -#include "vnl/algo/vnl_fft_base.h" -#include "vnl/algo/vnl_fft_1d.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -void -VnlFFT1DComplexConjugateToRealImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegion, ThreadIdType itkNotUsed( threadID ) ) -{ - // get pointers to the input and output - const typename Superclass::InputImageType * inputPtr = this->GetInput(); - typename Superclass::OutputImageType * outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - const typename Superclass::InputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - - unsigned int vec_size = inputSize[this->m_Direction]; - - typedef itk::ImageLinearConstIteratorWithIndex< InputImageType > InputIteratorType; - typedef itk::ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegion ); - OutputIteratorType outputIt( outputPtr, outputRegion ); - - inputIt.SetDirection(this->m_Direction); - outputIt.SetDirection(this->m_Direction); - - typedef typename TOutputImage::PixelType OutputPixelType; - vnl_vector< vcl_complex< OutputPixelType > > inputBuffer( vec_size ); - typename vnl_vector< vcl_complex< OutputPixelType > >::iterator inputBufferIt = inputBuffer.begin(); - // fft is done in-place - typename vnl_vector< vcl_complex< OutputPixelType > >::iterator outputBufferIt = inputBuffer.begin(); - vnl_fft_1d< OutputPixelType > v1d(vec_size); - - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - // copy the input line into our buffer - inputIt.GoToBeginOfLine(); - inputBufferIt = inputBuffer.begin(); - while( !inputIt.IsAtEndOfLine() ) - { - *inputBufferIt = inputIt.Get(); - ++inputIt; - ++inputBufferIt; - } - - // do the transform - v1d.fwd_transform(inputBuffer); - - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( (*outputBufferIt).real() / vec_size ); - ++outputIt; - ++outputBufferIt; - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.h deleted file mode 100644 index 8c8c6e2614..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.h +++ /dev/null @@ -1,85 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexToComplexImageFilter_h -#define itkVnlFFT1DComplexToComplexImageFilter_h - -#include "itkFFT1DComplexToComplexImageFilter.h" -#include - -namespace itk -{ - -/** \class VnlFFT1DComplexToComplexImageFilter - * - * \brief Perform the FFT along one dimension of an image using Vnl as a - * backend. - * - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage > -class VnlFFT1DComplexToComplexImageFilter: - public FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef VnlFFT1DComplexToComplexImageFilter Self; - typedef FFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - typedef typename Superclass::TransformDirectionType TransformDirectionType; - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Run-time type information (and related methods). */ - itkTypeMacro( VnlFFT1DComplexToComplexImageFilter, FFT1DComplexToComplexImageFilter ); - -protected: - VnlFFT1DComplexToComplexImageFilter() {} - virtual ~VnlFFT1DComplexToComplexImageFilter() {} - - virtual void ThreadedGenerateData( const OutputImageRegionType&, ThreadIdType threadID ) ITK_OVERRIDE; - -private: - VnlFFT1DComplexToComplexImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkVnlFFT1DComplexToComplexImageFilter.hxx" -#endif - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.hxx deleted file mode 100644 index 3ab41c2caa..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DComplexToComplexImageFilter.hxx +++ /dev/null @@ -1,127 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DComplexToComplexImageFilter_hxx -#define itkVnlFFT1DComplexToComplexImageFilter_hxx - -#include "itkVnlFFT1DComplexToComplexImageFilter.h" - -#include "itkFFT1DComplexToComplexImageFilter.hxx" -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkIndent.h" -#include "itkMetaDataObject.h" -#include "itkExceptionObject.h" -#include "vnl/algo/vnl_fft_base.h" -#include "vnl/algo/vnl_fft_1d.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -void -VnlFFT1DComplexToComplexImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegion, ThreadIdType itkNotUsed( threadID ) ) -{ - // get pointers to the input and output - const typename Superclass::InputImageType * inputPtr = this->GetInput(); - typename Superclass::OutputImageType * outputPtr = this->GetOutput(); - - if ( !inputPtr || !outputPtr ) - { - return; - } - - const typename Superclass::InputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - - const unsigned int direction = this->GetDirection(); - const unsigned int vectorSize = inputSize[direction]; - - typedef itk::ImageLinearConstIteratorWithIndex< InputImageType > InputIteratorType; - typedef itk::ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegion ); - OutputIteratorType outputIt( outputPtr, outputRegion ); - - inputIt.SetDirection( direction ); - outputIt.SetDirection( direction ); - - typedef typename TInputImage::PixelType PixelType; - typedef vnl_vector< PixelType > VNLVectorType; - VNLVectorType inputBuffer( vectorSize ); - typename VNLVectorType::iterator inputBufferIt = inputBuffer.begin(); - // fft is done in-place - typename VNLVectorType::iterator outputBufferIt = inputBuffer.begin(); - vnl_fft_1d< typename NumericTraits< PixelType >::ValueType > v1d(vectorSize); - - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - // copy the input line into our buffer - inputIt.GoToBeginOfLine(); - inputBufferIt = inputBuffer.begin(); - while( !inputIt.IsAtEndOfLine() ) - { - *inputBufferIt = inputIt.Get(); - ++inputIt; - ++inputBufferIt; - } - - // do the transform - if( this->m_TransformDirection == Superclass::DIRECT ) - { - v1d.bwd_transform(inputBuffer); - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( *outputBufferIt ); - ++outputIt; - ++outputBufferIt; - } - } - else // m_TransformDirection == INVERSE - { - v1d.fwd_transform(inputBuffer); - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( (*outputBufferIt) / static_cast< PixelType >( vectorSize )); - ++outputIt; - ++outputBufferIt; - } - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.h b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.h deleted file mode 100644 index 679b4b5bae..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.h +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_h -#define itkVnlFFT1DRealToComplexConjugateImageFilter_h - -#include "itkFFT1DRealToComplexConjugateImageFilter.h" -#include - -namespace itk -{ - -/** \class VnlFFT1DRealToComplexConjugateImageFilter - * - * \brief Perform the FFT along one dimension of an image using Vnl as a - * backend. - * - * \ingroup Ultrasound - */ -template< typename TInputImage, typename TOutputImage=Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > -class VnlFFT1DRealToComplexConjugateImageFilter : - public FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -{ -public: - /** Standard class typedefs. */ - typedef VnlFFT1DRealToComplexConjugateImageFilter Self; - typedef FFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - typedef typename Superclass::InputImageType InputImageType; - typedef typename Superclass::OutputImageType OutputImageType; - typedef typename OutputImageType::RegionType OutputImageRegionType; - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Run-time type information (and related methods). */ - itkTypeMacro( VnlFFT1DRealToComplexConjugateImageFilter, FFT1DRealToComplexConjugateImageFilter ); - -protected: - virtual void ThreadedGenerateData( const OutputImageRegionType&, ThreadIdType threadID ) ITK_OVERRIDE; - - VnlFFT1DRealToComplexConjugateImageFilter() { } - ~VnlFFT1DRealToComplexConjugateImageFilter() { } - -private: - VnlFFT1DRealToComplexConjugateImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented -}; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.hxx" -#endif - -#endif diff --git a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.hxx b/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.hxx deleted file mode 100644 index 0d38c0d745..0000000000 --- a/Modules/US/USHardwareDiPhAS/ITKUltrasound/itkVnlFFT1DRealToComplexConjugateImageFilter.hxx +++ /dev/null @@ -1,115 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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.txt - * - * 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. - * - *=========================================================================*/ -#ifndef itkVnlFFT1DRealToComplexConjugateImageFilter_hxx -#define itkVnlFFT1DRealToComplexConjugateImageFilter_hxx - -#include "itkVnlFFT1DRealToComplexConjugateImageFilter.h" - -#include "itkFFT1DRealToComplexConjugateImageFilter.hxx" -#include "itkImageLinearConstIteratorWithIndex.h" -#include "itkImageLinearIteratorWithIndex.h" -#include "itkIndent.h" -#include "itkMetaDataObject.h" -#include "itkExceptionObject.h" -#include "itkVnlFFTCommon.h" -#include "vnl/algo/vnl_fft_base.h" -#include "vnl/algo/vnl_fft_1d.h" - -namespace itk -{ - -template< typename TInputImage, typename TOutputImage > -void -VnlFFT1DRealToComplexConjugateImageFilter< TInputImage, TOutputImage > -::ThreadedGenerateData( const OutputImageRegionType& outputRegion, ThreadIdType itkNotUsed( threadID ) ) -{ - // get pointers to the input and output - const typename Superclass::InputImageType * inputPtr = this->GetInput(); - typename Superclass::OutputImageType * outputPtr = this->GetOutput(); - - const typename Superclass::InputImageType::SizeType & inputSize = inputPtr->GetRequestedRegion().GetSize(); - - const unsigned int direction = this->GetDirection(); - unsigned int vectorSize = inputSize[direction]; - if( ! VnlFFTCommon::IsDimensionSizeLegal(vectorSize) ) - { - itkExceptionMacro("Illegal Array DIM for FFT"); - } - - - typedef ImageLinearConstIteratorWithIndex< InputImageType > InputIteratorType; - typedef ImageLinearIteratorWithIndex< OutputImageType > OutputIteratorType; - InputIteratorType inputIt( inputPtr, outputRegion ); - OutputIteratorType outputIt( outputPtr, outputRegion ); - - inputIt.SetDirection( direction ); - outputIt.SetDirection( direction ); - - typedef typename TInputImage::PixelType PixelType; - typedef vcl_complex< PixelType > ComplexType; - typedef vnl_vector< ComplexType > ComplexVectorType; - ComplexVectorType inputBuffer( vectorSize ); - typename ComplexVectorType::iterator inputBufferIt = inputBuffer.begin(); - // fft is done in-place - typename ComplexVectorType::iterator outputBufferIt = inputBuffer.begin(); - vnl_fft_1d< PixelType > v1d( vectorSize ); - - // for every fft line - for( inputIt.GoToBegin(), outputIt.GoToBegin(); - !inputIt.IsAtEnd(); - outputIt.NextLine(), inputIt.NextLine() ) - { - // copy the input line into our buffer - inputIt.GoToBeginOfLine(); - inputBufferIt = inputBuffer.begin(); - while( !inputIt.IsAtEndOfLine() ) - { - *inputBufferIt = inputIt.Value(); - ++inputIt; - ++inputBufferIt; - } - - // do the transform - v1d.bwd_transform( inputBuffer ); - - // copy the output from the buffer into our line - outputBufferIt = inputBuffer.begin(); - outputIt.GoToBeginOfLine(); - while( !outputIt.IsAtEndOfLine() ) - { - outputIt.Set( *outputBufferIt ); - ++outputIt; - ++outputBufferIt; - } - } -} - -} // end namespace itk - -#endif diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence05.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence05.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence05.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence06.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence06.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence06.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence07.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence07.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence07.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence08.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence08.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence08.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence09.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence09.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence09.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence10.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence10.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence10.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence11.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence11.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence11.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence12.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence12.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence12.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence13.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence13.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence13.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence14.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence14.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence14.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence15.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence15.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence15.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence16.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence16.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence16.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence17.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence17.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence17.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence18.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence18.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence18.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence19.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence19.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence19.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence20.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence20.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence20.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence21.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence21.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence21.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence22.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence22.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence22.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence23.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence23.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence23.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence24.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence24.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence24.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/Resources/Fluence25.nrrd b/Modules/US/USHardwareDiPhAS/Resources/Fluence25.nrrd deleted file mode 100644 index 224a89f7ff..0000000000 Binary files a/Modules/US/USHardwareDiPhAS/Resources/Fluence25.nrrd and /dev/null differ diff --git a/Modules/US/USHardwareDiPhAS/files.cmake b/Modules/US/USHardwareDiPhAS/files.cmake deleted file mode 100644 index 84d6550ddb..0000000000 --- a/Modules/US/USHardwareDiPhAS/files.cmake +++ /dev/null @@ -1,34 +0,0 @@ -SET(CPP_FILES -mitkUSDiPhASActivator.cpp -mitkUSDiPhASDevice.cpp -mitkUSDiPhASImageSource.cpp -mitkUSDiPhASProbe.cpp -mitkUSDiPhASProbesControls.cpp -mitkUSDiPhASCustomControls.cpp -mitkUSDiPhASBModeImageFilter.hxx -mitkUSDiPhASBModeImageFilter.h -) - -set(RESOURCE_FILES - Fluence05.nrrd - Fluence06.nrrd - Fluence07.nrrd - Fluence08.nrrd - Fluence09.nrrd - Fluence10.nrrd - Fluence11.nrrd - Fluence12.nrrd - Fluence13.nrrd - Fluence14.nrrd - Fluence15.nrrd - Fluence16.nrrd - Fluence17.nrrd - Fluence18.nrrd - Fluence19.nrrd - Fluence20.nrrd - Fluence21.nrrd - Fluence22.nrrd - Fluence23.nrrd - Fluence24.nrrd - Fluence25.nrrd - ) \ No newline at end of file diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASActivator.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASActivator.cpp deleted file mode 100644 index e3a7d7c8f4..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASActivator.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkUSDiPhASActivator.h" - -mitk::USDiPhASActivator::USDiPhASActivator() -{ - MITK_INFO << "USDiPhASActivator created"; -} - -mitk::USDiPhASActivator::~USDiPhASActivator() -{ -} - -void mitk::USDiPhASActivator::Load(us::ModuleContext* context) -{ - // create a new device - m_Device = mitk::USDiPhASDevice::New("DiPhAS", "Ultrasound System"); - m_Device->Initialize(); -} - -void mitk::USDiPhASActivator::Unload(us::ModuleContext* context) -{ - // set smart pointer to null (device will be unregistered from - // micro service in it's destrcutor) - m_Device = 0; -} diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASActivator.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASActivator.h deleted file mode 100644 index 172e6656b8..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASActivator.h +++ /dev/null @@ -1,49 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef __mitkUSDiPhASActivator_h -#define __mitkUSDiPhASActivator_h - -#include "mitkUSDiPhASDevice.h" - -// Microservices -#include -#include - -namespace mitk -{ - class USDiPhASActivator : public us::ModuleActivator { - public: - - USDiPhASActivator(); - virtual ~USDiPhASActivator(); - - /** - * \brief DiPhAS device is created and initialized on module load. - * Service registration is done during the initialization process. - */ - void Load(us::ModuleContext* context); - - /** - * \brief Device pointer is removed on module unload. - * Service deregistration is done in the device destructor. - */ - void Unload(us::ModuleContext* context); - - protected: - USDiPhASDevice::Pointer m_Device; - }; -} // namespace mitk - -US_EXPORT_MODULE_ACTIVATOR(mitk::USDiPhASActivator) - -#endif // __mitkUSDiPhASActivator_h diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASBModeImageFilter.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASBModeImageFilter.h deleted file mode 100644 index ba7eb074e3..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASBModeImageFilter.h +++ /dev/null @@ -1,143 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= -* -* Copyright Insight Software Consortium -* -* 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.txt -* -* 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. -* -*=========================================================================*/ -#ifndef itkPhotoacousticBModeImageFilter_h -#define itkPhotoacousticBModeImageFilter_h - -#include "itkComplexToModulusImageFilter.h" -#include "itkConstantPadImageFilter.h" -#include "itkImageToImageFilter.h" -#include "itkImage.h" - -#include "ITKUltrasound/itkRegionFromReferenceImageFilter.h" -#include "ITKUltrasound/itkAnalyticSignalImageFilter.h" - -namespace itk -{ - - /** - * \class PhotoacousticBModeImageFilter - * - * \brief Create an Photoacoustic B-Mode (Brightness-Mode) image from raw - * "RF" data. The RF's envelope is calculated from the analytic signal and - * logarithmic intensity transform is NOT applied. This is for now the only - * difference to the "normal" BModeImageFilter. - * - * Use SetDirection() to define the axis of propagation. - * - */ - template < typename TInputImage, typename TOutputImage = TInputImage, typename TComplexImage = Image< std::complex< typename TInputImage::PixelType >, TInputImage::ImageDimension > > - class PhotoacousticBModeImageFilter : - public ImageToImageFilter< TInputImage, TOutputImage > - { - public: - /** Standard class typedefs. */ - typedef PhotoacousticBModeImageFilter Self; - typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; - typedef SmartPointer< Self > Pointer; - typedef SmartPointer< const Self > ConstPointer; - - /** The type of input image. */ - typedef TInputImage InputImageType; - - /** Dimension of the input and output images. */ - itkStaticConstMacro(ImageDimension, unsigned int, - TInputImage::ImageDimension); - - /** Typedef support for the input image scalar value type. */ - typedef typename InputImageType::PixelType InputPixelType; - - /** The type of output image. */ - typedef TOutputImage OutputImageType; - - /** Typedef support for the output image scalar value type. */ - typedef typename OutputImageType::PixelType OutputPixelType; - - /** Typedef of the image used for internal computations that has - * std::complex pixels. */ - typedef TComplexImage ComplexImageType; - - /** Other convenient typedefs */ - typedef typename InputImageType::RegionType InputRegionType; - typedef typename InputImageType::SizeType InputSizeType; - typedef typename InputImageType::IndexType InputIndexType; - - /** Run-time type information (and related methods) */ - itkTypeMacro(PhotoacousticBModeImageFilter, ImageToImageFilter); - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Set the direction in which the envelope is to be calculated. */ - virtual void SetDirection(unsigned int direction) - { - this->m_AnalyticFilter->SetDirection(direction); - this->Modified(); - } - - /** Get the direction in which the envelope is to be calculated. */ - virtual unsigned int GetDirection() const - { - return m_AnalyticFilter->GetDirection(); - } - - protected: - PhotoacousticBModeImageFilter(); - ~PhotoacousticBModeImageFilter() {} - - virtual void PrintSelf(std::ostream& os, Indent indent) const ITK_OVERRIDE; - - virtual void GenerateData() ITK_OVERRIDE; - - // These behave like their analogs in FFT1DRealToComplexConjugateImageFilter. - virtual void GenerateInputRequestedRegion() ITK_OVERRIDE; - virtual void EnlargeOutputRequestedRegion(DataObject *output) ITK_OVERRIDE; - - /** Component filters. */ - typedef AnalyticSignalImageFilter< InputImageType, ComplexImageType > AnalyticType; - typedef ComplexToModulusImageFilter< typename AnalyticType::OutputImageType, OutputImageType > ComplexToModulusType; - typedef ConstantPadImageFilter< InputImageType, InputImageType > PadType; - typedef RegionFromReferenceImageFilter< OutputImageType, OutputImageType > ROIType; - - private: - PhotoacousticBModeImageFilter(const Self&); // purposely not implemented - void operator=(const Self&); // purposely not implemented - - typename AnalyticType::Pointer m_AnalyticFilter; - typename ComplexToModulusType::Pointer m_ComplexToModulusFilter; - typename PadType::Pointer m_PadFilter; - typename ROIType::Pointer m_ROIFilter; - }; - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "mitkUSDiPhASBModeImageFilter.hxx" -#endif - -#endif // itkPhotoacousticBModeImageFilter_h diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASBModeImageFilter.hxx b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASBModeImageFilter.hxx deleted file mode 100644 index 4b34a1ae0e..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASBModeImageFilter.hxx +++ /dev/null @@ -1,203 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -/*========================================================================= -* -* Copyright Insight Software Consortium -* -* 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.txt -* -* 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. -* -*=========================================================================*/ -#ifndef itkPhotoacousticBModeImageFilter_hxx -#define itkPhotoacousticBModeImageFilter_hxx - -#include "mitkUSDiPhASBModeImageFilter.h" - -#include "itkMetaDataDictionary.h" - -#include -#include -#include - -namespace itk -{ - - template < typename TInputImage, typename TOutputImage, typename TComplexImage > - PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > - ::PhotoacousticBModeImageFilter() - { - m_AnalyticFilter = AnalyticType::New(); - m_ComplexToModulusFilter = ComplexToModulusType::New(); - m_PadFilter = PadType::New(); - m_ROIFilter = ROIType::New(); - - m_PadFilter->SetConstant(0.); - m_ComplexToModulusFilter->SetInput(m_AnalyticFilter->GetOutput()); - m_ROIFilter->SetInput(m_ComplexToModulusFilter->GetOutput()); - } - - - template < typename TInputImage, typename TOutputImage, typename TComplexImage > - void - PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > - ::PrintSelf(std::ostream& os, Indent indent) const - { - Superclass::PrintSelf(os, indent); - } - - - template < typename TInputImage, typename TOutputImage, typename TComplexImage > - void - PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > - ::GenerateInputRequestedRegion() - { - // call the superclass' implementation of this method - Superclass::GenerateInputRequestedRegion(); - - // get pointers to the inputs - InputImageType * inputPtr = const_cast (this->GetInput()); - OutputImageType * outputPtr = this->GetOutput(); - - // we need to compute the input requested region (size and start index) - typedef const typename OutputImageType::SizeType& OutputSizeType; - OutputSizeType outputRequestedRegionSize = - outputPtr->GetRequestedRegion().GetSize(); - typedef const typename OutputImageType::IndexType& OutputIndexType; - OutputIndexType outputRequestedRegionStartIndex = - outputPtr->GetRequestedRegion().GetIndex(); - - //// the regions other than the fft direction are fine - typename InputImageType::SizeType inputRequestedRegionSize = outputRequestedRegionSize; - typename InputImageType::IndexType inputRequestedRegionStartIndex = outputRequestedRegionStartIndex; - - // we but need all of the input in the fft direction - const unsigned int direction = this->GetDirection(); - const typename InputImageType::SizeType& inputLargeSize = - inputPtr->GetLargestPossibleRegion().GetSize(); - inputRequestedRegionSize[direction] = inputLargeSize[direction]; - const typename InputImageType::IndexType& inputLargeIndex = - inputPtr->GetLargestPossibleRegion().GetIndex(); - inputRequestedRegionStartIndex[direction] = inputLargeIndex[direction]; - - typename InputImageType::RegionType inputRequestedRegion; - inputRequestedRegion.SetSize(inputRequestedRegionSize); - inputRequestedRegion.SetIndex(inputRequestedRegionStartIndex); - - inputPtr->SetRequestedRegion(inputRequestedRegion); - } - - - template < typename TInputImage, typename TOutputImage, typename TComplexImage > - void - PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > - ::EnlargeOutputRequestedRegion(DataObject *output) - { - OutputImageType* outputPtr = dynamic_cast< OutputImageType* >(output); - - // we need to enlarge the region in the fft direction to the - // largest possible in that direction - typedef const typename OutputImageType::SizeType& ConstOutputSizeType; - ConstOutputSizeType requestedSize = - outputPtr->GetRequestedRegion().GetSize(); - ConstOutputSizeType outputLargeSize = - outputPtr->GetLargestPossibleRegion().GetSize(); - typedef const typename OutputImageType::IndexType& ConstOutputIndexType; - ConstOutputIndexType requestedIndex = - outputPtr->GetRequestedRegion().GetIndex(); - ConstOutputIndexType outputLargeIndex = - outputPtr->GetLargestPossibleRegion().GetIndex(); - - typename OutputImageType::SizeType enlargedSize = requestedSize; - typename OutputImageType::IndexType enlargedIndex = requestedIndex; - const unsigned int direction = this->GetDirection(); - enlargedSize[direction] = outputLargeSize[direction]; - enlargedIndex[direction] = outputLargeIndex[direction]; - - typename OutputImageType::RegionType enlargedRegion; - enlargedRegion.SetSize(enlargedSize); - enlargedRegion.SetIndex(enlargedIndex); - outputPtr->SetRequestedRegion(enlargedRegion); - } - - - template < typename TInputImage, typename TOutputImage, typename TComplexImage > - void - PhotoacousticBModeImageFilter< TInputImage, TOutputImage, TComplexImage > - ::GenerateData() - { - this->AllocateOutputs(); - - const InputImageType * inputPtr = this->GetInput(); - OutputImageType * outputPtr = this->GetOutput(); - - const unsigned int direction = m_AnalyticFilter->GetDirection(); - typename InputImageType::SizeType size = inputPtr->GetLargestPossibleRegion().GetSize(); - - // Zero padding. FFT direction should be factorable by 2 for all FFT - // implementations to work. - unsigned int n = size[direction]; - while (n % 2 == 0) - { - n /= 2; - } - bool doPadding; - if (n == 1) - { - doPadding = false; - } - else - { - doPadding = true; - } - if (doPadding) - { - n = size[direction]; - unsigned int newSizeDirection = 1; - while (newSizeDirection < n) - { - newSizeDirection *= 2; - } - typename InputImageType::SizeType padSize; - padSize.Fill(0); - padSize[direction] = newSizeDirection - size[direction]; - size[direction] = newSizeDirection; - m_PadFilter->SetPadUpperBound(padSize); - m_PadFilter->SetInput(inputPtr); - m_AnalyticFilter->SetInput(m_PadFilter->GetOutput()); - m_ROIFilter->SetReferenceImage(inputPtr); - m_ROIFilter->SetInput(m_ComplexToModulusFilter->GetOutput()); - m_ROIFilter->GraftOutput(outputPtr); - m_ROIFilter->Update(); - this->GraftOutput(m_ROIFilter->GetOutput()); - } - else // padding is not required - { - m_AnalyticFilter->SetInput(inputPtr); - m_ComplexToModulusFilter->GraftOutput(outputPtr); - m_ComplexToModulusFilter->Update(); - this->GraftOutput(m_ComplexToModulusFilter->GetOutput()); - } - - } - -} // end namespace itk - -#endif diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASCustomControls.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASCustomControls.cpp deleted file mode 100644 index 824a71f279..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASCustomControls.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkUSDiPhASCustomControls.h" -#include - -mitk::USDiPhASCustomControls::USDiPhASCustomControls(USDiPhASDevice* device) - : mitk::USDiPhASDeviceCustomControls(device), m_IsActive(false), m_device(device), currentBeamformingAlgorithm((int)Beamforming::PlaneWaveCompound) -{ -} - -mitk::USDiPhASCustomControls::~USDiPhASCustomControls() -{ -} - -void mitk::USDiPhASCustomControls::SetIsActive(bool isActive) -{ - m_IsActive = isActive; -} - -bool mitk::USDiPhASCustomControls::GetIsActive() -{ - return m_IsActive; -} - -void mitk::USDiPhASCustomControls::passGUIOut(std::function callback) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - callback("initializing"); - imageSource->SetGUIOutput(callback); -} - -// OnSet methods - -void mitk::USDiPhASCustomControls::OnSetCompensateEnergy(bool compensate) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - imageSource->ModifyEnergyCompensation(compensate); -} - -void mitk::USDiPhASCustomControls::OnSetUseBModeFilter(bool isSet) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - imageSource->ModifyUseBModeFilter(isSet); -} - -void mitk::USDiPhASCustomControls::OnSetRecord(bool record) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - imageSource->SetRecordingStatus(record); -} - -void mitk::USDiPhASCustomControls::OnSetVerticalSpacing(float mm) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - imageSource->SetVerticalSpacing(mm); -} - -void mitk::USDiPhASCustomControls::OnSetScatteringCoefficient(float coeff) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - imageSource->ModifyScatteringCoefficient(coeff); -} - -void mitk::USDiPhASCustomControls::OnSetCompensateScattering(bool compensate) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - imageSource->ModifyCompensateForScattering(compensate); -} - -void mitk::USDiPhASCustomControls::OnSetSavingSettings(SavingSettings settings) -{ - mitk::USDiPhASImageSource* imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - imageSource->SetSavingSettings(settings); -} - -//Transmit -void mitk::USDiPhASCustomControls::OnSetTransmitPhaseLength(double us) -{ - m_device->GetScanMode().transmitPhaseLengthSeconds = us/1000000; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetExcitationFrequency(double MHz) -{ - m_device->SetBursts(round(((120 / MHz) - 2) / 2)); - m_device->UpdateScanmode(); - // b = (c/f - 2) * 1/2, where c is the internal clock, f the wanted frequency, b the burst count -} - -void mitk::USDiPhASCustomControls::OnSetTransmitEvents(int events) -{ - m_device->GetScanMode().transmitEventsCount = events; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetVoltage(int voltage) -{ - m_device->GetScanMode().voltageV = voltage; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetMode(bool interleaved) -{ - m_device->SetInterleaved(interleaved); - m_device->UpdateScanmode(); -} - -//Receive -void mitk::USDiPhASCustomControls::OnSetScanDepth(double mm) -{ - auto& scanMode = m_device->GetScanMode(); - float time = 2 * (0.001 * (mm)) / scanMode.averageSpeedOfSound; - float timeInMicroSeconds = floor(time *1e6); // this is necessary because sub-microsecond accuracy causes undefined behaviour - m_device->GetScanMode().receivePhaseLengthSeconds = timeInMicroSeconds*1e-6; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetAveragingCount(int count) -{ - m_device->GetScanMode().averagingCount = count; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetTGCMin(int min) -{ - auto& scanMode = m_device->GetScanMode(); - char range = scanMode.tgcdB[7] - min; - for (int tgc = 0; tgc < 7; ++tgc) - scanMode.tgcdB[tgc] = round(tgc*range / 7 + min); - - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetTGCMax(int max) -{ - auto& scanMode = m_device->GetScanMode(); - char range = max - scanMode.tgcdB[0]; - for (int tgc = 1; tgc < 8; ++tgc) - scanMode.tgcdB[tgc] = round(tgc*range / 7 + scanMode.tgcdB[0]); - - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetDataType(DataType type) -{ - auto& scanMode = m_device->GetScanMode(); - auto imageSource = dynamic_cast(m_device->GetUSImageSource().GetPointer()); - switch (type) { - case DataType::Image_uChar : { - scanMode.transferBeamformedData = false; - scanMode.transferImageData = true; - m_device->UpdateScanmode(); - imageSource->ModifyDataType(DataType::Image_uChar); - break; - } - case DataType::Beamformed_Short : { - scanMode.transferBeamformedData = true; - scanMode.transferImageData = false; - m_device->UpdateScanmode(); - imageSource->ModifyDataType(DataType::Beamformed_Short); - break; - } - - default: - MITK_INFO << "Unknown Data Type requested"; - break; - } -} -// 0= image; 1= beamformed - -//Beamforming -void mitk::USDiPhASCustomControls::OnSetPitch(double mm) -{ - m_device->GetScanMode().reconstructedLinePitchMmOrAngleDegree = mm; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetReconstructedSamples(int samples) -{ - m_device->GetScanMode().reconstructionSamplesPerLine = samples; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetReconstructedLines(int lines) -{ - m_device->GetScanMode().reconstructionLines = lines; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetSpeedOfSound(int mps) -{ - m_device->GetScanMode().averageSpeedOfSound = mps; - m_device->SetInterleaved(m_device->IsInterleaved()); //update transmit parameters - m_device->UpdateScanmode(); -} - -//Bandpass -void mitk::USDiPhASCustomControls::OnSetBandpassEnabled(bool bandpass) -{ - m_device->GetScanMode().bandpassApply = bandpass; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetLowCut(double MHz) -{ - m_device->GetScanMode().bandpassFrequencyLowHz = MHz*1000*1000; - m_device->UpdateScanmode(); -} - -void mitk::USDiPhASCustomControls::OnSetHighCut(double MHz) -{ - m_device->GetScanMode().bandpassFrequencyHighHz = MHz*1000*1000; - m_device->UpdateScanmode(); -} diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASCustomControls.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASCustomControls.h deleted file mode 100644 index e58f8ea3d8..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASCustomControls.h +++ /dev/null @@ -1,102 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKUSDiPhASCustomControls_H_HEADER_INCLUDED_ -#define MITKUSDiPhASCustomControls_H_HEADER_INCLUDED_ - -#include "mitkUSDiPhASDeviceCustomControls.h" -#include "mitkUSDevice.h" -#include "mitkUSDiPhASDevice.h" -#include "Framework.IBMT.US.CWrapper.h" - -#include - -namespace mitk { -/** - * \brief Custom controls for mitk::USDiPhASDevice. - */ -class USDiPhASDevice; -class USDiPhASCustomControls : public USDiPhASDeviceCustomControls -{ -public: - mitkClassMacro(USDiPhASCustomControls, USAbstractControlInterface); - mitkNewMacro1Param(Self, mitk::USDiPhASDevice*); - - typedef USDiPhASDeviceCustomControls::DataType DataType; - typedef USDiPhASDeviceCustomControls::SavingSettings SavingSettings; - /** - * Activate or deactivate the custom controls. This is just for handling - * widget visibility in a GUI for example. - */ - virtual void SetIsActive( bool isActive ) override; - - /** - * \return if this custom controls are currently activated - */ - virtual bool GetIsActive( ) override; - - virtual void passGUIOut(std::function callback) override; - - BeamformingParametersPlaneWaveCompound parametersPW; - BeamformingParametersInterleaved_OA_US parametersOSUS; - -protected: - /** - * Class needs an mitk::USDiPhASDevice object for beeing constructed. - * This object's ScanMode will be manipulated by the custom controls methods. - */ - USDiPhASCustomControls(USDiPhASDevice* device); - virtual ~USDiPhASCustomControls( ); - - bool m_IsActive; - USImageVideoSource::Pointer m_ImageSource; - USDiPhASDevice* m_device; - int currentBeamformingAlgorithm; - - /** handlers for value changes - */ - virtual void OnSetCompensateEnergy(bool compensate) override; - virtual void OnSetUseBModeFilter(bool isSet) override; - virtual void OnSetRecord(bool record) override; - virtual void OnSetVerticalSpacing(float mm) override; - virtual void OnSetScatteringCoefficient(float coeff) override; - virtual void OnSetCompensateScattering(bool compensate) override; - virtual void OnSetSavingSettings(SavingSettings settings) override; - - //Transmit - virtual void OnSetTransmitPhaseLength(double us) override; - virtual void OnSetExcitationFrequency(double MHz) override; - virtual void OnSetTransmitEvents(int events) override; - virtual void OnSetVoltage(int voltage) override; - virtual void OnSetMode(bool interleaved) override; - - //Receive - virtual void OnSetScanDepth(double mm) override; - virtual void OnSetAveragingCount(int count) override; - virtual void OnSetTGCMin(int min) override; - virtual void OnSetTGCMax(int max) override; - virtual void OnSetDataType(DataType type) override; - - //Beamforming - virtual void OnSetPitch(double mm) override; - virtual void OnSetReconstructedSamples(int samples) override; - virtual void OnSetReconstructedLines(int lines) override; - virtual void OnSetSpeedOfSound(int mps) override; - - //Bandpass - virtual void OnSetBandpassEnabled(bool bandpass) override; - virtual void OnSetLowCut(double MHz) override; - virtual void OnSetHighCut(double MHz) override; -}; -} // namespace mitk - -#endif // MITKUSDiPhASCustomControls_H_HEADER_INCLUDED_ diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.cpp deleted file mode 100644 index e5edeadebe..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkUSDiPhASDevice.h" -#include "mitkUSDiPhASCustomControls.h" - -mitk::USDiPhASDevice::USDiPhASDevice(std::string manufacturer, std::string model) - : mitk::USDevice(manufacturer, model), m_ControlsProbes(mitk::USDiPhASProbesControls::New(this)), - m_ImageSource(mitk::USDiPhASImageSource::New(this)), - m_ControlInterfaceCustom(mitk::USDiPhASCustomControls::New(this)), - m_IsRunning(false), - m_BurstHalfwaveClockCount(7), - m_Interleaved(true) -{ - m_NumberOfOutputs = 2; - this->SetNumberOfIndexedOutputs(m_NumberOfOutputs); - - SetNthOutput(0, this->MakeOutput(0)); - SetNthOutput(1, this->MakeOutput(1)); -} - -mitk::USDiPhASDevice::~USDiPhASDevice() -{ -} - -//Gets - -std::string mitk::USDiPhASDevice::GetDeviceClass() -{ - return "org.mitk.modules.us.USDiPhASDevice"; -} - -mitk::USControlInterfaceProbes::Pointer mitk::USDiPhASDevice::GetControlInterfaceProbes() -{ - return m_ControlsProbes.GetPointer(); -}; - -mitk::USAbstractControlInterface::Pointer mitk::USDiPhASDevice::GetControlInterfaceCustom() -{ - return m_ControlInterfaceCustom.GetPointer(); -} - -mitk::USImageSource::Pointer mitk::USDiPhASDevice::GetUSImageSource() -{ - return m_ImageSource.GetPointer(); -} - -ScanModeNative& mitk::USDiPhASDevice::GetScanMode() -{ - return m_ScanMode; -} - -// Setup and Cleanup - -bool mitk::USDiPhASDevice::OnInitialization() -{ - return true; -} - -//---------------------------------------------------------------------------------------------------------------------------- -/* ugly wrapper stuff - find better solution so it isn't necessary to create a global pointer to USDiPhASDevice... - * passing a lambda function would be nicer - sadly something goes wrong when passing the adress of a lambda function: - * the API produces access violations. Passing the Lambda function itself would be preferable, but that's not possible -*/ - -mitk::USDiPhASDevice* w_device; -mitk::USDiPhASImageSource* w_ISource; - -void WrapperMessageCallback(const char* message) -{ - w_device->MessageCallback(message); -} - -void WrapperImageDataCallback( - short* rfDataChannelData, int channelDatalinesPerDataset, int channelDataSamplesPerChannel, int channelDataTotalDatasets, - short* rfDataArrayBeamformed, int beamformedLines, int beamformedSamples, int beamformedTotalDatasets, - unsigned char* imageData, int imageWidth, int imageHeight, int imagePixelFormat, int imageSetsTotal, double timeStamp) -{ - w_ISource->ImageDataCallback( - rfDataChannelData, channelDatalinesPerDataset, channelDataSamplesPerChannel, channelDataTotalDatasets, - rfDataArrayBeamformed, beamformedLines, beamformedSamples, beamformedTotalDatasets, - imageData, imageWidth, imageHeight, imagePixelFormat, imageSetsTotal, timeStamp); -} - -//---------------------------------------------------------------------------------------------------------------------------- - -bool mitk::USDiPhASDevice::OnConnection() -{ - w_device = this; - w_ISource = m_ImageSource; - // Need those pointers for the forwarders to call member functions; createBeamformer expects non-member function pointers. - createBeamformer((StringMessageCallback)&WrapperMessageCallback, (NewDataCallback)&WrapperImageDataCallback); - - InitializeScanMode(); - initBeamformer(); //start the hardware connection - - m_ImageSource->UpdateImageGeometry(); //make sure the image geometry is initialized! - // pass the new scanmode to the device: - setupScan(this->m_ScanMode); - return true; -} - -bool mitk::USDiPhASDevice::OnDisconnection() -{ - //close the beamformer so hardware is disconnected - closeBeamformer(); - return true; -} - -bool mitk::USDiPhASDevice::OnActivation() -{ - // probe controls are available now - m_ControlsProbes->SetIsActive(true); - - if (m_ControlsProbes->GetProbesCount() < 1) - { - MITK_WARN("USDevice")("USDiPhASDevice") << "No probe found."; - return false; - } - - m_ControlsProbes->SelectProbe(0); - - // toggle the beamformer of the API - if(!m_IsRunning) - m_IsRunning=toggleFreeze(); - return true; -} - -bool mitk::USDiPhASDevice::OnDeactivation() -{ - if(m_IsRunning) - m_IsRunning=toggleFreeze(); - return true; -} - -void mitk::USDiPhASDevice::OnFreeze(bool freeze) -{ - if(m_IsRunning==freeze) - m_IsRunning=toggleFreeze(); // toggleFreeze() returns true if it starts running the beamformer, otherwise false -} - -void mitk::USDiPhASDevice::UpdateScanmode() -{ - OnFreeze(true); - SetInterleaved(m_Interleaved); // update the beamforming parameters... - UpdateTransmitEvents(); - - if (!(dynamic_cast(this->m_ControlInterfaceCustom.GetPointer())->GetSilentUpdate())) - { - setupScan(this->m_ScanMode); - m_ImageSource->UpdateImageGeometry(); - } - - OnFreeze(false); -} - -void mitk::USDiPhASDevice::UpdateTransmitEvents() -{ - int numChannels = m_ScanMode.reconstructionLines; - - // transmitEventsCount defines only the number of acoustic measurements (angles); there will be one event added to the start for OA measurement - m_ScanMode.TransmitEvents = new TransmitEventNative[m_ScanMode.transmitEventsCount]; - - for (int ev = 0; ev < m_ScanMode.transmitEventsCount; ++ev) - { - m_ScanMode.TransmitEvents[ev].transmitEventDelays = new float[numChannels]; - m_ScanMode.TransmitEvents[ev].BurstHalfwaveClockCountPerChannel = new int[numChannels]; - m_ScanMode.TransmitEvents[ev].BurstCountPerChannel = new int[numChannels]; - m_ScanMode.TransmitEvents[ev].BurstUseNegativePolarityPerChannel = new bool[numChannels]; - m_ScanMode.TransmitEvents[ev].ChannelMultiplexerSetups = nullptr; - float tiltStrength = ((m_ScanMode.transmitEventsCount - 1) / 2 - ev) * 20e-9f; - - for (int i = 0; i < numChannels; ++i) - { - m_ScanMode.TransmitEvents[ev].BurstHalfwaveClockCountPerChannel[i] = m_BurstHalfwaveClockCount; // 120 MHz / (2 * (predefinedBurstHalfwaveClockCount + 1)) --> 7.5 MHz - m_ScanMode.TransmitEvents[ev].BurstCountPerChannel[i] = 1; // Burst with 1 cycle - m_ScanMode.TransmitEvents[ev].BurstUseNegativePolarityPerChannel[i] = true; - m_ScanMode.TransmitEvents[ev].transmitEventDelays[i] = 2e-6f + (i - numChannels / 2) * tiltStrength; - } - } - - m_ScanMode.transmitSequenceCount = 1; - m_ScanMode.transmitSequences = new SequenceNative[m_ScanMode.transmitSequenceCount]; - m_ScanMode.transmitSequences[0].startEvent = 0; - m_ScanMode.transmitSequences[0].endEvent = m_ScanMode.transmitEventsCount; -} - - - -void mitk::USDiPhASDevice::InitializeScanMode() -{ - // create a scanmode to be used for measurements: - m_ScanMode.scanModeName = "InterleavedMode"; - - // configure a linear transducer - m_ScanMode.transducerName = "L5-10"; - m_ScanMode.transducerCurvedRadiusMeter = 0; - m_ScanMode.transducerElementCount = 128; - m_ScanMode.transducerFrequencyHz = 7500000; - m_ScanMode.transducerPitchMeter = 0.0003f; - m_ScanMode.transducerType = 1; - - // configure the receive paramters: - m_ScanMode.receivePhaseLengthSeconds = 185e-6f; // about 15 cm imaging depth - m_ScanMode.tgcdB = new unsigned char[8]; - for (int tgc = 0; tgc < 8; ++tgc) - m_ScanMode.tgcdB[tgc] = tgc * 2 + 10; - m_ScanMode.accumulation = 1; - m_ScanMode.bandpassApply = false; - m_ScanMode.averagingCount = 1; - - // configure general processing: - m_ScanMode.transferChannelData = true; - - // configure reconstruction processing: - m_ScanMode.averageSpeedOfSound = 1540; - m_ScanMode.computeBeamforming = true; - - // setup beamforming parameters: - SetInterleaved(true); - - m_ScanMode.reconstructedLinePitchMmOrAngleDegree = 0.3f; - m_ScanMode.reconstructionLines = 128; - m_ScanMode.reconstructionSamplesPerLine = 2048; - m_ScanMode.transferBeamformedData = true; - - // configure the transmit sequence(s): - m_ScanMode.transmitEventsCount = 1; - m_ScanMode.transmitPhaseLengthSeconds = 1e-6f; - m_ScanMode.voltageV = 75; - UpdateTransmitEvents(); - - // configure bandpass: - m_ScanMode.bandpassApply = false; - m_ScanMode.bandpassFrequencyLowHz = 1e6f; - m_ScanMode.bandpassFrequencyHighHz = 20e6f; - - // configure image generation: - m_ScanMode.imageWidth = 512; - m_ScanMode.imageHeight = 512; - m_ScanMode.imageMultiplier = 1; - m_ScanMode.imageLeveling = 0; - m_ScanMode.transferImageData = false; - - // Trigger setup: - m_ScanMode.triggerSetup.enabled = true; - m_ScanMode.triggerSetup.constantPulseRepetitionRateHz = 20; - m_ScanMode.triggerSetup.triggerWidthMicroseconds = 15; - m_ScanMode.triggerSetup.delayTrigger2Microseconds = 300; -} - -// callback for the DiPhAS API - -void mitk::USDiPhASDevice::MessageCallback(const char* message) -{ - MITK_INFO << "DiPhAS API: " << message << '\n'; -} - -void mitk::USDiPhASDevice::SetBursts(int bursts) -{ - m_BurstHalfwaveClockCount = bursts; -} - -bool mitk::USDiPhASDevice::IsInterleaved() -{ - return m_Interleaved; -} - -void mitk::USDiPhASDevice::SetInterleaved(bool interleaved) -{ - m_Interleaved = interleaved; - if (interleaved) { - m_ScanMode.scanModeName = "Interleaved Beamforming Mode"; - m_CurrentBeamformingAlgorithm = Beamforming::Interleaved_OA_US; - - paramsInterleaved.SpeedOfSoundMeterPerSecond = m_ScanMode.averageSpeedOfSound; - paramsInterleaved.angleSkipFactor = 1; - paramsInterleaved.OptoacousticDelay = 0.0000003; // 300ns - paramsInterleaved.filter = Filter::None; - - m_ScanMode.beamformingAlgorithmParameters = ¶msInterleaved; - } - else { - m_ScanMode.scanModeName = "Plane Wave Beamforming Mode"; - m_CurrentBeamformingAlgorithm = Beamforming::PlaneWaveCompound; - - paramsPlaneWave.SpeedOfSoundMeterPerSecond = m_ScanMode.averageSpeedOfSound; - paramsPlaneWave.angleSkipFactor = 0; - paramsPlaneWave.usePhaseCoherence = 0; - - m_ScanMode.beamformingAlgorithmParameters = ¶msPlaneWave; - } - m_ScanMode.beamformingAlgorithm = m_CurrentBeamformingAlgorithm; -} diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.h deleted file mode 100644 index 1e97950225..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASDevice.h +++ /dev/null @@ -1,169 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKUSDiPhASDevice_H_HEADER_INCLUDED_ -#define MITKUSDiPhASDevice_H_HEADER_INCLUDED_ - -#include -#include "mitkUSDiPhASImageSource.h" -#include "mitkUSDevice.h" -#include "mitkUSDiPhASProbesControls.h" -#include "mitkUSDiPhASImageSource.h" -#include "mitkUSDiPhASCustomControls.h" - -#include "Framework.IBMT.US.CWrapper.h" - -#include -#include -#include -#include -#include - -#include - - -namespace mitk { - /** - * \brief Implementation of mitk::USDevice for DiPhAS API devices. - * Connects to a DiPhAS API device through its COM library interface. - * - * This class handles all API communications and creates interfaces for - * b mode, doppler and probes controls. - * Images given by the device are put into an object of - * mitk::USDiPhASImageSource. - */ - class USDiPhASImageSource; - - class USDiPhASDevice : public USDevice - { - public: - mitkClassMacro(USDiPhASDevice, mitk::USDevice); - mitkNewMacro2Param(Self, std::string, std::string); - - /** - * \brief Returns the class of the device. - */ - virtual std::string GetDeviceClass(); - - virtual USControlInterfaceProbes::Pointer GetControlInterfaceProbes(); - virtual itk::SmartPointer GetControlInterfaceCustom(); - - /** - * \brief Is called during the initialization process. - * There is nothing done on the initialization of a mik::USDiPhASDevive object. - * - * \return always true - */ - virtual bool OnInitialization(); - - /** - * \brief Is called during the connection process. - * Connect to the DiPhAS API. - * - * \return true if successfull, false if no device is connected to the pc - * \throws mitk::Exception if something goes wrong at the API calls - */ - virtual bool OnConnection(); - - /** - * \brief Is called during the disconnection process. - * Deactivate and remove all DiPhAS API controls. A disconnect from the - * DiPhAS API is not possible for which reason the hardware stays in connected - * state even after calling this method. - * - * \return always true - * \throws mitk::Exception if something goes wrong at the API calls - */ - virtual bool OnDisconnection(); - - /** - * \brief Is called during the activation process. - * After this method is finished, the device is generating images in b mode. - * Changing scanning mode is possible afterwards by using the appropriate - * control interfaces. - * - * \return always true - * \throws mitk::Exception if something goes wrong at the API calls - */ - virtual bool OnActivation(); - - /** - * \brief Is called during the deactivation process. - * After a call to this method the device is connected, but not producing images anymore. - * - * \return always true - * \throws mitk::Exception if something goes wrong at the API calls - */ - virtual bool OnDeactivation(); - - /** - * \brief Changes scan state of the device if freeze is toggeled in mitk::USDevice. - */ - virtual void OnFreeze(bool freeze); - - /** @return Returns the current image source of this device. */ - USImageSource::Pointer GetUSImageSource( ); - - /** @return Returns the currently used scanmode of this device*/ - ScanModeNative& GetScanMode(); - - /** Updates the Scanmode and feeds it to the hardware - */ - void UpdateScanmode(); - /** This method forwards messages from the API to the user*/ - void MessageCallback(const char* message); - void SetBursts(int bursts); - void SetInterleaved(bool interleaved); - bool IsInterleaved(); - - BeamformingParametersInterleaved_OA_US paramsInterleaved; - BeamformingParametersPlaneWaveCompound paramsPlaneWave; - - protected: - /** - * Constructs a mitk::USDiPhASDevice object by given manufacturer - * and model string. These strings are just for labeling the device - * in the micro service. - * - * Control interfaces and image source are available directly after - * construction. Registration at the micro service happens not before - * initialization method was called. - */ - USDiPhASDevice(std::string manufacturer, std::string model); - virtual ~USDiPhASDevice(); - - /** - * The DiPhAS API expects callback functions to pass - * both status messages and the processed images to the user. - * The message callback is here, the data itself is given directly to the image source. - */ - - /** - * This method sets up the scanmode at the begining - */ - void InitializeScanMode(); - void UpdateTransmitEvents(); - - USDiPhASProbesControls::Pointer m_ControlsProbes; - itk::SmartPointer m_ControlInterfaceCustom; - - mitk::USDiPhASImageSource::Pointer m_ImageSource; - - bool m_IsRunning; - ScanModeNative m_ScanMode; - int m_BurstHalfwaveClockCount; - Beamforming m_CurrentBeamformingAlgorithm; - bool m_Interleaved; - }; -} // namespace mitk - -#endif // MITKUSDiPhASDevice_H_HEADER_INCLUDED_ diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp deleted file mode 100644 index 45b4c65fd5..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.cpp +++ /dev/null @@ -1,927 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// std dependencies -#include -#include -#include - -// mitk dependencies -#include "mitkUSDiPhASDevice.h" -#include "mitkUSDiPhASImageSource.h" -#include -#include "mitkUSDiPhASBModeImageFilter.h" -#include "ITKUltrasound/itkBModeImageFilter.h" -#include "mitkImageCast.h" -#include "mitkITKImageImport.h" - -// itk dependencies -#include "itkImage.h" -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkCropImageFilter.h" -#include "itkRescaleIntensityImageFilter.h" -#include "itkIntensityWindowingImageFilter.h" -#include -#include "itkMultiplyImageFilter.h" - -mitk::USDiPhASImageSource::USDiPhASImageSource(mitk::USDiPhASDevice* device) - : m_Device(device), - m_StartTime(((float)std::clock()) / CLOCKS_PER_SEC), - m_UseGUIOutPut(false), - m_DataType(DataType::Image_uChar), - m_GUIOutput(nullptr), - m_UseBModeFilter(false), - m_CurrentlyRecording(false), - m_DataTypeModified(true), - m_DataTypeNext(DataType::Image_uChar), - m_CurrentImageTimestamp(0), - m_PyroConnected(false), - m_ImageTimestampBuffer(), - m_VerticalSpacing(0), - m_UseBModeFilterModified(false), - m_UseBModeFilterNext(false), - m_ScatteringCoefficientModified(false), - m_CompensateForScatteringModified(false), - m_VerticalSpacingModified(false), - m_ScatteringCoefficient(15), - m_CompensateForScattering(false), - m_CompensateEnergy(false), - m_CompensateEnergyNext(false), - m_CompensateEnergyModified(false) -{ - m_BufferSize = 100; - m_ImageTimestampBuffer.insert(m_ImageTimestampBuffer.begin(), m_BufferSize, 0); - m_LastWrittenImage = m_BufferSize - 1; - m_ImageBuffer.insert(m_ImageBuffer.begin(), m_BufferSize, nullptr); - - us::ModuleResource resourceFile; - std::string name; - m_FluenceCompOriginal.insert(m_FluenceCompOriginal.begin(), 5, Image::New()); - for (int i = 5; i <= 25; ++i) - { - name = "c:\\HomogeneousScatteringAssumptions\\Scattering" + std::to_string(i) + ".nrrd"; - - m_FluenceCompOriginal.push_back(mitk::IOUtil::Load(name)); - } - - m_FluenceCompResized.insert(m_FluenceCompResized.begin(), 26, Image::New()); - m_FluenceCompResizedItk.insert(m_FluenceCompResizedItk.begin(), 26, itk::Image::New()); -} - -mitk::USDiPhASImageSource::~USDiPhASImageSource() -{ - // close the pyro - MITK_INFO("Pyro Debug") << "StopDataAcquisition: " << m_Pyro->StopDataAcquisition(); - MITK_INFO("Pyro Debug") << "CloseConnection: " << m_Pyro->CloseConnection(); - m_PyroConnected = false; - m_Pyro = nullptr; -} - -void mitk::USDiPhASImageSource::GetNextRawImage(std::vector& imageVector) -{ - // modify all settings that have been changed here, so we don't get multithreading issues - if (m_DataTypeModified) - { - SetDataType(m_DataTypeNext); - m_DataTypeModified = false; - UpdateImageGeometry(); - } - if (m_UseBModeFilterModified) - { - SetUseBModeFilter(m_UseBModeFilterNext); - m_UseBModeFilterModified = false; - } - if (m_VerticalSpacingModified) - { - m_VerticalSpacing = m_VerticalSpacingNext; - m_VerticalSpacingModified = false; - } - if (m_ScatteringCoefficientModified) - { - m_ScatteringCoefficient = m_ScatteringCoefficientNext; - m_ScatteringCoefficientModified = false; - } - if (m_CompensateForScatteringModified) - { - m_CompensateForScattering = m_CompensateForScatteringNext; - m_CompensateForScatteringModified = false; - } - if (m_CompensateEnergyModified) - { - m_CompensateEnergy = m_CompensateEnergyNext; - m_CompensateEnergyModified = false; - } - - if (imageVector.size() != 2) - { - imageVector.resize(2); - } - - // make sure image is nullptr - mitk::Image::Pointer image = nullptr; - float ImageEnergyValue = 0; - - for (int i = 100; i > 90 && ImageEnergyValue <= 0; --i) - { - if (m_ImageTimestampBuffer[(m_LastWrittenImage + i) % 100] != 0) - { - ImageEnergyValue = m_Pyro->GetClosestEnergyInmJ(m_ImageTimestampBuffer[(m_LastWrittenImage + i) % 100]); - if (ImageEnergyValue > 0) { - image = &(*m_ImageBuffer[(m_LastWrittenImage + i) % 100]); - } - } - } - // if we did not get any usable Energy value, compensate using this default value - if (image == nullptr) - { - image = &(*m_ImageBuffer[m_LastWrittenImage]); - ImageEnergyValue = 40; - if (image == nullptr) - return; - } - - // do image processing before displaying it - if (image.IsNotNull()) - { - itkFloatImageType::Pointer itkImage; - - mitk::CastToItkImage(image, itkImage); - image = mitk::GrabItkImageMemory(itkImage); //thereby using float images - image = CutOffTop(image, 165); - - // now apply filters to the image, if the options have been selected. - if ((m_CompensateForScattering || m_UseBModeFilter) && m_DataType == DataType::Beamformed_Short) - { - if (m_Device->GetScanMode().beamformingAlgorithm == Beamforming::PlaneWaveCompound) // this is for ultrasound only mode - { - if (m_UseBModeFilter) - { - image = ApplyBmodeFilter(image, true); - if (m_VerticalSpacing) - image = ResampleOutputVertical(image, m_VerticalSpacing); - } - } - - else - { - Image::Pointer imagePA = Image::New(); - unsigned int dim[] = { image->GetDimension(0),image->GetDimension(1),1}; - imagePA->Initialize(image->GetPixelType(), 3, dim); - imagePA->SetGeometry(image->GetGeometry()); - - Image::Pointer imageUS = Image::New(); - imageUS->Initialize(image->GetPixelType(), 3, dim); - imageUS->SetGeometry(image->GetGeometry()); - - ImageReadAccessor inputReadAccessorCopyPA(image, image->GetSliceData(0)); - imagePA->SetSlice(inputReadAccessorCopyPA.GetData(), 0); - ImageReadAccessor inputReadAccessorCopyUS(image, image->GetSliceData(1)); - imageUS->SetSlice(inputReadAccessorCopyUS.GetData(), 0); - - // first, seperate the PA image from the USImages - - // then, we compensate the PAImage using our ImageEnergyValue - if(m_CompensateEnergy) - imagePA = MultiplyImage(imagePA, 1/ImageEnergyValue); // TODO: add the correct prefactor here!!!! - - // now we apply the BModeFilter - if (m_UseBModeFilter) - { - imageUS = ApplyBmodeFilter(imageUS, true); // the US Images get a logarithmic filter - imagePA = ApplyBmodeFilter(imagePA, false); - } - - ImageReadAccessor inputReadAccessorPA(imagePA, imagePA->GetSliceData(0)); - image->SetSlice(inputReadAccessorPA.GetData(), 0); - ImageReadAccessor inputReadAccessorUS(imageUS, imageUS->GetSliceData(0)); - image->SetSlice(inputReadAccessorUS.GetData(), 1); - if (m_VerticalSpacing) - { - image = ResampleOutputVertical(image, m_VerticalSpacing); - } - - // and finally the scattering corrections - if (m_CompensateForScattering) - { - auto curResizeImage = m_FluenceCompResized.at(m_ScatteringCoefficient); // just for convenience - - // update the fluence reference images! - bool doResampling = image->GetDimension(0) != curResizeImage->GetDimension(0) || image->GetDimension(1) != curResizeImage->GetDimension(1) - || image->GetGeometry()->GetSpacing()[0] != curResizeImage->GetGeometry()->GetSpacing()[0] || image->GetGeometry()->GetSpacing()[1] != curResizeImage->GetGeometry()->GetSpacing()[1]; - if (doResampling) - { - curResizeImage = ApplyResampling(m_FluenceCompOriginal.at(m_ScatteringCoefficient), image->GetGeometry()->GetSpacing(), image->GetDimensions()); - - double* rawOutputData = new double[image->GetDimension(0)*image->GetDimension(1)]; - double* rawScatteringData = (double*)curResizeImage->GetData(); - int sizeRawScatteringData = curResizeImage->GetDimension(0) * curResizeImage->GetDimension(1); - int imageSize = image->GetDimension(0)*image->GetDimension(1); - - //everything above 1.5mm is still inside the transducer; therefore the fluence compensation image has to be positioned a little lower - float upperCutoffmm = 1.5; - int lowerBound = std::round(upperCutoffmm / image->GetGeometry()->GetSpacing()[1])*image->GetDimension(0); - int upperBound = lowerBound + sizeRawScatteringData; - - for (int i = 0; i < lowerBound && i < imageSize; ++i) - { - rawOutputData[i] = 0; // everything than cannot be compensated shall be treated as garbage, here the upper 0.15mm - } - for (int i = lowerBound; i < upperBound && i < imageSize; ++i) - { - rawOutputData[i] = 1 / rawScatteringData[i-lowerBound]; - } - for (int i = upperBound; i < imageSize; ++i) - { - rawOutputData[i] = 0; // everything than cannot be compensated shall be treated as garbage - } - - - unsigned int dim[] = { image->GetDimension(0), image->GetDimension(1), 1 }; - curResizeImage->Initialize(mitk::MakeScalarPixelType(), 3, dim); - curResizeImage->SetGeometry(image->GetGeometry()); - curResizeImage->SetSlice(rawOutputData,0); - - delete[] rawOutputData; - - mitk::CastToItkImage(curResizeImage, m_FluenceCompResizedItk.at(m_ScatteringCoefficient)); - m_FluenceCompResized.at(m_ScatteringCoefficient) = mitk::GrabItkImageMemory(m_FluenceCompResizedItk.at(m_ScatteringCoefficient)); - - MITK_INFO << "Resized a fluence image."; - } - // actually apply the scattering compensation - imagePA = ApplyScatteringCompensation(imagePA, m_ScatteringCoefficient); - ImageReadAccessor inputReadAccessorPA(imagePA, imagePA->GetSliceData(0)); - image->SetSlice(inputReadAccessorPA.GetData(), 0); - } - } - } - - //TODO: completely rewrite this mess - - imageVector[0] = Image::New(); - unsigned int dim[] = { image->GetDimension(0),image->GetDimension(1),1 }; - imageVector[0]->Initialize(image->GetPixelType(), 3, dim); - imageVector[0]->SetGeometry(image->GetGeometry()); - - imageVector[1] = Image::New(); - imageVector[1]->Initialize(image->GetPixelType(), 3, dim); - imageVector[1]->SetGeometry(image->GetGeometry()); - - ImageReadAccessor inputReadAccessorCopyPA(image, image->GetSliceData(0)); - imageVector[0]->SetSlice(inputReadAccessorCopyPA.GetData(), 0); - ImageReadAccessor inputReadAccessorCopyUS(image, image->GetSliceData(1)); - imageVector[1]->SetSlice(inputReadAccessorCopyUS.GetData(), 0); - } -} - -mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyBmodeFilter(mitk::Image::Pointer image, bool useLogFilter) -{ - // we use this seperate ApplyBmodeFilter Method for processing of two-dimensional images - - // the image needs to be of floating point type for the envelope filter to work; the casting is done automatically by the CastToItkImage - - typedef itk::BModeImageFilter < itkFloatImageType, itkFloatImageType > BModeFilterType; - BModeFilterType::Pointer bModeFilter = BModeFilterType::New(); // LogFilter - - typedef itk::PhotoacousticBModeImageFilter < itkFloatImageType, itkFloatImageType > PhotoacousticBModeImageFilter; - PhotoacousticBModeImageFilter::Pointer photoacousticBModeFilter = PhotoacousticBModeImageFilter::New(); // No LogFilter - - itkFloatImageType::Pointer itkImage; - itkFloatImageType::Pointer bmode; - mitk::CastToItkImage(image, itkImage); - - if (useLogFilter) - { - bModeFilter->SetInput(itkImage); - bModeFilter->SetDirection(1); - bmode = bModeFilter->GetOutput(); - } - else - { - photoacousticBModeFilter->SetInput(itkImage); - photoacousticBModeFilter->SetDirection(1); - bmode = photoacousticBModeFilter->GetOutput(); - } - return mitk::GrabItkImageMemory(bmode); -} - -mitk::Image::Pointer mitk::USDiPhASImageSource::CutOffTop(mitk::Image::Pointer image, int cutOffSize) -{ - typedef itk::CropImageFilter < itkFloatImageType, itkFloatImageType > CutImageFilter; - itkFloatImageType::SizeType cropSize; - itkFloatImageType::Pointer itkImage; - mitk::CastToItkImage(image, itkImage); - - cropSize[0] = 0; - if(itkImage->GetLargestPossibleRegion().GetSize()[1] == 2048) - cropSize[1] = cutOffSize; - else - cropSize[1] = 0; - cropSize[2] = 0; - CutImageFilter::Pointer cutOffFilter = CutImageFilter::New(); - cutOffFilter->SetInput(itkImage); - cutOffFilter->SetLowerBoundaryCropSize(cropSize); - cutOffFilter->UpdateLargestPossibleRegion(); - return mitk::GrabItkImageMemory(cutOffFilter->GetOutput()); -} - -mitk::Image::Pointer mitk::USDiPhASImageSource::ResampleOutputVertical(mitk::Image::Pointer image, float verticalSpacing) -{ - typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; - ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); - - itkFloatImageType::Pointer itkImage; - - mitk::CastToItkImage(image, itkImage); - itkFloatImageType::SpacingType outputSpacing; - itkFloatImageType::SizeType inputSize = itkImage->GetLargestPossibleRegion().GetSize(); - itkFloatImageType::SizeType outputSize = inputSize; - - outputSpacing[0] = itkImage->GetSpacing()[0] * (static_cast(inputSize[0]) / static_cast(outputSize[0])); - outputSpacing[1] = verticalSpacing; - outputSpacing[2] = itkImage->GetSpacing()[2]; - - outputSize[1] = inputSize[1] * itkImage->GetSpacing()[1] / outputSpacing[1]; - - typedef itk::IdentityTransform TransformType; - resampleImageFilter->SetInput(itkImage); - resampleImageFilter->SetSize(outputSize); - resampleImageFilter->SetOutputSpacing(outputSpacing); - resampleImageFilter->SetTransform(TransformType::New()); - - resampleImageFilter->UpdateLargestPossibleRegion(); - return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput()); -} - -mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyScatteringCompensation(mitk::Image::Pointer inputImage, int scattering) -{ - typedef itk::MultiplyImageFilter MultiplyImageFilterType; - - itkFloatImageType::Pointer itkImage; - mitk::CastToItkImage(inputImage, itkImage); - - MultiplyImageFilterType::Pointer multiplyFilter = MultiplyImageFilterType::New(); - multiplyFilter->SetInput1(itkImage); - multiplyFilter->SetInput2(m_FluenceCompResizedItk.at(m_ScatteringCoefficient)); - - return mitk::GrabItkImageMemory(multiplyFilter->GetOutput()); -} - -mitk::Image::Pointer mitk::USDiPhASImageSource::ApplyResampling(mitk::Image::Pointer inputImage, mitk::Vector3D outputSpacing, unsigned int outputSize[3]) -{ - typedef itk::ResampleImageFilter < itkFloatImageType, itkFloatImageType > ResampleImageFilter; - ResampleImageFilter::Pointer resampleImageFilter = ResampleImageFilter::New(); - - itkFloatImageType::Pointer itkImage; - - mitk::CastToItkImage(inputImage, itkImage); - - itkFloatImageType::SpacingType outputSpacingItk; - itkFloatImageType::SizeType inputSizeItk = itkImage->GetLargestPossibleRegion().GetSize(); - itkFloatImageType::SizeType outputSizeItk = inputSizeItk; - itkFloatImageType::SpacingType inputSpacing = itkImage->GetSpacing(); - - outputSizeItk[0] = outputSize[0]; - outputSizeItk[1] = 10*(inputSpacing[1] * inputSizeItk[1]) / (outputSpacing[1]); - outputSizeItk[2] = 1; - - outputSpacingItk[0] = 0.996 * inputSpacing[0] * (static_cast(inputSizeItk[0]) / static_cast(outputSizeItk[0])); // TODO: find out why the spacing is not correct, so we need that factor; ?!?! - outputSpacingItk[1] = inputSpacing[1] * (static_cast(inputSizeItk[1]) / static_cast(outputSizeItk[1])); - outputSpacingItk[2] = outputSpacing[2]; - - typedef itk::IdentityTransform TransformType; - resampleImageFilter->SetInput(itkImage); - resampleImageFilter->SetSize(outputSizeItk); - resampleImageFilter->SetOutputSpacing(outputSpacingItk); - resampleImageFilter->SetTransform(TransformType::New()); - - resampleImageFilter->UpdateLargestPossibleRegion(); - return mitk::GrabItkImageMemory(resampleImageFilter->GetOutput()); -} - -mitk::Image::Pointer mitk::USDiPhASImageSource::MultiplyImage(mitk::Image::Pointer inputImage, double value) -{ - typedef itk::MultiplyImageFilter MultiplyImageFilterType; - - itkFloatImageType::Pointer itkImage; - mitk::CastToItkImage(inputImage, itkImage); - - MultiplyImageFilterType::Pointer multiplyFilter = MultiplyImageFilterType::New(); - multiplyFilter->SetInput1(itkImage); - multiplyFilter->SetConstant(value); - - return mitk::GrabItkImageMemory(multiplyFilter->GetOutput()); -} - -void mitk::USDiPhASImageSource::ImageDataCallback( - short* rfDataChannelData, - int& channelDataChannelsPerDataset, - int& channelDataSamplesPerChannel, - int& channelDataTotalDatasets, - - short* rfDataArrayBeamformed, - int& beamformedLines, - int& beamformedSamples, - int& beamformedTotalDatasets, - - unsigned char* imageData, - int& imageWidth, - int& imageHeight, - int& imageBytesPerPixel, - int& imageSetsTotal, - - double& timeStamp) -{ - if (m_DataTypeModified) - return; - - if (!m_PyroConnected) - { - m_Pyro = mitk::OphirPyro::New(); - MITK_INFO << "[Pyro Debug] OpenConnection: " << m_Pyro->OpenConnection(); - MITK_INFO << "[Pyro Debug] StartDataAcquisition: " << m_Pyro->StartDataAcquisition(); - m_PyroConnected = true; - } - - bool writeImage = ((m_DataType == DataType::Image_uChar) && (imageData != nullptr)) || ((m_DataType == DataType::Beamformed_Short) && (rfDataArrayBeamformed != nullptr)); - if (writeImage) - { - //get the timestamp we might save later on - m_CurrentImageTimestamp = std::chrono::high_resolution_clock::now().time_since_epoch().count(); - - // create a new image and initialize it - mitk::Image::Pointer image = mitk::Image::New(); - - switch (m_DataType) - { - case DataType::Image_uChar: { - m_ImageDimensions[0] = imageWidth; - m_ImageDimensions[1] = imageHeight; - m_ImageDimensions[2] = imageSetsTotal; - image->Initialize(mitk::MakeScalarPixelType(), 3, m_ImageDimensions); - break; - } - case DataType::Beamformed_Short: { - m_ImageDimensions[0] = beamformedLines; - m_ImageDimensions[1] = beamformedSamples; - m_ImageDimensions[2] = beamformedTotalDatasets; - image->Initialize(mitk::MakeScalarPixelType(), 3, m_ImageDimensions); - break; - } - } - image->GetGeometry()->SetSpacing(m_ImageSpacing); - image->GetGeometry()->Modified(); - - // write the given buffer into the image - switch (m_DataType) - { - case DataType::Image_uChar: { - for (unsigned char i = 0; i < imageSetsTotal; i++) { - image->SetSlice(&imageData[i*imageHeight*imageWidth], i); - } - break; - } - - case DataType::Beamformed_Short: { - short* flipme = new short[beamformedLines*beamformedSamples*beamformedTotalDatasets]; - int pixelsPerImage = beamformedLines*beamformedSamples; - - for (unsigned char currentSet = 0; currentSet < beamformedTotalDatasets; currentSet++) - { - for (unsigned short sample = 0; sample < beamformedSamples; sample++) - { - for (unsigned short line = 0; line < beamformedLines; line++) - { - flipme[sample*beamformedLines + line + pixelsPerImage*currentSet] - = rfDataArrayBeamformed[line*beamformedSamples + sample + pixelsPerImage*currentSet]; - } - } // the beamformed pa image is flipped by 90 degrees; we need to flip it manually - } - - for (unsigned char i = 0; i < beamformedTotalDatasets; i++) { - image->SetSlice(&flipme[i*beamformedLines*beamformedSamples], i); - // set every image to a different slice - } - - delete[] flipme; - break; - } - } - - if (m_SavingSettings.saveRaw && m_CurrentlyRecording && rfDataChannelData != nullptr) - { - unsigned int dim[3]; - dim[0] = channelDataChannelsPerDataset; - dim[1] = channelDataSamplesPerChannel; - dim[2] = 1; - short offset = m_Device->GetScanMode().accumulation * 2048; - - short* noOffset = new short[channelDataChannelsPerDataset*channelDataSamplesPerChannel*channelDataTotalDatasets]; - for (unsigned char set = 0; set < 1; ++set)// channelDataTotalDatasets; ++set) // we ignore the raw US images for now - { - for (unsigned short sam = 0; sam < channelDataSamplesPerChannel; ++sam) - { - for (unsigned short chan = 0; chan < channelDataChannelsPerDataset; ++chan) - { - noOffset[set*channelDataSamplesPerChannel*channelDataChannelsPerDataset + sam * channelDataChannelsPerDataset + chan] = - rfDataChannelData[set*channelDataSamplesPerChannel*channelDataChannelsPerDataset + sam * channelDataChannelsPerDataset + chan] - offset; // this offset in the raw Images is given by the API... - } - } - } - - // save the raw images when recording - for (unsigned char i = 0; i < 1; ++i)// channelDataTotalDatasets; ++i) // we ignore the raw US images for now - { - mitk::Image::Pointer rawImage = mitk::Image::New(); - rawImage->Initialize(mitk::MakeScalarPixelType(), 3, dim); - - rawImage->SetSlice(&noOffset[i*channelDataChannelsPerDataset*channelDataSamplesPerChannel]); - - float& recordTime = m_Device->GetScanMode().receivePhaseLengthSeconds; - int& speedOfSound = m_Device->GetScanMode().averageSpeedOfSound; - - mitk::Vector3D rawSpacing; - rawSpacing[0] = m_Device->GetScanMode().transducerPitchMeter * 1000; // save in mm - rawSpacing[1] = recordTime / channelDataSamplesPerChannel * 1000000; // save in us - rawSpacing[2] = 1; - - rawImage->GetGeometry()->SetSpacing(rawSpacing); - rawImage->GetGeometry()->Modified(); - - m_RawRecordedImages.push_back(rawImage); - } - - delete[] noOffset; - } - - itk::Index<3> pixel = { { - (itk::Index<3>::IndexValueType)(image->GetDimension(0) / 2), - (itk::Index<3>::IndexValueType)(22.0/532.0*m_Device->GetScanMode().reconstructionSamplesPerLine), - 0 } }; //22/532*2048 = 84 - if (!m_Pyro->IsSyncDelaySet() &&(image->GetPixelValueByIndex(pixel) < -30)) // #MagicNumber - { - MITK_INFO << "Setting SyncDelay now"; - m_Pyro->SetSyncDelay(m_CurrentImageTimestamp); - } - - m_ImageTimestampBuffer[(m_LastWrittenImage + 1) % m_BufferSize] = m_CurrentImageTimestamp; - m_ImageBuffer[(m_LastWrittenImage + 1) % m_BufferSize] = image; - m_LastWrittenImage = (m_LastWrittenImage + 1) % m_BufferSize; - - // if the user decides to start recording, we feed the vector the generated images - if (m_CurrentlyRecording) { - for (unsigned char index = 0; index < image->GetDimension(2); ++index) - { - if (image->IsSliceSet(index)) - { - m_RecordedImages.push_back(Image::New()); - unsigned int dim[] = { image ->GetDimension(0), image->GetDimension(1), 1}; - m_RecordedImages.back()->Initialize(image->GetPixelType(), 3, dim); - m_RecordedImages.back()->SetGeometry(image->GetGeometry()); - - mitk::ImageReadAccessor inputReadAccessor(image, image->GetSliceData(index)); - m_RecordedImages.back()->SetSlice(inputReadAccessor.GetData(),0); - } - } - m_ImageTimestampRecord.push_back(m_CurrentImageTimestamp); - // save timestamps for each laser image! - } - } -} - -void mitk::USDiPhASImageSource::UpdateImageGeometry() -{ - MITK_INFO << "Retreaving Image Geometry Information for Spacing..."; - float& recordTime = m_Device->GetScanMode().receivePhaseLengthSeconds; - int& speedOfSound = m_Device->GetScanMode().averageSpeedOfSound; - float& pitch = m_Device->GetScanMode().reconstructedLinePitchMmOrAngleDegree; - int& reconstructionLines = m_Device->GetScanMode().reconstructionLines; - - switch (m_DataType) - { - case DataType::Image_uChar : { - int& imageWidth = m_Device->GetScanMode().imageWidth; - int& imageHeight = m_Device->GetScanMode().imageHeight; - m_ImageSpacing[0] = pitch * reconstructionLines / imageWidth; - m_ImageSpacing[1] = recordTime * speedOfSound / 2 * 1000 / imageHeight; - break; - } - case DataType::Beamformed_Short : { - int& imageWidth = reconstructionLines; - int& imageHeight = m_Device->GetScanMode().reconstructionSamplesPerLine; - m_ImageSpacing[0] = pitch; - m_ImageSpacing[1] = recordTime * speedOfSound / 2 * 1000 / imageHeight; - break; - } - } - m_ImageSpacing[2] = 1; - - MITK_INFO << "Retreaving Image Geometry Information for Spacing " << m_ImageSpacing[0] << " ... " << m_ImageSpacing[1] << " ... " << m_ImageSpacing[2] << " ...[DONE]"; -} - -void mitk::USDiPhASImageSource::ModifyDataType(DataType dataT) -{ - m_DataTypeModified = true; - m_DataTypeNext = dataT; -} - -void mitk::USDiPhASImageSource::ModifyUseBModeFilter(bool isSet) -{ - m_UseBModeFilterModified = true; - m_UseBModeFilterNext = isSet; -} - -void mitk::USDiPhASImageSource::ModifyScatteringCoefficient(int coeff) -{ - m_ScatteringCoefficientNext = coeff; - m_ScatteringCoefficientModified = true; -} - -void mitk::USDiPhASImageSource::ModifyCompensateForScattering(bool useIt) -{ - m_CompensateForScatteringNext = useIt; - m_CompensateForScatteringModified = true; -} - -void mitk::USDiPhASImageSource::ModifyEnergyCompensation(bool compensate) -{ - m_CompensateEnergyNext = compensate; - m_CompensateEnergyModified = true; -} - -void mitk::USDiPhASImageSource::SetDataType(DataType dataT) -{ - if (dataT != m_DataType) - { - m_DataType = dataT; - MITK_INFO << "Setting new DataType..." << dataT; - switch (m_DataType) - { - case DataType::Image_uChar : - MITK_INFO << "height: " << m_Device->GetScanMode().imageHeight << " width: " << m_Device->GetScanMode().imageWidth; - break; - case DataType::Beamformed_Short : - MITK_INFO << "samples: " << m_Device->GetScanMode().reconstructionSamplesPerLine << " lines: " << m_Device->GetScanMode().reconstructionLines; - break; - } - } -} - -void mitk::USDiPhASImageSource::SetGUIOutput(std::function out) -{ - USDiPhASImageSource::m_GUIOutput = out; - m_StartTime = ((float)std::clock()) / CLOCKS_PER_SEC; //wait till the callback is available again - m_UseGUIOutPut = false; -} - -void mitk::USDiPhASImageSource::SetUseBModeFilter(bool isSet) -{ - m_UseBModeFilter = isSet; -} - -void mitk::USDiPhASImageSource::SetVerticalSpacing(float mm) -{ - m_VerticalSpacingNext = mm; - m_VerticalSpacingModified = true; -} - -void mitk::USDiPhASImageSource::SetSavingSettings(SavingSettings settings) -{ - m_SavingSettings = settings; -} - -// this is just a little function to set the filenames below right -inline void replaceAll(std::string& str, const std::string& from, const std::string& to) { - if (from.empty()) - return; - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' - } -} - -void mitk::USDiPhASImageSource::SetRecordingStatus(bool record) -{ - // start the recording process - if (record) - { - m_RecordedImages.clear(); - m_RawRecordedImages.clear(); // we make sure there are no leftovers - m_ImageTimestampRecord.clear(); // also for the timestamps - m_PixelValues.clear(); // aaaand for the pixel values - - if (m_SavingSettings.saveRaw) - { - m_Device->GetScanMode().transferChannelData = true; - m_Device->UpdateScanmode(); - // set the raw Data to be transfered - } - - // tell the callback to start recording images - m_CurrentlyRecording = true; - } - // save images, end recording, and clean up - else - { - m_CurrentlyRecording = false; - - m_Device->GetScanMode().transferChannelData = false; // make sure raw Channel Data is not transferred anymore! - m_Device->UpdateScanmode(); - - // get the time and date, put them into a nice string and create a folder for the images - time_t time = std::time(nullptr); - time_t* timeptr = &time; - std::string currentDate = std::ctime(timeptr); - replaceAll(currentDate, ":", "-"); - currentDate.pop_back(); - //std::string MakeFolder = "mkdir \"c:/DiPhASImageData/" + currentDate + "\""; - //system(MakeFolder.c_str()); - - // initialize file paths and the images - Image::Pointer PAImage = Image::New(); - Image::Pointer USImage = Image::New(); - std::string pathPA = "c:\\ImageData\\" + currentDate + "-" + "PAbeamformed" + ".nrrd"; - std::string pathUS = "c:\\ImageData\\" + currentDate + "-" + "USImages" + ".nrrd"; - std::string pathTS = "c:\\ImageData\\" + currentDate + "-" + "ts" + ".csv"; - std::string pathS = "c:\\ImageData\\" + currentDate + "-" + "Settings" + ".txt"; - - // idon't forget the raw Images (if chosen to be saved) - Image::Pointer PAImageRaw = Image::New(); - Image::Pointer USImageRaw = Image::New(); - std::string pathPARaw = "c:\\ImageData\\" + currentDate + "-" + "PAraw" + ".nrrd"; - std::string pathUSRaw = "c:\\ImageData\\" + currentDate + "-" + "USImagesRaw" + ".nrrd"; - - if (m_Device->GetScanMode().beamformingAlgorithm == (int)Beamforming::Interleaved_OA_US) // save a PAImage if we used interleaved mode - { - // first, save the data, so the pyro does not aquire more unneccessary timestamps - m_Pyro->SaveData(); - - // now order the images and save them - // the beamformed ones... - if (m_SavingSettings.saveBeamformed) - { - OrderImagesInterleaved(PAImage, USImage, m_RecordedImages, false); - mitk::IOUtil::Save(USImage, pathUS); - mitk::IOUtil::Save(PAImage, pathPA); - } - - // ...and the raw images - if (m_SavingSettings.saveRaw) - { - OrderImagesInterleaved(PAImageRaw, USImageRaw, m_RawRecordedImages, true); - // mitk::IOUtil::Save(USImageRaw, pathUSRaw); - mitk::IOUtil::Save(PAImageRaw, pathPARaw); - } - - // read the pixelvalues of the enveloped images at this position - - itk::Index<3> pixel = { { - (itk::Index<3>::IndexValueType)(m_RecordedImages.at(0)->GetDimension(0) / 2), - (itk::Index<3>::IndexValueType)(22.0 / 532.0*m_Device->GetScanMode().reconstructionSamplesPerLine), - 0 } }; //22/532*2048 = 84 - - GetPixelValues(pixel, m_PixelValues); // write the Pixelvalues to m_PixelValues - - // save the timestamps! - ofstream timestampFile; - - timestampFile.open(pathTS); - timestampFile << ",timestamp,pixelvalue"; // write the header - - for (int index = 0; index < m_ImageTimestampRecord.size(); ++index) - { - timestampFile << "\n" << index << "," << m_ImageTimestampRecord.at(index) << "," << m_PixelValues.at(index); - } - timestampFile.close(); - - //save the settings! - - ofstream settingsFile; - - settingsFile.open(pathS); - auto& sM = m_Device->GetScanMode(); - - settingsFile << "[General Parameters]\n"; - settingsFile << "Scan Depth [mm] = " << sM.receivePhaseLengthSeconds * sM.averageSpeedOfSound / 2 * 1000 << "\n"; - settingsFile << "Speed of Sound [m/s] = " << sM.averageSpeedOfSound << "\n"; - settingsFile << "Excitation Frequency [MHz] = " << sM.transducerFrequencyHz/1000000 << "\n"; - settingsFile << "Voltage [V] = " << sM.voltageV << "\n"; - settingsFile << "TGC min = " << (int)sM.tgcdB[0] << " max = " << (int)sM.tgcdB[7] << "\n"; - - settingsFile << "[Beamforming Parameters]\n"; - settingsFile << "Reconstructed Lines = " << sM.reconstructionLines << "\n"; - settingsFile << "Samples per Line = " << sM.reconstructionSamplesPerLine << "\n"; - - settingsFile.close(); - } - else if (m_Device->GetScanMode().beamformingAlgorithm == (int)Beamforming::PlaneWaveCompound) // save no PAImage if we used US only mode - { - OrderImagesUltrasound(USImage, m_RecordedImages); - mitk::IOUtil::Save(USImage, pathUS); - } - - m_PixelValues.clear(); - m_RawRecordedImages.clear(); // clean up the pixel values - m_RecordedImages.clear(); // clean up the images - m_ImageTimestampRecord.clear(); // clean up the timestamps - } -} - -void mitk::USDiPhASImageSource::GetPixelValues(itk::Index<3> pixel, std::vector& values) -{ - unsigned int events = 2; - for (int index = 0; index < m_RecordedImages.size(); index += events) // omit sound images - { - Image::Pointer image = m_RecordedImages.at(index); - image = ApplyBmodeFilter(image); - values.push_back(image.GetPointer()->GetPixelValueByIndex(pixel)); - } -} - -void mitk::USDiPhASImageSource::OrderImagesInterleaved(Image::Pointer PAImage, Image::Pointer USImage, std::vector recordedList, bool raw) -{ - unsigned int width = 32; - unsigned int height = 32; - unsigned int events = m_Device->GetScanMode().transmitEventsCount + 1; // the PA event is not included in the transmitEvents, so we add 1 here - if (!raw) - events = 2; // the beamformed image array contains only the resulting image of multiple events - - if (raw) - { - width = recordedList.at(0)->GetDimension(0); - height = recordedList.at(0)->GetDimension(1); - } - else if (m_DataType == DataType::Beamformed_Short) - { - width = m_Device->GetScanMode().reconstructionLines; - height = m_Device->GetScanMode().reconstructionSamplesPerLine; - } - else if (m_DataType == DataType::Image_uChar) - { - width = m_Device->GetScanMode().imageWidth; - height = m_Device->GetScanMode().imageHeight; - } - - unsigned int dimLaser[] = { (unsigned int)width, (unsigned int)height, (unsigned int)(recordedList.size() / events)}; - unsigned int dimSound[] = { (unsigned int)width, (unsigned int)height, (unsigned int)(recordedList.size() / events * (events-1))}; - - PAImage->Initialize(recordedList.back()->GetPixelType(), 3, dimLaser); - PAImage->SetGeometry(recordedList.back()->GetGeometry()); - USImage->Initialize(recordedList.back()->GetPixelType(), 3, dimSound); - USImage->SetGeometry(recordedList.back()->GetGeometry()); - - for (int index = 0; index < recordedList.size(); ++index) - { - mitk::ImageReadAccessor inputReadAccessor(recordedList.at(index)); - - if (index % events == 0) - { - PAImage->SetSlice(inputReadAccessor.GetData(), index / events); - } - else - { - if(!raw) - USImage->SetSlice(inputReadAccessor.GetData(), ((index - (index % events)) / events) + (index % events)-1); - } - } -} - -void mitk::USDiPhASImageSource::OrderImagesUltrasound(Image::Pointer USImage, std::vector recordedList) -{ - unsigned int width = 32; - unsigned int height = 32; - unsigned int events = m_Device->GetScanMode().transmitEventsCount; - - if (m_DataType == DataType::Beamformed_Short) - { - width = (unsigned int)m_Device->GetScanMode().reconstructionLines; - height = (unsigned int)m_Device->GetScanMode().reconstructionSamplesPerLine; - } - else if (m_DataType == DataType::Image_uChar) - { - width = (unsigned int)m_Device->GetScanMode().imageWidth; - height = (unsigned int)m_Device->GetScanMode().imageHeight; - } - - unsigned int dimSound[] = { (unsigned int)width, (unsigned int)height, (unsigned int)recordedList.size()}; - - USImage->Initialize(recordedList.back()->GetPixelType(), 3, dimSound); - USImage->SetGeometry(recordedList.back()->GetGeometry()); - - for (int index = 0; index < recordedList.size(); ++index) - { - mitk::ImageReadAccessor inputReadAccessor(recordedList.at(index)); - USImage->SetSlice(inputReadAccessor.GetData(), index); - } -} diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.h deleted file mode 100644 index 428b8e6b32..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASImageSource.h +++ /dev/null @@ -1,189 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKUSDiPhASImageSource_H_HEADER_INCLUDED_ -#define MITKUSDiPhASImageSource_H_HEADER_INCLUDED_ - - -#include "mitkUSImageSource.h" -#include "mitkUSDiPhASCustomControls.h" - -#include "Framework.IBMT.US.CWrapper.h" - -#include "mitkImageReadAccessor.h" -#include "itkFastMutexLock.h" -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace mitk { - -class USDiPhASDevice; -/** - * \brief Implementation of mitk::USImageSource for DiPhAS API devices. - * The method mitk::USImageSource::GetNextRawImage() is implemented for - * getting images from the DiPhAS API. - * - * The image data is given to this class from the DiPhAS API by calling - * a callback method that writes the image data to an mitk::image - */ -class USDiPhASImageSource : public USImageSource -{ - -public: - mitkClassMacro(USDiPhASImageSource, USImageSource); - mitkNewMacro1Param(Self, mitk::USDiPhASDevice*); - itkCloneMacro(Self); - - typedef itk::Image< float, 3 > itkFloatImageType; - typedef mitk::USDiPhASDeviceCustomControls::DataType DataType; - typedef mitk::USDiPhASDeviceCustomControls::SavingSettings SavingSettings; - - /** - * Implementation of the superclass method. Returns the pointer - * to the mitk::Image filled by DiPhAS API callback. - */ - virtual void GetNextRawImage( std::vector& ) override; - - /** - * The API calls this function to pass the image data to the - * user; here the m_Image is updated - */ - void mitk::USDiPhASImageSource::ImageDataCallback( - short* rfDataChannelData, - int& channelDataChannelsPerDataset, - int& channelDataSamplesPerChannel, - int& channelDataTotalDatasets, - - short* rfDataArrayBeamformed, - int& beamformedLines, - int& beamformedSamples, - int& beamformedTotalDatasets, - - unsigned char* imageData, - int& imageWidth, - int& imageHeight, - int& imagePixelFormat, - int& imageSetsTotal, - - double& timeStamp); - - void SetGUIOutput(std::function out); - - /** This starts or ends the recording session*/ - void SetRecordingStatus(bool record); - void SetSavingSettings(SavingSettings settings); - void SetVerticalSpacing(float mm); - - void ModifyDataType(DataType dataT); - void ModifyUseBModeFilter(bool isSet); - void ModifyScatteringCoefficient(int coeff); - void ModifyCompensateForScattering(bool useIt); - void ModifyEnergyCompensation(bool compensate); - - /** - * Sets the spacing used in the image based on the informations of the ScanMode in USDiPhAS Device - */ - void UpdateImageGeometry(); - -protected: - void SetDataType(DataType dataT); - void SetUseBModeFilter(bool isSet); - - USDiPhASImageSource(mitk::USDiPhASDevice* device); - virtual ~USDiPhASImageSource( ); - - /** This vector holds all the images we record, if recording is set to active. */ - std::vector m_RecordedImages; - std::vector m_RawRecordedImages; - std::vector m_ImageTimestampRecord; - std::vector m_ImageTimestampBuffer; - long long m_CurrentImageTimestamp; - bool m_CurrentlyRecording; - mitk::OphirPyro::Pointer m_Pyro; - bool m_PyroConnected; - - std::vector m_FluenceCompOriginal; - std::vector m_FluenceCompResized; - std::vector::Pointer> m_FluenceCompResizedItk; - - std::vector m_ImageBuffer; - int m_LastWrittenImage; - int m_BufferSize; - - unsigned int m_ImageDimensions[3]; - mitk::Vector3D m_ImageSpacing; - - mitk::Image::Pointer ApplyBmodeFilter(mitk::Image::Pointer image, bool useLogFilter = false); - mitk::Image::Pointer CutOffTop(mitk::Image::Pointer image, int cutOffSize = 165); - mitk::Image::Pointer ResampleOutputVertical(mitk::Image::Pointer image, float verticalSpacing = 0.1); - - mitk::Image::Pointer ApplyScatteringCompensation(mitk::Image::Pointer inputImage, int scatteringCoefficient); - mitk::Image::Pointer ApplyResampling(mitk::Image::Pointer inputImage, mitk::Vector3D outputSpacing, unsigned int outputSize[3]); - mitk::Image::Pointer MultiplyImage(mitk::Image::Pointer inputImage, double value); - - void OrderImagesInterleaved(Image::Pointer PAImage, Image::Pointer USImage, std::vector recordedList, bool raw); - void OrderImagesUltrasound(Image::Pointer USImage, std::vector recordedList); - - void GetPixelValues(itk::Index<3> pixel, std::vector& values); - float GetPixelValue(itk::Index<3> pixel); - std::vector m_PixelValues; - - mitk::USDiPhASDevice* m_Device; - - /** This is a callback to pass text data to the GUI. */ - std::function m_GUIOutput; - - /** - * Variables for management of current state. - */ - SavingSettings m_SavingSettings; - - float m_StartTime; - bool m_UseGUIOutPut; - - BeamformerStateInfoNative m_BeamformerInfos; - bool m_UseBModeFilter; - - bool m_DataTypeModified; - DataType m_DataTypeNext; - - bool m_UseBModeFilterModified; - bool m_UseBModeFilterNext; - - float m_VerticalSpacing; - float m_VerticalSpacingNext; - bool m_VerticalSpacingModified; - - int m_ScatteringCoefficient; - int m_ScatteringCoefficientNext; - bool m_ScatteringCoefficientModified; - - bool m_CompensateForScattering; - bool m_CompensateForScatteringNext; - bool m_CompensateForScatteringModified; - - bool m_CompensateEnergy; - bool m_CompensateEnergyNext; - bool m_CompensateEnergyModified; - - DataType m_DataType; -}; -} // namespace mitk - -#endif // MITKUSDiPhASImageSource_H diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbe.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbe.cpp deleted file mode 100644 index afe7d710ff..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbe.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkUSDiPhASProbe.h" -#include "Framework.IBMT.US.CWrapper.h" - -mitk::USDiPhASProbe::USDiPhASProbe(std::string ProbeName) -{ - SetName(ProbeName); -} - -mitk::USDiPhASProbe::~USDiPhASProbe() -{ -} diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbe.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbe.h deleted file mode 100644 index dfb307a928..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbe.h +++ /dev/null @@ -1,45 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKUSDiPhASProbe_H_HEADER_INCLUDED_ -#define MITKUSDiPhASProbe_H_HEADER_INCLUDED_ - -#include "mitkUSProbe.h" - -namespace mitk -{ - /** - * \brief Specialized mitk::USProbe for handling DiPhAS API probe objects. - * It encapsulates a probe object from the DiPhAS API. - * - * This class should only be instantiated by mitk::USDiPhASProbesControls. - * Every other object can get instances of mitk::USDiPhASProbe from there. - */ - class USDiPhASProbe : public USProbe - { - public: - mitkClassMacro(USDiPhASProbe, USProbe); - mitkNewMacro1Param(Self, std::string); - - protected: - /** - * Constructs mitk::USDiPhASProbe object. - * - * \param ProbeName - */ - USDiPhASProbe(std::string ProbeName); - virtual ~USDiPhASProbe(); - - }; -} // namespace mitk - -#endif // MITKUSDiPhASProbe_H_HEADER_INCLUDED_ diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbesControls.cpp b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbesControls.cpp deleted file mode 100644 index 0a7a6f262e..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbesControls.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include -#include "mitkUSDiPhASProbesControls.h" -#include "mitkUSDiPhASDevice.h" -#include - -mitk::USDiPhASProbesControls::USDiPhASProbesControls(itk::SmartPointer device) - : mitk::USControlInterfaceProbes(device.GetPointer()), - m_IsActive(false), m_DiPhASDevice(device) -{ -} - -mitk::USDiPhASProbesControls::~USDiPhASProbesControls() -{ -} - - -void mitk::USDiPhASProbesControls::SetIsActive(bool isActive) -{ - this->CreateProbesSet(); - m_IsActive = isActive; -} - -bool mitk::USDiPhASProbesControls::GetIsActive() -{ - return m_IsActive; -} - -std::vector mitk::USDiPhASProbesControls::GetProbeSet() -{ - // create a new vector of base class (USProbe) objects, because - // interface wants a vector of this type - std::vector usProbes(m_ProbesSet.size(), 0); - for (unsigned int n = 0; n < m_ProbesSet.size(); ++n) - { - usProbes.at(n) = m_ProbesSet.at(n).GetPointer(); - } - return usProbes; -} - -void mitk::USDiPhASProbesControls::OnSelectProbe(unsigned int index) -{ - if (index >= m_ProbesSet.size()) - { - MITK_ERROR("USDiPhASProbesControls")("USControlInterfaceProbes") - << "Cannot select probe with index " << index << ". Maximum possible index is " << m_ProbesSet.size() - 1 << "."; - mitkThrow() << "Cannot select probe with index " << index << - ". Maximum possible index is " << m_ProbesSet.size() - 1 << "."; - } - - m_SelectedProbeIndex = index; -} - -void mitk::USDiPhASProbesControls::OnSelectProbe(mitk::USProbe::Pointer probe) -{ -} - -mitk::USProbe::Pointer mitk::USDiPhASProbesControls::GetSelectedProbe() -{ - if (m_SelectedProbeIndex >= m_ProbesSet.size()) - { - MITK_ERROR("USDiPhASProbesControls")("USControlInterfaceProbes") - << "Cannot get active probe as the current index is" << m_SelectedProbeIndex << - ". Maximum possible index is " << m_ProbesSet.size() - 1 << "."; - mitkThrow() << "Cannot get active probe as the current index is" << m_SelectedProbeIndex << - ". Maximum possible index is " << m_ProbesSet.size() - 1 << "."; - } - - return m_ProbesSet.at(m_SelectedProbeIndex).GetPointer(); -} - -unsigned int mitk::USDiPhASProbesControls::GetProbesCount() const -{ - return m_ProbesSet.size(); -} - - -void mitk::USDiPhASProbesControls::ProbeRemoved(unsigned int index) -{ - MITK_INFO << "Probe removed..."; - - if (m_ProbesSet.size() > index) - { - m_ProbesSet.erase(m_ProbesSet.begin() + index); - } -} - -void mitk::USDiPhASProbesControls::ProbeAdded(unsigned int index) -{ - MITK_INFO << "Probe arrived..."; - - this->CreateProbesSet(); -} - -void mitk::USDiPhASProbesControls::CreateProbesSet() -{ - m_ProbesSet.push_back(mitk::USDiPhASProbe::New( m_DiPhASDevice->GetScanMode().transducerName )); -} diff --git a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbesControls.h b/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbesControls.h deleted file mode 100644 index fb2ddfb0ce..0000000000 --- a/Modules/US/USHardwareDiPhAS/mitkUSDiPhASProbesControls.h +++ /dev/null @@ -1,83 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef MITKUSDiPhASProbesControls_H_HEADER_INCLUDED_ -#define MITKUSDiPhASProbesControls_H_HEADER_INCLUDED_ - -#include "Framework.IBMT.US.CWrapper.h" -#include "mitkUSDiPhASProbe.h" -#include "mitkUSControlInterfaceProbes.h" - -#include - -namespace mitk { - class USDiPhASDevice; - - /** - * \brief Implementation of mitk::USControlInterfaceProbes for DiPhAS ultrasound devices. - * See documentation of mitk::USControlInterfaceProbes for a description of the interface methods. - * This class has to be implemented for the USDevice but the DiPhAS API does not support multiple devices. - * Therefore there will be just one probe at all times. - */ - class USDiPhASProbesControls : public USControlInterfaceProbes - { - public: - mitkClassMacro(USDiPhASProbesControls, USControlInterfaceProbes); - mitkNewMacro1Param(Self, itk::SmartPointer); - - /** - * Probe informations are fetched on activation. On deactivation there is nothing done. - */ - virtual void SetIsActive(bool); - - virtual bool GetIsActive(); - - virtual std::vector GetProbeSet(); - virtual void OnSelectProbe(unsigned int index); - virtual void OnSelectProbe(USProbe::Pointer probe); - virtual USProbe::Pointer GetSelectedProbe(); - virtual unsigned int GetProbesCount() const; - - void ProbeRemoved(unsigned int index); - void ProbeAdded(unsigned int index); - - protected: - /** - * Constructs an empty object. - * DiPhAS device has to be set after constructing by calling - * mitk::USDiPhASProbesControls::SetDiPhASDevice before the - * object can be used. - */ - USDiPhASProbesControls(itk::SmartPointer device); - virtual ~USDiPhASProbesControls(); - - /** - * Create collection object (DiPhAS API) for the API device. - */ - bool CreateProbesCollection(); - - /** - * Create vector of mitk::USDiPhASProbe objects from the - * DiPhAS API probe collection. Hence - * mitk::USDiPhASProbesControls::CreateProbesCollection has to - * be called before. - */ - void CreateProbesSet(); - - bool m_IsActive; - unsigned int m_SelectedProbeIndex; - std::vector m_ProbesSet; - itk::SmartPointer m_DiPhASDevice; - }; -} - -#endif // MITKUSDiPhASProbesControls_H_HEADER_INCLUDED_ diff --git a/Modules/US/files.cmake b/Modules/US/files.cmake index 2f67fd9490..aa771c24a3 100644 --- a/Modules/US/files.cmake +++ b/Modules/US/files.cmake @@ -1,37 +1,36 @@ SET(CPP_FILES ## Module Activator mitkUSActivator.cpp ## Model Classes USModel/mitkUSImage.cpp USModel/mitkUSImageMetadata.cpp USModel/mitkUSDevice.cpp USModel/mitkUSIGTLDevice.cpp USModel/mitkUSVideoDevice.cpp USModel/mitkUSVideoDeviceCustomControls.cpp USModel/mitkUSProbe.cpp USModel/mitkUSDevicePersistence.cpp USModel/mitkUSDeviceReaderWriterConstants.cpp USModel/mitkUSDeviceReaderXML.cpp USModel/mitkUSDeviceWriterXML.cpp ## Filters and Sources USFilters/mitkUSImageLoggingFilter.cpp USFilters/mitkUSImageSource.cpp USFilters/mitkUSImageVideoSource.cpp USFilters/mitkIGTLMessageToUSImageFilter.cpp ## Control Interfaces USControlInterfaces/mitkUSAbstractControlInterface.cpp USControlInterfaces/mitkUSControlInterfaceBMode.cpp USControlInterfaces/mitkUSControlInterfaceProbes.cpp USControlInterfaces/mitkUSControlInterfaceDoppler.cpp -USControlInterfaces/mitkUSDiPhASDeviceCustomControls.cpp ) set(RESOURCE_FILES Interactions/USPointMarkInteractions.xml Interactions/USZoneInteractions.xml Interactions/USZoneInteractionsHold.xml ) diff --git a/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.cpp b/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.cpp deleted file mode 100644 index 5a4864f72e..0000000000 --- a/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "QmitkUSControlsCustomDiPhASDeviceWidget.h" -#include "ui_QmitkUSControlsCustomDiPhASDeviceWidget.h" -#include - - -#include - -QmitkUSControlsCustomDiPhASDeviceWidget::QmitkUSControlsCustomDiPhASDeviceWidget() - : ui(new Ui::QmitkUSControlsCustomDiPhASDeviceWidget) -{ -} - -QmitkUSControlsCustomDiPhASDeviceWidget::QmitkUSControlsCustomDiPhASDeviceWidget(QWidget *parent) - : QmitkUSAbstractCustomWidget(parent), ui(new Ui::QmitkUSControlsCustomDiPhASDeviceWidget) -{ -} - -QmitkUSControlsCustomDiPhASDeviceWidget::~QmitkUSControlsCustomDiPhASDeviceWidget() -{ - delete ui; -} - -std::string QmitkUSControlsCustomDiPhASDeviceWidget::GetDeviceClass() const -{ - return "org.mitk.modules.us.USDiPhASDevice"; -} - -QmitkUSAbstractCustomWidget* QmitkUSControlsCustomDiPhASDeviceWidget::Clone(QWidget* parent) const -{ - QmitkUSAbstractCustomWidget* clonedWidget = new QmitkUSControlsCustomDiPhASDeviceWidget(parent); - clonedWidget->SetDevice(this->GetDevice()); - return clonedWidget; -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnDeviceSet() -{ - m_ControlInterface = dynamic_cast - (this->GetDevice()->GetControlInterfaceCustom().GetPointer()); - - if ( m_ControlInterface.IsNotNull() ) - { - m_ControlInterface->passGUIOut([this](QString str)->void{ - if (this->ui) { - this->ui->CurrentState->setText(str); - } }); - } - else - { - MITK_WARN("QmitkUSAbstractCustomWidget")("QmitkUSControlsCustomDiPhASDeviceWidget") - << "Did not get a custom device control interface."; - } - - //now pass the default values - - m_OldReconstructionLines = 0; - - m_ControlInterface->SetSilentUpdate(true); // don't update the scanmode everytime - - OnTransmitPhaseLengthChanged(); - OnExcitationFrequencyChanged(); - OnTransmitEventsChanged(); - OnVoltageChanged(); - OnScanDepthChanged(); // HERE - OnAveragingCountChanged(); - OnTGCMinChanged(); - OnTGCMaxChanged(); - OnDataTypeChanged(); - OnPitchChanged(); - OnReconstructedSamplesChanged(); - OnReconstructedLinesChanged(); - OnSpeedOfSoundChanged(); - OnBandpassEnabledChanged(); - OnLowCutChanged(); - OnHighCutChanged(); - OnUseBModeFilterChanged(); // HERE - OnVerticalSpacingChanged(); - OnScatteringCoefficientChanged(); - OnCompensateScatteringChanged(); - OnChangedSavingSettings(); - OnCompensateEnergyChanged(); - - m_ControlInterface->SetSilentUpdate(false); // on the last update pass the scanmode and geometry! - - OnModeChanged(); // HERE -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::Initialize() -{ - ui->setupUi(this); - - connect(ui->CompensateEnergy, SIGNAL(stateChanged(int)), this, SLOT(OnCompensateEnergyChanged())); - connect(ui->UseBModeFilter, SIGNAL(stateChanged(int)), this, SLOT(OnUseBModeFilterChanged())); - connect(ui->StartStopRecord, SIGNAL(clicked()), this, SLOT(OnRecordChanged())); - connect(ui->ScatteringCoefficient, SIGNAL(valueChanged(int)), this, SLOT(OnScatteringCoefficientChanged())); - connect(ui->CompensateScattering, SIGNAL(stateChanged(int)), this, SLOT(OnCompensateScatteringChanged())); - connect(ui->VerticalSpacing, SIGNAL(valueChanged(double)), this, SLOT(OnVerticalSpacingChanged())); - connect(ui->SaveBeamformed, SIGNAL(stateChanged(int)), this, SLOT(OnChangedSavingSettings())); - connect(ui->SaveRaw, SIGNAL(stateChanged(int)), this, SLOT(OnChangedSavingSettings())); - //transmit - connect(ui->TransmitPhaseLength, SIGNAL(valueChanged(double)), this, SLOT(OnTransmitPhaseLengthChanged())); - connect(ui->ExcitationFrequency, SIGNAL(valueChanged(double)), this, SLOT(OnExcitationFrequencyChanged())); - connect(ui->TransmitEvents, SIGNAL(valueChanged(int)), this, SLOT(OnTransmitEventsChanged())); - connect(ui->Voltage, SIGNAL(valueChanged(int)), this, SLOT(OnVoltageChanged())); - connect(ui->Mode, SIGNAL(currentTextChanged(QString)), this, SLOT(OnModeChanged())); - - //Receive - connect(ui->ScanDepth, SIGNAL(valueChanged(double)), this, SLOT(OnScanDepthChanged())); - connect(ui->AveragingCount, SIGNAL(valueChanged(int)), this, SLOT(OnAveragingCountChanged())); - connect(ui->TimeGainCompensationMinSlider, SIGNAL(valueChanged(int)), this, SLOT(OnTGCMinChanged())); - connect(ui->TimeGainCompensationMaxSlider, SIGNAL(valueChanged(int)), this, SLOT(OnTGCMaxChanged())); - connect(ui->DataType, SIGNAL(currentTextChanged(QString)), this, SLOT(OnDataTypeChanged())); - - //Beamforming - connect(ui->PitchOfTransducer, SIGNAL(valueChanged(double)), this, SLOT(OnPitchChanged())); - connect(ui->ReconstructedSamplesPerLine, SIGNAL(valueChanged(int)), this, SLOT(OnReconstructedSamplesChanged())); - connect(ui->ReconstructedLines, SIGNAL(valueChanged(int)), this, SLOT(OnReconstructedLinesChanged())); - connect(ui->SpeedOfSound, SIGNAL(valueChanged(int)), this, SLOT(OnSpeedOfSoundChanged())); - - //Bandpass - connect(ui->BandpassEnabled, SIGNAL(currentTextChanged(QString)), this, SLOT(OnBandpassEnabledChanged())); - connect(ui->LowCut, SIGNAL(valueChanged(double)), this, SLOT(OnLowCutChanged())); - connect(ui->HighCut, SIGNAL(valueChanged(double)), this, SLOT(OnHighCutChanged())); -} - -//slots - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnCompensateEnergyChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - bool CompensateEnergy = ui->CompensateEnergy->isChecked(); - m_ControlInterface->SetCompensateEnergy(CompensateEnergy); -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnUseBModeFilterChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - bool UseBModeFilter = ui->UseBModeFilter->isChecked(); - m_ControlInterface->SetUseBModeFilter(UseBModeFilter); -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnRecordChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - if (ui->StartStopRecord->text() == "Start Recording") - { - ui->StartStopRecord->setText("Stop Recording"); - - ui->UseBModeFilter->setEnabled(false); - ui->ScatteringCoefficient->setEnabled(false); - ui->CompensateScattering->setEnabled(false); - ui->VerticalSpacing->setEnabled(false); - ui->SaveBeamformed->setEnabled(false); - ui->SaveRaw->setEnabled(false); - ui->TransmitPhaseLength->setEnabled(false); - ui->ExcitationFrequency->setEnabled(false); - ui->TransmitEvents->setEnabled(false); - ui->Voltage->setEnabled(false); - ui->Mode->setEnabled(false); - ui->ScanDepth->setEnabled(false); - ui->AveragingCount->setEnabled(false); - ui->TimeGainCompensationMinSlider->setEnabled(false); - ui->TimeGainCompensationMaxSlider->setEnabled(false); - ui->DataType->setEnabled(false); - ui->PitchOfTransducer->setEnabled(false); - ui->ReconstructedSamplesPerLine->setEnabled(false); - ui->ReconstructedLines->setEnabled(false); - ui->SpeedOfSound->setEnabled(false); - ui->BandpassEnabled->setEnabled(false); - ui->LowCut->setEnabled(false); - ui->HighCut->setEnabled(false); - ui->CompensateEnergy->setEnabled(false); - - m_ControlInterface->SetRecord(true); - } - else - { - ui->StartStopRecord->setText("Start Recording"); - - ui->UseBModeFilter->setEnabled(true); - ui->CompensateScattering->setEnabled(true); - if(ui->CompensateScattering->isChecked()) - ui->ScatteringCoefficient->setEnabled(true); - ui->VerticalSpacing->setEnabled(true); - ui->SaveBeamformed->setEnabled(true); - ui->SaveRaw->setEnabled(true); - ui->TransmitPhaseLength->setEnabled(true); - ui->ExcitationFrequency->setEnabled(true); - ui->TransmitEvents->setEnabled(true); - ui->Voltage->setEnabled(true); - ui->Mode->setEnabled(true); - ui->ScanDepth->setEnabled(true); - ui->AveragingCount->setEnabled(true); - ui->TimeGainCompensationMinSlider->setEnabled(true); - ui->TimeGainCompensationMaxSlider->setEnabled(true); - ui->DataType->setEnabled(true); - ui->PitchOfTransducer->setEnabled(true); - ui->ReconstructedSamplesPerLine->setEnabled(true); - ui->ReconstructedLines->setEnabled(true); - ui->SpeedOfSound->setEnabled(true); - ui->BandpassEnabled->setEnabled(true); - ui->LowCut->setEnabled(true); - ui->HighCut->setEnabled(true); - ui->CompensateEnergy->setEnabled(true); - - m_ControlInterface->SetRecord(false); - } -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnVerticalSpacingChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetVerticalSpacing(ui->VerticalSpacing->value()); -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnScatteringCoefficientChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetScatteringCoefficient(ui->ScatteringCoefficient->value()); -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnCompensateScatteringChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - if (ui->CompensateScattering->isChecked()) - ui->ScatteringCoefficient->setEnabled(true); - else - ui->ScatteringCoefficient->setEnabled(false); - - m_ControlInterface->SetCompensateScattering(ui->CompensateScattering->isChecked()); -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnChangedSavingSettings() -{ - if (m_ControlInterface.IsNull()) { return; } - - mitk::USDiPhASDeviceCustomControls::SavingSettings settings; - - settings.saveBeamformed = ui->SaveBeamformed->isChecked(); - settings.saveRaw = ui->SaveRaw->isChecked(); - - m_ControlInterface->SetSavingSettings(settings); -} - -//Transmit -void QmitkUSControlsCustomDiPhASDeviceWidget::OnTransmitPhaseLengthChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetTransmitPhaseLength(ui->TransmitPhaseLength->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnExcitationFrequencyChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetExcitationFrequency(ui->ExcitationFrequency->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnTransmitEventsChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - - m_ControlInterface->SetTransmitEvents(ui->TransmitEvents->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnVoltageChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetVoltage(ui->Voltage->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnModeChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - QString Mode = ui->Mode->currentText(); - bool silent = m_ControlInterface->GetSilentUpdate(); - m_ControlInterface->SetSilentUpdate(true); - - if (Mode == "Ultrasound only") { - m_ControlInterface->SetMode(false); - ui->TransmitEvents->setValue(1); - } - else if (Mode == "Interleaved") { - m_ControlInterface->SetMode(true); - ui->TransmitEvents->setValue(1); - } - if (!silent) { m_ControlInterface->SetSilentUpdate(false); } - OnTransmitEventsChanged(); -} - -//Receive -void QmitkUSControlsCustomDiPhASDeviceWidget::OnScanDepthChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetScanDepth(ui->ScanDepth->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnAveragingCountChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetAveragingCount(ui->AveragingCount->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnTGCMinChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - - int tgcMin = ui->TimeGainCompensationMinSlider->value(); - int tgcMax = ui->TimeGainCompensationMaxSlider->value(); - if (tgcMin > tgcMax) { - ui->TimeGainCompensationMinSlider->setValue(tgcMax); - MITK_INFO << "User tried to set tgcMin>tgcMax."; - } - QString text("TGC min = " + QString::fromStdString(std::to_string(ui->TimeGainCompensationMinSlider->value()))); - ui->TimeGainCompensationMinLabel->setText(text); - m_ControlInterface->SetTGCMin(ui->TimeGainCompensationMinSlider->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnTGCMaxChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - - int tgcMin = ui->TimeGainCompensationMinSlider->value(); - int tgcMax = ui->TimeGainCompensationMaxSlider->value(); - if (tgcMin > tgcMax) { - ui->TimeGainCompensationMaxSlider->setValue(tgcMin); - MITK_INFO << "User tried to set tgcMin>tgcMax."; - } - QString text("TGC max = "+QString::fromStdString(std::to_string(ui->TimeGainCompensationMaxSlider->value()))); - ui->TimeGainCompensationMaxLabel->setText(text); - m_ControlInterface->SetTGCMax(ui->TimeGainCompensationMaxSlider->value()); -} - -void QmitkUSControlsCustomDiPhASDeviceWidget::OnDataTypeChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - QString DataType = ui->DataType->currentText(); - if (DataType == "Image Data") { - m_ControlInterface->SetDataType(mitk::USDiPhASDeviceCustomControls::DataType::Image_uChar); - } - else if (DataType == "Beamformed Data") { - m_ControlInterface->SetDataType(mitk::USDiPhASDeviceCustomControls::DataType::Beamformed_Short); - } -} - -//Beamforming -void QmitkUSControlsCustomDiPhASDeviceWidget::OnPitchChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetPitch(ui->PitchOfTransducer->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnReconstructedSamplesChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - m_ControlInterface->SetReconstructedSamples(ui->ReconstructedSamplesPerLine->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnReconstructedLinesChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - if (m_OldReconstructionLines == 0) - m_OldReconstructionLines = ui->ReconstructedLines->value(); - - m_ControlInterface->SetReconstructedLines(ui->ReconstructedLines->value()); - - ui->PitchOfTransducer->setValue(ui->PitchOfTransducer->value()*((double)m_OldReconstructionLines / (double)ui->ReconstructedLines->value())); - m_OldReconstructionLines = ui->ReconstructedLines->value(); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnSpeedOfSoundChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - - m_ControlInterface->SetSpeedOfSound(ui->SpeedOfSound->value()); -} - -//Bandpass -void QmitkUSControlsCustomDiPhASDeviceWidget::OnBandpassEnabledChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - - if (ui->BandpassEnabled->currentText() == "On") { - m_ControlInterface->SetBandpassEnabled(true); - } - else { - m_ControlInterface->SetBandpassEnabled(false); - } -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnLowCutChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - - unsigned int Low = ui->LowCut->value(); - unsigned int High = ui->HighCut->value(); - if (Low > High) { - ui->LowCut->setValue(High); - MITK_INFO << "User tried to set LowCut>HighCut."; - } - - m_ControlInterface->SetLowCut(ui->LowCut->value()); -} -void QmitkUSControlsCustomDiPhASDeviceWidget::OnHighCutChanged() -{ - if (m_ControlInterface.IsNull()) { return; } - - unsigned int Low = ui->LowCut->value(); - unsigned int High = ui->HighCut->value(); - if (Low > High) { - ui->HighCut->setValue(Low); - MITK_INFO << "User tried to set LowCut>HighCut."; - } - - m_ControlInterface->SetHighCut(ui->HighCut->value()); -} diff --git a/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.h b/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.h deleted file mode 100644 index e8e1043630..0000000000 --- a/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.h +++ /dev/null @@ -1,113 +0,0 @@ - -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef QmitkUSControlsCustomDiPhASDeviceWidget_H -#define QmitkUSControlsCustomDiPhASDeviceWidget_H - -#include "QmitkUSAbstractCustomWidget.h" -#include "mitkUSDiPhASDeviceCustomControls.h" - -#include "mitkUSDevice.h" - -#include - -namespace Ui { -class QmitkUSControlsCustomDiPhASDeviceWidget; -} - -/** \brief Widget for custom controls of mitk::USDiPhASDevice. - * This class handles the itk::USDiPhASDeviceCustomControls of video device - * objects. - */ -class QmitkUSControlsCustomDiPhASDeviceWidget : public QmitkUSAbstractCustomWidget -{ - Q_OBJECT - -private slots: - virtual void OnCompensateEnergyChanged(); - virtual void OnUseBModeFilterChanged(); - virtual void OnVerticalSpacingChanged(); - virtual void OnRecordChanged(); - virtual void OnScatteringCoefficientChanged(); - virtual void OnCompensateScatteringChanged(); - virtual void OnChangedSavingSettings(); - - //Transmit - virtual void OnTransmitPhaseLengthChanged(); - virtual void OnExcitationFrequencyChanged(); - virtual void OnTransmitEventsChanged(); - virtual void OnVoltageChanged(); - virtual void OnModeChanged(); - - //Receive - virtual void OnScanDepthChanged(); - virtual void OnAveragingCountChanged(); - virtual void OnTGCMinChanged(); - virtual void OnTGCMaxChanged(); - virtual void OnDataTypeChanged(); - - //Beamforming - virtual void OnPitchChanged(); - virtual void OnReconstructedSamplesChanged(); - virtual void OnReconstructedLinesChanged(); - virtual void OnSpeedOfSoundChanged(); - - //Bandpass - virtual void OnBandpassEnabledChanged(); - virtual void OnLowCutChanged(); - virtual void OnHighCutChanged(); - -public: - /** - * Constructs widget object. All gui control elements will be disabled until - * QmitkUSAbstractCustomWidget::SetDevice() was called. - */ - QmitkUSControlsCustomDiPhASDeviceWidget(); - ~QmitkUSControlsCustomDiPhASDeviceWidget() override; - - /** - * Getter for the device class of mitk:USDiPhASDevice. - */ - std::string GetDeviceClass() const override; - - /** - * Creates new QmitkUSAbstractCustomWidget with the same mitk::USDiPhASDevice - * and the same mitk::USDiPhASDeviceCustomControls which were set on the - * original object. - * - * This method is just for being calles by the factory. Use - * QmitkUSAbstractCustomWidget::CloneForQt() instead, if you want a clone of - * an object. - */ - QmitkUSAbstractCustomWidget* Clone(QWidget* parent = nullptr) const override; - - /** - * Gets control interface from the device which was currently set. Control - * elements are according to current crop area of the device. If custom - * control interface is null, the control elements stay disabled. - */ - void OnDeviceSet() override; - - void Initialize() override; - -protected: - void BlockSignalAndSetValue(QSpinBox* target, int value); - -private: - QmitkUSControlsCustomDiPhASDeviceWidget(QWidget *parent); - Ui::QmitkUSControlsCustomDiPhASDeviceWidget* ui; - mitk::USDiPhASDeviceCustomControls::Pointer m_ControlInterface; - int m_OldReconstructionLines; -}; - -#endif // QmitkUSControlsCustomDiPhASDeviceWidget_H diff --git a/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.ui b/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.ui deleted file mode 100644 index f45bef1372..0000000000 --- a/Modules/USUI/Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.ui +++ /dev/null @@ -1,663 +0,0 @@ - - - QmitkUSControlsCustomDiPhASDeviceWidget - - - - 0 - 0 - 351 - 903 - - - - Form - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - QFrame::WinPanel - - - QFrame::Raised - - - Started - - - Qt::AlignCenter - - - - - - - <html><head/><body><p><span style=" font-weight:600;">Record Images</span></p></body></html> - - - - - - - - - - - Save Beamformed - - - - - - - Save Raw - - - - - - - - - - 100 - 25 - - - - Start Recording - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - <html><head/><body><p><span style=" font-weight:600;">Receive Parameters</span></p></body></html> - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - 42 - - - 10 - - - Qt::Horizontal - - - - - - - 42 - - - 20 - - - Qt::Horizontal - - - 0 - - - - - - - Scan Depth [mm] - - - - - - - 1 - - - 100 - - - 1 - - - - - - - Averaging Count - - - - - - - false - - - - Beamformed Data - - - - - Image Data - - - - - - - - 3.000000000000000 - - - 200.000000000000000 - - - 50.000000000000000 - - - - - - - DataType - - - - - - - TGC Min - - - - - - - TGC Max - - - - - - - - - - - Compensate Fluence For Scattering - - - - - - - - - false - - - 5 - - - 25 - - - 15 - - - - - - - false - - - Avg. μs' [1/cm] - - - - - - - - - - - <html><head/><body><p><span style=" font-weight:600;">Beamforming Parameters</span></p></body></html> - - - - - - - - - 256 - - - 4096 - - - 256 - - - 2048 - - - - - - - 0.010000000000000 - - - 0.050000000000000 - - - 0.300000000000000 - - - - - - - Qt::PreventContextMenu - - - 128 - - - 1024 - - - 128 - - - 128 - - - - - - - Samples per Line - - - - - - - Reconstructed Lines - - - - - - - 1000 - - - 1000000 - - - 5 - - - 1480 - - - - - - - Speed of Sound [m/s] - - - - - - - Pitch of Transducer [mm] - - - - - - - - - <html><head/><body><p><span style=" font-weight:600;">Display Parameters</span></p></body></html> - - - - - - - - - Envelope Filter - - - true - - - - - - - Compensate Energy Values - - - - - - - - - 0.010000000000000 - - - 1.200000000000000 - - - 0.050000000000000 - - - 0.300000000000000 - - - - - - - Vertical Spacing - - - - - - - - - - - <html><head/><body><p><span style=" font-weight:600;">Transmit Parameters</span></p></body></html> - - - - - - - - - 1.000000000000000 - - - 15.000000000000000 - - - 0.100000000000000 - - - 7.500000000000000 - - - - - - - 1 - - - 11 - - - 2 - - - 1 - - - - - - - Transmit Events - - - - - - - true - - - false - - - 1 - - - 1.000000000000000 - - - 10000.000000000000000 - - - 4.000000000000000 - - - - - - - Transmit Phase Length [us] - - - - - - - Excitation Frequency [MHz] - - - - - - - false - - - - Interleaved - - - - - Ultrasound only - - - - - - - - false - - - 6 - - - 75 - - - 70 - - - - - - - Voltage [V] - - - - - - - Mode - - - - - - - - - false - - - <html><head/><body><p><span style=" font-weight:600;">Bandpass Parameters</span></p></body></html> - - - - - - - - - false - - - High Cut [MHz] - - - - - - - false - - - Low Cut [MHz] - - - - - - - false - - - Bandpass Enabled - - - - - - - false - - - - - - - false - - - 5.000000000000000 - - - - - - - false - - - - Off - - - - - On - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff --git a/Modules/USUI/files.cmake b/Modules/USUI/files.cmake index 828924aadc..70fadd9c46 100644 --- a/Modules/USUI/files.cmake +++ b/Modules/USUI/files.cmake @@ -1,37 +1,34 @@ set(CPP_FILES mitkUSUIActivator.cpp Qmitk/QmitkUSDeviceManagerWidget.cpp Qmitk/QmitkUSNewVideoDeviceWidget.cpp Qmitk/QmitkUSControlsBModeWidget.cpp Qmitk/QmitkUSControlsDopplerWidget.cpp Qmitk/QmitkUSControlsProbesWidget.cpp Qmitk/QmitkUSControlsCustomVideoDeviceWidget.cpp - Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.cpp Qmitk/QmitkUSAbstractCustomWidget.cpp Qmitk/QmitkComboBoxStepThrough.cpp ) set(UI_FILES Qmitk/QmitkUSDeviceManagerWidgetControls.ui Qmitk/QmitkUSNewVideoDeviceWidgetControls.ui Qmitk/QmitkUSControlsBModeWidget.ui Qmitk/QmitkUSControlsDopplerWidget.ui Qmitk/QmitkUSControlsProbesWidget.ui Qmitk/QmitkUSControlsCustomVideoDeviceWidget.ui - Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.ui ) set(MOC_H_FILES Qmitk/QmitkUSDeviceManagerWidget.h Qmitk/QmitkUSNewVideoDeviceWidget.h Qmitk/QmitkUSControlsBModeWidget.h Qmitk/QmitkUSControlsDopplerWidget.h Qmitk/QmitkUSControlsProbesWidget.h Qmitk/QmitkUSControlsCustomVideoDeviceWidget.h - Qmitk/QmitkUSControlsCustomDiPhASDeviceWidget.h Qmitk/QmitkUSAbstractCustomWidget.h Qmitk/QmitkComboBoxStepThrough.h ) set(QRC_FILES resources/USUI.qrc ) diff --git a/Modules/USUI/mitkUSUIActivator.cpp b/Modules/USUI/mitkUSUIActivator.cpp index 5e2a510c6c..08e217f7ae 100644 --- a/Modules/USUI/mitkUSUIActivator.cpp +++ b/Modules/USUI/mitkUSUIActivator.cpp @@ -1,42 +1,40 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSUIActivator.h" #include "QmitkUSControlsCustomVideoDeviceWidget.h" -#include "QmitkUSControlsCustomDiPhASDeviceWidget.h" mitk::USUIActivator::USUIActivator() { } mitk::USUIActivator::~USUIActivator() { } void mitk::USUIActivator::Load(us::ModuleContext* context) { m_USCustomWidgets.push_back(new QmitkUSControlsCustomVideoDeviceWidget()); - m_USCustomWidgets.push_back(new QmitkUSControlsCustomDiPhASDeviceWidget()); for (auto &widget : m_USCustomWidgets) { context->RegisterService(widget, widget->GetServiceProperties()); } } void mitk::USUIActivator::Unload(us::ModuleContext* /*context*/) { for (auto &widget : m_USCustomWidgets) { delete widget; } } diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 0d16bd73bc..ac518360a0 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,97 +1,90 @@ # Plug-ins must be ordered according to their dependencies set(MITK_PLUGINS org.blueberry.core.runtime:ON org.blueberry.core.expressions:OFF org.blueberry.core.commands:OFF org.blueberry.core.jobs:OFF org.blueberry.ui.qt:OFF org.blueberry.ui.qt.help:ON org.blueberry.ui.qt.log:ON org.blueberry.ui.qt.objectinspector:OFF org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.mitkworkbench.intro:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.mxnmultiwidgeteditor:OFF org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.chartExample:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.datastorageviewertest:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicombrowser:OFF org.mitk.gui.qt.dicominspector:OFF org.mitk.gui.qt.dosevisualization:OFF org.mitk.gui.qt.geometrytools:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF - org.mitk.gui.qt.lasercontrol:OFF org.mitk.gui.qt.openigtlink:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.pointsetinteractionmultispectrum:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.deformableclippingplane:OFF org.mitk.gui.qt.aicpregistration:OFF org.mitk.gui.qt.renderwindowmanager:OFF org.mitk.gui.qt.semanticrelations:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.tubegraph:OFF org.mitk.gui.qt.ugvisualization:OFF - org.mitk.gui.qt.photoacoustics.pausviewer:OFF - org.mitk.gui.qt.photoacoustics.pausmotioncompensation:OFF - org.mitk.gui.qt.photoacoustics.imageprocessing:OFF - org.mitk.gui.qt.photoacoustics.simulation:OFF - org.mitk.gui.qt.photoacoustics.spectralunmixing:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF org.mitk.gui.qt.igt.app.ultrasoundtrackingnavigation:OFF - org.mitk.gui.qt.spectrocamrecorder:OFF org.mitk.gui.qt.classificationsegmentation:OFF org.mitk.gui.qt.overlaymanager:OFF org.mitk.gui.qt.igt.app.hummelprotocolmeasurements:OFF org.mitk.gui.qt.multilabelsegmentation:OFF org.mitk.matchpoint.core.helper:OFF org.mitk.gui.qt.matchpoint.algorithm.browser:OFF org.mitk.gui.qt.matchpoint.algorithm.control:OFF org.mitk.gui.qt.matchpoint.mapper:OFF org.mitk.gui.qt.matchpoint.framereg:OFF org.mitk.gui.qt.matchpoint.visualizer:OFF org.mitk.gui.qt.matchpoint.evaluator:OFF org.mitk.gui.qt.matchpoint.manipulator:OFF org.mitk.gui.qt.preprocessing.resampling:OFF org.mitk.gui.qt.radiomics:OFF org.mitk.gui.qt.cest:OFF org.mitk.gui.qt.fit.demo:OFF org.mitk.gui.qt.fit.inspector:OFF org.mitk.gui.qt.fit.genericfitting:OFF org.mitk.gui.qt.pharmacokinetics.mri:OFF org.mitk.gui.qt.pharmacokinetics.pet:OFF org.mitk.gui.qt.pharmacokinetics.simulation:OFF org.mitk.gui.qt.pharmacokinetics.curvedescriptor:OFF org.mitk.gui.qt.pharmacokinetics.concentration.mri:OFF org.mitk.gui.qt.flowapplication:OFF org.mitk.gui.qt.flow.segmentation:OFF ) diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/CMakeLists.txt b/Plugins/org.mitk.gui.qt.lasercontrol/CMakeLists.txt deleted file mode 100644 index d22b896c7e..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -project(org_mitk_gui_qt_lasercontrol) - -if(WIN32) - foreach(config_type ${CMAKE_CONFIGURATION_TYPES}) - execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${MITK_BINARY_DIR}/bin/${config_type}") - endforeach() - if(MITK_USE_GALIL_HARDWARE) - configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclib.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY ) - configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclibo.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY ) - configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclib.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY ) - configure_file( ${MITK_GALIL_API_PATH}/dll/x64/gclibo.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY ) - endif() - if(MITK_USE_OPHIR_PYRO_HARDWARE) - configure_file( ${MITK_OPHIR_API_PATH}/Debug/OphirPyroWrapper.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY ) - configure_file( ${MITK_OPHIR_API_PATH}/Release/OphirPyroWrapper.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY ) - configure_file( ${MITK_OPHIR_API_PATH}/Debug/OphirLMMeasurement.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY ) - configure_file( ${MITK_OPHIR_API_PATH}/Release/OphirLMMeasurement.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY ) - configure_file( ${MITK_OPHIR_API_PATH}/Debug/Interop.OphirLMMeasurementLib.dll ${MITK_BINARY_DIR}/bin/Debug/ COPYONLY ) - configure_file( ${MITK_OPHIR_API_PATH}/Release/Interop.OphirLMMeasurementLib.dll ${MITK_BINARY_DIR}/bin/Release/ COPYONLY ) - endif() -endif() - -mitk_create_plugin( - EXPORT_DIRECTIVE LASERCONTROL_EXPORT - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkQtWidgetsExt MitkPhotoacousticsHardware -) diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/files.cmake b/Plugins/org.mitk.gui.qt.lasercontrol/files.cmake deleted file mode 100644 index ebb9b41a94..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/files.cmake +++ /dev/null @@ -1,37 +0,0 @@ -set(SRC_CPP_FILES - -) - -set(INTERNAL_CPP_FILES - mitkLaserControlPluginActivator.cpp - QmitkLaserControl.cpp - -) - -set(UI_FILES - src/internal/QmitkLaserControlControls.ui -) - -set(MOC_H_FILES - src/internal/mitkLaserControlPluginActivator.h - src/internal/QmitkLaserControl.h -) - -set(CACHED_RESOURCE_FILES - resources/iconLaserControl.svg - plugin.xml -) - -set(QRC_FILES - -) - -set(CPP_FILES) - -foreach(file ${SRC_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/${file}) -endforeach(file ${SRC_CPP_FILES}) - -foreach(file ${INTERNAL_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/internal/${file}) -endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.lasercontrol/manifest_headers.cmake deleted file mode 100644 index 11faba1fd4..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "MITK OPO Laser Control") -set(Plugin-Version "0.1") -set(Plugin-Vendor "German Cancer Research Center (DKFZ)") -set(Plugin-ContactAddress "http://www.mitk.org") -set(Require-Plugin org.mitk.gui.qt.common.legacy) diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/plugin.xml b/Plugins/org.mitk.gui.qt.lasercontrol/plugin.xml deleted file mode 100644 index e2c8781409..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/plugin.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaser.xpm b/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaser.xpm deleted file mode 100644 index e2c5d7c620..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaser.xpm +++ /dev/null @@ -1,133 +0,0 @@ -/* XPM */ -static char * iconLaser_xpm[] = { -"128 128 2 1", -" c None", -". c #000000", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .......... ", -" .. .......... ", -" .... .......... ", -" ....... .......... ", -" ........ .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" .......... .......... ", -" ......... .......... ", -" .......... .......... ", -" ......... .......... ", -" .......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .......... ", -" ......... .............. ", -" ......... .................. ", -" ...... .................... ", -" .... ...................... ", -" .. ........................ ", -" ........................ ", -" .......................... ", -" ............................ ", -" ............................ ", -" ............................ ", -" .............................. .................. ", -" .............................. ........................................ ", -" .............................. ........................................ ", -" .............................. ........................................ ", -" .............................. ......................................... ", -" .............................. ................................. ", -" .............................. ..... ", -" ............................ ", -" ............................ ", -" ............................ ", -" .......................... ", -" . ........................ ", -" ... ........................ ", -" ...... ...................... ", -" ........ .................... ", -" ........... .................. .. ", -" ........... .............. .... ", -" .......... .......... ....... ", -" ......... ........ ", -" ........ . ........ ", -" ..... ... ........ ", -" ... ...... ........ ", -" ... ..... ....... ", -" ..... ...... ....... ", -" ..... ..... ....... ", -" ..... ...... ....... ", -" ...... ..... ....... ", -" ..... ...... ....... ", -" ..... ..... ....... ", -" ..... ...... ....... ", -" ...... ..... ....... ", -" ..... ...... ........ ", -" ..... ..... ........ ", -" ..... ...... ........ ", -" ...... ..... ........ ", -" ..... ...... ....... ", -" ..... ..... ....... ", -" ..... ...... ....... ", -" ...... ..... ....... ", -" ..... ...... ....... ", -" ..... ..... ....... ", -" ..... ...... ....... ", -" ...... ..... ....... ", -" ..... ...... ....... ", -" ..... ..... ....... ", -" ..... ...... ........ ", -" ...... ..... ........ ", -" ..... ...... ........ ", -" ..... ...... ........ ", -" ..... ...... ........ ", -" ...... ...... ..... ", -" ..... ...... ... ", -" ..... ...... . ", -" ..... ...... ", -" ...... ..... ", -" ..... ... ", -" . ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaserControl.svg b/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaserControl.svg deleted file mode 100644 index 639a54b9c3..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/resources/iconLaserControl.svg +++ /dev/null @@ -1,88 +0,0 @@ - -image/svg+xml diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControl.cpp b/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControl.cpp deleted file mode 100644 index 35d1bde864..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControl.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// Blueberry -#include -#include - -// Qmitk -#include "QmitkLaserControl.h" - -// Qt -#include -#include - -const std::string OPOLaserControl::VIEW_ID = "org.mitk.views.lasercontrol"; - -void OPOLaserControl::SetFocus() -{ -} - -void OPOLaserControl::CreateQtPartControl(QWidget *parent) -{ - // create GUI widgets from the Qt Designer's .ui file - m_Controls.setupUi(parent); - connect(m_Controls.buttonInitLaser, SIGNAL(clicked()), this, SLOT(InitResetLaser())); - connect(m_Controls.buttonTune, SIGNAL(clicked()), this, SLOT(TuneWavelength())); - connect(m_Controls.buttonFastTuning, SIGNAL(clicked()), this, SLOT(StartFastTuning())); - connect(m_Controls.buttonFlashlamp, SIGNAL(clicked()), this, SLOT(ToggleFlashlamp())); - connect(m_Controls.buttonQSwitch, SIGNAL(clicked()), this, SLOT(ToggleQSwitch())); - connect(m_Controls.sliderWavelength, SIGNAL(valueChanged(int)), this, SLOT(SyncWavelengthSetBySlider())); - connect(m_Controls.spinBoxWavelength, SIGNAL(valueChanged(double)), this, SLOT(SyncWavelengthSetBySpinBox())); - connect(&m_ShutterWatcher, SIGNAL(finished()), this, SLOT(EnableLaser())); - - m_SyncFromSpinBox = true; - m_SyncFromSlider = true; - - m_PumpLaserConnected = false; - m_OPOConnected = false; - m_PyroConnected = false; -} - -void OPOLaserControl::EnableLaser() -{ - m_Controls.buttonQSwitch->setEnabled(true); - m_Controls.buttonQSwitch->setText("Start Laser"); - this->GetState(); -} - -void OPOLaserControl::SyncWavelengthSetBySlider() -{ - if (m_SyncFromSlider) - { - m_SyncFromSpinBox = false; - m_Controls.spinBoxWavelength->setValue(m_Controls.sliderWavelength->value() / 10); - } - else - m_SyncFromSlider = true; -} - -void OPOLaserControl::SyncWavelengthSetBySpinBox() -{ - if (m_SyncFromSpinBox) - { - m_SyncFromSlider = false; - m_Controls.sliderWavelength->setValue(m_Controls.spinBoxWavelength->value() * 10); - } - else - m_SyncFromSpinBox = true; -} - -void OPOLaserControl::InitResetLaser() -{ - m_Controls.buttonInitLaser->setEnabled(false); - m_Controls.buttonInitLaser->setText("working ..."); - - if (!m_PumpLaserConnected && !m_OPOConnected) - { - m_PumpLaserController = mitk::QuantelLaser::New(); - m_OPOMotor = mitk::GalilMotor::New(); - InitThread *initThread = new InitThread(m_PumpLaserController, m_OPOMotor); - connect(initThread, SIGNAL(result(bool, bool)), this, SLOT(InitLaser(bool, bool))); - connect(initThread, SIGNAL(finished()), initThread, SLOT(deleteLater())); - initThread->start(); - } - else - { - // destroy and free - m_Controls.buttonFlashlamp->setEnabled(false); - m_Controls.buttonQSwitch->setEnabled(false); - m_Controls.buttonTune->setEnabled(false); - m_Controls.buttonFastTuning->setEnabled(false); - - ResetThread *resetThread = new ResetThread(m_PumpLaserController, m_OPOMotor); - connect(resetThread, SIGNAL(result(bool, bool)), this, SLOT(ResetLaser(bool, bool))); - connect(resetThread, SIGNAL(finished()), resetThread, SLOT(deleteLater())); - resetThread->start(); - } - /* - try - { - if (!m_PyroConnected) - { - m_Pyro = mitk::OphirPyro::New(); - MITK_INFO << "[Pyro Debug] OpenConnection: " << m_Pyro->OpenConnection(); - MITK_INFO << "[Pyro Debug] StartDataAcquisition: " << m_Pyro->StartDataAcquisition(); - m_CurrentPulseEnergy = 0; - m_PyroConnected = true; - //QFuture future = QtConcurrent::run(this, &OPOLaserControl::ShowEnergy); - //m_EnergyWatcher.setFuture(future); - } - else - { - m_PyroConnected = false; - } - } catch (...) { - MITK_INFO << " While trying to connect to the Pyro an exception was caught (this almost always happens on the first try after reboot - try again!)"; - m_PyroConnected = false; - }*/ -} - -void OPOLaserControl::InitLaser(bool successLaser, bool successMotor) -{ - if (successLaser && successMotor) - { - m_Controls.buttonFlashlamp->setEnabled(true); - m_Controls.buttonQSwitch->setEnabled(false); - m_Controls.buttonInitLaser->setText("Reset and Release Laser"); - - std::string answer(""); - std::string triggerCommand("TRIG "); - if (m_Controls.checkBoxTriggerExternally->isChecked()) - { - triggerCommand.append("EE"); // set both Triggers external - m_PumpLaserController->SendAndReceiveLine(&triggerCommand, &answer); - MITK_INFO << answer; - } - else - { - triggerCommand.append("II"); // set both Triggers internal - m_PumpLaserController->SendAndReceiveLine(&triggerCommand, &answer); - MITK_INFO << answer; - std::string energyCommand("QDLY 30"); - m_PumpLaserController->SendAndReceiveLine(&energyCommand, &answer); - MITK_INFO << answer; - } - - m_PumpLaserConnected = true; - - m_Controls.buttonTune->setEnabled(true); - m_Controls.buttonFastTuning->setEnabled(true); - m_Controls.sliderWavelength->setMinimum(m_OPOMotor->GetMinWavelength() * 10); - m_Controls.sliderWavelength->setMaximum(m_OPOMotor->GetMaxWavelength() * 10); - m_Controls.spinBoxWavelength->setMinimum(m_OPOMotor->GetMinWavelength()); - m_Controls.spinBoxWavelength->setMaximum(m_OPOMotor->GetMaxWavelength()); - m_Controls.sliderWavelength->setValue(m_OPOMotor->GetCurrentWavelength() * 10); - m_Controls.spinBoxWavelength->setValue(m_OPOMotor->GetCurrentWavelength()); - - m_OPOConnected = true; // not always right FIXME - - this->GetState(); - } - else - { - if(!successLaser) - QMessageBox::warning(NULL, "Laser Control", "Opotek Pump Laser Initialization Failed."); - if(!successMotor) - QMessageBox::warning(NULL, "Laser Control", "OPO Initialization Failed."); - - m_Controls.buttonInitLaser->setText("Init Laser"); - return; - } - - m_Controls.buttonInitLaser->setEnabled(true); - this->GetState(); -} - -void OPOLaserControl::ResetLaser(bool successLaser, bool successMotor) -{ - if (successLaser && successMotor) - { - m_Controls.buttonFlashlamp->setEnabled(false); - m_Controls.buttonQSwitch->setEnabled(false); - m_Controls.buttonInitLaser->setText("Init Laser"); - m_PumpLaserConnected = false; - - m_Controls.buttonTune->setEnabled(false); - m_Controls.buttonFastTuning->setEnabled(false); - m_Controls.buttonInitLaser->setText("Init Laser"); - m_OPOConnected = false; - } - else - { - if(!successMotor) - QMessageBox::warning(NULL, "Laser Control", "OPO Release Failed."); - if(!successLaser) - QMessageBox::warning(NULL, "Laser Control", "Opotek Pump Laser Release Failed."); - - m_Controls.buttonInitLaser->setText("Reset and Release Laser"); - } - - m_Controls.buttonInitLaser->setEnabled(true); - this->GetState(); -} - -void OPOLaserControl::TuneWavelength() -{ - if (m_Controls.checkBoxCalibration->isChecked()) - { - m_OPOMotor->TuneToWavelength(m_Controls.spinBoxPosition->value(), true); - } - else - { - m_OPOMotor->TuneToWavelength(m_Controls.spinBoxWavelength->value(), false); - } - QString wavelengthText = QString::number(m_OPOMotor->GetCurrentWavelength()); - wavelengthText.append("nm"); - m_Controls.labelWavelength->setText(wavelengthText); -} - -void OPOLaserControl::StartFastTuning() -{ - std::vector listOfWavelengths; - double tmpWavelength = 0; - int currentRow = 0; - bool success = false; - - do - { - if (currentRow != 0) listOfWavelengths.push_back(tmpWavelength); - if (m_Controls.tableFastTuningWavelengths->item(0, currentRow)) - { - QString test = m_Controls.tableFastTuningWavelengths->item(0, currentRow)->text(); - tmpWavelength = test.toDouble(&success); - currentRow++; - } - else - tmpWavelength = 0; - - if (success == 0) - tmpWavelength = 0; - } while (tmpWavelength<950.1 && tmpWavelength>689.9); - - m_OPOMotor->FastTuneWavelengths(listOfWavelengths); -} - -void OPOLaserControl::ShutterCountDown() -{ - m_Controls.buttonFlashlamp->setText("Stop Lamp"); - m_Controls.buttonQSwitch->setEnabled(false); - m_Controls.buttonQSwitch->setText("10s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("9s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("8s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("7s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("6s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("5s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("4s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("3s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("2s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - m_Controls.buttonQSwitch->setText("1s ..."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - return; -} - -void OPOLaserControl::ShowEnergy() -{ - /*forever - { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - MITK_INFO << "[Pyro Debug] ShowEnergy()"; - if (!m_PyroConnected) - { - MITK_INFO << "[Pyro Debug] StopDataAcquisition: " << m_Pyro->StopDataAcquisition(); - MITK_INFO << "[Pyro Debug] CloseConnection: " << m_Pyro->CloseConnection(); - m_CurrentPulseEnergy = 0; - return; - } - // m_Pyro->GetDataFromSensor(); - m_CurrentPulseEnergy = 60000 * m_Pyro->LookupCurrentPulseEnergy(); - m_Controls.labelEnergy->setText(std::to_string(m_CurrentPulseEnergy).append(" mJ").c_str()); - }*/ -} - -void OPOLaserControl::ToggleFlashlamp() -{ - m_Controls.buttonFlashlamp->setText("..."); - if (!m_PumpLaserController->IsFlashing()) - { - if (m_PumpLaserController->StartFlashing()) - { - QFuture future = QtConcurrent::run(this, &OPOLaserControl::ShutterCountDown); - m_ShutterWatcher.setFuture(future); - } - else - m_Controls.buttonFlashlamp->setText("Start Lamp"); - } - else - { - if (m_PumpLaserController->StopFlashing()) - { - m_Controls.buttonFlashlamp->setText("Start Lamp"); - m_Controls.buttonQSwitch->setText("Start Laser"); - m_Controls.buttonQSwitch->setEnabled(false); - } - else - m_Controls.buttonFlashlamp->setText("Stop Lamp"); - } - this->GetState(); -} - -void OPOLaserControl::ToggleQSwitch() -{ - m_Controls.buttonQSwitch->setText("..."); - if (!m_PumpLaserController->IsEmitting()) - { - if (m_PumpLaserController->StartQswitching()) - m_Controls.buttonQSwitch->setText("Stop Laser"); - else - m_Controls.buttonQSwitch->setText("Start Laser"); - } - else - { - if (m_PumpLaserController->StopQswitching()) - m_Controls.buttonQSwitch->setText("Start Laser"); - else - m_Controls.buttonQSwitch->setText("Stop Laser"); - } - this->GetState(); -} - -void OPOLaserControl::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, - const QList& nodes) -{ -} - -void OPOLaserControl::GetState() -{ - mitk::QuantelLaser::LaserState pumpLaserState = m_PumpLaserController->GetState(); - - if (pumpLaserState == mitk::QuantelLaser::STATE0) - m_Controls.labelStatus->setText("PL0: Boot Fault."); - else if (pumpLaserState == mitk::QuantelLaser::STATE1) - m_Controls.labelStatus->setText("PL1: Warm Up."); - else if (pumpLaserState == mitk::QuantelLaser::STATE2) - m_Controls.labelStatus->setText("PL2: Laser Ready."); - else if (pumpLaserState == mitk::QuantelLaser::STATE3) - m_Controls.labelStatus->setText("PL3: Flashing. Pulse Disabled."); - else if (pumpLaserState == mitk::QuantelLaser::STATE4) - m_Controls.labelStatus->setText("PL4: Flashing. Shutter Closed."); - else if (pumpLaserState == mitk::QuantelLaser::STATE5) - m_Controls.labelStatus->setText("PL5: Flashing. Shutter Open."); - else if (pumpLaserState == mitk::QuantelLaser::STATE6) - m_Controls.labelStatus->setText("PL6: Flashing. Pulse Enabled."); - else if (pumpLaserState == mitk::QuantelLaser::STATE7) - m_Controls.labelStatus->setText("PL7: Undefined State."); - else if (pumpLaserState == mitk::QuantelLaser::UNCONNECTED) - m_Controls.labelStatus->setText("PL Not Connected."); -} diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControl.h b/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControl.h deleted file mode 100644 index fe93a60379..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControl.h +++ /dev/null @@ -1,138 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef OPOLaserControl_h -#define OPOLaserControl_h - -#include - -#include - -#include "ui_QmitkLaserControlControls.h" - -#include -#include -#include - -// Photoacoustics Hardware -#include -#include -//#include - -#include - -/** - \brief OPOLaserControl - - \warning This class is not yet documented. Use "git blame" and ask the author why he is a lazy fuck. - - \sa QmitkAbstractView - \ingroup ${plugin_target}_internal -*/ -class OPOLaserControl : public QmitkAbstractView -{ - // this is needed for all Qt objects that should have a Qt meta-object - // (everything that derives from QObject and wants to have signal/slots) - Q_OBJECT - -public: - - static const std::string VIEW_ID; - - protected slots: - - /// \brief Called when the user clicks the GUI button - void GetState(); - - void InitLaser(bool successLaser, bool successMotor); - void ResetLaser(bool successLaser, bool successMotor); - void InitResetLaser(); - void TuneWavelength(); - void StartFastTuning(); - - void ShutterCountDown(); - void EnableLaser(); - void ShowEnergy(); - - void ToggleFlashlamp(); - void ToggleQSwitch(); - void SyncWavelengthSetBySlider(); - void SyncWavelengthSetBySpinBox(); - - protected: - - virtual void CreateQtPartControl(QWidget *parent) override; - - virtual void SetFocus() override; - - /// \brief called by QmitkFunctionality when DataManager's selection has changed - virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, - const QList& nodes ) override; - - Ui::OPOLaserControlControls m_Controls; - bool m_PumpLaserConnected; - bool m_OPOConnected; - bool m_PyroConnected; - bool m_SyncFromSpinBox; - bool m_SyncFromSlider; - double m_CurrentPulseEnergy; - - QFutureWatcher m_ShutterWatcher; - QFutureWatcher m_EnergyWatcher; - - mitk::QuantelLaser::Pointer m_PumpLaserController; - mitk::GalilMotor::Pointer m_OPOMotor; - //mitk::OphirPyro::Pointer m_Pyro; - -}; - -class InitThread : public QThread -{ - Q_OBJECT - void run() Q_DECL_OVERRIDE - { - emit result(m_PumpLaserController->OpenConnection("OpotekPhocusMobile"), m_OPOMotor->OpenConnection("OpotekPhocusMobile")); - } - signals: - void result(bool, bool); - public: - InitThread(mitk::QuantelLaser::Pointer ql, mitk::GalilMotor::Pointer gm) - { - m_PumpLaserController = ql; - m_OPOMotor = gm; - } - mitk::QuantelLaser::Pointer m_PumpLaserController; - mitk::GalilMotor::Pointer m_OPOMotor; -}; - -class ResetThread : public QThread -{ - Q_OBJECT - void run() Q_DECL_OVERRIDE - { - emit result(m_PumpLaserController->CloseConnection(), m_OPOMotor->CloseConnection()); - } -signals: - void result(bool, bool); -public: - ResetThread(mitk::QuantelLaser::Pointer ql, mitk::GalilMotor::Pointer gm) - { - m_PumpLaserController = ql; - m_OPOMotor = gm; - } - mitk::QuantelLaser::Pointer m_PumpLaserController; - mitk::GalilMotor::Pointer m_OPOMotor; -}; - -#endif // OPOLaserControl_h - diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControlControls.ui b/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControlControls.ui deleted file mode 100644 index 8eb85c86e6..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/QmitkLaserControlControls.ui +++ /dev/null @@ -1,775 +0,0 @@ - - - OPOLaserControlControls - - - - 0 - 0 - 343 - 528 - - - - - 0 - 0 - - - - - 9 - - - - QmitkTemplate - - - - - - - - - 9 - - - - OPOTEK Phocus Control - - - - - 10 - 20 - 301 - 431 - - - - - - - true - - - - 10 - - - - Trigger Externally - - - true - - - - - - - - 10 - - - - Init Laser - - - - - - - - - false - - - - 10 - - - - Start Lamp - - - - - - - false - - - - 10 - - - - Start Laser - - - - - - - - - - 11 - 75 - true - - - - Laser Status - - - - - - - - - Current Wavelength - - - - - - - - 10 - 75 - true - PreferDefault - true - - - - 750.0 nm - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - Pulse Energy - - - - - - - false - - - - 10 - 75 - true - PreferDefault - true - - - - 0 mJ - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - 6900 - - - 9500 - - - 5 - - - 100 - - - 7500 - - - Qt::Horizontal - - - QSlider::NoTicks - - - 10000 - - - - - - - - - 1 - - - 690.000000000000000 - - - 950.000000000000000 - - - 0.500000000000000 - - - 750.000000000000000 - - - - - - - nm - - - - - - - false - - - Tune - - - - - - - - - - 10 - 50 - false - - - - Fast Tuning Wavelengths - - - - - - - - 0 - 75 - - - - - 16777215 - 75 - - - - - 10 - - - - true - - - Qt::SolidLine - - - 42 - - - 50 - - - 30 - - - 30 - - - - λ/nm - - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 10 - - - - - 11 - - - - - 12 - - - - - 13 - - - - - 14 - - - - - 15 - - - - - 16 - - - - - 17 - - - - - 18 - - - - - 19 - - - - - 20 - - - - - 21 - - - - - 22 - - - - - 23 - - - - - 24 - - - - - 25 - - - - - 26 - - - - - 27 - - - - - 28 - - - - - 29 - - - - - 30 - - - - - 31 - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - 37 - - - - - 38 - - - - - 39 - - - - - 40 - - - - - 700 - - - - - 710 - - - - - 720 - - - - - 730 - - - - - 740 - - - - - 750 - - - - - 760 - - - - - 770 - - - - - 780 - - - - - 790 - - - - - 800 - - - - - 810 - - - - - 820 - - - - - 830 - - - - - 840 - - - - - 850 - - - - - 860 - - - - - 870 - - - - - 880 - - - - - 890 - - - - - 900 - - - - - 910 - - - - - 920 - - - - - 930 - - - - - 940 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - Start Fast Tuning - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - calibrate OPO - - - - - - - 50000 - - - 400 - - - 24400 - - - - - - - - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/mitkLaserControlPluginActivator.cpp b/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/mitkLaserControlPluginActivator.cpp deleted file mode 100644 index 5bc8a2de7c..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/mitkLaserControlPluginActivator.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#include "mitkLaserControlPluginActivator.h" -#include "QmitkLaserControl.h" - -namespace mitk { - -void org_mitk_gui_qt_lasercontrol_Activator::start(ctkPluginContext* context) -{ - BERRY_REGISTER_EXTENSION_CLASS(OPOLaserControl, context) -} - -void org_mitk_gui_qt_lasercontrol_Activator::stop(ctkPluginContext* context) -{ - Q_UNUSED(context) -} - -} diff --git a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/mitkLaserControlPluginActivator.h b/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/mitkLaserControlPluginActivator.h deleted file mode 100644 index dca635ac4f..0000000000 --- a/Plugins/org.mitk.gui.qt.lasercontrol/src/internal/mitkLaserControlPluginActivator.h +++ /dev/null @@ -1,37 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef org_mitk_gui_qt_lasercontrol_Activator_h -#define org_mitk_gui_qt_lasercontrol_Activator_h - -#include - -namespace mitk { - -class org_mitk_gui_qt_lasercontrol_Activator : - public QObject, public ctkPluginActivator -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_lasercontrol") - Q_INTERFACES(ctkPluginActivator) - -public: - - void start(ctkPluginContext* context); - void stop(ctkPluginContext* context); - -}; // org_mitk_gui_qt_lasercontrol_Activator - -} - -#endif // org_mitk_gui_qt_lasercontrol_Activator_h diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/CMakeLists.txt b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/CMakeLists.txt deleted file mode 100644 index 0b44d554e6..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -project(org_mitk_gui_qt_photoacoustics_imageprocessing) - -mitk_create_plugin( - EXPORT_DIRECTIVE IMAGEPROCESSING_EXPORT - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkQtWidgetsExt MitkPhotoacousticsAlgorithms -) - -IF(MITK_USE_OpenCL) - add_definitions(-DPHOTOACOUSTICS_USE_GPU) -ENDIF(MITK_USE_OpenCL) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/Manual.dox deleted file mode 100644 index 4add60b8c5..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/Manual.dox +++ /dev/null @@ -1,66 +0,0 @@ -/** -\page org_mitk_views_photoacoustics_imageprocessing The Photoacoustics Imageprocessing Plugin - -\imageMacro{pai-dox.png,"Icon of Imageprocessing",2.00} - -\tableofcontents - -\section org_mitk_gui_qt_photoacoustics_imageprocessingOverview Overview -This plugin offers an interface to perform image processing on photoacoustic, as well as ultrasound images, i.e. to use beamforming and post-processing filters. -For convenience, image processing can be done automatically for a whole batch of files containing PA or US data. - -\section org_mitk_gui_qt_photoacoustics_imageprocessingPrerequisites Prerequisites -To use the much more performant openCL filters which run on the graphics card, MITK has to be able to use openCL, for which it is necessary to install the openCL implementation provided by your graphics card vendor. - -\section org_mitk_gui_qt_photoacoustics_imageprocessingFiltering Using the filters -To perform image processing, simply load an image into MITK and select it in the Data manager. Only the selected image will be processed by the filters. -\imageMacro{QmikPhotoacousticsImageProcessing_DataManager.png,"Select the image to be processed",7.62} -Before performing reconstruction or using other filters those can be configured using the plugin's settings panel. -\imageMacro{QmikPhotoacousticsImageProcessing_Settings.png,"The plugin's GUI",7.62} - -\subsection org_mitk_gui_qt_photoacoustics_imageprocessingImageDetails Image Details -To create the .nrrd images necessary for the plugin from raw data, one can use e.g. pynrrd, a python package for very straightforward creation of .nrrd images. -The Beamforming Filter is also able to read certain paramters, as the scan depth and the transducer pitch from the selected image. To this end, the image must have a time-axis spacing in µs and a horizontal spacing in mm. - -\subsection org_mitk_gui_qt_photoacoustics_imageprocessingBeamforming The Beamforming Settings -For beamforming, three beamforming algorithms are available: -
    -
  • DAS (Delay And Sum) -
  • DMAS (Delay Multiply And Sum) -
  • sDMAS (signed Delay Multiply And Sum) -
-Each of those can be coupled with either spherical delay calculation or a quadratic approximation for the delays. To supress noise, one of the following apodizations can be chosen to be used when beamforming: -
    -
  • Box (No apodization) -
  • Hamming -
  • Von Hann -
-Other Standard beamforming parameters are available, which have to be chosen depending on the source image to attain a correctly reconstructed image. -As mentioned above, Plugin is able to calculate the used scan depth as well as the transducer pitch from the selected image if the time-axis spacing is in microseconds, and the horizontal spacing in mm. If such a spacing is given, -check the box "Auto Get Depth" to make the plugin read those values by itself. -If the US source or the laser used for imaging is not located at the top of the image, an option is given to cut off pixels at the top of the image until the source. This value should be calibrated by the user -to match the used hardware. -If one wishes to beamform only certain slices of a given image, those can be selected by checking "select slices" and setting the "min" and "max" values accordingly, which are to be understood as closed interval boundaries. - -\subsection org_mitk_gui_qt_photoacoustics_imageprocessingBandpass The Bandpass Settings -The bandpass uses an itk implementation of an 1D Fast Fourier Transform (FFT) to transform the image vertically, then filters the image using a Tukey window in the frequency domain and performs an inverse 1D FFT to get the filtered image. -The "smoothness" of the tukey window can be chosen by using the "Tukey window alpha" parameter. The Tukey window interpolates between a Box window (alpha = 0) and a Von Hann window (alpha = 1). -The filtered frequencies can be set by defining the High and Low pass frequencies. - -\subsection org_mitk_gui_qt_photoacoustics_imageprocessingCrop The Crop Filter Settings -The crop filter cuts off parts of the image at the top and the bottom. The amount of pixels cut off can be configured using the "Cut Top" and "Cut Bottom" parameters. - -\subsection org_mitk_gui_qt_photoacoustics_imageprocessingBMode The BMode Filter Settings -The B-mode filters available are: -
    -
  • An absolute filter -
  • An envelope detection filter -
-If desired, the filter can also resample the image to a given spacing; to do this, check the "Do Resampling" box and set the desired spacing in mm. -Afterwards a logarithmic filter can be applied, if "Add Logfilter" is checked. - -\subsection org_mitk_gui_qt_photoacoustics_imageprocessingBatch Batch Processing -When processing large amounts of data, an option is available to automatically process multiple images by applying all filters in order to those images and saving the resulting images. -In the first row of the Batch Processing Panel one can select which filters should be applied to the image; in the second row one can select whether the resulting image from the filter should be saved. -After pressing the "Start Batch Processing" button, one can choose first the images to be processed, and then the folder where they will be saved. -*/ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/QmikPhotoacousticsImageProcessing_DataManager.png b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/QmikPhotoacousticsImageProcessing_DataManager.png deleted file mode 100644 index 29b7b0e002..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/QmikPhotoacousticsImageProcessing_DataManager.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/QmikPhotoacousticsImageProcessing_Settings.png b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/QmikPhotoacousticsImageProcessing_Settings.png deleted file mode 100644 index f8210298cf..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/QmikPhotoacousticsImageProcessing_Settings.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/pai-dox.png b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/pai-dox.png deleted file mode 100644 index 1b8dc34c11..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/UserManual/pai-dox.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/doxygen/modules.dox deleted file mode 100644 index 5bd6326234..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/documentation/doxygen/modules.dox +++ /dev/null @@ -1,16 +0,0 @@ -/** - \defgroup org_mitk_gui_qt_photoacoustics_imageprocessing org.mitk.gui.qt.photoacoustics.imageprocessing - \ingroup MITKPlugins - - \brief Describe your plugin here. - -*/ - -/** - \defgroup org_mitk_gui_qt_photoacoustics_imageprocessing_internal Internal - \ingroup org_mitk_gui_qt_photoacoustics_imageprocessing - - \brief This subcategory includes the internal classes of the org.mitk.gui.qt.photoacoustics.imageprocessing plugin. Other - plugins must not rely on these classes. They contain implementation details and their interface - may change at any time. We mean it. -*/ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/files.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/files.cmake deleted file mode 100644 index 4b9c855389..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/files.cmake +++ /dev/null @@ -1,36 +0,0 @@ -set(SRC_CPP_FILES - -) - -set(INTERNAL_CPP_FILES - org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.cpp - PAImageProcessing.cpp -) - -set(UI_FILES - src/internal/PAImageProcessingControls.ui -) - -set(MOC_H_FILES - src/internal/org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.h - src/internal/PAImageProcessing.h -) - -set(CACHED_RESOURCE_FILES - resources/pai.svg - plugin.xml -) - -set(QRC_FILES - -) - -set(CPP_FILES ) - -foreach(file ${SRC_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/${file}) -endforeach(file ${SRC_CPP_FILES}) - -foreach(file ${INTERNAL_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/internal/${file}) -endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/manifest_headers.cmake deleted file mode 100644 index 948e85963d..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "Imageprocessing") -set(Plugin-Version "0.1") -set(Plugin-Vendor "DKFZ") -set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/plugin.xml b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/plugin.xml deleted file mode 100644 index 1ef31f0130..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/plugin.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/resources/pai.svg b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/resources/pai.svg deleted file mode 100644 index 8002f7c6ec..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/resources/pai.svg +++ /dev/null @@ -1,49 +0,0 @@ - -image/svg+xml diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp deleted file mode 100644 index 7285a94907..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.cpp +++ /dev/null @@ -1,1142 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// Blueberry -#include -#include - -// Qmitk -#include "PAImageProcessing.h" - -// Qt -#include -#include -#include -#include - -//mitk image -#include -#include "mitkPhotoacousticFilterService.h" -#include "mitkCastToFloatImageFilter.h" -#include "mitkBeamformingFilter.h" - -//other -#include -#include -#include - -#define GPU_BATCH_SIZE 32 - -const std::string PAImageProcessing::VIEW_ID = "org.mitk.views.paimageprocessing"; - -PAImageProcessing::PAImageProcessing() : m_ResampleSpacing(0), m_UseLogfilter(false), m_FilterBank(mitk::PhotoacousticFilterService::New()) -{ - qRegisterMetaType(); - qRegisterMetaType(); -} - -void PAImageProcessing::SetFocus() -{ - m_Controls.buttonApplyBModeFilter->setFocus(); -} - -void PAImageProcessing::CreateQtPartControl(QWidget *parent) -{ - // create GUI widgets from the Qt Designer's .ui file - m_Controls.setupUi(parent); - connect(m_Controls.buttonApplyBModeFilter, SIGNAL(clicked()), this, SLOT(StartBmodeThread())); - connect(m_Controls.Geometry, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangedProbe())); - connect(m_Controls.DoResampling, SIGNAL(clicked()), this, SLOT(UseResampling())); - connect(m_Controls.Logfilter, SIGNAL(clicked()), this, SLOT(UseLogfilter())); - connect(m_Controls.ResamplingValue, SIGNAL(valueChanged(double)), this, SLOT(SetResampling())); - connect(m_Controls.buttonApplyBeamforming, SIGNAL(clicked()), this, SLOT(StartBeamformingThread())); - connect(m_Controls.buttonApplyCropFilter, SIGNAL(clicked()), this, SLOT(StartCropThread())); - connect(m_Controls.buttonApplyBandpass, SIGNAL(clicked()), this, SLOT(StartBandpassThread())); - connect(m_Controls.UseImageSpacing, SIGNAL(clicked()), this, SLOT(UseImageSpacing())); - connect(m_Controls.ScanDepth, SIGNAL(valueChanged(double)), this, SLOT(UpdateImageInfo())); - connect(m_Controls.SpeedOfSound, SIGNAL(valueChanged(double)), this, SLOT(UpdateImageInfo())); - connect(m_Controls.SpeedOfSound, SIGNAL(valueChanged(double)), this, SLOT(ChangedSOSBeamforming())); - connect(m_Controls.BPSpeedOfSound, SIGNAL(valueChanged(double)), this, SLOT(ChangedSOSBandpass())); - connect(m_Controls.Samples, SIGNAL(valueChanged(int)), this, SLOT(UpdateImageInfo())); - connect(m_Controls.UseImageSpacing, SIGNAL(clicked()), this, SLOT(UpdateImageInfo())); - connect(m_Controls.boundLow, SIGNAL(valueChanged(int)), this, SLOT(LowerSliceBoundChanged())); - connect(m_Controls.boundHigh, SIGNAL(valueChanged(int)), this, SLOT(UpperSliceBoundChanged())); - connect(m_Controls.Partial, SIGNAL(clicked()), this, SLOT(SliceBoundsEnabled())); - connect(m_Controls.BatchProcessing, SIGNAL(clicked()), this, SLOT(BatchProcessing())); - connect(m_Controls.StepBeamforming, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); - connect(m_Controls.StepCropping, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); - connect(m_Controls.StepBandpass, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); - connect(m_Controls.StepBMode, SIGNAL(clicked()), this, SLOT(UpdateSaveBoxes())); - connect(m_Controls.UseSignalDelay, SIGNAL(clicked()), this, SLOT(UseSignalDelay())); - connect(m_Controls.IsBFImage, SIGNAL(clicked()), this, SLOT(UpdateImageInfo())); - UpdateSaveBoxes(); - UseSignalDelay(); - m_Controls.ResamplingValue->setEnabled(false); - m_Controls.progressBar->setMinimum(0); - m_Controls.progressBar->setMaximum(100); - m_Controls.progressBar->setVisible(false); - m_Controls.UseImageSpacing->setToolTip("Image spacing of y-Axis must be in us, x-Axis in mm."); - m_Controls.UseImageSpacing->setToolTipDuration(5000); - m_Controls.ProgressInfo->setVisible(false); - m_Controls.UseGPUBmode->hide(); - -#ifndef PHOTOACOUSTICS_USE_GPU - m_Controls.UseGPUBf->setEnabled(false); - m_Controls.UseGPUBf->setChecked(false); - m_Controls.UseGPUBmode->setEnabled(false); - m_Controls.UseGPUBmode->setChecked(false); -#endif - - UseImageSpacing(); - ChangedProbe(); -} - -void PAImageProcessing::ChangedProbe() -{ - if (m_Controls.Geometry->currentText() == "Concave") - { - m_Controls.ProbeRadius->setEnabled(true); - } - else - { - m_Controls.ProbeRadius->setEnabled(false); - } -} - -void PAImageProcessing::UseSignalDelay() -{ - if (m_Controls.UseSignalDelay->isChecked()) - { - m_Controls.SignalDelay->setEnabled(true); - } - else - { - m_Controls.SignalDelay->setEnabled(false); - } -} - -void PAImageProcessing::ChangedSOSBandpass() -{ - m_Controls.SpeedOfSound->setValue(m_Controls.BPSpeedOfSound->value()); -} - -void PAImageProcessing::ChangedSOSBeamforming() -{ - m_Controls.BPSpeedOfSound->setValue(m_Controls.SpeedOfSound->value()); -} - -std::vector splitpath( - const std::string& str - , const std::set delimiters) -{ - std::vector result; - - char const* pch = str.c_str(); - char const* start = pch; - for (; *pch; ++pch) - { - if (delimiters.find(*pch) != delimiters.end()) - { - if (start != pch) - { - std::string str(start, pch); - result.push_back(str); - } - else - { - result.push_back(""); - } - start = pch + 1; - } - } - result.push_back(start); - - return result; -} - -void PAImageProcessing::UpdateSaveBoxes() -{ - if (m_Controls.StepBeamforming->isChecked()) - m_Controls.SaveBeamforming->setEnabled(true); - else - m_Controls.SaveBeamforming->setEnabled(false); - - if (m_Controls.StepCropping->isChecked()) - m_Controls.SaveCropping->setEnabled(true); - else - m_Controls.SaveCropping->setEnabled(false); - - if (m_Controls.StepBandpass->isChecked()) - m_Controls.SaveBandpass->setEnabled(true); - else - m_Controls.SaveBandpass->setEnabled(false); - - if (m_Controls.StepBMode->isChecked()) - m_Controls.SaveBMode->setEnabled(true); - else - m_Controls.SaveBMode->setEnabled(false); -} - -void PAImageProcessing::BatchProcessing() -{ - QFileDialog LoadDialog(nullptr, "Select Files to be processed"); - LoadDialog.setFileMode(QFileDialog::FileMode::ExistingFiles); - LoadDialog.setNameFilter(tr("Images (*.nrrd)")); - LoadDialog.setViewMode(QFileDialog::Detail); - - QStringList fileNames; - if (LoadDialog.exec()) - fileNames = LoadDialog.selectedFiles(); - - QString saveDir = QFileDialog::getExistingDirectory(nullptr, tr("Select Directory To Save To"), - "", - QFileDialog::ShowDirsOnly - | QFileDialog::DontResolveSymlinks); - - DisableControls(); - - std::set delims{ '/' }; - - bool doSteps[] = { m_Controls.StepBeamforming->isChecked(), m_Controls.StepCropping->isChecked() , m_Controls.StepBandpass->isChecked(), m_Controls.StepBMode->isChecked() }; - bool saveSteps[] = { m_Controls.SaveBeamforming->isChecked(), m_Controls.SaveCropping->isChecked() , m_Controls.SaveBandpass->isChecked(), m_Controls.SaveBMode->isChecked() }; - - for (int fileNumber = 0; fileNumber < fileNames.size(); ++fileNumber) - { - m_Controls.progressBar->setValue(0); - m_Controls.progressBar->setVisible(true); - m_Controls.ProgressInfo->setVisible(true); - m_Controls.ProgressInfo->setText("loading file"); - - QString filename = fileNames.at(fileNumber); - auto split = splitpath(filename.toStdString(), delims); - std::string imageName = split.at(split.size() - 1); - - // remove ".nrrd" - imageName = imageName.substr(0, imageName.size() - 5); - - mitk::Image::Pointer image = mitk::IOUtil::Load(filename.toStdString().c_str()); - auto BFconfig = CreateBeamformingSettings(image); - - // Beamforming - if (doSteps[0]) - { - if (m_Controls.UseSignalDelay->isChecked()) - { - float signalDelay = m_Controls.SignalDelay->value(); - if (signalDelay != 0) - { - int cropPixels = std::round(signalDelay / BFconfig->GetTimeSpacing() / 1000000); - MITK_INFO << cropPixels; - int errCode = 0; - image = m_FilterBank->ApplyCropping(image, cropPixels, 0, 0, 0, 0, 0, &errCode); - - if (errCode == -1) - { - QMessageBox Msgbox; - Msgbox.setText("It has been attempted to cut off more pixels than the image contains. Aborting batch processing."); - Msgbox.exec(); - m_Controls.progressBar->setVisible(false); - EnableControls(); - return; - } - - BFconfig = mitk::BeamformingSettings::New(BFconfig->GetPitchInMeters(), BFconfig->GetSpeedOfSound(), - BFconfig->GetTimeSpacing(), BFconfig->GetAngle(), BFconfig->GetIsPhotoacousticImage(), BFconfig->GetSamplesPerLine(), - BFconfig->GetReconstructionLines(), image->GetDimensions(), BFconfig->GetReconstructionDepth(), - BFconfig->GetUseGPU(), BFconfig->GetGPUBatchSize(), BFconfig->GetApod(), - BFconfig->GetApodizationArraySize(), BFconfig->GetAlgorithm(), BFconfig->GetGeometry(), BFconfig->GetProbeRadius()); - } - } - - std::function progressHandle = [this](int progress, std::string progressInfo) { - this->UpdateProgress(progress, progressInfo); - }; - m_Controls.progressBar->setValue(100); - - image = m_FilterBank->ApplyBeamforming(image, BFconfig, progressHandle); - - if (saveSteps[0]) - { - std::string saveFileName = saveDir.toStdString() + "/" + imageName + " beamformed" + ".nrrd"; - mitk::IOUtil::Save(image, saveFileName); - } - } - - // Cropping - if (doSteps[1]) - { - m_Controls.ProgressInfo->setText("cropping image"); - - int errCode = 0; - image = m_FilterBank->ApplyCropping(image, m_Controls.CutoffAbove->value(), m_Controls.CutoffBelow->value(), m_Controls.CutoffRight->value(), m_Controls.CutoffLeft->value(), 0, 0, &errCode); - - if (errCode == -1) - { - QMessageBox Msgbox; - Msgbox.setText("It has been attempted to cut off more pixels than the image contains. Aborting batch processing."); - Msgbox.exec(); - m_Controls.progressBar->setVisible(false); - EnableControls(); - return; - } - - if (saveSteps[1]) - { - std::string saveFileName = saveDir.toStdString() + "/" + imageName + " cropped" + ".nrrd"; - mitk::IOUtil::Save(image, saveFileName); - } - } - - // Bandpass - if (doSteps[2]) - { - m_Controls.ProgressInfo->setText("applying bandpass"); - float recordTime = image->GetDimension(1)*image->GetGeometry()->GetSpacing()[1] / 1000 / m_Controls.BPSpeedOfSound->value(); - // add a safeguard so the program does not chrash when applying a Bandpass that reaches out of the bounds of the image - float maxFrequency = 1 / (recordTime / image->GetDimension(1)) * image->GetDimension(1) / 2 / 2 / 1000; - float BPHighPass = 1000000 * m_Controls.BPhigh->value(); // [Hz] - float BPLowPass = maxFrequency - 1000000 * m_Controls.BPlow->value(); // [Hz] - - if (BPLowPass > maxFrequency) - { - QMessageBox Msgbox; - Msgbox.setText("LowPass too low, disabled it."); - Msgbox.exec(); - - BPLowPass = 0; - } - if (BPLowPass < 0) - { - QMessageBox Msgbox; - Msgbox.setText("LowPass too high, disabled it."); - Msgbox.exec(); - - BPLowPass = 0; - } - if (BPHighPass > maxFrequency) - { - QMessageBox Msgbox; - Msgbox.setText("HighPass too high, disabled it."); - Msgbox.exec(); - - BPHighPass = 0; - } - if (BPHighPass > maxFrequency - BPLowPass) - { - QMessageBox Msgbox; - Msgbox.setText("HighPass higher than LowPass, disabled both."); - Msgbox.exec(); - - BPHighPass = 0; - BPLowPass = 0; - } - - image = m_FilterBank->ApplyBandpassFilter(image, BPHighPass, BPLowPass, - m_Controls.BPFalloffHigh->value(), - m_Controls.BPFalloffLow->value(), - BFconfig->GetTimeSpacing(), - BFconfig->GetSpeedOfSound(), - m_Controls.IsBFImage->isChecked()); - - if (saveSteps[2]) - { - std::string saveFileName = saveDir.toStdString() + "/" + imageName + " bandpassed" + ".nrrd"; - mitk::IOUtil::Save(image, saveFileName); - } - } - // Bmode - if (doSteps[3]) - { - m_Controls.ProgressInfo->setText("applying bmode filter"); - - if (m_Controls.BModeMethod->currentText() == "Absolute Filter") - image = m_FilterBank->ApplyBmodeFilter(image, mitk::PhotoacousticFilterService::BModeMethod::Abs, m_UseLogfilter); - else if (m_Controls.BModeMethod->currentText() == "Envelope Detection") - image = m_FilterBank->ApplyBmodeFilter(image, mitk::PhotoacousticFilterService::BModeMethod::EnvelopeDetection, m_UseLogfilter); - - if (m_ResampleSpacing != 0) - { - double desiredSpacing[2]{ image->GetGeometry()->GetSpacing()[0], m_ResampleSpacing }; - - image = m_FilterBank->ApplyResampling(image, desiredSpacing); - } - - if (saveSteps[3]) - { - std::string saveFileName = saveDir.toStdString() + "/" + imageName + " bmode" + ".nrrd"; - mitk::IOUtil::Save(image, saveFileName); - } - } - m_Controls.progressBar->setVisible(false); - } - - EnableControls(); -} - -void PAImageProcessing::StartBeamformingThread() -{ - QList nodes = this->GetDataManagerSelection(); - if (nodes.empty()) return; - - mitk::DataStorage::Pointer storage = this->GetDataStorage(); - - mitk::DataNode::Pointer node = nodes.front(); - - if (!node) - { - // Nothing selected. Inform the user and return - QMessageBox::information(nullptr, "Template", "Please load and select an image before starting image processing."); - return; - } - - mitk::BaseData* data = node->GetData(); - if (data) - { - // test if this data item is an image or not (could also be a surface or something totally different) - mitk::Image* image = dynamic_cast(data); - if (image) - { - auto BFconfig = CreateBeamformingSettings(image); - std::stringstream message; - std::string name; - message << "Performing beamforming for image "; - if (node->GetName(name)) - { - // a property called "name" was found for this DataNode - message << "'" << name << "'"; - m_OldNodeName = name; - } - else - m_OldNodeName = " "; - - message << "."; - MITK_INFO << message.str(); - - m_Controls.progressBar->setValue(0); - m_Controls.progressBar->setVisible(true); - m_Controls.ProgressInfo->setVisible(true); - m_Controls.ProgressInfo->setText("started"); - DisableControls(); - - BeamformingThread *thread = new BeamformingThread(); - connect(thread, &BeamformingThread::result, this, &PAImageProcessing::HandleResults); - connect(thread, &BeamformingThread::updateProgress, this, &PAImageProcessing::UpdateProgress); - connect(thread, &BeamformingThread::finished, thread, &QObject::deleteLater); - - thread->setConfig(BFconfig); - - if (m_Controls.UseSignalDelay->isChecked()) - thread->setSignalDelay(m_Controls.SignalDelay->value()); - - thread->setInputImage(image); - thread->setFilterBank(m_FilterBank); - - MITK_INFO << "Started new thread for Beamforming"; - thread->start(); - } - } -} - -void PAImageProcessing::HandleResults(mitk::Image::Pointer image, std::string nameExtension) -{ - if (image == nullptr) - { - QMessageBox Msgbox; - Msgbox.setText("An error has occurred during processing; please see the console output."); - Msgbox.exec(); - - // disable progress bar - m_Controls.progressBar->setVisible(false); - m_Controls.ProgressInfo->setVisible(false); - EnableControls(); - - return; - } - MITK_INFO << "Handling results..."; - auto newNode = mitk::DataNode::New(); - newNode->SetData(image); - - newNode->SetName(m_OldNodeName + nameExtension); - - // update level window for the current dynamic range - mitk::LevelWindow levelWindow; - newNode->GetLevelWindow(levelWindow); - levelWindow.SetAuto(image, true, true); - newNode->SetLevelWindow(levelWindow); - - // add new node to data storage - this->GetDataStorage()->Add(newNode); - - // disable progress bar - m_Controls.progressBar->setVisible(false); - m_Controls.ProgressInfo->setVisible(false); - EnableControls(); - - // update rendering - mitk::RenderingManager::GetInstance()->InitializeViews(image->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - MITK_INFO << "Handling results...[Done]"; -} - -void PAImageProcessing::StartBmodeThread() -{ - QList nodes = this->GetDataManagerSelection(); - if (nodes.empty()) return; - - mitk::DataStorage::Pointer storage = this->GetDataStorage(); - - mitk::DataNode::Pointer node = nodes.front(); - - if (!node) - { - // Nothing selected. Inform the user and return - QMessageBox::information(nullptr, "Template", "Please load and select an image before starting image processing."); - return; - } - - mitk::BaseData* data = node->GetData(); - if (data) - { - // test if this data item is an image or not (could also be a surface or something totally different) - mitk::Image* image = dynamic_cast(data); - if (image) - { - std::stringstream message; - std::string name; - message << "Performing image processing for image "; - if (node->GetName(name)) - { - // a property called "name" was found for this DataNode - message << "'" << name << "'"; - m_OldNodeName = name; - } - else - m_OldNodeName = " "; - - message << "."; - MITK_INFO << message.str(); - - DisableControls(); - - BmodeThread *thread = new BmodeThread(); - connect(thread, &BmodeThread::result, this, &PAImageProcessing::HandleResults); - connect(thread, &BmodeThread::finished, thread, &QObject::deleteLater); - - bool useGPU = m_Controls.UseGPUBmode->isChecked(); - - if (m_Controls.BModeMethod->currentText() == "Absolute Filter") - thread->setConfig(m_UseLogfilter, m_ResampleSpacing, mitk::PhotoacousticFilterService::BModeMethod::Abs, useGPU); - else if (m_Controls.BModeMethod->currentText() == "Envelope Detection") - thread->setConfig(m_UseLogfilter, m_ResampleSpacing, mitk::PhotoacousticFilterService::BModeMethod::EnvelopeDetection, useGPU); - thread->setInputImage(image); - thread->setFilterBank(m_FilterBank); - - MITK_INFO << "Started new thread for Image Processing"; - thread->start(); - } - } -} - -void PAImageProcessing::StartCropThread() -{ - QList nodes = this->GetDataManagerSelection(); - if (nodes.empty()) return; - - mitk::DataStorage::Pointer storage = this->GetDataStorage(); - - mitk::DataNode::Pointer node = nodes.front(); - - if (!node) - { - // Nothing selected. Inform the user and return - QMessageBox::information(nullptr, "Template", "Please load and select an image before starting image cropping."); - return; - } - - mitk::BaseData* data = node->GetData(); - if (data) - { - // test if this data item is an image or not (could also be a surface or something totally different) - mitk::Image* image = dynamic_cast(data); - if (image) - { - std::stringstream message; - std::string name; - message << "Performing image cropping for image "; - if (node->GetName(name)) - { - // a property called "name" was found for this DataNode - message << "'" << name << "'"; - m_OldNodeName = name; - } - else - m_OldNodeName = " "; - - message << "."; - MITK_INFO << message.str(); - - DisableControls(); - - CropThread *thread = new CropThread(); - connect(thread, &CropThread::result, this, &PAImageProcessing::HandleResults); - connect(thread, &CropThread::finished, thread, &QObject::deleteLater); - - if(m_Controls.Partial->isChecked()) - thread->setConfig(m_Controls.CutoffAbove->value(), m_Controls.CutoffBelow->value(), m_Controls.CutoffRight->value(), m_Controls.CutoffLeft->value(), m_Controls.boundLow->value(), m_Controls.boundHigh->value()); - else - thread->setConfig(m_Controls.CutoffAbove->value(), m_Controls.CutoffBelow->value(), m_Controls.CutoffRight->value(), m_Controls.CutoffLeft->value(), 0, image->GetDimension(2) - 1); - - thread->setInputImage(image); - thread->setFilterBank(m_FilterBank); - - MITK_INFO << "Started new thread for Image Cropping"; - thread->start(); - } - } -} - -void PAImageProcessing::StartBandpassThread() -{ - QList nodes = this->GetDataManagerSelection(); - if (nodes.empty()) return; - - mitk::DataStorage::Pointer storage = this->GetDataStorage(); - - mitk::DataNode::Pointer node = nodes.front(); - - if (!node) - { - // Nothing selected. Inform the user and return - QMessageBox::information(nullptr, "Template", "Please load and select an image before applying a bandpass filter."); - return; - } - - mitk::BaseData* data = node->GetData(); - if (data) - { - // test if this data item is an image or not (could also be a surface or something totally different) - mitk::Image* image = dynamic_cast(data); - if (image) - { - auto config = CreateBeamformingSettings(image); - std::stringstream message; - std::string name; - message << "Performing Bandpass filter on image "; - if (node->GetName(name)) - { - // a property called "name" was found for this DataNode - message << "'" << name << "'"; - m_OldNodeName = name; - } - else - m_OldNodeName = " "; - - message << "."; - MITK_INFO << message.str(); - - DisableControls(); - - BandpassThread *thread = new BandpassThread(); - connect(thread, &BandpassThread::result, this, &PAImageProcessing::HandleResults); - connect(thread, &BandpassThread::finished, thread, &QObject::deleteLater); - - float BPHighPass = 1000000.0f * m_Controls.BPhigh->value(); // [Now in Hz] - float BPLowPass = 1000000.0f * m_Controls.BPlow->value(); // [Now in Hz] - - thread->setConfig(BPHighPass, BPLowPass, m_Controls.BPFalloffLow->value(), m_Controls.BPFalloffHigh->value(), - config->GetTimeSpacing(), config->GetSpeedOfSound(), m_Controls.IsBFImage->isChecked()); - thread->setInputImage(image); - thread->setFilterBank(m_FilterBank); - - MITK_INFO << "Started new thread for Bandpass filter"; - thread->start(); - } - } -} - -void PAImageProcessing::SliceBoundsEnabled() -{ - if (!m_Controls.Partial->isChecked()) - { - m_Controls.boundLow->setEnabled(false); - m_Controls.boundHigh->setEnabled(false); - return; - } - else - { - m_Controls.boundLow->setEnabled(true); - m_Controls.boundHigh->setEnabled(true); - } -} - -void PAImageProcessing::UpperSliceBoundChanged() -{ - if (m_Controls.boundLow->value() > m_Controls.boundHigh->value()) - { - m_Controls.boundLow->setValue(m_Controls.boundHigh->value()); - } -} - -void PAImageProcessing::LowerSliceBoundChanged() -{ - if (m_Controls.boundLow->value() > m_Controls.boundHigh->value()) - { - m_Controls.boundHigh->setValue(m_Controls.boundLow->value()); - } -} - -void PAImageProcessing::UpdateProgress(int progress, std::string progressInfo) -{ - if (progress < 100) - m_Controls.progressBar->setValue(progress); - else - m_Controls.progressBar->setValue(100); - m_Controls.ProgressInfo->setText(progressInfo.c_str()); - qApp->processEvents(); -} - -void PAImageProcessing::PAMessageBox(std::string message) -{ - if (0 != message.compare("noMessage")) - { - QMessageBox msgBox; - msgBox.setText(message.c_str()); - msgBox.exec(); - } -} - -void PAImageProcessing::UpdateImageInfo() -{ - QList nodes = this->GetDataManagerSelection(); - if (nodes.empty()) return; - - mitk::DataNode::Pointer node = nodes.front(); - - if (!node) - { - // Nothing selected - return; - } - - mitk::BaseData* data = node->GetData(); - if (data) - { - // test if this data item is an image or not (could also be a surface or something totally different) - mitk::Image* image = dynamic_cast(data); - - if (image) - { - // beamforming configs - if (m_Controls.UseImageSpacing->isChecked()) - { - m_Controls.ElementCount->setValue(image->GetDimension(0)); - m_Controls.Pitch->setValue(image->GetGeometry()->GetSpacing()[0]); - } - - m_Controls.boundLow->setMaximum(image->GetDimension(2) - 1); - m_Controls.boundHigh->setMaximum(image->GetDimension(2) - 1); - - float speedOfSound = m_Controls.SpeedOfSound->value(); // [m/s] - std::stringstream frequency; - float timeSpacing; - if (m_Controls.UseImageSpacing->isChecked()) - { - timeSpacing = image->GetGeometry()->GetSpacing()[1] / 1000000.0f; - MITK_INFO << "Calculated Scan Depth of " << (image->GetDimension(1)*image->GetGeometry()->GetSpacing()[1] / - 1000000) * speedOfSound * 100 / 2 << "cm"; - } - else - { - timeSpacing = (2 * m_Controls.ScanDepth->value() / 1000 / speedOfSound) / image->GetDimension(1); - } - float maxFrequency = (1 / timeSpacing) / 2; - if(m_Controls.IsBFImage->isChecked()) - maxFrequency = ( 1 / (image->GetGeometry()->GetSpacing()[1] / 1e3 / speedOfSound)) / 2; - frequency << maxFrequency / 1e6; //[MHz] - frequency << "MHz"; - - m_Controls.BPhigh->setMaximum(maxFrequency / 1e6); - m_Controls.BPlow->setMaximum(maxFrequency / 1e6); - - frequency << " is the maximal allowed frequency for the selected image."; - m_Controls.BPhigh->setToolTip(frequency.str().c_str()); - m_Controls.BPlow->setToolTip(frequency.str().c_str()); - m_Controls.BPhigh->setToolTipDuration(5000); - m_Controls.BPlow->setToolTipDuration(5000); - } - } -} - -void PAImageProcessing::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, - const QList& nodes) -{ - // iterate all selected objects, adjust warning visibility - foreach(mitk::DataNode::Pointer node, nodes) - { - if (node.IsNotNull() && dynamic_cast(node->GetData())) - { - m_Controls.labelWarning->setVisible(false); - m_Controls.buttonApplyBModeFilter->setEnabled(true); - m_Controls.labelWarning2->setVisible(false); - m_Controls.buttonApplyCropFilter->setEnabled(true); - m_Controls.labelWarning3->setVisible(false); - m_Controls.buttonApplyBandpass->setEnabled(true); - m_Controls.labelWarning4->setVisible(false); - m_Controls.buttonApplyBeamforming->setEnabled(true); - UpdateImageInfo(); - return; - } - } - m_Controls.labelWarning->setVisible(true); - m_Controls.buttonApplyBModeFilter->setEnabled(false); - m_Controls.labelWarning2->setVisible(true); - m_Controls.buttonApplyCropFilter->setEnabled(false); - m_Controls.labelWarning3->setVisible(true); - m_Controls.buttonApplyBandpass->setEnabled(false); - m_Controls.labelWarning4->setVisible(true); - m_Controls.buttonApplyBeamforming->setEnabled(false); -} - -void PAImageProcessing::UseResampling() -{ - if (m_Controls.DoResampling->isChecked()) - { - m_Controls.ResamplingValue->setEnabled(true); - m_ResampleSpacing = m_Controls.ResamplingValue->value(); - } - else - { - m_Controls.ResamplingValue->setEnabled(false); - m_ResampleSpacing = 0; - } -} - -void PAImageProcessing::UseLogfilter() -{ - m_UseLogfilter = m_Controls.Logfilter->isChecked(); -} - -void PAImageProcessing::SetResampling() -{ - m_ResampleSpacing = m_Controls.ResamplingValue->value(); -} - -mitk::BeamformingSettings::Pointer PAImageProcessing::CreateBeamformingSettings(mitk::Image::Pointer image) -{ - mitk::BeamformingSettings::BeamformingAlgorithm algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DAS; - if ("DAS" == m_Controls.BFAlgorithm->currentText()) - algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DAS; - else if ("DMAS" == m_Controls.BFAlgorithm->currentText()) - algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::DMAS; - else if ("sDMAS" == m_Controls.BFAlgorithm->currentText()) - algorithm = mitk::BeamformingSettings::BeamformingAlgorithm::sDMAS; - - mitk::BeamformingSettings::Apodization apod = mitk::BeamformingSettings::Apodization::Box; - if ("Von Hann" == m_Controls.Apodization->currentText()) - { - apod = mitk::BeamformingSettings::Apodization::Hann; - } - else if ("Hamming" == m_Controls.Apodization->currentText()) - { - apod = mitk::BeamformingSettings::Apodization::Hamm; - } - else if ("Box" == m_Controls.Apodization->currentText()) - { - apod = mitk::BeamformingSettings::Apodization::Box; - } - - float pitchInMeters = m_Controls.Pitch->value() / 1000; // [m] - float speedOfSound = m_Controls.SpeedOfSound->value(); // [m/s] - unsigned int samplesPerLine = m_Controls.Samples->value(); - unsigned int reconstructionLines = m_Controls.Lines->value(); - unsigned int apodizatonArraySize = m_Controls.Lines->value(); - float angle = m_Controls.Angle->value(); // [deg] - bool useGPU = m_Controls.UseGPUBf->isChecked(); - - float timeSpacing; - if (m_Controls.UseImageSpacing->isChecked()) - { - timeSpacing = image->GetGeometry()->GetSpacing()[1] / 1000000.0f; - MITK_INFO << "Calculated Scan Depth of " << (image->GetDimension(1)*image->GetGeometry()->GetSpacing()[1] / - 1000000) * speedOfSound * 100 << "cm"; - } - else - { - timeSpacing = (2 * m_Controls.ScanDepth->value() / 1000 / speedOfSound) / image->GetDimension(1); - } - - bool isPAImage = true; - if ("US Image" == m_Controls.ImageType->currentText()) - { - isPAImage = false; - } - else if ("PA Image" == m_Controls.ImageType->currentText()) - { - isPAImage = true; - } - - float reconstructionDepth = m_Controls.ReconstructionDepth->value() / 1000.f; // [m] - - mitk::BeamformingSettings::ProbeGeometry geometry = mitk::BeamformingSettings::ProbeGeometry::Linear; - if ("Linear" == m_Controls.Geometry->currentText()) - { - geometry = mitk::BeamformingSettings::ProbeGeometry::Linear; - } - else if ("Concave" == m_Controls.Geometry->currentText()) - { - geometry = mitk::BeamformingSettings::ProbeGeometry::Concave; - } - float probeRadius = m_Controls.ProbeRadius->value()/1000.f; // [m] - - return mitk::BeamformingSettings::New(pitchInMeters, - speedOfSound, timeSpacing, angle, isPAImage, samplesPerLine, reconstructionLines, - image->GetDimensions(), reconstructionDepth, useGPU, GPU_BATCH_SIZE, apod, - apodizatonArraySize, algorithm, geometry, probeRadius); -} - -void PAImageProcessing::EnableControls() -{ - m_Controls.BatchProcessing->setEnabled(true); - m_Controls.StepBeamforming->setEnabled(true); - m_Controls.StepBandpass->setEnabled(true); - m_Controls.StepCropping->setEnabled(true); - m_Controls.StepBMode->setEnabled(true); - - UpdateSaveBoxes(); - - m_Controls.DoResampling->setEnabled(true); - UseResampling(); - m_Controls.Logfilter->setEnabled(true); - m_Controls.BModeMethod->setEnabled(true); - m_Controls.buttonApplyBModeFilter->setEnabled(true); - - m_Controls.CutoffAbove->setEnabled(true); - m_Controls.CutoffBelow->setEnabled(true); - m_Controls.buttonApplyCropFilter->setEnabled(true); - m_Controls.BPSpeedOfSound->setEnabled(true); - m_Controls.buttonApplyBandpass->setEnabled(true); - - m_Controls.Partial->setEnabled(true); - m_Controls.boundHigh->setEnabled(true); - m_Controls.boundLow->setEnabled(true); - m_Controls.BFAlgorithm->setEnabled(true); - m_Controls.ReconstructionDepth->setEnabled(true); - m_Controls.ImageType->setEnabled(true); - m_Controls.Apodization->setEnabled(true); - -#ifdef PHOTOACOUSTICS_USE_GPU - m_Controls.UseGPUBf->setEnabled(true); - m_Controls.UseGPUBmode->setEnabled(true); -#endif - - m_Controls.BPhigh->setEnabled(true); - m_Controls.BPlow->setEnabled(true); - m_Controls.BPFalloffLow->setEnabled(true); - m_Controls.BPFalloffHigh->setEnabled(true); - m_Controls.UseImageSpacing->setEnabled(true); - UseImageSpacing(); - m_Controls.Pitch->setEnabled(true); - m_Controls.ElementCount->setEnabled(true); - m_Controls.SpeedOfSound->setEnabled(true); - m_Controls.Samples->setEnabled(true); - m_Controls.Lines->setEnabled(true); - m_Controls.Angle->setEnabled(true); - m_Controls.buttonApplyBeamforming->setEnabled(true); - m_Controls.UseSignalDelay->setEnabled(true); - m_Controls.SignalDelay->setEnabled(true); -} - -void PAImageProcessing::DisableControls() -{ - m_Controls.BatchProcessing->setEnabled(false); - m_Controls.StepBeamforming->setEnabled(false); - m_Controls.StepBandpass->setEnabled(false); - m_Controls.StepCropping->setEnabled(false); - m_Controls.StepBMode->setEnabled(false); - m_Controls.SaveBeamforming->setEnabled(false); - m_Controls.SaveBandpass->setEnabled(false); - m_Controls.SaveCropping->setEnabled(false); - m_Controls.SaveBMode->setEnabled(false); - - m_Controls.DoResampling->setEnabled(false); - m_Controls.ResamplingValue->setEnabled(false); - m_Controls.Logfilter->setEnabled(false); - m_Controls.BModeMethod->setEnabled(false); - m_Controls.buttonApplyBModeFilter->setEnabled(false); - - m_Controls.CutoffAbove->setEnabled(false); - m_Controls.CutoffBelow->setEnabled(false); - m_Controls.buttonApplyCropFilter->setEnabled(false); - m_Controls.BPSpeedOfSound->setEnabled(false); - m_Controls.buttonApplyBandpass->setEnabled(false); - - m_Controls.Partial->setEnabled(false); - m_Controls.boundHigh->setEnabled(false); - m_Controls.boundLow->setEnabled(false); - m_Controls.BFAlgorithm->setEnabled(false); - m_Controls.ReconstructionDepth->setEnabled(false); - m_Controls.ImageType->setEnabled(false); - m_Controls.Apodization->setEnabled(false); - -#ifdef PHOTOACOUSTICS_USE_GPU - m_Controls.UseGPUBf->setEnabled(false); - m_Controls.UseGPUBmode->setEnabled(false); -#endif - - m_Controls.BPhigh->setEnabled(false); - m_Controls.BPlow->setEnabled(false); - m_Controls.BPFalloffLow->setEnabled(false); - m_Controls.BPFalloffHigh->setEnabled(false); - m_Controls.UseImageSpacing->setEnabled(false); - m_Controls.ScanDepth->setEnabled(false); - m_Controls.Pitch->setEnabled(false); - m_Controls.ElementCount->setEnabled(false); - m_Controls.SpeedOfSound->setEnabled(false); - m_Controls.Samples->setEnabled(false); - m_Controls.Lines->setEnabled(false); - m_Controls.Angle->setEnabled(false); - m_Controls.buttonApplyBeamforming->setEnabled(false); - m_Controls.UseSignalDelay->setEnabled(false); - m_Controls.SignalDelay->setEnabled(false); -} - -void PAImageProcessing::UseImageSpacing() -{ - if (m_Controls.UseImageSpacing->isChecked()) - { - m_Controls.ScanDepth->setDisabled(true); - } - else - { - m_Controls.ScanDepth->setEnabled(true); - } -} - -#include - -void BeamformingThread::run() -{ - if (m_SignalDelay != 0) - { - int cropPixels = std::round(m_SignalDelay / m_BFconfig->GetTimeSpacing() / 1000000); - MITK_INFO << cropPixels; - int errCode = 0; - m_InputImage = m_FilterBank->ApplyCropping(m_InputImage, cropPixels, 0, 0, 0, 0, 0, &errCode); - - m_BFconfig = mitk::BeamformingSettings::New(m_BFconfig->GetPitchInMeters(), m_BFconfig->GetSpeedOfSound(), - m_BFconfig->GetTimeSpacing(), m_BFconfig->GetAngle(), m_BFconfig->GetIsPhotoacousticImage(), m_BFconfig->GetSamplesPerLine(), - m_BFconfig->GetReconstructionLines(), m_InputImage->GetDimensions(), m_BFconfig->GetReconstructionDepth(), - m_BFconfig->GetUseGPU(), m_BFconfig->GetGPUBatchSize(), m_BFconfig->GetApod(), - m_BFconfig->GetApodizationArraySize(), m_BFconfig->GetAlgorithm(), m_BFconfig->GetGeometry(), m_BFconfig->GetProbeRadius()); - } - - mitk::Image::Pointer resultImage; - std::function progressHandle = [this](int progress, std::string progressInfo) { - emit updateProgress(progress, progressInfo); - }; - resultImage = m_FilterBank->ApplyBeamforming(m_InputImage, m_BFconfig, progressHandle); - emit result(resultImage, "_bf"); -} - -void BeamformingThread::setConfig(mitk::BeamformingSettings::Pointer BFconfig) -{ - m_BFconfig = BFconfig; -} - -void BeamformingThread::setSignalDelay(float delay) -{ - m_SignalDelay = delay; -} - -void BeamformingThread::setInputImage(mitk::Image::Pointer image) -{ - m_InputImage = image; -} - -void BmodeThread::run() -{ - mitk::Image::Pointer resultImage = m_FilterBank->ApplyBmodeFilter(m_InputImage, - m_Method, m_UseLogfilter); - - if (m_ResampleSpacing != 0) - { - double desiredSpacing[2]{ m_InputImage->GetGeometry()->GetSpacing()[0], m_ResampleSpacing }; - resultImage = m_FilterBank->ApplyResampling(resultImage, desiredSpacing); - } - emit result(resultImage, "_bmode"); -} - -void BmodeThread::setConfig(bool useLogfilter, double resampleSpacing, mitk::PhotoacousticFilterService::BModeMethod method, bool useGPU) -{ - m_UseLogfilter = useLogfilter; - m_ResampleSpacing = resampleSpacing; - m_Method = method; - m_UseGPU = useGPU; -} - -void BmodeThread::setInputImage(mitk::Image::Pointer image) -{ - m_InputImage = image; -} - -void CropThread::run() -{ - mitk::Image::Pointer resultImage; - - int errCode = 0; - - resultImage = m_FilterBank->ApplyCropping(m_InputImage, m_CutAbove, m_CutBelow, m_CutRight, m_CutLeft, m_CutSliceFirst, (m_InputImage->GetDimension(2) - 1) - m_CutSliceLast, &errCode); - if (errCode == -1) - { - emit result(nullptr, "_cropped"); - return; - } - emit result(resultImage, "_cropped"); -} - -void CropThread::setConfig(unsigned int CutAbove, unsigned int CutBelow, unsigned int CutRight, unsigned int CutLeft, unsigned int CutSliceFirst, unsigned int CutSliceLast) -{ - m_CutAbove = CutAbove; - m_CutBelow = CutBelow; - m_CutRight = CutRight; - m_CutLeft = CutLeft; - - m_CutSliceLast = CutSliceLast; - m_CutSliceFirst = CutSliceFirst; -} - -void CropThread::setInputImage(mitk::Image::Pointer image) -{ - m_InputImage = image; -} - -void BandpassThread::run() -{ - mitk::Image::Pointer resultImage = m_FilterBank->ApplyBandpassFilter(m_InputImage, m_BPHighPass, m_BPLowPass, m_TukeyAlphaHighPass, m_TukeyAlphaLowPass, m_TimeSpacing, m_SpeedOfSound, m_IsBFImage); - emit result(resultImage, "_bandpassed"); -} - -void BandpassThread::setConfig(float BPHighPass, float BPLowPass, float TukeyAlphaHighPass, float TukeyAlphaLowPass, float TimeSpacing, float SpeedOfSound, bool IsBFImage) -{ - m_BPHighPass = BPHighPass; - m_BPLowPass = BPLowPass; - m_TukeyAlphaHighPass = TukeyAlphaHighPass; - m_TukeyAlphaLowPass = TukeyAlphaLowPass; - m_TimeSpacing = TimeSpacing; - m_SpeedOfSound = SpeedOfSound; - m_IsBFImage = IsBFImage; -} - -void BandpassThread::setInputImage(mitk::Image::Pointer image) -{ - m_InputImage = image; -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.h b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.h deleted file mode 100644 index e0b3172f56..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessing.h +++ /dev/null @@ -1,243 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef PAImageProcessing_h -#define PAImageProcessing_h - -#include - -#include - -#include -#include - -#include "ui_PAImageProcessingControls.h" - -#include "mitkBeamformingFilter.h" -#include "mitkBeamformingSettings.h" - -Q_DECLARE_METATYPE(mitk::Image::Pointer) -Q_DECLARE_METATYPE(std::string) - -/*! -* \brief Plugin implementing an interface for the Photoacoustic Algorithms Module -* -* Beamforming, Image processing as B-Mode filtering, cropping, resampling, as well as batch processing can be performed using this plugin. -*/ - -class PAImageProcessing : public QmitkAbstractView -{ - // this is needed for all Qt objects that should have a Qt meta-object - // (everything that derives from QObject and wants to have signal/slots) - Q_OBJECT - -public: - - static const std::string VIEW_ID; - - PAImageProcessing(); - - protected slots: - - void UpperSliceBoundChanged(); - void LowerSliceBoundChanged(); - void SliceBoundsEnabled(); - - void ChangedProbe(); - void UseResampling(); - void UseLogfilter(); - void SetResampling(); - void UseImageSpacing(); - void UpdateImageInfo(); - void UseSignalDelay(); - - /** \brief Beamforming is being performed in a separate thread to keep the workbench from freezing. - */ - void StartBeamformingThread(); - - /** \brief B-mode filtering is being performed in a separate thread to keep the workbench from freezing. - */ - void StartBmodeThread(); - - /** \brief Cropping is being performed in a separate thread to keep the workbench from freezing. - */ - void StartCropThread(); - - /** \brief Method called when the bandpass thread finishes; - * it adds the image to a new data node and registers it to the worbench's data storage - */ - void HandleResults(mitk::Image::Pointer image, std::string nameExtension); - - /** \brief Bandpassing is being performed in a separate thread to keep the workbench from freezing. - */ - void StartBandpassThread(); - - void UpdateProgress(int progress, std::string progressInfo); - void PAMessageBox(std::string message); - - void BatchProcessing(); - void UpdateSaveBoxes(); - - void ChangedSOSBandpass(); - void ChangedSOSBeamforming(); - -protected: - void CreateQtPartControl(QWidget *parent) override; - - void SetFocus() override; - - /** \brief called by QmitkFunctionality when DataManager's selection has changed. - * On a change some parameters are internally updated to calculate bounds for GUI elements as the slice selector for beamforming or - * the bandpass filter settings. - */ - void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, - const QList& nodes) override; - - /** \brief Instance of the GUI controls - */ - Ui::PAImageProcessingControls m_Controls; - - float m_ResampleSpacing; - bool m_UseLogfilter; - std::string m_OldNodeName; - - /** \brief Method for updating the BFconfig by using a selected image and the GUI configuration. - */ - mitk::BeamformingSettings::Pointer CreateBeamformingSettings(mitk::Image::Pointer image); - - void EnableControls(); - void DisableControls(); - - /** \brief Class through which the filters are called. - */ - mitk::PhotoacousticFilterService::Pointer m_FilterBank; -}; - -class BeamformingThread : public QThread -{ - Q_OBJECT - void run() Q_DECL_OVERRIDE; - -signals: - void result(mitk::Image::Pointer, std::string nameExtension); - void updateProgress(int, std::string); - void message(std::string); - -public: - BeamformingThread() : m_SignalDelay(0) {} - - void setConfig(mitk::BeamformingSettings::Pointer BFconfig); - void setSignalDelay(float delay); - void setInputImage(mitk::Image::Pointer image); - void setFilterBank(mitk::PhotoacousticFilterService::Pointer filterBank) - { - m_FilterBank = filterBank; - } - -protected: - mitk::BeamformingSettings::Pointer m_BFconfig; - mitk::Image::Pointer m_InputImage; - int m_Cutoff; - float m_SignalDelay; // [us] - - mitk::PhotoacousticFilterService::Pointer m_FilterBank; -}; - -class BmodeThread : public QThread -{ - Q_OBJECT - void run() Q_DECL_OVERRIDE; - -signals: - void result(mitk::Image::Pointer, std::string nameExtension); - -public: - enum BModeMethod { ShapeDetection, Abs }; - - void setConfig(bool useLogfilter, double resampleSpacing, mitk::PhotoacousticFilterService::BModeMethod method, bool useGPU); - void setInputImage(mitk::Image::Pointer image); - void setFilterBank(mitk::PhotoacousticFilterService::Pointer filterBank) - { - m_FilterBank = filterBank; - } - -protected: - mitk::Image::Pointer m_InputImage; - - mitk::PhotoacousticFilterService::BModeMethod m_Method; - bool m_UseLogfilter; - double m_ResampleSpacing; - bool m_UseGPU; - - mitk::PhotoacousticFilterService::Pointer m_FilterBank; -}; - -class CropThread : public QThread -{ - Q_OBJECT - void run() Q_DECL_OVERRIDE; - -signals: - void result(mitk::Image::Pointer, std::string nameExtension); - -public: - void setConfig(unsigned int CutAbove, unsigned int CutBelow, unsigned int CutRight, unsigned int CutLeft, unsigned int CutSliceFirst, unsigned int CutSliceLast); - void setInputImage(mitk::Image::Pointer image); - void setFilterBank(mitk::PhotoacousticFilterService::Pointer filterBank) - { - m_FilterBank = filterBank; - } - -protected: - mitk::Image::Pointer m_InputImage; - - unsigned int m_CutAbove; - unsigned int m_CutBelow; - unsigned int m_CutRight; - unsigned int m_CutLeft; - unsigned int m_CutSliceLast; - unsigned int m_CutSliceFirst; - - mitk::PhotoacousticFilterService::Pointer m_FilterBank; -}; - -class BandpassThread : public QThread -{ - Q_OBJECT - void run() Q_DECL_OVERRIDE; - -signals: - void result(mitk::Image::Pointer, std::string nameExtension); - -public: - void setConfig(float BPHighPass, float BPLowPass, float TukeyAlphaHighPass, float TukeyAlphaLowPass, float TimeSpacing, float SpeedOfSound, bool IsBFImage); - void setInputImage(mitk::Image::Pointer image); - void setFilterBank(mitk::PhotoacousticFilterService::Pointer filterBank) - { - m_FilterBank = filterBank; - } - -protected: - mitk::Image::Pointer m_InputImage; - - float m_BPHighPass; - float m_BPLowPass; - float m_TukeyAlphaHighPass; - float m_TukeyAlphaLowPass; - float m_TimeSpacing; - float m_SpeedOfSound; - bool m_IsBFImage; - - mitk::PhotoacousticFilterService::Pointer m_FilterBank; -}; - -#endif // PAImageProcessing_h diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessingControls.ui b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessingControls.ui deleted file mode 100644 index 6ec9decbac..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/PAImageProcessingControls.ui +++ /dev/null @@ -1,1317 +0,0 @@ - - - PAImageProcessingControls - - - - 0 - 0 - 601 - 890 - - - - - 0 - 0 - - - - QmitkTemplate - - - - - - - - - 0 - 0 - - - - 1 - - - - - 0 - 0 - 98 - 28 - - - - Bandpass - - - - - 10 - 0 - 301 - 529 - - - - - QLayout::SetDefaultConstraint - - - 0 - - - - - - 0 - 0 - - - - 3 - - - 0.010000000000000 - - - 200.000000000000000 - - - 0.100000000000000 - - - 8.000000000000000 - - - - - - - [MHz] f High Pass - - - - - - - [MHz] f Low Pass - - - - - - - - 0 - 0 - - - - 3 - - - 200.000000000000000 - - - 0.100000000000000 - - - 0.100000000000000 - - - - - - - 1 - - - 200.000000000000000 - - - 3000.000000000000000 - - - 5.000000000000000 - - - 1500.000000000000000 - - - - - - - [m/s] Speed of Sound - - - - - - - 1.000000000000000 - - - 0.100000000000000 - - - 0.500000000000000 - - - - - - - <html><head/><body><p><span style=" font-family:'sans-serif'; font-size:14px; color:#222222; background-color:#ffffff;">At </span><span style=" font-family:'sans-serif'; font-size:14px; font-style:italic; color:#222222; background-color:#ffffff;">α</span><span style=" font-family:'sans-serif'; font-size:14px; color:#222222; background-color:#ffffff;"> = 0 it's rectangular, at </span><span style=" font-family:'sans-serif'; font-size:14px; font-style:italic; color:#222222; background-color:#ffffff;">α</span><span style=" font-family:'sans-serif'; font-size:14px; color:#222222; background-color:#ffffff;"> = 1 it's a Hann window. Both flanks can be set independently.</span></p></body></html> - - - Tukey Window α High Pass - - - - - - - 2 - - - 1.000000000000000 - - - 0.100000000000000 - - - 0.500000000000000 - - - - - - - <html><head/><body><p><span style=" font-family:'sans-serif'; font-size:14px; color:#222222; background-color:#ffffff;">At </span><span style=" font-family:'sans-serif'; font-size:14px; font-style:italic; color:#222222; background-color:#ffffff;">α</span><span style=" font-family:'sans-serif'; font-size:14px; color:#222222; background-color:#ffffff;"> = 0 it's rectangular, at </span><span style=" font-family:'sans-serif'; font-size:14px; font-style:italic; color:#222222; background-color:#ffffff;">α</span><span style=" font-family:'sans-serif'; font-size:14px; color:#222222; background-color:#ffffff;"> = 1 it's a Hann window. Both flanks can be set independently.</span></p></body></html> - - - Tukey Window α Low Pass - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - <html><head/><body><p><span style=" font-size:10pt; font-weight:600; color:#ff0000;">Select input data in datamanager!</span></p></body></html> - - - - - - - Apply Bandpass - - - - - - - <html><head/><body><p>If not checked, treat input as raw US/PA data with Y-axis as a time coordinate in microseconds</p></body></html> - - - Assume Spatial Coordinates - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - 583 - 732 - - - - Beamforming - - - - - 10 - 0 - 306 - 661 - - - - - 5 - - - - - - 0 - 0 - - - - - PA Image - - - - - US Image - - - - - - - - <html><head/><body><p>which type of image do you plan to reconstruct?</p></body></html> - - - Raw Data Type - - - - - - - - 0 - 0 - - - - - DAS - - - - - DMAS - - - - - sDMAS - - - - - - - - - 0 - 0 - - - - - Von Hann - - - - - Hamming - - - - - Box - - - - - - - - [mm] Transducer Pitch - - - - - - - Apodization Function - - - - - - - Beamforming Algorithm - - - - - - - - - - - - - - - 0 - 0 - - - - 3 - - - 0.010000000000000 - - - 9.000000000000000 - - - 0.050000000000000 - - - 0.340000000000000 - - - - - - - Probe Geomentry - - - - - - - - 0 - 0 - - - - 5 - - - 1.000000000000000 - - - 180.000000000000000 - - - 45.000000000000000 - - - - - - - <html><head/><body><p>... of the transducer elements.</p></body></html> - - - [°] Sensitive Angle - - - - - - - [mm] Reconstruction Depth - - - - - - - 4 - - - 300.000000000000000 - - - 0.100000000000000 - - - 60.000000000000000 - - - - - - - Linear - - - - Linear - - - - - Concave - - - - - - - - 2 - - - 0.000000000000000 - - - 999.990000000000009 - - - 40.000000000000000 - - - - - - - [mm] Concave Probe Radius - - - - - - - <html><head/><body><p>Some setups' hardware produces signal delays that need to be cropped out of the image before performing beamforming. To do this, select this box.</p></body></html> - - - Consider Hardware Delay [µs] - - - false - - - - - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - <html><head/><body><p>... from y-spacing in the selected raw data. If this is switched of &quot;Manual Scan Depth&quot; is used.</p></body></html> - - - Automatic Get Depth - - - true - - - - - - - [mm] Manual Scan Depth - - - - - - - <html><head/><body><p>Using GPU is recommended - It is so much faster.</p></body></html> - - - Compute On GPU - - - true - - - - - - - - 0 - 0 - - - - 64 - - - 2048 - - - 128 - - - 512 - - - - - - - - 0 - 0 - - - - 2 - - - 2048 - - - 64 - - - 256 - - - - - - - Reconstructed Lines - - - - - - - - 75 - true - - - - Advanced Options - - - - - - - - 0 - 0 - - - - 4 - - - 300.000000000000000 - - - 0.100000000000000 - - - 60.000000000000000 - - - - - - - - 0 - 0 - - - - 1 - - - 200.000000000000000 - - - 3000.000000000000000 - - - 5.000000000000000 - - - 1500.000000000000000 - - - - - - - <html><head/><body><p>... Good default - change only if you know what you are doing.</p></body></html> - - - Samples - - - - - - - [m/s] Speed of Sound - - - - - - - - 0 - 0 - - - - 256 - - - 16384 - - - 256 - - - 2048 - - - - - - - <html><head/><body><p>Set automatically from selected raw data x-Geometry.</p></body></html> - - - Transducer Elements - - - - - - - - 75 - true - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - <html><head/><body><p><span style=" font-size:10pt; font-weight:600; color:#ff0000;">Select input data in datamanager!</span></p></body></html> - - - - - - - - - - - - - - true - - - - 0 - 0 - - - - 100 - - - 0 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Apply Beamforming - - - - - - - - - - 0 - 0 - 98 - 28 - - - - Cropping - - - - - 10 - 0 - 330 - 301 - - - - - - - 999999999 - - - - - - - Left - - - - - - - Bottom - - - - - - - minimal beamformed slice - - - First Slice - - - - - - - 999999999 - - - - - - - Right - - - - - - - Select Slices - - - - - - - Apply Crop Filer - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - <html><head/><body><p><span style=" font-size:10pt; font-weight:600; color:#ff0000;">Select input data in datamanager!</span></p></body></html> - - - - - - - Top - - - - - - - false - - - 99999 - - - - - - - Cut N Pixels from ... - - - - - - - 999999999 - - - 1 - - - 0 - - - - - - - 999999999 - - - 0 - - - - - - - false - - - 99999 - - - 10 - - - - - - - Maximal beamformed slice - - - Last Slice - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - 98 - 28 - - - - B-mode Generation - - - - - 10 - 0 - 301 - 261 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - <html><head/><body><p><span style=" font-size:10pt; font-weight:600; color:#ff0000;">Select input data in datamanager!</span></p></body></html> - - - - - - - Envelope Detection - - - - Envelope Detection - - - - - Absolute Filter - - - - - - - - - - <html><head/><body><p>The image will still be oversampled after B-Mode generation. This default performs a sensible downsampling.</p></body></html> - - - Resample Image after B-mode - - - true - - - - - - - - - - 0 - 0 - - - - - 13 - 0 - - - - - 11 - - - - 3 - - - 0.010000000000000 - - - 1.000000000000000 - - - 0.010000000000000 - - - 0.050000000000000 - - - - - - - [mm] Resampled y-Spacing - - - - - - - - - - - <html><head/><body><p>Adds a log() filter after the B-mode filter. Often used in US B-mode images.</p></body></html> - - - Logarithmic Compression - - - - - - - Use GPU - - - - - - - - 0 - 0 - - - - Do image processing - - - Apply B-mode Filter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - 98 - 28 - - - - Legacy Batch Processing - - - - - 10 - 0 - 309 - 231 - - - - - - - - 300 - 100 - - - - <html><head/><body><p><span style=" font-weight:600;">Note:</span> This batch processing tool is depricated <br/>and is no longer tested. It is recommended to <br/>use the PA command line tool to process large <br/>amounts of files with consistent settings.</p></body></html> - - - - - - - - - Bandpass - - - true - - - - - - - Crop - - - true - - - - - - - Save - - - false - - - - - - - Save - - - false - - - - - - - Save - - - false - - - - - - - Beamform - - - true - - - - - - - B-Mode - - - true - - - - - - - Save - - - true - - - - - - - Start Batch Processing - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.cpp deleted file mode 100644 index 5546ab5a81..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.h" -#include "PAImageProcessing.h" - -void mitk::org_mitk_gui_qt_photoacoustics_imageprocessing_Activator::start(ctkPluginContext* context) -{ - BERRY_REGISTER_EXTENSION_CLASS(PAImageProcessing, context) -} - -void mitk::org_mitk_gui_qt_photoacoustics_imageprocessing_Activator::stop(ctkPluginContext*) -{ -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.h b/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.h deleted file mode 100644 index fe6d9ea9aa..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.imageprocessing/src/internal/org_mitk_gui_qt_photoacoustics_imageprocessing_Activator.h +++ /dev/null @@ -1,32 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef org_mitk_gui_qt_photoacoustics_imageprocessing_Activator_h -#define org_mitk_gui_qt_photoacoustics_imageprocessing_Activator_h - -#include - -namespace mitk -{ - class org_mitk_gui_qt_photoacoustics_imageprocessing_Activator : public QObject, public ctkPluginActivator - { - Q_OBJECT - Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_photoacoustics_imageprocessing") - Q_INTERFACES(ctkPluginActivator) - - public: - void start(ctkPluginContext* context) override; - void stop(ctkPluginContext* context) override; - }; -} - -#endif diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/CMakeLists.txt deleted file mode 100644 index ec72937f68..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -project(org_mitk_gui_qt_photoacoustics_pausmotioncompensation) - -mitk_create_plugin( - EXPORT_DIRECTIVE PAUSMOTIONCOMPENSATION_EXPORT - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkQtWidgetsExt MitkPhotoacousticsAlgorithms -) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/files.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/files.cmake deleted file mode 100644 index 8641eb6e78..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/files.cmake +++ /dev/null @@ -1,42 +0,0 @@ -set(SRC_CPP_FILES - -) - -set(INTERNAL_CPP_FILES - org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.cpp - PAUSMotionCompensation.cpp -) - -set(UI_FILES - src/internal/PAUSMotionCompensationControls.ui -) - -set(MOC_H_FILES - src/internal/org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.h - src/internal/PAUSMotionCompensation.h -) - -# list of resource files which can be used by the plug-in -# system without loading the plug-ins shared library, -# for example the icon used in the menu and tabs for the -# plug-in views in the workbench -set(CACHED_RESOURCE_FILES - resources/pai.svg - plugin.xml -) - -# list of Qt .qrc files which contain additional resources -# specific to this plugin -set(QRC_FILES - -) - -set(CPP_FILES ) - -foreach(file ${SRC_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/${file}) -endforeach(file ${SRC_CPP_FILES}) - -foreach(file ${INTERNAL_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/internal/${file}) -endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/manifest_headers.cmake deleted file mode 100644 index 7a507c2915..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "Pausmotioncompensation") -set(Plugin-Version "0.1") -set(Plugin-Vendor "DKFZ") -set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/plugin.xml b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/plugin.xml deleted file mode 100644 index 36c99db51c..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/plugin.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/resources/icon.xpm b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/resources/icon.xpm deleted file mode 100644 index 9057c20bc6..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/resources/icon.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * icon_xpm[] = { -"16 16 2 1", -" c #FF0000", -". c #000000", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/resources/pai.svg b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/resources/pai.svg deleted file mode 100644 index d6f03a56da..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/resources/pai.svg +++ /dev/null @@ -1,286 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensation.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensation.cpp deleted file mode 100644 index a747f6651f..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensation.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// Blueberry -#include -#include - -// Qmitk -#include "PAUSMotionCompensation.h" - -// Qt -#include - -// mitk image -#include - -const std::string PAUSMotionCompensation::VIEW_ID = "org.mitk.views.pausmotioncompensation"; - -void PAUSMotionCompensation::SetFocus() -{ - m_Controls.buttonPerformImageProcessing->setFocus(); -} - -void PAUSMotionCompensation::CreateQtPartControl(QWidget *parent) -{ - // create GUI widgets from the Qt Designer's .ui file - m_Controls.setupUi(parent); - connect( - m_Controls.buttonPerformImageProcessing, &QPushButton::clicked, this, &PAUSMotionCompensation::DoImageProcessing); - connect( - m_Controls.buttonUpdateParameters, &QPushButton::clicked, this, &PAUSMotionCompensation::DoUpdateParameters); -} - -void PAUSMotionCompensation::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, - const QList &nodes) -{ - // Clear the combo box where we choose the photoacoustic image - m_Controls.comboBoxPA->clear(); - - // Make sure that there are exactle 2 nodes selected - if (nodes.size() != 2) { - m_Controls.labelWarning->setVisible(true); - m_Controls.buttonPerformImageProcessing->setEnabled(false); - return; - } - - // Make sure that the image data is okay - foreach (mitk::DataNode::Pointer node, nodes) { - if (node.IsNull() || !dynamic_cast(node->GetData())) { - m_Controls.labelWarning->setVisible(true); - m_Controls.buttonPerformImageProcessing->setEnabled(false); - return; - } - - // Add the image names to the combo box - m_Controls.comboBoxPA->addItem(QString::fromStdString(node->GetName())); - } - - m_Controls.labelWarning->setVisible(false); - m_Controls.buttonPerformImageProcessing->setEnabled(true); - -} - -void PAUSMotionCompensation::DoImageProcessing() -{ - QList nodes = this->GetDataManagerSelection(); - - // Make sure that there are two images selected - if (nodes.empty() || nodes.size() != 2) - { - QMessageBox::information(nullptr, "Warning", "Please select two images before starting image processing."); - return; - } - - mitk::DataNode::Pointer paNode, usNode; - - foreach (mitk::DataNode::Pointer node, nodes) { - if(m_Controls.comboBoxPA->itemText(m_Controls.comboBoxPA->currentIndex()) == QString::fromStdString(node->GetName())) { - paNode = node; - } else { - usNode = node; - } - } - - if(paNode.IsNull() || usNode.IsNull()) { - MITK_INFO << "One of the nodes is empty. This may happen, if the two images have the same name. Please rename one of them."; - QMessageBox::information(nullptr, "Template", "One of the nodes is empty. This may happen, if the two images have the same name. Please rename one of them."); - return; - } - - // here we have a valid mitk::DataNode - - // a node itself is not very useful, we need its data item (the image) - mitk::BaseData *paData = paNode->GetData(); - mitk::BaseData *usData = usNode->GetData(); - if (paData && usData) - { - // test if this data item is an image or not (could also be a surface or something totally different) - mitk::Image *paImage = dynamic_cast(paData); - mitk::Image *usImage = dynamic_cast(usData); - if (paImage && usImage) - { - std::stringstream message; - std::string name; - message << "Performing motion compensation for image "; - if (paNode->GetName(name)) - { - // a property called "name" was found for this DataNode - message << "'" << name << "'"; - } - message << " and "; - if (usNode->GetName(name)) { - message << "'" << name << "'"; - } - message << "."; - MITK_INFO << message.str(); - - // actually do something here... - m_Filter->SetPaInput(paImage); - m_Filter->SetUsInput(usImage); - try{ - m_Filter->Update(); - } - catch (const std::exception& ) { - QMessageBox::information(nullptr, "Warning", "Please make sure that both input images have the same dimension(s)."); - } - mitk::Image::Pointer paOutput = m_Filter->GetPaOutput(); - mitk::Image::Pointer usOutput = m_Filter->GetUsOutput(); - - auto paOutNode = mitk::DataNode::New(); - paOutNode->SetData(paOutput); - paOutNode->SetName(paNode->GetName() + " compensated"); - - this->GetDataStorage()->Add(paOutNode); - - auto usOutNode = mitk::DataNode::New(); - usOutNode->SetData(usOutput); - usOutNode->SetName(usNode->GetName() + " compensated"); - - this->GetDataStorage()->Add(usOutNode); - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } - } -} - -void PAUSMotionCompensation::DoUpdateParameters() { - - bool ok; - - unsigned int batchSize = m_Controls.lineBatchSize->text().toInt(&ok); - if(!ok) { - QMessageBox::information(nullptr, "Warning", "Invalid parameter."); - return; - } - m_Filter->SetBatchSize(batchSize); - - double pyrScale = m_Controls.linePyrScale->text().toDouble(&ok); - if(!ok) { - QMessageBox::information(nullptr, "Warning", "Invalid parameter."); - return; - } - m_Filter->SetPyrScale(pyrScale); - - unsigned int levels = m_Controls.lineLevels->text().toInt(&ok); - if(!ok) { - QMessageBox::information(nullptr, "Warning", "Invalid parameter."); - return; - } - m_Filter->SetLevels(levels); - - unsigned int winSize = m_Controls.lineWinSize->text().toInt(&ok); - if(!ok) { - QMessageBox::information(nullptr, "Warning", "Invalid parameter."); - return; - } - m_Filter->SetWinSize(winSize); - - unsigned int iterations = m_Controls.lineIterations->text().toInt(&ok); - if(!ok) { - QMessageBox::information(nullptr, "Warning", "Invalid parameter."); - return; - } - m_Filter->SetIterations(iterations); - - unsigned int polyN = m_Controls.linePolyN->text().toInt(&ok); - if(!ok) { - QMessageBox::information(nullptr, "Warning", "Invalid parameter."); - return; - } - m_Filter->SetPolyN(polyN); - - double polySigma = m_Controls.linePolySigma->text().toDouble(&ok); - if(!ok) { - QMessageBox::information(nullptr, "Warning", "Invalid parameter."); - return; - } - m_Filter->SetPolySigma(polySigma); -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensation.h b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensation.h deleted file mode 100644 index 7834097528..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensation.h +++ /dev/null @@ -1,58 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef PAUSMotionCompensation_h -#define PAUSMotionCompensation_h - -#include - -#include - -#include "ui_PAUSMotionCompensationControls.h" - -#include "mitkPhotoacousticMotionCorrectionFilter.h" - -/** - \brief PAUSMotionCompensation - - Photoacoustic and ultrasound image motion correction can be performed with this plugin. Internally OpenCV2 calc OpticalFlowFarneback is used. - \sa QmitkAbstractView - \ingroup ${plugin_target}_internal -*/ -class PAUSMotionCompensation : public QmitkAbstractView -{ - // this is needed for all Qt objects that should have a Qt meta-object - // (everything that derives from QObject and wants to have signal/slots) - Q_OBJECT - -public: - static const std::string VIEW_ID; - -protected: - void CreateQtPartControl(QWidget *parent) override; - - void SetFocus() override; - - /// \brief called by QmitkFunctionality when DataManager's selection has changed - void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, - const QList &nodes) override; - - /// \brief Called when the user clicks the GUI button - void DoImageProcessing(); - void DoUpdateParameters(); - - Ui::PAUSMotionCompensationControls m_Controls; - mitk::PhotoacousticMotionCorrectionFilter::Pointer m_Filter = mitk::PhotoacousticMotionCorrectionFilter::New(); -}; - -#endif // PAUSMotionCompensation_h diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensationControls.ui b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensationControls.ui deleted file mode 100644 index 8afd79a28c..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/PAUSMotionCompensationControls.ui +++ /dev/null @@ -1,179 +0,0 @@ - - - PAUSMotionCompensationControls - - - - 0 - 0 - 242 - 555 - - - - - 0 - 0 - - - - QmitkTemplate - - - - - - QLabel { color: rgb(255, 0, 0) } - - - Please select 2 images! - - - - - - - Photoacoustic image - - - - - - - - - - Do image processing - - - Start processing - - - - - - - Batch size - - - - - - - 5 - - - - - - - Pyramid scale: - - - - - - - 0.5 - - - - - - - Levels: - - - - - - - 3 - - - - - - - Averaging window size: - - - - - - - 15 - - - - - - - Iterations: - - - - - - - 3 - - - - - - - Pixel neighborhood for poly-expan: - - - - - - - 5 - - - - - - - Standard deviation: - - - - - - - 1.1 - - - - - - - Update Parameters - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 220 - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.cpp deleted file mode 100644 index ee5313cc7b..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#include "org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.h" -#include "PAUSMotionCompensation.h" - -namespace mitk -{ - void org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator::start(ctkPluginContext *context) - { - BERRY_REGISTER_EXTENSION_CLASS(PAUSMotionCompensation, context) - } - - void org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator::stop(ctkPluginContext *context) { Q_UNUSED(context) } -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.h b/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.h deleted file mode 100644 index 50bacd7c85..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausmotioncompensation/src/internal/org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator.h +++ /dev/null @@ -1,34 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator_h -#define org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator_h - -#include - -namespace mitk -{ - class org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator : public QObject, public ctkPluginActivator - { - Q_OBJECT - Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_photoacoustics_pausmotioncompensation") - Q_INTERFACES(ctkPluginActivator) - - public: - void start(ctkPluginContext *context) override; - void stop(ctkPluginContext *context) override; - - }; // org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator -} - -#endif // org_mitk_gui_qt_photoacoustics_pausmotioncompensation_Activator_h diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/CMakeLists.txt b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/CMakeLists.txt deleted file mode 100644 index 5c420ea0f4..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# The project name must correspond to the directory name of your plug-in -# and must not contain periods. -project(org_mitk_gui_qt_photoacoustics_pausviewer) - -mitk_create_plugin( - EXPORT_DIRECTIVE PHOTOACOUSTICS_PAUSVIEWER_EXPORTS - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkQtWidgets MitkAnnotation -) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/files.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/files.cmake deleted file mode 100644 index eabd5d2d68..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/files.cmake +++ /dev/null @@ -1,29 +0,0 @@ -set(SRC_CPP_FILES - QmitkPAUSViewerView.cpp -) - -set(INTERNAL_CPP_FILES - org_mitk_gui_qt_photoacoustics_pausviewer_Activator.cpp -) - -set(UI_FILES - src/internal/QmitkPAUSViewerViewControls.ui -) - -set(MOC_H_FILES - src/QmitkPAUSViewerView.h - src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.h -) - -set(CACHED_RESOURCE_FILES - resources/iconPAUSViewer.svg - plugin.xml -) - -foreach(file ${SRC_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/${file}) -endforeach(file ${SRC_CPP_FILES}) - -foreach(file ${INTERNAL_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/internal/${file}) -endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/manifest_headers.cmake deleted file mode 100644 index bd3c813501..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "PA US Viewer") -set(Plugin-Version "0.9") -set(Plugin-Vendor "German Cancer Research Center (DKFZ)") -set(Plugin-ContactAddress "http://www.mitk.org") -set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/plugin.xml b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/plugin.xml deleted file mode 100644 index 841dacc1b8..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/plugin.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/PAUSViewer.png b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/PAUSViewer.png deleted file mode 100644 index 8c0e9f9c88..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/PAUSViewer.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/iconPAUSViewer.svg b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/iconPAUSViewer.svg deleted file mode 100644 index fa91872af4..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/resources/iconPAUSViewer.svg +++ /dev/null @@ -1,62 +0,0 @@ - -image/svg+xml diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/QmitkPAUSViewerView.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/QmitkPAUSViewerView.cpp deleted file mode 100644 index c5952656d8..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/QmitkPAUSViewerView.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// Blueberry -#include -#include -#include "mitkScaleLegendAnnotation.h" -#include "mitkLayoutAnnotationRenderer.h" -#include "mitkManualPlacementAnnotationRenderer.h" -#include "mitkTextAnnotation2D.h" - -#include "QmitkPAUSViewerView.h" - -const std::string QmitkPAUSViewerView::VIEW_ID = "org.mitk.views.photoacoustics.pausviewer"; - -QmitkPAUSViewerView::QmitkPAUSViewerView() : m_PADataStorage(mitk::StandaloneDataStorage::New()), m_USDataStorage(mitk::StandaloneDataStorage::New()), m_UltrasoundReference(nullptr) -{ -} - -QmitkPAUSViewerView::~QmitkPAUSViewerView() -{ - if(m_UltrasoundReference != nullptr) - *m_UltrasoundReference = nullptr; -} - -void QmitkPAUSViewerView::InitWindows() -{ - AddOverlays(); -} - -void QmitkPAUSViewerView::SetFocus() -{ -} - -void QmitkPAUSViewerView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, - const QList& /*nodes*/) -{ -} - -void QmitkPAUSViewerView::CreateQtPartControl(QWidget *parent) -{ - m_Controls = new Ui::QmitkPAUSViewerViewControls; - m_Controls->setupUi(parent); - - m_Controls->m_PARenderWindow->GetRenderer()->SetDataStorage(m_PADataStorage); - m_Controls->m_USRenderWindow->GetRenderer()->SetDataStorage(m_USDataStorage); -} - -void QmitkPAUSViewerView::SetPADataStorage(mitk::StandaloneDataStorage::Pointer paStore) -{ - if (m_Controls == nullptr) - return; - - m_PADataStorage = paStore; - m_Controls->m_PARenderWindow->GetRenderer()->SetDataStorage(m_PADataStorage); - m_Controls->m_PALevelWindow->SetDataStorage(m_PADataStorage); -} - -void QmitkPAUSViewerView::SetUSDataStorage(mitk::StandaloneDataStorage::Pointer usStore) -{ - if (m_Controls == nullptr) - return; - - m_USDataStorage = usStore; - m_Controls->m_USRenderWindow->GetRenderer()->SetDataStorage(m_USDataStorage); - m_Controls->m_USLevelWindow->SetDataStorage(m_USDataStorage); -} - -vtkRenderWindow* QmitkPAUSViewerView::GetPARenderWindow() -{ - if (m_Controls == nullptr) - return nullptr; - - return m_Controls->m_PARenderWindow->renderWindow(); -} - -vtkRenderWindow* QmitkPAUSViewerView::GetUSRenderWindow() -{ - if (m_Controls == nullptr) - return nullptr; - - return m_Controls->m_USRenderWindow->renderWindow(); -} - - -void QmitkPAUSViewerView::AddOverlays() -{ - //if (m_PARenderer == nullptr || /*m_PAOverlayController == nullptr||*/ m_USRenderer == nullptr /*|| m_USOverlayController == nullptr*/) - //{ - m_PARenderer = mitk::BaseRenderer::GetInstance(GetPARenderWindow()); - m_USRenderer = mitk::BaseRenderer::GetInstance(GetUSRenderWindow()); - //} - MITK_INFO << "1111111111111111111111"; - mitk::ScaleLegendAnnotation::Pointer scaleAnnotation = mitk::ScaleLegendAnnotation::New(); - //scaleAnnotation->SetLeftAxisVisibility(true); - //scaleAnnotation->SetRightAxisVisibility(false); - //scaleAnnotation->SetRightAxisVisibility(false); - //scaleAnnotation->SetTopAxisVisibility(false); - //scaleAnnotation->SetCornerOffsetFactor(0); - MITK_INFO << "1111111111111111111111"; - - // Add Overlays - //![TextAnnotation2D] - // Create a textAnnotation2D - mitk::TextAnnotation2D::Pointer textAnnotation = mitk::TextAnnotation2D::New(); - - textAnnotation->SetText("Test!"); // set UTF-8 encoded text to render - textAnnotation->SetFontSize(40); - textAnnotation->SetColor(1, 0, 0); // Set text color to red - textAnnotation->SetOpacity(0.5); - MITK_INFO << "1111111111111111111111"; - - // The position of the Annotation can be set to a fixed coordinate on the display. - mitk::Point2D pos; - pos[0] = 10; - pos[1] = 20; - textAnnotation->SetPosition2D(pos); - MITK_INFO << "1111111111111111111111"; - - std::string rendererID = m_PARenderer->GetName(); - - // The LayoutAnnotationRenderer can place the TextAnnotation2D at some defined corner positions - mitk::LayoutAnnotationRenderer::AddAnnotation( - textAnnotation, rendererID, mitk::LayoutAnnotationRenderer::TopLeft, 5, 5, 1); - mitk::LayoutAnnotationRenderer::AddAnnotation( - textAnnotation, m_PARenderer.GetPointer(), mitk::LayoutAnnotationRenderer::TopLeft, 5, 5, 1); - mitk::ManualPlacementAnnotationRenderer::AddAnnotation( - textAnnotation, m_PARenderer.GetPointer()); - MITK_INFO << "1111111111111111111111"; - - - mitk::LayoutAnnotationRenderer::AddAnnotation(scaleAnnotation.GetPointer(), m_PARenderer->GetName(), mitk::LayoutAnnotationRenderer::TopLeft, 5, 5, 1); - mitk::LayoutAnnotationRenderer::AddAnnotation(scaleAnnotation.GetPointer(), m_USRenderer, mitk::LayoutAnnotationRenderer::TopLeft, 5, 5, 1); - MITK_INFO << "1111111111111111111111"; - -} - -void QmitkPAUSViewerView::RemoveOverlays() -{ - // m_PAOverlayManager->RemoveAllOverlays(); -} - -void QmitkPAUSViewerView::SetUltrasoundReference(QmitkPAUSViewerView** ultrasoundReference) -{ - m_UltrasoundReference = ultrasoundReference; -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/QmitkPAUSViewerView.h b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/QmitkPAUSViewerView.h deleted file mode 100644 index f8aaa5d4ee..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/QmitkPAUSViewerView.h +++ /dev/null @@ -1,70 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef QMITKPAUSVIEWERVIEW_H_INCLUDED -#define QMITKPAUSVIEWERVIEW_H_INCLUDED - -#include -#include -#include -#include -#include "QmitkRenderWindow.h" - -#include "ui_QmitkPAUSViewerViewControls.h" -#include "org_mitk_gui_qt_photoacoustics_pausviewer_Export.h" - -#include "mitkCommon.h" - -class PHOTOACOUSTICS_PAUSVIEWER_EXPORTS QmitkPAUSViewerView : public QmitkAbstractView -{ - // this is needed for all Qt objects that should have a Qt meta-object - // (everything that derives from QObject and wants to have signal/slots) - Q_OBJECT - -public: - - static const std::string VIEW_ID; - - QmitkPAUSViewerView(); - ~QmitkPAUSViewerView() override; - - void CreateQtPartControl(QWidget *parent) override; - void InitWindows(); - - void SetPADataStorage(mitk::StandaloneDataStorage::Pointer paStore); - void SetUSDataStorage(mitk::StandaloneDataStorage::Pointer usStore); - - vtkRenderWindow* GetPARenderWindow(); - vtkRenderWindow* GetUSRenderWindow(); - - void SetUltrasoundReference(QmitkPAUSViewerView** ultrasoundReference); - -protected: - - void AddOverlays(); - void RemoveOverlays(); - - mitk::StandaloneDataStorage::Pointer m_PADataStorage; - mitk::StandaloneDataStorage::Pointer m_USDataStorage; - mitk::BaseRenderer::Pointer m_PARenderer; - mitk::BaseRenderer::Pointer m_USRenderer; - - void SetFocus() override; - - void OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList&) override; - - Ui::QmitkPAUSViewerViewControls* m_Controls; - QmitkPAUSViewerView** m_UltrasoundReference; -}; - -#endif // QMITKPAUSVIEWERVIEW_H_INCLUDED - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/QmitkPAUSViewerViewControls.ui b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/QmitkPAUSViewerViewControls.ui deleted file mode 100644 index 8d192e8de4..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/QmitkPAUSViewerViewControls.ui +++ /dev/null @@ -1,129 +0,0 @@ - - - QmitkPAUSViewerViewControls - - - - 0 - 0 - 1086 - 744 - - - - - 0 - 0 - - - - QmitkTemplate - - - false - - - - - - - - - 0 - 0 - - - - - - - - - 75 - true - - - - Ultrasound - - - - - - - - 0 - 0 - - - - - - - - - 75 - true - - - - Photoacoustics - - - - - - - - 0 - 0 - - - - - 20 - 20 - - - - - - - - - 0 - 0 - - - - - 20 - 20 - - - - - - - - - - - - QmitkRenderWindow - QListView -
QmitkRenderWindow.h
-
- - QmitkLevelWindowWidget - QWidget -
QmitkLevelWindowWidget.h
- 1 -
-
- - QmitkDataStorageComboBox.h - - - -
diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.cpp deleted file mode 100644 index e8add31500..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "org_mitk_gui_qt_photoacoustics_pausviewer_Activator.h" -#include "QmitkPAUSViewerView.h" - - -namespace mitk { - - void org_mitk_gui_qt_photoacoustics_pausviewer_Activator::start(ctkPluginContext* context) - { - BERRY_REGISTER_EXTENSION_CLASS(QmitkPAUSViewerView, context) - } - - void org_mitk_gui_qt_photoacoustics_pausviewer_Activator::stop(ctkPluginContext* context) - { - Q_UNUSED(context) - } - -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.h b/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.h deleted file mode 100644 index aae45490d2..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.pausviewer/src/internal/org_mitk_gui_qt_photoacoustics_pausviewer_Activator.h +++ /dev/null @@ -1,35 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ -#ifndef _MITKPAUSVIEWERPLUGINACTIVATOR_H -#define _MITKPAUSVIEWERPLUGINACTIVATOR_H - -#include - -namespace mitk { - - class org_mitk_gui_qt_photoacoustics_pausviewer_Activator : - public QObject, public ctkPluginActivator - { - Q_OBJECT - Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_photoacoustics_pausviewer") - Q_INTERFACES(ctkPluginActivator) - - public: - - void start(ctkPluginContext* context) override; - void stop(ctkPluginContext* context) override; - - }; - -} - -#endif // _MITKPAUSVIEWERPLUGINACTIVATOR_H diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/CMakeLists.txt deleted file mode 100644 index e481678c85..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -project(org_mitk_gui_qt_photoacoustics_simulation) - -mitk_create_plugin( - EXPORT_DIRECTIVE PHOTOACOUSTICSIMULATION_EXPORT - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkPhotoacousticsLib MitkQtWidgetsExt - PACKAGE_DEPENDS PUBLIC ITK -) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/files.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/files.cmake deleted file mode 100644 index 1d8c9f11f8..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/files.cmake +++ /dev/null @@ -1,42 +0,0 @@ -set(SRC_CPP_FILES - -) - -set(INTERNAL_CPP_FILES - org_mitk_gui_qt_photoacousticsimulation_Activator.cpp - PASimulator.cpp -) - -set(UI_FILES - src/internal/PASimulatorControls.ui -) - -set(MOC_H_FILES - src/internal/org_mitk_gui_qt_photoacousticsimulation_Activator.h - src/internal/PASimulator.h -) - -# list of resource files which can be used by the plug-in -# system without loading the plug-ins shared library, -# for example the icon used in the menu and tabs for the -# plug-in views in the workbench -set(CACHED_RESOURCE_FILES - resources/pai_simulation.svg - plugin.xml -) - -# list of Qt .qrc files which contain additional resources -# specific to this plugin -set(QRC_FILES - -) - -set(CPP_FILES ) - -foreach(file ${SRC_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/${file}) -endforeach(file ${SRC_CPP_FILES}) - -foreach(file ${INTERNAL_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/internal/${file}) -endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/manifest_headers.cmake deleted file mode 100644 index 4580c5bd1b..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "Photoacousticsimulation") -set(Plugin-Version "0.1") -set(Plugin-Vendor "DKFZ") -set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/plugin.xml b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/plugin.xml deleted file mode 100644 index 1e47858a91..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/plugin.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/resources/pai_simulation.svg b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/resources/pai_simulation.svg deleted file mode 100644 index 23e71640e5..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/resources/pai_simulation.svg +++ /dev/null @@ -1,74 +0,0 @@ - -image/svg+xml diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.cpp deleted file mode 100644 index bc0de72a49..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// Blueberry -#include -#include - -// Qmitk -#include "PASimulator.h" - -// Qt -#include -#include -#include - -// mitk -#include -#include -#include - -#include -#include - -const std::string PASimulator::VIEW_ID = "org.mitk.views.pasimulator"; - -void PASimulator::SetFocus() -{ - m_Controls.pushButtonShowRandomTissue->setFocus(); -} - -void PASimulator::CreateQtPartControl(QWidget *parent) -{ - m_Controls.setupUi(parent); - connect(m_Controls.pushButtonShowRandomTissue, SIGNAL(clicked()), this, SLOT(DoImageProcessing())); - connect(m_Controls.pushButtonOpenPath, SIGNAL(clicked()), this, SLOT(OpenFolder())); - connect(m_Controls.pushButtonOpenBinary, SIGNAL(clicked()), this, SLOT(OpenBinary())); - connect(m_Controls.checkBoxGenerateBatch, SIGNAL(clicked()), this, SLOT(UpdateVisibilityOfBatchCreation())); - connect(m_Controls.pushButtonAjustWavelength, SIGNAL(clicked()), this, SLOT(UpdateParametersAccordingToWavelength())); - connect(m_Controls.checkBoxRngSeed, SIGNAL(clicked()), this, SLOT(ClickedCheckboxFixedSeed())); - connect(m_Controls.checkBoxRandomizeParameters, SIGNAL(clicked()), this, SLOT(ClickedRandomizePhysicalParameters())); - - auto home = std::getenv("HOME"); - std::string home_env = ""; - if (home != nullptr) - { - home_env = std::string(home); - } - else - { - home = std::getenv("HOMEPATH"); - if (home != nullptr) - { - home_env = std::string(home); - } - } - m_Controls.label_NrrdFilePath->setText(home_env.c_str()); - - m_PhotoacousticPropertyCalculator = mitk::pa::PropertyCalculator::New(); - - UpdateVisibilityOfBatchCreation(); - ClickedRandomizePhysicalParameters(); - ClickedCheckboxFixedSeed(); -} - -void PASimulator::ClickedRandomizePhysicalParameters() -{ - m_Controls.spinboxRandomizeParameters->setEnabled(m_Controls.checkBoxRandomizeParameters->isChecked()); -} - -void PASimulator::ClickedCheckboxFixedSeed() -{ - m_Controls.spinBoxRngSeed->setEnabled(m_Controls.checkBoxRngSeed->isChecked()); -} - -void PASimulator::UpdateParametersAccordingToWavelength() -{ - int wavelength = m_Controls.spinboxWavelength->value(); - double bloodOxygenation = m_Controls.spinboxBloodOxygenSaturation->value() / 100; - - auto result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::BLOOD, wavelength, bloodOxygenation); - m_Controls.spinboxMaxAbsorption->setValue(result.mua); - m_Controls.spinboxMinAbsorption->setValue(result.mua); - m_Controls.spinboxBloodVesselScatteringMinimum->setValue(result.mus); - m_Controls.spinboxBloodVesselScatteringMaximum->setValue(result.mus); - m_Controls.spinboxBloodVesselAnisotropyMinimum->setValue(result.g); - m_Controls.spinboxBloodVesselAnisotropyMaximum->setValue(result.g); - - result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::EPIDERMIS, wavelength, bloodOxygenation); - m_Controls.spinboxSkinAbsorption->setValue(result.mua); - m_Controls.spinboxSkinScattering->setValue(result.mus); - m_Controls.spinboxSkinAnisotropy->setValue(result.g); - - result = m_PhotoacousticPropertyCalculator->CalculatePropertyForSpecificWavelength( - mitk::pa::PropertyCalculator::TissueType::STANDARD_TISSUE, wavelength, bloodOxygenation); - m_Controls.spinboxBackgroundAbsorption->setValue(result.mua); - m_Controls.spinboxBackgroundScattering->setValue(result.mus); - m_Controls.spinboxBackgroundAnisotropy->setValue(result.g); -} - -void PASimulator::UpdateVisibilityOfBatchCreation() -{ - m_Controls.widgetBatchFile->setVisible(m_Controls.checkBoxGenerateBatch->isChecked()); -} - -mitk::pa::TissueGeneratorParameters::Pointer PASimulator::GetParametersFromUIInput() -{ - auto parameters = mitk::pa::TissueGeneratorParameters::New(); - - // Getting settings from UI - // General settings - parameters->SetXDim(m_Controls.spinboxXDim->value()); - parameters->SetYDim(m_Controls.spinboxYDim->value()); - parameters->SetZDim(m_Controls.spinboxZDim->value()); - parameters->SetDoPartialVolume(m_Controls.checkBoxPartialVolume->isChecked()); - parameters->SetRandomizePhysicalProperties(m_Controls.checkBoxRandomizeParameters->isChecked()); - parameters->SetRandomizePhysicalPropertiesPercentage(m_Controls.spinboxRandomizeParameters->value()); - parameters->SetVoxelSpacingInCentimeters(m_Controls.spinboxSpacing->value()); - parameters->SetUseRngSeed(m_Controls.checkBoxRngSeed->isChecked()); - parameters->SetRngSeed(m_Controls.spinBoxRngSeed->value()); - - // Monte Carlo simulation parameters - parameters->SetMCflag(m_Controls.spinboxMcFlag->value()); - parameters->SetMCLaunchflag(m_Controls.spinboxLaunchFlag->value()); - parameters->SetMCBoundaryflag(m_Controls.spinboxboundaryFlag->value()); - parameters->SetMCLaunchPointX(m_Controls.spinboxLaunchpointX->value()); - parameters->SetMCLaunchPointY(m_Controls.spinboxLaunchpointY->value()); - parameters->SetMCLaunchPointZ(m_Controls.spinboxLaunchpointZ->value()); - parameters->SetMCFocusPointX(m_Controls.spinboxFocuspointX->value()); - parameters->SetMCFocusPointY(m_Controls.spinboxFocuspointY->value()); - parameters->SetMCFocusPointZ(m_Controls.spinboxFocuspointZ->value()); - parameters->SetMCTrajectoryVectorX(m_Controls.spinboxTrajectoryVectorX->value()); - parameters->SetMCTrajectoryVectorY(m_Controls.spinboxTrajectoryVectorY->value()); - parameters->SetMCTrajectoryVectorZ(m_Controls.spinboxTrajectoryVectorZ->value()); - parameters->SetMCRadius(m_Controls.spinboxRadius->value()); - parameters->SetMCWaist(m_Controls.spinboxWaist->value()); - - // Vessel settings - parameters->SetMaxVesselAbsorption(m_Controls.spinboxMaxAbsorption->value()); - parameters->SetMinVesselAbsorption(m_Controls.spinboxMinAbsorption->value()); - parameters->SetMaxVesselBending(m_Controls.spinboxMaxBending->value()); - parameters->SetMinVesselBending(m_Controls.spinboxMinBending->value()); - parameters->SetMaxVesselRadiusInMillimeters(m_Controls.spinboxMaxDiameter->value()); - parameters->SetMinVesselRadiusInMillimeters(m_Controls.spinboxMinDiameter->value()); - parameters->SetMaxNumberOfVessels(m_Controls.spinboxMaxVessels->value()); - parameters->SetMinNumberOfVessels(m_Controls.spinboxMinVessels->value()); - parameters->SetMinVesselScattering(m_Controls.spinboxBloodVesselScatteringMinimum->value()); - parameters->SetMaxVesselScattering(m_Controls.spinboxBloodVesselScatteringMaximum->value()); - parameters->SetMinVesselAnisotropy(m_Controls.spinboxBloodVesselAnisotropyMinimum->value()); - parameters->SetMaxVesselAnisotropy(m_Controls.spinboxBloodVesselAnisotropyMaximum->value()); - parameters->SetVesselBifurcationFrequency(m_Controls.spinboxBifurcationFrequency->value()); - parameters->SetMinVesselZOrigin(m_Controls.spinboxMinSpawnDepth->value()); - parameters->SetMaxVesselZOrigin(m_Controls.spinboxMaxSpawnDepth->value()); - - // Background tissue settings - parameters->SetMinBackgroundAbsorption(m_Controls.spinboxBackgroundAbsorption->value()); - parameters->SetMaxBackgroundAbsorption(m_Controls.spinboxBackgroundAbsorption->value()); - parameters->SetBackgroundScattering(m_Controls.spinboxBackgroundScattering->value()); - parameters->SetBackgroundAnisotropy(m_Controls.spinboxBackgroundAnisotropy->value()); - - // Air settings - parameters->SetAirThicknessInMillimeters(m_Controls.spinboxAirThickness->value()); - - //Skin tissue settings - parameters->SetSkinThicknessInMillimeters(m_Controls.spinboxSkinThickness->value()); - parameters->SetSkinAbsorption(m_Controls.spinboxSkinAbsorption->value()); - parameters->SetSkinScattering(m_Controls.spinboxSkinScattering->value()); - parameters->SetSkinAnisotropy(m_Controls.spinboxSkinAnisotropy->value()); - - parameters->SetCalculateNewVesselPositionCallback(&mitk::pa::VesselMeanderStrategy::CalculateNewRandomlyDivergingDirectionVector); - - return parameters; -} - -void PASimulator::DoImageProcessing() -{ - int numberOfVolumes = 1; - - if (m_Controls.checkBoxGenerateBatch->isChecked()) - { - if (m_Controls.labelBinarypath->text().isNull() || m_Controls.labelBinarypath->text().isEmpty()) - { - QMessageBox::warning(nullptr, QString("Warning"), QString("You need to specify the binary first!")); - return; - } - - numberOfVolumes = m_Controls.spinboxNumberVolumes->value(); - - if (numberOfVolumes < 1) - { - QMessageBox::warning(nullptr, QString("Warning"), QString("You need to create at least one volume!")); - return; - } - } - - auto tissueParameters = GetParametersFromUIInput(); - - for (int volumeIndex = 0; volumeIndex < numberOfVolumes; volumeIndex++) - { - mitk::pa::InSilicoTissueVolume::Pointer volume = - mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(tissueParameters); - - mitk::Image::Pointer tissueVolume = volume->ConvertToMitkImage(); - - if (m_Controls.checkBoxGenerateBatch->isChecked()) - { - std::string nrrdFilePath = m_Controls.label_NrrdFilePath->text().toStdString(); - std::string tissueName = m_Controls.lineEditTissueName->text().toStdString(); - std::string binaryPath = m_Controls.labelBinarypath->text().toStdString(); - long numberOfPhotons = m_Controls.spinboxNumberPhotons->value() * 1000L; - - auto batchParameters = mitk::pa::SimulationBatchGeneratorParameters::New(); - batchParameters->SetBinaryPath(binaryPath); - batchParameters->SetNrrdFilePath(nrrdFilePath); - batchParameters->SetNumberOfPhotons(numberOfPhotons); - batchParameters->SetTissueName(tissueName); - batchParameters->SetVolumeIndex(volumeIndex); - batchParameters->SetYOffsetLowerThresholdInCentimeters(m_Controls.spinboxFromValue->value()); - batchParameters->SetYOffsetUpperThresholdInCentimeters(m_Controls.spinboxToValue->value()); - batchParameters->SetYOffsetStepInCentimeters(m_Controls.spinboxStepValue->value()); - mitk::pa::SimulationBatchGenerator::WriteBatchFileAndSaveTissueVolume(batchParameters, tissueVolume); - } - else - { - mitk::DataNode::Pointer dataNode = mitk::DataNode::New(); - dataNode->SetData(tissueVolume); - dataNode->SetName(m_Controls.lineEditTissueName->text().toStdString()); - this->GetDataStorage()->Add(dataNode); - mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); - } - } -} - -void PASimulator::OpenFolder() -{ - m_Controls.label_NrrdFilePath->setText(QFileDialog::getExistingDirectory().append("/")); -} - -void PASimulator::OpenBinary() -{ - m_Controls.labelBinarypath->setText(QFileDialog::getOpenFileName()); -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.h b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.h deleted file mode 100644 index 60dc6b4dd2..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulator.h +++ /dev/null @@ -1,72 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef PASimulator_h -#define PASimulator_h - -#include - -#include - -#include "ui_PASimulatorControls.h" - -#include "mitkPATissueGenerator.h" -#include "mitkPATissueGeneratorParameters.h" -#include "mitkPAInSilicoTissueVolume.h" -#include "mitkPAPropertyCalculator.h" -#include "mitkPASimulationBatchGenerator.h" - -/** - \brief PASimulator - - \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. - - \sa QmitkAbstractView - \ingroup ${plugin_target}_internal -*/ -class PASimulator : public QmitkAbstractView -{ - // this is needed for all Qt objects that should have a Qt meta-object - // (everything that derives from QObject and wants to have signal/slots) - Q_OBJECT - -public: - - static const std::string VIEW_ID; - - protected slots: - - /// \brief Called when the user clicks the GUI button - void DoImageProcessing(); - void ClickedCheckboxFixedSeed(); - void ClickedRandomizePhysicalParameters(); - void OpenFolder(); - void OpenBinary(); - void UpdateVisibilityOfBatchCreation(); - void UpdateParametersAccordingToWavelength(); - -protected: - - void CreateQtPartControl(QWidget *parent) override; - - void SetFocus() override; - - Ui::PASimulatorControls m_Controls; - - mitk::pa::PropertyCalculator::Pointer m_PhotoacousticPropertyCalculator; - -private: - - mitk::pa::TissueGeneratorParameters::Pointer GetParametersFromUIInput(); -}; - -#endif // PASimulator_h diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulatorControls.ui b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulatorControls.ui deleted file mode 100644 index 4187e1e967..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/PASimulatorControls.ui +++ /dev/null @@ -1,4728 +0,0 @@ - - - PASimulatorControls - - - - 0 - 0 - 437 - 655 - - - - - 0 - 0 - - - - - Ubuntu - - - - Qt::NoContextMenu - - - QmitkTemplate - - - - :/org.mitk.gui.qt.photoacousticsimulation/resources/icon.xpm:/org.mitk.gui.qt.photoacousticsimulation/resources/icon.xpm - - - - - - - 0 - 0 - - - - - 415 - 600 - - - - - Ubuntu - - - - 0 - - - - Generator - - - - - 10 - 10 - 391 - 581 - - - - - 0 - 0 - - - - - 391 - 581 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 75 - true - - - - Volume parameters - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Tissue name: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Size x: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 50 - false - - - - Spacing: - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - PhotoacousticTissue - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 1 - - - 9999 - - - 35 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - y: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 9999 - - - 50 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - z: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 9999 - - - 50 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - voxels - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 5 - - - 0.010000000000000 - - - 0.120000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - cm - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Randomize: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Custom seed: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Partial volume effects: - - - - - - - Generate batch file output: - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - - - false - - - - - - - true - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - - - true - - - - - - - true - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - - - true - - - - - - - - - - false - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - sigma: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 0 - - - 100.000000000000000 - - - 0.010000000000000 - - - 2.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - % - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 999999999 - - - 1337 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - Number of volumes to generate: - - - - - - - 1 - - - 9999999 - - - 1 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Save generated tissue path: - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - open - - - - - - - - - - - - - - - - - - Path to MitkMcxyz binary: - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - open - - - - - - - - - - - - - - - - - - From (cm): - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - -100000.000000000000000 - - - 100000.000000000000000 - - - 0.100000000000000 - - - -1.800000000000000 - - - - - - - To (cm): - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.100000000000000 - - - 1.800000000000000 - - - - - - - Step: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.010000000000000 - - - 0.120000000000000 - - - - - - - - - - - Number of Photons (x1000): - - - - - - - 0 - - - 999999999 - - - 1 - - - 100000 - - - - - - - - - - - - - 0 - 0 - - - - Generate Tissue - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Tissue - - - - - 10 - 10 - 391 - 581 - - - - - 0 - 0 - - - - - 391 - 581 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 11 - 75 - false - true - false - - - - Air Parameters - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 50 - false - - - - Thickness: - - - - - - - - 0 - 0 - - - - - 0 - 10 - - - - - 16777215 - 10 - - - - - 11 - 75 - true - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 75 - false - true - false - - - - Background Parameters - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Absorption coefficient: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Scattering coefficient: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Anisotropy facor: - - - - - - - - 0 - 0 - - - - - 0 - 10 - - - - - 16777215 - 10 - - - - - 11 - 75 - true - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 75 - false - true - false - - - - Skin Parameters - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Thickness: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Absorption coefficient: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Scattering coefficient: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Anisotropy facor: - - - - - - - - 0 - 0 - - - - - 0 - 10 - - - - - 16777215 - 10 - - - - - 11 - 75 - true - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 11 - 75 - true - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 999.990000000000009 - - - 0.100000000000000 - - - 12.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - mm - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 0 - 10 - - - - - 16777215 - 10 - - - - - 11 - 75 - true - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 75 - true - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 5 - - - 0.010000000000000 - - - 0.100000000000000 - - - 0.100000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - per cm - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 5 - - - 0.010000000000000 - - - 1000.000000000000000 - - - 0.500000000000000 - - - 15.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - per cm - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 5 - - - 0.010000000000000 - - - 1.000000000000000 - - - 0.010000000000000 - - - 0.900000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 0 - 10 - - - - - 16777215 - 10 - - - - - 11 - 75 - true - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 75 - true - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 0.100000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - mm - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 5 - - - 0.010000000000000 - - - 0.100000000000000 - - - 3.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - per cm - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 5 - - - 0.010000000000000 - - - 1000.000000000000000 - - - 0.500000000000000 - - - 20.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - per cm - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 5 - - - 0.010000000000000 - - - 1.000000000000000 - - - 0.010000000000000 - - - 0.900000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 0 - 10 - - - - - 16777215 - 10 - - - - - 11 - 75 - true - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Vessels - - - - - 10 - 10 - 391 - 581 - - - - - 0 - 0 - - - - - 391 - 581 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 75 - true - - - - - - - Vessel Parameters - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The number of bloos vessels to generate - - - Count: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The radius of the blood vessels in mm - - - Radius: - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - the absorption coefficient refers to the number of absorption events per centimeter. - - - Absorption: - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The reduced scattering coefficient. -It refers to the amount of scattering events per centimeter. - - - Scattering: - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The anisotropy factor is the probability of a photon to not change its direction after a scattering event. - - - Anisotropy factor: - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The bifurcation frequency determines how often the vessel should bifurcate. -The vessel will bifurcate after meandering a mean of the specified amount of voxels. -When given a value of 0, the vessel will never bifurcate. - - - Bifurcation frequency: - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The curvedness it a setting to determine how much the vessel is allowed to bend during creation. -A value of 0 refers to no bending at all and a value of 5 is the maximum. - - - Curvedness: - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The spawn depth defines the depth range in which the vessels enter the volume. - - - Spawn depth: - - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimum number of blood vessels - - - 0 - - - 1 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - to - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The maximum number of blood vessels - - - 1 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Vessels - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimum radius - - - 5 - - - 2.250000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - to - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The maximum radius - - - 5 - - - 4.050000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - mm - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimum absorption coefficient - - - 5 - - - 0.010000000000000 - - - 2.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - to - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The maximum absorption coefficient - - - 5 - - - 0.010000000000000 - - - 8.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - per cm - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimum scattering - - - 5 - - - 0.010000000000000 - - - 999.000000000000000 - - - 1.000000000000000 - - - 15.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - to - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimum scattering - - - 5 - - - 0.010000000000000 - - - 999.000000000000000 - - - 1.000000000000000 - - - 15.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - per cm - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimum anisotropy factor - - - 5 - - - 0.010000000000000 - - - 1.000000000000000 - - - 0.100000000000000 - - - 0.900000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - to - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The maximum anisotropy factor - - - 5 - - - 0.010000000000000 - - - 1.000000000000000 - - - 0.100000000000000 - - - 0.900000000000000 - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The bifurcation frequency determines how often the vessel should bifurcate. -The vessel will bifurcate after meandering a mean of the specified amount of voxels. -When given a value of 0, the vessel will never bifurcate. - - - 0 - - - 1.000000000000000 - - - 999999999.000000000000000 - - - 5.000000000000000 - - - 50.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - voxels - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimal curvedness of the vessel. -A value of 0 refers to no bending at all and a value of 5 is the maximum. - - - 5.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - to - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The maximal curvedness of the vessel. -A value of 0 refers to no bending at all and a value of 5 is the maximum. - - - 5.000000000000000 - - - 0.010000000000000 - - - 0.200000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - A.U. - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - The minimum spawn depth - - - 5 - - - 0.010000000000000 - - - 2.200000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - to - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - the maximum spawn depth - - - 5 - - - 0.010000000000000 - - - 4.200000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - cm - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Monte Carlo - - - - - 10 - 10 - 391 - 581 - - - - - 0 - 0 - - - - - 391 - 581 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 75 - true - - - - Monte Carlo Parameters - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 50 - false - - - - General: - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Mcflag: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Launchflag: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Boundaryflag: - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 1 - - - 4 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 0 - - - 0 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 1 - - - 2 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 50 - false - - - - Initial launch point: - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - x - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - y - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - z - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 50 - false - - - - Focus point: - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - x - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - y - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - z - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - - 50 - false - - - - Trajectory vector: - - - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - x - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - y - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.342000000000000 - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - z - - - - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 4 - - - 1000000.000000000000000 - - - 0.939700000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - radius: - - - - - - - waist: - - - - - - - - - - - - - 4 - - - 1000.000000000000000 - - - 0.500000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 4 - - - 1000.000000000000000 - - - 0.010000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Wavelength - - - - - 10 - 10 - 391 - 581 - - - - - 0 - 0 - - - - - 391 - 581 - - - - Qt::NoContextMenu - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 75 - true - - - - Adjust physical properties by wavelength - - - - - - - false - - - - 16777215 - 250 - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Ubuntu'; font-size:7.8pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">This widget enables the adjustment of the physical properties of the tissue according to a selected wavelength of the light and the oxygen saturation of the blood.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The algorithm and measurements were provided by the publication </span><span style=" font-size:11pt; font-weight:600;">Optical properties of biological tissues: a review </span><span style=" font-size:11pt;">by Steve L. Jacques.</span></p></body></html> - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Wavelength: - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - Vessel oxygen saturation: - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 0 - - - 300.000000000000000 - - - 1000.000000000000000 - - - 650.000000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - 0 - - - 100.000000000000000 - - - 75.000000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 25 - - - - - 16777215 - 25 - - - - % - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - Adjust tissue properties - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/org_mitk_gui_qt_photoacousticsimulation_Activator.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/org_mitk_gui_qt_photoacousticsimulation_Activator.cpp deleted file mode 100644 index aa825b7358..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/org_mitk_gui_qt_photoacousticsimulation_Activator.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "org_mitk_gui_qt_photoacousticsimulation_Activator.h" -#include "PASimulator.h" - -void mitk::org_mitk_gui_qt_photoacousticsimulation_Activator::start(ctkPluginContext* context) -{ - BERRY_REGISTER_EXTENSION_CLASS(PASimulator, context) -} - -void mitk::org_mitk_gui_qt_photoacousticsimulation_Activator::stop(ctkPluginContext*) -{ -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/org_mitk_gui_qt_photoacousticsimulation_Activator.h b/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/org_mitk_gui_qt_photoacousticsimulation_Activator.h deleted file mode 100644 index 7a0804c507..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.simulation/src/internal/org_mitk_gui_qt_photoacousticsimulation_Activator.h +++ /dev/null @@ -1,32 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef org_mitk_gui_qt_photoacousticsimulation_Activator_h -#define org_mitk_gui_qt_photoacousticsimulation_Activator_h - -#include - -namespace mitk -{ - class org_mitk_gui_qt_photoacousticsimulation_Activator : public QObject, public ctkPluginActivator - { - Q_OBJECT - Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_photoacousticsimulation") - Q_INTERFACES(ctkPluginActivator) - - public: - void start(ctkPluginContext* context) override; - void stop(ctkPluginContext* context) override; - }; -} - -#endif diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/CMakeLists.txt b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/CMakeLists.txt deleted file mode 100644 index ac2049cb04..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -project(org_mitk_gui_qt_photoacoustics_spectralunmixing) - -mitk_create_plugin( - EXPORT_DIRECTIVE SPECTRALUNMIXING_EXPORT - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkQtWidgetsExt MitkPhotoacousticsLib -) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/GUI.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/GUI.PNG deleted file mode 100644 index 23c2c5cdd0..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/GUI.PNG and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/Manual.dox deleted file mode 100644 index f0c5887d21..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/Manual.dox +++ /dev/null @@ -1,32 +0,0 @@ -/** -\page org_mitk_gui_qt_photoacoustics_spectralunmixing The spectral unmixing (SU) plugin - -\imageMacro{photoacoustics_spectralunmixing-dox.png,"Icon of Spectralunmixing",2.00} - -\tableofcontents - -\section org_mitk_gui_qt_photoacoustics_spectralunmixingIntroduction -The spectral unmixing plugin provides a GUI tool to perform spectral unmixing of multispectral MITK images. It was designed to unmix beamformed photoacoustic images. The outputs are MITK images for every chosen absorber (endmember). Furthermore it is possible to calculate the oxygen saturation of the multispectral input if the endmembers oxy- and deoxyhemoglobin are selected in the GUI as well as an output image that contains the information about the relative error between unmixing result and the input image. -Detailed information about the Plugin, the baseclass and its subclasses can be found in their header files. If you want to call the SU filter from your own class have a look at the “mitkSpectralUnmixingTest.cpp”. There you find information about which functions are callable or have to be called from your class to guarantee the promised functionality of the SU filter. - -\section org_mitk_gui_qt_photoacoustics_spectralunmixingOverview -
    -
  • supports several linear Eigen solvers collected in the “mitkPALinearSpectralUnmixingFilter” -
  • supports several linear Vigra solvers collected in the “mitkPASpectralUnmixingVigraFilter” -
  • calculates oxygen saturation with the “mitkPASpectralUnmixingSO2” -
- -\section How to add an additional algorithm: -If the algorithm fits in one of the existing classes you can ignore steps 0. – 3. -0. Have a look at the commit rMITK36cfd1731089: implement three empty classes for Simplex, Lagrange and Vigra SU algorithms. Which actually are exactly the first (not all!) steps to implement a new algorithm. -1. Add your future header and cpp file to files.cmake -2. Create a header file which needs at least the methods shown in header.PNG -\imageMacro{header.PNG,"empty header for a new SU algorithm",2.00} -3. Create a cpp file which takes an Eigen endmember matrix and an Eigen input vector as inputs and returns an Eigen vector as result. A structure like in the cpp.PNG is recommended. If your class will consist of more than one algorithm you should have an if/else decision between them with an enum like in the cpp.PNG otherwise you can directly return your result. -\imageMacro{cpp.PNG,"example cpp file for a new SU algorithm",2.00} -4. In the Plugin you just have to add another “else if” like in the plugin.PNG. The string in the else if has to be the same then selectable in the GUI(step 5). -\imageMacro{plugin.PNG,"changes of Plugin for a new SU algorithm",2.00} -5. To make you algorithm selectable you have to add to the GUI Combobox. Klick at 1. (GUI.PNG), then at 2. and then name your algorithm 3. like in step 4. -\imageMacro{GUI.PNG,"changes of GUI for a new SU algorithm",2.00} - -*/ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/cpp.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/cpp.PNG deleted file mode 100644 index b47993b6cc..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/cpp.PNG and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/header.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/header.PNG deleted file mode 100644 index 1f02be12c8..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/header.PNG and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/photoacoustics_spectralunmixing-dox.png b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/photoacoustics_spectralunmixing-dox.png deleted file mode 100644 index 3384467830..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/photoacoustics_spectralunmixing-dox.png and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/plugin.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/plugin.PNG deleted file mode 100644 index 89d7559d66..0000000000 Binary files a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/plugin.PNG and /dev/null differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/doxygen/modules.dox deleted file mode 100644 index de1394cc0e..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/doxygen/modules.dox +++ /dev/null @@ -1,16 +0,0 @@ -/** - \defgroup org_mitk_gui_qt_photoacoustics_spectralunmixing org.mitk.gui.qt.photoacoustics.spectralunmixing - \ingroup MITKPlugins - - \brief Describe your plugin here. - -*/ - -/** - \defgroup org_mitk_gui_qt_photoacoustics_spectralunmixing_internal Internal - \ingroup org_mitk_gui_qt_photoacoustics_spectralunmixing - - \brief This subcategory includes the internal classes of the org.mitk.gui.qt.photoacoustics.spectralunmixing plugin. Other - plugins must not rely on these classes. They contain implementation details and their interface - may change at any time. We mean it. -*/ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/files.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/files.cmake deleted file mode 100644 index 2940e51e6b..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/files.cmake +++ /dev/null @@ -1,42 +0,0 @@ -set(SRC_CPP_FILES - -) - -set(INTERNAL_CPP_FILES - org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.cpp - SpectralUnmixing.cpp -) - -set(UI_FILES - src/internal/SpectralUnmixingControls.ui -) - -set(MOC_H_FILES - src/internal/org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.h - src/internal/SpectralUnmixing.h -) - -# list of resource files which can be used by the plug-in -# system without loading the plug-ins shared library, -# for example the icon used in the menu and tabs for the -# plug-in views in the workbench -set(CACHED_RESOURCE_FILES - resources/spectralunmixing.svg - plugin.xml -) - -# list of Qt .qrc files which contain additional resources -# specific to this plugin -set(QRC_FILES - -) - -set(CPP_FILES ) - -foreach(file ${SRC_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/${file}) -endforeach(file ${SRC_CPP_FILES}) - -foreach(file ${INTERNAL_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/internal/${file}) -endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/manifest_headers.cmake deleted file mode 100644 index a537cfdfe3..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "Spectralunmixing") -set(Plugin-Version "0.1") -set(Plugin-Vendor "DKFZ") -set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/plugin.xml b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/plugin.xml deleted file mode 100644 index 0e3fe22367..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/plugin.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/resources/spectralunmixing.svg b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/resources/spectralunmixing.svg deleted file mode 100644 index d021376ed0..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/resources/spectralunmixing.svg +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixing.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixing.cpp deleted file mode 100644 index df041d4a4d..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixing.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -// Blueberry -#include -#include - -// Qmitk -#include "SpectralUnmixing.h" - -// Qt -#include - -// mitk image -#include - -// Include to perform Spectral Unmixing -#include "mitkPASpectralUnmixingFilterBase.h" -#include "mitkPALinearSpectralUnmixingFilter.h" -#include "mitkPASpectralUnmixingSO2.h" -#include "mitkPASpectralUnmixingFilterVigra.h" -#include "mitkPASpectralUnmixingFilterLagrange.h" -#include "mitkPASpectralUnmixingFilterSimplex.h" - -#include -#include -#include - -const std::string SpectralUnmixing::VIEW_ID = "org.mitk.views.spectralunmixing"; - -void SpectralUnmixing::SetFocus() -{ - m_Controls.buttonPerformImageProcessing->setFocus(); -} - -void SpectralUnmixing::CreateQtPartControl(QWidget *parent) -{ - // create GUI widgets from the Qt Designer's .ui file - m_Controls.setupUi(parent); - connect(m_Controls.buttonPerformImageProcessing, &QPushButton::clicked, this, &SpectralUnmixing::DoImageProcessing); - m_Controls.tableWeight->hide(); - m_Controls.tableSO2->hide(); - m_Controls.tableError->hide(); - connect((QObject*)(m_Controls.QComboBoxAlgorithm), SIGNAL(currentIndexChanged(int)), this, SLOT(EnableGUIWeight())); - connect((QObject*)(m_Controls.checkBoxsO2), SIGNAL(clicked()), this, SLOT(EnableGUISO2())); - connect((QObject*)(m_Controls.checkBoxError), SIGNAL(clicked()), this, SLOT(EnableGUIError())); - this->connect(this, SIGNAL(finishSignal()), this, SLOT(storeOutputs())); - this->connect(this, SIGNAL(crashSignal()), this, SLOT(crashInfo())); - this->connect(this, SIGNAL(enableSignal()), this, SLOT(EnableGUIControl())); -} - -void SpectralUnmixing::EnableGUIControl() -{ - SwitchGUIControl(false); -} - -void SpectralUnmixing::SwitchGUIControl(bool change) -{ - m_Controls.inputtable->setEnabled(change); - m_Controls.checkBoxOx->setEnabled(change); - m_Controls.checkBoxDeOx->setEnabled(change); - m_Controls.checkBoxMelanin->setEnabled(change); - m_Controls.checkBoxAdd->setEnabled(change); - m_Controls.QComboBoxAlgorithm->setEnabled(change); - m_Controls.tableWeight->setEnabled(change); - m_Controls.checkBoxsO2->setEnabled(change); - m_Controls.tableSO2->setEnabled(change); - m_Controls.checkBoxVerbose->setEnabled(change); - m_Controls.checkBoxChrono->setEnabled(change); - m_Controls.buttonPerformImageProcessing->setEnabled(change); - m_Controls.checkBoxError->setEnabled(change); -} - -void SpectralUnmixing::EnableGUIWeight() -{ - auto qs = m_Controls.QComboBoxAlgorithm->currentText(); - std::string Algorithm = qs.toUtf8().constData(); - if (Algorithm == "weighted") - m_Controls.tableWeight->show(); - else - m_Controls.tableWeight->hide(); -} - -void SpectralUnmixing::EnableGUISO2() -{ - if (m_Controls.checkBoxsO2->isChecked()) - m_Controls.tableSO2->show(); - else - m_Controls.tableSO2->hide(); -} - -void SpectralUnmixing::EnableGUIError() -{ - if (m_Controls.checkBoxError->isChecked()) - m_Controls.tableError->show(); - else - m_Controls.tableError->hide(); -} - -void SpectralUnmixing::SetVerboseMode(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter, bool PluginVerbose) -{ - m_SpectralUnmixingFilter->Verbose(PluginVerbose); -} - -void SpectralUnmixing::SetWavlength(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter) -{ - int col = 0; - int Wavelength = 1; - while (m_Controls.inputtable->item(0, col) && Wavelength > 0) - { - QString Text = m_Controls.inputtable->item(0, col)->text(); - Wavelength = Text.toInt(); - if (Wavelength > 0) - { - m_SpectralUnmixingFilter->AddWavelength(Wavelength); - MITK_INFO(PluginVerbose) << "Wavelength: " << Wavelength << "nm \n"; - } - ++col; - } -} - -void SpectralUnmixing::SetChromophore(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter, std::vector boolVec, - std::vector chromophoreNameVec) -{ - unsigned int numberofChromophores = 0; - - std::vector m_ChromoType = { mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED, - mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED, mitk::pa::PropertyCalculator::ChromophoreType::MELANIN, - mitk::pa::PropertyCalculator::ChromophoreType::ONEENDMEMBER}; - - for (unsigned int chromo = 0; chromo < m_ChromoType.size(); ++chromo) - { - if (boolVec[chromo] == true) - { - MITK_INFO(PluginVerbose) << "Chromophore: " << chromophoreNameVec[chromo]; - m_SpectralUnmixingFilter->AddChromophore(m_ChromoType[chromo]); - numberofChromophores += 1; - } - } - - if (numberofChromophores == 0) - mitkThrow() << "PRESS 'IGNORE' AND CHOOSE A CHROMOPHORE!"; -} - -void SpectralUnmixing::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, - const QList &nodes) -{ - // iterate all selected objects, adjust warning visibility - foreach (mitk::DataNode::Pointer node, nodes) - { - if (node.IsNotNull() && dynamic_cast(node->GetData())) - { - m_Controls.labelWarning->setVisible(false); - m_Controls.buttonPerformImageProcessing->setEnabled(true); - return; - } - } - - m_Controls.labelWarning->setVisible(true); - m_Controls.buttonPerformImageProcessing->setEnabled(false); -} - -mitk::pa::SpectralUnmixingFilterBase::Pointer SpectralUnmixing::GetFilterInstance(std::string algorithm) -{ - mitk::pa::SpectralUnmixingFilterBase::Pointer spectralUnmixingFilter; - - if (algorithm == "householderQr") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); - } - - else if (algorithm == "ldlt") - { - MITK_WARN << "Unfortunaly algorithm is likley to fail!"; - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::LDLT); - } - - else if (algorithm == "llt") - { - MITK_WARN << "Unfortunaly algorithm is likley to fail!"; - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::LLT); - } - - else if (algorithm == "colPivHouseholderQr") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::COLPIVHOUSEHOLDERQR); - } - - else if (algorithm == "jacobiSvd") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::JACOBISVD); - } - - else if (algorithm == "fullPivLu") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVLU); - } - - else if (algorithm == "fullPivHouseholderQr") - { - spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVHOUSEHOLDERQR); - } - - else if (algorithm == "NNLARS") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LARS); - } - - else if (algorithm == "NNGoldfarb") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::GOLDFARB); - } - - else if (algorithm == "weighted") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::WEIGHTED); - //Tranfer GUI information(Weights) to filter - unsigned int colunm = 0; - int Weight = 1; - while (m_Controls.tableWeight->item(0, colunm) && Weight > 0) - { - QString Text = m_Controls.tableWeight->item(0, colunm)->text(); - Weight = Text.toInt(); - if (Weight > 0) - { - MITK_INFO(PluginVerbose) << "Weight: " << Weight; - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->AddWeight(Weight); - } - ++colunm; - } - } - - else if (algorithm == "LS") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); - dynamic_cast(spectralUnmixingFilter.GetPointer()) - ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LS); - } - - else if (algorithm == "SimplexMax") - { - spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterSimplex::New(); - } - - else - mitkThrow() << "404 ALGORITHM NOT FOUND!"; - - return spectralUnmixingFilter; -} - - -void SpectralUnmixing::SetSO2Settings(mitk::pa::SpectralUnmixingSO2::Pointer m_sO2) -{ - for (unsigned int i = 0; i < 4; ++i) - { - if (m_Controls.tableSO2->item(0, i)) - { - QString Text = m_Controls.tableSO2->item(0, i)->text(); - int value = Text.toInt(); - MITK_INFO(PluginVerbose) << "SO2 setting value: " << value; - m_sO2->AddSO2Settings(value); - } - else - m_sO2->AddSO2Settings(0); - } -} - -void SpectralUnmixing::SetRelativeErrorSettings(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter) -{ - for (unsigned int i = 0; i < 2; ++i) - { - if (m_Controls.tableError->item(0, i)) - { - QString Text = m_Controls.tableError->item(0, i)->text(); - int value = Text.toInt(); - MITK_INFO(PluginVerbose) << "Relative error setting value: " << value; - m_SpectralUnmixingFilter->AddRelativeErrorSettings(value); - } - else - m_SpectralUnmixingFilter->AddRelativeErrorSettings(0); - } -} - -void SpectralUnmixing::CalculateSO2(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter, std::vector boolVec) -{ - MITK_INFO(PluginVerbose) << "CALCULATE OXYGEN SATURATION ..."; - - if (!boolVec[0]) - mitkThrow() << "SELECT CHROMOPHORE DEOXYHEMOGLOBIN!"; - if (!boolVec[1]) - mitkThrow() << "SELECT CHROMOPHORE OXYHEMOGLOBIN!"; - auto m_sO2 = mitk::pa::SpectralUnmixingSO2::New(); - m_sO2->Verbose(PluginVerbose); - SetSO2Settings(m_sO2); - - // Initialize pipeline from SU filter class to SO2 class - auto output1 = m_SpectralUnmixingFilter->GetOutput(0); - auto output2 = m_SpectralUnmixingFilter->GetOutput(1); - m_sO2->SetInput(0, output1); - m_sO2->SetInput(1, output2); - - m_sO2->Update(); - - mitk::Image::Pointer sO2 = m_sO2->GetOutput(0); - sO2->SetSpacing(output1->GetGeometry()->GetSpacing()); - WriteOutputToDataStorage(sO2, "sO2"); - MITK_INFO(PluginVerbose) << "[DONE]"; -} - -void SpectralUnmixing::WriteOutputToDataStorage(mitk::Image::Pointer m_Image, std::string name) -{ - mitk::DataNode::Pointer dataNodeOutput = mitk::DataNode::New(); - dataNodeOutput->SetData(m_Image); - dataNodeOutput->SetName(name); - this->GetDataStorage()->Add(dataNodeOutput); -} - -void SpectralUnmixing::Settings(mitk::Image::Pointer image) -{ - boolVec = { m_Controls.checkBoxOx->isChecked(), m_Controls.checkBoxDeOx->isChecked(), - m_Controls.checkBoxMelanin->isChecked(), m_Controls.checkBoxAdd->isChecked() }; - outputNameVec = { "HbO2", "Hb", "Melanin", "Static Endmember" }; - sO2Bool = (m_Controls.checkBoxsO2->isChecked()); - - //Read GUI information(algorithm) - auto qs = m_Controls.QComboBoxAlgorithm->currentText(); - Algorithm = qs.toUtf8().constData(); - - m_SpectralUnmixingFilter = GetFilterInstance(Algorithm); - SetVerboseMode(m_SpectralUnmixingFilter, PluginVerbose); - m_SpectralUnmixingFilter->RelativeError(m_Controls.checkBoxError->isChecked()); - m_SpectralUnmixingFilter->SetInput(image); - SetWavlength(m_SpectralUnmixingFilter); - SetChromophore(m_SpectralUnmixingFilter, boolVec, outputNameVec); - - boolVec.push_back(m_Controls.checkBoxError->isChecked()); - outputNameVec.push_back("Relative Error"); - if (m_Controls.checkBoxError->isChecked()) - SetRelativeErrorSettings(m_SpectralUnmixingFilter); - - m_SpectralUnmixingFilter->AddOutputs(std::accumulate(boolVec.begin(), boolVec.end(), 0)); - MITK_INFO(PluginVerbose) << "Number of indexed outputs: " << std::accumulate(boolVec.begin(), boolVec.end(), 0); -} - -void SpectralUnmixing::storeOutputs() -{ - int outputCounter = 0; - mitk::Image::Pointer m_Output; - for (unsigned int chromophore = 0; chromophore < outputNameVec.size(); ++chromophore) - { - if (boolVec[chromophore] != false) - { - m_Output = m_SpectralUnmixingFilter->GetOutput(outputCounter++); - m_Output->SetSpacing(image->GetGeometry()->GetSpacing()); - WriteOutputToDataStorage(m_Output, outputNameVec[chromophore] + Algorithm); - } - } - - if (sO2Bool) - CalculateSO2(m_SpectralUnmixingFilter, boolVec); - - mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); - MITK_INFO(PluginVerbose) << "Adding images to DataStorage...[DONE]"; - - std::chrono::steady_clock::time_point _end(std::chrono::steady_clock::now()); - MITK_INFO(m_Controls.checkBoxChrono->isChecked()) << "Time for image Processing: " - << std::chrono::duration_cast>(_end - _start).count(); - QApplication::setOverrideCursor(Qt::ArrowCursor); - SwitchGUIControl(true); -} - -void SpectralUnmixing::WorkingThreadUpdateFilter(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter) -{ - //SwitchGUIControl(false); - emit enableSignal(); - try - { - m_SpectralUnmixingFilter->Update(); - emit finishSignal(); - } - catch (const mitk::Exception& e) - { - QApplication::setOverrideCursor(Qt::ArrowCursor); - SwitchGUIControl(true); - errorMessage = e.GetDescription(); - emit crashSignal(); - } -} - -void SpectralUnmixing::crashInfo() -{ - const char *error = errorMessage.c_str(); - QMessageBox::information(nullptr, "Template", error); -} - -void SpectralUnmixing::DoImageProcessing() -{ - QList nodes = this->GetDataManagerSelection(); - if (nodes.empty()) - return; - - mitk::DataNode *node = nodes.front(); - - if (!node) - { - // Nothing selected. Inform the user and return - QMessageBox::information(nullptr, "Template", "Please load and select an image before starting image processing."); - return; - } - - // here we have a valid mitk::DataNode - - // a node itself is not very useful, we need its data item (the image) - mitk::BaseData *data = node->GetData(); - if (data) - { - // test if this data item is an image or not (could also be a surface or something totally different) - image = dynamic_cast(data); - if (image) - { - std::stringstream message; - std::string name; - message << "PERFORMING SPECTRAL UNMIXING "; - if (node->GetName(name)) - { - // a property called "name" was found for this DataNode - message << "'" << name << "'"; - } - message << "."; - - _start = std::chrono::steady_clock::now(); - PluginVerbose = m_Controls.checkBoxVerbose->isChecked(); - MITK_INFO(PluginVerbose) << message.str(); - - try - { - Settings(image); - MITK_INFO(PluginVerbose) << "Updating Filter..."; - QApplication::setOverrideCursor(Qt::WaitCursor); - QtConcurrent::run(this, &SpectralUnmixing::WorkingThreadUpdateFilter, m_SpectralUnmixingFilter); - } - catch (const mitk::Exception& e) - { - QApplication::setOverrideCursor(Qt::ArrowCursor); - QMessageBox::information(nullptr, "Template", e.GetDescription()); - } - } - } -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixing.h b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixing.h deleted file mode 100644 index bb47e7f612..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixing.h +++ /dev/null @@ -1,197 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef SpectralUnmixing_h -#define SpectralUnmixing_h - -#include - -#include -#include -#include - -#include -#include "ui_SpectralUnmixingControls.h" - -/** -* \brief The spectral unmixing plugin provides a GUI tool to perform spectral unmixing of multispectral MITK images. -* It was designed to unmix beamformed photoacoustic imgaes. The outputs are as well MITK images for every chosen absorber -* (endmember). Furthermore it is possible to calculate the oxygen saturation of the multispectral input if the endmembers -* oxy- and deoxyhemoglobin are selected in the GUI. -* -* For further information look at the documentation of the mitkPASpectralUnmixingFilterBase.h -* -* @exeption if the GenerateOutput method throws a exception the plugin will show a QMessageBox with the exception -* message at the GUI -*/ -class SpectralUnmixing : public QmitkAbstractView -{ - // this is needed for all Qt objects that should have a Qt meta-object - // (everything that derives from QObject and wants to have signal/slots) - Q_OBJECT - - public: - static const std::string VIEW_ID; - - protected: - void CreateQtPartControl(QWidget *parent) override; - void SetFocus() override; - - /// \brief called by QmitkFunctionality when DataManager's selection has changed - void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, - const QList &nodes) override; - - - /** - * \brief Called when the user clicks the GUI button. Checks if the selected data is an image. Then passen on the GUI - * information using the Settings method. Afterwards it performs spectral unmixing via the WorkingThreadUpdateFilter - * method in a own thread. The spectral unmixing is based on the spectral unmixing filter base and its subclasses. - * @exception if nothing is selected. Inform the user and return - * @exception if settings fails. Informs with the mitkthorw information of the filter as QMessageBox - */ - void DoImageProcessing(); - - /** - * \brief slots are there to show/hide input tables for weights-, relative error and SO2 settings ig they are not needed - */ - public slots: - void EnableGUIWeight(); - void EnableGUISO2(); - void EnableGUIError(); - - /** - * \brief slot waits for finishSignal of the working thread and starts storeOutputs - */ - public slots: - /** - * \brief slot does the image post processing - * - GetOutput from m_SpectralUnmixingFilter - * - calles WriteOutputToDataStorage - * - if (true) calls CalculateSO2 - * - does the rendering - * - if (true) shows the chrono result - * - switches the GUI back on - */ - void storeOutputs(); - signals: - void finishSignal(); - - public slots: - void EnableGUIControl(); - signals: - void enableSignal(); - - /** - * \brief slot waits for crashSignal and if neccessary ends working thread and shows QMessageBox with the error message - */ - public slots: - void crashInfo(); - signals: - void crashSignal(); - - protected: - Ui::SpectralUnmixingControls m_Controls; - - /** - * \brief passes the algorithm information from the GUI on to the spectral unmixing filter base subclass method - * "SetAlgortihm" and initializes the subclassFilter::Pointer. - * @param algorithm has to be a string which can be assigned to the mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType - * @throws if the algorithm string doesn't match to an implemented algorithm - */ - mitk::pa::SpectralUnmixingFilterBase::Pointer GetFilterInstance(std::string algorithm); - - bool PluginVerbose = true; - mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter; - std::vector outputNameVec; - std::vector boolVec; - std::string Algorithm; - bool sO2Bool; - mitk::Image *image; - std::chrono::steady_clock::time_point _start; - std::string errorMessage; - - private: - /** - * \brief thread - * - disables GUI - * - tries Filter->Update() method - * - gives finishSignal which calls storeOutputs - * - cathes by enables GUI and gives crashSignal - */ - void WorkingThreadUpdateFilter(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter); - - /** - * \brief takes an MITK image as input and performs spectral unmixing based on the spectral unmixing filter base and its subclasses. - * Therefor it first passes all information from the GUI into the filter by using the "set"methods of the plugin, which then are calling - * the "add" methods of the filter(base). - * @param image has to be an MITK image (pointer). For the request on the image look at the docu of the mitkPASpectralUnmixngFilterBase.h - */ - virtual void Settings(mitk::Image::Pointer image); - - /** - * \brief The method takes a image pointer and a file name which then will get to the data storage. - * @param m_Image is a mitk_::Image::Pointer pointing at the output which one wants to get stored - * @param name has to be a string and will be the file name - */ - virtual void WriteOutputToDataStorage(mitk::Image::Pointer m_Image, std::string name); - - /** - * \brief passes the algorithm information if verbose mode is requested from the GUI on to the spectral unmixing filter - * @param m_SpectralUnmixingFilter is a pointer of the spectral unmixing filter base - * @param PluginVerbose is the GUI information bool - */ - virtual void SetVerboseMode(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter, bool PluginVerbose); - - /** - * \brief passes the wavelength information from the GUI on to the spectral unmixing filter base method "AddWavelength". - * @param m_SpectralUnmixingFilter is a pointer of the spectral unmixing filter base - */ - virtual void SetWavlength(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter); - - /** - * \brief passes the chromophore information from the GUI on to the spectral unmixing filter base method "AddChromophore". - * @param m_SpectralUnmixingFilter is a pointer of the spectral unmixing filter base - * @param boolVec is a vector which contains the information which chromophore was checked in the GUI - * @param chromophoreNameVec contains the names of all chromophores as strings - * @throws "PRESS 'IGNORE' AND CHOOSE A CHROMOPHORE!" if no chromophore was chosen - */ - virtual void SetChromophore(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter, std::vector boolVec, std::vector chromophoreNameVec); - - /** - * \brief passes the SetRelativeErrorSettings information from the GUI on to the spectral unmixing filter base method "AddRelativeErrorSettings". - * @param m_SpectralUnmixingFilter is a pointer of the spectral unmixing filter base# - */ - virtual void SetRelativeErrorSettings(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter); - - /** - * \brief passes the SetSO2Settings information from the GUI on to the spectral unmixing SO2 filter method "AddSO2Settings". - * @param m_sO2 is a pointer of the spectral unmixing SO2 filter - */ - virtual void SetSO2Settings(mitk::pa::SpectralUnmixingSO2::Pointer m_sO2); - - /** - * \brief calcultes out of two identical sized MITK images the oxygen saturation and stores the result in an image. Herein the two - * input images are the output for oxy- and deoxyhemoglobin from the GenerateOutput method (spectral unmixing filter results). - * @param m_SpectralUnmixingFilter is a pointer of the spectral unmixing filter base to get the filter output images as sO2 input - * @param boolVec is a vector which contains the information which chromophore was checked in the GUI - * @throws if oxy- or deoxyhemoglobin was not selected in the GUI - */ - virtual void CalculateSO2(mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter, std::vector boolVec); - - /** - * \brief enables/disables GUI - * @param change true means GUI buttons enabled, false disabled respectively - */ - virtual void SwitchGUIControl(bool change); -}; - -#endif // SpectralUnmixing_h diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixingControls.ui b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixingControls.ui deleted file mode 100644 index aa90868457..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/SpectralUnmixingControls.ui +++ /dev/null @@ -1,1232 +0,0 @@ - - - SpectralUnmixingControls - - - - 0 - 0 - 325 - 742 - - - - - 0 - 0 - - - - QmitkTemplate - - - - - - QLabel { color: rgb(255, 0, 0) } - - - Please select an image! - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Wavelengths settings - - - - - - - - 0 - 75 - - - - - 16777215 - 75 - - - - - 10 - - - - <html><head/><body><p>* \brief All values have to be intergers. They need to have the same order than the wavelength at the image.</p></body></html> - - - true - - - Qt::SolidLine - - - 42 - - - 50 - - - 30 - - - 30 - - - - λ [nm] - - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 10 - - - - - 11 - - - - - 12 - - - - - 13 - - - - - 14 - - - - - 15 - - - - - 16 - - - - - 17 - - - - - 18 - - - - - 19 - - - - - 20 - - - - - 21 - - - - - 22 - - - - - 23 - - - - - 24 - - - - - 25 - - - - - 26 - - - - - 27 - - - - - 28 - - - - - 29 - - - - - 30 - - - - - 31 - - - - - 32 - - - - - 33 - - - - - 34 - - - - - 35 - - - - - 36 - - - - - 37 - - - - - 38 - - - - - 39 - - - - - 40 - - - - - 760 - - - - - 798 - - - - - 858 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 790 - - - - - 800 - - - - - 810 - - - - - 820 - - - - - 830 - - - - - 840 - - - - - 850 - - - - - 860 - - - - - 870 - - - - - 880 - - - - - 890 - - - - - 900 - - - - - 910 - - - - - 920 - - - - - 930 - - - - - 940 - - - - - 950 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - <html><head/><body><p><span style=" font-weight:400;">* \brief Select as least one Absorber. It's not possible to select more absorbers then wavelengths.</span></p></body></html> - - - Chromophore selection - - - - - - - <html><head/><body><p>* \brief One of the main absorbers in near infrared spectrum.</p></body></html> - - - Oxyhemoglobin - - - true - - - - - - - true - - - <html><head/><body><p>* \brief One of the main absorbers in near infrared spectrum.</p></body></html> - - - Deoxygenated hemoglobin - - - true - - - true - - - false - - - - - - - <html><head/><body><p>* \brief One of the main absorbers in near infrared spectrum.</p></body></html> - - - Melanin - - - - - - - <html><head/><body><p>* \brief This endmember will be unmixed with 1 at all wavelgnths.</p></body></html> - - - Static Endmember - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - <html><head/><body><p><span style=" font-weight:400;">* \brief One needs to choose an spectral unmixing algorithm.</span></p></body></html> - - - Unmixing algorithm - - - - - - - true - - - - MS Shell Dlg 2 - - - - <html><head/><body><p>* \brief For detailed information about the algorithms please have a look at the documentation.</p></body></html> - - - false - - - 21 - - - 2147483647 - - - - ==CHOSE ALGORITHM== - - - - - ==QR decomposition== - - - - - householderQr - - - - - colPivHouseholderQr - - - - - fullPivHouseholderQr - - - - - ==LU decompositon - - - - - fullPivLu - - - - - ==Cholesky decompostion== - - - - - ldlt - - - - - llt - - - - .. - - - - - ==Least squares== - - - - - LS - - - - - jacobiSvd - - - - - NNLARS - - - - - NNGoldfarb - - - - - weighted - - - - - ==Others== - - - - - SimplexMax - - - - - - - - true - - - - 0 - 75 - - - - - 380 - 81 - - - - <html><head/><body><p>* \brief the weights are at the same order as the wavelength</p></body></html> - - - false - - - false - - - - Weights [%] - - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 10 - - - - - 11 - - - - - 12 - - - - - 13 - - - - - 14 - - - - - 15 - - - - - 16 - - - - - 17 - - - - - 18 - - - - - 19 - - - - - 20 - - - - - 21 - - - - - 22 - - - - - 23 - - - - - 24 - - - - - 25 - - - - - 26 - - - - - 11 - - - - - 10 - - - - - 9 - - - - - 8 - - - - - 7 - - - - - 7 - - - - - 6 - - - - - 6 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 5 - - - - - 6 - - - - - 6 - - - - - 6 - - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Oxygen saturation - - - - - - - <html><head/><body><p>* \brief calculates HbO2/(HbO2+Hb) if De- and oxyhemoglobin are selected.</p></body></html> - - - calculate sO2 - - - false - - - - - - - - 380 - 82 - - - - <html><head/><body><p>* \brief below threshold calculated sO2 value will set to zero</p></body></html> - - - - Threshold - - - - - HbO2 - - - - - Hb - - - - - - - - Sum - - - - - SO2 % - - - - - - - - - - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - - - - - 75 - true - - - - Additional Settings - - - - - - - <html><head/><body><p>* \brief This mode will give additional console outputs for debugging.</p></body></html> - - - Verbose Mode (additional console outputs) - - - false - - - - - - - <html><head/><body><p>* \brief This checkbox will start Chrono and takes the time between clicking of the &quot;Perform spectral unmixing&quot; button until the GUI enables again.</p></body></html> - - - Chrono - - - - - - - <html><head/><body><p>* \brief Calculates the realtive error between unmixing result and the input image in the L2 norm.</p></body></html> - - - Relative error image - - - - - - - - 307 - 70 - - - - <html><head/><body><p>* \brief below the threshold calculated relative error will set to zero</p></body></html> - - - - Threshold - - - - - HbO2 - - - - - Hb - - - - - - - - - - - - - - - - - - Do image processing - - - Perform spectral unmixing - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - 17 - 54 - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.cpp b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.cpp deleted file mode 100644 index 6964b0ff61..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#include "org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.h" -#include "SpectralUnmixing.h" - -namespace mitk -{ - void org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator::start(ctkPluginContext *context) - { - BERRY_REGISTER_EXTENSION_CLASS(SpectralUnmixing, context) - } - - void org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator::stop(ctkPluginContext *context) { Q_UNUSED(context) } -} diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.h b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.h deleted file mode 100644 index 42d07daaa1..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/src/internal/org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator.h +++ /dev/null @@ -1,34 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator_h -#define org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator_h - -#include - -namespace mitk -{ - class org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator : public QObject, public ctkPluginActivator - { - Q_OBJECT - Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_photoacoustics_spectralunmixing") - Q_INTERFACES(ctkPluginActivator) - - public: - void start(ctkPluginContext *context) override; - void stop(ctkPluginContext *context) override; - - }; // org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator -} - -#endif // org_mitk_gui_qt_photoacoustics_spectralunmixing_Activator_h diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/CMakeLists.txt b/Plugins/org.mitk.gui.qt.spectrocamrecorder/CMakeLists.txt deleted file mode 100644 index 34a55ab54c..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -project(org_mitk_gui_qt_spectrocamrecorder) - -mitk_create_plugin( - EXPORT_DIRECTIVE SPECTROCAMRECORDER_EXPORT - EXPORTED_INCLUDE_SUFFIXES src - MODULE_DEPENDS MitkQtWidgetsExt MitkSpectroCam -) diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/files.cmake b/Plugins/org.mitk.gui.qt.spectrocamrecorder/files.cmake deleted file mode 100644 index 563aebf275..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/files.cmake +++ /dev/null @@ -1,42 +0,0 @@ -set(SRC_CPP_FILES - -) - -set(INTERNAL_CPP_FILES - org_mitk_gui_qt_spectrocamrecorder_Activator.cpp - SpectroCamRecorder.cpp -) - -set(UI_FILES - src/internal/SpectroCamRecorderControls.ui -) - -set(MOC_H_FILES - src/internal/org_mitk_gui_qt_spectrocamrecorder_Activator.h - src/internal/SpectroCamRecorder.h -) - -# list of resource files which can be used by the plug-in -# system without loading the plug-ins shared library, -# for example the icon used in the menu and tabs for the -# plug-in views in the workbench -set(CACHED_RESOURCE_FILES - resources/icon.xpm - plugin.xml -) - -# list of Qt .qrc files which contain additional resources -# specific to this plugin -set(QRC_FILES - -) - -set(CPP_FILES ) - -foreach(file ${SRC_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/${file}) -endforeach(file ${SRC_CPP_FILES}) - -foreach(file ${INTERNAL_CPP_FILES}) - set(CPP_FILES ${CPP_FILES} src/internal/${file}) -endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.spectrocamrecorder/manifest_headers.cmake deleted file mode 100644 index 8be1ce8a71..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/manifest_headers.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(Plugin-Name "Spectrocamrecorder") -set(Plugin-Version "0.1") -set(Plugin-Vendor "DKFZ") -set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/plugin.xml b/Plugins/org.mitk.gui.qt.spectrocamrecorder/plugin.xml deleted file mode 100644 index 028c1f5624..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/plugin.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/resources/icon.xpm b/Plugins/org.mitk.gui.qt.spectrocamrecorder/resources/icon.xpm deleted file mode 100644 index ea406d17e1..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/resources/icon.xpm +++ /dev/null @@ -1,1144 +0,0 @@ -/* XPM */ -static char * C:\m\MITK\Plugins\org_mitk_gui_qt_spectrocamrecorder\resources\icon_xpm[] = { -"48 48 1093 2", -" c None", -". c #F8F7F7", -"+ c #F7F7F6", -"@ c #F6F6F5", -"# c #F3F3F3", -"$ c #F5F5F5", -"% c #F7F7F7", -"& c #F8F8F7", -"* c #F7F6F6", -"= c #F8F8F8", -"- c #F6F6F6", -"; c #FFFFFF", -"> c #FBFBFB", -", c #F2F2F2", -"' c #E8E8E7", -") c #E2E2E1", -"! c #E2E2E0", -"~ c #DDDEDC", -"{ c #D4D4D2", -"] c #C9C8C7", -"^ c #BCBABB", -"/ c #B7B7B7", -"( c #C5C5C5", -"_ c #E4E4E4", -": c #FEFEFE", -"< c #ECECEC", -"[ c #B6B6B6", -"} c #767676", -"| c #525252", -"1 c #484848", -"2 c #505050", -"3 c #60615F", -"4 c #71726E", -"5 c #7A7978", -"6 c #7A7777", -"7 c #717171", -"8 c #6B6B6B", -"9 c #7B7B7B", -"0 c #A7A7A7", -"a c #E8E8E8", -"b c #FDFDFD", -"c c #E2E2E2", -"d c #7E7E7E", -"e c #313131", -"f c #181819", -"g c #18171C", -"h c #1A191E", -"i c #1A191D", -"j c #1C1B20", -"k c #2B2A2E", -"l c #434243", -"m c #565555", -"n c #595859", -"o c #575757", -"p c #515151", -"q c #4F4F4F", -"r c #7C7C7C", -"s c #D3D3D3", -"t c #EFEFEF", -"u c #242424", -"v c #1F1E1F", -"w c #262526", -"x c #1F1E21", -"y c #17181B", -"z c #18171B", -"A c #19181B", -"B c #1D1D1E", -"C c #2F2F2F", -"D c #404040", -"E c #444444", -"F c #434343", -"G c #424242", -"H c #3A3A3A", -"I c #656565", -"J c #C9C9C9", -"K c #ACACAC", -"L c #2B2B2B", -"M c #1B1A1B", -"N c #272526", -"O c #3A3738", -"P c #383436", -"Q c #2E2B2C", -"R c #262626", -"S c #1A1919", -"T c #161616", -"U c #161617", -"V c #1B1B1B", -"W c #2A2A2A", -"X c #353535", -"Y c #363636", -"Z c #373737", -"` c #343434", -" . c #626262", -".. c #EDEDED", -"+. c #555555", -"@. c #1A1A1A", -"#. c #1C1C1C", -"$. c #201E1E", -"%. c #2C2829", -"&. c #393939", -"*. c #3B3939", -"=. c #3D3A39", -"-. c #32302C", -";. c #2D2B2C", -">. c #272425", -",. c #1B1A1A", -"'. c #1D1D1D", -"). c #292929", -"!. c #2D2D2D", -"~. c #323232", -"{. c #E7E7E7", -"]. c #252525", -"^. c #1F1C1D", -"/. c #343233", -"(. c #444847", -"_. c #414241", -":. c #454141", -"<. c #494545", -"[. c #4A4647", -"}. c #484445", -"|. c #2F2C2D", -"1. c #1A1A19", -"2. c #1F1F1F", -"3. c #292A29", -"4. c #2B2A2B", -"5. c #303030", -"6. c #3B3B3B", -"7. c #999999", -"8. c #1E1E1E", -"9. c #212121", -"0. c #202020", -"a. c #272626", -"b. c #363233", -"c. c #433E3F", -"d. c #4B4748", -"e. c #3F3C3C", -"f. c #1F1E1E", -"g. c #161717", -"h. c #2B2A2D", -"i. c #2A292C", -"j. c #2E2D2E", -"k. c #535353", -"l. c #D0D0D0", -"m. c #FFFEFF", -"n. c #F4F4F4", -"o. c #151616", -"p. c #141515", -"q. c #191819", -"r. c #1E1C1C", -"s. c #282527", -"t. c #2E2C2D", -"u. c #1E1D1D", -"v. c #151515", -"w. c #1C1C1D", -"x. c #26252A", -"y. c #29282A", -"z. c #2C2B2D", -"A. c #2B2B2C", -"B. c #2D2D2E", -"C. c #838383", -"D. c #F0F0F0", -"E. c #F9F9F9", -"F. c #3A3939", -"G. c #1E1F1E", -"H. c #121615", -"I. c #131515", -"J. c #141414", -"K. c #242427", -"L. c #2C2B30", -"M. c #252429", -"N. c #2A282D", -"O. c #282729", -"P. c #818181", -"Q. c #A7A5A4", -"R. c #A6A2A0", -"S. c #B1AFAD", -"T. c #C6C6C5", -"U. c #DCDCDC", -"V. c #D2D2D2", -"W. c #1A1B1B", -"X. c #1B1E1D", -"Y. c #212222", -"Z. c #171918", -"`. c #151415", -" + c #302F34", -".+ c #242328", -"++ c #27262B", -"@+ c #464646", -"#+ c #6B6B6A", -"$+ c #656664", -"%+ c #666866", -"&+ c #4C4C4B", -"*+ c #5E5E5D", -"=+ c #D1D1D1", -"-+ c #C7C7C7", -";+ c #181B1B", -">+ c #181A19", -",+ c #191919", -"'+ c #171717", -")+ c #181818", -"!+ c #141315", -"~+ c #2A292D", -"{+ c #28272C", -"]+ c #29282D", -"^+ c #26262A", -"/+ c #38383A", -"(+ c #4B4C4D", -"_+ c #2D3030", -":+ c #282A29", -"<+ c #303031", -"[+ c #999998", -"}+ c #C4C4C4", -"|+ c #2C2C2C", -"1+ c #1E1E1F", -"2+ c #3B3A3E", -"3+ c #2F2E33", -"4+ c #333237", -"5+ c #36353A", -"6+ c #37363B", -"7+ c #38373B", -"8+ c #252428", -"9+ c #121313", -"0+ c #151516", -"a+ c #1B1B1C", -"b+ c #60605F", -"c+ c #C8C8C8", -"d+ c #3D3D40", -"e+ c #4C4B51", -"f+ c #4B4A50", -"g+ c #4F4E55", -"h+ c #4F4E54", -"i+ c #504F55", -"j+ c #2D2D31", -"k+ c #100D0F", -"l+ c #232323", -"m+ c #6A6C6A", -"n+ c #EEEEED", -"o+ c #D4D4D4", -"p+ c #191A1A", -"q+ c #181919", -"r+ c #131313", -"s+ c #323335", -"t+ c #65656B", -"u+ c #5F5E66", -"v+ c #616068", -"w+ c #3E3F44", -"x+ c #171718", -"y+ c #262221", -"z+ c #362E2B", -"A+ c #42423E", -"B+ c #727674", -"C+ c #F2F2F1", -"D+ c #E3E3E3", -"E+ c #3C3C3C", -"F+ c #1B1C1B", -"G+ c #171A19", -"H+ c #161919", -"I+ c #171919", -"J+ c #222224", -"K+ c #68676E", -"L+ c #696870", -"M+ c #68676F", -"N+ c #65646C", -"O+ c #63616A", -"P+ c #4A4B50", -"Q+ c #1A1A1D", -"R+ c #222627", -"S+ c #363633", -"T+ c #323331", -"U+ c #797A7A", -"V+ c #191B1B", -"W+ c #181A1A", -"X+ c #141415", -"Y+ c #19191C", -"Z+ c #5D5B62", -"`+ c #6D6C74", -" @ c #67666E", -".@ c #64636B", -"+@ c #605F68", -"@@ c #202122", -"#@ c #2E3232", -"$@ c #5D5F60", -"%@ c #767677", -"&@ c #C0C0C0", -"*@ c #707070", -"=@ c #131314", -"-@ c #161519", -";@ c #4A4A4F", -">@ c #6A6971", -",@ c #605F67", -"'@ c #5B5A62", -")@ c #55545C", -"!@ c #44434A", -"~@ c #333333", -"{@ c #7D7E7C", -"]@ c #D1D2D1", -"^@ c #F1F1F1", -"/@ c #FAFAFA", -"(@ c #18181A", -"_@ c #1D1D1F", -":@ c #212022", -"<@ c #101010", -"[@ c #121212", -"}@ c #111111", -"|@ c #121213", -"1@ c #37373A", -"2@ c #595860", -"3@ c #49484F", -"4@ c #3F3E43", -"5@ c #34333A", -"6@ c #2A2A2E", -"7@ c #151718", -"8@ c #262825", -"9@ c #565755", -"0@ c #B3B3B2", -"a@ c #555556", -"b@ c #8A898E", -"c@ c #818082", -"d@ c #0B0B0B", -"e@ c #0C0C0C", -"f@ c #0D0D0D", -"g@ c #0E0E0E", -"h@ c #0F0F0F", -"i@ c #34333B", -"j@ c #26252B", -"k@ c #212025", -"l@ c #1D1C20", -"m@ c #191A1D", -"n@ c #15181A", -"o@ c #1B1D1E", -"p@ c #252426", -"q@ c #727273", -"r@ c #FCFCFC", -"s@ c #383838", -"t@ c #454748", -"u@ c #67676B", -"v@ c #585659", -"w@ c #0A0A0A", -"x@ c #2F312E", -"y@ c #58654D", -"z@ c #637951", -"A@ c #5B734C", -"B@ c #4C5E3E", -"C@ c #33402D", -"D@ c #1E241E", -"E@ c #18191A", -"F@ c #E0E0E0", -"G@ c #BCBCBC", -"H@ c #909090", -"I@ c #797979", -"J@ c #555655", -"K@ c #252323", -"L@ c #1C1717", -"M@ c #2C292C", -"N@ c #302F30", -"O@ c #050505", -"P@ c #080808", -"Q@ c #090909", -"R@ c #191D1C", -"S@ c #323637", -"T@ c #4D5152", -"U@ c #5A6161", -"V@ c #576454", -"W@ c #96BD72", -"X@ c #A9D77D", -"Y@ c #A8D47C", -"Z@ c #A7D37C", -"`@ c #9DC977", -" # c #82A567", -".# c #586E4A", -"+# c #30382D", -"@# c #7B7A7C", -"## c #FCFBFC", -"$# c #DADADA", -"%# c #C2C2C2", -"&# c #9F9F9F", -"*# c #676767", -"=# c #0D0E0D", -"-# c #101011", -";# c #111110", -"># c #171210", -",# c #1A1817", -"'# c #262727", -")# c #060606", -"!# c #040404", -"~# c #313434", -"{# c #515B58", -"]# c #5B6565", -"^# c #5B6566", -"/# c #5A6566", -"(# c #596C5B", -"_# c #98C274", -":# c #A4D27B", -"<# c #A4D07A", -"[# c #A4D17B", -"}# c #A8D47F", -"|# c #A6D47F", -"1# c #7FA065", -"2# c #8E8C89", -"3# c #F7F5F5", -"4# c #FEFFFF", -"5# c #E0E1E3", -"6# c #D5D7D9", -"7# c #D6D7D9", -"8# c #B1B2B2", -"9# c #4C4C4C", -"0# c #101110", -"a# c #0C0D0C", -"b# c #020202", -"c# c #0E0D0E", -"d# c #1A1A1B", -"e# c #3D4344", -"f# c #5D6969", -"g# c #616E6D", -"h# c #5C6769", -"i# c #5A6468", -"j# c #596567", -"k# c #58675F", -"l# c #8DB36F", -"m# c #A4D47C", -"n# c #A2D17D", -"o# c #A2D17C", -"p# c #A1D17C", -"q# c #9DB073", -"r# c #AB7875", -"s# c #E1B4B4", -"t# c #F8EDEE", -"u# c #FDFEFF", -"v# c #F0F1F1", -"w# c #B3B5B5", -"x# c #727578", -"y# c #82868A", -"z# c #A0A4A8", -"A# c #959799", -"B# c #636363", -"C# c #0E0C0B", -"D# c #141211", -"E# c #070707", -"F# c #181918", -"G# c #3F4645", -"H# c #5C6868", -"I# c #5E6B6B", -"J# c #5C6969", -"K# c #5B666A", -"L# c #5A6569", -"M# c #5A6568", -"N# c #586663", -"O# c #82A46B", -"P# c #A5D57E", -"Q# c #A2D17E", -"R# c #A2D27E", -"S# c #A2D27D", -"T# c #9CC076", -"U# c #BC8069", -"V# c #EE6F73", -"W# c #F1797B", -"X# c #F0AFAE", -"Y# c #F9F1F2", -"Z# c #FDFFFF", -"`# c #C6C9C8", -" $ c #5A5D5C", -".$ c #282828", -"+$ c #3E3F40", -"@$ c #777A7D", -"#$ c #A4A8AC", -"$$ c #787C7F", -"%$ c #343537", -"&$ c #131212", -"*$ c #150F0F", -"=$ c #1E1818", -"-$ c #0F1010", -";$ c #232724", -">$ c #535D5B", -",$ c #5F6C6C", -"'$ c #5B6767", -")$ c #5A6666", -"!$ c #596568", -"~$ c #5A6665", -"{$ c #78956A", -"]$ c #A6D780", -"^$ c #A2D37D", -"/$ c #A3D27E", -"($ c #98C776", -"_$ c #AB8D67", -":$ c #E56C6C", -"<$ c #F57174", -"[$ c #F27070", -"}$ c #EE7976", -"|$ c #F1C0BF", -"1$ c #F9FAFA", -"2$ c #979A9A", -"3$ c #373B3C", -"4$ c #19191A", -"5$ c #262728", -"6$ c #6A6C70", -"7$ c #8A9398", -"8$ c #52575B", -"9$ c #171818", -"0$ c #0E0C0C", -"a$ c #0D0B0B", -"b$ c #1D1F1D", -"c$ c #414645", -"d$ c #535B5A", -"e$ c #5B6766", -"f$ c #5A6667", -"g$ c #596566", -"h$ c #5A6668", -"i$ c #535D60", -"j$ c #556651", -"k$ c #88AF6C", -"l$ c #98C576", -"m$ c #9BD07A", -"n$ c #9F9F6E", -"o$ c #DB726D", -"p$ c #F47173", -"q$ c #F27273", -"r$ c #F27373", -"s$ c #F26F6E", -"t$ c #EF8C8A", -"u$ c #F4E3E1", -"v$ c #656769", -"w$ c #25282B", -"x$ c #151617", -"y$ c #1D1E21", -"z$ c #72777E", -"A$ c #7B8288", -"B$ c #313436", -"C$ c #202021", -"D$ c #202120", -"E$ c #242724", -"F$ c #424947", -"G$ c #5A6564", -"H$ c #5A6767", -"I$ c #596466", -"J$ c #454D52", -"K$ c #2A2F31", -"L$ c #1D1F1C", -"M$ c #2E3828", -"N$ c #45543B", -"O$ c #637A56", -"P$ c #6D835B", -"Q$ c #BC6F66", -"R$ c #F26F71", -"S$ c #F37273", -"T$ c #F37372", -"U$ c #F37271", -"V$ c #F0736E", -"W$ c #F0BAB6", -"X$ c #4D5052", -"Y$ c #171A1D", -"Z$ c #0E0E0F", -"`$ c #0A0B0B", -" % c #0C0B0B", -".% c #4A4B4F", -"+% c #9CA2AA", -"@% c #63696C", -"#% c #100F0F", -"$% c #10100F", -"%% c #111011", -"&% c #333236", -"*% c #29282C", -"=% c #080807", -"-% c #131413", -";% c #323737", -">% c #4B5454", -",% c #363D3F", -"'% c #191B1C", -")% c #131414", -"!% c #353735", -"~% c #414440", -"{% c #A4595A", -"]% c #F57072", -"^% c #F47072", -"/% c #F37272", -"(% c #F27371", -"_% c #F37371", -":% c #F1706B", -"<% c #EE958F", -"[% c #E1E1E1", -"}% c #56595B", -"|% c #131619", -"1% c #0D0E0E", -"2% c #1B1A19", -"3% c #242425", -"4% c #95979F", -"5% c #91969B", -"6% c #292B2C", -"7% c #0B0D0E", -"8% c #101314", -"9% c #1D1F20", -"0% c #15171A", -"a% c #2E2D31", -"b% c #1C1B1D", -"c% c #1A191B", -"d% c #080708", -"e% c #0B0C0B", -"f% c #1C1E1A", -"g% c #141411", -"h% c #0D0D0A", -"i% c #222222", -"j% c #323333", -"k% c #4C3434", -"l% c #C85D5E", -"m% c #F36F6F", -"n% c #F26F70", -"o% c #F37170", -"p% c #F7716E", -"q% c #DA7772", -"r% c #ECEDEE", -"s% c #808486", -"t% c #1F2225", -"u% c #0F1012", -"v% c #2B2A29", -"w% c #0E0C0E", -"x% c #1F1622", -"y% c #7D7E88", -"z% c #C2C6CB", -"A% c #5B5F61", -"B% c #121517", -"C% c #14171A", -"D% c #1D2023", -"E% c #1D1D20", -"F% c #070607", -"G% c #131411", -"H% c #0D0E0A", -"I% c #0D0D0C", -"J% c #2E2E2E", -"K% c #232525", -"L% c #151919", -"M% c #723839", -"N% c #EB6E6E", -"O% c #DE6F6E", -"P% c #CC6C6C", -"Q% c #B26566", -"R% c #80595A", -"S% c #CDD0D1", -"T% c #5B5F62", -"U% c #202123", -"V% c #3B3A38", -"W% c #110E15", -"X% c #23192A", -"Y% c #5E5C67", -"Z% c #E6E6ED", -"`% c #9CA0A2", -" & c #25272A", -".& c #18181D", -"+& c #171619", -"@& c #2B2C28", -"#& c #21221D", -"$& c #0C0C0B", -"%& c #101111", -"&& c #181614", -"*& c #684C4B", -"=& c #795D5C", -"-& c #675E5D", -";& c #5B5E60", -">& c #565E62", -",& c #4D565C", -"'& c #F1F3F4", -")& c #888B8F", -"!& c #303234", -"~& c #363534", -"{& c #2C2B29", -"]& c #161418", -"^& c #313134", -"/& c #C1C2C7", -"(& c #AFB4B8", -"_& c #2F3033", -":& c #0E0D11", -"<& c #0A090A", -"[& c #141316", -"}& c #141416", -"|& c #121413", -"1& c #0E0F0E", -"2& c #1D1D1A", -"3& c #141511", -"4& c #0E0E0D", -"5& c #131514", -"6& c #455150", -"7& c #556365", -"8& c #546063", -"9& c #555F62", -"0& c #556062", -"a& c #4E5A59", -"b& c #F5F7F7", -"c& c #969A9E", -"d& c #313237", -"e& c #221F23", -"f& c #35312F", -"g& c #211E1B", -"h& c #141010", -"i& c #201E22", -"j& c #727881", -"k& c #717E89", -"l& c #1E2327", -"m& c #16151B", -"n& c #1C1B1F", -"o& c #2F2E2F", -"p& c #1A1B1C", -"q& c #0C0A0A", -"r& c #16110F", -"s& c #201814", -"t& c #2E231C", -"u& c #2A221A", -"v& c #10100A", -"w& c #090A06", -"x& c #1E2020", -"y& c #525C5E", -"z& c #566166", -"A& c #566165", -"B& c #546064", -"C& c #535E62", -"D& c #535E5D", -"E& c #FCFCFB", -"F& c #B1B4B6", -"G& c #383B3E", -"H& c #0E0F12", -"I& c #1D1C1B", -"J& c #282421", -"K& c #191311", -"L& c #191516", -"M& c #3D424D", -"N& c #475260", -"O& c #1D2125", -"P& c #181719", -"Q& c #17161B", -"R& c #141417", -"S& c #1D1B1D", -"T& c #383637", -"U& c #232424", -"V& c #232626", -"W& c #302A28", -"X& c #4E362A", -"Y& c #644031", -"Z& c #7D533D", -"`& c #956348", -" * c #AA6F51", -".* c #935F43", -"+* c #281F13", -"@* c #0D0F0B", -"#* c #0B0C08", -"$* c #131412", -"%* c #0E0D0D", -"&* c #292E2F", -"** c #556064", -"=* c #545F63", -"-* c #515C60", -";* c #606C6B", -">* c #D2D3D3", -",* c #4F5356", -"'* c #101316", -")* c #1B1916", -"!* c #1C1815", -"~* c #1C1816", -"{* c #515357", -"]* c #6E747A", -"^* c #3A3C3E", -"/* c #151416", -"(* c #101013", -"_* c #333434", -":* c #454747", -"<* c #5F6262", -"[* c #835B45", -"}* c #C4794F", -"|* c #D18057", -"1* c #D38359", -"2* c #D18359", -"3* c #CE825A", -"4* c #CB8057", -"5* c #6F4730", -"6* c #161510", -"7* c #12120F", -"8* c #171815", -"9* c #0B0C0A", -"0* c #0B0B09", -"a* c #101212", -"b* c #393F41", -"c* c #545E61", -"d* c #4D595C", -"e* c #737E77", -"f* c #F2F3F3", -"g* c #8E9193", -"h* c #2F3235", -"i* c #0B0A0B", -"j* c #121211", -"k* c #262522", -"l* c #747677", -"m* c #909494", -"n* c #464848", -"o* c #343435", -"p* c #616161", -"q* c #787878", -"r* c #939393", -"s* c #B3B4B4", -"t* c #C4C4C6", -"u* c #C28F73", -"v* c #B97249", -"w* c #CB7C4F", -"x* c #D18051", -"y* c #CF8153", -"z* c #CD8155", -"A* c #CD8157", -"B* c #B9744F", -"C* c #493121", -"D* c #0B0C09", -"E* c #131A1B", -"F* c #2C3D4B", -"G* c #3D5363", -"H* c #4A5960", -"I* c #515B5E", -"J* c #525D61", -"K* c #505C60", -"L* c #505B5D", -"M* c #979D94", -"N* c #D8D8D9", -"O* c #666A6B", -"P* c #242728", -"Q* c #191B1E", -"R* c #191D1F", -"S* c #353738", -"T* c #85888A", -"U* c #838585", -"V* c #363735", -"W* c #5C5C5C", -"X* c #AAAAAA", -"Y* c #CACACA", -"Z* c #D7D7D7", -"`* c #E8E8E9", -" = c #BEA598", -".= c #6B4B39", -"+= c #C1784A", -"@= c #D5834F", -"#= c #D08151", -"$= c #CF8152", -"%= c #CD8055", -"&= c #D38557", -"*= c #75513B", -"== c #262927", -"-= c #1D201C", -";= c #161614", -">= c #11110F", -",= c #131516", -"'= c #1F2B34", -")= c #31495D", -"!= c #3C5B79", -"~= c #3B5E7D", -"{= c #3E5C77", -"]= c #425563", -"^= c #4A555A", -"/= c #4E585B", -"(= c #606867", -"_= c #C5C8BF", -":= c #BCC1C1", -"<= c #535B5D", -"[= c #262C2F", -"}= c #22272A", -"|= c #4B4F53", -"1= c #808286", -"2= c #7E7F80", -"3= c #777876", -"4= c #818281", -"5= c #A6A6A6", -"6= c #B4B4B4", -"7= c #D5D5D5", -"8= c #DDDDDD", -"9= c #ECECEB", -"0= c #AAABA9", -"a= c #514F4C", -"b= c #26231E", -"c= c #7E5638", -"d= c #C67C4B", -"e= c #D48251", -"f= c #D28151", -"g= c #D58354", -"h= c #B3724C", -"i= c #564A3C", -"j= c #3E433E", -"k= c #3B403A", -"l= c #353B35", -"m= c #343632", -"n= c #313A44", -"o= c #36526D", -"p= c #3C5D7C", -"q= c #3C5D7D", -"r= c #3B5D7E", -"s= c #3A5E80", -"t= c #3A5A79", -"u= c #3D5365", -"v= c #3E474B", -"w= c #767977", -"x= c #E7E7E5", -"y= c #E7E9E9", -"z= c #B1B7BA", -"A= c #84898D", -"B= c #73787B", -"C= c #94969B", -"D= c #BBBCBF", -"E= c #D3D3D4", -"F= c #D7D8D7", -"G= c #E5E5E5", -"H= c #E6E6E6", -"I= c #D4CFD5", -"J= c #685A6A", -"K= c #39263E", -"L= c #291F30", -"M= c #342926", -"N= c #9E673E", -"O= c #D88450", -"P= c #D6824F", -"Q= c #C6794A", -"R= c #725441", -"S= c #41463E", -"T= c #414740", -"U= c #40453F", -"V= c #40453E", -"W= c #40443E", -"X= c #3C4A55", -"Y= c #3B597A", -"Z= c #3B5D80", -"`= c #3B5C7F", -" - c #3A5C7E", -".- c #3A5C7C", -"+- c #365572", -"@- c #4C5A67", -"#- c #BDBEBE", -"$- c #D4D5D5", -"%- c #CCCDCD", -"&- c #D5D4D5", -"*- c #DFDEDF", -"=- c #EAEAEA", -"-- c #ECEDEC", -";- c #B6C3B8", -">- c #89998D", -",- c #888490", -"'- c #7D6888", -")- c #6C5770", -"!- c #976558", -"~- c #D37F4B", -"{- c #D1804B", -"]- c #8E5F41", -"^- c #46473E", -"/- c #3F443E", -"(- c #3F443D", -"_- c #3A484E", -":- c #3A5673", -"<- c #3A5A7C", -"[- c #3A5A7B", -"}- c #395A7B", -"|- c #385978", -"1- c #46617B", -"2- c #A2ADB4", -"3- c #F4F4F3", -"4- c #D9D9D9", -"5- c #D8D8D8", -"6- c #DBDBDB", -"7- c #DEDEDE", -"8- c #EBEBEB", -"9- c #E9E9E9", -"0- c #F6F3F5", -"a- c #D2DFD3", -"b- c #92C58E", -"c- c #8CC886", -"d- c #8EC987", -"e- c #8CC685", -"f- c #88BF84", -"g- c #979774", -"h- c #C47A4D", -"i- c #A2663D", -"j- c #4E4639", -"k- c #3E433D", -"l- c #3E443C", -"m- c #3B4647", -"n- c #3A536D", -"o- c #3B5879", -"p- c #3B5878", -"q- c #395878", -"r- c #385876", -"s- c #425E77", -"t- c #959FAA", -"u- c #EEEEEE", -"v- c #DFDFDF", -"w- c #F7F6F7", -"x- c #E9ECE7", -"y- c #A6CDA4", -"z- c #89C783", -"A- c #8BC983", -"B- c #8AC983", -"C- c #8AC982", -"D- c #89CA81", -"E- c #8BB980", -"F- c #837B68", -"G- c #4E453D", -"H- c #3B413C", -"I- c #3D423C", -"J- c #3C433B", -"K- c #394440", -"L- c #385064", -"M- c #395674", -"N- c #3B5675", -"O- c #3D5975", -"P- c #4D647A", -"Q- c #A4ADB6", -"R- c #F9F9F8", -"S- c #C6DDC5", -"T- c #8DC788", -"U- c #88C882", -"V- c #8BC984", -"W- c #8AC981", -"X- c #92CA8E", -"Y- c #BDD0BD", -"Z- c #B3B3B3", -"`- c #707B74", -" ; c #505C54", -".; c #444F47", -"+; c #404841", -"@; c #3E443E", -"#; c #3E443D", -"$; c #3C443D", -"%; c #39403B", -"&; c #384854", -"*; c #405A74", -"=; c #4F647B", -"-; c #818F9C", -";; c #CACDD2", -">; c #DEE6DE", -",; c #99C696", -"'; c #85C57C", -"); c #88C77F", -"!; c #89C781", -"~; c #88C781", -"{; c #87C780", -"]; c #84C47E", -"^; c #AED2AB", -"/; c #FAFBF9", -"(; c #EFF2F2", -"_; c #C0CEC7", -":; c #8DA398", -"<; c #667F74", -"[; c #546860", -"}; c #515E55", -"|; c #4F554E", -"1; c #464944", -"2; c #505454", -"3; c #879097", -"4; c #C2C7CB", -"5; c #A8B5A7", -"6; c #79B073", -"7; c #7DC46F", -"8; c #81C575", -"9; c #84C679", -"0; c #82C579", -"a; c #82C67B", -"b; c #81C47A", -"c; c #7CC273", -"d; c #94C68C", -"e; c #E1EAE0", -"f; c #D9DEDA", -"g; c #B8C3BD", -"h; c #97A7A0", -"i; c #82958D", -"j; c #7D8981", -"k; c #7C817A", -"l; c #797D77", -"m; c #7F8280", -"n; c #A1A7AE", -"o; c #C1C6CD", -"p; c #DEE2E4", -"q; c #F3F4F4", -"r; c #F6F5F6", -"s; c #BFC5BF", -"t; c #92B78D", -"u; c #7FBE72", -"v; c #7DBE75", -"w; c #84C27C", -"x; c #83C37A", -"y; c #82C57A", -"z; c #82C37B", -"A; c #81C07B", -"B; c #85B080", -"C; c #ADB3AC", -"D; c #B2B5B5", -"E; c #9DA39E", -"F; c #949993", -"G; c #949691", -"H; c #939592", -"I; c #939792", -"J; c #949893", -"K; c #8F9799", -"L; c #8D9CAB", -"M; c #8E9EAD", -"N; c #9FABB8", -"O; c #BCC4CB", -"P; c #E6E8EA", -". . . . . . . . . . . . . . . . . . . . . . . . + + @ # $ + . . . . . . % . & & & . * = % = - = ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; > , ' ) ! ~ { ] ^ / ( _ = : ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; < [ } | 1 2 3 4 5 6 7 8 9 0 a b ; ; ; ; ; ; ; ; ; ; ; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; c d e f g h i j k l m n o p q r s b ; ; ; ; ; ; ; ; ; ; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; t d u v w x i y z A B C D E F G H I J ; ; ; ; ; ; ; ; ; ; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; : ; K L M N O P Q R S T U V W X Y Y Z ` .s ; ; ; ; ; ; ; ; ; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ..+.@.#.$.%.&.*.=.-.;.>.,.'.).!.C e e ~.7 {.; ; ; ; ; ; ; ; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; [ ].'.V ^./.(._.:.<.[.}.|.1.2.3.4.!.C 5.6.7.% ; ; ; ; ; ; ; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; d 8.'.V S 2.9.0.a.b.c.d.e.f.g.u h.i.j.C !.k.l.; ; ; ; m.m.; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; n.k.8.#.V V g.o.p.T q.r.s.t.u.v.w.k x.y.z.A.B.C.D.> # E.; ; : : ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; c 6.'.@.u F.G.H.I.J.J.J.J.T T T v.K.L.M.x.N.O.H P.Q.R.S.T.U.$ ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; V.e '.W.X.Y.@.Z.o.J.J.J.v.v.v.v.`.i +x..+++++K.@+#+$+%+&+*+=+; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; -+L '.V ;+>+@.@.,+,+v.J.J.'+)+v.v.!+~+ +M.{+]+^+/+(+_+:+u <+[+- ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; }+W '.V W.W.,+)+)+,+)+'+)+|+).J.v.J.1+2+3+4+5+6+7+8+v.9+0+a+b+' ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; c+!.'.V V V S ,+)+'+T T '+9.2.J.v.v.T d+e+f+g+h+i+j+o.v.k+l+m+n+; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; o+~.'.V W.p+q+q+)+'+T v.v.J.r+v.v.v.v.s+t+u+v+u+u+w+x+y+z+A+B+C+; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; D+E+#.F+;+G+H+I+)+'+T v.v.v.v.v.v.v.J.J+K+L+M+N+O+P+Q+R+S+T+U+- ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; # q #.F+V+W+I+)+'+'+T v.v.v.v.v.v.J.X+Y+Z+`+ @.@+@h+@@#@$@%@&@: ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; *@#.V ,+v.'+)+)+)+)+'+T T v.v.J.J.=@-@;@>@,@'@)@!@~@{@]@^@/@; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; 7.V (@_@:@<@[@v.T T T J.r+[@[@[@}@}@|@1@2@3@4@5@6@7@8@9@0@; ; ; ; ", -"; ; ; ; ; ; ; ; ; ; ; ; ; ; ; }+R a@b@c@G.d@e@e@f@f@f@g@g@g@g@h@h@h@J+i@j@k@l@m@n@o@p@q@> ; ; ; ", -"; ; ; ; ; ; ; ; ; ; : : : r@: ( s@t@u@v@'.h@d@w@w@d@e@g@g@f@e@f@J.2.x@y@z@A@B@C@D@E@R r ; ; ; ; ", -"; ; ; ; ; ; ; : b r@$ F@G@H@I@J@K@L@M@N@].w@O@O@P@Q@w@d@e@f@R@S@T@U@V@W@X@Y@Z@`@ #.#+#@#; ; ; ; ", -"; ; ; ; : ####n.$#%#&#*#!.[@=#-#;#>#,#'#8.d@)#!#O@w@w@w@=@~#{#]#^#/#(#_#:#<#<#[#}#|#1#2#3#4#4#; ", -"; ; : % 5#6#7#8#7 9#G 9#&.#.J.r+0#a#}@q+)#b#O@)#!#Q@c#d#e#f#g#h#i#j#k#l#m#n#n#o#o#p#q#r#s#t#u#; ", -"; ; v#w#x#y#z#A#B#@+C u ].#.r+v.v.r+g@C#D#Q@O@E#O@E#F#G#H#I#J#K#L#M#N#O#P#Q#R#n#S#T#U#V#W#X#Y#Z#", -"; > `# $.$+$@$#$$$%$0.'+<@[@r+,+,+'+&$*$=$-$Q@w@w@P@;$>$,$'$)$!$M#)$~${$]$^$S#/$($_$:$<$[$}$|$1$", -"; # 2$3$Y.4$5$6$7$8$9$[@h@<@[@#.,+J.<@0$a$f@}@e@[@d@b$c$d$e$f$g$g$h$i$j$k$l$p#m$n$o$p$q$r$s$t$u$", -"; _ v$w$x$<@w@y$z$A$B$h@r+v.[@#.l+g@e@e@<@C$f w@v.h@'+D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$S$T$U$V$W$", -"; U.X$Y$Z$J.`$ %.%+%@%p.#%'+@.J.W $%g@h@%%&%*%h@J.h@h@<@=%-%;%>%,%'%)%h@}@2.!%~%{%]%^%/%(%_%:%<%", -"; [%}%|%1%2%g@C#3%4%5%6%7%8%9%0%a%b%r+r+[@c%0+T J.w@e@J.P@d%e%f%g%h%<@'+i%u e j%k%l%m%n%o%o%p%q%", -"; r%s%t%u%v%r+w%x%y%z%A%B%C%D%D%^+E%J.J.[@f@d@,+T Q@g@'+<@F%e%G%H%I%8.T ].J%X K%L%M%N%N%O%P%Q%R%", -"m./@S%T%U%V%V W%X%Y%Z%`% &.&+&4$f T r+r+}@f@e@,+V [@h@8.~.r+e@@&#&$&8.g@T l+9.0+%&&&*&=&-&;&>&,&", -"; 4#'&)&!&~&{&%%]&^&/&(&_&:&<&w@e@Z$[&}&0+a+)+'+'.T w@=@].|&1&2&3&4&e@w@d@f@,+#.h@5&6&7&8&9&0&a&", -"; ; b&c&d&e&f&g&h&i&j&k&l&P@)#P@h@|@g m&n&o&i%T p&T q&r&s&t&u&v&w&1.,+h@f@f@<@Q@r+x&y&z&A&B&C&D&", -"; ; E&F&G&H&I&J&K&L&M&N&O&o.r+T l+P&Q&R&S&T&U&V&W&X&Y&Z&`& *.*+*@*#*$*G.[@}@'+f@%*&*****=*=*-*;*", -"; ; ; >*,*'*`$)*!*~*{*]*^*L 8.l+L /*(*=@p+_*:*<*[*}*|*1*2*3*4*5*6*7*8*9$'+J.9*0*a*b*c*=*C&C&d*e*", -"; ; ; f*g*h*-$i*j*k*l*m*n*W )+2.0.#.o*p*q*r*s*t*u*v*w*x*y*z*A*B*C*[@<@e@f@I%D*E*F*G*H*I*J*K*L*M*", -"; ; ; ; N*O*P*Q*R*S*T*U*V*#.).E+W*P.X*Y*Z*F@_ `* =.=+=@=#=$=%=&=*===-=;=>=,='=)=!=~={=]=^=/=(=_=", -"; ; ; ; : :=<=[=}=|=1=2=3=4=5=6=Y*7=8=[%[%D+9=0=a=b=c=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=", -"; ; ; ; ; y=z=A=B=C=D=E=F=Z*U.U.[%[%D+G=H=< I=J=K=L=M=N=O=P=Q=R=S=T=U=V=W=X=Y=Z=`=`= -.-+-@-#-b ", -"; ; ; ; b _ $-l.%-&-*-a _ F@[%c _ {.a =-..--;->-,-'-)-!-~-{-]-^-V=U=U=/-(-_-:-<-[-[-}-|-1-2-3-; ", -"; ; ; ; r@G=4-5-6-7-F@a 8-a {.9-8-< t v#0-a-b-c-d-e-f-g-h-i-j-k-/-k-k-k-l-m-n-o-p-q-r-s-t-u-; ; ", -"; ; ; ; r@a v-v-D+G=H=8-$ $ u-t ^@, n.w-x-y-z-A-B-C-D-E-F-G-H-/-k-k-k-I-J-K-L-M-N-O-P-Q-^@; ; ; ", -"; ; ; ; r@.._ G==-8-< t E.> n.n.- % R-+ S-T-U-V-V-B-W-X-Y-Z-`- ;.;+;@;#;$;%;&;*;=;-;;;; ; ; ; ; ", -"; ; ; ; : $ < ..t D.D.# E.b E.= /@> ##>;,;';);!;!;~;{;];^;/;(;_;:;<;[;};|;1;2;3;4;% ; ; ; ; ; ; ", -"; ; ; ; ; /@# , n.$ $ % > b r@r@b : , 5;6;7;8;9;0;a;b;c;d;e;v#f;g;h;i;j;k;l;m;n;o;p;q;; ; ; ; ; ", -"; ; ; ; : b = - = E./@> b : : : : ; r;s;t;u;v;w;x;y;z;A;B;C;D;E;F;G;H;I;J;J;K;L;M;N;O;P;> ; ; ; "}; diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorder.cpp b/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorder.cpp deleted file mode 100644 index 77b0e8d92f..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorder.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -// Blueberry -#include -#include - -// Qmitk -#include "SpectroCamRecorder.h" - -// Qt -#include - -//mitk image -#include - -// other -#include - -const std::string SpectroCamRecorder::VIEW_ID = "org.mitk.views.spectrocamrecorder"; - -void SpectroCamRecorder::SetFocus() -{ - m_Controls.buttonPerformImageProcessing->setFocus(); -} - -void SpectroCamRecorder::CreateQtPartControl( QWidget *parent ) -{ - // create GUI widgets from the Qt Designer's .ui file - m_Controls.setupUi( parent ); - connect( m_Controls.buttonPerformImageProcessing, SIGNAL(clicked()), this, SLOT(DoImageProcessing()) ); - connect( m_Controls.buttonWhiteBalance, SIGNAL(clicked()), this, SLOT(SetWhiteBalance()) ); - connect( m_Controls.buttonSave, SIGNAL(clicked()), this, SLOT(SaveImage()) ); - - // intialize the camera (!= start). - m_Controller.Ini(); -} - -SpectroCamRecorder::~SpectroCamRecorder() -{ - if (m_Controller.isCameraRunning()) - { - m_Controller.CloseCameraConnection(); - } -} - -void SpectroCamRecorder::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, - const QList& nodes ) -{ - //// iterate all selected objects, adjust warning visibility - //foreach( mitk::DataNode::Pointer node, nodes ) - //{ - // if( node.IsNotNull() && dynamic_cast(node->GetData()) ) - // { - // m_Controls.labelWarning->setVisible( false ); - // m_Controls.buttonPerformImageProcessing->setEnabled( true ); - // return; - // } - //} - - //m_Controls.labelWarning->setVisible( true ); - //m_Controls.buttonPerformImageProcessing->setEnabled( false ); -} - - -void SpectroCamRecorder::SaveImage() -{ - mitk::Image::Pointer imageToSave = m_Controller.GetCurrentImage(); - QString imageName = m_Controls.lineEdit->text(); - - - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData(imageToSave); - imageNode->SetName(imageName.toStdString()); - - - GetDataStorage()->Add(imageNode); - -} - -void SpectroCamRecorder::SetWhiteBalance() -{ - m_Controller.SetCurrentImageAsWhiteBalance(); -} - -void SpectroCamRecorder::DoImageProcessing() -{ - //QList nodes = this->GetDataManagerSelection(); - //if (nodes.empty()) return; - - //mitk::DataNode* node = nodes.front(); - - //if (!node) - //{ - // // Nothing selected. Inform the user and return - // QMessageBox::information( nullptr, "Template", "Please load and select an image before starting image processing."); - // return; - //} - - //// here we have a valid mitk::DataNode - - //// a node itself is not very useful, we need its data item (the image) - //mitk::BaseData* data = node->GetData(); - //if (data) - //{ - // // test if this data item is an image or not (could also be a surface or something totally different) - // mitk::Image* image = dynamic_cast( data ); - // if (image) - // { - // std::stringstream message; - // std::string name; - // message << "Performing image processing for image "; - // if (node->GetName(name)) - // { - // // a property called "name" was found for this DataNode - // message << "'" << name << "'"; - // } - // message << "."; - // MITK_INFO << message.str(); - - // // actually do something here... - - // } - //} - - if (m_Controller.isCameraRunning()) - { - m_Controller.CloseCameraConnection(); - } - else - { - m_Controller.OpenCameraConnection(); - } -} diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorder.h b/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorder.h deleted file mode 100644 index 8b66e67852..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorder.h +++ /dev/null @@ -1,75 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef SpectroCamRecorder_h -#define SpectroCamRecorder_h - -#include - -#include - -#include "ui_SpectroCamRecorderControls.h" - -#include - - -/** -\brief SpectroCamRecorder - -\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. - -\sa QmitkAbstractView -\ingroup ${plugin_target}_internal -*/ -class SpectroCamRecorder : public QmitkAbstractView -{ - // this is needed for all Qt objects that should have a Qt meta-object - // (everything that derives from QObject and wants to have signal/slots) - Q_OBJECT - -public: - - static const std::string VIEW_ID; - - virtual ~SpectroCamRecorder(); - -protected slots: - - /// \brief Called when the user clicks the GUI button - void DoImageProcessing(); - - void SetWhiteBalance(); - - void SaveImage(); - -protected: - - virtual void CreateQtPartControl(QWidget *parent); - - virtual void SetFocus(); - - /// \brief called by QmitkFunctionality when DataManager's selection has changed - virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, - const QList& nodes ); - - Ui::SpectroCamRecorderControls m_Controls; - -private: - - mitk::SpectroCamController m_Controller; - - - -}; - -#endif // SpectroCamRecorder_h diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorderControls.ui b/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorderControls.ui deleted file mode 100644 index 6aeca09807..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/SpectroCamRecorderControls.ui +++ /dev/null @@ -1,82 +0,0 @@ - - - SpectroCamRecorderControls - - - - 0 - 0 - 222 - 228 - - - - - 0 - 0 - - - - QmitkTemplate - - - - - - Do image processing - - - Start/Stop camera - - - - - - - Use current stack as white balance - - - - - - - Save current stack to datastorage - - - - - - - stack name - - - - - - - stack_1 - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 220 - - - - - - - - - - diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/org_mitk_gui_qt_spectrocamrecorder_Activator.cpp b/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/org_mitk_gui_qt_spectrocamrecorder_Activator.cpp deleted file mode 100644 index 1f23f17995..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/org_mitk_gui_qt_spectrocamrecorder_Activator.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "org_mitk_gui_qt_spectrocamrecorder_Activator.h" -#include "SpectroCamRecorder.h" - -namespace mitk { - -void org_mitk_gui_qt_spectrocamrecorder_Activator::start(ctkPluginContext* context) -{ - BERRY_REGISTER_EXTENSION_CLASS(SpectroCamRecorder, context) -} - -void org_mitk_gui_qt_spectrocamrecorder_Activator::stop(ctkPluginContext* context) -{ - Q_UNUSED(context) -} - -} diff --git a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/org_mitk_gui_qt_spectrocamrecorder_Activator.h b/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/org_mitk_gui_qt_spectrocamrecorder_Activator.h deleted file mode 100644 index 150987c1d6..0000000000 --- a/Plugins/org.mitk.gui.qt.spectrocamrecorder/src/internal/org_mitk_gui_qt_spectrocamrecorder_Activator.h +++ /dev/null @@ -1,37 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - - -#ifndef org_mitk_gui_qt_spectrocamrecorder_Activator_h -#define org_mitk_gui_qt_spectrocamrecorder_Activator_h - -#include - -namespace mitk { - -class org_mitk_gui_qt_spectrocamrecorder_Activator : - public QObject, public ctkPluginActivator -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_spectrocamrecorder") - Q_INTERFACES(ctkPluginActivator) - -public: - - void start(ctkPluginContext* context); - void stop(ctkPluginContext* context); - -}; // org_mitk_gui_qt_spectrocamrecorder_Activator - -} - -#endif // org_mitk_gui_qt_spectrocamrecorder_Activator_h